diff options
255 files changed, 11516 insertions, 9687 deletions
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt index 07c65e3cdcbe..f4d04a067282 100644 --- a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt +++ b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt | |||
@@ -3,9 +3,11 @@ Altera SOCFPGA System Manager | |||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : "altr,sys-mgr" | 4 | - compatible : "altr,sys-mgr" |
5 | - reg : Should contain 1 register ranges(address and length) | 5 | - reg : Should contain 1 register ranges(address and length) |
6 | - cpu1-start-addr : CPU1 start address in hex. | ||
6 | 7 | ||
7 | Example: | 8 | Example: |
8 | sysmgr@ffd08000 { | 9 | sysmgr@ffd08000 { |
9 | compatible = "altr,sys-mgr"; | 10 | compatible = "altr,sys-mgr"; |
10 | reg = <0xffd08000 0x1000>; | 11 | reg = <0xffd08000 0x1000>; |
12 | cpu1-start-addr = <0xffd080c4>; | ||
11 | }; | 13 | }; |
diff --git a/Documentation/devicetree/bindings/arm/sirf.txt b/Documentation/devicetree/bindings/arm/sirf.txt index 1881e1c6dda5..c6ba6d3c747f 100644 --- a/Documentation/devicetree/bindings/arm/sirf.txt +++ b/Documentation/devicetree/bindings/arm/sirf.txt | |||
@@ -1,3 +1,9 @@ | |||
1 | prima2 "cb" evaluation board | 1 | CSR SiRFprimaII and SiRFmarco device tree bindings. |
2 | ======================================== | ||
3 | |||
2 | Required root node properties: | 4 | Required root node properties: |
3 | - compatible = "sirf,prima2-cb", "sirf,prima2"; | 5 | - compatible: |
6 | - "sirf,prima2-cb" : prima2 "cb" evaluation board | ||
7 | - "sirf,marco-cb" : marco "cb" evaluation board | ||
8 | - "sirf,prima2" : prima2 device based board | ||
9 | - "sirf,marco" : marco device based board | ||
diff --git a/Documentation/devicetree/bindings/arm/vt8500.txt b/Documentation/devicetree/bindings/arm/vt8500.txt index d657832c6819..87dc1ddf4770 100644 --- a/Documentation/devicetree/bindings/arm/vt8500.txt +++ b/Documentation/devicetree/bindings/arm/vt8500.txt | |||
@@ -12,3 +12,11 @@ compatible = "wm,wm8505"; | |||
12 | Boards with the Wondermedia WM8650 SoC shall have the following properties: | 12 | Boards with the Wondermedia WM8650 SoC shall have the following properties: |
13 | Required root node property: | 13 | Required root node property: |
14 | compatible = "wm,wm8650"; | 14 | compatible = "wm,wm8650"; |
15 | |||
16 | Boards with the Wondermedia WM8750 SoC shall have the following properties: | ||
17 | Required root node property: | ||
18 | compatible = "wm,wm8750"; | ||
19 | |||
20 | Boards with the Wondermedia WM8850 SoC shall have the following properties: | ||
21 | Required root node property: | ||
22 | compatible = "wm,wm8850"; | ||
diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.txt b/Documentation/devicetree/bindings/clock/imx31-clock.txt new file mode 100644 index 000000000000..19df842c694f --- /dev/null +++ b/Documentation/devicetree/bindings/clock/imx31-clock.txt | |||
@@ -0,0 +1,91 @@ | |||
1 | * Clock bindings for Freescale i.MX31 | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "fsl,imx31-ccm" | ||
5 | - reg: Address and length of the register set | ||
6 | - interrupts: Should contain CCM interrupt | ||
7 | - #clock-cells: Should be <1> | ||
8 | |||
9 | The clock consumer should specify the desired clock by having the clock | ||
10 | ID in its "clocks" phandle cell. The following is a full list of i.MX31 | ||
11 | clocks and IDs. | ||
12 | |||
13 | Clock ID | ||
14 | ----------------------- | ||
15 | dummy 0 | ||
16 | ckih 1 | ||
17 | ckil 2 | ||
18 | mpll 3 | ||
19 | spll 4 | ||
20 | upll 5 | ||
21 | mcu_main 6 | ||
22 | hsp 7 | ||
23 | ahb 8 | ||
24 | nfc 9 | ||
25 | ipg 10 | ||
26 | per_div 11 | ||
27 | per 12 | ||
28 | csi_sel 13 | ||
29 | fir_sel 14 | ||
30 | csi_div 15 | ||
31 | usb_div_pre 16 | ||
32 | usb_div_post 17 | ||
33 | fir_div_pre 18 | ||
34 | fir_div_post 19 | ||
35 | sdhc1_gate 20 | ||
36 | sdhc2_gate 21 | ||
37 | gpt_gate 22 | ||
38 | epit1_gate 23 | ||
39 | epit2_gate 24 | ||
40 | iim_gate 25 | ||
41 | ata_gate 26 | ||
42 | sdma_gate 27 | ||
43 | cspi3_gate 28 | ||
44 | rng_gate 29 | ||
45 | uart1_gate 30 | ||
46 | uart2_gate 31 | ||
47 | ssi1_gate 32 | ||
48 | i2c1_gate 33 | ||
49 | i2c2_gate 34 | ||
50 | i2c3_gate 35 | ||
51 | hantro_gate 36 | ||
52 | mstick1_gate 37 | ||
53 | mstick2_gate 38 | ||
54 | csi_gate 39 | ||
55 | rtc_gate 40 | ||
56 | wdog_gate 41 | ||
57 | pwm_gate 42 | ||
58 | sim_gate 43 | ||
59 | ect_gate 44 | ||
60 | usb_gate 45 | ||
61 | kpp_gate 46 | ||
62 | ipu_gate 47 | ||
63 | uart3_gate 48 | ||
64 | uart4_gate 49 | ||
65 | uart5_gate 50 | ||
66 | owire_gate 51 | ||
67 | ssi2_gate 52 | ||
68 | cspi1_gate 53 | ||
69 | cspi2_gate 54 | ||
70 | gacc_gate 55 | ||
71 | emi_gate 56 | ||
72 | rtic_gate 57 | ||
73 | firi_gate 58 | ||
74 | |||
75 | Examples: | ||
76 | |||
77 | clks: ccm@53f80000{ | ||
78 | compatible = "fsl,imx31-ccm"; | ||
79 | reg = <0x53f80000 0x4000>; | ||
80 | interrupts = <0 31 0x04 0 53 0x04>; | ||
81 | #clock-cells = <1>; | ||
82 | }; | ||
83 | |||
84 | uart1: serial@43f90000 { | ||
85 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; | ||
86 | reg = <0x43f90000 0x4000>; | ||
87 | interrupts = <45>; | ||
88 | clocks = <&clks 10>, <&clks 30>; | ||
89 | clock-names = "ipg", "per"; | ||
90 | status = "disabled"; | ||
91 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt new file mode 100644 index 000000000000..0921fac73528 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt | |||
@@ -0,0 +1,205 @@ | |||
1 | NVIDIA Tegra20 Clock And Reset Controller | ||
2 | |||
3 | This binding uses the common clock binding: | ||
4 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
5 | |||
6 | The CAR (Clock And Reset) Controller on Tegra is the HW module responsible | ||
7 | for muxing and gating Tegra's clocks, and setting their rates. | ||
8 | |||
9 | Required properties : | ||
10 | - compatible : Should be "nvidia,tegra20-car" | ||
11 | - reg : Should contain CAR registers location and length | ||
12 | - clocks : Should contain phandle and clock specifiers for two clocks: | ||
13 | the 32 KHz "32k_in", and the board-specific oscillator "osc". | ||
14 | - #clock-cells : Should be 1. | ||
15 | In clock consumers, this cell represents the clock ID exposed by the CAR. | ||
16 | |||
17 | The first 96 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB | ||
18 | registers. These IDs often match those in the CAR's RST_DEVICES registers, | ||
19 | but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In | ||
20 | this case, those clocks are assigned IDs above 95 in order to highlight | ||
21 | this issue. Implementations that interpret these clock IDs as bit values | ||
22 | within the CLK_OUT_ENB or RST_DEVICES registers should be careful to | ||
23 | explicitly handle these special cases. | ||
24 | |||
25 | The balance of the clocks controlled by the CAR are assigned IDs of 96 and | ||
26 | above. | ||
27 | |||
28 | 0 cpu | ||
29 | 1 unassigned | ||
30 | 2 unassigned | ||
31 | 3 ac97 | ||
32 | 4 rtc | ||
33 | 5 tmr | ||
34 | 6 uart1 | ||
35 | 7 unassigned (register bit affects uart2 and vfir) | ||
36 | 8 gpio | ||
37 | 9 sdmmc2 | ||
38 | 10 unassigned (register bit affects spdif_in and spdif_out) | ||
39 | 11 i2s1 | ||
40 | 12 i2c1 | ||
41 | 13 ndflash | ||
42 | 14 sdmmc1 | ||
43 | 15 sdmmc4 | ||
44 | 16 twc | ||
45 | 17 pwm | ||
46 | 18 i2s2 | ||
47 | 19 epp | ||
48 | 20 unassigned (register bit affects vi and vi_sensor) | ||
49 | 21 2d | ||
50 | 22 usbd | ||
51 | 23 isp | ||
52 | 24 3d | ||
53 | 25 ide | ||
54 | 26 disp2 | ||
55 | 27 disp1 | ||
56 | 28 host1x | ||
57 | 29 vcp | ||
58 | 30 unassigned | ||
59 | 31 cache2 | ||
60 | |||
61 | 32 mem | ||
62 | 33 ahbdma | ||
63 | 34 apbdma | ||
64 | 35 unassigned | ||
65 | 36 kbc | ||
66 | 37 stat_mon | ||
67 | 38 pmc | ||
68 | 39 fuse | ||
69 | 40 kfuse | ||
70 | 41 sbc1 | ||
71 | 42 snor | ||
72 | 43 spi1 | ||
73 | 44 sbc2 | ||
74 | 45 xio | ||
75 | 46 sbc3 | ||
76 | 47 dvc | ||
77 | 48 dsi | ||
78 | 49 unassigned (register bit affects tvo and cve) | ||
79 | 50 mipi | ||
80 | 51 hdmi | ||
81 | 52 csi | ||
82 | 53 tvdac | ||
83 | 54 i2c2 | ||
84 | 55 uart3 | ||
85 | 56 unassigned | ||
86 | 57 emc | ||
87 | 58 usb2 | ||
88 | 59 usb3 | ||
89 | 60 mpe | ||
90 | 61 vde | ||
91 | 62 bsea | ||
92 | 63 bsev | ||
93 | |||
94 | 64 speedo | ||
95 | 65 uart4 | ||
96 | 66 uart5 | ||
97 | 67 i2c3 | ||
98 | 68 sbc4 | ||
99 | 69 sdmmc3 | ||
100 | 70 pcie | ||
101 | 71 owr | ||
102 | 72 afi | ||
103 | 73 csite | ||
104 | 74 unassigned | ||
105 | 75 avpucq | ||
106 | 76 la | ||
107 | 77 unassigned | ||
108 | 78 unassigned | ||
109 | 79 unassigned | ||
110 | 80 unassigned | ||
111 | 81 unassigned | ||
112 | 82 unassigned | ||
113 | 83 unassigned | ||
114 | 84 irama | ||
115 | 85 iramb | ||
116 | 86 iramc | ||
117 | 87 iramd | ||
118 | 88 cram2 | ||
119 | 89 audio_2x a/k/a audio_2x_sync_clk | ||
120 | 90 clk_d | ||
121 | 91 unassigned | ||
122 | 92 sus | ||
123 | 93 cdev1 | ||
124 | 94 cdev2 | ||
125 | 95 unassigned | ||
126 | |||
127 | 96 uart2 | ||
128 | 97 vfir | ||
129 | 98 spdif_in | ||
130 | 99 spdif_out | ||
131 | 100 vi | ||
132 | 101 vi_sensor | ||
133 | 102 tvo | ||
134 | 103 cve | ||
135 | 104 osc | ||
136 | 105 clk_32k a/k/a clk_s | ||
137 | 106 clk_m | ||
138 | 107 sclk | ||
139 | 108 cclk | ||
140 | 109 hclk | ||
141 | 110 pclk | ||
142 | 111 blink | ||
143 | 112 pll_a | ||
144 | 113 pll_a_out0 | ||
145 | 114 pll_c | ||
146 | 115 pll_c_out1 | ||
147 | 116 pll_d | ||
148 | 117 pll_d_out0 | ||
149 | 118 pll_e | ||
150 | 119 pll_m | ||
151 | 120 pll_m_out1 | ||
152 | 121 pll_p | ||
153 | 122 pll_p_out1 | ||
154 | 123 pll_p_out2 | ||
155 | 124 pll_p_out3 | ||
156 | 125 pll_p_out4 | ||
157 | 126 pll_s | ||
158 | 127 pll_u | ||
159 | 128 pll_x | ||
160 | 129 cop a/k/a avp | ||
161 | 130 audio a/k/a audio_sync_clk | ||
162 | 131 pll_ref | ||
163 | 132 twd | ||
164 | |||
165 | Example SoC include file: | ||
166 | |||
167 | / { | ||
168 | tegra_car: clock { | ||
169 | compatible = "nvidia,tegra20-car"; | ||
170 | reg = <0x60006000 0x1000>; | ||
171 | #clock-cells = <1>; | ||
172 | }; | ||
173 | |||
174 | usb@c5004000 { | ||
175 | clocks = <&tegra_car 58>; /* usb2 */ | ||
176 | }; | ||
177 | }; | ||
178 | |||
179 | Example board file: | ||
180 | |||
181 | / { | ||
182 | clocks { | ||
183 | compatible = "simple-bus"; | ||
184 | #address-cells = <1>; | ||
185 | #size-cells = <0>; | ||
186 | |||
187 | osc: clock@0 { | ||
188 | compatible = "fixed-clock"; | ||
189 | reg = <0>; | ||
190 | #clock-cells = <0>; | ||
191 | clock-frequency = <12000000>; | ||
192 | }; | ||
193 | |||
194 | clk_32k: clock@1 { | ||
195 | compatible = "fixed-clock"; | ||
196 | reg = <1>; | ||
197 | #clock-cells = <0>; | ||
198 | clock-frequency = <32768>; | ||
199 | }; | ||
200 | }; | ||
201 | |||
202 | &tegra_car { | ||
203 | clocks = <&clk_32k> <&osc>; | ||
204 | }; | ||
205 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt new file mode 100644 index 000000000000..f3da3be5fcad --- /dev/null +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt | |||
@@ -0,0 +1,262 @@ | |||
1 | NVIDIA Tegra30 Clock And Reset Controller | ||
2 | |||
3 | This binding uses the common clock binding: | ||
4 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
5 | |||
6 | The CAR (Clock And Reset) Controller on Tegra is the HW module responsible | ||
7 | for muxing and gating Tegra's clocks, and setting their rates. | ||
8 | |||
9 | Required properties : | ||
10 | - compatible : Should be "nvidia,tegra30-car" | ||
11 | - reg : Should contain CAR registers location and length | ||
12 | - clocks : Should contain phandle and clock specifiers for two clocks: | ||
13 | the 32 KHz "32k_in", and the board-specific oscillator "osc". | ||
14 | - #clock-cells : Should be 1. | ||
15 | In clock consumers, this cell represents the clock ID exposed by the CAR. | ||
16 | |||
17 | The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB | ||
18 | registers. These IDs often match those in the CAR's RST_DEVICES registers, | ||
19 | but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In | ||
20 | this case, those clocks are assigned IDs above 160 in order to highlight | ||
21 | this issue. Implementations that interpret these clock IDs as bit values | ||
22 | within the CLK_OUT_ENB or RST_DEVICES registers should be careful to | ||
23 | explicitly handle these special cases. | ||
24 | |||
25 | The balance of the clocks controlled by the CAR are assigned IDs of 160 and | ||
26 | above. | ||
27 | |||
28 | 0 cpu | ||
29 | 1 unassigned | ||
30 | 2 unassigned | ||
31 | 3 unassigned | ||
32 | 4 rtc | ||
33 | 5 timer | ||
34 | 6 uarta | ||
35 | 7 unassigned (register bit affects uartb and vfir) | ||
36 | 8 gpio | ||
37 | 9 sdmmc2 | ||
38 | 10 unassigned (register bit affects spdif_in and spdif_out) | ||
39 | 11 i2s1 | ||
40 | 12 i2c1 | ||
41 | 13 ndflash | ||
42 | 14 sdmmc1 | ||
43 | 15 sdmmc4 | ||
44 | 16 unassigned | ||
45 | 17 pwm | ||
46 | 18 i2s2 | ||
47 | 19 epp | ||
48 | 20 unassigned (register bit affects vi and vi_sensor) | ||
49 | 21 2d | ||
50 | 22 usbd | ||
51 | 23 isp | ||
52 | 24 3d | ||
53 | 25 unassigned | ||
54 | 26 disp2 | ||
55 | 27 disp1 | ||
56 | 28 host1x | ||
57 | 29 vcp | ||
58 | 30 i2s0 | ||
59 | 31 cop_cache | ||
60 | |||
61 | 32 mc | ||
62 | 33 ahbdma | ||
63 | 34 apbdma | ||
64 | 35 unassigned | ||
65 | 36 kbc | ||
66 | 37 statmon | ||
67 | 38 pmc | ||
68 | 39 unassigned (register bit affects fuse and fuse_burn) | ||
69 | 40 kfuse | ||
70 | 41 sbc1 | ||
71 | 42 nor | ||
72 | 43 unassigned | ||
73 | 44 sbc2 | ||
74 | 45 unassigned | ||
75 | 46 sbc3 | ||
76 | 47 i2c5 | ||
77 | 48 dsia | ||
78 | 49 unassigned (register bit affects cve and tvo) | ||
79 | 50 mipi | ||
80 | 51 hdmi | ||
81 | 52 csi | ||
82 | 53 tvdac | ||
83 | 54 i2c2 | ||
84 | 55 uartc | ||
85 | 56 unassigned | ||
86 | 57 emc | ||
87 | 58 usb2 | ||
88 | 59 usb3 | ||
89 | 60 mpe | ||
90 | 61 vde | ||
91 | 62 bsea | ||
92 | 63 bsev | ||
93 | |||
94 | 64 speedo | ||
95 | 65 uartd | ||
96 | 66 uarte | ||
97 | 67 i2c3 | ||
98 | 68 sbc4 | ||
99 | 69 sdmmc3 | ||
100 | 70 pcie | ||
101 | 71 owr | ||
102 | 72 afi | ||
103 | 73 csite | ||
104 | 74 pciex | ||
105 | 75 avpucq | ||
106 | 76 la | ||
107 | 77 unassigned | ||
108 | 78 unassigned | ||
109 | 79 dtv | ||
110 | 80 ndspeed | ||
111 | 81 i2cslow | ||
112 | 82 dsib | ||
113 | 83 unassigned | ||
114 | 84 irama | ||
115 | 85 iramb | ||
116 | 86 iramc | ||
117 | 87 iramd | ||
118 | 88 cram2 | ||
119 | 89 unassigned | ||
120 | 90 audio_2x a/k/a audio_2x_sync_clk | ||
121 | 91 unassigned | ||
122 | 92 csus | ||
123 | 93 cdev2 | ||
124 | 94 cdev1 | ||
125 | 95 unassigned | ||
126 | |||
127 | 96 cpu_g | ||
128 | 97 cpu_lp | ||
129 | 98 3d2 | ||
130 | 99 mselect | ||
131 | 100 tsensor | ||
132 | 101 i2s3 | ||
133 | 102 i2s4 | ||
134 | 103 i2c4 | ||
135 | 104 sbc5 | ||
136 | 105 sbc6 | ||
137 | 106 d_audio | ||
138 | 107 apbif | ||
139 | 108 dam0 | ||
140 | 109 dam1 | ||
141 | 110 dam2 | ||
142 | 111 hda2codec_2x | ||
143 | 112 atomics | ||
144 | 113 audio0_2x | ||
145 | 114 audio1_2x | ||
146 | 115 audio2_2x | ||
147 | 116 audio3_2x | ||
148 | 117 audio4_2x | ||
149 | 118 audio5_2x | ||
150 | 119 actmon | ||
151 | 120 extern1 | ||
152 | 121 extern2 | ||
153 | 122 extern3 | ||
154 | 123 sata_oob | ||
155 | 124 sata | ||
156 | 125 hda | ||
157 | 127 se | ||
158 | 128 hda2hdmi | ||
159 | 129 sata_cold | ||
160 | |||
161 | 160 uartb | ||
162 | 161 vfir | ||
163 | 162 spdif_in | ||
164 | 163 spdif_out | ||
165 | 164 vi | ||
166 | 165 vi_sensor | ||
167 | 166 fuse | ||
168 | 167 fuse_burn | ||
169 | 168 cve | ||
170 | 169 tvo | ||
171 | |||
172 | 170 clk_32k | ||
173 | 171 clk_m | ||
174 | 172 clk_m_div2 | ||
175 | 173 clk_m_div4 | ||
176 | 174 pll_ref | ||
177 | 175 pll_c | ||
178 | 176 pll_c_out1 | ||
179 | 177 pll_m | ||
180 | 178 pll_m_out1 | ||
181 | 179 pll_p | ||
182 | 180 pll_p_out1 | ||
183 | 181 pll_p_out2 | ||
184 | 182 pll_p_out3 | ||
185 | 183 pll_p_out4 | ||
186 | 184 pll_a | ||
187 | 185 pll_a_out0 | ||
188 | 186 pll_d | ||
189 | 187 pll_d_out0 | ||
190 | 188 pll_d2 | ||
191 | 189 pll_d2_out0 | ||
192 | 190 pll_u | ||
193 | 191 pll_x | ||
194 | 192 pll_x_out0 | ||
195 | 193 pll_e | ||
196 | 194 spdif_in_sync | ||
197 | 195 i2s0_sync | ||
198 | 196 i2s1_sync | ||
199 | 197 i2s2_sync | ||
200 | 198 i2s3_sync | ||
201 | 199 i2s4_sync | ||
202 | 200 vimclk | ||
203 | 201 audio0 | ||
204 | 202 audio1 | ||
205 | 203 audio2 | ||
206 | 204 audio3 | ||
207 | 205 audio4 | ||
208 | 206 audio5 | ||
209 | 207 clk_out_1 (extern1) | ||
210 | 208 clk_out_2 (extern2) | ||
211 | 209 clk_out_3 (extern3) | ||
212 | 210 sclk | ||
213 | 211 blink | ||
214 | 212 cclk_g | ||
215 | 213 cclk_lp | ||
216 | 214 twd | ||
217 | 215 cml0 | ||
218 | 216 cml1 | ||
219 | 217 hclk | ||
220 | 218 pclk | ||
221 | |||
222 | Example SoC include file: | ||
223 | |||
224 | / { | ||
225 | tegra_car: clock { | ||
226 | compatible = "nvidia,tegra30-car"; | ||
227 | reg = <0x60006000 0x1000>; | ||
228 | #clock-cells = <1>; | ||
229 | }; | ||
230 | |||
231 | usb@c5004000 { | ||
232 | clocks = <&tegra_car 58>; /* usb2 */ | ||
233 | }; | ||
234 | }; | ||
235 | |||
236 | Example board file: | ||
237 | |||
238 | / { | ||
239 | clocks { | ||
240 | compatible = "simple-bus"; | ||
241 | #address-cells = <1>; | ||
242 | #size-cells = <0>; | ||
243 | |||
244 | osc: clock@0 { | ||
245 | compatible = "fixed-clock"; | ||
246 | reg = <0>; | ||
247 | #clock-cells = <0>; | ||
248 | clock-frequency = <12000000>; | ||
249 | }; | ||
250 | |||
251 | clk_32k: clock@1 { | ||
252 | compatible = "fixed-clock"; | ||
253 | reg = <1>; | ||
254 | #clock-cells = <0>; | ||
255 | clock-frequency = <32768>; | ||
256 | }; | ||
257 | }; | ||
258 | |||
259 | &tegra_car { | ||
260 | clocks = <&clk_32k> <&osc>; | ||
261 | }; | ||
262 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt index e9b005dc7625..34c952883276 100644 --- a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt | |||
@@ -11,6 +11,7 @@ Required properties : | |||
11 | - phy_type : Should be one of "ulpi" or "utmi". | 11 | - phy_type : Should be one of "ulpi" or "utmi". |
12 | - nvidia,vbus-gpio : If present, specifies a gpio that needs to be | 12 | - nvidia,vbus-gpio : If present, specifies a gpio that needs to be |
13 | activated for the bus to be powered. | 13 | activated for the bus to be powered. |
14 | - nvidia,phy : phandle of the PHY instance, the controller is connected to. | ||
14 | 15 | ||
15 | Required properties for phy_type == ulpi: | 16 | Required properties for phy_type == ulpi: |
16 | - nvidia,phy-reset-gpio : The GPIO used to reset the PHY. | 17 | - nvidia,phy-reset-gpio : The GPIO used to reset the PHY. |
@@ -27,3 +28,5 @@ Optional properties: | |||
27 | registers are accessed through the APB_MISC base address instead of | 28 | registers are accessed through the APB_MISC base address instead of |
28 | the USB controller. Since this is a legacy issue it probably does not | 29 | the USB controller. Since this is a legacy issue it probably does not |
29 | warrant a compatible string of its own. | 30 | warrant a compatible string of its own. |
31 | - nvidia,needs-double-reset : boolean is to be set for some of the Tegra2 | ||
32 | USB ports, which need reset twice due to hardware issues. | ||
diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt b/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt new file mode 100644 index 000000000000..6bdaba2f0aa1 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | Tegra SOC USB PHY | ||
2 | |||
3 | The device node for Tegra SOC USB PHY: | ||
4 | |||
5 | Required properties : | ||
6 | - compatible : Should be "nvidia,tegra20-usb-phy". | ||
7 | - reg : Address and length of the register set for the USB PHY interface. | ||
8 | - phy_type : Should be one of "ulpi" or "utmi". | ||
9 | |||
10 | Required properties for phy_type == ulpi: | ||
11 | - nvidia,phy-reset-gpio : The GPIO used to reset the PHY. | ||
12 | |||
13 | Optional properties: | ||
14 | - nvidia,has-legacy-mode : boolean indicates whether this controller can | ||
15 | operate in legacy mode (as APX 2500 / 2600). In legacy mode some | ||
16 | registers are accessed through the APB_MISC base address instead of | ||
17 | the USB controller. \ No newline at end of file | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bfd7c69c85a5..2c370c869beb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -393,6 +393,7 @@ config ARCH_GEMINI | |||
393 | config ARCH_SIRF | 393 | config ARCH_SIRF |
394 | bool "CSR SiRF" | 394 | bool "CSR SiRF" |
395 | select ARCH_REQUIRE_GPIOLIB | 395 | select ARCH_REQUIRE_GPIOLIB |
396 | select AUTO_ZRELADDR | ||
396 | select COMMON_CLK | 397 | select COMMON_CLK |
397 | select GENERIC_CLOCKEVENTS | 398 | select GENERIC_CLOCKEVENTS |
398 | select GENERIC_IRQ_CHIP | 399 | select GENERIC_IRQ_CHIP |
@@ -640,6 +641,7 @@ config ARCH_LPC32XX | |||
640 | config ARCH_TEGRA | 641 | config ARCH_TEGRA |
641 | bool "NVIDIA Tegra" | 642 | bool "NVIDIA Tegra" |
642 | select ARCH_HAS_CPUFREQ | 643 | select ARCH_HAS_CPUFREQ |
644 | select ARCH_REQUIRE_GPIOLIB | ||
643 | select CLKDEV_LOOKUP | 645 | select CLKDEV_LOOKUP |
644 | select CLKSRC_MMIO | 646 | select CLKSRC_MMIO |
645 | select CLKSRC_OF | 647 | select CLKSRC_OF |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 5f0cdf28c227..acddddac7ee4 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -205,12 +205,19 @@ choice | |||
205 | Say Y here if you want kernel low-level debugging support | 205 | Say Y here if you want kernel low-level debugging support |
206 | on i.MX28. | 206 | on i.MX28. |
207 | 207 | ||
208 | config DEBUG_IMX31_IMX35_UART | 208 | config DEBUG_IMX31_UART |
209 | bool "i.MX31 and i.MX35 Debug UART" | 209 | bool "i.MX31 Debug UART" |
210 | depends on SOC_IMX31 || SOC_IMX35 | 210 | depends on SOC_IMX31 |
211 | help | 211 | help |
212 | Say Y here if you want kernel low-level debugging support | 212 | Say Y here if you want kernel low-level debugging support |
213 | on i.MX31 or i.MX35. | 213 | on i.MX31. |
214 | |||
215 | config DEBUG_IMX35_UART | ||
216 | bool "i.MX35 Debug UART" | ||
217 | depends on SOC_IMX35 | ||
218 | help | ||
219 | Say Y here if you want kernel low-level debugging support | ||
220 | on i.MX35. | ||
214 | 221 | ||
215 | config DEBUG_IMX51_UART | 222 | config DEBUG_IMX51_UART |
216 | bool "i.MX51 Debug UART" | 223 | bool "i.MX51 Debug UART" |
@@ -393,6 +400,20 @@ choice | |||
393 | Say Y here if you want kernel low-level debugging support | 400 | Say Y here if you want kernel low-level debugging support |
394 | on Tegra based platforms. | 401 | on Tegra based platforms. |
395 | 402 | ||
403 | config DEBUG_SIRFPRIMA2_UART1 | ||
404 | bool "Kernel low-level debugging messages via SiRFprimaII UART1" | ||
405 | depends on ARCH_PRIMA2 | ||
406 | help | ||
407 | Say Y here if you want the debug print routines to direct | ||
408 | their output to the uart1 port on SiRFprimaII devices. | ||
409 | |||
410 | config DEBUG_SIRFMARCO_UART1 | ||
411 | bool "Kernel low-level debugging messages via SiRFmarco UART1" | ||
412 | depends on ARCH_MARCO | ||
413 | help | ||
414 | Say Y here if you want the debug print routines to direct | ||
415 | their output to the uart1 port on SiRFmarco devices. | ||
416 | |||
396 | config DEBUG_VEXPRESS_UART0_DETECT | 417 | config DEBUG_VEXPRESS_UART0_DETECT |
397 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" | 418 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" |
398 | depends on ARCH_VEXPRESS && CPU_CP15_MMU | 419 | depends on ARCH_VEXPRESS && CPU_CP15_MMU |
@@ -464,11 +485,16 @@ choice | |||
464 | 485 | ||
465 | endchoice | 486 | endchoice |
466 | 487 | ||
467 | config DEBUG_IMX6Q_UART_PORT | 488 | config DEBUG_IMX_UART_PORT |
468 | int "i.MX6Q Debug UART Port (1-5)" if DEBUG_IMX6Q_UART | 489 | int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \ |
469 | range 1 5 | 490 | DEBUG_IMX25_UART || \ |
491 | DEBUG_IMX21_IMX27_UART || \ | ||
492 | DEBUG_IMX31_UART || \ | ||
493 | DEBUG_IMX35_UART || \ | ||
494 | DEBUG_IMX51_UART || \ | ||
495 | DEBUG_IMX50_IMX53_UART || \ | ||
496 | DEBUG_IMX6Q_UART | ||
470 | default 1 | 497 | default 1 |
471 | depends on SOC_IMX6Q | ||
472 | help | 498 | help |
473 | Choose UART port on which kernel low-level debug messages | 499 | Choose UART port on which kernel low-level debug messages |
474 | should be output. | 500 | should be output. |
@@ -557,7 +583,8 @@ config DEBUG_LL_INCLUDE | |||
557 | default "debug/imx.S" if DEBUG_IMX1_UART || \ | 583 | default "debug/imx.S" if DEBUG_IMX1_UART || \ |
558 | DEBUG_IMX25_UART || \ | 584 | DEBUG_IMX25_UART || \ |
559 | DEBUG_IMX21_IMX27_UART || \ | 585 | DEBUG_IMX21_IMX27_UART || \ |
560 | DEBUG_IMX31_IMX35_UART || \ | 586 | DEBUG_IMX31_UART || \ |
587 | DEBUG_IMX35_UART || \ | ||
561 | DEBUG_IMX51_UART || \ | 588 | DEBUG_IMX51_UART || \ |
562 | DEBUG_IMX53_UART ||\ | 589 | DEBUG_IMX53_UART ||\ |
563 | DEBUG_IMX6Q_UART | 590 | DEBUG_IMX6Q_UART |
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 5ebb44fe826a..042f2111485b 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile | |||
@@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \ | |||
73 | kirkwood-ts219-6281.dtb \ | 73 | kirkwood-ts219-6281.dtb \ |
74 | kirkwood-ts219-6282.dtb \ | 74 | kirkwood-ts219-6282.dtb \ |
75 | kirkwood-openblocks_a6.dtb | 75 | kirkwood-openblocks_a6.dtb |
76 | dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb | ||
76 | dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ | 77 | dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ |
77 | msm8960-cdp.dtb | 78 | msm8960-cdp.dtb |
78 | dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ | 79 | dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ |
@@ -124,6 +125,8 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ | |||
124 | r8a7740-armadillo800eva.dtb \ | 125 | r8a7740-armadillo800eva.dtb \ |
125 | sh73a0-kzm9g.dtb \ | 126 | sh73a0-kzm9g.dtb \ |
126 | sh7372-mackerel.dtb | 127 | sh7372-mackerel.dtb |
128 | dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \ | ||
129 | socfpga_vt.dtb | ||
127 | dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \ | 130 | dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \ |
128 | spear1340-evb.dtb | 131 | spear1340-evb.dtb |
129 | dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ | 132 | dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ |
@@ -143,7 +146,9 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ | |||
143 | tegra20-ventana.dtb \ | 146 | tegra20-ventana.dtb \ |
144 | tegra20-whistler.dtb \ | 147 | tegra20-whistler.dtb \ |
145 | tegra30-cardhu-a02.dtb \ | 148 | tegra30-cardhu-a02.dtb \ |
146 | tegra30-cardhu-a04.dtb | 149 | tegra30-cardhu-a04.dtb \ |
150 | tegra114-dalmore.dtb \ | ||
151 | tegra114-pluto.dtb | ||
147 | dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ | 152 | dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ |
148 | vexpress-v2p-ca9.dtb \ | 153 | vexpress-v2p-ca9.dtb \ |
149 | vexpress-v2p-ca15-tc1.dtb \ | 154 | vexpress-v2p-ca15-tc1.dtb \ |
@@ -151,7 +156,8 @@ dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ | |||
151 | xenvm-4.2.dtb | 156 | xenvm-4.2.dtb |
152 | dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ | 157 | dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ |
153 | wm8505-ref.dtb \ | 158 | wm8505-ref.dtb \ |
154 | wm8650-mid.dtb | 159 | wm8650-mid.dtb \ |
160 | wm8850-w70v2.dtb | ||
155 | dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb | 161 | dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb |
156 | 162 | ||
157 | targets += dtbs | 163 | targets += dtbs |
diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index eb504a6c0f4a..c8a8c08b48dd 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi | |||
@@ -15,11 +15,18 @@ | |||
15 | interrupt-parent = <&gic>; | 15 | interrupt-parent = <&gic>; |
16 | 16 | ||
17 | cpus { | 17 | cpus { |
18 | #address-cells = <1>; | ||
19 | #size-cells = <0>; | ||
20 | |||
18 | cpu@0 { | 21 | cpu@0 { |
22 | device_type = "cpu"; | ||
19 | compatible = "arm,cortex-a9"; | 23 | compatible = "arm,cortex-a9"; |
24 | reg = <0>; | ||
20 | }; | 25 | }; |
21 | cpu@1 { | 26 | cpu@1 { |
27 | device_type = "cpu"; | ||
22 | compatible = "arm,cortex-a9"; | 28 | compatible = "arm,cortex-a9"; |
29 | reg = <1>; | ||
23 | }; | 30 | }; |
24 | }; | 31 | }; |
25 | 32 | ||
diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi index eef7099f3e3c..454c2d175402 100644 --- a/arch/arm/boot/dts/imx31.dtsi +++ b/arch/arm/boot/dts/imx31.dtsi | |||
@@ -45,6 +45,8 @@ | |||
45 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; | 45 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; |
46 | reg = <0x43f90000 0x4000>; | 46 | reg = <0x43f90000 0x4000>; |
47 | interrupts = <45>; | 47 | interrupts = <45>; |
48 | clocks = <&clks 10>, <&clks 30>; | ||
49 | clock-names = "ipg", "per"; | ||
48 | status = "disabled"; | 50 | status = "disabled"; |
49 | }; | 51 | }; |
50 | 52 | ||
@@ -52,12 +54,16 @@ | |||
52 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; | 54 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; |
53 | reg = <0x43f94000 0x4000>; | 55 | reg = <0x43f94000 0x4000>; |
54 | interrupts = <32>; | 56 | interrupts = <32>; |
57 | clocks = <&clks 10>, <&clks 31>; | ||
58 | clock-names = "ipg", "per"; | ||
55 | status = "disabled"; | 59 | status = "disabled"; |
56 | }; | 60 | }; |
57 | 61 | ||
58 | uart4: serial@43fb0000 { | 62 | uart4: serial@43fb0000 { |
59 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; | 63 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; |
60 | reg = <0x43fb0000 0x4000>; | 64 | reg = <0x43fb0000 0x4000>; |
65 | clocks = <&clks 10>, <&clks 49>; | ||
66 | clock-names = "ipg", "per"; | ||
61 | interrupts = <46>; | 67 | interrupts = <46>; |
62 | status = "disabled"; | 68 | status = "disabled"; |
63 | }; | 69 | }; |
@@ -66,6 +72,8 @@ | |||
66 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; | 72 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; |
67 | reg = <0x43fb4000 0x4000>; | 73 | reg = <0x43fb4000 0x4000>; |
68 | interrupts = <47>; | 74 | interrupts = <47>; |
75 | clocks = <&clks 10>, <&clks 50>; | ||
76 | clock-names = "ipg", "per"; | ||
69 | status = "disabled"; | 77 | status = "disabled"; |
70 | }; | 78 | }; |
71 | }; | 79 | }; |
@@ -81,8 +89,17 @@ | |||
81 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; | 89 | compatible = "fsl,imx31-uart", "fsl,imx21-uart"; |
82 | reg = <0x5000c000 0x4000>; | 90 | reg = <0x5000c000 0x4000>; |
83 | interrupts = <18>; | 91 | interrupts = <18>; |
92 | clocks = <&clks 10>, <&clks 48>; | ||
93 | clock-names = "ipg", "per"; | ||
84 | status = "disabled"; | 94 | status = "disabled"; |
85 | }; | 95 | }; |
96 | |||
97 | clks: ccm@53f80000{ | ||
98 | compatible = "fsl,imx31-ccm"; | ||
99 | reg = <0x53f80000 0x4000>; | ||
100 | interrupts = <0 31 0x04 0 53 0x04>; | ||
101 | #clock-cells = <1>; | ||
102 | }; | ||
86 | }; | 103 | }; |
87 | }; | 104 | }; |
88 | }; | 105 | }; |
diff --git a/arch/arm/boot/dts/marco-evb.dts b/arch/arm/boot/dts/marco-evb.dts new file mode 100644 index 000000000000..5130aeacfca5 --- /dev/null +++ b/arch/arm/boot/dts/marco-evb.dts | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * DTS file for CSR SiRFmarco Evaluation Board | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | /dts-v1/; | ||
10 | |||
11 | /include/ "marco.dtsi" | ||
12 | |||
13 | / { | ||
14 | model = "CSR SiRFmarco Evaluation Board"; | ||
15 | compatible = "sirf,marco-cb", "sirf,marco"; | ||
16 | |||
17 | memory { | ||
18 | reg = <0x40000000 0x60000000>; | ||
19 | }; | ||
20 | |||
21 | axi { | ||
22 | peri-iobg { | ||
23 | uart1: uart@cc060000 { | ||
24 | status = "okay"; | ||
25 | }; | ||
26 | uart2: uart@cc070000 { | ||
27 | status = "okay"; | ||
28 | }; | ||
29 | i2c0: i2c@cc0e0000 { | ||
30 | status = "okay"; | ||
31 | fpga-cpld@4d { | ||
32 | compatible = "sirf,fpga-cpld"; | ||
33 | reg = <0x4d>; | ||
34 | }; | ||
35 | }; | ||
36 | spi1: spi@cc170000 { | ||
37 | status = "okay"; | ||
38 | pinctrl-names = "default"; | ||
39 | pinctrl-0 = <&spi1_pins_a>; | ||
40 | spi@0 { | ||
41 | compatible = "spidev"; | ||
42 | reg = <0>; | ||
43 | spi-max-frequency = <1000000>; | ||
44 | }; | ||
45 | }; | ||
46 | pci-iobg { | ||
47 | sd0: sdhci@cd000000 { | ||
48 | bus-width = <8>; | ||
49 | status = "okay"; | ||
50 | }; | ||
51 | }; | ||
52 | }; | ||
53 | }; | ||
54 | }; | ||
diff --git a/arch/arm/boot/dts/marco.dtsi b/arch/arm/boot/dts/marco.dtsi new file mode 100644 index 000000000000..1579c3491ccd --- /dev/null +++ b/arch/arm/boot/dts/marco.dtsi | |||
@@ -0,0 +1,756 @@ | |||
1 | /* | ||
2 | * DTS file for CSR SiRFmarco SoC | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | /include/ "skeleton.dtsi" | ||
10 | / { | ||
11 | compatible = "sirf,marco"; | ||
12 | #address-cells = <1>; | ||
13 | #size-cells = <1>; | ||
14 | interrupt-parent = <&gic>; | ||
15 | |||
16 | cpus { | ||
17 | #address-cells = <1>; | ||
18 | #size-cells = <0>; | ||
19 | |||
20 | cpu@0 { | ||
21 | device_type = "cpu"; | ||
22 | compatible = "arm,cortex-a9"; | ||
23 | reg = <0>; | ||
24 | }; | ||
25 | cpu@1 { | ||
26 | device_type = "cpu"; | ||
27 | compatible = "arm,cortex-a9"; | ||
28 | reg = <1>; | ||
29 | }; | ||
30 | }; | ||
31 | |||
32 | axi { | ||
33 | compatible = "simple-bus"; | ||
34 | #address-cells = <1>; | ||
35 | #size-cells = <1>; | ||
36 | ranges = <0x40000000 0x40000000 0xa0000000>; | ||
37 | |||
38 | l2-cache-controller@c0030000 { | ||
39 | compatible = "sirf,marco-pl310-cache", "arm,pl310-cache"; | ||
40 | reg = <0xc0030000 0x1000>; | ||
41 | interrupts = <0 59 0>; | ||
42 | arm,tag-latency = <1 1 1>; | ||
43 | arm,data-latency = <1 1 1>; | ||
44 | arm,filter-ranges = <0x40000000 0x80000000>; | ||
45 | }; | ||
46 | |||
47 | gic: interrupt-controller@c0011000 { | ||
48 | compatible = "arm,cortex-a9-gic"; | ||
49 | interrupt-controller; | ||
50 | #interrupt-cells = <3>; | ||
51 | reg = <0xc0011000 0x1000>, | ||
52 | <0xc0010100 0x0100>; | ||
53 | }; | ||
54 | |||
55 | rstc-iobg { | ||
56 | compatible = "simple-bus"; | ||
57 | #address-cells = <1>; | ||
58 | #size-cells = <1>; | ||
59 | ranges = <0xc2000000 0xc2000000 0x1000000>; | ||
60 | |||
61 | reset-controller@c2000000 { | ||
62 | compatible = "sirf,marco-rstc"; | ||
63 | reg = <0xc2000000 0x10000>; | ||
64 | }; | ||
65 | }; | ||
66 | |||
67 | sys-iobg { | ||
68 | compatible = "simple-bus"; | ||
69 | #address-cells = <1>; | ||
70 | #size-cells = <1>; | ||
71 | ranges = <0xc3000000 0xc3000000 0x1000000>; | ||
72 | |||
73 | clock-controller@c3000000 { | ||
74 | compatible = "sirf,marco-clkc"; | ||
75 | reg = <0xc3000000 0x1000>; | ||
76 | interrupts = <0 3 0>; | ||
77 | }; | ||
78 | |||
79 | rsc-controller@c3010000 { | ||
80 | compatible = "sirf,marco-rsc"; | ||
81 | reg = <0xc3010000 0x1000>; | ||
82 | }; | ||
83 | }; | ||
84 | |||
85 | mem-iobg { | ||
86 | compatible = "simple-bus"; | ||
87 | #address-cells = <1>; | ||
88 | #size-cells = <1>; | ||
89 | ranges = <0xc4000000 0xc4000000 0x1000000>; | ||
90 | |||
91 | memory-controller@c4000000 { | ||
92 | compatible = "sirf,marco-memc"; | ||
93 | reg = <0xc4000000 0x10000>; | ||
94 | interrupts = <0 27 0>; | ||
95 | }; | ||
96 | }; | ||
97 | |||
98 | disp-iobg0 { | ||
99 | compatible = "simple-bus"; | ||
100 | #address-cells = <1>; | ||
101 | #size-cells = <1>; | ||
102 | ranges = <0xc5000000 0xc5000000 0x1000000>; | ||
103 | |||
104 | display0@c5000000 { | ||
105 | compatible = "sirf,marco-lcd"; | ||
106 | reg = <0xc5000000 0x10000>; | ||
107 | interrupts = <0 30 0>; | ||
108 | }; | ||
109 | |||
110 | vpp0@c5010000 { | ||
111 | compatible = "sirf,marco-vpp"; | ||
112 | reg = <0xc5010000 0x10000>; | ||
113 | interrupts = <0 31 0>; | ||
114 | }; | ||
115 | }; | ||
116 | |||
117 | disp-iobg1 { | ||
118 | compatible = "simple-bus"; | ||
119 | #address-cells = <1>; | ||
120 | #size-cells = <1>; | ||
121 | ranges = <0xc6000000 0xc6000000 0x1000000>; | ||
122 | |||
123 | display1@c6000000 { | ||
124 | compatible = "sirf,marco-lcd"; | ||
125 | reg = <0xc6000000 0x10000>; | ||
126 | interrupts = <0 62 0>; | ||
127 | }; | ||
128 | |||
129 | vpp1@c6010000 { | ||
130 | compatible = "sirf,marco-vpp"; | ||
131 | reg = <0xc6010000 0x10000>; | ||
132 | interrupts = <0 63 0>; | ||
133 | }; | ||
134 | }; | ||
135 | |||
136 | graphics-iobg { | ||
137 | compatible = "simple-bus"; | ||
138 | #address-cells = <1>; | ||
139 | #size-cells = <1>; | ||
140 | ranges = <0xc8000000 0xc8000000 0x1000000>; | ||
141 | |||
142 | graphics@c8000000 { | ||
143 | compatible = "powervr,sgx540"; | ||
144 | reg = <0xc8000000 0x1000000>; | ||
145 | interrupts = <0 6 0>; | ||
146 | }; | ||
147 | }; | ||
148 | |||
149 | multimedia-iobg { | ||
150 | compatible = "simple-bus"; | ||
151 | #address-cells = <1>; | ||
152 | #size-cells = <1>; | ||
153 | ranges = <0xc9000000 0xc9000000 0x1000000>; | ||
154 | |||
155 | multimedia@a0000000 { | ||
156 | compatible = "sirf,marco-video-codec"; | ||
157 | reg = <0xc9000000 0x1000000>; | ||
158 | interrupts = <0 5 0>; | ||
159 | }; | ||
160 | }; | ||
161 | |||
162 | dsp-iobg { | ||
163 | compatible = "simple-bus"; | ||
164 | #address-cells = <1>; | ||
165 | #size-cells = <1>; | ||
166 | ranges = <0xca000000 0xca000000 0x2000000>; | ||
167 | |||
168 | dspif@ca000000 { | ||
169 | compatible = "sirf,marco-dspif"; | ||
170 | reg = <0xca000000 0x10000>; | ||
171 | interrupts = <0 9 0>; | ||
172 | }; | ||
173 | |||
174 | gps@ca010000 { | ||
175 | compatible = "sirf,marco-gps"; | ||
176 | reg = <0xca010000 0x10000>; | ||
177 | interrupts = <0 7 0>; | ||
178 | }; | ||
179 | |||
180 | dsp@cb000000 { | ||
181 | compatible = "sirf,marco-dsp"; | ||
182 | reg = <0xcb000000 0x1000000>; | ||
183 | interrupts = <0 8 0>; | ||
184 | }; | ||
185 | }; | ||
186 | |||
187 | peri-iobg { | ||
188 | compatible = "simple-bus"; | ||
189 | #address-cells = <1>; | ||
190 | #size-cells = <1>; | ||
191 | ranges = <0xcc000000 0xcc000000 0x2000000>; | ||
192 | |||
193 | timer@cc020000 { | ||
194 | compatible = "sirf,marco-tick"; | ||
195 | reg = <0xcc020000 0x1000>; | ||
196 | interrupts = <0 0 0>, | ||
197 | <0 1 0>, | ||
198 | <0 2 0>, | ||
199 | <0 49 0>, | ||
200 | <0 50 0>, | ||
201 | <0 51 0>; | ||
202 | }; | ||
203 | |||
204 | nand@cc030000 { | ||
205 | compatible = "sirf,marco-nand"; | ||
206 | reg = <0xcc030000 0x10000>; | ||
207 | interrupts = <0 41 0>; | ||
208 | }; | ||
209 | |||
210 | audio@cc040000 { | ||
211 | compatible = "sirf,marco-audio"; | ||
212 | reg = <0xcc040000 0x10000>; | ||
213 | interrupts = <0 35 0>; | ||
214 | }; | ||
215 | |||
216 | uart0: uart@cc050000 { | ||
217 | cell-index = <0>; | ||
218 | compatible = "sirf,marco-uart"; | ||
219 | reg = <0xcc050000 0x1000>; | ||
220 | interrupts = <0 17 0>; | ||
221 | fifosize = <128>; | ||
222 | status = "disabled"; | ||
223 | }; | ||
224 | |||
225 | uart1: uart@cc060000 { | ||
226 | cell-index = <1>; | ||
227 | compatible = "sirf,marco-uart"; | ||
228 | reg = <0xcc060000 0x1000>; | ||
229 | interrupts = <0 18 0>; | ||
230 | fifosize = <32>; | ||
231 | status = "disabled"; | ||
232 | }; | ||
233 | |||
234 | uart2: uart@cc070000 { | ||
235 | cell-index = <2>; | ||
236 | compatible = "sirf,marco-uart"; | ||
237 | reg = <0xcc070000 0x1000>; | ||
238 | interrupts = <0 19 0>; | ||
239 | fifosize = <128>; | ||
240 | status = "disabled"; | ||
241 | }; | ||
242 | |||
243 | uart3: uart@cc190000 { | ||
244 | cell-index = <3>; | ||
245 | compatible = "sirf,marco-uart"; | ||
246 | reg = <0xcc190000 0x1000>; | ||
247 | interrupts = <0 66 0>; | ||
248 | fifosize = <128>; | ||
249 | status = "disabled"; | ||
250 | }; | ||
251 | |||
252 | uart4: uart@cc1a0000 { | ||
253 | cell-index = <4>; | ||
254 | compatible = "sirf,marco-uart"; | ||
255 | reg = <0xcc1a0000 0x1000>; | ||
256 | interrupts = <0 69 0>; | ||
257 | fifosize = <128>; | ||
258 | status = "disabled"; | ||
259 | }; | ||
260 | |||
261 | usp0: usp@cc080000 { | ||
262 | cell-index = <0>; | ||
263 | compatible = "sirf,marco-usp"; | ||
264 | reg = <0xcc080000 0x10000>; | ||
265 | interrupts = <0 20 0>; | ||
266 | status = "disabled"; | ||
267 | }; | ||
268 | |||
269 | usp1: usp@cc090000 { | ||
270 | cell-index = <1>; | ||
271 | compatible = "sirf,marco-usp"; | ||
272 | reg = <0xcc090000 0x10000>; | ||
273 | interrupts = <0 21 0>; | ||
274 | status = "disabled"; | ||
275 | }; | ||
276 | |||
277 | usp2: usp@cc0a0000 { | ||
278 | cell-index = <2>; | ||
279 | compatible = "sirf,marco-usp"; | ||
280 | reg = <0xcc0a0000 0x10000>; | ||
281 | interrupts = <0 22 0>; | ||
282 | status = "disabled"; | ||
283 | }; | ||
284 | |||
285 | dmac0: dma-controller@cc0b0000 { | ||
286 | cell-index = <0>; | ||
287 | compatible = "sirf,marco-dmac"; | ||
288 | reg = <0xcc0b0000 0x10000>; | ||
289 | interrupts = <0 12 0>; | ||
290 | }; | ||
291 | |||
292 | dmac1: dma-controller@cc160000 { | ||
293 | cell-index = <1>; | ||
294 | compatible = "sirf,marco-dmac"; | ||
295 | reg = <0xcc160000 0x10000>; | ||
296 | interrupts = <0 13 0>; | ||
297 | }; | ||
298 | |||
299 | vip@cc0c0000 { | ||
300 | compatible = "sirf,marco-vip"; | ||
301 | reg = <0xcc0c0000 0x10000>; | ||
302 | }; | ||
303 | |||
304 | spi0: spi@cc0d0000 { | ||
305 | cell-index = <0>; | ||
306 | compatible = "sirf,marco-spi"; | ||
307 | reg = <0xcc0d0000 0x10000>; | ||
308 | interrupts = <0 15 0>; | ||
309 | sirf,spi-num-chipselects = <1>; | ||
310 | cs-gpios = <&gpio 0 0>; | ||
311 | sirf,spi-dma-rx-channel = <25>; | ||
312 | sirf,spi-dma-tx-channel = <20>; | ||
313 | #address-cells = <1>; | ||
314 | #size-cells = <0>; | ||
315 | status = "disabled"; | ||
316 | }; | ||
317 | |||
318 | spi1: spi@cc170000 { | ||
319 | cell-index = <1>; | ||
320 | compatible = "sirf,marco-spi"; | ||
321 | reg = <0xcc170000 0x10000>; | ||
322 | interrupts = <0 16 0>; | ||
323 | sirf,spi-num-chipselects = <1>; | ||
324 | cs-gpios = <&gpio 0 0>; | ||
325 | sirf,spi-dma-rx-channel = <12>; | ||
326 | sirf,spi-dma-tx-channel = <13>; | ||
327 | #address-cells = <1>; | ||
328 | #size-cells = <0>; | ||
329 | status = "disabled"; | ||
330 | }; | ||
331 | |||
332 | i2c0: i2c@cc0e0000 { | ||
333 | cell-index = <0>; | ||
334 | compatible = "sirf,marco-i2c"; | ||
335 | reg = <0xcc0e0000 0x10000>; | ||
336 | interrupts = <0 24 0>; | ||
337 | #address-cells = <1>; | ||
338 | #size-cells = <0>; | ||
339 | status = "disabled"; | ||
340 | }; | ||
341 | |||
342 | i2c1: i2c@cc0f0000 { | ||
343 | cell-index = <1>; | ||
344 | compatible = "sirf,marco-i2c"; | ||
345 | reg = <0xcc0f0000 0x10000>; | ||
346 | interrupts = <0 25 0>; | ||
347 | #address-cells = <1>; | ||
348 | #size-cells = <0>; | ||
349 | status = "disabled"; | ||
350 | }; | ||
351 | |||
352 | tsc@cc110000 { | ||
353 | compatible = "sirf,marco-tsc"; | ||
354 | reg = <0xcc110000 0x10000>; | ||
355 | interrupts = <0 33 0>; | ||
356 | }; | ||
357 | |||
358 | gpio: pinctrl@cc120000 { | ||
359 | #gpio-cells = <2>; | ||
360 | #interrupt-cells = <2>; | ||
361 | compatible = "sirf,marco-pinctrl"; | ||
362 | reg = <0xcc120000 0x10000>; | ||
363 | interrupts = <0 43 0>, | ||
364 | <0 44 0>, | ||
365 | <0 45 0>, | ||
366 | <0 46 0>, | ||
367 | <0 47 0>; | ||
368 | gpio-controller; | ||
369 | interrupt-controller; | ||
370 | |||
371 | lcd_16pins_a: lcd0_0 { | ||
372 | lcd { | ||
373 | sirf,pins = "lcd_16bitsgrp"; | ||
374 | sirf,function = "lcd_16bits"; | ||
375 | }; | ||
376 | }; | ||
377 | lcd_18pins_a: lcd0_1 { | ||
378 | lcd { | ||
379 | sirf,pins = "lcd_18bitsgrp"; | ||
380 | sirf,function = "lcd_18bits"; | ||
381 | }; | ||
382 | }; | ||
383 | lcd_24pins_a: lcd0_2 { | ||
384 | lcd { | ||
385 | sirf,pins = "lcd_24bitsgrp"; | ||
386 | sirf,function = "lcd_24bits"; | ||
387 | }; | ||
388 | }; | ||
389 | lcdrom_pins_a: lcdrom0_0 { | ||
390 | lcd { | ||
391 | sirf,pins = "lcdromgrp"; | ||
392 | sirf,function = "lcdrom"; | ||
393 | }; | ||
394 | }; | ||
395 | uart0_pins_a: uart0_0 { | ||
396 | uart { | ||
397 | sirf,pins = "uart0grp"; | ||
398 | sirf,function = "uart0"; | ||
399 | }; | ||
400 | }; | ||
401 | uart1_pins_a: uart1_0 { | ||
402 | uart { | ||
403 | sirf,pins = "uart1grp"; | ||
404 | sirf,function = "uart1"; | ||
405 | }; | ||
406 | }; | ||
407 | uart2_pins_a: uart2_0 { | ||
408 | uart { | ||
409 | sirf,pins = "uart2grp"; | ||
410 | sirf,function = "uart2"; | ||
411 | }; | ||
412 | }; | ||
413 | uart2_noflow_pins_a: uart2_1 { | ||
414 | uart { | ||
415 | sirf,pins = "uart2_nostreamctrlgrp"; | ||
416 | sirf,function = "uart2_nostreamctrl"; | ||
417 | }; | ||
418 | }; | ||
419 | spi0_pins_a: spi0_0 { | ||
420 | spi { | ||
421 | sirf,pins = "spi0grp"; | ||
422 | sirf,function = "spi0"; | ||
423 | }; | ||
424 | }; | ||
425 | spi1_pins_a: spi1_0 { | ||
426 | spi { | ||
427 | sirf,pins = "spi1grp"; | ||
428 | sirf,function = "spi1"; | ||
429 | }; | ||
430 | }; | ||
431 | i2c0_pins_a: i2c0_0 { | ||
432 | i2c { | ||
433 | sirf,pins = "i2c0grp"; | ||
434 | sirf,function = "i2c0"; | ||
435 | }; | ||
436 | }; | ||
437 | i2c1_pins_a: i2c1_0 { | ||
438 | i2c { | ||
439 | sirf,pins = "i2c1grp"; | ||
440 | sirf,function = "i2c1"; | ||
441 | }; | ||
442 | }; | ||
443 | pwm0_pins_a: pwm0_0 { | ||
444 | pwm { | ||
445 | sirf,pins = "pwm0grp"; | ||
446 | sirf,function = "pwm0"; | ||
447 | }; | ||
448 | }; | ||
449 | pwm1_pins_a: pwm1_0 { | ||
450 | pwm { | ||
451 | sirf,pins = "pwm1grp"; | ||
452 | sirf,function = "pwm1"; | ||
453 | }; | ||
454 | }; | ||
455 | pwm2_pins_a: pwm2_0 { | ||
456 | pwm { | ||
457 | sirf,pins = "pwm2grp"; | ||
458 | sirf,function = "pwm2"; | ||
459 | }; | ||
460 | }; | ||
461 | pwm3_pins_a: pwm3_0 { | ||
462 | pwm { | ||
463 | sirf,pins = "pwm3grp"; | ||
464 | sirf,function = "pwm3"; | ||
465 | }; | ||
466 | }; | ||
467 | gps_pins_a: gps_0 { | ||
468 | gps { | ||
469 | sirf,pins = "gpsgrp"; | ||
470 | sirf,function = "gps"; | ||
471 | }; | ||
472 | }; | ||
473 | vip_pins_a: vip_0 { | ||
474 | vip { | ||
475 | sirf,pins = "vipgrp"; | ||
476 | sirf,function = "vip"; | ||
477 | }; | ||
478 | }; | ||
479 | sdmmc0_pins_a: sdmmc0_0 { | ||
480 | sdmmc0 { | ||
481 | sirf,pins = "sdmmc0grp"; | ||
482 | sirf,function = "sdmmc0"; | ||
483 | }; | ||
484 | }; | ||
485 | sdmmc1_pins_a: sdmmc1_0 { | ||
486 | sdmmc1 { | ||
487 | sirf,pins = "sdmmc1grp"; | ||
488 | sirf,function = "sdmmc1"; | ||
489 | }; | ||
490 | }; | ||
491 | sdmmc2_pins_a: sdmmc2_0 { | ||
492 | sdmmc2 { | ||
493 | sirf,pins = "sdmmc2grp"; | ||
494 | sirf,function = "sdmmc2"; | ||
495 | }; | ||
496 | }; | ||
497 | sdmmc3_pins_a: sdmmc3_0 { | ||
498 | sdmmc3 { | ||
499 | sirf,pins = "sdmmc3grp"; | ||
500 | sirf,function = "sdmmc3"; | ||
501 | }; | ||
502 | }; | ||
503 | sdmmc4_pins_a: sdmmc4_0 { | ||
504 | sdmmc4 { | ||
505 | sirf,pins = "sdmmc4grp"; | ||
506 | sirf,function = "sdmmc4"; | ||
507 | }; | ||
508 | }; | ||
509 | sdmmc5_pins_a: sdmmc5_0 { | ||
510 | sdmmc5 { | ||
511 | sirf,pins = "sdmmc5grp"; | ||
512 | sirf,function = "sdmmc5"; | ||
513 | }; | ||
514 | }; | ||
515 | i2s_pins_a: i2s_0 { | ||
516 | i2s { | ||
517 | sirf,pins = "i2sgrp"; | ||
518 | sirf,function = "i2s"; | ||
519 | }; | ||
520 | }; | ||
521 | ac97_pins_a: ac97_0 { | ||
522 | ac97 { | ||
523 | sirf,pins = "ac97grp"; | ||
524 | sirf,function = "ac97"; | ||
525 | }; | ||
526 | }; | ||
527 | nand_pins_a: nand_0 { | ||
528 | nand { | ||
529 | sirf,pins = "nandgrp"; | ||
530 | sirf,function = "nand"; | ||
531 | }; | ||
532 | }; | ||
533 | usp0_pins_a: usp0_0 { | ||
534 | usp0 { | ||
535 | sirf,pins = "usp0grp"; | ||
536 | sirf,function = "usp0"; | ||
537 | }; | ||
538 | }; | ||
539 | usp1_pins_a: usp1_0 { | ||
540 | usp1 { | ||
541 | sirf,pins = "usp1grp"; | ||
542 | sirf,function = "usp1"; | ||
543 | }; | ||
544 | }; | ||
545 | usp2_pins_a: usp2_0 { | ||
546 | usp2 { | ||
547 | sirf,pins = "usp2grp"; | ||
548 | sirf,function = "usp2"; | ||
549 | }; | ||
550 | }; | ||
551 | usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus_0 { | ||
552 | usb0_utmi_drvbus { | ||
553 | sirf,pins = "usb0_utmi_drvbusgrp"; | ||
554 | sirf,function = "usb0_utmi_drvbus"; | ||
555 | }; | ||
556 | }; | ||
557 | usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus_0 { | ||
558 | usb1_utmi_drvbus { | ||
559 | sirf,pins = "usb1_utmi_drvbusgrp"; | ||
560 | sirf,function = "usb1_utmi_drvbus"; | ||
561 | }; | ||
562 | }; | ||
563 | warm_rst_pins_a: warm_rst_0 { | ||
564 | warm_rst { | ||
565 | sirf,pins = "warm_rstgrp"; | ||
566 | sirf,function = "warm_rst"; | ||
567 | }; | ||
568 | }; | ||
569 | pulse_count_pins_a: pulse_count_0 { | ||
570 | pulse_count { | ||
571 | sirf,pins = "pulse_countgrp"; | ||
572 | sirf,function = "pulse_count"; | ||
573 | }; | ||
574 | }; | ||
575 | cko0_rst_pins_a: cko0_rst_0 { | ||
576 | cko0_rst { | ||
577 | sirf,pins = "cko0_rstgrp"; | ||
578 | sirf,function = "cko0_rst"; | ||
579 | }; | ||
580 | }; | ||
581 | cko1_rst_pins_a: cko1_rst_0 { | ||
582 | cko1_rst { | ||
583 | sirf,pins = "cko1_rstgrp"; | ||
584 | sirf,function = "cko1_rst"; | ||
585 | }; | ||
586 | }; | ||
587 | }; | ||
588 | |||
589 | pwm@cc130000 { | ||
590 | compatible = "sirf,marco-pwm"; | ||
591 | reg = <0xcc130000 0x10000>; | ||
592 | }; | ||
593 | |||
594 | efusesys@cc140000 { | ||
595 | compatible = "sirf,marco-efuse"; | ||
596 | reg = <0xcc140000 0x10000>; | ||
597 | }; | ||
598 | |||
599 | pulsec@cc150000 { | ||
600 | compatible = "sirf,marco-pulsec"; | ||
601 | reg = <0xcc150000 0x10000>; | ||
602 | interrupts = <0 48 0>; | ||
603 | }; | ||
604 | |||
605 | pci-iobg { | ||
606 | compatible = "sirf,marco-pciiobg", "simple-bus"; | ||
607 | #address-cells = <1>; | ||
608 | #size-cells = <1>; | ||
609 | ranges = <0xcd000000 0xcd000000 0x1000000>; | ||
610 | |||
611 | sd0: sdhci@cd000000 { | ||
612 | cell-index = <0>; | ||
613 | compatible = "sirf,marco-sdhc"; | ||
614 | reg = <0xcd000000 0x100000>; | ||
615 | interrupts = <0 38 0>; | ||
616 | status = "disabled"; | ||
617 | }; | ||
618 | |||
619 | sd1: sdhci@cd100000 { | ||
620 | cell-index = <1>; | ||
621 | compatible = "sirf,marco-sdhc"; | ||
622 | reg = <0xcd100000 0x100000>; | ||
623 | interrupts = <0 38 0>; | ||
624 | status = "disabled"; | ||
625 | }; | ||
626 | |||
627 | sd2: sdhci@cd200000 { | ||
628 | cell-index = <2>; | ||
629 | compatible = "sirf,marco-sdhc"; | ||
630 | reg = <0xcd200000 0x100000>; | ||
631 | interrupts = <0 23 0>; | ||
632 | status = "disabled"; | ||
633 | }; | ||
634 | |||
635 | sd3: sdhci@cd300000 { | ||
636 | cell-index = <3>; | ||
637 | compatible = "sirf,marco-sdhc"; | ||
638 | reg = <0xcd300000 0x100000>; | ||
639 | interrupts = <0 23 0>; | ||
640 | status = "disabled"; | ||
641 | }; | ||
642 | |||
643 | sd4: sdhci@cd400000 { | ||
644 | cell-index = <4>; | ||
645 | compatible = "sirf,marco-sdhc"; | ||
646 | reg = <0xcd400000 0x100000>; | ||
647 | interrupts = <0 39 0>; | ||
648 | status = "disabled"; | ||
649 | }; | ||
650 | |||
651 | sd5: sdhci@cd500000 { | ||
652 | cell-index = <5>; | ||
653 | compatible = "sirf,marco-sdhc"; | ||
654 | reg = <0xcd500000 0x100000>; | ||
655 | interrupts = <0 39 0>; | ||
656 | status = "disabled"; | ||
657 | }; | ||
658 | |||
659 | pci-copy@cd900000 { | ||
660 | compatible = "sirf,marco-pcicp"; | ||
661 | reg = <0xcd900000 0x100000>; | ||
662 | interrupts = <0 40 0>; | ||
663 | }; | ||
664 | |||
665 | rom-interface@cda00000 { | ||
666 | compatible = "sirf,marco-romif"; | ||
667 | reg = <0xcda00000 0x100000>; | ||
668 | }; | ||
669 | }; | ||
670 | }; | ||
671 | |||
672 | rtc-iobg { | ||
673 | compatible = "sirf,marco-rtciobg", "sirf-marco-rtciobg-bus"; | ||
674 | #address-cells = <1>; | ||
675 | #size-cells = <1>; | ||
676 | reg = <0xc1000000 0x10000>; | ||
677 | |||
678 | gpsrtc@1000 { | ||
679 | compatible = "sirf,marco-gpsrtc"; | ||
680 | reg = <0x1000 0x1000>; | ||
681 | interrupts = <0 55 0>, | ||
682 | <0 56 0>, | ||
683 | <0 57 0>; | ||
684 | }; | ||
685 | |||
686 | sysrtc@2000 { | ||
687 | compatible = "sirf,marco-sysrtc"; | ||
688 | reg = <0x2000 0x1000>; | ||
689 | interrupts = <0 52 0>, | ||
690 | <0 53 0>, | ||
691 | <0 54 0>; | ||
692 | }; | ||
693 | |||
694 | pwrc@3000 { | ||
695 | compatible = "sirf,marco-pwrc"; | ||
696 | reg = <0x3000 0x1000>; | ||
697 | interrupts = <0 32 0>; | ||
698 | }; | ||
699 | }; | ||
700 | |||
701 | uus-iobg { | ||
702 | compatible = "simple-bus"; | ||
703 | #address-cells = <1>; | ||
704 | #size-cells = <1>; | ||
705 | ranges = <0xce000000 0xce000000 0x1000000>; | ||
706 | |||
707 | usb0: usb@ce000000 { | ||
708 | compatible = "chipidea,ci13611a-marco"; | ||
709 | reg = <0xce000000 0x10000>; | ||
710 | interrupts = <0 10 0>; | ||
711 | }; | ||
712 | |||
713 | usb1: usb@ce010000 { | ||
714 | compatible = "chipidea,ci13611a-marco"; | ||
715 | reg = <0xce010000 0x10000>; | ||
716 | interrupts = <0 11 0>; | ||
717 | }; | ||
718 | |||
719 | security@ce020000 { | ||
720 | compatible = "sirf,marco-security"; | ||
721 | reg = <0xce020000 0x10000>; | ||
722 | interrupts = <0 42 0>; | ||
723 | }; | ||
724 | }; | ||
725 | |||
726 | can-iobg { | ||
727 | compatible = "simple-bus"; | ||
728 | #address-cells = <1>; | ||
729 | #size-cells = <1>; | ||
730 | ranges = <0xd0000000 0xd0000000 0x1000000>; | ||
731 | |||
732 | can0: can@d0000000 { | ||
733 | compatible = "sirf,marco-can"; | ||
734 | reg = <0xd0000000 0x10000>; | ||
735 | }; | ||
736 | |||
737 | can1: can@d0010000 { | ||
738 | compatible = "sirf,marco-can"; | ||
739 | reg = <0xd0010000 0x10000>; | ||
740 | }; | ||
741 | }; | ||
742 | |||
743 | lvds-iobg { | ||
744 | compatible = "simple-bus"; | ||
745 | #address-cells = <1>; | ||
746 | #size-cells = <1>; | ||
747 | ranges = <0xd1000000 0xd1000000 0x1000000>; | ||
748 | |||
749 | lvds@d1000000 { | ||
750 | compatible = "sirf,marco-lvds"; | ||
751 | reg = <0xd1000000 0x10000>; | ||
752 | interrupts = <0 64 0>; | ||
753 | }; | ||
754 | }; | ||
755 | }; | ||
756 | }; | ||
diff --git a/arch/arm/boot/dts/sh73a0-reference.dtsi b/arch/arm/boot/dts/sh73a0-reference.dtsi new file mode 100644 index 000000000000..d4bb0125b2b2 --- /dev/null +++ b/arch/arm/boot/dts/sh73a0-reference.dtsi | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Device Tree Source for the SH73A0 SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public License | ||
7 | * version 2. This program is licensed "as is" without any warranty of any | ||
8 | * kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | /include/ "sh73a0.dtsi" | ||
12 | |||
13 | / { | ||
14 | compatible = "renesas,sh73a0"; | ||
15 | |||
16 | mmcif: mmcif@0x10010000 { | ||
17 | compatible = "renesas,sh-mmcif"; | ||
18 | reg = <0xe6bd0000 0x100>; | ||
19 | interrupt-parent = <&gic>; | ||
20 | interrupts = <0 140 0x4 | ||
21 | 0 141 0x4>; | ||
22 | reg-io-width = <4>; | ||
23 | }; | ||
24 | }; | ||
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi new file mode 100644 index 000000000000..8a59465d0231 --- /dev/null +++ b/arch/arm/boot/dts/sh73a0.dtsi | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Device Tree Source for the SH73A0 SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public License | ||
7 | * version 2. This program is licensed "as is" without any warranty of any | ||
8 | * kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | /include/ "skeleton.dtsi" | ||
12 | |||
13 | / { | ||
14 | compatible = "renesas,sh73a0"; | ||
15 | |||
16 | cpus { | ||
17 | #address-cells = <1>; | ||
18 | #size-cells = <0>; | ||
19 | |||
20 | cpu@0 { | ||
21 | device_type = "cpu"; | ||
22 | compatible = "arm,cortex-a9"; | ||
23 | reg = <0>; | ||
24 | }; | ||
25 | cpu@1 { | ||
26 | device_type = "cpu"; | ||
27 | compatible = "arm,cortex-a9"; | ||
28 | reg = <1>; | ||
29 | }; | ||
30 | }; | ||
31 | |||
32 | gic: interrupt-controller@f0001000 { | ||
33 | compatible = "arm,cortex-a9-gic"; | ||
34 | #interrupt-cells = <3>; | ||
35 | #address-cells = <1>; | ||
36 | interrupt-controller; | ||
37 | reg = <0xf0001000 0x1000>, | ||
38 | <0xf0000100 0x100>; | ||
39 | }; | ||
40 | |||
41 | i2c0: i2c@0xe6820000 { | ||
42 | #address-cells = <1>; | ||
43 | #size-cells = <0>; | ||
44 | compatible = "renesas,rmobile-iic"; | ||
45 | reg = <0xe6820000 0x425>; | ||
46 | interrupt-parent = <&gic>; | ||
47 | interrupts = <0 167 0x4 | ||
48 | 0 168 0x4 | ||
49 | 0 169 0x4 | ||
50 | 0 170 0x4>; | ||
51 | }; | ||
52 | |||
53 | i2c1: i2c@0xe6822000 { | ||
54 | #address-cells = <1>; | ||
55 | #size-cells = <0>; | ||
56 | compatible = "renesas,rmobile-iic"; | ||
57 | reg = <0xe6822000 0x425>; | ||
58 | interrupt-parent = <&gic>; | ||
59 | interrupts = <0 51 0x4 | ||
60 | 0 52 0x4 | ||
61 | 0 53 0x4 | ||
62 | 0 54 0x4>; | ||
63 | }; | ||
64 | |||
65 | i2c2: i2c@0xe6824000 { | ||
66 | #address-cells = <1>; | ||
67 | #size-cells = <0>; | ||
68 | compatible = "renesas,rmobile-iic"; | ||
69 | reg = <0xe6824000 0x425>; | ||
70 | interrupt-parent = <&gic>; | ||
71 | interrupts = <0 171 0x4 | ||
72 | 0 172 0x4 | ||
73 | 0 173 0x4 | ||
74 | 0 174 0x4>; | ||
75 | }; | ||
76 | |||
77 | i2c3: i2c@0xe6826000 { | ||
78 | #address-cells = <1>; | ||
79 | #size-cells = <0>; | ||
80 | compatible = "renesas,rmobile-iic"; | ||
81 | reg = <0xe6826000 0x425>; | ||
82 | interrupt-parent = <&gic>; | ||
83 | interrupts = <0 183 0x4 | ||
84 | 0 184 0x4 | ||
85 | 0 185 0x4 | ||
86 | 0 186 0x4>; | ||
87 | }; | ||
88 | |||
89 | i2c4: i2c@0xe6828000 { | ||
90 | #address-cells = <1>; | ||
91 | #size-cells = <0>; | ||
92 | compatible = "renesas,rmobile-iic"; | ||
93 | reg = <0xe6828000 0x425>; | ||
94 | interrupt-parent = <&gic>; | ||
95 | interrupts = <0 187 0x4 | ||
96 | 0 188 0x4 | ||
97 | 0 189 0x4 | ||
98 | 0 190 0x4>; | ||
99 | }; | ||
100 | }; | ||
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 19aec421bb26..936d2306e7e1 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi | |||
@@ -25,6 +25,10 @@ | |||
25 | ethernet0 = &gmac0; | 25 | ethernet0 = &gmac0; |
26 | serial0 = &uart0; | 26 | serial0 = &uart0; |
27 | serial1 = &uart1; | 27 | serial1 = &uart1; |
28 | timer0 = &timer0; | ||
29 | timer1 = &timer1; | ||
30 | timer2 = &timer2; | ||
31 | timer3 = &timer3; | ||
28 | }; | 32 | }; |
29 | 33 | ||
30 | cpus { | 34 | cpus { |
@@ -98,47 +102,41 @@ | |||
98 | interrupts = <1 13 0xf04>; | 102 | interrupts = <1 13 0xf04>; |
99 | }; | 103 | }; |
100 | 104 | ||
101 | timer0: timer@ffc08000 { | 105 | timer0: timer0@ffc08000 { |
102 | compatible = "snps,dw-apb-timer-sp"; | 106 | compatible = "snps,dw-apb-timer-sp"; |
103 | interrupts = <0 167 4>; | 107 | interrupts = <0 167 4>; |
104 | clock-frequency = <200000000>; | ||
105 | reg = <0xffc08000 0x1000>; | 108 | reg = <0xffc08000 0x1000>; |
106 | }; | 109 | }; |
107 | 110 | ||
108 | timer1: timer@ffc09000 { | 111 | timer1: timer1@ffc09000 { |
109 | compatible = "snps,dw-apb-timer-sp"; | 112 | compatible = "snps,dw-apb-timer-sp"; |
110 | interrupts = <0 168 4>; | 113 | interrupts = <0 168 4>; |
111 | clock-frequency = <200000000>; | ||
112 | reg = <0xffc09000 0x1000>; | 114 | reg = <0xffc09000 0x1000>; |
113 | }; | 115 | }; |
114 | 116 | ||
115 | timer2: timer@ffd00000 { | 117 | timer2: timer2@ffd00000 { |
116 | compatible = "snps,dw-apb-timer-osc"; | 118 | compatible = "snps,dw-apb-timer-osc"; |
117 | interrupts = <0 169 4>; | 119 | interrupts = <0 169 4>; |
118 | clock-frequency = <200000000>; | ||
119 | reg = <0xffd00000 0x1000>; | 120 | reg = <0xffd00000 0x1000>; |
120 | }; | 121 | }; |
121 | 122 | ||
122 | timer3: timer@ffd01000 { | 123 | timer3: timer3@ffd01000 { |
123 | compatible = "snps,dw-apb-timer-osc"; | 124 | compatible = "snps,dw-apb-timer-osc"; |
124 | interrupts = <0 170 4>; | 125 | interrupts = <0 170 4>; |
125 | clock-frequency = <200000000>; | ||
126 | reg = <0xffd01000 0x1000>; | 126 | reg = <0xffd01000 0x1000>; |
127 | }; | 127 | }; |
128 | 128 | ||
129 | uart0: uart@ffc02000 { | 129 | uart0: serial0@ffc02000 { |
130 | compatible = "snps,dw-apb-uart"; | 130 | compatible = "snps,dw-apb-uart"; |
131 | reg = <0xffc02000 0x1000>; | 131 | reg = <0xffc02000 0x1000>; |
132 | clock-frequency = <7372800>; | ||
133 | interrupts = <0 162 4>; | 132 | interrupts = <0 162 4>; |
134 | reg-shift = <2>; | 133 | reg-shift = <2>; |
135 | reg-io-width = <4>; | 134 | reg-io-width = <4>; |
136 | }; | 135 | }; |
137 | 136 | ||
138 | uart1: uart@ffc03000 { | 137 | uart1: serial1@ffc03000 { |
139 | compatible = "snps,dw-apb-uart"; | 138 | compatible = "snps,dw-apb-uart"; |
140 | reg = <0xffc03000 0x1000>; | 139 | reg = <0xffc03000 0x1000>; |
141 | clock-frequency = <7372800>; | ||
142 | interrupts = <0 163 4>; | 140 | interrupts = <0 163 4>; |
143 | reg-shift = <2>; | 141 | reg-shift = <2>; |
144 | reg-io-width = <4>; | 142 | reg-io-width = <4>; |
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dts index ab7e4a94299f..3ae8a83a0875 100644 --- a/arch/arm/boot/dts/socfpga_cyclone5.dts +++ b/arch/arm/boot/dts/socfpga_cyclone5.dts | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | / { | 21 | / { |
22 | model = "Altera SOCFPGA Cyclone V"; | 22 | model = "Altera SOCFPGA Cyclone V"; |
23 | compatible = "altr,socfpga-cyclone5"; | 23 | compatible = "altr,socfpga-cyclone5", "altr,socfpga"; |
24 | 24 | ||
25 | chosen { | 25 | chosen { |
26 | bootargs = "console=ttyS0,57600"; | 26 | bootargs = "console=ttyS0,57600"; |
@@ -29,6 +29,36 @@ | |||
29 | memory { | 29 | memory { |
30 | name = "memory"; | 30 | name = "memory"; |
31 | device_type = "memory"; | 31 | device_type = "memory"; |
32 | reg = <0x0 0x10000000>; /* 256MB */ | 32 | reg = <0x0 0x40000000>; /* 1GB */ |
33 | }; | ||
34 | |||
35 | soc { | ||
36 | timer0@ffc08000 { | ||
37 | clock-frequency = <100000000>; | ||
38 | }; | ||
39 | |||
40 | timer1@ffc09000 { | ||
41 | clock-frequency = <100000000>; | ||
42 | }; | ||
43 | |||
44 | timer2@ffd00000 { | ||
45 | clock-frequency = <25000000>; | ||
46 | }; | ||
47 | |||
48 | timer3@ffd01000 { | ||
49 | clock-frequency = <25000000>; | ||
50 | }; | ||
51 | |||
52 | serial0@ffc02000 { | ||
53 | clock-frequency = <100000000>; | ||
54 | }; | ||
55 | |||
56 | serial1@ffc03000 { | ||
57 | clock-frequency = <100000000>; | ||
58 | }; | ||
59 | |||
60 | sysmgr@ffd08000 { | ||
61 | cpu1-start-addr = <0xffd080c4>; | ||
62 | }; | ||
33 | }; | 63 | }; |
34 | }; | 64 | }; |
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts new file mode 100644 index 000000000000..1036eba40bbf --- /dev/null +++ b/arch/arm/boot/dts/socfpga_vt.dts | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Altera Corporation <www.altera.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | /dts-v1/; | ||
19 | /include/ "socfpga.dtsi" | ||
20 | |||
21 | / { | ||
22 | model = "Altera SOCFPGA VT"; | ||
23 | compatible = "altr,socfpga-vt", "altr,socfpga"; | ||
24 | |||
25 | chosen { | ||
26 | bootargs = "console=ttyS0,57600"; | ||
27 | }; | ||
28 | |||
29 | memory { | ||
30 | name = "memory"; | ||
31 | device_type = "memory"; | ||
32 | reg = <0x0 0x40000000>; /* 1 GB */ | ||
33 | }; | ||
34 | |||
35 | soc { | ||
36 | timer0@ffc08000 { | ||
37 | clock-frequency = <7000000>; | ||
38 | }; | ||
39 | |||
40 | timer1@ffc09000 { | ||
41 | clock-frequency = <7000000>; | ||
42 | }; | ||
43 | |||
44 | timer2@ffd00000 { | ||
45 | clock-frequency = <7000000>; | ||
46 | }; | ||
47 | |||
48 | timer3@ffd01000 { | ||
49 | clock-frequency = <7000000>; | ||
50 | }; | ||
51 | |||
52 | serial0@ffc02000 { | ||
53 | clock-frequency = <7372800>; | ||
54 | }; | ||
55 | |||
56 | serial1@ffc03000 { | ||
57 | clock-frequency = <7372800>; | ||
58 | }; | ||
59 | |||
60 | sysmgr@ffd08000 { | ||
61 | cpu1-start-addr = <0xffd08010>; | ||
62 | }; | ||
63 | }; | ||
64 | }; | ||
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts new file mode 100644 index 000000000000..a30aca62658a --- /dev/null +++ b/arch/arm/boot/dts/tegra114-dalmore.dts | |||
@@ -0,0 +1,21 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "tegra114.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "NVIDIA Tegra114 Dalmore evaluation board"; | ||
7 | compatible = "nvidia,dalmore", "nvidia,tegra114"; | ||
8 | |||
9 | memory { | ||
10 | reg = <0x80000000 0x40000000>; | ||
11 | }; | ||
12 | |||
13 | serial@70006300 { | ||
14 | status = "okay"; | ||
15 | clock-frequency = <408000000>; | ||
16 | }; | ||
17 | |||
18 | pmc { | ||
19 | nvidia,invert-interrupt; | ||
20 | }; | ||
21 | }; | ||
diff --git a/arch/arm/boot/dts/tegra114-pluto.dts b/arch/arm/boot/dts/tegra114-pluto.dts new file mode 100644 index 000000000000..9bea8f57aa47 --- /dev/null +++ b/arch/arm/boot/dts/tegra114-pluto.dts | |||
@@ -0,0 +1,21 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "tegra114.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "NVIDIA Tegra114 Pluto evaluation board"; | ||
7 | compatible = "nvidia,pluto", "nvidia,tegra114"; | ||
8 | |||
9 | memory { | ||
10 | reg = <0x80000000 0x40000000>; | ||
11 | }; | ||
12 | |||
13 | serial@70006300 { | ||
14 | status = "okay"; | ||
15 | clock-frequency = <408000000>; | ||
16 | }; | ||
17 | |||
18 | pmc { | ||
19 | nvidia,invert-interrupt; | ||
20 | }; | ||
21 | }; | ||
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi new file mode 100644 index 000000000000..1dfaf2874c57 --- /dev/null +++ b/arch/arm/boot/dts/tegra114.dtsi | |||
@@ -0,0 +1,153 @@ | |||
1 | /include/ "skeleton.dtsi" | ||
2 | |||
3 | / { | ||
4 | compatible = "nvidia,tegra114"; | ||
5 | interrupt-parent = <&gic>; | ||
6 | |||
7 | gic: interrupt-controller { | ||
8 | compatible = "arm,cortex-a15-gic"; | ||
9 | #interrupt-cells = <3>; | ||
10 | interrupt-controller; | ||
11 | reg = <0x50041000 0x1000>, | ||
12 | <0x50042000 0x1000>, | ||
13 | <0x50044000 0x2000>, | ||
14 | <0x50046000 0x2000>; | ||
15 | interrupts = <1 9 0xf04>; | ||
16 | }; | ||
17 | |||
18 | timer@60005000 { | ||
19 | compatible = "nvidia,tegra114-timer", "nvidia,tegra20-timer"; | ||
20 | reg = <0x60005000 0x400>; | ||
21 | interrupts = <0 0 0x04 | ||
22 | 0 1 0x04 | ||
23 | 0 41 0x04 | ||
24 | 0 42 0x04 | ||
25 | 0 121 0x04 | ||
26 | 0 122 0x04>; | ||
27 | }; | ||
28 | |||
29 | tegra_car: clock { | ||
30 | compatible = "nvidia,tegra114-car, nvidia,tegra30-car"; | ||
31 | reg = <0x60006000 0x1000>; | ||
32 | #clock-cells = <1>; | ||
33 | }; | ||
34 | |||
35 | ahb: ahb { | ||
36 | compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb"; | ||
37 | reg = <0x6000c004 0x14c>; | ||
38 | }; | ||
39 | |||
40 | gpio: gpio { | ||
41 | compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio"; | ||
42 | reg = <0x6000d000 0x1000>; | ||
43 | interrupts = <0 32 0x04 | ||
44 | 0 33 0x04 | ||
45 | 0 34 0x04 | ||
46 | 0 35 0x04 | ||
47 | 0 55 0x04 | ||
48 | 0 87 0x04 | ||
49 | 0 89 0x04 | ||
50 | 0 125 0x04>; | ||
51 | #gpio-cells = <2>; | ||
52 | gpio-controller; | ||
53 | #interrupt-cells = <2>; | ||
54 | interrupt-controller; | ||
55 | }; | ||
56 | |||
57 | pinmux: pinmux { | ||
58 | compatible = "nvidia,tegra114-pinmux"; | ||
59 | reg = <0x70000868 0x148 /* Pad control registers */ | ||
60 | 0x70003000 0x40c>; /* Mux registers */ | ||
61 | }; | ||
62 | |||
63 | serial@70006000 { | ||
64 | compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; | ||
65 | reg = <0x70006000 0x40>; | ||
66 | reg-shift = <2>; | ||
67 | interrupts = <0 36 0x04>; | ||
68 | status = "disabled"; | ||
69 | }; | ||
70 | |||
71 | serial@70006040 { | ||
72 | compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; | ||
73 | reg = <0x70006040 0x40>; | ||
74 | reg-shift = <2>; | ||
75 | interrupts = <0 37 0x04>; | ||
76 | status = "disabled"; | ||
77 | }; | ||
78 | |||
79 | serial@70006200 { | ||
80 | compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; | ||
81 | reg = <0x70006200 0x100>; | ||
82 | reg-shift = <2>; | ||
83 | interrupts = <0 46 0x04>; | ||
84 | status = "disabled"; | ||
85 | }; | ||
86 | |||
87 | serial@70006300 { | ||
88 | compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; | ||
89 | reg = <0x70006300 0x100>; | ||
90 | reg-shift = <2>; | ||
91 | interrupts = <0 90 0x04>; | ||
92 | status = "disabled"; | ||
93 | }; | ||
94 | |||
95 | rtc { | ||
96 | compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc"; | ||
97 | reg = <0x7000e000 0x100>; | ||
98 | interrupts = <0 2 0x04>; | ||
99 | }; | ||
100 | |||
101 | pmc { | ||
102 | compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc"; | ||
103 | reg = <0x7000e400 0x400>; | ||
104 | }; | ||
105 | |||
106 | iommu { | ||
107 | compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu"; | ||
108 | reg = <0x7000f010 0x02c | ||
109 | 0x7000f1f0 0x010 | ||
110 | 0x7000f228 0x074>; | ||
111 | nvidia,#asids = <4>; | ||
112 | dma-window = <0 0x40000000>; | ||
113 | nvidia,swgroups = <0x18659fe>; | ||
114 | nvidia,ahb = <&ahb>; | ||
115 | }; | ||
116 | |||
117 | cpus { | ||
118 | #address-cells = <1>; | ||
119 | #size-cells = <0>; | ||
120 | |||
121 | cpu@0 { | ||
122 | device_type = "cpu"; | ||
123 | compatible = "arm,cortex-a15"; | ||
124 | reg = <0>; | ||
125 | }; | ||
126 | |||
127 | cpu@1 { | ||
128 | device_type = "cpu"; | ||
129 | compatible = "arm,cortex-a15"; | ||
130 | reg = <1>; | ||
131 | }; | ||
132 | |||
133 | cpu@2 { | ||
134 | device_type = "cpu"; | ||
135 | compatible = "arm,cortex-a15"; | ||
136 | reg = <2>; | ||
137 | }; | ||
138 | |||
139 | cpu@3 { | ||
140 | device_type = "cpu"; | ||
141 | compatible = "arm,cortex-a15"; | ||
142 | reg = <3>; | ||
143 | }; | ||
144 | }; | ||
145 | |||
146 | timer { | ||
147 | compatible = "arm,armv7-timer"; | ||
148 | interrupts = <1 13 0xf08>, | ||
149 | <1 14 0xf08>, | ||
150 | <1 11 0xf08>, | ||
151 | <1 10 0xf08>; | ||
152 | }; | ||
153 | }; | ||
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts index 43eb72af8948..2b4169702c8d 100644 --- a/arch/arm/boot/dts/tegra20-harmony.dts +++ b/arch/arm/boot/dts/tegra20-harmony.dts | |||
@@ -432,6 +432,10 @@ | |||
432 | status = "okay"; | 432 | status = "okay"; |
433 | }; | 433 | }; |
434 | 434 | ||
435 | usb-phy@c5004400 { | ||
436 | nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ | ||
437 | }; | ||
438 | |||
435 | sdhci@c8000200 { | 439 | sdhci@c8000200 { |
436 | status = "okay"; | 440 | status = "okay"; |
437 | cd-gpios = <&gpio 69 0>; /* gpio PI5 */ | 441 | cd-gpios = <&gpio 69 0>; /* gpio PI5 */ |
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index 6a93d1404c76..11b30db63ff2 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts | |||
@@ -266,6 +266,8 @@ | |||
266 | clock-frequency = <80000>; | 266 | clock-frequency = <80000>; |
267 | request-gpios = <&gpio 170 0>; /* gpio PV2 */ | 267 | request-gpios = <&gpio 170 0>; /* gpio PV2 */ |
268 | slave-addr = <138>; | 268 | slave-addr = <138>; |
269 | clocks = <&tegra_car 67>, <&tegra_car 124>; | ||
270 | clock-names = "div-clk", "fast-clk"; | ||
269 | }; | 271 | }; |
270 | 272 | ||
271 | i2c@7000d000 { | 273 | i2c@7000d000 { |
@@ -418,6 +420,10 @@ | |||
418 | status = "okay"; | 420 | status = "okay"; |
419 | }; | 421 | }; |
420 | 422 | ||
423 | usb-phy@c5004400 { | ||
424 | nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ | ||
425 | }; | ||
426 | |||
421 | sdhci@c8000000 { | 427 | sdhci@c8000000 { |
422 | status = "okay"; | 428 | status = "okay"; |
423 | cd-gpios = <&gpio 173 0>; /* gpio PV5 */ | 429 | cd-gpios = <&gpio 173 0>; /* gpio PV5 */ |
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index 420459825b46..607bf0c6bf9c 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts | |||
@@ -561,6 +561,10 @@ | |||
561 | status = "okay"; | 561 | status = "okay"; |
562 | }; | 562 | }; |
563 | 563 | ||
564 | usb-phy@c5004400 { | ||
565 | nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ | ||
566 | }; | ||
567 | |||
564 | sdhci@c8000000 { | 568 | sdhci@c8000000 { |
565 | status = "okay"; | 569 | status = "okay"; |
566 | power-gpios = <&gpio 86 0>; /* gpio PK6 */ | 570 | power-gpios = <&gpio 86 0>; /* gpio PK6 */ |
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts index b70b4cb754c8..e47cf6a58b6f 100644 --- a/arch/arm/boot/dts/tegra20-trimslice.dts +++ b/arch/arm/boot/dts/tegra20-trimslice.dts | |||
@@ -310,6 +310,10 @@ | |||
310 | status = "okay"; | 310 | status = "okay"; |
311 | }; | 311 | }; |
312 | 312 | ||
313 | usb-phy@c5004400 { | ||
314 | nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ | ||
315 | }; | ||
316 | |||
313 | sdhci@c8000000 { | 317 | sdhci@c8000000 { |
314 | status = "okay"; | 318 | status = "okay"; |
315 | bus-width = <4>; | 319 | bus-width = <4>; |
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts index adc47547eaae..f6c61d10fd27 100644 --- a/arch/arm/boot/dts/tegra20-ventana.dts +++ b/arch/arm/boot/dts/tegra20-ventana.dts | |||
@@ -497,6 +497,10 @@ | |||
497 | status = "okay"; | 497 | status = "okay"; |
498 | }; | 498 | }; |
499 | 499 | ||
500 | usb-phy@c5004400 { | ||
501 | nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ | ||
502 | }; | ||
503 | |||
500 | sdhci@c8000000 { | 504 | sdhci@c8000000 { |
501 | status = "okay"; | 505 | status = "okay"; |
502 | power-gpios = <&gpio 86 0>; /* gpio PK6 */ | 506 | power-gpios = <&gpio 86 0>; /* gpio PK6 */ |
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index b8effa1cbda7..2e7c83c7253b 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
@@ -9,6 +9,7 @@ | |||
9 | reg = <0x50000000 0x00024000>; | 9 | reg = <0x50000000 0x00024000>; |
10 | interrupts = <0 65 0x04 /* mpcore syncpt */ | 10 | interrupts = <0 65 0x04 /* mpcore syncpt */ |
11 | 0 67 0x04>; /* mpcore general */ | 11 | 0 67 0x04>; /* mpcore general */ |
12 | clocks = <&tegra_car 28>; | ||
12 | 13 | ||
13 | #address-cells = <1>; | 14 | #address-cells = <1>; |
14 | #size-cells = <1>; | 15 | #size-cells = <1>; |
@@ -19,41 +20,49 @@ | |||
19 | compatible = "nvidia,tegra20-mpe"; | 20 | compatible = "nvidia,tegra20-mpe"; |
20 | reg = <0x54040000 0x00040000>; | 21 | reg = <0x54040000 0x00040000>; |
21 | interrupts = <0 68 0x04>; | 22 | interrupts = <0 68 0x04>; |
23 | clocks = <&tegra_car 60>; | ||
22 | }; | 24 | }; |
23 | 25 | ||
24 | vi { | 26 | vi { |
25 | compatible = "nvidia,tegra20-vi"; | 27 | compatible = "nvidia,tegra20-vi"; |
26 | reg = <0x54080000 0x00040000>; | 28 | reg = <0x54080000 0x00040000>; |
27 | interrupts = <0 69 0x04>; | 29 | interrupts = <0 69 0x04>; |
30 | clocks = <&tegra_car 100>; | ||
28 | }; | 31 | }; |
29 | 32 | ||
30 | epp { | 33 | epp { |
31 | compatible = "nvidia,tegra20-epp"; | 34 | compatible = "nvidia,tegra20-epp"; |
32 | reg = <0x540c0000 0x00040000>; | 35 | reg = <0x540c0000 0x00040000>; |
33 | interrupts = <0 70 0x04>; | 36 | interrupts = <0 70 0x04>; |
37 | clocks = <&tegra_car 19>; | ||
34 | }; | 38 | }; |
35 | 39 | ||
36 | isp { | 40 | isp { |
37 | compatible = "nvidia,tegra20-isp"; | 41 | compatible = "nvidia,tegra20-isp"; |
38 | reg = <0x54100000 0x00040000>; | 42 | reg = <0x54100000 0x00040000>; |
39 | interrupts = <0 71 0x04>; | 43 | interrupts = <0 71 0x04>; |
44 | clocks = <&tegra_car 23>; | ||
40 | }; | 45 | }; |
41 | 46 | ||
42 | gr2d { | 47 | gr2d { |
43 | compatible = "nvidia,tegra20-gr2d"; | 48 | compatible = "nvidia,tegra20-gr2d"; |
44 | reg = <0x54140000 0x00040000>; | 49 | reg = <0x54140000 0x00040000>; |
45 | interrupts = <0 72 0x04>; | 50 | interrupts = <0 72 0x04>; |
51 | clocks = <&tegra_car 21>; | ||
46 | }; | 52 | }; |
47 | 53 | ||
48 | gr3d { | 54 | gr3d { |
49 | compatible = "nvidia,tegra20-gr3d"; | 55 | compatible = "nvidia,tegra20-gr3d"; |
50 | reg = <0x54180000 0x00040000>; | 56 | reg = <0x54180000 0x00040000>; |
57 | clocks = <&tegra_car 24>; | ||
51 | }; | 58 | }; |
52 | 59 | ||
53 | dc@54200000 { | 60 | dc@54200000 { |
54 | compatible = "nvidia,tegra20-dc"; | 61 | compatible = "nvidia,tegra20-dc"; |
55 | reg = <0x54200000 0x00040000>; | 62 | reg = <0x54200000 0x00040000>; |
56 | interrupts = <0 73 0x04>; | 63 | interrupts = <0 73 0x04>; |
64 | clocks = <&tegra_car 27>, <&tegra_car 121>; | ||
65 | clock-names = "disp1", "parent"; | ||
57 | 66 | ||
58 | rgb { | 67 | rgb { |
59 | status = "disabled"; | 68 | status = "disabled"; |
@@ -64,6 +73,8 @@ | |||
64 | compatible = "nvidia,tegra20-dc"; | 73 | compatible = "nvidia,tegra20-dc"; |
65 | reg = <0x54240000 0x00040000>; | 74 | reg = <0x54240000 0x00040000>; |
66 | interrupts = <0 74 0x04>; | 75 | interrupts = <0 74 0x04>; |
76 | clocks = <&tegra_car 26>, <&tegra_car 121>; | ||
77 | clock-names = "disp2", "parent"; | ||
67 | 78 | ||
68 | rgb { | 79 | rgb { |
69 | status = "disabled"; | 80 | status = "disabled"; |
@@ -74,6 +85,8 @@ | |||
74 | compatible = "nvidia,tegra20-hdmi"; | 85 | compatible = "nvidia,tegra20-hdmi"; |
75 | reg = <0x54280000 0x00040000>; | 86 | reg = <0x54280000 0x00040000>; |
76 | interrupts = <0 75 0x04>; | 87 | interrupts = <0 75 0x04>; |
88 | clocks = <&tegra_car 51>, <&tegra_car 117>; | ||
89 | clock-names = "hdmi", "parent"; | ||
77 | status = "disabled"; | 90 | status = "disabled"; |
78 | }; | 91 | }; |
79 | 92 | ||
@@ -81,12 +94,14 @@ | |||
81 | compatible = "nvidia,tegra20-tvo"; | 94 | compatible = "nvidia,tegra20-tvo"; |
82 | reg = <0x542c0000 0x00040000>; | 95 | reg = <0x542c0000 0x00040000>; |
83 | interrupts = <0 76 0x04>; | 96 | interrupts = <0 76 0x04>; |
97 | clocks = <&tegra_car 102>; | ||
84 | status = "disabled"; | 98 | status = "disabled"; |
85 | }; | 99 | }; |
86 | 100 | ||
87 | dsi { | 101 | dsi { |
88 | compatible = "nvidia,tegra20-dsi"; | 102 | compatible = "nvidia,tegra20-dsi"; |
89 | reg = <0x54300000 0x00040000>; | 103 | reg = <0x54300000 0x00040000>; |
104 | clocks = <&tegra_car 48>; | ||
90 | status = "disabled"; | 105 | status = "disabled"; |
91 | }; | 106 | }; |
92 | }; | 107 | }; |
@@ -123,6 +138,12 @@ | |||
123 | 0 42 0x04>; | 138 | 0 42 0x04>; |
124 | }; | 139 | }; |
125 | 140 | ||
141 | tegra_car: clock { | ||
142 | compatible = "nvidia,tegra20-car"; | ||
143 | reg = <0x60006000 0x1000>; | ||
144 | #clock-cells = <1>; | ||
145 | }; | ||
146 | |||
126 | apbdma: dma { | 147 | apbdma: dma { |
127 | compatible = "nvidia,tegra20-apbdma"; | 148 | compatible = "nvidia,tegra20-apbdma"; |
128 | reg = <0x6000a000 0x1200>; | 149 | reg = <0x6000a000 0x1200>; |
@@ -142,6 +163,7 @@ | |||
142 | 0 117 0x04 | 163 | 0 117 0x04 |
143 | 0 118 0x04 | 164 | 0 118 0x04 |
144 | 0 119 0x04>; | 165 | 0 119 0x04>; |
166 | clocks = <&tegra_car 34>; | ||
145 | }; | 167 | }; |
146 | 168 | ||
147 | ahb { | 169 | ahb { |
@@ -183,6 +205,7 @@ | |||
183 | reg = <0x70002800 0x200>; | 205 | reg = <0x70002800 0x200>; |
184 | interrupts = <0 13 0x04>; | 206 | interrupts = <0 13 0x04>; |
185 | nvidia,dma-request-selector = <&apbdma 2>; | 207 | nvidia,dma-request-selector = <&apbdma 2>; |
208 | clocks = <&tegra_car 11>; | ||
186 | status = "disabled"; | 209 | status = "disabled"; |
187 | }; | 210 | }; |
188 | 211 | ||
@@ -191,6 +214,7 @@ | |||
191 | reg = <0x70002a00 0x200>; | 214 | reg = <0x70002a00 0x200>; |
192 | interrupts = <0 3 0x04>; | 215 | interrupts = <0 3 0x04>; |
193 | nvidia,dma-request-selector = <&apbdma 1>; | 216 | nvidia,dma-request-selector = <&apbdma 1>; |
217 | clocks = <&tegra_car 18>; | ||
194 | status = "disabled"; | 218 | status = "disabled"; |
195 | }; | 219 | }; |
196 | 220 | ||
@@ -199,6 +223,7 @@ | |||
199 | reg = <0x70006000 0x40>; | 223 | reg = <0x70006000 0x40>; |
200 | reg-shift = <2>; | 224 | reg-shift = <2>; |
201 | interrupts = <0 36 0x04>; | 225 | interrupts = <0 36 0x04>; |
226 | clocks = <&tegra_car 6>; | ||
202 | status = "disabled"; | 227 | status = "disabled"; |
203 | }; | 228 | }; |
204 | 229 | ||
@@ -207,6 +232,7 @@ | |||
207 | reg = <0x70006040 0x40>; | 232 | reg = <0x70006040 0x40>; |
208 | reg-shift = <2>; | 233 | reg-shift = <2>; |
209 | interrupts = <0 37 0x04>; | 234 | interrupts = <0 37 0x04>; |
235 | clocks = <&tegra_car 96>; | ||
210 | status = "disabled"; | 236 | status = "disabled"; |
211 | }; | 237 | }; |
212 | 238 | ||
@@ -215,6 +241,7 @@ | |||
215 | reg = <0x70006200 0x100>; | 241 | reg = <0x70006200 0x100>; |
216 | reg-shift = <2>; | 242 | reg-shift = <2>; |
217 | interrupts = <0 46 0x04>; | 243 | interrupts = <0 46 0x04>; |
244 | clocks = <&tegra_car 55>; | ||
218 | status = "disabled"; | 245 | status = "disabled"; |
219 | }; | 246 | }; |
220 | 247 | ||
@@ -223,6 +250,7 @@ | |||
223 | reg = <0x70006300 0x100>; | 250 | reg = <0x70006300 0x100>; |
224 | reg-shift = <2>; | 251 | reg-shift = <2>; |
225 | interrupts = <0 90 0x04>; | 252 | interrupts = <0 90 0x04>; |
253 | clocks = <&tegra_car 65>; | ||
226 | status = "disabled"; | 254 | status = "disabled"; |
227 | }; | 255 | }; |
228 | 256 | ||
@@ -231,6 +259,7 @@ | |||
231 | reg = <0x70006400 0x100>; | 259 | reg = <0x70006400 0x100>; |
232 | reg-shift = <2>; | 260 | reg-shift = <2>; |
233 | interrupts = <0 91 0x04>; | 261 | interrupts = <0 91 0x04>; |
262 | clocks = <&tegra_car 66>; | ||
234 | status = "disabled"; | 263 | status = "disabled"; |
235 | }; | 264 | }; |
236 | 265 | ||
@@ -238,6 +267,7 @@ | |||
238 | compatible = "nvidia,tegra20-pwm"; | 267 | compatible = "nvidia,tegra20-pwm"; |
239 | reg = <0x7000a000 0x100>; | 268 | reg = <0x7000a000 0x100>; |
240 | #pwm-cells = <2>; | 269 | #pwm-cells = <2>; |
270 | clocks = <&tegra_car 17>; | ||
241 | }; | 271 | }; |
242 | 272 | ||
243 | rtc { | 273 | rtc { |
@@ -252,6 +282,8 @@ | |||
252 | interrupts = <0 38 0x04>; | 282 | interrupts = <0 38 0x04>; |
253 | #address-cells = <1>; | 283 | #address-cells = <1>; |
254 | #size-cells = <0>; | 284 | #size-cells = <0>; |
285 | clocks = <&tegra_car 12>, <&tegra_car 124>; | ||
286 | clock-names = "div-clk", "fast-clk"; | ||
255 | status = "disabled"; | 287 | status = "disabled"; |
256 | }; | 288 | }; |
257 | 289 | ||
@@ -262,6 +294,7 @@ | |||
262 | nvidia,dma-request-selector = <&apbdma 11>; | 294 | nvidia,dma-request-selector = <&apbdma 11>; |
263 | #address-cells = <1>; | 295 | #address-cells = <1>; |
264 | #size-cells = <0>; | 296 | #size-cells = <0>; |
297 | clocks = <&tegra_car 43>; | ||
265 | status = "disabled"; | 298 | status = "disabled"; |
266 | }; | 299 | }; |
267 | 300 | ||
@@ -271,6 +304,8 @@ | |||
271 | interrupts = <0 84 0x04>; | 304 | interrupts = <0 84 0x04>; |
272 | #address-cells = <1>; | 305 | #address-cells = <1>; |
273 | #size-cells = <0>; | 306 | #size-cells = <0>; |
307 | clocks = <&tegra_car 54>, <&tegra_car 124>; | ||
308 | clock-names = "div-clk", "fast-clk"; | ||
274 | status = "disabled"; | 309 | status = "disabled"; |
275 | }; | 310 | }; |
276 | 311 | ||
@@ -280,6 +315,8 @@ | |||
280 | interrupts = <0 92 0x04>; | 315 | interrupts = <0 92 0x04>; |
281 | #address-cells = <1>; | 316 | #address-cells = <1>; |
282 | #size-cells = <0>; | 317 | #size-cells = <0>; |
318 | clocks = <&tegra_car 67>, <&tegra_car 124>; | ||
319 | clock-names = "div-clk", "fast-clk"; | ||
283 | status = "disabled"; | 320 | status = "disabled"; |
284 | }; | 321 | }; |
285 | 322 | ||
@@ -289,6 +326,8 @@ | |||
289 | interrupts = <0 53 0x04>; | 326 | interrupts = <0 53 0x04>; |
290 | #address-cells = <1>; | 327 | #address-cells = <1>; |
291 | #size-cells = <0>; | 328 | #size-cells = <0>; |
329 | clocks = <&tegra_car 47>, <&tegra_car 124>; | ||
330 | clock-names = "div-clk", "fast-clk"; | ||
292 | status = "disabled"; | 331 | status = "disabled"; |
293 | }; | 332 | }; |
294 | 333 | ||
@@ -299,6 +338,7 @@ | |||
299 | nvidia,dma-request-selector = <&apbdma 15>; | 338 | nvidia,dma-request-selector = <&apbdma 15>; |
300 | #address-cells = <1>; | 339 | #address-cells = <1>; |
301 | #size-cells = <0>; | 340 | #size-cells = <0>; |
341 | clocks = <&tegra_car 41>; | ||
302 | status = "disabled"; | 342 | status = "disabled"; |
303 | }; | 343 | }; |
304 | 344 | ||
@@ -309,6 +349,7 @@ | |||
309 | nvidia,dma-request-selector = <&apbdma 16>; | 349 | nvidia,dma-request-selector = <&apbdma 16>; |
310 | #address-cells = <1>; | 350 | #address-cells = <1>; |
311 | #size-cells = <0>; | 351 | #size-cells = <0>; |
352 | clocks = <&tegra_car 44>; | ||
312 | status = "disabled"; | 353 | status = "disabled"; |
313 | }; | 354 | }; |
314 | 355 | ||
@@ -319,6 +360,7 @@ | |||
319 | nvidia,dma-request-selector = <&apbdma 17>; | 360 | nvidia,dma-request-selector = <&apbdma 17>; |
320 | #address-cells = <1>; | 361 | #address-cells = <1>; |
321 | #size-cells = <0>; | 362 | #size-cells = <0>; |
363 | clocks = <&tegra_car 46>; | ||
322 | status = "disabled"; | 364 | status = "disabled"; |
323 | }; | 365 | }; |
324 | 366 | ||
@@ -329,6 +371,7 @@ | |||
329 | nvidia,dma-request-selector = <&apbdma 18>; | 371 | nvidia,dma-request-selector = <&apbdma 18>; |
330 | #address-cells = <1>; | 372 | #address-cells = <1>; |
331 | #size-cells = <0>; | 373 | #size-cells = <0>; |
374 | clocks = <&tegra_car 68>; | ||
332 | status = "disabled"; | 375 | status = "disabled"; |
333 | }; | 376 | }; |
334 | 377 | ||
@@ -357,12 +400,40 @@ | |||
357 | #size-cells = <0>; | 400 | #size-cells = <0>; |
358 | }; | 401 | }; |
359 | 402 | ||
403 | phy1: usb-phy@c5000400 { | ||
404 | compatible = "nvidia,tegra20-usb-phy"; | ||
405 | reg = <0xc5000400 0x3c00>; | ||
406 | phy_type = "utmi"; | ||
407 | nvidia,has-legacy-mode; | ||
408 | clocks = <&tegra_car 22>, <&tegra_car 127>; | ||
409 | clock-names = "phy", "pll_u"; | ||
410 | }; | ||
411 | |||
412 | phy2: usb-phy@c5004400 { | ||
413 | compatible = "nvidia,tegra20-usb-phy"; | ||
414 | reg = <0xc5004400 0x3c00>; | ||
415 | phy_type = "ulpi"; | ||
416 | clocks = <&tegra_car 94>, <&tegra_car 127>; | ||
417 | clock-names = "phy", "pll_u"; | ||
418 | }; | ||
419 | |||
420 | phy3: usb-phy@c5008400 { | ||
421 | compatible = "nvidia,tegra20-usb-phy"; | ||
422 | reg = <0xc5008400 0x3C00>; | ||
423 | phy_type = "utmi"; | ||
424 | clocks = <&tegra_car 22>, <&tegra_car 127>; | ||
425 | clock-names = "phy", "pll_u"; | ||
426 | }; | ||
427 | |||
360 | usb@c5000000 { | 428 | usb@c5000000 { |
361 | compatible = "nvidia,tegra20-ehci", "usb-ehci"; | 429 | compatible = "nvidia,tegra20-ehci", "usb-ehci"; |
362 | reg = <0xc5000000 0x4000>; | 430 | reg = <0xc5000000 0x4000>; |
363 | interrupts = <0 20 0x04>; | 431 | interrupts = <0 20 0x04>; |
364 | phy_type = "utmi"; | 432 | phy_type = "utmi"; |
365 | nvidia,has-legacy-mode; | 433 | nvidia,has-legacy-mode; |
434 | clocks = <&tegra_car 22>; | ||
435 | nvidia,needs-double-reset; | ||
436 | nvidia,phy = <&phy1>; | ||
366 | status = "disabled"; | 437 | status = "disabled"; |
367 | }; | 438 | }; |
368 | 439 | ||
@@ -371,6 +442,8 @@ | |||
371 | reg = <0xc5004000 0x4000>; | 442 | reg = <0xc5004000 0x4000>; |
372 | interrupts = <0 21 0x04>; | 443 | interrupts = <0 21 0x04>; |
373 | phy_type = "ulpi"; | 444 | phy_type = "ulpi"; |
445 | clocks = <&tegra_car 58>; | ||
446 | nvidia,phy = <&phy2>; | ||
374 | status = "disabled"; | 447 | status = "disabled"; |
375 | }; | 448 | }; |
376 | 449 | ||
@@ -379,6 +452,8 @@ | |||
379 | reg = <0xc5008000 0x4000>; | 452 | reg = <0xc5008000 0x4000>; |
380 | interrupts = <0 97 0x04>; | 453 | interrupts = <0 97 0x04>; |
381 | phy_type = "utmi"; | 454 | phy_type = "utmi"; |
455 | clocks = <&tegra_car 59>; | ||
456 | nvidia,phy = <&phy3>; | ||
382 | status = "disabled"; | 457 | status = "disabled"; |
383 | }; | 458 | }; |
384 | 459 | ||
@@ -386,6 +461,7 @@ | |||
386 | compatible = "nvidia,tegra20-sdhci"; | 461 | compatible = "nvidia,tegra20-sdhci"; |
387 | reg = <0xc8000000 0x200>; | 462 | reg = <0xc8000000 0x200>; |
388 | interrupts = <0 14 0x04>; | 463 | interrupts = <0 14 0x04>; |
464 | clocks = <&tegra_car 14>; | ||
389 | status = "disabled"; | 465 | status = "disabled"; |
390 | }; | 466 | }; |
391 | 467 | ||
@@ -393,6 +469,7 @@ | |||
393 | compatible = "nvidia,tegra20-sdhci"; | 469 | compatible = "nvidia,tegra20-sdhci"; |
394 | reg = <0xc8000200 0x200>; | 470 | reg = <0xc8000200 0x200>; |
395 | interrupts = <0 15 0x04>; | 471 | interrupts = <0 15 0x04>; |
472 | clocks = <&tegra_car 9>; | ||
396 | status = "disabled"; | 473 | status = "disabled"; |
397 | }; | 474 | }; |
398 | 475 | ||
@@ -400,6 +477,7 @@ | |||
400 | compatible = "nvidia,tegra20-sdhci"; | 477 | compatible = "nvidia,tegra20-sdhci"; |
401 | reg = <0xc8000400 0x200>; | 478 | reg = <0xc8000400 0x200>; |
402 | interrupts = <0 19 0x04>; | 479 | interrupts = <0 19 0x04>; |
480 | clocks = <&tegra_car 69>; | ||
403 | status = "disabled"; | 481 | status = "disabled"; |
404 | }; | 482 | }; |
405 | 483 | ||
@@ -407,9 +485,27 @@ | |||
407 | compatible = "nvidia,tegra20-sdhci"; | 485 | compatible = "nvidia,tegra20-sdhci"; |
408 | reg = <0xc8000600 0x200>; | 486 | reg = <0xc8000600 0x200>; |
409 | interrupts = <0 31 0x04>; | 487 | interrupts = <0 31 0x04>; |
488 | clocks = <&tegra_car 15>; | ||
410 | status = "disabled"; | 489 | status = "disabled"; |
411 | }; | 490 | }; |
412 | 491 | ||
492 | cpus { | ||
493 | #address-cells = <1>; | ||
494 | #size-cells = <0>; | ||
495 | |||
496 | cpu@0 { | ||
497 | device_type = "cpu"; | ||
498 | compatible = "arm,cortex-a9"; | ||
499 | reg = <0>; | ||
500 | }; | ||
501 | |||
502 | cpu@1 { | ||
503 | device_type = "cpu"; | ||
504 | compatible = "arm,cortex-a9"; | ||
505 | reg = <1>; | ||
506 | }; | ||
507 | }; | ||
508 | |||
413 | pmu { | 509 | pmu { |
414 | compatible = "arm,cortex-a9-pmu"; | 510 | compatible = "arm,cortex-a9-pmu"; |
415 | interrupts = <0 56 0x04 | 511 | interrupts = <0 56 0x04 |
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 529fdb82dfdb..2de8b919d78c 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi | |||
@@ -9,6 +9,7 @@ | |||
9 | reg = <0x50000000 0x00024000>; | 9 | reg = <0x50000000 0x00024000>; |
10 | interrupts = <0 65 0x04 /* mpcore syncpt */ | 10 | interrupts = <0 65 0x04 /* mpcore syncpt */ |
11 | 0 67 0x04>; /* mpcore general */ | 11 | 0 67 0x04>; /* mpcore general */ |
12 | clocks = <&tegra_car 28>; | ||
12 | 13 | ||
13 | #address-cells = <1>; | 14 | #address-cells = <1>; |
14 | #size-cells = <1>; | 15 | #size-cells = <1>; |
@@ -19,41 +20,50 @@ | |||
19 | compatible = "nvidia,tegra30-mpe"; | 20 | compatible = "nvidia,tegra30-mpe"; |
20 | reg = <0x54040000 0x00040000>; | 21 | reg = <0x54040000 0x00040000>; |
21 | interrupts = <0 68 0x04>; | 22 | interrupts = <0 68 0x04>; |
23 | clocks = <&tegra_car 60>; | ||
22 | }; | 24 | }; |
23 | 25 | ||
24 | vi { | 26 | vi { |
25 | compatible = "nvidia,tegra30-vi"; | 27 | compatible = "nvidia,tegra30-vi"; |
26 | reg = <0x54080000 0x00040000>; | 28 | reg = <0x54080000 0x00040000>; |
27 | interrupts = <0 69 0x04>; | 29 | interrupts = <0 69 0x04>; |
30 | clocks = <&tegra_car 164>; | ||
28 | }; | 31 | }; |
29 | 32 | ||
30 | epp { | 33 | epp { |
31 | compatible = "nvidia,tegra30-epp"; | 34 | compatible = "nvidia,tegra30-epp"; |
32 | reg = <0x540c0000 0x00040000>; | 35 | reg = <0x540c0000 0x00040000>; |
33 | interrupts = <0 70 0x04>; | 36 | interrupts = <0 70 0x04>; |
37 | clocks = <&tegra_car 19>; | ||
34 | }; | 38 | }; |
35 | 39 | ||
36 | isp { | 40 | isp { |
37 | compatible = "nvidia,tegra30-isp"; | 41 | compatible = "nvidia,tegra30-isp"; |
38 | reg = <0x54100000 0x00040000>; | 42 | reg = <0x54100000 0x00040000>; |
39 | interrupts = <0 71 0x04>; | 43 | interrupts = <0 71 0x04>; |
44 | clocks = <&tegra_car 23>; | ||
40 | }; | 45 | }; |
41 | 46 | ||
42 | gr2d { | 47 | gr2d { |
43 | compatible = "nvidia,tegra30-gr2d"; | 48 | compatible = "nvidia,tegra30-gr2d"; |
44 | reg = <0x54140000 0x00040000>; | 49 | reg = <0x54140000 0x00040000>; |
45 | interrupts = <0 72 0x04>; | 50 | interrupts = <0 72 0x04>; |
51 | clocks = <&tegra_car 21>; | ||
46 | }; | 52 | }; |
47 | 53 | ||
48 | gr3d { | 54 | gr3d { |
49 | compatible = "nvidia,tegra30-gr3d"; | 55 | compatible = "nvidia,tegra30-gr3d"; |
50 | reg = <0x54180000 0x00040000>; | 56 | reg = <0x54180000 0x00040000>; |
57 | clocks = <&tegra_car 24 &tegra_car 98>; | ||
58 | clock-names = "3d", "3d2"; | ||
51 | }; | 59 | }; |
52 | 60 | ||
53 | dc@54200000 { | 61 | dc@54200000 { |
54 | compatible = "nvidia,tegra30-dc"; | 62 | compatible = "nvidia,tegra30-dc"; |
55 | reg = <0x54200000 0x00040000>; | 63 | reg = <0x54200000 0x00040000>; |
56 | interrupts = <0 73 0x04>; | 64 | interrupts = <0 73 0x04>; |
65 | clocks = <&tegra_car 27>, <&tegra_car 179>; | ||
66 | clock-names = "disp1", "parent"; | ||
57 | 67 | ||
58 | rgb { | 68 | rgb { |
59 | status = "disabled"; | 69 | status = "disabled"; |
@@ -64,6 +74,8 @@ | |||
64 | compatible = "nvidia,tegra30-dc"; | 74 | compatible = "nvidia,tegra30-dc"; |
65 | reg = <0x54240000 0x00040000>; | 75 | reg = <0x54240000 0x00040000>; |
66 | interrupts = <0 74 0x04>; | 76 | interrupts = <0 74 0x04>; |
77 | clocks = <&tegra_car 26>, <&tegra_car 179>; | ||
78 | clock-names = "disp2", "parent"; | ||
67 | 79 | ||
68 | rgb { | 80 | rgb { |
69 | status = "disabled"; | 81 | status = "disabled"; |
@@ -74,6 +86,8 @@ | |||
74 | compatible = "nvidia,tegra30-hdmi"; | 86 | compatible = "nvidia,tegra30-hdmi"; |
75 | reg = <0x54280000 0x00040000>; | 87 | reg = <0x54280000 0x00040000>; |
76 | interrupts = <0 75 0x04>; | 88 | interrupts = <0 75 0x04>; |
89 | clocks = <&tegra_car 51>, <&tegra_car 189>; | ||
90 | clock-names = "hdmi", "parent"; | ||
77 | status = "disabled"; | 91 | status = "disabled"; |
78 | }; | 92 | }; |
79 | 93 | ||
@@ -81,12 +95,14 @@ | |||
81 | compatible = "nvidia,tegra30-tvo"; | 95 | compatible = "nvidia,tegra30-tvo"; |
82 | reg = <0x542c0000 0x00040000>; | 96 | reg = <0x542c0000 0x00040000>; |
83 | interrupts = <0 76 0x04>; | 97 | interrupts = <0 76 0x04>; |
98 | clocks = <&tegra_car 169>; | ||
84 | status = "disabled"; | 99 | status = "disabled"; |
85 | }; | 100 | }; |
86 | 101 | ||
87 | dsi { | 102 | dsi { |
88 | compatible = "nvidia,tegra30-dsi"; | 103 | compatible = "nvidia,tegra30-dsi"; |
89 | reg = <0x54300000 0x00040000>; | 104 | reg = <0x54300000 0x00040000>; |
105 | clocks = <&tegra_car 48>; | ||
90 | status = "disabled"; | 106 | status = "disabled"; |
91 | }; | 107 | }; |
92 | }; | 108 | }; |
@@ -125,6 +141,12 @@ | |||
125 | 0 122 0x04>; | 141 | 0 122 0x04>; |
126 | }; | 142 | }; |
127 | 143 | ||
144 | tegra_car: clock { | ||
145 | compatible = "nvidia,tegra30-car"; | ||
146 | reg = <0x60006000 0x1000>; | ||
147 | #clock-cells = <1>; | ||
148 | }; | ||
149 | |||
128 | apbdma: dma { | 150 | apbdma: dma { |
129 | compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; | 151 | compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; |
130 | reg = <0x6000a000 0x1400>; | 152 | reg = <0x6000a000 0x1400>; |
@@ -160,6 +182,7 @@ | |||
160 | 0 141 0x04 | 182 | 0 141 0x04 |
161 | 0 142 0x04 | 183 | 0 142 0x04 |
162 | 0 143 0x04>; | 184 | 0 143 0x04>; |
185 | clocks = <&tegra_car 34>; | ||
163 | }; | 186 | }; |
164 | 187 | ||
165 | ahb: ahb { | 188 | ahb: ahb { |
@@ -195,6 +218,7 @@ | |||
195 | reg = <0x70006000 0x40>; | 218 | reg = <0x70006000 0x40>; |
196 | reg-shift = <2>; | 219 | reg-shift = <2>; |
197 | interrupts = <0 36 0x04>; | 220 | interrupts = <0 36 0x04>; |
221 | clocks = <&tegra_car 6>; | ||
198 | status = "disabled"; | 222 | status = "disabled"; |
199 | }; | 223 | }; |
200 | 224 | ||
@@ -203,6 +227,7 @@ | |||
203 | reg = <0x70006040 0x40>; | 227 | reg = <0x70006040 0x40>; |
204 | reg-shift = <2>; | 228 | reg-shift = <2>; |
205 | interrupts = <0 37 0x04>; | 229 | interrupts = <0 37 0x04>; |
230 | clocks = <&tegra_car 160>; | ||
206 | status = "disabled"; | 231 | status = "disabled"; |
207 | }; | 232 | }; |
208 | 233 | ||
@@ -211,6 +236,7 @@ | |||
211 | reg = <0x70006200 0x100>; | 236 | reg = <0x70006200 0x100>; |
212 | reg-shift = <2>; | 237 | reg-shift = <2>; |
213 | interrupts = <0 46 0x04>; | 238 | interrupts = <0 46 0x04>; |
239 | clocks = <&tegra_car 55>; | ||
214 | status = "disabled"; | 240 | status = "disabled"; |
215 | }; | 241 | }; |
216 | 242 | ||
@@ -219,6 +245,7 @@ | |||
219 | reg = <0x70006300 0x100>; | 245 | reg = <0x70006300 0x100>; |
220 | reg-shift = <2>; | 246 | reg-shift = <2>; |
221 | interrupts = <0 90 0x04>; | 247 | interrupts = <0 90 0x04>; |
248 | clocks = <&tegra_car 65>; | ||
222 | status = "disabled"; | 249 | status = "disabled"; |
223 | }; | 250 | }; |
224 | 251 | ||
@@ -227,6 +254,7 @@ | |||
227 | reg = <0x70006400 0x100>; | 254 | reg = <0x70006400 0x100>; |
228 | reg-shift = <2>; | 255 | reg-shift = <2>; |
229 | interrupts = <0 91 0x04>; | 256 | interrupts = <0 91 0x04>; |
257 | clocks = <&tegra_car 66>; | ||
230 | status = "disabled"; | 258 | status = "disabled"; |
231 | }; | 259 | }; |
232 | 260 | ||
@@ -234,6 +262,7 @@ | |||
234 | compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm"; | 262 | compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm"; |
235 | reg = <0x7000a000 0x100>; | 263 | reg = <0x7000a000 0x100>; |
236 | #pwm-cells = <2>; | 264 | #pwm-cells = <2>; |
265 | clocks = <&tegra_car 17>; | ||
237 | }; | 266 | }; |
238 | 267 | ||
239 | rtc { | 268 | rtc { |
@@ -248,6 +277,8 @@ | |||
248 | interrupts = <0 38 0x04>; | 277 | interrupts = <0 38 0x04>; |
249 | #address-cells = <1>; | 278 | #address-cells = <1>; |
250 | #size-cells = <0>; | 279 | #size-cells = <0>; |
280 | clocks = <&tegra_car 12>, <&tegra_car 182>; | ||
281 | clock-names = "div-clk", "fast-clk"; | ||
251 | status = "disabled"; | 282 | status = "disabled"; |
252 | }; | 283 | }; |
253 | 284 | ||
@@ -257,6 +288,8 @@ | |||
257 | interrupts = <0 84 0x04>; | 288 | interrupts = <0 84 0x04>; |
258 | #address-cells = <1>; | 289 | #address-cells = <1>; |
259 | #size-cells = <0>; | 290 | #size-cells = <0>; |
291 | clocks = <&tegra_car 54>, <&tegra_car 182>; | ||
292 | clock-names = "div-clk", "fast-clk"; | ||
260 | status = "disabled"; | 293 | status = "disabled"; |
261 | }; | 294 | }; |
262 | 295 | ||
@@ -266,6 +299,8 @@ | |||
266 | interrupts = <0 92 0x04>; | 299 | interrupts = <0 92 0x04>; |
267 | #address-cells = <1>; | 300 | #address-cells = <1>; |
268 | #size-cells = <0>; | 301 | #size-cells = <0>; |
302 | clocks = <&tegra_car 67>, <&tegra_car 182>; | ||
303 | clock-names = "div-clk", "fast-clk"; | ||
269 | status = "disabled"; | 304 | status = "disabled"; |
270 | }; | 305 | }; |
271 | 306 | ||
@@ -275,6 +310,8 @@ | |||
275 | interrupts = <0 120 0x04>; | 310 | interrupts = <0 120 0x04>; |
276 | #address-cells = <1>; | 311 | #address-cells = <1>; |
277 | #size-cells = <0>; | 312 | #size-cells = <0>; |
313 | clocks = <&tegra_car 103>, <&tegra_car 182>; | ||
314 | clock-names = "div-clk", "fast-clk"; | ||
278 | status = "disabled"; | 315 | status = "disabled"; |
279 | }; | 316 | }; |
280 | 317 | ||
@@ -284,6 +321,8 @@ | |||
284 | interrupts = <0 53 0x04>; | 321 | interrupts = <0 53 0x04>; |
285 | #address-cells = <1>; | 322 | #address-cells = <1>; |
286 | #size-cells = <0>; | 323 | #size-cells = <0>; |
324 | clocks = <&tegra_car 47>, <&tegra_car 182>; | ||
325 | clock-names = "div-clk", "fast-clk"; | ||
287 | status = "disabled"; | 326 | status = "disabled"; |
288 | }; | 327 | }; |
289 | 328 | ||
@@ -294,6 +333,7 @@ | |||
294 | nvidia,dma-request-selector = <&apbdma 15>; | 333 | nvidia,dma-request-selector = <&apbdma 15>; |
295 | #address-cells = <1>; | 334 | #address-cells = <1>; |
296 | #size-cells = <0>; | 335 | #size-cells = <0>; |
336 | clocks = <&tegra_car 41>; | ||
297 | status = "disabled"; | 337 | status = "disabled"; |
298 | }; | 338 | }; |
299 | 339 | ||
@@ -304,6 +344,7 @@ | |||
304 | nvidia,dma-request-selector = <&apbdma 16>; | 344 | nvidia,dma-request-selector = <&apbdma 16>; |
305 | #address-cells = <1>; | 345 | #address-cells = <1>; |
306 | #size-cells = <0>; | 346 | #size-cells = <0>; |
347 | clocks = <&tegra_car 44>; | ||
307 | status = "disabled"; | 348 | status = "disabled"; |
308 | }; | 349 | }; |
309 | 350 | ||
@@ -314,6 +355,7 @@ | |||
314 | nvidia,dma-request-selector = <&apbdma 17>; | 355 | nvidia,dma-request-selector = <&apbdma 17>; |
315 | #address-cells = <1>; | 356 | #address-cells = <1>; |
316 | #size-cells = <0>; | 357 | #size-cells = <0>; |
358 | clocks = <&tegra_car 46>; | ||
317 | status = "disabled"; | 359 | status = "disabled"; |
318 | }; | 360 | }; |
319 | 361 | ||
@@ -324,6 +366,7 @@ | |||
324 | nvidia,dma-request-selector = <&apbdma 18>; | 366 | nvidia,dma-request-selector = <&apbdma 18>; |
325 | #address-cells = <1>; | 367 | #address-cells = <1>; |
326 | #size-cells = <0>; | 368 | #size-cells = <0>; |
369 | clocks = <&tegra_car 68>; | ||
327 | status = "disabled"; | 370 | status = "disabled"; |
328 | }; | 371 | }; |
329 | 372 | ||
@@ -334,6 +377,7 @@ | |||
334 | nvidia,dma-request-selector = <&apbdma 27>; | 377 | nvidia,dma-request-selector = <&apbdma 27>; |
335 | #address-cells = <1>; | 378 | #address-cells = <1>; |
336 | #size-cells = <0>; | 379 | #size-cells = <0>; |
380 | clocks = <&tegra_car 104>; | ||
337 | status = "disabled"; | 381 | status = "disabled"; |
338 | }; | 382 | }; |
339 | 383 | ||
@@ -344,6 +388,7 @@ | |||
344 | nvidia,dma-request-selector = <&apbdma 28>; | 388 | nvidia,dma-request-selector = <&apbdma 28>; |
345 | #address-cells = <1>; | 389 | #address-cells = <1>; |
346 | #size-cells = <0>; | 390 | #size-cells = <0>; |
391 | clocks = <&tegra_car 105>; | ||
347 | status = "disabled"; | 392 | status = "disabled"; |
348 | }; | 393 | }; |
349 | 394 | ||
@@ -377,7 +422,13 @@ | |||
377 | 0x70080200 0x100>; | 422 | 0x70080200 0x100>; |
378 | interrupts = <0 103 0x04>; | 423 | interrupts = <0 103 0x04>; |
379 | nvidia,dma-request-selector = <&apbdma 1>; | 424 | nvidia,dma-request-selector = <&apbdma 1>; |
380 | 425 | clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>, | |
426 | <&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>, | ||
427 | <&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>, | ||
428 | <&tegra_car 110>, <&tegra_car 162>; | ||
429 | clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", | ||
430 | "i2s3", "i2s4", "dam0", "dam1", "dam2", | ||
431 | "spdif_in"; | ||
381 | ranges; | 432 | ranges; |
382 | #address-cells = <1>; | 433 | #address-cells = <1>; |
383 | #size-cells = <1>; | 434 | #size-cells = <1>; |
@@ -386,6 +437,7 @@ | |||
386 | compatible = "nvidia,tegra30-i2s"; | 437 | compatible = "nvidia,tegra30-i2s"; |
387 | reg = <0x70080300 0x100>; | 438 | reg = <0x70080300 0x100>; |
388 | nvidia,ahub-cif-ids = <4 4>; | 439 | nvidia,ahub-cif-ids = <4 4>; |
440 | clocks = <&tegra_car 30>; | ||
389 | status = "disabled"; | 441 | status = "disabled"; |
390 | }; | 442 | }; |
391 | 443 | ||
@@ -393,6 +445,7 @@ | |||
393 | compatible = "nvidia,tegra30-i2s"; | 445 | compatible = "nvidia,tegra30-i2s"; |
394 | reg = <0x70080400 0x100>; | 446 | reg = <0x70080400 0x100>; |
395 | nvidia,ahub-cif-ids = <5 5>; | 447 | nvidia,ahub-cif-ids = <5 5>; |
448 | clocks = <&tegra_car 11>; | ||
396 | status = "disabled"; | 449 | status = "disabled"; |
397 | }; | 450 | }; |
398 | 451 | ||
@@ -400,6 +453,7 @@ | |||
400 | compatible = "nvidia,tegra30-i2s"; | 453 | compatible = "nvidia,tegra30-i2s"; |
401 | reg = <0x70080500 0x100>; | 454 | reg = <0x70080500 0x100>; |
402 | nvidia,ahub-cif-ids = <6 6>; | 455 | nvidia,ahub-cif-ids = <6 6>; |
456 | clocks = <&tegra_car 18>; | ||
403 | status = "disabled"; | 457 | status = "disabled"; |
404 | }; | 458 | }; |
405 | 459 | ||
@@ -407,6 +461,7 @@ | |||
407 | compatible = "nvidia,tegra30-i2s"; | 461 | compatible = "nvidia,tegra30-i2s"; |
408 | reg = <0x70080600 0x100>; | 462 | reg = <0x70080600 0x100>; |
409 | nvidia,ahub-cif-ids = <7 7>; | 463 | nvidia,ahub-cif-ids = <7 7>; |
464 | clocks = <&tegra_car 101>; | ||
410 | status = "disabled"; | 465 | status = "disabled"; |
411 | }; | 466 | }; |
412 | 467 | ||
@@ -414,6 +469,7 @@ | |||
414 | compatible = "nvidia,tegra30-i2s"; | 469 | compatible = "nvidia,tegra30-i2s"; |
415 | reg = <0x70080700 0x100>; | 470 | reg = <0x70080700 0x100>; |
416 | nvidia,ahub-cif-ids = <8 8>; | 471 | nvidia,ahub-cif-ids = <8 8>; |
472 | clocks = <&tegra_car 102>; | ||
417 | status = "disabled"; | 473 | status = "disabled"; |
418 | }; | 474 | }; |
419 | }; | 475 | }; |
@@ -422,6 +478,7 @@ | |||
422 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; | 478 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; |
423 | reg = <0x78000000 0x200>; | 479 | reg = <0x78000000 0x200>; |
424 | interrupts = <0 14 0x04>; | 480 | interrupts = <0 14 0x04>; |
481 | clocks = <&tegra_car 14>; | ||
425 | status = "disabled"; | 482 | status = "disabled"; |
426 | }; | 483 | }; |
427 | 484 | ||
@@ -429,6 +486,7 @@ | |||
429 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; | 486 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; |
430 | reg = <0x78000200 0x200>; | 487 | reg = <0x78000200 0x200>; |
431 | interrupts = <0 15 0x04>; | 488 | interrupts = <0 15 0x04>; |
489 | clocks = <&tegra_car 9>; | ||
432 | status = "disabled"; | 490 | status = "disabled"; |
433 | }; | 491 | }; |
434 | 492 | ||
@@ -436,6 +494,7 @@ | |||
436 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; | 494 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; |
437 | reg = <0x78000400 0x200>; | 495 | reg = <0x78000400 0x200>; |
438 | interrupts = <0 19 0x04>; | 496 | interrupts = <0 19 0x04>; |
497 | clocks = <&tegra_car 69>; | ||
439 | status = "disabled"; | 498 | status = "disabled"; |
440 | }; | 499 | }; |
441 | 500 | ||
@@ -443,9 +502,39 @@ | |||
443 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; | 502 | compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; |
444 | reg = <0x78000600 0x200>; | 503 | reg = <0x78000600 0x200>; |
445 | interrupts = <0 31 0x04>; | 504 | interrupts = <0 31 0x04>; |
505 | clocks = <&tegra_car 15>; | ||
446 | status = "disabled"; | 506 | status = "disabled"; |
447 | }; | 507 | }; |
448 | 508 | ||
509 | cpus { | ||
510 | #address-cells = <1>; | ||
511 | #size-cells = <0>; | ||
512 | |||
513 | cpu@0 { | ||
514 | device_type = "cpu"; | ||
515 | compatible = "arm,cortex-a9"; | ||
516 | reg = <0>; | ||
517 | }; | ||
518 | |||
519 | cpu@1 { | ||
520 | device_type = "cpu"; | ||
521 | compatible = "arm,cortex-a9"; | ||
522 | reg = <1>; | ||
523 | }; | ||
524 | |||
525 | cpu@2 { | ||
526 | device_type = "cpu"; | ||
527 | compatible = "arm,cortex-a9"; | ||
528 | reg = <2>; | ||
529 | }; | ||
530 | |||
531 | cpu@3 { | ||
532 | device_type = "cpu"; | ||
533 | compatible = "arm,cortex-a9"; | ||
534 | reg = <3>; | ||
535 | }; | ||
536 | }; | ||
537 | |||
449 | pmu { | 538 | pmu { |
450 | compatible = "arm,cortex-a9-pmu"; | 539 | compatible = "arm,cortex-a9-pmu"; |
451 | interrupts = <0 144 0x04 | 540 | interrupts = <0 144 0x04 |
diff --git a/arch/arm/boot/dts/wm8850-w70v2.dts b/arch/arm/boot/dts/wm8850-w70v2.dts new file mode 100644 index 000000000000..fcc660c89540 --- /dev/null +++ b/arch/arm/boot/dts/wm8850-w70v2.dts | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * wm8850-w70v2.dts | ||
3 | * - Device tree file for Wondermedia WM8850 Tablet | ||
4 | * - 'W70-V2' mainboard | ||
5 | * - HongLianYing 'HLY070ML268-21A' 7" LCD panel | ||
6 | * | ||
7 | * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> | ||
8 | * | ||
9 | * Licensed under GPLv2 or later | ||
10 | */ | ||
11 | |||
12 | /dts-v1/; | ||
13 | /include/ "wm8850.dtsi" | ||
14 | |||
15 | / { | ||
16 | model = "Wondermedia WM8850-W70v2 Tablet"; | ||
17 | |||
18 | /* | ||
19 | * Display node is based on Sascha Hauer's patch on dri-devel. | ||
20 | * Added a bpp property to calculate the size of the framebuffer | ||
21 | * until the binding is formalized. | ||
22 | */ | ||
23 | display: display@0 { | ||
24 | modes { | ||
25 | mode0: mode@0 { | ||
26 | hactive = <800>; | ||
27 | vactive = <480>; | ||
28 | hback-porch = <88>; | ||
29 | hfront-porch = <40>; | ||
30 | hsync-len = <0>; | ||
31 | vback-porch = <32>; | ||
32 | vfront-porch = <11>; | ||
33 | vsync-len = <1>; | ||
34 | clock = <0>; /* unused but required */ | ||
35 | bpp = <16>; /* non-standard but required */ | ||
36 | }; | ||
37 | }; | ||
38 | }; | ||
39 | |||
40 | backlight { | ||
41 | compatible = "pwm-backlight"; | ||
42 | pwms = <&pwm 0 50000 1>; /* duty inverted */ | ||
43 | |||
44 | brightness-levels = <0 40 60 80 100 130 190 255>; | ||
45 | default-brightness-level = <5>; | ||
46 | }; | ||
47 | }; | ||
diff --git a/arch/arm/boot/dts/wm8850.dtsi b/arch/arm/boot/dts/wm8850.dtsi new file mode 100644 index 000000000000..e8cbfdc87bba --- /dev/null +++ b/arch/arm/boot/dts/wm8850.dtsi | |||
@@ -0,0 +1,224 @@ | |||
1 | /* | ||
2 | * wm8850.dtsi - Device tree file for Wondermedia WM8850 SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> | ||
5 | * | ||
6 | * Licensed under GPLv2 or later | ||
7 | */ | ||
8 | |||
9 | /include/ "skeleton.dtsi" | ||
10 | |||
11 | / { | ||
12 | compatible = "wm,wm8850"; | ||
13 | |||
14 | aliases { | ||
15 | serial0 = &uart0; | ||
16 | serial1 = &uart1; | ||
17 | serial2 = &uart2; | ||
18 | serial3 = &uart3; | ||
19 | }; | ||
20 | |||
21 | soc { | ||
22 | #address-cells = <1>; | ||
23 | #size-cells = <1>; | ||
24 | compatible = "simple-bus"; | ||
25 | ranges; | ||
26 | interrupt-parent = <&intc0>; | ||
27 | |||
28 | intc0: interrupt-controller@d8140000 { | ||
29 | compatible = "via,vt8500-intc"; | ||
30 | interrupt-controller; | ||
31 | reg = <0xd8140000 0x10000>; | ||
32 | #interrupt-cells = <1>; | ||
33 | }; | ||
34 | |||
35 | /* Secondary IC cascaded to intc0 */ | ||
36 | intc1: interrupt-controller@d8150000 { | ||
37 | compatible = "via,vt8500-intc"; | ||
38 | interrupt-controller; | ||
39 | #interrupt-cells = <1>; | ||
40 | reg = <0xD8150000 0x10000>; | ||
41 | interrupts = <56 57 58 59 60 61 62 63>; | ||
42 | }; | ||
43 | |||
44 | gpio: gpio-controller@d8110000 { | ||
45 | compatible = "wm,wm8650-gpio"; | ||
46 | gpio-controller; | ||
47 | reg = <0xd8110000 0x10000>; | ||
48 | #gpio-cells = <3>; | ||
49 | }; | ||
50 | |||
51 | pmc@d8130000 { | ||
52 | compatible = "via,vt8500-pmc"; | ||
53 | reg = <0xd8130000 0x1000>; | ||
54 | |||
55 | clocks { | ||
56 | #address-cells = <1>; | ||
57 | #size-cells = <0>; | ||
58 | |||
59 | ref25: ref25M { | ||
60 | #clock-cells = <0>; | ||
61 | compatible = "fixed-clock"; | ||
62 | clock-frequency = <25000000>; | ||
63 | }; | ||
64 | |||
65 | ref24: ref24M { | ||
66 | #clock-cells = <0>; | ||
67 | compatible = "fixed-clock"; | ||
68 | clock-frequency = <24000000>; | ||
69 | }; | ||
70 | |||
71 | plla: plla { | ||
72 | #clock-cells = <0>; | ||
73 | compatible = "wm,wm8750-pll-clock"; | ||
74 | clocks = <&ref25>; | ||
75 | reg = <0x200>; | ||
76 | }; | ||
77 | |||
78 | pllb: pllb { | ||
79 | #clock-cells = <0>; | ||
80 | compatible = "wm,wm8750-pll-clock"; | ||
81 | clocks = <&ref25>; | ||
82 | reg = <0x204>; | ||
83 | }; | ||
84 | |||
85 | clkuart0: uart0 { | ||
86 | #clock-cells = <0>; | ||
87 | compatible = "via,vt8500-device-clock"; | ||
88 | clocks = <&ref24>; | ||
89 | enable-reg = <0x254>; | ||
90 | enable-bit = <24>; | ||
91 | }; | ||
92 | |||
93 | clkuart1: uart1 { | ||
94 | #clock-cells = <0>; | ||
95 | compatible = "via,vt8500-device-clock"; | ||
96 | clocks = <&ref24>; | ||
97 | enable-reg = <0x254>; | ||
98 | enable-bit = <25>; | ||
99 | }; | ||
100 | |||
101 | clkuart2: uart2 { | ||
102 | #clock-cells = <0>; | ||
103 | compatible = "via,vt8500-device-clock"; | ||
104 | clocks = <&ref24>; | ||
105 | enable-reg = <0x254>; | ||
106 | enable-bit = <26>; | ||
107 | }; | ||
108 | |||
109 | clkuart3: uart3 { | ||
110 | #clock-cells = <0>; | ||
111 | compatible = "via,vt8500-device-clock"; | ||
112 | clocks = <&ref24>; | ||
113 | enable-reg = <0x254>; | ||
114 | enable-bit = <27>; | ||
115 | }; | ||
116 | |||
117 | clkpwm: pwm { | ||
118 | #clock-cells = <0>; | ||
119 | compatible = "via,vt8500-device-clock"; | ||
120 | clocks = <&pllb>; | ||
121 | divisor-reg = <0x350>; | ||
122 | enable-reg = <0x250>; | ||
123 | enable-bit = <17>; | ||
124 | }; | ||
125 | |||
126 | clksdhc: sdhc { | ||
127 | #clock-cells = <0>; | ||
128 | compatible = "via,vt8500-device-clock"; | ||
129 | clocks = <&pllb>; | ||
130 | divisor-reg = <0x330>; | ||
131 | divisor-mask = <0x3f>; | ||
132 | enable-reg = <0x250>; | ||
133 | enable-bit = <0>; | ||
134 | }; | ||
135 | }; | ||
136 | }; | ||
137 | |||
138 | fb@d8051700 { | ||
139 | compatible = "wm,wm8505-fb"; | ||
140 | reg = <0xd8051700 0x200>; | ||
141 | display = <&display>; | ||
142 | default-mode = <&mode0>; | ||
143 | }; | ||
144 | |||
145 | ge_rops@d8050400 { | ||
146 | compatible = "wm,prizm-ge-rops"; | ||
147 | reg = <0xd8050400 0x100>; | ||
148 | }; | ||
149 | |||
150 | pwm: pwm@d8220000 { | ||
151 | #pwm-cells = <3>; | ||
152 | compatible = "via,vt8500-pwm"; | ||
153 | reg = <0xd8220000 0x100>; | ||
154 | clocks = <&clkpwm>; | ||
155 | }; | ||
156 | |||
157 | timer@d8130100 { | ||
158 | compatible = "via,vt8500-timer"; | ||
159 | reg = <0xd8130100 0x28>; | ||
160 | interrupts = <36>; | ||
161 | }; | ||
162 | |||
163 | ehci@d8007900 { | ||
164 | compatible = "via,vt8500-ehci"; | ||
165 | reg = <0xd8007900 0x200>; | ||
166 | interrupts = <26>; | ||
167 | }; | ||
168 | |||
169 | uhci@d8007b00 { | ||
170 | compatible = "platform-uhci"; | ||
171 | reg = <0xd8007b00 0x200>; | ||
172 | interrupts = <26>; | ||
173 | }; | ||
174 | |||
175 | uhci@d8008d00 { | ||
176 | compatible = "platform-uhci"; | ||
177 | reg = <0xd8008d00 0x200>; | ||
178 | interrupts = <26>; | ||
179 | }; | ||
180 | |||
181 | uart0: uart@d8200000 { | ||
182 | compatible = "via,vt8500-uart"; | ||
183 | reg = <0xd8200000 0x1040>; | ||
184 | interrupts = <32>; | ||
185 | clocks = <&clkuart0>; | ||
186 | }; | ||
187 | |||
188 | uart1: uart@d82b0000 { | ||
189 | compatible = "via,vt8500-uart"; | ||
190 | reg = <0xd82b0000 0x1040>; | ||
191 | interrupts = <33>; | ||
192 | clocks = <&clkuart1>; | ||
193 | }; | ||
194 | |||
195 | uart2: uart@d8210000 { | ||
196 | compatible = "via,vt8500-uart"; | ||
197 | reg = <0xd8210000 0x1040>; | ||
198 | interrupts = <47>; | ||
199 | clocks = <&clkuart2>; | ||
200 | }; | ||
201 | |||
202 | uart3: uart@d82c0000 { | ||
203 | compatible = "via,vt8500-uart"; | ||
204 | reg = <0xd82c0000 0x1040>; | ||
205 | interrupts = <50>; | ||
206 | clocks = <&clkuart3>; | ||
207 | }; | ||
208 | |||
209 | rtc@d8100000 { | ||
210 | compatible = "via,vt8500-rtc"; | ||
211 | reg = <0xd8100000 0x10000>; | ||
212 | interrupts = <48>; | ||
213 | }; | ||
214 | |||
215 | sdhc@d800a000 { | ||
216 | compatible = "wm,wm8505-sdhc"; | ||
217 | reg = <0xd800a000 0x1000>; | ||
218 | interrupts = <20 21>; | ||
219 | clocks = <&clksdhc>; | ||
220 | bus-width = <4>; | ||
221 | sdon-inverted; | ||
222 | }; | ||
223 | }; | ||
224 | }; | ||
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 6dddbf877b0c..0a3966787563 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig | |||
@@ -19,6 +19,7 @@ CONFIG_MODULE_SRCVERSION_ALL=y | |||
19 | CONFIG_ARCH_MXC=y | 19 | CONFIG_ARCH_MXC=y |
20 | CONFIG_ARCH_MULTI_V6=y | 20 | CONFIG_ARCH_MULTI_V6=y |
21 | CONFIG_ARCH_MULTI_V7=y | 21 | CONFIG_ARCH_MULTI_V7=y |
22 | CONFIG_MACH_IMX31_DT=y | ||
22 | CONFIG_MACH_MX31LILLY=y | 23 | CONFIG_MACH_MX31LILLY=y |
23 | CONFIG_MACH_MX31LITE=y | 24 | CONFIG_MACH_MX31LITE=y |
24 | CONFIG_MACH_PCM037=y | 25 | CONFIG_MACH_PCM037=y |
@@ -150,6 +151,7 @@ CONFIG_MFD_MC13XXX_I2C=y | |||
150 | CONFIG_REGULATOR=y | 151 | CONFIG_REGULATOR=y |
151 | CONFIG_REGULATOR_FIXED_VOLTAGE=y | 152 | CONFIG_REGULATOR_FIXED_VOLTAGE=y |
152 | CONFIG_REGULATOR_DA9052=y | 153 | CONFIG_REGULATOR_DA9052=y |
154 | CONFIG_REGULATOR_ANATOP=y | ||
153 | CONFIG_REGULATOR_MC13783=y | 155 | CONFIG_REGULATOR_MC13783=y |
154 | CONFIG_REGULATOR_MC13892=y | 156 | CONFIG_REGULATOR_MC13892=y |
155 | CONFIG_MEDIA_SUPPORT=y | 157 | CONFIG_MEDIA_SUPPORT=y |
@@ -158,6 +160,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y | |||
158 | CONFIG_MEDIA_CAMERA_SUPPORT=y | 160 | CONFIG_MEDIA_CAMERA_SUPPORT=y |
159 | CONFIG_SOC_CAMERA=y | 161 | CONFIG_SOC_CAMERA=y |
160 | CONFIG_SOC_CAMERA_OV2640=y | 162 | CONFIG_SOC_CAMERA_OV2640=y |
163 | CONFIG_DRM=y | ||
161 | CONFIG_VIDEO_MX3=y | 164 | CONFIG_VIDEO_MX3=y |
162 | CONFIG_FB=y | 165 | CONFIG_FB=y |
163 | CONFIG_LCD_PLATFORM=y | 166 | CONFIG_LCD_PLATFORM=y |
@@ -196,9 +199,14 @@ CONFIG_RTC_CLASS=y | |||
196 | CONFIG_RTC_INTF_DEV_UIE_EMUL=y | 199 | CONFIG_RTC_INTF_DEV_UIE_EMUL=y |
197 | CONFIG_RTC_DRV_MC13XXX=y | 200 | CONFIG_RTC_DRV_MC13XXX=y |
198 | CONFIG_RTC_DRV_MXC=y | 201 | CONFIG_RTC_DRV_MXC=y |
202 | CONFIG_RTC_DRV_SNVS=y | ||
199 | CONFIG_DMADEVICES=y | 203 | CONFIG_DMADEVICES=y |
200 | CONFIG_IMX_SDMA=y | 204 | CONFIG_IMX_SDMA=y |
201 | CONFIG_MXS_DMA=y | 205 | CONFIG_MXS_DMA=y |
206 | CONFIG_STAGING=y | ||
207 | CONFIG_DRM_IMX=y | ||
208 | CONFIG_DRM_IMX_IPUV3_CORE=y | ||
209 | CONFIG_DRM_IMX_IPUV3=y | ||
202 | CONFIG_COMMON_CLK_DEBUG=y | 210 | CONFIG_COMMON_CLK_DEBUG=y |
203 | # CONFIG_IOMMU_SUPPORT is not set | 211 | # CONFIG_IOMMU_SUPPORT is not set |
204 | CONFIG_EXT2_FS=y | 212 | CONFIG_EXT2_FS=y |
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index 93f3794ba5cb..13482ea58b09 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig | |||
@@ -56,6 +56,7 @@ CONFIG_AEABI=y | |||
56 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 56 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
57 | CONFIG_ZBOOT_ROM_BSS=0x0 | 57 | CONFIG_ZBOOT_ROM_BSS=0x0 |
58 | CONFIG_CPU_IDLE=y | 58 | CONFIG_CPU_IDLE=y |
59 | CONFIG_CPU_IDLE_KIRKWOOD=y | ||
59 | CONFIG_NET=y | 60 | CONFIG_NET=y |
60 | CONFIG_PACKET=y | 61 | CONFIG_PACKET=y |
61 | CONFIG_UNIX=y | 62 | CONFIG_UNIX=y |
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 7bf535104e26..fbbc5bb022d5 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig | |||
@@ -1,5 +1,7 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | 1 | CONFIG_EXPERIMENTAL=y |
2 | CONFIG_SYSVIPC=y | 2 | CONFIG_SYSVIPC=y |
3 | CONFIG_NO_HZ=y | ||
4 | CONFIG_HIGH_RES_TIMERS=y | ||
3 | CONFIG_TASKSTATS=y | 5 | CONFIG_TASKSTATS=y |
4 | CONFIG_TASK_DELAY_ACCT=y | 6 | CONFIG_TASK_DELAY_ACCT=y |
5 | CONFIG_TASK_XACCT=y | 7 | CONFIG_TASK_XACCT=y |
@@ -8,7 +10,6 @@ CONFIG_IKCONFIG=y | |||
8 | CONFIG_IKCONFIG_PROC=y | 10 | CONFIG_IKCONFIG_PROC=y |
9 | # CONFIG_UTS_NS is not set | 11 | # CONFIG_UTS_NS is not set |
10 | # CONFIG_IPC_NS is not set | 12 | # CONFIG_IPC_NS is not set |
11 | # CONFIG_USER_NS is not set | ||
12 | # CONFIG_PID_NS is not set | 13 | # CONFIG_PID_NS is not set |
13 | # CONFIG_NET_NS is not set | 14 | # CONFIG_NET_NS is not set |
14 | CONFIG_PERF_EVENTS=y | 15 | CONFIG_PERF_EVENTS=y |
@@ -24,8 +25,6 @@ CONFIG_BLK_DEV_INTEGRITY=y | |||
24 | CONFIG_ARCH_MXS=y | 25 | CONFIG_ARCH_MXS=y |
25 | CONFIG_MACH_MXS_DT=y | 26 | CONFIG_MACH_MXS_DT=y |
26 | # CONFIG_ARM_THUMB is not set | 27 | # CONFIG_ARM_THUMB is not set |
27 | CONFIG_NO_HZ=y | ||
28 | CONFIG_HIGH_RES_TIMERS=y | ||
29 | CONFIG_PREEMPT_VOLUNTARY=y | 28 | CONFIG_PREEMPT_VOLUNTARY=y |
30 | CONFIG_AEABI=y | 29 | CONFIG_AEABI=y |
31 | CONFIG_AUTO_ZRELADDR=y | 30 | CONFIG_AUTO_ZRELADDR=y |
@@ -46,25 +45,34 @@ CONFIG_SYN_COOKIES=y | |||
46 | CONFIG_CAN=m | 45 | CONFIG_CAN=m |
47 | CONFIG_CAN_RAW=m | 46 | CONFIG_CAN_RAW=m |
48 | CONFIG_CAN_BCM=m | 47 | CONFIG_CAN_BCM=m |
49 | CONFIG_CAN_DEV=m | ||
50 | CONFIG_CAN_FLEXCAN=m | 48 | CONFIG_CAN_FLEXCAN=m |
51 | # CONFIG_WIRELESS is not set | 49 | # CONFIG_WIRELESS is not set |
52 | CONFIG_DEVTMPFS=y | 50 | CONFIG_DEVTMPFS=y |
51 | CONFIG_DEVTMPFS_MOUNT=y | ||
53 | # CONFIG_FIRMWARE_IN_KERNEL is not set | 52 | # CONFIG_FIRMWARE_IN_KERNEL is not set |
54 | # CONFIG_BLK_DEV is not set | ||
55 | CONFIG_MTD=y | 53 | CONFIG_MTD=y |
54 | CONFIG_MTD_CMDLINE_PARTS=y | ||
56 | CONFIG_MTD_CHAR=y | 55 | CONFIG_MTD_CHAR=y |
56 | CONFIG_MTD_BLOCK=y | ||
57 | CONFIG_MTD_DATAFLASH=y | 57 | CONFIG_MTD_DATAFLASH=y |
58 | CONFIG_MTD_M25P80 | 58 | CONFIG_MTD_M25P80=y |
59 | # CONFIG_M25PXX_USE_FAST_READ is not set | ||
60 | CONFIG_MTD_SST25L=y | ||
59 | CONFIG_MTD_NAND=y | 61 | CONFIG_MTD_NAND=y |
60 | CONFIG_MTD_NAND_GPMI_NAND=y | 62 | CONFIG_MTD_NAND_GPMI_NAND=y |
63 | CONFIG_MTD_UBI=y | ||
64 | # CONFIG_BLK_DEV is not set | ||
65 | CONFIG_EEPROM_AT24=y | ||
66 | CONFIG_SCSI=y | ||
67 | CONFIG_BLK_DEV_SD=y | ||
61 | CONFIG_NETDEVICES=y | 68 | CONFIG_NETDEVICES=y |
62 | CONFIG_NET_ETHERNET=y | ||
63 | CONFIG_ENC28J60=y | 69 | CONFIG_ENC28J60=y |
64 | CONFIG_USB_USBNET=y | 70 | CONFIG_USB_USBNET=y |
65 | CONFIG_USB_NET_SMSC95XX=y | 71 | CONFIG_USB_NET_SMSC95XX=y |
66 | # CONFIG_NETDEV_1000 is not set | 72 | CONFIG_SMSC_PHY=y |
67 | # CONFIG_NETDEV_10000 is not set | 73 | CONFIG_ICPLUS_PHY=y |
74 | CONFIG_REALTEK_PHY=y | ||
75 | CONFIG_MICREL_PHY=y | ||
68 | # CONFIG_WLAN is not set | 76 | # CONFIG_WLAN is not set |
69 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | 77 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
70 | CONFIG_INPUT_EVDEV=m | 78 | CONFIG_INPUT_EVDEV=m |
@@ -91,21 +99,6 @@ CONFIG_SPI_MXS=y | |||
91 | CONFIG_DEBUG_GPIO=y | 99 | CONFIG_DEBUG_GPIO=y |
92 | CONFIG_GPIO_SYSFS=y | 100 | CONFIG_GPIO_SYSFS=y |
93 | # CONFIG_HWMON is not set | 101 | # CONFIG_HWMON is not set |
94 | # CONFIG_MFD_SUPPORT is not set | ||
95 | CONFIG_DISPLAY_SUPPORT=m | ||
96 | # CONFIG_HID_SUPPORT is not set | ||
97 | CONFIG_SOUND=y | ||
98 | CONFIG_SND=y | ||
99 | CONFIG_SND_TIMER=y | ||
100 | CONFIG_SND_PCM=y | ||
101 | CONFIG_SND_JACK=y | ||
102 | CONFIG_SND_DRIVERS=y | ||
103 | CONFIG_SND_ARM=y | ||
104 | CONFIG_SND_SOC=y | ||
105 | CONFIG_SND_MXS_SOC=y | ||
106 | CONFIG_SND_SOC_MXS_SGTL5000=y | ||
107 | CONFIG_SND_SOC_I2C_AND_SPI=y | ||
108 | CONFIG_SND_SOC_SGTL5000=y | ||
109 | CONFIG_REGULATOR=y | 102 | CONFIG_REGULATOR=y |
110 | CONFIG_REGULATOR_FIXED_VOLTAGE=y | 103 | CONFIG_REGULATOR_FIXED_VOLTAGE=y |
111 | CONFIG_FB=y | 104 | CONFIG_FB=y |
@@ -117,13 +110,16 @@ CONFIG_BACKLIGHT_PWM=y | |||
117 | CONFIG_FRAMEBUFFER_CONSOLE=y | 110 | CONFIG_FRAMEBUFFER_CONSOLE=y |
118 | CONFIG_FONTS=y | 111 | CONFIG_FONTS=y |
119 | CONFIG_LOGO=y | 112 | CONFIG_LOGO=y |
113 | CONFIG_SOUND=y | ||
114 | CONFIG_SND=y | ||
115 | CONFIG_SND_SOC=y | ||
116 | CONFIG_SND_MXS_SOC=y | ||
117 | CONFIG_SND_SOC_MXS_SGTL5000=y | ||
120 | CONFIG_USB=y | 118 | CONFIG_USB=y |
121 | CONFIG_USB_CHIPIDEA=y | 119 | CONFIG_USB_CHIPIDEA=y |
122 | CONFIG_USB_CHIPIDEA_HOST=y | 120 | CONFIG_USB_CHIPIDEA_HOST=y |
123 | CONFIG_USB_STORAGE=y | 121 | CONFIG_USB_STORAGE=y |
124 | CONFIG_USB_MXS_PHY=y | 122 | CONFIG_USB_MXS_PHY=y |
125 | CONFIG_SCSI=y | ||
126 | CONFIG_BLK_DEV_SD=y | ||
127 | CONFIG_MMC=y | 123 | CONFIG_MMC=y |
128 | CONFIG_MMC_MXS=y | 124 | CONFIG_MMC_MXS=y |
129 | CONFIG_NEW_LEDS=y | 125 | CONFIG_NEW_LEDS=y |
@@ -147,16 +143,23 @@ CONFIG_COMMON_CLK_DEBUG=y | |||
147 | CONFIG_IIO=y | 143 | CONFIG_IIO=y |
148 | CONFIG_PWM=y | 144 | CONFIG_PWM=y |
149 | CONFIG_PWM_MXS=y | 145 | CONFIG_PWM_MXS=y |
146 | CONFIG_EXT2_FS=y | ||
147 | CONFIG_EXT2_FS_XATTR=y | ||
150 | CONFIG_EXT3_FS=y | 148 | CONFIG_EXT3_FS=y |
149 | CONFIG_EXT4_FS=y | ||
151 | # CONFIG_DNOTIFY is not set | 150 | # CONFIG_DNOTIFY is not set |
152 | CONFIG_FSCACHE=m | 151 | CONFIG_FSCACHE=m |
153 | CONFIG_FSCACHE_STATS=y | 152 | CONFIG_FSCACHE_STATS=y |
154 | CONFIG_CACHEFILES=m | 153 | CONFIG_CACHEFILES=m |
155 | CONFIG_TMPFS=y | 154 | CONFIG_TMPFS=y |
156 | CONFIG_TMPFS_POSIX_ACL=y | 155 | CONFIG_TMPFS_POSIX_ACL=y |
157 | # CONFIG_MISC_FILESYSTEMS is not set | 156 | CONFIG_JFFS2_FS=y |
157 | CONFIG_JFFS2_COMPRESSION_OPTIONS=y | ||
158 | CONFIG_JFFS2_LZO=y | ||
159 | CONFIG_JFFS2_RUBIN=y | ||
160 | CONFIG_UBIFS_FS=y | ||
161 | CONFIG_UBIFS_FS_ADVANCED_COMPR=y | ||
158 | CONFIG_NFS_FS=y | 162 | CONFIG_NFS_FS=y |
159 | CONFIG_NFS_V3=y | ||
160 | CONFIG_NFS_V3_ACL=y | 163 | CONFIG_NFS_V3_ACL=y |
161 | CONFIG_NFS_V4=y | 164 | CONFIG_NFS_V4=y |
162 | CONFIG_ROOT_NFS=y | 165 | CONFIG_ROOT_NFS=y |
@@ -170,17 +173,12 @@ CONFIG_MAGIC_SYSRQ=y | |||
170 | CONFIG_UNUSED_SYMBOLS=y | 173 | CONFIG_UNUSED_SYMBOLS=y |
171 | CONFIG_DEBUG_KERNEL=y | 174 | CONFIG_DEBUG_KERNEL=y |
172 | CONFIG_LOCKUP_DETECTOR=y | 175 | CONFIG_LOCKUP_DETECTOR=y |
173 | CONFIG_DETECT_HUNG_TASK=y | ||
174 | CONFIG_TIMER_STATS=y | 176 | CONFIG_TIMER_STATS=y |
175 | CONFIG_PROVE_LOCKING=y | 177 | CONFIG_PROVE_LOCKING=y |
176 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | ||
177 | CONFIG_DEBUG_INFO=y | 178 | CONFIG_DEBUG_INFO=y |
178 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
179 | CONFIG_BLK_DEV_IO_TRACE=y | 179 | CONFIG_BLK_DEV_IO_TRACE=y |
180 | CONFIG_STRICT_DEVMEM=y | 180 | CONFIG_STRICT_DEVMEM=y |
181 | CONFIG_DEBUG_USER=y | 181 | CONFIG_DEBUG_USER=y |
182 | CONFIG_CRYPTO=y | ||
183 | CONFIG_CRYPTO_CRC32C=m | ||
184 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 182 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
185 | # CONFIG_CRYPTO_HW is not set | 183 | # CONFIG_CRYPTO_HW is not set |
186 | CONFIG_CRC_ITU_T=m | 184 | CONFIG_CRC_ITU_T=m |
diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig index 6a936c7c078a..002a1ceadceb 100644 --- a/arch/arm/configs/prima2_defconfig +++ b/arch/arm/configs/prima2_defconfig | |||
@@ -11,6 +11,9 @@ CONFIG_PARTITION_ADVANCED=y | |||
11 | CONFIG_BSD_DISKLABEL=y | 11 | CONFIG_BSD_DISKLABEL=y |
12 | CONFIG_SOLARIS_X86_PARTITION=y | 12 | CONFIG_SOLARIS_X86_PARTITION=y |
13 | CONFIG_ARCH_SIRF=y | 13 | CONFIG_ARCH_SIRF=y |
14 | # CONFIG_SWP_EMULATE is not set | ||
15 | CONFIG_SMP=y | ||
16 | CONFIG_SCHED_MC=y | ||
14 | CONFIG_PREEMPT=y | 17 | CONFIG_PREEMPT=y |
15 | CONFIG_AEABI=y | 18 | CONFIG_AEABI=y |
16 | CONFIG_KEXEC=y | 19 | CONFIG_KEXEC=y |
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h index 86dff32a0737..18d169373612 100644 --- a/arch/arm/include/asm/smp_scu.h +++ b/arch/arm/include/asm/smp_scu.h | |||
@@ -6,6 +6,23 @@ | |||
6 | #define SCU_PM_POWEROFF 3 | 6 | #define SCU_PM_POWEROFF 3 |
7 | 7 | ||
8 | #ifndef __ASSEMBLER__ | 8 | #ifndef __ASSEMBLER__ |
9 | |||
10 | #include <asm/cputype.h> | ||
11 | |||
12 | static inline bool scu_a9_has_base(void) | ||
13 | { | ||
14 | return read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9; | ||
15 | } | ||
16 | |||
17 | static inline unsigned long scu_a9_get_base(void) | ||
18 | { | ||
19 | unsigned long pa; | ||
20 | |||
21 | asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa)); | ||
22 | |||
23 | return pa; | ||
24 | } | ||
25 | |||
9 | unsigned int scu_get_core_count(void __iomem *); | 26 | unsigned int scu_get_core_count(void __iomem *); |
10 | int scu_power_mode(void __iomem *, unsigned int); | 27 | int scu_power_mode(void __iomem *, unsigned int); |
11 | 28 | ||
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h new file mode 100644 index 000000000000..91d38e38a0b4 --- /dev/null +++ b/arch/arm/include/debug/imx-uart.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef __DEBUG_IMX_UART_H | ||
10 | #define __DEBUG_IMX_UART_H | ||
11 | |||
12 | #define IMX1_UART1_BASE_ADDR 0x00206000 | ||
13 | #define IMX1_UART2_BASE_ADDR 0x00207000 | ||
14 | #define IMX1_UART_BASE_ADDR(n) IMX1_UART##n##_BASE_ADDR | ||
15 | #define IMX1_UART_BASE(n) IMX1_UART_BASE_ADDR(n) | ||
16 | |||
17 | #define IMX21_UART1_BASE_ADDR 0x1000a000 | ||
18 | #define IMX21_UART2_BASE_ADDR 0x1000b000 | ||
19 | #define IMX21_UART3_BASE_ADDR 0x1000c000 | ||
20 | #define IMX21_UART4_BASE_ADDR 0x1000d000 | ||
21 | #define IMX21_UART_BASE_ADDR(n) IMX21_UART##n##_BASE_ADDR | ||
22 | #define IMX21_UART_BASE(n) IMX21_UART_BASE_ADDR(n) | ||
23 | |||
24 | #define IMX25_UART1_BASE_ADDR 0x43f90000 | ||
25 | #define IMX25_UART2_BASE_ADDR 0x43f94000 | ||
26 | #define IMX25_UART3_BASE_ADDR 0x5000c000 | ||
27 | #define IMX25_UART4_BASE_ADDR 0x50008000 | ||
28 | #define IMX25_UART5_BASE_ADDR 0x5002c000 | ||
29 | #define IMX25_UART_BASE_ADDR(n) IMX25_UART##n##_BASE_ADDR | ||
30 | #define IMX25_UART_BASE(n) IMX25_UART_BASE_ADDR(n) | ||
31 | |||
32 | #define IMX31_UART1_BASE_ADDR 0x43f90000 | ||
33 | #define IMX31_UART2_BASE_ADDR 0x43f94000 | ||
34 | #define IMX31_UART3_BASE_ADDR 0x5000c000 | ||
35 | #define IMX31_UART4_BASE_ADDR 0x43fb0000 | ||
36 | #define IMX31_UART5_BASE_ADDR 0x43fb4000 | ||
37 | #define IMX31_UART_BASE_ADDR(n) IMX31_UART##n##_BASE_ADDR | ||
38 | #define IMX31_UART_BASE(n) IMX31_UART_BASE_ADDR(n) | ||
39 | |||
40 | #define IMX35_UART1_BASE_ADDR 0x43f90000 | ||
41 | #define IMX35_UART2_BASE_ADDR 0x43f94000 | ||
42 | #define IMX35_UART3_BASE_ADDR 0x5000c000 | ||
43 | #define IMX35_UART_BASE_ADDR(n) IMX35_UART##n##_BASE_ADDR | ||
44 | #define IMX35_UART_BASE(n) IMX35_UART_BASE_ADDR(n) | ||
45 | |||
46 | #define IMX51_UART1_BASE_ADDR 0x73fbc000 | ||
47 | #define IMX51_UART2_BASE_ADDR 0x73fc0000 | ||
48 | #define IMX51_UART3_BASE_ADDR 0x7000c000 | ||
49 | #define IMX51_UART_BASE_ADDR(n) IMX51_UART##n##_BASE_ADDR | ||
50 | #define IMX51_UART_BASE(n) IMX51_UART_BASE_ADDR(n) | ||
51 | |||
52 | #define IMX53_UART1_BASE_ADDR 0x53fbc000 | ||
53 | #define IMX53_UART2_BASE_ADDR 0x53fc0000 | ||
54 | #define IMX53_UART3_BASE_ADDR 0x5000c000 | ||
55 | #define IMX53_UART4_BASE_ADDR 0x53ff0000 | ||
56 | #define IMX53_UART5_BASE_ADDR 0x63f90000 | ||
57 | #define IMX53_UART_BASE_ADDR(n) IMX53_UART##n##_BASE_ADDR | ||
58 | #define IMX53_UART_BASE(n) IMX53_UART_BASE_ADDR(n) | ||
59 | |||
60 | #define IMX6Q_UART1_BASE_ADDR 0x02020000 | ||
61 | #define IMX6Q_UART2_BASE_ADDR 0x021e8000 | ||
62 | #define IMX6Q_UART3_BASE_ADDR 0x021ec000 | ||
63 | #define IMX6Q_UART4_BASE_ADDR 0x021f0000 | ||
64 | #define IMX6Q_UART5_BASE_ADDR 0x021f4000 | ||
65 | #define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR | ||
66 | #define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n) | ||
67 | |||
68 | #define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT) | ||
69 | |||
70 | #ifdef CONFIG_DEBUG_IMX1_UART | ||
71 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX1) | ||
72 | #elif defined(CONFIG_DEBUG_IMX21_IMX27_UART) | ||
73 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX21) | ||
74 | #elif defined(CONFIG_DEBUG_IMX25_UART) | ||
75 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX25) | ||
76 | #elif defined(CONFIG_DEBUG_IMX31_UART) | ||
77 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX31) | ||
78 | #elif defined(CONFIG_DEBUG_IMX35_UART) | ||
79 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX35) | ||
80 | #elif defined(CONFIG_DEBUG_IMX51_UART) | ||
81 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX51) | ||
82 | #elif defined(CONFIG_DEBUG_IMX53_UART) | ||
83 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX53) | ||
84 | #elif defined(CONFIG_DEBUG_IMX6Q_UART) | ||
85 | #define UART_PADDR IMX_DEBUG_UART_BASE(IMX6Q) | ||
86 | #endif | ||
87 | |||
88 | #endif /* __DEBUG_IMX_UART_H */ | ||
diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index c6f294cf18f0..619d8cc1ac12 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S | |||
@@ -10,35 +10,8 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | #define IMX6Q_UART1_BASE_ADDR 0x02020000 | ||
14 | #define IMX6Q_UART2_BASE_ADDR 0x021e8000 | ||
15 | #define IMX6Q_UART3_BASE_ADDR 0x021ec000 | ||
16 | #define IMX6Q_UART4_BASE_ADDR 0x021f0000 | ||
17 | #define IMX6Q_UART5_BASE_ADDR 0x021f4000 | ||
18 | 13 | ||
19 | /* | 14 | #include "imx-uart.h" |
20 | * IMX6Q_UART_BASE_ADDR is put in the middle to force the expansion | ||
21 | * of IMX6Q_UART##n##_BASE_ADDR. | ||
22 | */ | ||
23 | #define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR | ||
24 | #define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n) | ||
25 | #define IMX6Q_DEBUG_UART_BASE IMX6Q_UART_BASE(CONFIG_DEBUG_IMX6Q_UART_PORT) | ||
26 | |||
27 | #ifdef CONFIG_DEBUG_IMX1_UART | ||
28 | #define UART_PADDR 0x00206000 | ||
29 | #elif defined (CONFIG_DEBUG_IMX25_UART) | ||
30 | #define UART_PADDR 0x43f90000 | ||
31 | #elif defined (CONFIG_DEBUG_IMX21_IMX27_UART) | ||
32 | #define UART_PADDR 0x1000a000 | ||
33 | #elif defined (CONFIG_DEBUG_IMX31_IMX35_UART) | ||
34 | #define UART_PADDR 0x43f90000 | ||
35 | #elif defined (CONFIG_DEBUG_IMX51_UART) | ||
36 | #define UART_PADDR 0x73fbc000 | ||
37 | #elif defined (CONFIG_DEBUG_IMX53_UART) | ||
38 | #define UART_PADDR 0x53fbc000 | ||
39 | #elif defined (CONFIG_DEBUG_IMX6Q_UART) | ||
40 | #define UART_PADDR IMX6Q_DEBUG_UART_BASE | ||
41 | #endif | ||
42 | 15 | ||
43 | /* | 16 | /* |
44 | * FIXME: This is a copy of IMX_IO_P2V in hardware.h, and needs to | 17 | * FIXME: This is a copy of IMX_IO_P2V in hardware.h, and needs to |
diff --git a/arch/arm/mach-bcm2835/bcm2835.c b/arch/arm/mach-bcm2835/bcm2835.c index d615a61e902c..6f5785985dd1 100644 --- a/arch/arm/mach-bcm2835/bcm2835.c +++ b/arch/arm/mach-bcm2835/bcm2835.c | |||
@@ -26,11 +26,13 @@ | |||
26 | #include <mach/bcm2835_soc.h> | 26 | #include <mach/bcm2835_soc.h> |
27 | 27 | ||
28 | #define PM_RSTC 0x1c | 28 | #define PM_RSTC 0x1c |
29 | #define PM_RSTS 0x20 | ||
29 | #define PM_WDOG 0x24 | 30 | #define PM_WDOG 0x24 |
30 | 31 | ||
31 | #define PM_PASSWORD 0x5a000000 | 32 | #define PM_PASSWORD 0x5a000000 |
32 | #define PM_RSTC_WRCFG_MASK 0x00000030 | 33 | #define PM_RSTC_WRCFG_MASK 0x00000030 |
33 | #define PM_RSTC_WRCFG_FULL_RESET 0x00000020 | 34 | #define PM_RSTC_WRCFG_FULL_RESET 0x00000020 |
35 | #define PM_RSTS_HADWRH_SET 0x00000040 | ||
34 | 36 | ||
35 | static void __iomem *wdt_regs; | 37 | static void __iomem *wdt_regs; |
36 | 38 | ||
@@ -67,6 +69,29 @@ static void bcm2835_restart(char mode, const char *cmd) | |||
67 | mdelay(1); | 69 | mdelay(1); |
68 | } | 70 | } |
69 | 71 | ||
72 | /* | ||
73 | * We can't really power off, but if we do the normal reset scheme, and | ||
74 | * indicate to bootcode.bin not to reboot, then most of the chip will be | ||
75 | * powered off. | ||
76 | */ | ||
77 | static void bcm2835_power_off(void) | ||
78 | { | ||
79 | u32 val; | ||
80 | |||
81 | /* | ||
82 | * We set the watchdog hard reset bit here to distinguish this reset | ||
83 | * from the normal (full) reset. bootcode.bin will not reboot after a | ||
84 | * hard reset. | ||
85 | */ | ||
86 | val = readl_relaxed(wdt_regs + PM_RSTS); | ||
87 | val &= ~PM_RSTC_WRCFG_MASK; | ||
88 | val |= PM_PASSWORD | PM_RSTS_HADWRH_SET; | ||
89 | writel_relaxed(val, wdt_regs + PM_RSTS); | ||
90 | |||
91 | /* Continue with normal reset mechanism */ | ||
92 | bcm2835_restart(0, ""); | ||
93 | } | ||
94 | |||
70 | static struct map_desc io_map __initdata = { | 95 | static struct map_desc io_map __initdata = { |
71 | .virtual = BCM2835_PERIPH_VIRT, | 96 | .virtual = BCM2835_PERIPH_VIRT, |
72 | .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS), | 97 | .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS), |
@@ -84,6 +109,9 @@ static void __init bcm2835_init(void) | |||
84 | int ret; | 109 | int ret; |
85 | 110 | ||
86 | bcm2835_setup_restart(); | 111 | bcm2835_setup_restart(); |
112 | if (wdt_regs) | ||
113 | pm_power_off = bcm2835_power_off; | ||
114 | |||
87 | bcm2835_init_clocks(); | 115 | bcm2835_init_clocks(); |
88 | 116 | ||
89 | ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, | 117 | ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, |
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index e3742716cbaa..6da25eebf911 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c | |||
@@ -652,8 +652,13 @@ static __init void da830_evm_init(void) | |||
652 | if (ret) | 652 | if (ret) |
653 | pr_warning("da830_evm_init: rtc setup failed: %d\n", ret); | 653 | pr_warning("da830_evm_init: rtc setup failed: %d\n", ret); |
654 | 654 | ||
655 | ret = da8xx_register_spi(0, da830evm_spi_info, | 655 | ret = spi_register_board_info(da830evm_spi_info, |
656 | ARRAY_SIZE(da830evm_spi_info)); | 656 | ARRAY_SIZE(da830evm_spi_info)); |
657 | if (ret) | ||
658 | pr_warn("%s: spi info registration failed: %d\n", __func__, | ||
659 | ret); | ||
660 | |||
661 | ret = da8xx_register_spi_bus(0, ARRAY_SIZE(da830evm_spi_info)); | ||
657 | if (ret) | 662 | if (ret) |
658 | pr_warning("da830_evm_init: spi 0 registration failed: %d\n", | 663 | pr_warning("da830_evm_init: spi 0 registration failed: %d\n", |
659 | ret); | 664 | ret); |
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 3b3356097bb0..3a76a47df39c 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
@@ -1565,8 +1565,13 @@ static __init void da850_evm_init(void) | |||
1565 | 1565 | ||
1566 | da850_vpif_init(); | 1566 | da850_vpif_init(); |
1567 | 1567 | ||
1568 | ret = da8xx_register_spi(1, da850evm_spi_info, | 1568 | ret = spi_register_board_info(da850evm_spi_info, |
1569 | ARRAY_SIZE(da850evm_spi_info)); | 1569 | ARRAY_SIZE(da850evm_spi_info)); |
1570 | if (ret) | ||
1571 | pr_warn("%s: spi info registration failed: %d\n", __func__, | ||
1572 | ret); | ||
1573 | |||
1574 | ret = da8xx_register_spi_bus(1, ARRAY_SIZE(da850evm_spi_info)); | ||
1570 | if (ret) | 1575 | if (ret) |
1571 | pr_warning("da850_evm_init: spi 1 registration failed: %d\n", | 1576 | pr_warning("da850_evm_init: spi 1 registration failed: %d\n", |
1572 | ret); | 1577 | ret); |
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index b0df578bf744..9549d53aa63f 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c | |||
@@ -529,8 +529,13 @@ static void __init mityomapl138_init(void) | |||
529 | 529 | ||
530 | mityomapl138_setup_nand(); | 530 | mityomapl138_setup_nand(); |
531 | 531 | ||
532 | ret = da8xx_register_spi(1, mityomapl138_spi_flash_info, | 532 | ret = spi_register_board_info(mityomapl138_spi_flash_info, |
533 | ARRAY_SIZE(mityomapl138_spi_flash_info)); | 533 | ARRAY_SIZE(mityomapl138_spi_flash_info)); |
534 | if (ret) | ||
535 | pr_warn("spi info registration failed: %d\n", ret); | ||
536 | |||
537 | ret = da8xx_register_spi_bus(1, | ||
538 | ARRAY_SIZE(mityomapl138_spi_flash_info)); | ||
534 | if (ret) | 539 | if (ret) |
535 | pr_warning("spi 1 registration failed: %d\n", ret); | 540 | pr_warning("spi 1 registration failed: %d\n", ret); |
536 | 541 | ||
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 34668ead53c7..d458558ee84a 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c | |||
@@ -52,6 +52,40 @@ static void __clk_disable(struct clk *clk) | |||
52 | __clk_disable(clk->parent); | 52 | __clk_disable(clk->parent); |
53 | } | 53 | } |
54 | 54 | ||
55 | int davinci_clk_reset(struct clk *clk, bool reset) | ||
56 | { | ||
57 | unsigned long flags; | ||
58 | |||
59 | if (clk == NULL || IS_ERR(clk)) | ||
60 | return -EINVAL; | ||
61 | |||
62 | spin_lock_irqsave(&clockfw_lock, flags); | ||
63 | if (clk->flags & CLK_PSC) | ||
64 | davinci_psc_reset(clk->gpsc, clk->lpsc, reset); | ||
65 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | EXPORT_SYMBOL(davinci_clk_reset); | ||
70 | |||
71 | int davinci_clk_reset_assert(struct clk *clk) | ||
72 | { | ||
73 | if (clk == NULL || IS_ERR(clk) || !clk->reset) | ||
74 | return -EINVAL; | ||
75 | |||
76 | return clk->reset(clk, true); | ||
77 | } | ||
78 | EXPORT_SYMBOL(davinci_clk_reset_assert); | ||
79 | |||
80 | int davinci_clk_reset_deassert(struct clk *clk) | ||
81 | { | ||
82 | if (clk == NULL || IS_ERR(clk) || !clk->reset) | ||
83 | return -EINVAL; | ||
84 | |||
85 | return clk->reset(clk, false); | ||
86 | } | ||
87 | EXPORT_SYMBOL(davinci_clk_reset_deassert); | ||
88 | |||
55 | int clk_enable(struct clk *clk) | 89 | int clk_enable(struct clk *clk) |
56 | { | 90 | { |
57 | unsigned long flags; | 91 | unsigned long flags; |
@@ -535,7 +569,7 @@ int davinci_set_refclk_rate(unsigned long rate) | |||
535 | } | 569 | } |
536 | 570 | ||
537 | int __init davinci_clk_init(struct clk_lookup *clocks) | 571 | int __init davinci_clk_init(struct clk_lookup *clocks) |
538 | { | 572 | { |
539 | struct clk_lookup *c; | 573 | struct clk_lookup *c; |
540 | struct clk *clk; | 574 | struct clk *clk; |
541 | size_t num_clocks = 0; | 575 | size_t num_clocks = 0; |
@@ -576,6 +610,9 @@ int __init davinci_clk_init(struct clk_lookup *clocks) | |||
576 | if (clk->lpsc) | 610 | if (clk->lpsc) |
577 | clk->flags |= CLK_PSC; | 611 | clk->flags |= CLK_PSC; |
578 | 612 | ||
613 | if (clk->flags & PSC_LRST) | ||
614 | clk->reset = davinci_clk_reset; | ||
615 | |||
579 | clk_register(clk); | 616 | clk_register(clk); |
580 | num_clocks++; | 617 | num_clocks++; |
581 | 618 | ||
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 46f0f1bf1a4c..8694b395fc92 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h | |||
@@ -103,6 +103,7 @@ struct clk { | |||
103 | unsigned long (*recalc) (struct clk *); | 103 | unsigned long (*recalc) (struct clk *); |
104 | int (*set_rate) (struct clk *clk, unsigned long rate); | 104 | int (*set_rate) (struct clk *clk, unsigned long rate); |
105 | int (*round_rate) (struct clk *clk, unsigned long rate); | 105 | int (*round_rate) (struct clk *clk, unsigned long rate); |
106 | int (*reset) (struct clk *clk, bool reset); | ||
106 | }; | 107 | }; |
107 | 108 | ||
108 | /* Clock flags: SoC-specific flags start at BIT(16) */ | 109 | /* Clock flags: SoC-specific flags start at BIT(16) */ |
@@ -112,6 +113,7 @@ struct clk { | |||
112 | #define PRE_PLL BIT(4) /* source is before PLL mult/div */ | 113 | #define PRE_PLL BIT(4) /* source is before PLL mult/div */ |
113 | #define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ | 114 | #define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ |
114 | #define PSC_FORCE BIT(6) /* Force module state transtition */ | 115 | #define PSC_FORCE BIT(6) /* Force module state transtition */ |
116 | #define PSC_LRST BIT(8) /* Use local reset on enable/disable */ | ||
115 | 117 | ||
116 | #define CLK(dev, con, ck) \ | 118 | #define CLK(dev, con, ck) \ |
117 | { \ | 119 | { \ |
@@ -126,6 +128,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv, | |||
126 | int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate); | 128 | int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate); |
127 | int davinci_set_refclk_rate(unsigned long rate); | 129 | int davinci_set_refclk_rate(unsigned long rate); |
128 | int davinci_simple_set_rate(struct clk *clk, unsigned long rate); | 130 | int davinci_simple_set_rate(struct clk *clk, unsigned long rate); |
131 | int davinci_clk_reset(struct clk *clk, bool reset); | ||
129 | 132 | ||
130 | extern struct platform_device davinci_wdt_device; | 133 | extern struct platform_device davinci_wdt_device; |
131 | extern void davinci_watchdog_reset(struct platform_device *); | 134 | extern void davinci_watchdog_reset(struct platform_device *); |
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 6b9154e9f908..0c4a26ddebba 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c | |||
@@ -76,6 +76,13 @@ static struct clk pll0_aux_clk = { | |||
76 | .flags = CLK_PLL | PRE_PLL, | 76 | .flags = CLK_PLL | PRE_PLL, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static struct clk pll0_sysclk1 = { | ||
80 | .name = "pll0_sysclk1", | ||
81 | .parent = &pll0_clk, | ||
82 | .flags = CLK_PLL, | ||
83 | .div_reg = PLLDIV1, | ||
84 | }; | ||
85 | |||
79 | static struct clk pll0_sysclk2 = { | 86 | static struct clk pll0_sysclk2 = { |
80 | .name = "pll0_sysclk2", | 87 | .name = "pll0_sysclk2", |
81 | .parent = &pll0_clk, | 88 | .parent = &pll0_clk, |
@@ -368,10 +375,19 @@ static struct clk sata_clk = { | |||
368 | .flags = PSC_FORCE, | 375 | .flags = PSC_FORCE, |
369 | }; | 376 | }; |
370 | 377 | ||
378 | static struct clk dsp_clk = { | ||
379 | .name = "dsp", | ||
380 | .parent = &pll0_sysclk1, | ||
381 | .domain = DAVINCI_GPSC_DSPDOMAIN, | ||
382 | .lpsc = DA8XX_LPSC0_GEM, | ||
383 | .flags = PSC_LRST | PSC_FORCE, | ||
384 | }; | ||
385 | |||
371 | static struct clk_lookup da850_clks[] = { | 386 | static struct clk_lookup da850_clks[] = { |
372 | CLK(NULL, "ref", &ref_clk), | 387 | CLK(NULL, "ref", &ref_clk), |
373 | CLK(NULL, "pll0", &pll0_clk), | 388 | CLK(NULL, "pll0", &pll0_clk), |
374 | CLK(NULL, "pll0_aux", &pll0_aux_clk), | 389 | CLK(NULL, "pll0_aux", &pll0_aux_clk), |
390 | CLK(NULL, "pll0_sysclk1", &pll0_sysclk1), | ||
375 | CLK(NULL, "pll0_sysclk2", &pll0_sysclk2), | 391 | CLK(NULL, "pll0_sysclk2", &pll0_sysclk2), |
376 | CLK(NULL, "pll0_sysclk3", &pll0_sysclk3), | 392 | CLK(NULL, "pll0_sysclk3", &pll0_sysclk3), |
377 | CLK(NULL, "pll0_sysclk4", &pll0_sysclk4), | 393 | CLK(NULL, "pll0_sysclk4", &pll0_sysclk4), |
@@ -413,6 +429,7 @@ static struct clk_lookup da850_clks[] = { | |||
413 | CLK("spi_davinci.1", NULL, &spi1_clk), | 429 | CLK("spi_davinci.1", NULL, &spi1_clk), |
414 | CLK("vpif", NULL, &vpif_clk), | 430 | CLK("vpif", NULL, &vpif_clk), |
415 | CLK("ahci", NULL, &sata_clk), | 431 | CLK("ahci", NULL, &sata_clk), |
432 | CLK("davinci-rproc.0", NULL, &dsp_clk), | ||
416 | CLK(NULL, NULL, NULL), | 433 | CLK(NULL, NULL, NULL), |
417 | }; | 434 | }; |
418 | 435 | ||
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 2d5502d84a22..aa402bc160c8 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c | |||
@@ -751,7 +751,7 @@ void __iomem * __init da8xx_get_mem_ctlr(void) | |||
751 | 751 | ||
752 | da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K); | 752 | da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K); |
753 | if (!da8xx_ddr2_ctlr_base) | 753 | if (!da8xx_ddr2_ctlr_base) |
754 | pr_warning("%s: Unable to map DDR2 controller", __func__); | 754 | pr_warn("%s: Unable to map DDR2 controller", __func__); |
755 | 755 | ||
756 | return da8xx_ddr2_ctlr_base; | 756 | return da8xx_ddr2_ctlr_base; |
757 | } | 757 | } |
@@ -832,7 +832,7 @@ static struct resource da8xx_spi1_resources[] = { | |||
832 | }, | 832 | }, |
833 | }; | 833 | }; |
834 | 834 | ||
835 | struct davinci_spi_platform_data da8xx_spi_pdata[] = { | 835 | static struct davinci_spi_platform_data da8xx_spi_pdata[] = { |
836 | [0] = { | 836 | [0] = { |
837 | .version = SPI_VERSION_2, | 837 | .version = SPI_VERSION_2, |
838 | .intr_line = 1, | 838 | .intr_line = 1, |
@@ -866,20 +866,12 @@ static struct platform_device da8xx_spi_device[] = { | |||
866 | }, | 866 | }, |
867 | }; | 867 | }; |
868 | 868 | ||
869 | int __init da8xx_register_spi(int instance, const struct spi_board_info *info, | 869 | int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect) |
870 | unsigned len) | ||
871 | { | 870 | { |
872 | int ret; | ||
873 | |||
874 | if (instance < 0 || instance > 1) | 871 | if (instance < 0 || instance > 1) |
875 | return -EINVAL; | 872 | return -EINVAL; |
876 | 873 | ||
877 | ret = spi_register_board_info(info, len); | 874 | da8xx_spi_pdata[instance].num_chipselect = num_chipselect; |
878 | if (ret) | ||
879 | pr_warning("%s: failed to register board info for spi %d :" | ||
880 | " %d\n", __func__, instance, ret); | ||
881 | |||
882 | da8xx_spi_pdata[instance].num_chipselect = len; | ||
883 | 875 | ||
884 | if (instance == 1 && cpu_is_davinci_da850()) { | 876 | if (instance == 1 && cpu_is_davinci_da850()) { |
885 | da8xx_spi1_resources[0].start = DA850_SPI1_BASE; | 877 | da8xx_spi1_resources[0].start = DA850_SPI1_BASE; |
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h index a3b040219876..3e8af6a0b64c 100644 --- a/arch/arm/mach-davinci/include/mach/clock.h +++ b/arch/arm/mach-davinci/include/mach/clock.h | |||
@@ -18,4 +18,7 @@ struct clk; | |||
18 | extern int clk_register(struct clk *clk); | 18 | extern int clk_register(struct clk *clk); |
19 | extern void clk_unregister(struct clk *clk); | 19 | extern void clk_unregister(struct clk *clk); |
20 | 20 | ||
21 | int davinci_clk_reset_assert(struct clk *c); | ||
22 | int davinci_clk_reset_deassert(struct clk *c); | ||
23 | |||
21 | #endif | 24 | #endif |
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 700d311c6854..1b14aea40310 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h | |||
@@ -82,8 +82,7 @@ void __init da850_init(void); | |||
82 | int da830_register_edma(struct edma_rsv_info *rsv); | 82 | int da830_register_edma(struct edma_rsv_info *rsv); |
83 | int da850_register_edma(struct edma_rsv_info *rsv[2]); | 83 | int da850_register_edma(struct edma_rsv_info *rsv[2]); |
84 | int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata); | 84 | int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata); |
85 | int da8xx_register_spi(int instance, | 85 | int da8xx_register_spi_bus(int instance, unsigned num_chipselect); |
86 | const struct spi_board_info *info, unsigned len); | ||
87 | int da8xx_register_watchdog(void); | 86 | int da8xx_register_watchdog(void); |
88 | int da8xx_register_usb20(unsigned mA, unsigned potpgt); | 87 | int da8xx_register_usb20(unsigned mA, unsigned potpgt); |
89 | int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata); | 88 | int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata); |
@@ -110,7 +109,6 @@ extern struct platform_device da8xx_serial_device; | |||
110 | extern struct emac_platform_data da8xx_emac_pdata; | 109 | extern struct emac_platform_data da8xx_emac_pdata; |
111 | extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata; | 110 | extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata; |
112 | extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata; | 111 | extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata; |
113 | extern struct davinci_spi_platform_data da8xx_spi_pdata[]; | ||
114 | 112 | ||
115 | extern struct platform_device da8xx_wdt_device; | 113 | extern struct platform_device da8xx_wdt_device; |
116 | 114 | ||
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 40a0027838e8..0a22710493fd 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h | |||
@@ -246,6 +246,7 @@ | |||
246 | 246 | ||
247 | #define MDSTAT_STATE_MASK 0x3f | 247 | #define MDSTAT_STATE_MASK 0x3f |
248 | #define PDSTAT_STATE_MASK 0x1f | 248 | #define PDSTAT_STATE_MASK 0x1f |
249 | #define MDCTL_LRST BIT(8) | ||
249 | #define MDCTL_FORCE BIT(31) | 250 | #define MDCTL_FORCE BIT(31) |
250 | #define PDCTL_NEXT BIT(0) | 251 | #define PDCTL_NEXT BIT(0) |
251 | #define PDCTL_EPCGOOD BIT(8) | 252 | #define PDCTL_EPCGOOD BIT(8) |
@@ -253,6 +254,8 @@ | |||
253 | #ifndef __ASSEMBLER__ | 254 | #ifndef __ASSEMBLER__ |
254 | 255 | ||
255 | extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); | 256 | extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); |
257 | extern void davinci_psc_reset(unsigned int ctlr, unsigned int id, | ||
258 | bool reset); | ||
256 | extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, | 259 | extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, |
257 | unsigned int id, bool enable, u32 flags); | 260 | unsigned int id, bool enable, u32 flags); |
258 | 261 | ||
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index d7e210f4b55c..82fdc69d5728 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c | |||
@@ -35,7 +35,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) | |||
35 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 35 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
36 | 36 | ||
37 | if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { | 37 | if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { |
38 | pr_warning("PSC: Bad psc data: 0x%x[%d]\n", | 38 | pr_warn("PSC: Bad psc data: 0x%x[%d]\n", |
39 | (int)soc_info->psc_bases, ctlr); | 39 | (int)soc_info->psc_bases, ctlr); |
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
@@ -48,6 +48,31 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) | |||
48 | return mdstat & BIT(12); | 48 | return mdstat & BIT(12); |
49 | } | 49 | } |
50 | 50 | ||
51 | /* Control "reset" line associated with PSC domain */ | ||
52 | void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset) | ||
53 | { | ||
54 | u32 mdctl; | ||
55 | void __iomem *psc_base; | ||
56 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
57 | |||
58 | if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { | ||
59 | pr_warn("PSC: Bad psc data: 0x%x[%d]\n", | ||
60 | (int)soc_info->psc_bases, ctlr); | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K); | ||
65 | |||
66 | mdctl = readl(psc_base + MDCTL + 4 * id); | ||
67 | if (reset) | ||
68 | mdctl &= ~MDCTL_LRST; | ||
69 | else | ||
70 | mdctl |= MDCTL_LRST; | ||
71 | writel(mdctl, psc_base + MDCTL + 4 * id); | ||
72 | |||
73 | iounmap(psc_base); | ||
74 | } | ||
75 | |||
51 | /* Enable or disable a PSC domain */ | 76 | /* Enable or disable a PSC domain */ |
52 | void davinci_psc_config(unsigned int domain, unsigned int ctlr, | 77 | void davinci_psc_config(unsigned int domain, unsigned int ctlr, |
53 | unsigned int id, bool enable, u32 flags) | 78 | unsigned int id, bool enable, u32 flags) |
@@ -58,7 +83,7 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, | |||
58 | u32 next_state = PSC_STATE_ENABLE; | 83 | u32 next_state = PSC_STATE_ENABLE; |
59 | 84 | ||
60 | if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { | 85 | if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { |
61 | pr_warning("PSC: Bad psc data: 0x%x[%d]\n", | 86 | pr_warn("PSC: Bad psc data: 0x%x[%d]\n", |
62 | (int)soc_info->psc_bases, ctlr); | 87 | (int)soc_info->psc_bases, ctlr); |
63 | return; | 88 | return; |
64 | } | 89 | } |
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 240e0294c372..c4ce0906d76a 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile | |||
@@ -28,7 +28,11 @@ obj-$(CONFIG_MXC_ULPI) += ulpi.o | |||
28 | obj-$(CONFIG_MXC_USE_EPIT) += epit.o | 28 | obj-$(CONFIG_MXC_USE_EPIT) += epit.o |
29 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o | 29 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o |
30 | obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o | 30 | obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o |
31 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | 31 | |
32 | ifeq ($(CONFIG_CPU_IDLE),y) | ||
33 | obj-y += cpuidle.o | ||
34 | obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o | ||
35 | endif | ||
32 | 36 | ||
33 | ifdef CONFIG_SND_IMX_SOC | 37 | ifdef CONFIG_SND_IMX_SOC |
34 | obj-y += ssi-fiq.o | 38 | obj-y += ssi-fiq.o |
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index e30369a58e4e..30b3242a7d49 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c | |||
@@ -62,7 +62,7 @@ static const char *clko_sel_clks[] = { | |||
62 | "32k", "usb_div", "dptc", | 62 | "32k", "usb_div", "dptc", |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static const char *ssi_sel_clks[] = { "spll", "mpll", }; | 65 | static const char *ssi_sel_clks[] = { "spll_gate", "mpll", }; |
66 | 66 | ||
67 | enum mx27_clks { | 67 | enum mx27_clks { |
68 | dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div, | 68 | dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div, |
@@ -82,7 +82,7 @@ enum mx27_clks { | |||
82 | csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate, | 82 | csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate, |
83 | uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate, | 83 | uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate, |
84 | uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel, | 84 | uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel, |
85 | mpll_sel, clk_max | 85 | mpll_sel, spll_gate, clk_max |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static struct clk *clk[clk_max]; | 88 | static struct clk *clk[clk_max]; |
@@ -104,6 +104,7 @@ int __init mx27_clocks_init(unsigned long fref) | |||
104 | ARRAY_SIZE(mpll_sel_clks)); | 104 | ARRAY_SIZE(mpll_sel_clks)); |
105 | clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); | 105 | clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); |
106 | clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0); | 106 | clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0); |
107 | clk[spll_gate] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); | ||
107 | clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); | 108 | clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); |
108 | 109 | ||
109 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { | 110 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { |
@@ -121,7 +122,7 @@ int __init mx27_clocks_init(unsigned long fref) | |||
121 | clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6); | 122 | clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6); |
122 | clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks)); | 123 | clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks)); |
123 | clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6); | 124 | clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6); |
124 | clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3); | 125 | clk[usb_div] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 28, 3); |
125 | clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); | 126 | clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); |
126 | clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); | 127 | clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); |
127 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) | 128 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) |
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index 16ccbd41dea9..b5b65f3efaf1 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c | |||
@@ -34,8 +34,8 @@ static const char *csi_sel[] = { "upll", "spll", }; | |||
34 | static const char *fir_sel[] = { "mcu_main", "upll", "spll" }; | 34 | static const char *fir_sel[] = { "mcu_main", "upll", "spll" }; |
35 | 35 | ||
36 | enum mx31_clks { | 36 | enum mx31_clks { |
37 | ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div, | 37 | dummy, ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, |
38 | per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre, | 38 | per_div, per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre, |
39 | fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate, | 39 | fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate, |
40 | iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate, | 40 | iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate, |
41 | uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate, | 41 | uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate, |
@@ -46,12 +46,15 @@ enum mx31_clks { | |||
46 | }; | 46 | }; |
47 | 47 | ||
48 | static struct clk *clk[clk_max]; | 48 | static struct clk *clk[clk_max]; |
49 | static struct clk_onecell_data clk_data; | ||
49 | 50 | ||
50 | int __init mx31_clocks_init(unsigned long fref) | 51 | int __init mx31_clocks_init(unsigned long fref) |
51 | { | 52 | { |
52 | void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); | 53 | void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); |
53 | int i; | 54 | int i; |
55 | struct device_node *np; | ||
54 | 56 | ||
57 | clk[dummy] = imx_clk_fixed("dummy", 0); | ||
55 | clk[ckih] = imx_clk_fixed("ckih", fref); | 58 | clk[ckih] = imx_clk_fixed("ckih", fref); |
56 | clk[ckil] = imx_clk_fixed("ckil", 32768); | 59 | clk[ckil] = imx_clk_fixed("ckil", 32768); |
57 | clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL); | 60 | clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL); |
@@ -116,6 +119,14 @@ int __init mx31_clocks_init(unsigned long fref) | |||
116 | pr_err("imx31 clk %d: register failed with %ld\n", | 119 | pr_err("imx31 clk %d: register failed with %ld\n", |
117 | i, PTR_ERR(clk[i])); | 120 | i, PTR_ERR(clk[i])); |
118 | 121 | ||
122 | np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); | ||
123 | |||
124 | if (np) { | ||
125 | clk_data.clks = clk; | ||
126 | clk_data.clk_num = ARRAY_SIZE(clk); | ||
127 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
128 | } | ||
129 | |||
119 | clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); | 130 | clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); |
120 | clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); | 131 | clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); |
121 | clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0"); | 132 | clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0"); |
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index f0727e80815d..74e3a34d78b8 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c | |||
@@ -67,13 +67,13 @@ enum mx35_clks { | |||
67 | 67 | ||
68 | static struct clk *clk[clk_max]; | 68 | static struct clk *clk[clk_max]; |
69 | 69 | ||
70 | int __init mx35_clocks_init() | 70 | int __init mx35_clocks_init(void) |
71 | { | 71 | { |
72 | void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); | 72 | void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); |
73 | u32 pdr0, consumer_sel, hsp_sel; | 73 | u32 pdr0, consumer_sel, hsp_sel; |
74 | struct arm_ahb_div *aad; | 74 | struct arm_ahb_div *aad; |
75 | unsigned char *hsp_div; | 75 | unsigned char *hsp_div; |
76 | int i; | 76 | u32 i; |
77 | 77 | ||
78 | pdr0 = __raw_readl(base + MXC_CCM_PDR0); | 78 | pdr0 = __raw_readl(base + MXC_CCM_PDR0); |
79 | consumer_sel = (pdr0 >> 16) & 0xf; | 79 | consumer_sel = (pdr0 >> 16) & 0xf; |
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 19644f6524dc..540138c4606c 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c | |||
@@ -54,8 +54,19 @@ | |||
54 | #define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) | 54 | #define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) |
55 | #define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) | 55 | #define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) |
56 | 56 | ||
57 | #define CGPR 0x64 | ||
58 | #define BM_CGPR_CHICKEN_BIT (0x1 << 17) | ||
59 | |||
57 | static void __iomem *ccm_base; | 60 | static void __iomem *ccm_base; |
58 | 61 | ||
62 | void imx6q_set_chicken_bit(void) | ||
63 | { | ||
64 | u32 val = readl_relaxed(ccm_base + CGPR); | ||
65 | |||
66 | val |= BM_CGPR_CHICKEN_BIT; | ||
67 | writel_relaxed(val, ccm_base + CGPR); | ||
68 | } | ||
69 | |||
59 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | 70 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) |
60 | { | 71 | { |
61 | u32 val = readl_relaxed(ccm_base + CLPCR); | 72 | u32 val = readl_relaxed(ccm_base + CLPCR); |
@@ -66,6 +77,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | |||
66 | break; | 77 | break; |
67 | case WAIT_UNCLOCKED: | 78 | case WAIT_UNCLOCKED: |
68 | val |= 0x1 << BP_CLPCR_LPM; | 79 | val |= 0x1 << BP_CLPCR_LPM; |
80 | val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; | ||
69 | break; | 81 | break; |
70 | case STOP_POWER_ON: | 82 | case STOP_POWER_ON: |
71 | val |= 0x2 << BP_CLPCR_LPM; | 83 | val |= 0x2 << BP_CLPCR_LPM; |
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 76c420043289..5a800bfcec5b 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -116,9 +116,11 @@ extern u32 *pl310_get_save_ptr(void); | |||
116 | extern void v7_secondary_startup(void); | 116 | extern void v7_secondary_startup(void); |
117 | extern void imx_scu_map_io(void); | 117 | extern void imx_scu_map_io(void); |
118 | extern void imx_smp_prepare(void); | 118 | extern void imx_smp_prepare(void); |
119 | extern void imx_scu_standby_enable(void); | ||
119 | #else | 120 | #else |
120 | static inline void imx_scu_map_io(void) {} | 121 | static inline void imx_scu_map_io(void) {} |
121 | static inline void imx_smp_prepare(void) {} | 122 | static inline void imx_smp_prepare(void) {} |
123 | static inline void imx_scu_standby_enable(void) {} | ||
122 | #endif | 124 | #endif |
123 | extern void imx_enable_cpu(int cpu, bool enable); | 125 | extern void imx_enable_cpu(int cpu, bool enable); |
124 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); | 126 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); |
@@ -128,6 +130,7 @@ extern void imx_gpc_init(void); | |||
128 | extern void imx_gpc_pre_suspend(void); | 130 | extern void imx_gpc_pre_suspend(void); |
129 | extern void imx_gpc_post_resume(void); | 131 | extern void imx_gpc_post_resume(void); |
130 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | 132 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); |
133 | extern void imx6q_set_chicken_bit(void); | ||
131 | 134 | ||
132 | extern void imx_cpu_die(unsigned int cpu); | 135 | extern void imx_cpu_die(unsigned int cpu); |
133 | extern int imx_cpu_kill(unsigned int cpu); | 136 | extern int imx_cpu_kill(unsigned int cpu); |
diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c new file mode 100644 index 000000000000..d533e2695f0e --- /dev/null +++ b/arch/arm/mach-imx/cpuidle-imx6q.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/clockchips.h> | ||
10 | #include <linux/cpuidle.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <asm/cpuidle.h> | ||
13 | #include <asm/proc-fns.h> | ||
14 | |||
15 | #include "common.h" | ||
16 | #include "cpuidle.h" | ||
17 | |||
18 | static atomic_t master = ATOMIC_INIT(0); | ||
19 | static DEFINE_SPINLOCK(master_lock); | ||
20 | |||
21 | static int imx6q_enter_wait(struct cpuidle_device *dev, | ||
22 | struct cpuidle_driver *drv, int index) | ||
23 | { | ||
24 | int cpu = dev->cpu; | ||
25 | |||
26 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | ||
27 | |||
28 | if (atomic_inc_return(&master) == num_online_cpus()) { | ||
29 | /* | ||
30 | * With this lock, we prevent other cpu to exit and enter | ||
31 | * this function again and become the master. | ||
32 | */ | ||
33 | if (!spin_trylock(&master_lock)) | ||
34 | goto idle; | ||
35 | imx6q_set_lpm(WAIT_UNCLOCKED); | ||
36 | cpu_do_idle(); | ||
37 | imx6q_set_lpm(WAIT_CLOCKED); | ||
38 | spin_unlock(&master_lock); | ||
39 | goto done; | ||
40 | } | ||
41 | |||
42 | idle: | ||
43 | cpu_do_idle(); | ||
44 | done: | ||
45 | atomic_dec(&master); | ||
46 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | ||
47 | |||
48 | return index; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * For each cpu, setup the broadcast timer because local timer | ||
53 | * stops for the states other than WFI. | ||
54 | */ | ||
55 | static void imx6q_setup_broadcast_timer(void *arg) | ||
56 | { | ||
57 | int cpu = smp_processor_id(); | ||
58 | |||
59 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); | ||
60 | } | ||
61 | |||
62 | static struct cpuidle_driver imx6q_cpuidle_driver = { | ||
63 | .name = "imx6q_cpuidle", | ||
64 | .owner = THIS_MODULE, | ||
65 | .en_core_tk_irqen = 1, | ||
66 | .states = { | ||
67 | /* WFI */ | ||
68 | ARM_CPUIDLE_WFI_STATE, | ||
69 | /* WAIT */ | ||
70 | { | ||
71 | .exit_latency = 50, | ||
72 | .target_residency = 75, | ||
73 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
74 | .enter = imx6q_enter_wait, | ||
75 | .name = "WAIT", | ||
76 | .desc = "Clock off", | ||
77 | }, | ||
78 | }, | ||
79 | .state_count = 2, | ||
80 | .safe_state_index = 0, | ||
81 | }; | ||
82 | |||
83 | int __init imx6q_cpuidle_init(void) | ||
84 | { | ||
85 | /* Need to enable SCU standby for entering WAIT modes */ | ||
86 | imx_scu_standby_enable(); | ||
87 | |||
88 | /* Set chicken bit to get a reliable WAIT mode support */ | ||
89 | imx6q_set_chicken_bit(); | ||
90 | |||
91 | /* Configure the broadcast timer on each cpu */ | ||
92 | on_each_cpu(imx6q_setup_broadcast_timer, NULL, 1); | ||
93 | |||
94 | return imx_cpuidle_init(&imx6q_cpuidle_driver); | ||
95 | } | ||
diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h index bc932d1af372..e092d1359d94 100644 --- a/arch/arm/mach-imx/cpuidle.h +++ b/arch/arm/mach-imx/cpuidle.h | |||
@@ -14,9 +14,14 @@ | |||
14 | 14 | ||
15 | #ifdef CONFIG_CPU_IDLE | 15 | #ifdef CONFIG_CPU_IDLE |
16 | extern int imx_cpuidle_init(struct cpuidle_driver *drv); | 16 | extern int imx_cpuidle_init(struct cpuidle_driver *drv); |
17 | extern int imx6q_cpuidle_init(void); | ||
17 | #else | 18 | #else |
18 | static inline int imx_cpuidle_init(struct cpuidle_driver *drv) | 19 | static inline int imx_cpuidle_init(struct cpuidle_driver *drv) |
19 | { | 20 | { |
20 | return -ENODEV; | 21 | return -ENODEV; |
21 | } | 22 | } |
23 | static inline int imx6q_cpuidle_init(void) | ||
24 | { | ||
25 | return -ENODEV; | ||
26 | } | ||
22 | #endif | 27 | #endif |
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index ff24920699e4..a96ccc7f5012 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c | |||
@@ -101,11 +101,16 @@ static void imx_gpc_irq_mask(struct irq_data *d) | |||
101 | void __init imx_gpc_init(void) | 101 | void __init imx_gpc_init(void) |
102 | { | 102 | { |
103 | struct device_node *np; | 103 | struct device_node *np; |
104 | int i; | ||
104 | 105 | ||
105 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc"); | 106 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc"); |
106 | gpc_base = of_iomap(np, 0); | 107 | gpc_base = of_iomap(np, 0); |
107 | WARN_ON(!gpc_base); | 108 | WARN_ON(!gpc_base); |
108 | 109 | ||
110 | /* Initially mask all interrupts */ | ||
111 | for (i = 0; i < IMR_NUM; i++) | ||
112 | writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4); | ||
113 | |||
109 | /* Register GPC as the secondary interrupt controller behind GIC */ | 114 | /* Register GPC as the secondary interrupt controller behind GIC */ |
110 | gic_arch_extn.irq_mask = imx_gpc_irq_mask; | 115 | gic_arch_extn.irq_mask = imx_gpc_irq_mask; |
111 | gic_arch_extn.irq_unmask = imx_gpc_irq_unmask; | 116 | gic_arch_extn.irq_unmask = imx_gpc_irq_unmask; |
diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index 7e49deb128a4..921fc1555854 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S | |||
@@ -17,53 +17,6 @@ | |||
17 | 17 | ||
18 | .section ".text.head", "ax" | 18 | .section ".text.head", "ax" |
19 | 19 | ||
20 | /* | ||
21 | * The secondary kernel init calls v7_flush_dcache_all before it enables | ||
22 | * the L1; however, the L1 comes out of reset in an undefined state, so | ||
23 | * the clean + invalidate performed by v7_flush_dcache_all causes a bunch | ||
24 | * of cache lines with uninitialized data and uninitialized tags to get | ||
25 | * written out to memory, which does really unpleasant things to the main | ||
26 | * processor. We fix this by performing an invalidate, rather than a | ||
27 | * clean + invalidate, before jumping into the kernel. | ||
28 | * | ||
29 | * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs | ||
30 | * to be called for both secondary cores startup and primary core resume | ||
31 | * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S. | ||
32 | */ | ||
33 | ENTRY(v7_invalidate_l1) | ||
34 | mov r0, #0 | ||
35 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
36 | mcr p15, 2, r0, c0, c0, 0 | ||
37 | mrc p15, 1, r0, c0, c0, 0 | ||
38 | |||
39 | ldr r1, =0x7fff | ||
40 | and r2, r1, r0, lsr #13 | ||
41 | |||
42 | ldr r1, =0x3ff | ||
43 | |||
44 | and r3, r1, r0, lsr #3 @ NumWays - 1 | ||
45 | add r2, r2, #1 @ NumSets | ||
46 | |||
47 | and r0, r0, #0x7 | ||
48 | add r0, r0, #4 @ SetShift | ||
49 | |||
50 | clz r1, r3 @ WayShift | ||
51 | add r4, r3, #1 @ NumWays | ||
52 | 1: sub r2, r2, #1 @ NumSets-- | ||
53 | mov r3, r4 @ Temp = NumWays | ||
54 | 2: subs r3, r3, #1 @ Temp-- | ||
55 | mov r5, r3, lsl r1 | ||
56 | mov r6, r2, lsl r0 | ||
57 | orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) | ||
58 | mcr p15, 0, r5, c7, c6, 2 | ||
59 | bgt 2b | ||
60 | cmp r2, #0 | ||
61 | bgt 1b | ||
62 | dsb | ||
63 | isb | ||
64 | mov pc, lr | ||
65 | ENDPROC(v7_invalidate_l1) | ||
66 | |||
67 | #ifdef CONFIG_SMP | 20 | #ifdef CONFIG_SMP |
68 | ENTRY(v7_secondary_startup) | 21 | ENTRY(v7_secondary_startup) |
69 | bl v7_invalidate_l1 | 22 | bl v7_invalidate_l1 |
diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/imx31-dt.c index b5c04eece780..67de611e29ab 100644 --- a/arch/arm/mach-imx/imx31-dt.c +++ b/arch/arm/mach-imx/imx31-dt.c | |||
@@ -18,24 +18,9 @@ | |||
18 | #include "common.h" | 18 | #include "common.h" |
19 | #include "mx31.h" | 19 | #include "mx31.h" |
20 | 20 | ||
21 | static const struct of_dev_auxdata imx31_auxdata_lookup[] __initconst = { | ||
22 | OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART1_BASE_ADDR, | ||
23 | "imx21-uart.0", NULL), | ||
24 | OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART2_BASE_ADDR, | ||
25 | "imx21-uart.1", NULL), | ||
26 | OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART3_BASE_ADDR, | ||
27 | "imx21-uart.2", NULL), | ||
28 | OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART4_BASE_ADDR, | ||
29 | "imx21-uart.3", NULL), | ||
30 | OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART5_BASE_ADDR, | ||
31 | "imx21-uart.4", NULL), | ||
32 | { /* sentinel */ } | ||
33 | }; | ||
34 | |||
35 | static void __init imx31_dt_init(void) | 21 | static void __init imx31_dt_init(void) |
36 | { | 22 | { |
37 | of_platform_populate(NULL, of_default_bus_match_table, | 23 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
38 | imx31_auxdata_lookup, NULL); | ||
39 | } | 24 | } |
40 | 25 | ||
41 | static const char *imx31_dt_board_compat[] __initdata = { | 26 | static const char *imx31_dt_board_compat[] __initdata = { |
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 5a18e7e5c564..1786b2d1257e 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
15 | #include <linux/cpuidle.h> | ||
16 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
17 | #include <linux/export.h> | 16 | #include <linux/export.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -27,7 +26,6 @@ | |||
27 | #include <linux/regmap.h> | 26 | #include <linux/regmap.h> |
28 | #include <linux/micrel_phy.h> | 27 | #include <linux/micrel_phy.h> |
29 | #include <linux/mfd/syscon.h> | 28 | #include <linux/mfd/syscon.h> |
30 | #include <asm/cpuidle.h> | ||
31 | #include <asm/smp_twd.h> | 29 | #include <asm/smp_twd.h> |
32 | #include <asm/hardware/cache-l2x0.h> | 30 | #include <asm/hardware/cache-l2x0.h> |
33 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
@@ -202,17 +200,14 @@ static void __init imx6q_init_machine(void) | |||
202 | imx6q_1588_init(); | 200 | imx6q_1588_init(); |
203 | } | 201 | } |
204 | 202 | ||
205 | static struct cpuidle_driver imx6q_cpuidle_driver = { | ||
206 | .name = "imx6q_cpuidle", | ||
207 | .owner = THIS_MODULE, | ||
208 | .en_core_tk_irqen = 1, | ||
209 | .states[0] = ARM_CPUIDLE_WFI_STATE, | ||
210 | .state_count = 1, | ||
211 | }; | ||
212 | |||
213 | static void __init imx6q_init_late(void) | 203 | static void __init imx6q_init_late(void) |
214 | { | 204 | { |
215 | imx_cpuidle_init(&imx6q_cpuidle_driver); | 205 | /* |
206 | * WAIT mode is broken on TO 1.0 and 1.1, so there is no point | ||
207 | * to run cpuidle on them. | ||
208 | */ | ||
209 | if (imx6q_revision() > IMX_CHIP_REVISION_1_1) | ||
210 | imx6q_cpuidle_init(); | ||
216 | } | 211 | } |
217 | 212 | ||
218 | static void __init imx6q_map_io(void) | 213 | static void __init imx6q_map_io(void) |
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index b2872ec614a4..7c0b03f67b05 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include "common.h" | 20 | #include "common.h" |
21 | #include "hardware.h" | 21 | #include "hardware.h" |
22 | 22 | ||
23 | #define SCU_STANDBY_ENABLE (1 << 5) | ||
24 | |||
23 | static void __iomem *scu_base; | 25 | static void __iomem *scu_base; |
24 | 26 | ||
25 | static struct map_desc scu_io_desc __initdata = { | 27 | static struct map_desc scu_io_desc __initdata = { |
@@ -42,6 +44,14 @@ void __init imx_scu_map_io(void) | |||
42 | scu_base = IMX_IO_ADDRESS(base); | 44 | scu_base = IMX_IO_ADDRESS(base); |
43 | } | 45 | } |
44 | 46 | ||
47 | void imx_scu_standby_enable(void) | ||
48 | { | ||
49 | u32 val = readl_relaxed(scu_base); | ||
50 | |||
51 | val |= SCU_STANDBY_ENABLE; | ||
52 | writel_relaxed(val, scu_base); | ||
53 | } | ||
54 | |||
45 | static void __cpuinit imx_secondary_init(unsigned int cpu) | 55 | static void __cpuinit imx_secondary_init(unsigned int cpu) |
46 | { | 56 | { |
47 | /* | 57 | /* |
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 62769df36db1..fea91313678b 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c | |||
@@ -152,7 +152,8 @@ static int v2_set_next_event(unsigned long evt, | |||
152 | 152 | ||
153 | __raw_writel(tcmp, timer_base + V2_TCMP); | 153 | __raw_writel(tcmp, timer_base + V2_TCMP); |
154 | 154 | ||
155 | return (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ? | 155 | return evt < 0x7fffffff && |
156 | (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ? | ||
156 | -ETIME : 0; | 157 | -ETIME : 0; |
157 | } | 158 | } |
158 | 159 | ||
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 8d2e5a96247c..d6653095a1eb 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile | |||
@@ -19,7 +19,6 @@ obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o | |||
19 | obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o | 19 | obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o |
20 | obj-$(CONFIG_MACH_T5325) += t5325-setup.o | 20 | obj-$(CONFIG_MACH_T5325) += t5325-setup.o |
21 | 21 | ||
22 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | ||
23 | obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o | 22 | obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o |
24 | obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o | 23 | obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o |
25 | obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o | 24 | obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o |
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index d4af5c191c24..95cc04d14b65 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c | |||
@@ -98,6 +98,8 @@ static void __init kirkwood_dt_init(void) | |||
98 | /* Setup root of clk tree */ | 98 | /* Setup root of clk tree */ |
99 | kirkwood_of_clk_init(); | 99 | kirkwood_of_clk_init(); |
100 | 100 | ||
101 | kirkwood_cpuidle_init(); | ||
102 | |||
101 | #ifdef CONFIG_KEXEC | 103 | #ifdef CONFIG_KEXEC |
102 | kexec_reinit = kirkwood_enable_pcie; | 104 | kexec_reinit = kirkwood_enable_pcie; |
103 | #endif | 105 | #endif |
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index b5ad4dff6b12..49792a0cd2d3 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -499,6 +499,28 @@ void __init kirkwood_wdt_init(void) | |||
499 | orion_wdt_init(); | 499 | orion_wdt_init(); |
500 | } | 500 | } |
501 | 501 | ||
502 | /***************************************************************************** | ||
503 | * CPU idle | ||
504 | ****************************************************************************/ | ||
505 | static struct resource kirkwood_cpuidle_resource[] = { | ||
506 | { | ||
507 | .flags = IORESOURCE_MEM, | ||
508 | .start = DDR_OPERATION_BASE, | ||
509 | .end = DDR_OPERATION_BASE + 3, | ||
510 | }, | ||
511 | }; | ||
512 | |||
513 | static struct platform_device kirkwood_cpuidle = { | ||
514 | .name = "kirkwood_cpuidle", | ||
515 | .id = -1, | ||
516 | .resource = kirkwood_cpuidle_resource, | ||
517 | .num_resources = 1, | ||
518 | }; | ||
519 | |||
520 | void __init kirkwood_cpuidle_init(void) | ||
521 | { | ||
522 | platform_device_register(&kirkwood_cpuidle); | ||
523 | } | ||
502 | 524 | ||
503 | /***************************************************************************** | 525 | /***************************************************************************** |
504 | * Time handling | 526 | * Time handling |
@@ -667,6 +689,7 @@ void __init kirkwood_init(void) | |||
667 | kirkwood_xor1_init(); | 689 | kirkwood_xor1_init(); |
668 | kirkwood_crypto_init(); | 690 | kirkwood_crypto_init(); |
669 | 691 | ||
692 | kirkwood_cpuidle_init(); | ||
670 | #ifdef CONFIG_KEXEC | 693 | #ifdef CONFIG_KEXEC |
671 | kexec_reinit = kirkwood_enable_pcie; | 694 | kexec_reinit = kirkwood_enable_pcie; |
672 | #endif | 695 | #endif |
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 283ab611e8da..e956d0277dd1 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h | |||
@@ -50,6 +50,7 @@ void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay); | |||
50 | void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, | 50 | void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, |
51 | int (*dev_ready)(struct mtd_info *)); | 51 | int (*dev_ready)(struct mtd_info *)); |
52 | void kirkwood_audio_init(void); | 52 | void kirkwood_audio_init(void); |
53 | void kirkwood_cpuidle_init(void); | ||
53 | void kirkwood_restart(char, const char *); | 54 | void kirkwood_restart(char, const char *); |
54 | void kirkwood_clk_init(void); | 55 | void kirkwood_clk_init(void); |
55 | 56 | ||
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 041653a04a9c..a05563a31c95 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h | |||
@@ -60,8 +60,9 @@ | |||
60 | * Register Map | 60 | * Register Map |
61 | */ | 61 | */ |
62 | #define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000) | 62 | #define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000) |
63 | #define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000) | ||
63 | #define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500) | 64 | #define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500) |
64 | #define DDR_OPERATION_BASE (DDR_VIRT_BASE + 0x1418) | 65 | #define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418) |
65 | 66 | ||
66 | #define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000) | 67 | #define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000) |
67 | #define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x10000) | 68 | #define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x10000) |
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index a1c3ab6fc809..d96ad4c09972 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c | |||
@@ -247,13 +247,9 @@ static struct hw_pci kirkwood_pci __initdata = { | |||
247 | 247 | ||
248 | static void __init add_pcie_port(int index, void __iomem *base) | 248 | static void __init add_pcie_port(int index, void __iomem *base) |
249 | { | 249 | { |
250 | pr_info("Kirkwood PCIe port %d: ", index); | 250 | pcie_port_map[num_pcie_ports++] = index; |
251 | 251 | pr_info("Kirkwood PCIe port %d: link %s\n", index, | |
252 | if (orion_pcie_link_up(base)) { | 252 | orion_pcie_link_up(base) ? "up" : "down"); |
253 | pr_info("link up\n"); | ||
254 | pcie_port_map[num_pcie_ports++] = index; | ||
255 | } else | ||
256 | pr_info("link down, ignoring\n"); | ||
257 | } | 253 | } |
258 | 254 | ||
259 | void __init kirkwood_pcie_init(unsigned int portmask) | 255 | void __init kirkwood_pcie_init(unsigned int portmask) |
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c index 27451b1ba3f1..421020498a1b 100644 --- a/arch/arm/mach-mxs/timer.c +++ b/arch/arm/mach-mxs/timer.c | |||
@@ -72,8 +72,9 @@ | |||
72 | #define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14) | 72 | #define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14) |
73 | #define BM_TIMROT_TIMCTRLn_IRQ (1 << 15) | 73 | #define BM_TIMROT_TIMCTRLn_IRQ (1 << 15) |
74 | #define BP_TIMROT_TIMCTRLn_SELECT 0 | 74 | #define BP_TIMROT_TIMCTRLn_SELECT 0 |
75 | #define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8 | 75 | #define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8 |
76 | #define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb | 76 | #define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb |
77 | #define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS 0xf | ||
77 | 78 | ||
78 | static struct clock_event_device mxs_clockevent_device; | 79 | static struct clock_event_device mxs_clockevent_device; |
79 | static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED; | 80 | static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED; |
@@ -206,7 +207,8 @@ static int __init mxs_clockevent_init(struct clk *timer_clk) | |||
206 | mxs_clockevent_device.set_next_event = timrotv1_set_next_event; | 207 | mxs_clockevent_device.set_next_event = timrotv1_set_next_event; |
207 | mxs_clockevent_device.cpumask = cpumask_of(0); | 208 | mxs_clockevent_device.cpumask = cpumask_of(0); |
208 | clockevents_config_and_register(&mxs_clockevent_device, | 209 | clockevents_config_and_register(&mxs_clockevent_device, |
209 | clk_get_rate(timer_clk), 0xf, | 210 | clk_get_rate(timer_clk), |
211 | timrot_is_v1() ? 0xf : 0x2, | ||
210 | timrot_is_v1() ? 0xfffe : 0xfffffffe); | 212 | timrot_is_v1() ? 0xfffe : 0xfffffffe); |
211 | 213 | ||
212 | return 0; | 214 | return 0; |
@@ -274,7 +276,7 @@ void __init mxs_timer_init(void) | |||
274 | /* one for clock_event */ | 276 | /* one for clock_event */ |
275 | __raw_writel((timrot_is_v1() ? | 277 | __raw_writel((timrot_is_v1() ? |
276 | BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL : | 278 | BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL : |
277 | BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) | | 279 | BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) | |
278 | BM_TIMROT_TIMCTRLn_UPDATE | | 280 | BM_TIMROT_TIMCTRLn_UPDATE | |
279 | BM_TIMROT_TIMCTRLn_IRQ_EN, | 281 | BM_TIMROT_TIMCTRLn_IRQ_EN, |
280 | mxs_timrot_base + HW_TIMROT_TIMCTRLn(0)); | 282 | mxs_timrot_base + HW_TIMROT_TIMCTRLn(0)); |
@@ -282,7 +284,7 @@ void __init mxs_timer_init(void) | |||
282 | /* another for clocksource */ | 284 | /* another for clocksource */ |
283 | __raw_writel((timrot_is_v1() ? | 285 | __raw_writel((timrot_is_v1() ? |
284 | BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL : | 286 | BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL : |
285 | BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) | | 287 | BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) | |
286 | BM_TIMROT_TIMCTRLn_RELOAD, | 288 | BM_TIMROT_TIMCTRLn_RELOAD, |
287 | mxs_timrot_base + HW_TIMROT_TIMCTRLn(1)); | 289 | mxs_timrot_base + HW_TIMROT_TIMCTRLn(1)); |
288 | 290 | ||
diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c index af11dcdb7e2c..a00d39107a21 100644 --- a/arch/arm/mach-omap2/am35xx-emac.c +++ b/arch/arm/mach-omap2/am35xx-emac.c | |||
@@ -63,7 +63,7 @@ static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh, | |||
63 | struct platform_device *pdev; | 63 | struct platform_device *pdev; |
64 | 64 | ||
65 | pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len, | 65 | pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len, |
66 | NULL, 0, false); | 66 | false); |
67 | if (IS_ERR(pdev)) { | 67 | if (IS_ERR(pdev)) { |
68 | WARN(1, "Can't build omap_device for %s:%s.\n", | 68 | WARN(1, "Can't build omap_device for %s:%s.\n", |
69 | oh->class->name, oh->name); | 69 | oh->class->name, oh->name); |
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index e71ebdefc679..15a3914ab492 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
@@ -425,7 +425,7 @@ static void enable_board_wakeup_source(void) | |||
425 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); | 425 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); |
426 | } | 426 | } |
427 | 427 | ||
428 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 428 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
429 | 429 | ||
430 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 430 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
431 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 431 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 33846274bb8a..67447bd4564f 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c | |||
@@ -53,7 +53,7 @@ static void enable_board_wakeup_source(void) | |||
53 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); | 53 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); |
54 | } | 54 | } |
55 | 55 | ||
56 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 56 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
57 | 57 | ||
58 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 58 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
59 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 59 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 07f0be24a5d1..52cc2c597314 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c | |||
@@ -40,7 +40,7 @@ static struct omap_board_mux board_mux[] __initdata = { | |||
40 | }; | 40 | }; |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | static struct usbhs_omap_board_data usbhs_bdata __initdata = { | 43 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
44 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 44 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
45 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | 45 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, |
46 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 46 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 6f5b2a05f4b2..9fb85908a61e 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c | |||
@@ -274,7 +274,7 @@ static __init void am3517_evm_mcbsp1_init(void) | |||
274 | omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); | 274 | omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); |
275 | } | 275 | } |
276 | 276 | ||
277 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 277 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
278 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 278 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
279 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ | 279 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ |
280 | defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE) | 280 | defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE) |
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 231a7d825f99..10054e3c3482 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c | |||
@@ -419,7 +419,7 @@ static struct omap2_hsmmc_info mmc[] = { | |||
419 | {} /* Terminator */ | 419 | {} /* Terminator */ |
420 | }; | 420 | }; |
421 | 421 | ||
422 | static struct usbhs_omap_board_data usbhs_bdata __initdata = { | 422 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
423 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 423 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
424 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 424 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
425 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 425 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index 6a9529ab95cd..5e54f565a294 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c | |||
@@ -166,7 +166,7 @@ static inline void cm_t3517_init_rtc(void) {} | |||
166 | #define HSUSB2_RESET_GPIO (147) | 166 | #define HSUSB2_RESET_GPIO (147) |
167 | #define USB_HUB_RESET_GPIO (152) | 167 | #define USB_HUB_RESET_GPIO (152) |
168 | 168 | ||
169 | static struct usbhs_omap_board_data cm_t3517_ehci_pdata __initdata = { | 169 | static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = { |
170 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 170 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
171 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 171 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
172 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 172 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index a37514ecc385..4dadb0b7b808 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c | |||
@@ -436,7 +436,7 @@ static struct platform_device *devkit8000_devices[] __initdata = { | |||
436 | &omap_dm9000_dev, | 436 | &omap_dm9000_dev, |
437 | }; | 437 | }; |
438 | 438 | ||
439 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 439 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
440 | 440 | ||
441 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 441 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
442 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | 442 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 3f97f30d788e..c10738a067cd 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
@@ -527,7 +527,7 @@ static void __init igep_i2c_init(void) | |||
527 | omap3_pmic_init("twl4030", &igep_twldata); | 527 | omap3_pmic_init("twl4030", &igep_twldata); |
528 | } | 528 | } |
529 | 529 | ||
530 | static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = { | 530 | static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = { |
531 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 531 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
532 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | 532 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, |
533 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 533 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
@@ -538,7 +538,7 @@ static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = { | |||
538 | .reset_gpio_port[2] = -EINVAL, | 538 | .reset_gpio_port[2] = -EINVAL, |
539 | }; | 539 | }; |
540 | 540 | ||
541 | static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = { | 541 | static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = { |
542 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 542 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, |
543 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 543 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
544 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 544 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 284500ddacdb..70bc1fc808c8 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -431,7 +431,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = { | |||
431 | &madc_hwmon, | 431 | &madc_hwmon, |
432 | }; | 432 | }; |
433 | 433 | ||
434 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 434 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
435 | 435 | ||
436 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 436 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, |
437 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 437 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index f43763647d58..8258a78c3dfb 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -539,7 +539,7 @@ static int __init omap3_evm_i2c_init(void) | |||
539 | return 0; | 539 | return 0; |
540 | } | 540 | } |
541 | 541 | ||
542 | static struct usbhs_omap_board_data usbhs_bdata __initdata = { | 542 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
543 | 543 | ||
544 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 544 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, |
545 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 545 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 07cc0884e761..2bba362148a0 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -568,7 +568,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = { | |||
568 | &pandora_backlight, | 568 | &pandora_backlight, |
569 | }; | 569 | }; |
570 | 570 | ||
571 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 571 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
572 | 572 | ||
573 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 573 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, |
574 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 574 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 0490acbc4331..95c10b3aa678 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c | |||
@@ -362,7 +362,7 @@ static struct platform_device *omap3_stalker_devices[] __initdata = { | |||
362 | &keys_gpio, | 362 | &keys_gpio, |
363 | }; | 363 | }; |
364 | 364 | ||
365 | static struct usbhs_omap_board_data usbhs_bdata __initconst = { | 365 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
366 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 366 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, |
367 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 367 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
368 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 368 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index 91daf71190cf..bcd44fbcd877 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c | |||
@@ -310,7 +310,7 @@ static struct platform_device *omap3_touchbook_devices[] __initdata = { | |||
310 | &keys_gpio, | 310 | &keys_gpio, |
311 | }; | 311 | }; |
312 | 312 | ||
313 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 313 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
314 | 314 | ||
315 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 315 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
316 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 316 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 7b152d04a602..b02c2f00609b 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c | |||
@@ -140,7 +140,7 @@ static struct platform_device *panda_devices[] __initdata = { | |||
140 | &btwilink_device, | 140 | &btwilink_device, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 143 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
144 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 144 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
145 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | 145 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, |
146 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 146 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 6975a8585dae..1bcf39671c35 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
@@ -458,7 +458,7 @@ static int __init overo_spi_init(void) | |||
458 | return 0; | 458 | return 0; |
459 | } | 459 | } |
460 | 460 | ||
461 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 461 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
462 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 462 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, |
463 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 463 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
464 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 464 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index d257cf1e0abe..5e4d4c9fe61a 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c | |||
@@ -92,7 +92,7 @@ static struct mtd_partition zoom_nand_partitions[] = { | |||
92 | }, | 92 | }, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | 95 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
96 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 96 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, |
97 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 97 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
98 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | 98 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, |
diff --git a/arch/arm/mach-omap2/cclock2420_data.c b/arch/arm/mach-omap2/cclock2420_data.c index ab7e952d2070..0f0a97c1fcc0 100644 --- a/arch/arm/mach-omap2/cclock2420_data.c +++ b/arch/arm/mach-omap2/cclock2420_data.c | |||
@@ -622,15 +622,10 @@ static struct clk_hw_omap gpios_fck_hw = { | |||
622 | 622 | ||
623 | DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops); | 623 | DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops); |
624 | 624 | ||
625 | static struct clk wu_l4_ick; | ||
626 | |||
627 | DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm"); | ||
628 | DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops); | ||
629 | |||
630 | static struct clk gpios_ick; | 625 | static struct clk gpios_ick; |
631 | 626 | ||
632 | static const char *gpios_ick_parent_names[] = { | 627 | static const char *gpios_ick_parent_names[] = { |
633 | "wu_l4_ick", | 628 | "sys_ck", |
634 | }; | 629 | }; |
635 | 630 | ||
636 | static struct clk_hw_omap gpios_ick_hw = { | 631 | static struct clk_hw_omap gpios_ick_hw = { |
@@ -1682,13 +1677,6 @@ static struct clk_hw_omap wdt1_ick_hw = { | |||
1682 | 1677 | ||
1683 | DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); | 1678 | DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); |
1684 | 1679 | ||
1685 | static struct clk wdt1_osc_ck; | ||
1686 | |||
1687 | static const struct clk_ops wdt1_osc_ck_ops = {}; | ||
1688 | |||
1689 | DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL); | ||
1690 | DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops); | ||
1691 | |||
1692 | static struct clk wdt3_fck; | 1680 | static struct clk wdt3_fck; |
1693 | 1681 | ||
1694 | static struct clk_hw_omap wdt3_fck_hw = { | 1682 | static struct clk_hw_omap wdt3_fck_hw = { |
@@ -1767,7 +1755,6 @@ static struct omap_clk omap2420_clks[] = { | |||
1767 | CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X), | 1755 | CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X), |
1768 | CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X), | 1756 | CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X), |
1769 | CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X), | 1757 | CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X), |
1770 | CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_242X), | ||
1771 | CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_242X), | 1758 | CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_242X), |
1772 | CLK(NULL, "sys_clkout", &sys_clkout, CK_242X), | 1759 | CLK(NULL, "sys_clkout", &sys_clkout, CK_242X), |
1773 | CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X), | 1760 | CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X), |
@@ -1797,7 +1784,6 @@ static struct omap_clk omap2420_clks[] = { | |||
1797 | /* L4 domain clocks */ | 1784 | /* L4 domain clocks */ |
1798 | CLK(NULL, "l4_ck", &l4_ck, CK_242X), | 1785 | CLK(NULL, "l4_ck", &l4_ck, CK_242X), |
1799 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X), | 1786 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X), |
1800 | CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_242X), | ||
1801 | /* virtual meta-group clock */ | 1787 | /* virtual meta-group clock */ |
1802 | CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X), | 1788 | CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X), |
1803 | /* general l4 interface ck, multi-parent functional clk */ | 1789 | /* general l4 interface ck, multi-parent functional clk */ |
diff --git a/arch/arm/mach-omap2/cclock2430_data.c b/arch/arm/mach-omap2/cclock2430_data.c index eb3dab68d536..aed8f74ca076 100644 --- a/arch/arm/mach-omap2/cclock2430_data.c +++ b/arch/arm/mach-omap2/cclock2430_data.c | |||
@@ -601,15 +601,10 @@ static struct clk_hw_omap gpios_fck_hw = { | |||
601 | 601 | ||
602 | DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops); | 602 | DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops); |
603 | 603 | ||
604 | static struct clk wu_l4_ick; | ||
605 | |||
606 | DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm"); | ||
607 | DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops); | ||
608 | |||
609 | static struct clk gpios_ick; | 604 | static struct clk gpios_ick; |
610 | 605 | ||
611 | static const char *gpios_ick_parent_names[] = { | 606 | static const char *gpios_ick_parent_names[] = { |
612 | "wu_l4_ick", | 607 | "sys_ck", |
613 | }; | 608 | }; |
614 | 609 | ||
615 | static struct clk_hw_omap gpios_ick_hw = { | 610 | static struct clk_hw_omap gpios_ick_hw = { |
@@ -1811,13 +1806,6 @@ static struct clk_hw_omap wdt1_ick_hw = { | |||
1811 | 1806 | ||
1812 | DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); | 1807 | DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); |
1813 | 1808 | ||
1814 | static struct clk wdt1_osc_ck; | ||
1815 | |||
1816 | static const struct clk_ops wdt1_osc_ck_ops = {}; | ||
1817 | |||
1818 | DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL); | ||
1819 | DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops); | ||
1820 | |||
1821 | static struct clk wdt4_fck; | 1809 | static struct clk wdt4_fck; |
1822 | 1810 | ||
1823 | static struct clk_hw_omap wdt4_fck_hw = { | 1811 | static struct clk_hw_omap wdt4_fck_hw = { |
@@ -1869,7 +1857,6 @@ static struct omap_clk omap2430_clks[] = { | |||
1869 | CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X), | 1857 | CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X), |
1870 | CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X), | 1858 | CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X), |
1871 | CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X), | 1859 | CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X), |
1872 | CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_243X), | ||
1873 | CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X), | 1860 | CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X), |
1874 | CLK(NULL, "sys_clkout", &sys_clkout, CK_243X), | 1861 | CLK(NULL, "sys_clkout", &sys_clkout, CK_243X), |
1875 | CLK(NULL, "emul_ck", &emul_ck, CK_243X), | 1862 | CLK(NULL, "emul_ck", &emul_ck, CK_243X), |
@@ -1898,7 +1885,6 @@ static struct omap_clk omap2430_clks[] = { | |||
1898 | /* L4 domain clocks */ | 1885 | /* L4 domain clocks */ |
1899 | CLK(NULL, "l4_ck", &l4_ck, CK_243X), | 1886 | CLK(NULL, "l4_ck", &l4_ck, CK_243X), |
1900 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X), | 1887 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X), |
1901 | CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_243X), | ||
1902 | /* virtual meta-group clock */ | 1888 | /* virtual meta-group clock */ |
1903 | CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X), | 1889 | CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X), |
1904 | /* general l4 interface ck, multi-parent functional clk */ | 1890 | /* general l4 interface ck, multi-parent functional clk */ |
diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c index a2cc046b47f4..cebe2b31943e 100644 --- a/arch/arm/mach-omap2/cclock44xx_data.c +++ b/arch/arm/mach-omap2/cclock44xx_data.c | |||
@@ -16,6 +16,10 @@ | |||
16 | * XXX Some of the ES1 clocks have been removed/changed; once support | 16 | * XXX Some of the ES1 clocks have been removed/changed; once support |
17 | * is added for discriminating clocks by ES level, these should be added back | 17 | * is added for discriminating clocks by ES level, these should be added back |
18 | * in. | 18 | * in. |
19 | * | ||
20 | * XXX All of the remaining MODULEMODE clock nodes should be removed | ||
21 | * once the drivers are updated to use pm_runtime or to use the appropriate | ||
22 | * upstream clock node for rate/parent selection. | ||
19 | */ | 23 | */ |
20 | 24 | ||
21 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
@@ -315,7 +319,7 @@ DEFINE_CLK_DIVIDER(dpll_abe_m2_ck, "dpll_abe_ck", &dpll_abe_ck, 0x0, | |||
315 | OMAP4430_CM_DIV_M2_DPLL_ABE, OMAP4430_DPLL_CLKOUT_DIV_SHIFT, | 319 | OMAP4430_CM_DIV_M2_DPLL_ABE, OMAP4430_DPLL_CLKOUT_DIV_SHIFT, |
316 | OMAP4430_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); | 320 | OMAP4430_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); |
317 | 321 | ||
318 | static const struct clk_ops dmic_fck_ops = { | 322 | static const struct clk_ops dpll_hsd_ops = { |
319 | .enable = &omap2_dflt_clk_enable, | 323 | .enable = &omap2_dflt_clk_enable, |
320 | .disable = &omap2_dflt_clk_disable, | 324 | .disable = &omap2_dflt_clk_disable, |
321 | .is_enabled = &omap2_dflt_clk_is_enabled, | 325 | .is_enabled = &omap2_dflt_clk_is_enabled, |
@@ -325,6 +329,12 @@ static const struct clk_ops dmic_fck_ops = { | |||
325 | .init = &omap2_init_clk_clkdm, | 329 | .init = &omap2_init_clk_clkdm, |
326 | }; | 330 | }; |
327 | 331 | ||
332 | static const struct clk_ops func_dmic_abe_gfclk_ops = { | ||
333 | .recalc_rate = &omap2_clksel_recalc, | ||
334 | .get_parent = &omap2_clksel_find_parent_index, | ||
335 | .set_parent = &omap2_clksel_set_parent, | ||
336 | }; | ||
337 | |||
328 | static const char *dpll_core_m3x2_ck_parents[] = { | 338 | static const char *dpll_core_m3x2_ck_parents[] = { |
329 | "dpll_core_x2_ck", | 339 | "dpll_core_x2_ck", |
330 | }; | 340 | }; |
@@ -340,7 +350,7 @@ DEFINE_CLK_OMAP_MUX_GATE(dpll_core_m3x2_ck, NULL, dpll_core_m3x2_div, | |||
340 | OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, | 350 | OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, |
341 | OMAP4430_CM_DIV_M3_DPLL_CORE, | 351 | OMAP4430_CM_DIV_M3_DPLL_CORE, |
342 | OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, | 352 | OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, |
343 | dpll_core_m3x2_ck_parents, dmic_fck_ops); | 353 | dpll_core_m3x2_ck_parents, dpll_hsd_ops); |
344 | 354 | ||
345 | DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m7x2_ck, "dpll_core_x2_ck", | 355 | DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m7x2_ck, "dpll_core_x2_ck", |
346 | &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M7_DPLL_CORE, | 356 | &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M7_DPLL_CORE, |
@@ -547,7 +557,7 @@ DEFINE_CLK_OMAP_MUX_GATE(dpll_per_m3x2_ck, NULL, dpll_per_m3x2_div, | |||
547 | OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, | 557 | OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, |
548 | OMAP4430_CM_DIV_M3_DPLL_PER, | 558 | OMAP4430_CM_DIV_M3_DPLL_PER, |
549 | OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, | 559 | OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, |
550 | dpll_per_m3x2_ck_parents, dmic_fck_ops); | 560 | dpll_per_m3x2_ck_parents, dpll_hsd_ops); |
551 | 561 | ||
552 | DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m4x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck, | 562 | DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m4x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck, |
553 | 0x0, OMAP4430_CM_DIV_M4_DPLL_PER, | 563 | 0x0, OMAP4430_CM_DIV_M4_DPLL_PER, |
@@ -749,10 +759,6 @@ DEFINE_CLK_GATE(aes2_fck, "l3_div_ck", &l3_div_ck, 0x0, | |||
749 | OMAP4430_CM_L4SEC_AES2_CLKCTRL, | 759 | OMAP4430_CM_L4SEC_AES2_CLKCTRL, |
750 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | 760 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); |
751 | 761 | ||
752 | DEFINE_CLK_GATE(aess_fck, "aess_fclk", &aess_fclk, 0x0, | ||
753 | OMAP4430_CM1_ABE_AESS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, | ||
754 | 0x0, NULL); | ||
755 | |||
756 | DEFINE_CLK_GATE(bandgap_fclk, "sys_32k_ck", &sys_32k_ck, 0x0, | 762 | DEFINE_CLK_GATE(bandgap_fclk, "sys_32k_ck", &sys_32k_ck, 0x0, |
757 | OMAP4430_CM_WKUP_BANDGAP_CLKCTRL, | 763 | OMAP4430_CM_WKUP_BANDGAP_CLKCTRL, |
758 | OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT, 0x0, NULL); | 764 | OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT, 0x0, NULL); |
@@ -774,11 +780,6 @@ DEFINE_CLK_GATE(bandgap_ts_fclk, "div_ts_ck", &div_ts_ck, 0x0, | |||
774 | OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT, | 780 | OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT, |
775 | 0x0, NULL); | 781 | 0x0, NULL); |
776 | 782 | ||
777 | DEFINE_CLK_GATE(des3des_fck, "l4_div_ck", &l4_div_ck, 0x0, | ||
778 | OMAP4430_CM_L4SEC_DES3DES_CLKCTRL, | ||
779 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, | ||
780 | 0x0, NULL); | ||
781 | |||
782 | static const char *dmic_sync_mux_ck_parents[] = { | 783 | static const char *dmic_sync_mux_ck_parents[] = { |
783 | "abe_24m_fclk", "syc_clk_div_ck", "func_24m_clk", | 784 | "abe_24m_fclk", "syc_clk_div_ck", "func_24m_clk", |
784 | }; | 785 | }; |
@@ -795,23 +796,13 @@ static const struct clksel func_dmic_abe_gfclk_sel[] = { | |||
795 | { .parent = NULL }, | 796 | { .parent = NULL }, |
796 | }; | 797 | }; |
797 | 798 | ||
798 | static const char *dmic_fck_parents[] = { | 799 | static const char *func_dmic_abe_gfclk_parents[] = { |
799 | "dmic_sync_mux_ck", "pad_clks_ck", "slimbus_clk", | 800 | "dmic_sync_mux_ck", "pad_clks_ck", "slimbus_clk", |
800 | }; | 801 | }; |
801 | 802 | ||
802 | /* Merged func_dmic_abe_gfclk into dmic */ | 803 | DEFINE_CLK_OMAP_MUX(func_dmic_abe_gfclk, "abe_clkdm", func_dmic_abe_gfclk_sel, |
803 | static struct clk dmic_fck; | 804 | OMAP4430_CM1_ABE_DMIC_CLKCTRL, OMAP4430_CLKSEL_SOURCE_MASK, |
804 | 805 | func_dmic_abe_gfclk_parents, func_dmic_abe_gfclk_ops); | |
805 | DEFINE_CLK_OMAP_MUX_GATE(dmic_fck, "abe_clkdm", func_dmic_abe_gfclk_sel, | ||
806 | OMAP4430_CM1_ABE_DMIC_CLKCTRL, | ||
807 | OMAP4430_CLKSEL_SOURCE_MASK, | ||
808 | OMAP4430_CM1_ABE_DMIC_CLKCTRL, | ||
809 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
810 | dmic_fck_parents, dmic_fck_ops); | ||
811 | |||
812 | DEFINE_CLK_GATE(dsp_fck, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, 0x0, | ||
813 | OMAP4430_CM_TESLA_TESLA_CLKCTRL, | ||
814 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
815 | 806 | ||
816 | DEFINE_CLK_GATE(dss_sys_clk, "syc_clk_div_ck", &syc_clk_div_ck, 0x0, | 807 | DEFINE_CLK_GATE(dss_sys_clk, "syc_clk_div_ck", &syc_clk_div_ck, 0x0, |
817 | OMAP4430_CM_DSS_DSS_CLKCTRL, | 808 | OMAP4430_CM_DSS_DSS_CLKCTRL, |
@@ -833,177 +824,57 @@ DEFINE_CLK_GATE(dss_fck, "l3_div_ck", &l3_div_ck, 0x0, | |||
833 | OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, | 824 | OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, |
834 | 0x0, NULL); | 825 | 0x0, NULL); |
835 | 826 | ||
836 | DEFINE_CLK_GATE(efuse_ctrl_cust_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0, | ||
837 | OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL, | ||
838 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
839 | |||
840 | DEFINE_CLK_GATE(emif1_fck, "ddrphy_ck", &ddrphy_ck, 0x0, | ||
841 | OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL, | ||
842 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
843 | |||
844 | DEFINE_CLK_GATE(emif2_fck, "ddrphy_ck", &ddrphy_ck, 0x0, | ||
845 | OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL, | ||
846 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
847 | |||
848 | DEFINE_CLK_DIVIDER(fdif_fck, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, 0x0, | 827 | DEFINE_CLK_DIVIDER(fdif_fck, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, 0x0, |
849 | OMAP4430_CM_CAM_FDIF_CLKCTRL, OMAP4430_CLKSEL_FCLK_SHIFT, | 828 | OMAP4430_CM_CAM_FDIF_CLKCTRL, OMAP4430_CLKSEL_FCLK_SHIFT, |
850 | OMAP4430_CLKSEL_FCLK_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); | 829 | OMAP4430_CLKSEL_FCLK_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); |
851 | 830 | ||
852 | DEFINE_CLK_GATE(fpka_fck, "l4_div_ck", &l4_div_ck, 0x0, | ||
853 | OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL, | ||
854 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
855 | |||
856 | DEFINE_CLK_GATE(gpio1_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, | 831 | DEFINE_CLK_GATE(gpio1_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, |
857 | OMAP4430_CM_WKUP_GPIO1_CLKCTRL, | 832 | OMAP4430_CM_WKUP_GPIO1_CLKCTRL, |
858 | OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL); | 833 | OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL); |
859 | 834 | ||
860 | DEFINE_CLK_GATE(gpio1_ick, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, 0x0, | ||
861 | OMAP4430_CM_WKUP_GPIO1_CLKCTRL, | ||
862 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
863 | |||
864 | DEFINE_CLK_GATE(gpio2_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, | 835 | DEFINE_CLK_GATE(gpio2_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, |
865 | OMAP4430_CM_L4PER_GPIO2_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, | 836 | OMAP4430_CM_L4PER_GPIO2_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, |
866 | 0x0, NULL); | 837 | 0x0, NULL); |
867 | 838 | ||
868 | DEFINE_CLK_GATE(gpio2_ick, "l4_div_ck", &l4_div_ck, 0x0, | ||
869 | OMAP4430_CM_L4PER_GPIO2_CLKCTRL, | ||
870 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
871 | |||
872 | DEFINE_CLK_GATE(gpio3_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, | 839 | DEFINE_CLK_GATE(gpio3_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, |
873 | OMAP4430_CM_L4PER_GPIO3_CLKCTRL, | 840 | OMAP4430_CM_L4PER_GPIO3_CLKCTRL, |
874 | OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL); | 841 | OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL); |
875 | 842 | ||
876 | DEFINE_CLK_GATE(gpio3_ick, "l4_div_ck", &l4_div_ck, 0x0, | ||
877 | OMAP4430_CM_L4PER_GPIO3_CLKCTRL, | ||
878 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
879 | |||
880 | DEFINE_CLK_GATE(gpio4_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, | 843 | DEFINE_CLK_GATE(gpio4_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, |
881 | OMAP4430_CM_L4PER_GPIO4_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, | 844 | OMAP4430_CM_L4PER_GPIO4_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, |
882 | 0x0, NULL); | 845 | 0x0, NULL); |
883 | 846 | ||
884 | DEFINE_CLK_GATE(gpio4_ick, "l4_div_ck", &l4_div_ck, 0x0, | ||
885 | OMAP4430_CM_L4PER_GPIO4_CLKCTRL, | ||
886 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
887 | |||
888 | DEFINE_CLK_GATE(gpio5_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, | 847 | DEFINE_CLK_GATE(gpio5_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, |
889 | OMAP4430_CM_L4PER_GPIO5_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, | 848 | OMAP4430_CM_L4PER_GPIO5_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, |
890 | 0x0, NULL); | 849 | 0x0, NULL); |
891 | 850 | ||
892 | DEFINE_CLK_GATE(gpio5_ick, "l4_div_ck", &l4_div_ck, 0x0, | ||
893 | OMAP4430_CM_L4PER_GPIO5_CLKCTRL, | ||
894 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
895 | |||
896 | DEFINE_CLK_GATE(gpio6_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, | 851 | DEFINE_CLK_GATE(gpio6_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0, |
897 | OMAP4430_CM_L4PER_GPIO6_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, | 852 | OMAP4430_CM_L4PER_GPIO6_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT, |
898 | 0x0, NULL); | 853 | 0x0, NULL); |
899 | 854 | ||
900 | DEFINE_CLK_GATE(gpio6_ick, "l4_div_ck", &l4_div_ck, 0x0, | ||
901 | OMAP4430_CM_L4PER_GPIO6_CLKCTRL, | ||
902 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
903 | |||
904 | DEFINE_CLK_GATE(gpmc_ick, "l3_div_ck", &l3_div_ck, 0x0, | ||
905 | OMAP4430_CM_L3_2_GPMC_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, | ||
906 | 0x0, NULL); | ||
907 | |||
908 | static const struct clksel sgx_clk_mux_sel[] = { | 855 | static const struct clksel sgx_clk_mux_sel[] = { |
909 | { .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates }, | 856 | { .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates }, |
910 | { .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates }, | 857 | { .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates }, |
911 | { .parent = NULL }, | 858 | { .parent = NULL }, |
912 | }; | 859 | }; |
913 | 860 | ||
914 | static const char *gpu_fck_parents[] = { | 861 | static const char *sgx_clk_mux_parents[] = { |
915 | "dpll_core_m7x2_ck", "dpll_per_m7x2_ck", | 862 | "dpll_core_m7x2_ck", "dpll_per_m7x2_ck", |
916 | }; | 863 | }; |
917 | 864 | ||
918 | /* Merged sgx_clk_mux into gpu */ | 865 | DEFINE_CLK_OMAP_MUX(sgx_clk_mux, "l3_gfx_clkdm", sgx_clk_mux_sel, |
919 | DEFINE_CLK_OMAP_MUX_GATE(gpu_fck, "l3_gfx_clkdm", sgx_clk_mux_sel, | 866 | OMAP4430_CM_GFX_GFX_CLKCTRL, OMAP4430_CLKSEL_SGX_FCLK_MASK, |
920 | OMAP4430_CM_GFX_GFX_CLKCTRL, | 867 | sgx_clk_mux_parents, func_dmic_abe_gfclk_ops); |
921 | OMAP4430_CLKSEL_SGX_FCLK_MASK, | ||
922 | OMAP4430_CM_GFX_GFX_CLKCTRL, | ||
923 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
924 | gpu_fck_parents, dmic_fck_ops); | ||
925 | |||
926 | DEFINE_CLK_GATE(hdq1w_fck, "func_12m_fclk", &func_12m_fclk, 0x0, | ||
927 | OMAP4430_CM_L4PER_HDQ1W_CLKCTRL, | ||
928 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
929 | 868 | ||
930 | DEFINE_CLK_DIVIDER(hsi_fck, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, 0x0, | 869 | DEFINE_CLK_DIVIDER(hsi_fck, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, 0x0, |
931 | OMAP4430_CM_L3INIT_HSI_CLKCTRL, OMAP4430_CLKSEL_24_25_SHIFT, | 870 | OMAP4430_CM_L3INIT_HSI_CLKCTRL, OMAP4430_CLKSEL_24_25_SHIFT, |
932 | OMAP4430_CLKSEL_24_25_WIDTH, CLK_DIVIDER_POWER_OF_TWO, | 871 | OMAP4430_CLKSEL_24_25_WIDTH, CLK_DIVIDER_POWER_OF_TWO, |
933 | NULL); | 872 | NULL); |
934 | 873 | ||
935 | DEFINE_CLK_GATE(i2c1_fck, "func_96m_fclk", &func_96m_fclk, 0x0, | ||
936 | OMAP4430_CM_L4PER_I2C1_CLKCTRL, | ||
937 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
938 | |||
939 | DEFINE_CLK_GATE(i2c2_fck, "func_96m_fclk", &func_96m_fclk, 0x0, | ||
940 | OMAP4430_CM_L4PER_I2C2_CLKCTRL, | ||
941 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
942 | |||
943 | DEFINE_CLK_GATE(i2c3_fck, "func_96m_fclk", &func_96m_fclk, 0x0, | ||
944 | OMAP4430_CM_L4PER_I2C3_CLKCTRL, | ||
945 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
946 | |||
947 | DEFINE_CLK_GATE(i2c4_fck, "func_96m_fclk", &func_96m_fclk, 0x0, | ||
948 | OMAP4430_CM_L4PER_I2C4_CLKCTRL, | ||
949 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
950 | |||
951 | DEFINE_CLK_GATE(ipu_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0, | ||
952 | OMAP4430_CM_DUCATI_DUCATI_CLKCTRL, | ||
953 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
954 | |||
955 | DEFINE_CLK_GATE(iss_ctrlclk, "func_96m_fclk", &func_96m_fclk, 0x0, | 874 | DEFINE_CLK_GATE(iss_ctrlclk, "func_96m_fclk", &func_96m_fclk, 0x0, |
956 | OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT, | 875 | OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT, |
957 | 0x0, NULL); | 876 | 0x0, NULL); |
958 | 877 | ||
959 | DEFINE_CLK_GATE(iss_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0, | ||
960 | OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, | ||
961 | 0x0, NULL); | ||
962 | |||
963 | DEFINE_CLK_GATE(iva_fck, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0, | ||
964 | OMAP4430_CM_IVAHD_IVAHD_CLKCTRL, | ||
965 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
966 | |||
967 | DEFINE_CLK_GATE(kbd_fck, "sys_32k_ck", &sys_32k_ck, 0x0, | ||
968 | OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL, | ||
969 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
970 | |||
971 | static struct clk l3_instr_ick; | ||
972 | |||
973 | static const char *l3_instr_ick_parent_names[] = { | ||
974 | "l3_div_ck", | ||
975 | }; | ||
976 | |||
977 | static const struct clk_ops l3_instr_ick_ops = { | ||
978 | .enable = &omap2_dflt_clk_enable, | ||
979 | .disable = &omap2_dflt_clk_disable, | ||
980 | .is_enabled = &omap2_dflt_clk_is_enabled, | ||
981 | .init = &omap2_init_clk_clkdm, | ||
982 | }; | ||
983 | |||
984 | static struct clk_hw_omap l3_instr_ick_hw = { | ||
985 | .hw = { | ||
986 | .clk = &l3_instr_ick, | ||
987 | }, | ||
988 | .enable_reg = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL, | ||
989 | .enable_bit = OMAP4430_MODULEMODE_HWCTRL_SHIFT, | ||
990 | .clkdm_name = "l3_instr_clkdm", | ||
991 | }; | ||
992 | |||
993 | DEFINE_STRUCT_CLK(l3_instr_ick, l3_instr_ick_parent_names, l3_instr_ick_ops); | ||
994 | |||
995 | static struct clk l3_main_3_ick; | ||
996 | static struct clk_hw_omap l3_main_3_ick_hw = { | ||
997 | .hw = { | ||
998 | .clk = &l3_main_3_ick, | ||
999 | }, | ||
1000 | .enable_reg = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL, | ||
1001 | .enable_bit = OMAP4430_MODULEMODE_HWCTRL_SHIFT, | ||
1002 | .clkdm_name = "l3_instr_clkdm", | ||
1003 | }; | ||
1004 | |||
1005 | DEFINE_STRUCT_CLK(l3_main_3_ick, l3_instr_ick_parent_names, l3_instr_ick_ops); | ||
1006 | |||
1007 | DEFINE_CLK_MUX(mcasp_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, | 878 | DEFINE_CLK_MUX(mcasp_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, |
1008 | OMAP4430_CM1_ABE_MCASP_CLKCTRL, | 879 | OMAP4430_CM1_ABE_MCASP_CLKCTRL, |
1009 | OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT, | 880 | OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT, |
@@ -1016,17 +887,13 @@ static const struct clksel func_mcasp_abe_gfclk_sel[] = { | |||
1016 | { .parent = NULL }, | 887 | { .parent = NULL }, |
1017 | }; | 888 | }; |
1018 | 889 | ||
1019 | static const char *mcasp_fck_parents[] = { | 890 | static const char *func_mcasp_abe_gfclk_parents[] = { |
1020 | "mcasp_sync_mux_ck", "pad_clks_ck", "slimbus_clk", | 891 | "mcasp_sync_mux_ck", "pad_clks_ck", "slimbus_clk", |
1021 | }; | 892 | }; |
1022 | 893 | ||
1023 | /* Merged func_mcasp_abe_gfclk into mcasp */ | 894 | DEFINE_CLK_OMAP_MUX(func_mcasp_abe_gfclk, "abe_clkdm", func_mcasp_abe_gfclk_sel, |
1024 | DEFINE_CLK_OMAP_MUX_GATE(mcasp_fck, "abe_clkdm", func_mcasp_abe_gfclk_sel, | 895 | OMAP4430_CM1_ABE_MCASP_CLKCTRL, OMAP4430_CLKSEL_SOURCE_MASK, |
1025 | OMAP4430_CM1_ABE_MCASP_CLKCTRL, | 896 | func_mcasp_abe_gfclk_parents, func_dmic_abe_gfclk_ops); |
1026 | OMAP4430_CLKSEL_SOURCE_MASK, | ||
1027 | OMAP4430_CM1_ABE_MCASP_CLKCTRL, | ||
1028 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1029 | mcasp_fck_parents, dmic_fck_ops); | ||
1030 | 897 | ||
1031 | DEFINE_CLK_MUX(mcbsp1_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, | 898 | DEFINE_CLK_MUX(mcbsp1_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, |
1032 | OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, | 899 | OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, |
@@ -1040,17 +907,14 @@ static const struct clksel func_mcbsp1_gfclk_sel[] = { | |||
1040 | { .parent = NULL }, | 907 | { .parent = NULL }, |
1041 | }; | 908 | }; |
1042 | 909 | ||
1043 | static const char *mcbsp1_fck_parents[] = { | 910 | static const char *func_mcbsp1_gfclk_parents[] = { |
1044 | "mcbsp1_sync_mux_ck", "pad_clks_ck", "slimbus_clk", | 911 | "mcbsp1_sync_mux_ck", "pad_clks_ck", "slimbus_clk", |
1045 | }; | 912 | }; |
1046 | 913 | ||
1047 | /* Merged func_mcbsp1_gfclk into mcbsp1 */ | 914 | DEFINE_CLK_OMAP_MUX(func_mcbsp1_gfclk, "abe_clkdm", func_mcbsp1_gfclk_sel, |
1048 | DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "abe_clkdm", func_mcbsp1_gfclk_sel, | 915 | OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, |
1049 | OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, | 916 | OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp1_gfclk_parents, |
1050 | OMAP4430_CLKSEL_SOURCE_MASK, | 917 | func_dmic_abe_gfclk_ops); |
1051 | OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, | ||
1052 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1053 | mcbsp1_fck_parents, dmic_fck_ops); | ||
1054 | 918 | ||
1055 | DEFINE_CLK_MUX(mcbsp2_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, | 919 | DEFINE_CLK_MUX(mcbsp2_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, |
1056 | OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, | 920 | OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, |
@@ -1064,17 +928,14 @@ static const struct clksel func_mcbsp2_gfclk_sel[] = { | |||
1064 | { .parent = NULL }, | 928 | { .parent = NULL }, |
1065 | }; | 929 | }; |
1066 | 930 | ||
1067 | static const char *mcbsp2_fck_parents[] = { | 931 | static const char *func_mcbsp2_gfclk_parents[] = { |
1068 | "mcbsp2_sync_mux_ck", "pad_clks_ck", "slimbus_clk", | 932 | "mcbsp2_sync_mux_ck", "pad_clks_ck", "slimbus_clk", |
1069 | }; | 933 | }; |
1070 | 934 | ||
1071 | /* Merged func_mcbsp2_gfclk into mcbsp2 */ | 935 | DEFINE_CLK_OMAP_MUX(func_mcbsp2_gfclk, "abe_clkdm", func_mcbsp2_gfclk_sel, |
1072 | DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "abe_clkdm", func_mcbsp2_gfclk_sel, | 936 | OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, |
1073 | OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, | 937 | OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp2_gfclk_parents, |
1074 | OMAP4430_CLKSEL_SOURCE_MASK, | 938 | func_dmic_abe_gfclk_ops); |
1075 | OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, | ||
1076 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1077 | mcbsp2_fck_parents, dmic_fck_ops); | ||
1078 | 939 | ||
1079 | DEFINE_CLK_MUX(mcbsp3_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, | 940 | DEFINE_CLK_MUX(mcbsp3_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0, |
1080 | OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, | 941 | OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, |
@@ -1088,17 +949,14 @@ static const struct clksel func_mcbsp3_gfclk_sel[] = { | |||
1088 | { .parent = NULL }, | 949 | { .parent = NULL }, |
1089 | }; | 950 | }; |
1090 | 951 | ||
1091 | static const char *mcbsp3_fck_parents[] = { | 952 | static const char *func_mcbsp3_gfclk_parents[] = { |
1092 | "mcbsp3_sync_mux_ck", "pad_clks_ck", "slimbus_clk", | 953 | "mcbsp3_sync_mux_ck", "pad_clks_ck", "slimbus_clk", |
1093 | }; | 954 | }; |
1094 | 955 | ||
1095 | /* Merged func_mcbsp3_gfclk into mcbsp3 */ | 956 | DEFINE_CLK_OMAP_MUX(func_mcbsp3_gfclk, "abe_clkdm", func_mcbsp3_gfclk_sel, |
1096 | DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "abe_clkdm", func_mcbsp3_gfclk_sel, | 957 | OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, |
1097 | OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, | 958 | OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp3_gfclk_parents, |
1098 | OMAP4430_CLKSEL_SOURCE_MASK, | 959 | func_dmic_abe_gfclk_ops); |
1099 | OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, | ||
1100 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1101 | mcbsp3_fck_parents, dmic_fck_ops); | ||
1102 | 960 | ||
1103 | static const char *mcbsp4_sync_mux_ck_parents[] = { | 961 | static const char *mcbsp4_sync_mux_ck_parents[] = { |
1104 | "func_96m_fclk", "per_abe_nc_fclk", | 962 | "func_96m_fclk", "per_abe_nc_fclk", |
@@ -1115,37 +973,14 @@ static const struct clksel per_mcbsp4_gfclk_sel[] = { | |||
1115 | { .parent = NULL }, | 973 | { .parent = NULL }, |
1116 | }; | 974 | }; |
1117 | 975 | ||
1118 | static const char *mcbsp4_fck_parents[] = { | 976 | static const char *per_mcbsp4_gfclk_parents[] = { |
1119 | "mcbsp4_sync_mux_ck", "pad_clks_ck", | 977 | "mcbsp4_sync_mux_ck", "pad_clks_ck", |
1120 | }; | 978 | }; |
1121 | 979 | ||
1122 | /* Merged per_mcbsp4_gfclk into mcbsp4 */ | 980 | DEFINE_CLK_OMAP_MUX(per_mcbsp4_gfclk, "l4_per_clkdm", per_mcbsp4_gfclk_sel, |
1123 | DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "l4_per_clkdm", per_mcbsp4_gfclk_sel, | 981 | OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, |
1124 | OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, | 982 | OMAP4430_CLKSEL_SOURCE_24_24_MASK, per_mcbsp4_gfclk_parents, |
1125 | OMAP4430_CLKSEL_SOURCE_24_24_MASK, | 983 | func_dmic_abe_gfclk_ops); |
1126 | OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, | ||
1127 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1128 | mcbsp4_fck_parents, dmic_fck_ops); | ||
1129 | |||
1130 | DEFINE_CLK_GATE(mcpdm_fck, "pad_clks_ck", &pad_clks_ck, 0x0, | ||
1131 | OMAP4430_CM1_ABE_PDM_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, | ||
1132 | 0x0, NULL); | ||
1133 | |||
1134 | DEFINE_CLK_GATE(mcspi1_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1135 | OMAP4430_CM_L4PER_MCSPI1_CLKCTRL, | ||
1136 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1137 | |||
1138 | DEFINE_CLK_GATE(mcspi2_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1139 | OMAP4430_CM_L4PER_MCSPI2_CLKCTRL, | ||
1140 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1141 | |||
1142 | DEFINE_CLK_GATE(mcspi3_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1143 | OMAP4430_CM_L4PER_MCSPI3_CLKCTRL, | ||
1144 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1145 | |||
1146 | DEFINE_CLK_GATE(mcspi4_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1147 | OMAP4430_CM_L4PER_MCSPI4_CLKCTRL, | ||
1148 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1149 | 984 | ||
1150 | static const struct clksel hsmmc1_fclk_sel[] = { | 985 | static const struct clksel hsmmc1_fclk_sel[] = { |
1151 | { .parent = &func_64m_fclk, .rates = div_1_0_rates }, | 986 | { .parent = &func_64m_fclk, .rates = div_1_0_rates }, |
@@ -1153,69 +988,22 @@ static const struct clksel hsmmc1_fclk_sel[] = { | |||
1153 | { .parent = NULL }, | 988 | { .parent = NULL }, |
1154 | }; | 989 | }; |
1155 | 990 | ||
1156 | static const char *mmc1_fck_parents[] = { | 991 | static const char *hsmmc1_fclk_parents[] = { |
1157 | "func_64m_fclk", "func_96m_fclk", | 992 | "func_64m_fclk", "func_96m_fclk", |
1158 | }; | 993 | }; |
1159 | 994 | ||
1160 | /* Merged hsmmc1_fclk into mmc1 */ | 995 | DEFINE_CLK_OMAP_MUX(hsmmc1_fclk, "l3_init_clkdm", hsmmc1_fclk_sel, |
1161 | DEFINE_CLK_OMAP_MUX_GATE(mmc1_fck, "l3_init_clkdm", hsmmc1_fclk_sel, | 996 | OMAP4430_CM_L3INIT_MMC1_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1162 | OMAP4430_CM_L3INIT_MMC1_CLKCTRL, OMAP4430_CLKSEL_MASK, | 997 | hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops); |
1163 | OMAP4430_CM_L3INIT_MMC1_CLKCTRL, | ||
1164 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1165 | mmc1_fck_parents, dmic_fck_ops); | ||
1166 | |||
1167 | /* Merged hsmmc2_fclk into mmc2 */ | ||
1168 | DEFINE_CLK_OMAP_MUX_GATE(mmc2_fck, "l3_init_clkdm", hsmmc1_fclk_sel, | ||
1169 | OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK, | ||
1170 | OMAP4430_CM_L3INIT_MMC2_CLKCTRL, | ||
1171 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1172 | mmc1_fck_parents, dmic_fck_ops); | ||
1173 | |||
1174 | DEFINE_CLK_GATE(mmc3_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1175 | OMAP4430_CM_L4PER_MMCSD3_CLKCTRL, | ||
1176 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1177 | |||
1178 | DEFINE_CLK_GATE(mmc4_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1179 | OMAP4430_CM_L4PER_MMCSD4_CLKCTRL, | ||
1180 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1181 | |||
1182 | DEFINE_CLK_GATE(mmc5_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1183 | OMAP4430_CM_L4PER_MMCSD5_CLKCTRL, | ||
1184 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1185 | |||
1186 | DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1187 | OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, | ||
1188 | OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL); | ||
1189 | |||
1190 | DEFINE_CLK_GATE(ocp2scp_usb_phy_ick, "l4_div_ck", &l4_div_ck, 0x0, | ||
1191 | OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, | ||
1192 | OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); | ||
1193 | |||
1194 | static struct clk ocp_wp_noc_ick; | ||
1195 | |||
1196 | static struct clk_hw_omap ocp_wp_noc_ick_hw = { | ||
1197 | .hw = { | ||
1198 | .clk = &ocp_wp_noc_ick, | ||
1199 | }, | ||
1200 | .enable_reg = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL, | ||
1201 | .enable_bit = OMAP4430_MODULEMODE_HWCTRL_SHIFT, | ||
1202 | .clkdm_name = "l3_instr_clkdm", | ||
1203 | }; | ||
1204 | |||
1205 | DEFINE_STRUCT_CLK(ocp_wp_noc_ick, l3_instr_ick_parent_names, l3_instr_ick_ops); | ||
1206 | 998 | ||
1207 | DEFINE_CLK_GATE(rng_ick, "l4_div_ck", &l4_div_ck, 0x0, | 999 | DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel, |
1208 | OMAP4430_CM_L4SEC_RNG_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, | 1000 | OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1209 | 0x0, NULL); | 1001 | hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops); |
1210 | 1002 | ||
1211 | DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0, | 1003 | DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0, |
1212 | OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL, | 1004 | OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL, |
1213 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | 1005 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); |
1214 | 1006 | ||
1215 | DEFINE_CLK_GATE(sl2if_ick, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0, | ||
1216 | OMAP4430_CM_IVAHD_SL2_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, | ||
1217 | 0x0, NULL); | ||
1218 | |||
1219 | DEFINE_CLK_GATE(slimbus1_fclk_1, "func_24m_clk", &func_24m_clk, 0x0, | 1007 | DEFINE_CLK_GATE(slimbus1_fclk_1, "func_24m_clk", &func_24m_clk, 0x0, |
1220 | OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, | 1008 | OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, |
1221 | OMAP4430_OPTFCLKEN_FCLK1_SHIFT, 0x0, NULL); | 1009 | OMAP4430_OPTFCLKEN_FCLK1_SHIFT, 0x0, NULL); |
@@ -1232,10 +1020,6 @@ DEFINE_CLK_GATE(slimbus1_slimbus_clk, "slimbus_clk", &slimbus_clk, 0x0, | |||
1232 | OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, | 1020 | OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, |
1233 | OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT, 0x0, NULL); | 1021 | OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT, 0x0, NULL); |
1234 | 1022 | ||
1235 | DEFINE_CLK_GATE(slimbus1_fck, "ocp_abe_iclk", &ocp_abe_iclk, 0x0, | ||
1236 | OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, | ||
1237 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1238 | |||
1239 | DEFINE_CLK_GATE(slimbus2_fclk_1, "per_abe_24m_fclk", &per_abe_24m_fclk, 0x0, | 1023 | DEFINE_CLK_GATE(slimbus2_fclk_1, "per_abe_24m_fclk", &per_abe_24m_fclk, 0x0, |
1240 | OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, | 1024 | OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, |
1241 | OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT, 0x0, NULL); | 1025 | OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT, 0x0, NULL); |
@@ -1249,10 +1033,6 @@ DEFINE_CLK_GATE(slimbus2_slimbus_clk, "pad_slimbus_core_clks_ck", | |||
1249 | OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, | 1033 | OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, |
1250 | OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT, 0x0, NULL); | 1034 | OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT, 0x0, NULL); |
1251 | 1035 | ||
1252 | DEFINE_CLK_GATE(slimbus2_fck, "l4_div_ck", &l4_div_ck, 0x0, | ||
1253 | OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, | ||
1254 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1255 | |||
1256 | DEFINE_CLK_GATE(smartreflex_core_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, | 1036 | DEFINE_CLK_GATE(smartreflex_core_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, |
1257 | 0x0, OMAP4430_CM_ALWON_SR_CORE_CLKCTRL, | 1037 | 0x0, OMAP4430_CM_ALWON_SR_CORE_CLKCTRL, |
1258 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | 1038 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); |
@@ -1271,52 +1051,35 @@ static const struct clksel dmt1_clk_mux_sel[] = { | |||
1271 | { .parent = NULL }, | 1051 | { .parent = NULL }, |
1272 | }; | 1052 | }; |
1273 | 1053 | ||
1274 | /* Merged dmt1_clk_mux into timer1 */ | 1054 | DEFINE_CLK_OMAP_MUX(dmt1_clk_mux, "l4_wkup_clkdm", dmt1_clk_mux_sel, |
1275 | DEFINE_CLK_OMAP_MUX_GATE(timer1_fck, "l4_wkup_clkdm", dmt1_clk_mux_sel, | 1055 | OMAP4430_CM_WKUP_TIMER1_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1276 | OMAP4430_CM_WKUP_TIMER1_CLKCTRL, OMAP4430_CLKSEL_MASK, | 1056 | abe_dpll_bypass_clk_mux_ck_parents, |
1277 | OMAP4430_CM_WKUP_TIMER1_CLKCTRL, | 1057 | func_dmic_abe_gfclk_ops); |
1278 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | 1058 | |
1279 | abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); | 1059 | DEFINE_CLK_OMAP_MUX(cm2_dm10_mux, "l4_per_clkdm", dmt1_clk_mux_sel, |
1280 | 1060 | OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, OMAP4430_CLKSEL_MASK, | |
1281 | /* Merged cm2_dm10_mux into timer10 */ | 1061 | abe_dpll_bypass_clk_mux_ck_parents, |
1282 | DEFINE_CLK_OMAP_MUX_GATE(timer10_fck, "l4_per_clkdm", dmt1_clk_mux_sel, | 1062 | func_dmic_abe_gfclk_ops); |
1283 | OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, | 1063 | |
1284 | OMAP4430_CLKSEL_MASK, | 1064 | DEFINE_CLK_OMAP_MUX(cm2_dm11_mux, "l4_per_clkdm", dmt1_clk_mux_sel, |
1285 | OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, | 1065 | OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1286 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | 1066 | abe_dpll_bypass_clk_mux_ck_parents, |
1287 | abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); | 1067 | func_dmic_abe_gfclk_ops); |
1288 | 1068 | ||
1289 | /* Merged cm2_dm11_mux into timer11 */ | 1069 | DEFINE_CLK_OMAP_MUX(cm2_dm2_mux, "l4_per_clkdm", dmt1_clk_mux_sel, |
1290 | DEFINE_CLK_OMAP_MUX_GATE(timer11_fck, "l4_per_clkdm", dmt1_clk_mux_sel, | 1070 | OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1291 | OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, | 1071 | abe_dpll_bypass_clk_mux_ck_parents, |
1292 | OMAP4430_CLKSEL_MASK, | 1072 | func_dmic_abe_gfclk_ops); |
1293 | OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, | 1073 | |
1294 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | 1074 | DEFINE_CLK_OMAP_MUX(cm2_dm3_mux, "l4_per_clkdm", dmt1_clk_mux_sel, |
1295 | abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); | 1075 | OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1296 | 1076 | abe_dpll_bypass_clk_mux_ck_parents, | |
1297 | /* Merged cm2_dm2_mux into timer2 */ | 1077 | func_dmic_abe_gfclk_ops); |
1298 | DEFINE_CLK_OMAP_MUX_GATE(timer2_fck, "l4_per_clkdm", dmt1_clk_mux_sel, | 1078 | |
1299 | OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, | 1079 | DEFINE_CLK_OMAP_MUX(cm2_dm4_mux, "l4_per_clkdm", dmt1_clk_mux_sel, |
1300 | OMAP4430_CLKSEL_MASK, | 1080 | OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1301 | OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, | 1081 | abe_dpll_bypass_clk_mux_ck_parents, |
1302 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | 1082 | func_dmic_abe_gfclk_ops); |
1303 | abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); | ||
1304 | |||
1305 | /* Merged cm2_dm3_mux into timer3 */ | ||
1306 | DEFINE_CLK_OMAP_MUX_GATE(timer3_fck, "l4_per_clkdm", dmt1_clk_mux_sel, | ||
1307 | OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, | ||
1308 | OMAP4430_CLKSEL_MASK, | ||
1309 | OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, | ||
1310 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1311 | abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); | ||
1312 | |||
1313 | /* Merged cm2_dm4_mux into timer4 */ | ||
1314 | DEFINE_CLK_OMAP_MUX_GATE(timer4_fck, "l4_per_clkdm", dmt1_clk_mux_sel, | ||
1315 | OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, | ||
1316 | OMAP4430_CLKSEL_MASK, | ||
1317 | OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, | ||
1318 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1319 | abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); | ||
1320 | 1083 | ||
1321 | static const struct clksel timer5_sync_mux_sel[] = { | 1084 | static const struct clksel timer5_sync_mux_sel[] = { |
1322 | { .parent = &syc_clk_div_ck, .rates = div_1_0_rates }, | 1085 | { .parent = &syc_clk_div_ck, .rates = div_1_0_rates }, |
@@ -1324,61 +1087,30 @@ static const struct clksel timer5_sync_mux_sel[] = { | |||
1324 | { .parent = NULL }, | 1087 | { .parent = NULL }, |
1325 | }; | 1088 | }; |
1326 | 1089 | ||
1327 | static const char *timer5_fck_parents[] = { | 1090 | static const char *timer5_sync_mux_parents[] = { |
1328 | "syc_clk_div_ck", "sys_32k_ck", | 1091 | "syc_clk_div_ck", "sys_32k_ck", |
1329 | }; | 1092 | }; |
1330 | 1093 | ||
1331 | /* Merged timer5_sync_mux into timer5 */ | 1094 | DEFINE_CLK_OMAP_MUX(timer5_sync_mux, "abe_clkdm", timer5_sync_mux_sel, |
1332 | DEFINE_CLK_OMAP_MUX_GATE(timer5_fck, "abe_clkdm", timer5_sync_mux_sel, | 1095 | OMAP4430_CM1_ABE_TIMER5_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1333 | OMAP4430_CM1_ABE_TIMER5_CLKCTRL, OMAP4430_CLKSEL_MASK, | 1096 | timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); |
1334 | OMAP4430_CM1_ABE_TIMER5_CLKCTRL, | ||
1335 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1336 | timer5_fck_parents, dmic_fck_ops); | ||
1337 | |||
1338 | /* Merged timer6_sync_mux into timer6 */ | ||
1339 | DEFINE_CLK_OMAP_MUX_GATE(timer6_fck, "abe_clkdm", timer5_sync_mux_sel, | ||
1340 | OMAP4430_CM1_ABE_TIMER6_CLKCTRL, OMAP4430_CLKSEL_MASK, | ||
1341 | OMAP4430_CM1_ABE_TIMER6_CLKCTRL, | ||
1342 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1343 | timer5_fck_parents, dmic_fck_ops); | ||
1344 | |||
1345 | /* Merged timer7_sync_mux into timer7 */ | ||
1346 | DEFINE_CLK_OMAP_MUX_GATE(timer7_fck, "abe_clkdm", timer5_sync_mux_sel, | ||
1347 | OMAP4430_CM1_ABE_TIMER7_CLKCTRL, OMAP4430_CLKSEL_MASK, | ||
1348 | OMAP4430_CM1_ABE_TIMER7_CLKCTRL, | ||
1349 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1350 | timer5_fck_parents, dmic_fck_ops); | ||
1351 | |||
1352 | /* Merged timer8_sync_mux into timer8 */ | ||
1353 | DEFINE_CLK_OMAP_MUX_GATE(timer8_fck, "abe_clkdm", timer5_sync_mux_sel, | ||
1354 | OMAP4430_CM1_ABE_TIMER8_CLKCTRL, OMAP4430_CLKSEL_MASK, | ||
1355 | OMAP4430_CM1_ABE_TIMER8_CLKCTRL, | ||
1356 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1357 | timer5_fck_parents, dmic_fck_ops); | ||
1358 | |||
1359 | /* Merged cm2_dm9_mux into timer9 */ | ||
1360 | DEFINE_CLK_OMAP_MUX_GATE(timer9_fck, "l4_per_clkdm", dmt1_clk_mux_sel, | ||
1361 | OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, | ||
1362 | OMAP4430_CLKSEL_MASK, | ||
1363 | OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, | ||
1364 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, | ||
1365 | abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); | ||
1366 | |||
1367 | DEFINE_CLK_GATE(uart1_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | ||
1368 | OMAP4430_CM_L4PER_UART1_CLKCTRL, | ||
1369 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | ||
1370 | 1097 | ||
1371 | DEFINE_CLK_GATE(uart2_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | 1098 | DEFINE_CLK_OMAP_MUX(timer6_sync_mux, "abe_clkdm", timer5_sync_mux_sel, |
1372 | OMAP4430_CM_L4PER_UART2_CLKCTRL, | 1099 | OMAP4430_CM1_ABE_TIMER6_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1373 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | 1100 | timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); |
1374 | 1101 | ||
1375 | DEFINE_CLK_GATE(uart3_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | 1102 | DEFINE_CLK_OMAP_MUX(timer7_sync_mux, "abe_clkdm", timer5_sync_mux_sel, |
1376 | OMAP4430_CM_L4PER_UART3_CLKCTRL, | 1103 | OMAP4430_CM1_ABE_TIMER7_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1377 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | 1104 | timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); |
1378 | 1105 | ||
1379 | DEFINE_CLK_GATE(uart4_fck, "func_48m_fclk", &func_48m_fclk, 0x0, | 1106 | DEFINE_CLK_OMAP_MUX(timer8_sync_mux, "abe_clkdm", timer5_sync_mux_sel, |
1380 | OMAP4430_CM_L4PER_UART4_CLKCTRL, | 1107 | OMAP4430_CM1_ABE_TIMER8_CLKCTRL, OMAP4430_CLKSEL_MASK, |
1381 | OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); | 1108 | timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); |
1109 | |||
1110 | DEFINE_CLK_OMAP_MUX(cm2_dm9_mux, "l4_per_clkdm", dmt1_clk_mux_sel, | ||
1111 | OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, OMAP4430_CLKSEL_MASK, | ||
1112 | abe_dpll_bypass_clk_mux_ck_parents, | ||
1113 | func_dmic_abe_gfclk_ops); | ||
1382 | 1114 | ||
1383 | static struct clk usb_host_fs_fck; | 1115 | static struct clk usb_host_fs_fck; |
1384 | 1116 | ||
@@ -1512,18 +1244,6 @@ DEFINE_CLK_GATE(usim_fclk, "usim_ck", &usim_ck, 0x0, | |||
1512 | OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_OPTFCLKEN_FCLK_SHIFT, | 1244 | OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_OPTFCLKEN_FCLK_SHIFT, |
1513 | 0x0, NULL); | 1245 | 0x0, NULL); |
1514 | 1246 | ||
1515 | DEFINE_CLK_GATE(usim_fck, "sys_32k_ck", &sys_32k_ck, 0x0, | ||
1516 | OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, | ||
1517 | 0x0, NULL); | ||
1518 | |||
1519 | DEFINE_CLK_GATE(wd_timer2_fck, "sys_32k_ck", &sys_32k_ck, 0x0, | ||
1520 | OMAP4430_CM_WKUP_WDT2_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, | ||
1521 | 0x0, NULL); | ||
1522 | |||
1523 | DEFINE_CLK_GATE(wd_timer3_fck, "sys_32k_ck", &sys_32k_ck, 0x0, | ||
1524 | OMAP4430_CM1_ABE_WDT3_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, | ||
1525 | 0x0, NULL); | ||
1526 | |||
1527 | /* Remaining optional clocks */ | 1247 | /* Remaining optional clocks */ |
1528 | static const char *pmd_stm_clock_mux_ck_parents[] = { | 1248 | static const char *pmd_stm_clock_mux_ck_parents[] = { |
1529 | "sys_clkin_ck", "dpll_core_m6x2_ck", "tie_low_clock_ck", | 1249 | "sys_clkin_ck", "dpll_core_m6x2_ck", "tie_low_clock_ck", |
@@ -1774,106 +1494,61 @@ static struct omap_clk omap44xx_clks[] = { | |||
1774 | CLK(NULL, "syc_clk_div_ck", &syc_clk_div_ck, CK_443X), | 1494 | CLK(NULL, "syc_clk_div_ck", &syc_clk_div_ck, CK_443X), |
1775 | CLK(NULL, "aes1_fck", &aes1_fck, CK_443X), | 1495 | CLK(NULL, "aes1_fck", &aes1_fck, CK_443X), |
1776 | CLK(NULL, "aes2_fck", &aes2_fck, CK_443X), | 1496 | CLK(NULL, "aes2_fck", &aes2_fck, CK_443X), |
1777 | CLK(NULL, "aess_fck", &aess_fck, CK_443X), | ||
1778 | CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X), | 1497 | CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X), |
1779 | CLK(NULL, "div_ts_ck", &div_ts_ck, CK_446X), | 1498 | CLK(NULL, "div_ts_ck", &div_ts_ck, CK_446X), |
1780 | CLK(NULL, "bandgap_ts_fclk", &bandgap_ts_fclk, CK_446X), | 1499 | CLK(NULL, "bandgap_ts_fclk", &bandgap_ts_fclk, CK_446X), |
1781 | CLK(NULL, "des3des_fck", &des3des_fck, CK_443X), | ||
1782 | CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X), | 1500 | CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X), |
1783 | CLK(NULL, "dmic_fck", &dmic_fck, CK_443X), | 1501 | CLK(NULL, "func_dmic_abe_gfclk", &func_dmic_abe_gfclk, CK_443X), |
1784 | CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), | ||
1785 | CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X), | 1502 | CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X), |
1786 | CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X), | 1503 | CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X), |
1787 | CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X), | 1504 | CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X), |
1788 | CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X), | 1505 | CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X), |
1789 | CLK(NULL, "dss_fck", &dss_fck, CK_443X), | 1506 | CLK(NULL, "dss_fck", &dss_fck, CK_443X), |
1790 | CLK("omapdss_dss", "ick", &dss_fck, CK_443X), | 1507 | CLK("omapdss_dss", "ick", &dss_fck, CK_443X), |
1791 | CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), | ||
1792 | CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), | ||
1793 | CLK(NULL, "emif2_fck", &emif2_fck, CK_443X), | ||
1794 | CLK(NULL, "fdif_fck", &fdif_fck, CK_443X), | 1508 | CLK(NULL, "fdif_fck", &fdif_fck, CK_443X), |
1795 | CLK(NULL, "fpka_fck", &fpka_fck, CK_443X), | ||
1796 | CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_443X), | 1509 | CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_443X), |
1797 | CLK(NULL, "gpio1_ick", &gpio1_ick, CK_443X), | ||
1798 | CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_443X), | 1510 | CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_443X), |
1799 | CLK(NULL, "gpio2_ick", &gpio2_ick, CK_443X), | ||
1800 | CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_443X), | 1511 | CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_443X), |
1801 | CLK(NULL, "gpio3_ick", &gpio3_ick, CK_443X), | ||
1802 | CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_443X), | 1512 | CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_443X), |
1803 | CLK(NULL, "gpio4_ick", &gpio4_ick, CK_443X), | ||
1804 | CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_443X), | 1513 | CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_443X), |
1805 | CLK(NULL, "gpio5_ick", &gpio5_ick, CK_443X), | ||
1806 | CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_443X), | 1514 | CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_443X), |
1807 | CLK(NULL, "gpio6_ick", &gpio6_ick, CK_443X), | 1515 | CLK(NULL, "sgx_clk_mux", &sgx_clk_mux, CK_443X), |
1808 | CLK(NULL, "gpmc_ick", &gpmc_ick, CK_443X), | ||
1809 | CLK(NULL, "gpu_fck", &gpu_fck, CK_443X), | ||
1810 | CLK(NULL, "hdq1w_fck", &hdq1w_fck, CK_443X), | ||
1811 | CLK(NULL, "hsi_fck", &hsi_fck, CK_443X), | 1516 | CLK(NULL, "hsi_fck", &hsi_fck, CK_443X), |
1812 | CLK(NULL, "i2c1_fck", &i2c1_fck, CK_443X), | ||
1813 | CLK(NULL, "i2c2_fck", &i2c2_fck, CK_443X), | ||
1814 | CLK(NULL, "i2c3_fck", &i2c3_fck, CK_443X), | ||
1815 | CLK(NULL, "i2c4_fck", &i2c4_fck, CK_443X), | ||
1816 | CLK(NULL, "ipu_fck", &ipu_fck, CK_443X), | ||
1817 | CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X), | 1517 | CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X), |
1818 | CLK(NULL, "iss_fck", &iss_fck, CK_443X), | ||
1819 | CLK(NULL, "iva_fck", &iva_fck, CK_443X), | ||
1820 | CLK(NULL, "kbd_fck", &kbd_fck, CK_443X), | ||
1821 | CLK(NULL, "l3_instr_ick", &l3_instr_ick, CK_443X), | ||
1822 | CLK(NULL, "l3_main_3_ick", &l3_main_3_ick, CK_443X), | ||
1823 | CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X), | 1518 | CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X), |
1824 | CLK(NULL, "mcasp_fck", &mcasp_fck, CK_443X), | 1519 | CLK(NULL, "func_mcasp_abe_gfclk", &func_mcasp_abe_gfclk, CK_443X), |
1825 | CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X), | 1520 | CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X), |
1826 | CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_443X), | 1521 | CLK(NULL, "func_mcbsp1_gfclk", &func_mcbsp1_gfclk, CK_443X), |
1827 | CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_443X), | 1522 | CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_443X), |
1828 | CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_443X), | 1523 | CLK(NULL, "func_mcbsp2_gfclk", &func_mcbsp2_gfclk, CK_443X), |
1829 | CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_443X), | 1524 | CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_443X), |
1830 | CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_443X), | 1525 | CLK(NULL, "func_mcbsp3_gfclk", &func_mcbsp3_gfclk, CK_443X), |
1831 | CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X), | 1526 | CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X), |
1832 | CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_443X), | 1527 | CLK(NULL, "per_mcbsp4_gfclk", &per_mcbsp4_gfclk, CK_443X), |
1833 | CLK(NULL, "mcpdm_fck", &mcpdm_fck, CK_443X), | 1528 | CLK(NULL, "hsmmc1_fclk", &hsmmc1_fclk, CK_443X), |
1834 | CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_443X), | 1529 | CLK(NULL, "hsmmc2_fclk", &hsmmc2_fclk, CK_443X), |
1835 | CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_443X), | ||
1836 | CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_443X), | ||
1837 | CLK(NULL, "mcspi4_fck", &mcspi4_fck, CK_443X), | ||
1838 | CLK(NULL, "mmc1_fck", &mmc1_fck, CK_443X), | ||
1839 | CLK(NULL, "mmc2_fck", &mmc2_fck, CK_443X), | ||
1840 | CLK(NULL, "mmc3_fck", &mmc3_fck, CK_443X), | ||
1841 | CLK(NULL, "mmc4_fck", &mmc4_fck, CK_443X), | ||
1842 | CLK(NULL, "mmc5_fck", &mmc5_fck, CK_443X), | ||
1843 | CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X), | ||
1844 | CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X), | ||
1845 | CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X), | ||
1846 | CLK(NULL, "rng_ick", &rng_ick, CK_443X), | ||
1847 | CLK("omap_rng", "ick", &rng_ick, CK_443X), | ||
1848 | CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X), | 1530 | CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X), |
1849 | CLK(NULL, "sl2if_ick", &sl2if_ick, CK_443X), | ||
1850 | CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X), | 1531 | CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X), |
1851 | CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X), | 1532 | CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X), |
1852 | CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_443X), | 1533 | CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_443X), |
1853 | CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_443X), | 1534 | CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_443X), |
1854 | CLK(NULL, "slimbus1_fck", &slimbus1_fck, CK_443X), | ||
1855 | CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_443X), | 1535 | CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_443X), |
1856 | CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_443X), | 1536 | CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_443X), |
1857 | CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_443X), | 1537 | CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_443X), |
1858 | CLK(NULL, "slimbus2_fck", &slimbus2_fck, CK_443X), | ||
1859 | CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_443X), | 1538 | CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_443X), |
1860 | CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_443X), | 1539 | CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_443X), |
1861 | CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_443X), | 1540 | CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_443X), |
1862 | CLK(NULL, "timer1_fck", &timer1_fck, CK_443X), | 1541 | CLK(NULL, "dmt1_clk_mux", &dmt1_clk_mux, CK_443X), |
1863 | CLK(NULL, "timer10_fck", &timer10_fck, CK_443X), | 1542 | CLK(NULL, "cm2_dm10_mux", &cm2_dm10_mux, CK_443X), |
1864 | CLK(NULL, "timer11_fck", &timer11_fck, CK_443X), | 1543 | CLK(NULL, "cm2_dm11_mux", &cm2_dm11_mux, CK_443X), |
1865 | CLK(NULL, "timer2_fck", &timer2_fck, CK_443X), | 1544 | CLK(NULL, "cm2_dm2_mux", &cm2_dm2_mux, CK_443X), |
1866 | CLK(NULL, "timer3_fck", &timer3_fck, CK_443X), | 1545 | CLK(NULL, "cm2_dm3_mux", &cm2_dm3_mux, CK_443X), |
1867 | CLK(NULL, "timer4_fck", &timer4_fck, CK_443X), | 1546 | CLK(NULL, "cm2_dm4_mux", &cm2_dm4_mux, CK_443X), |
1868 | CLK(NULL, "timer5_fck", &timer5_fck, CK_443X), | 1547 | CLK(NULL, "timer5_sync_mux", &timer5_sync_mux, CK_443X), |
1869 | CLK(NULL, "timer6_fck", &timer6_fck, CK_443X), | 1548 | CLK(NULL, "timer6_sync_mux", &timer6_sync_mux, CK_443X), |
1870 | CLK(NULL, "timer7_fck", &timer7_fck, CK_443X), | 1549 | CLK(NULL, "timer7_sync_mux", &timer7_sync_mux, CK_443X), |
1871 | CLK(NULL, "timer8_fck", &timer8_fck, CK_443X), | 1550 | CLK(NULL, "timer8_sync_mux", &timer8_sync_mux, CK_443X), |
1872 | CLK(NULL, "timer9_fck", &timer9_fck, CK_443X), | 1551 | CLK(NULL, "cm2_dm9_mux", &cm2_dm9_mux, CK_443X), |
1873 | CLK(NULL, "uart1_fck", &uart1_fck, CK_443X), | ||
1874 | CLK(NULL, "uart2_fck", &uart2_fck, CK_443X), | ||
1875 | CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), | ||
1876 | CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), | ||
1877 | CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X), | 1552 | CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X), |
1878 | CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X), | 1553 | CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X), |
1879 | CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), | 1554 | CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), |
@@ -1901,9 +1576,6 @@ static struct omap_clk omap44xx_clks[] = { | |||
1901 | CLK("usbhs_tll", "usbtll_ick", &usb_tll_hs_ick, CK_443X), | 1576 | CLK("usbhs_tll", "usbtll_ick", &usb_tll_hs_ick, CK_443X), |
1902 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), | 1577 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), |
1903 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), | 1578 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), |
1904 | CLK(NULL, "usim_fck", &usim_fck, CK_443X), | ||
1905 | CLK(NULL, "wd_timer2_fck", &wd_timer2_fck, CK_443X), | ||
1906 | CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_443X), | ||
1907 | CLK(NULL, "pmd_stm_clock_mux_ck", &pmd_stm_clock_mux_ck, CK_443X), | 1579 | CLK(NULL, "pmd_stm_clock_mux_ck", &pmd_stm_clock_mux_ck, CK_443X), |
1908 | CLK(NULL, "pmd_trace_clk_mux_ck", &pmd_trace_clk_mux_ck, CK_443X), | 1580 | CLK(NULL, "pmd_trace_clk_mux_ck", &pmd_trace_clk_mux_ck, CK_443X), |
1909 | CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X), | 1581 | CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X), |
@@ -1980,15 +1652,6 @@ static struct omap_clk omap44xx_clks[] = { | |||
1980 | CLK(NULL, "cpufreq_ck", &dpll_mpu_ck, CK_443X), | 1652 | CLK(NULL, "cpufreq_ck", &dpll_mpu_ck, CK_443X), |
1981 | }; | 1653 | }; |
1982 | 1654 | ||
1983 | static const char *enable_init_clks[] = { | ||
1984 | "emif1_fck", | ||
1985 | "emif2_fck", | ||
1986 | "gpmc_ick", | ||
1987 | "l3_instr_ick", | ||
1988 | "l3_main_3_ick", | ||
1989 | "ocp_wp_noc_ick", | ||
1990 | }; | ||
1991 | |||
1992 | int __init omap4xxx_clk_init(void) | 1655 | int __init omap4xxx_clk_init(void) |
1993 | { | 1656 | { |
1994 | u32 cpu_clkflg; | 1657 | u32 cpu_clkflg; |
@@ -2019,9 +1682,6 @@ int __init omap4xxx_clk_init(void) | |||
2019 | 1682 | ||
2020 | omap2_clk_disable_autoidle_all(); | 1683 | omap2_clk_disable_autoidle_all(); |
2021 | 1684 | ||
2022 | omap2_clk_enable_init_clocks(enable_init_clks, | ||
2023 | ARRAY_SIZE(enable_init_clks)); | ||
2024 | |||
2025 | /* | 1685 | /* |
2026 | * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power | 1686 | * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power |
2027 | * state when turning the ABE clock domain. Workaround this by | 1687 | * state when turning the ABE clock domain. Workaround this by |
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 7faf82d4e85c..2da3b5ec010c 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c | |||
@@ -92,8 +92,6 @@ static int _clkdm_register(struct clockdomain *clkdm) | |||
92 | 92 | ||
93 | pwrdm_add_clkdm(pwrdm, clkdm); | 93 | pwrdm_add_clkdm(pwrdm, clkdm); |
94 | 94 | ||
95 | spin_lock_init(&clkdm->lock); | ||
96 | |||
97 | pr_debug("clockdomain: registered %s\n", clkdm->name); | 95 | pr_debug("clockdomain: registered %s\n", clkdm->name); |
98 | 96 | ||
99 | return 0; | 97 | return 0; |
@@ -122,7 +120,7 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm, | |||
122 | return cd; | 120 | return cd; |
123 | } | 121 | } |
124 | 122 | ||
125 | /* | 123 | /** |
126 | * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store | 124 | * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store |
127 | * @autodep: struct clkdm_autodep * to resolve | 125 | * @autodep: struct clkdm_autodep * to resolve |
128 | * | 126 | * |
@@ -154,88 +152,206 @@ static void _autodep_lookup(struct clkdm_autodep *autodep) | |||
154 | autodep->clkdm.ptr = clkdm; | 152 | autodep->clkdm.ptr = clkdm; |
155 | } | 153 | } |
156 | 154 | ||
157 | /* | 155 | /** |
158 | * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable | 156 | * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms |
159 | * @clkdm: struct clockdomain * | 157 | * @clkdm: clockdomain that we are resolving dependencies for |
158 | * @clkdm_deps: ptr to array of struct clkdm_deps to resolve | ||
160 | * | 159 | * |
161 | * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' | 160 | * Iterates through @clkdm_deps, looking up the struct clockdomain named by |
162 | * in hardware-supervised mode. Meant to be called from clock framework | 161 | * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. |
163 | * when a clock inside clockdomain 'clkdm' is enabled. No return value. | 162 | * No return value. |
163 | */ | ||
164 | static void _resolve_clkdm_deps(struct clockdomain *clkdm, | ||
165 | struct clkdm_dep *clkdm_deps) | ||
166 | { | ||
167 | struct clkdm_dep *cd; | ||
168 | |||
169 | for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { | ||
170 | if (cd->clkdm) | ||
171 | continue; | ||
172 | cd->clkdm = _clkdm_lookup(cd->clkdm_name); | ||
173 | |||
174 | WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", | ||
175 | clkdm->name, cd->clkdm_name); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * _clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 (lockless) | ||
181 | * @clkdm1: wake this struct clockdomain * up (dependent) | ||
182 | * @clkdm2: when this struct clockdomain * wakes up (source) | ||
164 | * | 183 | * |
165 | * XXX autodeps are deprecated and should be removed at the earliest | 184 | * When the clockdomain represented by @clkdm2 wakes up, wake up |
166 | * opportunity | 185 | * @clkdm1. Implemented in hardware on the OMAP, this feature is |
186 | * designed to reduce wakeup latency of the dependent clockdomain @clkdm1. | ||
187 | * Returns -EINVAL if presented with invalid clockdomain pointers, | ||
188 | * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon | ||
189 | * success. | ||
167 | */ | 190 | */ |
168 | void _clkdm_add_autodeps(struct clockdomain *clkdm) | 191 | static int _clkdm_add_wkdep(struct clockdomain *clkdm1, |
192 | struct clockdomain *clkdm2) | ||
169 | { | 193 | { |
170 | struct clkdm_autodep *autodep; | 194 | struct clkdm_dep *cd; |
195 | int ret = 0; | ||
171 | 196 | ||
172 | if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) | 197 | if (!clkdm1 || !clkdm2) |
173 | return; | 198 | return -EINVAL; |
174 | 199 | ||
175 | for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { | 200 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); |
176 | if (IS_ERR(autodep->clkdm.ptr)) | 201 | if (IS_ERR(cd)) |
177 | continue; | 202 | ret = PTR_ERR(cd); |
178 | 203 | ||
179 | pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", | 204 | if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) |
180 | clkdm->name, autodep->clkdm.ptr->name); | 205 | ret = -EINVAL; |
206 | |||
207 | if (ret) { | ||
208 | pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", | ||
209 | clkdm1->name, clkdm2->name); | ||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | cd->wkdep_usecount++; | ||
214 | if (cd->wkdep_usecount == 1) { | ||
215 | pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", | ||
216 | clkdm1->name, clkdm2->name); | ||
181 | 217 | ||
182 | clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); | 218 | ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2); |
183 | clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); | ||
184 | } | 219 | } |
220 | |||
221 | return ret; | ||
185 | } | 222 | } |
186 | 223 | ||
187 | /* | 224 | /** |
188 | * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm | 225 | * _clkdm_del_wkdep - remove a wakeup dep from clkdm2 to clkdm1 (lockless) |
189 | * @clkdm: struct clockdomain * | 226 | * @clkdm1: wake this struct clockdomain * up (dependent) |
227 | * @clkdm2: when this struct clockdomain * wakes up (source) | ||
190 | * | 228 | * |
191 | * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' | 229 | * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2 |
192 | * in hardware-supervised mode. Meant to be called from clock framework | 230 | * wakes up. Returns -EINVAL if presented with invalid clockdomain |
193 | * when a clock inside clockdomain 'clkdm' is disabled. No return value. | 231 | * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or |
232 | * 0 upon success. | ||
233 | */ | ||
234 | static int _clkdm_del_wkdep(struct clockdomain *clkdm1, | ||
235 | struct clockdomain *clkdm2) | ||
236 | { | ||
237 | struct clkdm_dep *cd; | ||
238 | int ret = 0; | ||
239 | |||
240 | if (!clkdm1 || !clkdm2) | ||
241 | return -EINVAL; | ||
242 | |||
243 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); | ||
244 | if (IS_ERR(cd)) | ||
245 | ret = PTR_ERR(cd); | ||
246 | |||
247 | if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) | ||
248 | ret = -EINVAL; | ||
249 | |||
250 | if (ret) { | ||
251 | pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", | ||
252 | clkdm1->name, clkdm2->name); | ||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | cd->wkdep_usecount--; | ||
257 | if (cd->wkdep_usecount == 0) { | ||
258 | pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", | ||
259 | clkdm1->name, clkdm2->name); | ||
260 | |||
261 | ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); | ||
262 | } | ||
263 | |||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | /** | ||
268 | * _clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 (lockless) | ||
269 | * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) | ||
270 | * @clkdm2: when this struct clockdomain * is active (source) | ||
194 | * | 271 | * |
195 | * XXX autodeps are deprecated and should be removed at the earliest | 272 | * Prevent @clkdm1 from automatically going inactive (and then to |
196 | * opportunity | 273 | * retention or off) if @clkdm2 is active. Returns -EINVAL if |
274 | * presented with invalid clockdomain pointers or called on a machine | ||
275 | * that does not support software-configurable hardware sleep | ||
276 | * dependencies, -ENOENT if the specified dependency cannot be set in | ||
277 | * hardware, or 0 upon success. | ||
197 | */ | 278 | */ |
198 | void _clkdm_del_autodeps(struct clockdomain *clkdm) | 279 | static int _clkdm_add_sleepdep(struct clockdomain *clkdm1, |
280 | struct clockdomain *clkdm2) | ||
199 | { | 281 | { |
200 | struct clkdm_autodep *autodep; | 282 | struct clkdm_dep *cd; |
283 | int ret = 0; | ||
201 | 284 | ||
202 | if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) | 285 | if (!clkdm1 || !clkdm2) |
203 | return; | 286 | return -EINVAL; |
204 | 287 | ||
205 | for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { | 288 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); |
206 | if (IS_ERR(autodep->clkdm.ptr)) | 289 | if (IS_ERR(cd)) |
207 | continue; | 290 | ret = PTR_ERR(cd); |
208 | 291 | ||
209 | pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", | 292 | if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) |
210 | clkdm->name, autodep->clkdm.ptr->name); | 293 | ret = -EINVAL; |
211 | 294 | ||
212 | clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); | 295 | if (ret) { |
213 | clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); | 296 | pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", |
297 | clkdm1->name, clkdm2->name); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | cd->sleepdep_usecount++; | ||
302 | if (cd->sleepdep_usecount == 1) { | ||
303 | pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n", | ||
304 | clkdm1->name, clkdm2->name); | ||
305 | |||
306 | ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2); | ||
214 | } | 307 | } |
308 | |||
309 | return ret; | ||
215 | } | 310 | } |
216 | 311 | ||
217 | /** | 312 | /** |
218 | * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms | 313 | * _clkdm_del_sleepdep - remove a sleep dep from clkdm2 to clkdm1 (lockless) |
219 | * @clkdm: clockdomain that we are resolving dependencies for | 314 | * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) |
220 | * @clkdm_deps: ptr to array of struct clkdm_deps to resolve | 315 | * @clkdm2: when this struct clockdomain * is active (source) |
221 | * | 316 | * |
222 | * Iterates through @clkdm_deps, looking up the struct clockdomain named by | 317 | * Allow @clkdm1 to automatically go inactive (and then to retention or |
223 | * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. | 318 | * off), independent of the activity state of @clkdm2. Returns -EINVAL |
224 | * No return value. | 319 | * if presented with invalid clockdomain pointers or called on a machine |
320 | * that does not support software-configurable hardware sleep dependencies, | ||
321 | * -ENOENT if the specified dependency cannot be cleared in hardware, or | ||
322 | * 0 upon success. | ||
225 | */ | 323 | */ |
226 | static void _resolve_clkdm_deps(struct clockdomain *clkdm, | 324 | static int _clkdm_del_sleepdep(struct clockdomain *clkdm1, |
227 | struct clkdm_dep *clkdm_deps) | 325 | struct clockdomain *clkdm2) |
228 | { | 326 | { |
229 | struct clkdm_dep *cd; | 327 | struct clkdm_dep *cd; |
328 | int ret = 0; | ||
230 | 329 | ||
231 | for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { | 330 | if (!clkdm1 || !clkdm2) |
232 | if (cd->clkdm) | 331 | return -EINVAL; |
233 | continue; | ||
234 | cd->clkdm = _clkdm_lookup(cd->clkdm_name); | ||
235 | 332 | ||
236 | WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", | 333 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); |
237 | clkdm->name, cd->clkdm_name); | 334 | if (IS_ERR(cd)) |
335 | ret = PTR_ERR(cd); | ||
336 | |||
337 | if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) | ||
338 | ret = -EINVAL; | ||
339 | |||
340 | if (ret) { | ||
341 | pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", | ||
342 | clkdm1->name, clkdm2->name); | ||
343 | return ret; | ||
238 | } | 344 | } |
345 | |||
346 | cd->sleepdep_usecount--; | ||
347 | if (cd->sleepdep_usecount == 0) { | ||
348 | pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n", | ||
349 | clkdm1->name, clkdm2->name); | ||
350 | |||
351 | ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); | ||
352 | } | ||
353 | |||
354 | return ret; | ||
239 | } | 355 | } |
240 | 356 | ||
241 | /* Public functions */ | 357 | /* Public functions */ |
@@ -456,30 +572,18 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm) | |||
456 | int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | 572 | int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) |
457 | { | 573 | { |
458 | struct clkdm_dep *cd; | 574 | struct clkdm_dep *cd; |
459 | int ret = 0; | 575 | int ret; |
460 | 576 | ||
461 | if (!clkdm1 || !clkdm2) | 577 | if (!clkdm1 || !clkdm2) |
462 | return -EINVAL; | 578 | return -EINVAL; |
463 | 579 | ||
464 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); | 580 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); |
465 | if (IS_ERR(cd)) | 581 | if (IS_ERR(cd)) |
466 | ret = PTR_ERR(cd); | 582 | return PTR_ERR(cd); |
467 | 583 | ||
468 | if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) | 584 | pwrdm_lock(cd->clkdm->pwrdm.ptr); |
469 | ret = -EINVAL; | 585 | ret = _clkdm_add_wkdep(clkdm1, clkdm2); |
470 | 586 | pwrdm_unlock(cd->clkdm->pwrdm.ptr); | |
471 | if (ret) { | ||
472 | pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", | ||
473 | clkdm1->name, clkdm2->name); | ||
474 | return ret; | ||
475 | } | ||
476 | |||
477 | if (atomic_inc_return(&cd->wkdep_usecount) == 1) { | ||
478 | pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", | ||
479 | clkdm1->name, clkdm2->name); | ||
480 | |||
481 | ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2); | ||
482 | } | ||
483 | 587 | ||
484 | return ret; | 588 | return ret; |
485 | } | 589 | } |
@@ -497,30 +601,18 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | |||
497 | int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | 601 | int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) |
498 | { | 602 | { |
499 | struct clkdm_dep *cd; | 603 | struct clkdm_dep *cd; |
500 | int ret = 0; | 604 | int ret; |
501 | 605 | ||
502 | if (!clkdm1 || !clkdm2) | 606 | if (!clkdm1 || !clkdm2) |
503 | return -EINVAL; | 607 | return -EINVAL; |
504 | 608 | ||
505 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); | 609 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); |
506 | if (IS_ERR(cd)) | 610 | if (IS_ERR(cd)) |
507 | ret = PTR_ERR(cd); | 611 | return PTR_ERR(cd); |
508 | 612 | ||
509 | if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) | 613 | pwrdm_lock(cd->clkdm->pwrdm.ptr); |
510 | ret = -EINVAL; | 614 | ret = _clkdm_del_wkdep(clkdm1, clkdm2); |
511 | 615 | pwrdm_unlock(cd->clkdm->pwrdm.ptr); | |
512 | if (ret) { | ||
513 | pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", | ||
514 | clkdm1->name, clkdm2->name); | ||
515 | return ret; | ||
516 | } | ||
517 | |||
518 | if (atomic_dec_return(&cd->wkdep_usecount) == 0) { | ||
519 | pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", | ||
520 | clkdm1->name, clkdm2->name); | ||
521 | |||
522 | ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); | ||
523 | } | ||
524 | 616 | ||
525 | return ret; | 617 | return ret; |
526 | } | 618 | } |
@@ -560,7 +652,7 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | |||
560 | return ret; | 652 | return ret; |
561 | } | 653 | } |
562 | 654 | ||
563 | /* XXX It's faster to return the atomic wkdep_usecount */ | 655 | /* XXX It's faster to return the wkdep_usecount */ |
564 | return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2); | 656 | return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2); |
565 | } | 657 | } |
566 | 658 | ||
@@ -600,30 +692,18 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm) | |||
600 | int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | 692 | int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) |
601 | { | 693 | { |
602 | struct clkdm_dep *cd; | 694 | struct clkdm_dep *cd; |
603 | int ret = 0; | 695 | int ret; |
604 | 696 | ||
605 | if (!clkdm1 || !clkdm2) | 697 | if (!clkdm1 || !clkdm2) |
606 | return -EINVAL; | 698 | return -EINVAL; |
607 | 699 | ||
608 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); | 700 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); |
609 | if (IS_ERR(cd)) | 701 | if (IS_ERR(cd)) |
610 | ret = PTR_ERR(cd); | 702 | return PTR_ERR(cd); |
611 | 703 | ||
612 | if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) | 704 | pwrdm_lock(cd->clkdm->pwrdm.ptr); |
613 | ret = -EINVAL; | 705 | ret = _clkdm_add_sleepdep(clkdm1, clkdm2); |
614 | 706 | pwrdm_unlock(cd->clkdm->pwrdm.ptr); | |
615 | if (ret) { | ||
616 | pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", | ||
617 | clkdm1->name, clkdm2->name); | ||
618 | return ret; | ||
619 | } | ||
620 | |||
621 | if (atomic_inc_return(&cd->sleepdep_usecount) == 1) { | ||
622 | pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n", | ||
623 | clkdm1->name, clkdm2->name); | ||
624 | |||
625 | ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2); | ||
626 | } | ||
627 | 707 | ||
628 | return ret; | 708 | return ret; |
629 | } | 709 | } |
@@ -643,30 +723,18 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | |||
643 | int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | 723 | int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) |
644 | { | 724 | { |
645 | struct clkdm_dep *cd; | 725 | struct clkdm_dep *cd; |
646 | int ret = 0; | 726 | int ret; |
647 | 727 | ||
648 | if (!clkdm1 || !clkdm2) | 728 | if (!clkdm1 || !clkdm2) |
649 | return -EINVAL; | 729 | return -EINVAL; |
650 | 730 | ||
651 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); | 731 | cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); |
652 | if (IS_ERR(cd)) | 732 | if (IS_ERR(cd)) |
653 | ret = PTR_ERR(cd); | 733 | return PTR_ERR(cd); |
654 | 734 | ||
655 | if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) | 735 | pwrdm_lock(cd->clkdm->pwrdm.ptr); |
656 | ret = -EINVAL; | 736 | ret = _clkdm_del_sleepdep(clkdm1, clkdm2); |
657 | 737 | pwrdm_unlock(cd->clkdm->pwrdm.ptr); | |
658 | if (ret) { | ||
659 | pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", | ||
660 | clkdm1->name, clkdm2->name); | ||
661 | return ret; | ||
662 | } | ||
663 | |||
664 | if (atomic_dec_return(&cd->sleepdep_usecount) == 0) { | ||
665 | pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n", | ||
666 | clkdm1->name, clkdm2->name); | ||
667 | |||
668 | ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); | ||
669 | } | ||
670 | 738 | ||
671 | return ret; | 739 | return ret; |
672 | } | 740 | } |
@@ -708,7 +776,7 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) | |||
708 | return ret; | 776 | return ret; |
709 | } | 777 | } |
710 | 778 | ||
711 | /* XXX It's faster to return the atomic sleepdep_usecount */ | 779 | /* XXX It's faster to return the sleepdep_usecount */ |
712 | return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2); | 780 | return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2); |
713 | } | 781 | } |
714 | 782 | ||
@@ -734,18 +802,17 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) | |||
734 | } | 802 | } |
735 | 803 | ||
736 | /** | 804 | /** |
737 | * clkdm_sleep - force clockdomain sleep transition | 805 | * clkdm_sleep_nolock - force clockdomain sleep transition (lockless) |
738 | * @clkdm: struct clockdomain * | 806 | * @clkdm: struct clockdomain * |
739 | * | 807 | * |
740 | * Instruct the CM to force a sleep transition on the specified | 808 | * Instruct the CM to force a sleep transition on the specified |
741 | * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if | 809 | * clockdomain @clkdm. Only for use by the powerdomain code. Returns |
742 | * clockdomain does not support software-initiated sleep; 0 upon | 810 | * -EINVAL if @clkdm is NULL or if clockdomain does not support |
743 | * success. | 811 | * software-initiated sleep; 0 upon success. |
744 | */ | 812 | */ |
745 | int clkdm_sleep(struct clockdomain *clkdm) | 813 | int clkdm_sleep_nolock(struct clockdomain *clkdm) |
746 | { | 814 | { |
747 | int ret; | 815 | int ret; |
748 | unsigned long flags; | ||
749 | 816 | ||
750 | if (!clkdm) | 817 | if (!clkdm) |
751 | return -EINVAL; | 818 | return -EINVAL; |
@@ -761,26 +828,45 @@ int clkdm_sleep(struct clockdomain *clkdm) | |||
761 | 828 | ||
762 | pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); | 829 | pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); |
763 | 830 | ||
764 | spin_lock_irqsave(&clkdm->lock, flags); | ||
765 | clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; | 831 | clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; |
766 | ret = arch_clkdm->clkdm_sleep(clkdm); | 832 | ret = arch_clkdm->clkdm_sleep(clkdm); |
767 | spin_unlock_irqrestore(&clkdm->lock, flags); | 833 | ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
834 | |||
768 | return ret; | 835 | return ret; |
769 | } | 836 | } |
770 | 837 | ||
771 | /** | 838 | /** |
772 | * clkdm_wakeup - force clockdomain wakeup transition | 839 | * clkdm_sleep - force clockdomain sleep transition |
773 | * @clkdm: struct clockdomain * | 840 | * @clkdm: struct clockdomain * |
774 | * | 841 | * |
775 | * Instruct the CM to force a wakeup transition on the specified | 842 | * Instruct the CM to force a sleep transition on the specified |
776 | * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the | 843 | * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if |
777 | * clockdomain does not support software-controlled wakeup; 0 upon | 844 | * clockdomain does not support software-initiated sleep; 0 upon |
778 | * success. | 845 | * success. |
779 | */ | 846 | */ |
780 | int clkdm_wakeup(struct clockdomain *clkdm) | 847 | int clkdm_sleep(struct clockdomain *clkdm) |
848 | { | ||
849 | int ret; | ||
850 | |||
851 | pwrdm_lock(clkdm->pwrdm.ptr); | ||
852 | ret = clkdm_sleep_nolock(clkdm); | ||
853 | pwrdm_unlock(clkdm->pwrdm.ptr); | ||
854 | |||
855 | return ret; | ||
856 | } | ||
857 | |||
858 | /** | ||
859 | * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless) | ||
860 | * @clkdm: struct clockdomain * | ||
861 | * | ||
862 | * Instruct the CM to force a wakeup transition on the specified | ||
863 | * clockdomain @clkdm. Only for use by the powerdomain code. Returns | ||
864 | * -EINVAL if @clkdm is NULL or if the clockdomain does not support | ||
865 | * software-controlled wakeup; 0 upon success. | ||
866 | */ | ||
867 | int clkdm_wakeup_nolock(struct clockdomain *clkdm) | ||
781 | { | 868 | { |
782 | int ret; | 869 | int ret; |
783 | unsigned long flags; | ||
784 | 870 | ||
785 | if (!clkdm) | 871 | if (!clkdm) |
786 | return -EINVAL; | 872 | return -EINVAL; |
@@ -796,28 +882,46 @@ int clkdm_wakeup(struct clockdomain *clkdm) | |||
796 | 882 | ||
797 | pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); | 883 | pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); |
798 | 884 | ||
799 | spin_lock_irqsave(&clkdm->lock, flags); | ||
800 | clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; | 885 | clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; |
801 | ret = arch_clkdm->clkdm_wakeup(clkdm); | 886 | ret = arch_clkdm->clkdm_wakeup(clkdm); |
802 | ret |= pwrdm_state_switch(clkdm->pwrdm.ptr); | 887 | ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
803 | spin_unlock_irqrestore(&clkdm->lock, flags); | 888 | |
804 | return ret; | 889 | return ret; |
805 | } | 890 | } |
806 | 891 | ||
807 | /** | 892 | /** |
808 | * clkdm_allow_idle - enable hwsup idle transitions for clkdm | 893 | * clkdm_wakeup - force clockdomain wakeup transition |
809 | * @clkdm: struct clockdomain * | 894 | * @clkdm: struct clockdomain * |
810 | * | 895 | * |
811 | * Allow the hardware to automatically switch the clockdomain @clkdm into | 896 | * Instruct the CM to force a wakeup transition on the specified |
812 | * active or idle states, as needed by downstream clocks. If the | 897 | * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the |
898 | * clockdomain does not support software-controlled wakeup; 0 upon | ||
899 | * success. | ||
900 | */ | ||
901 | int clkdm_wakeup(struct clockdomain *clkdm) | ||
902 | { | ||
903 | int ret; | ||
904 | |||
905 | pwrdm_lock(clkdm->pwrdm.ptr); | ||
906 | ret = clkdm_wakeup_nolock(clkdm); | ||
907 | pwrdm_unlock(clkdm->pwrdm.ptr); | ||
908 | |||
909 | return ret; | ||
910 | } | ||
911 | |||
912 | /** | ||
913 | * clkdm_allow_idle_nolock - enable hwsup idle transitions for clkdm | ||
914 | * @clkdm: struct clockdomain * | ||
915 | * | ||
916 | * Allow the hardware to automatically switch the clockdomain @clkdm | ||
917 | * into active or idle states, as needed by downstream clocks. If the | ||
813 | * clockdomain has any downstream clocks enabled in the clock | 918 | * clockdomain has any downstream clocks enabled in the clock |
814 | * framework, wkdep/sleepdep autodependencies are added; this is so | 919 | * framework, wkdep/sleepdep autodependencies are added; this is so |
815 | * device drivers can read and write to the device. No return value. | 920 | * device drivers can read and write to the device. Only for use by |
921 | * the powerdomain code. No return value. | ||
816 | */ | 922 | */ |
817 | void clkdm_allow_idle(struct clockdomain *clkdm) | 923 | void clkdm_allow_idle_nolock(struct clockdomain *clkdm) |
818 | { | 924 | { |
819 | unsigned long flags; | ||
820 | |||
821 | if (!clkdm) | 925 | if (!clkdm) |
822 | return; | 926 | return; |
823 | 927 | ||
@@ -833,11 +937,26 @@ void clkdm_allow_idle(struct clockdomain *clkdm) | |||
833 | pr_debug("clockdomain: enabling automatic idle transitions for %s\n", | 937 | pr_debug("clockdomain: enabling automatic idle transitions for %s\n", |
834 | clkdm->name); | 938 | clkdm->name); |
835 | 939 | ||
836 | spin_lock_irqsave(&clkdm->lock, flags); | ||
837 | clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; | 940 | clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; |
838 | arch_clkdm->clkdm_allow_idle(clkdm); | 941 | arch_clkdm->clkdm_allow_idle(clkdm); |
839 | pwrdm_state_switch(clkdm->pwrdm.ptr); | 942 | pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
840 | spin_unlock_irqrestore(&clkdm->lock, flags); | 943 | } |
944 | |||
945 | /** | ||
946 | * clkdm_allow_idle - enable hwsup idle transitions for clkdm | ||
947 | * @clkdm: struct clockdomain * | ||
948 | * | ||
949 | * Allow the hardware to automatically switch the clockdomain @clkdm into | ||
950 | * active or idle states, as needed by downstream clocks. If the | ||
951 | * clockdomain has any downstream clocks enabled in the clock | ||
952 | * framework, wkdep/sleepdep autodependencies are added; this is so | ||
953 | * device drivers can read and write to the device. No return value. | ||
954 | */ | ||
955 | void clkdm_allow_idle(struct clockdomain *clkdm) | ||
956 | { | ||
957 | pwrdm_lock(clkdm->pwrdm.ptr); | ||
958 | clkdm_allow_idle_nolock(clkdm); | ||
959 | pwrdm_unlock(clkdm->pwrdm.ptr); | ||
841 | } | 960 | } |
842 | 961 | ||
843 | /** | 962 | /** |
@@ -847,12 +966,11 @@ void clkdm_allow_idle(struct clockdomain *clkdm) | |||
847 | * Prevent the hardware from automatically switching the clockdomain | 966 | * Prevent the hardware from automatically switching the clockdomain |
848 | * @clkdm into inactive or idle states. If the clockdomain has | 967 | * @clkdm into inactive or idle states. If the clockdomain has |
849 | * downstream clocks enabled in the clock framework, wkdep/sleepdep | 968 | * downstream clocks enabled in the clock framework, wkdep/sleepdep |
850 | * autodependencies are removed. No return value. | 969 | * autodependencies are removed. Only for use by the powerdomain |
970 | * code. No return value. | ||
851 | */ | 971 | */ |
852 | void clkdm_deny_idle(struct clockdomain *clkdm) | 972 | void clkdm_deny_idle_nolock(struct clockdomain *clkdm) |
853 | { | 973 | { |
854 | unsigned long flags; | ||
855 | |||
856 | if (!clkdm) | 974 | if (!clkdm) |
857 | return; | 975 | return; |
858 | 976 | ||
@@ -868,11 +986,25 @@ void clkdm_deny_idle(struct clockdomain *clkdm) | |||
868 | pr_debug("clockdomain: disabling automatic idle transitions for %s\n", | 986 | pr_debug("clockdomain: disabling automatic idle transitions for %s\n", |
869 | clkdm->name); | 987 | clkdm->name); |
870 | 988 | ||
871 | spin_lock_irqsave(&clkdm->lock, flags); | ||
872 | clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; | 989 | clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; |
873 | arch_clkdm->clkdm_deny_idle(clkdm); | 990 | arch_clkdm->clkdm_deny_idle(clkdm); |
874 | pwrdm_state_switch(clkdm->pwrdm.ptr); | 991 | pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
875 | spin_unlock_irqrestore(&clkdm->lock, flags); | 992 | } |
993 | |||
994 | /** | ||
995 | * clkdm_deny_idle - disable hwsup idle transitions for clkdm | ||
996 | * @clkdm: struct clockdomain * | ||
997 | * | ||
998 | * Prevent the hardware from automatically switching the clockdomain | ||
999 | * @clkdm into inactive or idle states. If the clockdomain has | ||
1000 | * downstream clocks enabled in the clock framework, wkdep/sleepdep | ||
1001 | * autodependencies are removed. No return value. | ||
1002 | */ | ||
1003 | void clkdm_deny_idle(struct clockdomain *clkdm) | ||
1004 | { | ||
1005 | pwrdm_lock(clkdm->pwrdm.ptr); | ||
1006 | clkdm_deny_idle_nolock(clkdm); | ||
1007 | pwrdm_unlock(clkdm->pwrdm.ptr); | ||
876 | } | 1008 | } |
877 | 1009 | ||
878 | /** | 1010 | /** |
@@ -889,14 +1021,11 @@ void clkdm_deny_idle(struct clockdomain *clkdm) | |||
889 | bool clkdm_in_hwsup(struct clockdomain *clkdm) | 1021 | bool clkdm_in_hwsup(struct clockdomain *clkdm) |
890 | { | 1022 | { |
891 | bool ret; | 1023 | bool ret; |
892 | unsigned long flags; | ||
893 | 1024 | ||
894 | if (!clkdm) | 1025 | if (!clkdm) |
895 | return false; | 1026 | return false; |
896 | 1027 | ||
897 | spin_lock_irqsave(&clkdm->lock, flags); | ||
898 | ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; | 1028 | ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; |
899 | spin_unlock_irqrestore(&clkdm->lock, flags); | ||
900 | 1029 | ||
901 | return ret; | 1030 | return ret; |
902 | } | 1031 | } |
@@ -918,30 +1047,91 @@ bool clkdm_missing_idle_reporting(struct clockdomain *clkdm) | |||
918 | return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false; | 1047 | return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false; |
919 | } | 1048 | } |
920 | 1049 | ||
1050 | /* Public autodep handling functions (deprecated) */ | ||
1051 | |||
1052 | /** | ||
1053 | * clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable | ||
1054 | * @clkdm: struct clockdomain * | ||
1055 | * | ||
1056 | * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' | ||
1057 | * in hardware-supervised mode. Meant to be called from clock framework | ||
1058 | * when a clock inside clockdomain 'clkdm' is enabled. No return value. | ||
1059 | * | ||
1060 | * XXX autodeps are deprecated and should be removed at the earliest | ||
1061 | * opportunity | ||
1062 | */ | ||
1063 | void clkdm_add_autodeps(struct clockdomain *clkdm) | ||
1064 | { | ||
1065 | struct clkdm_autodep *autodep; | ||
1066 | |||
1067 | if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) | ||
1068 | return; | ||
1069 | |||
1070 | for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { | ||
1071 | if (IS_ERR(autodep->clkdm.ptr)) | ||
1072 | continue; | ||
1073 | |||
1074 | pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", | ||
1075 | clkdm->name, autodep->clkdm.ptr->name); | ||
1076 | |||
1077 | _clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); | ||
1078 | _clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); | ||
1079 | } | ||
1080 | } | ||
1081 | |||
1082 | /** | ||
1083 | * clkdm_del_autodeps - remove auto sleepdeps/wkdeps from clkdm | ||
1084 | * @clkdm: struct clockdomain * | ||
1085 | * | ||
1086 | * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' | ||
1087 | * in hardware-supervised mode. Meant to be called from clock framework | ||
1088 | * when a clock inside clockdomain 'clkdm' is disabled. No return value. | ||
1089 | * | ||
1090 | * XXX autodeps are deprecated and should be removed at the earliest | ||
1091 | * opportunity | ||
1092 | */ | ||
1093 | void clkdm_del_autodeps(struct clockdomain *clkdm) | ||
1094 | { | ||
1095 | struct clkdm_autodep *autodep; | ||
1096 | |||
1097 | if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) | ||
1098 | return; | ||
1099 | |||
1100 | for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { | ||
1101 | if (IS_ERR(autodep->clkdm.ptr)) | ||
1102 | continue; | ||
1103 | |||
1104 | pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", | ||
1105 | clkdm->name, autodep->clkdm.ptr->name); | ||
1106 | |||
1107 | _clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); | ||
1108 | _clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); | ||
1109 | } | ||
1110 | } | ||
1111 | |||
921 | /* Clockdomain-to-clock/hwmod framework interface code */ | 1112 | /* Clockdomain-to-clock/hwmod framework interface code */ |
922 | 1113 | ||
923 | static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) | 1114 | static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) |
924 | { | 1115 | { |
925 | unsigned long flags; | ||
926 | |||
927 | if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) | 1116 | if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) |
928 | return -EINVAL; | 1117 | return -EINVAL; |
929 | 1118 | ||
930 | spin_lock_irqsave(&clkdm->lock, flags); | 1119 | pwrdm_lock(clkdm->pwrdm.ptr); |
931 | 1120 | ||
932 | /* | 1121 | /* |
933 | * For arch's with no autodeps, clkcm_clk_enable | 1122 | * For arch's with no autodeps, clkcm_clk_enable |
934 | * should be called for every clock instance or hwmod that is | 1123 | * should be called for every clock instance or hwmod that is |
935 | * enabled, so the clkdm can be force woken up. | 1124 | * enabled, so the clkdm can be force woken up. |
936 | */ | 1125 | */ |
937 | if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) { | 1126 | clkdm->usecount++; |
938 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1127 | if (clkdm->usecount > 1 && autodeps) { |
1128 | pwrdm_unlock(clkdm->pwrdm.ptr); | ||
939 | return 0; | 1129 | return 0; |
940 | } | 1130 | } |
941 | 1131 | ||
942 | arch_clkdm->clkdm_clk_enable(clkdm); | 1132 | arch_clkdm->clkdm_clk_enable(clkdm); |
943 | pwrdm_state_switch(clkdm->pwrdm.ptr); | 1133 | pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
944 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1134 | pwrdm_unlock(clkdm->pwrdm.ptr); |
945 | 1135 | ||
946 | pr_debug("clockdomain: %s: enabled\n", clkdm->name); | 1136 | pr_debug("clockdomain: %s: enabled\n", clkdm->name); |
947 | 1137 | ||
@@ -990,36 +1180,34 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) | |||
990 | */ | 1180 | */ |
991 | int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) | 1181 | int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) |
992 | { | 1182 | { |
993 | unsigned long flags; | ||
994 | |||
995 | if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) | 1183 | if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) |
996 | return -EINVAL; | 1184 | return -EINVAL; |
997 | 1185 | ||
998 | spin_lock_irqsave(&clkdm->lock, flags); | 1186 | pwrdm_lock(clkdm->pwrdm.ptr); |
999 | 1187 | ||
1000 | /* corner case: disabling unused clocks */ | 1188 | /* corner case: disabling unused clocks */ |
1001 | if ((__clk_get_enable_count(clk) == 0) && | 1189 | if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0) |
1002 | (atomic_read(&clkdm->usecount) == 0)) | ||
1003 | goto ccd_exit; | 1190 | goto ccd_exit; |
1004 | 1191 | ||
1005 | if (atomic_read(&clkdm->usecount) == 0) { | 1192 | if (clkdm->usecount == 0) { |
1006 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1193 | pwrdm_unlock(clkdm->pwrdm.ptr); |
1007 | WARN_ON(1); /* underflow */ | 1194 | WARN_ON(1); /* underflow */ |
1008 | return -ERANGE; | 1195 | return -ERANGE; |
1009 | } | 1196 | } |
1010 | 1197 | ||
1011 | if (atomic_dec_return(&clkdm->usecount) > 0) { | 1198 | clkdm->usecount--; |
1012 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1199 | if (clkdm->usecount > 0) { |
1200 | pwrdm_unlock(clkdm->pwrdm.ptr); | ||
1013 | return 0; | 1201 | return 0; |
1014 | } | 1202 | } |
1015 | 1203 | ||
1016 | arch_clkdm->clkdm_clk_disable(clkdm); | 1204 | arch_clkdm->clkdm_clk_disable(clkdm); |
1017 | pwrdm_state_switch(clkdm->pwrdm.ptr); | 1205 | pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
1018 | 1206 | ||
1019 | pr_debug("clockdomain: %s: disabled\n", clkdm->name); | 1207 | pr_debug("clockdomain: %s: disabled\n", clkdm->name); |
1020 | 1208 | ||
1021 | ccd_exit: | 1209 | ccd_exit: |
1022 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1210 | pwrdm_unlock(clkdm->pwrdm.ptr); |
1023 | 1211 | ||
1024 | return 0; | 1212 | return 0; |
1025 | } | 1213 | } |
@@ -1072,8 +1260,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh) | |||
1072 | */ | 1260 | */ |
1073 | int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) | 1261 | int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) |
1074 | { | 1262 | { |
1075 | unsigned long flags; | ||
1076 | |||
1077 | /* The clkdm attribute does not exist yet prior OMAP4 */ | 1263 | /* The clkdm attribute does not exist yet prior OMAP4 */ |
1078 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | 1264 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) |
1079 | return 0; | 1265 | return 0; |
@@ -1086,22 +1272,23 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) | |||
1086 | if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) | 1272 | if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) |
1087 | return -EINVAL; | 1273 | return -EINVAL; |
1088 | 1274 | ||
1089 | spin_lock_irqsave(&clkdm->lock, flags); | 1275 | pwrdm_lock(clkdm->pwrdm.ptr); |
1090 | 1276 | ||
1091 | if (atomic_read(&clkdm->usecount) == 0) { | 1277 | if (clkdm->usecount == 0) { |
1092 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1278 | pwrdm_unlock(clkdm->pwrdm.ptr); |
1093 | WARN_ON(1); /* underflow */ | 1279 | WARN_ON(1); /* underflow */ |
1094 | return -ERANGE; | 1280 | return -ERANGE; |
1095 | } | 1281 | } |
1096 | 1282 | ||
1097 | if (atomic_dec_return(&clkdm->usecount) > 0) { | 1283 | clkdm->usecount--; |
1098 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1284 | if (clkdm->usecount > 0) { |
1285 | pwrdm_unlock(clkdm->pwrdm.ptr); | ||
1099 | return 0; | 1286 | return 0; |
1100 | } | 1287 | } |
1101 | 1288 | ||
1102 | arch_clkdm->clkdm_clk_disable(clkdm); | 1289 | arch_clkdm->clkdm_clk_disable(clkdm); |
1103 | pwrdm_state_switch(clkdm->pwrdm.ptr); | 1290 | pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
1104 | spin_unlock_irqrestore(&clkdm->lock, flags); | 1291 | pwrdm_unlock(clkdm->pwrdm.ptr); |
1105 | 1292 | ||
1106 | pr_debug("clockdomain: %s: disabled\n", clkdm->name); | 1293 | pr_debug("clockdomain: %s: disabled\n", clkdm->name); |
1107 | 1294 | ||
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index bc42446e23ab..2da37656a693 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h | |||
@@ -15,7 +15,6 @@ | |||
15 | #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H | 15 | #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H |
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/spinlock.h> | ||
19 | 18 | ||
20 | #include "powerdomain.h" | 19 | #include "powerdomain.h" |
21 | #include "clock.h" | 20 | #include "clock.h" |
@@ -92,8 +91,8 @@ struct clkdm_autodep { | |||
92 | struct clkdm_dep { | 91 | struct clkdm_dep { |
93 | const char *clkdm_name; | 92 | const char *clkdm_name; |
94 | struct clockdomain *clkdm; | 93 | struct clockdomain *clkdm; |
95 | atomic_t wkdep_usecount; | 94 | s16 wkdep_usecount; |
96 | atomic_t sleepdep_usecount; | 95 | s16 sleepdep_usecount; |
97 | }; | 96 | }; |
98 | 97 | ||
99 | /* Possible flags for struct clockdomain._flags */ | 98 | /* Possible flags for struct clockdomain._flags */ |
@@ -137,9 +136,8 @@ struct clockdomain { | |||
137 | const u16 clkdm_offs; | 136 | const u16 clkdm_offs; |
138 | struct clkdm_dep *wkdep_srcs; | 137 | struct clkdm_dep *wkdep_srcs; |
139 | struct clkdm_dep *sleepdep_srcs; | 138 | struct clkdm_dep *sleepdep_srcs; |
140 | atomic_t usecount; | 139 | int usecount; |
141 | struct list_head node; | 140 | struct list_head node; |
142 | spinlock_t lock; | ||
143 | }; | 141 | }; |
144 | 142 | ||
145 | /** | 143 | /** |
@@ -196,12 +194,16 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); | |||
196 | int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); | 194 | int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); |
197 | int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); | 195 | int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); |
198 | 196 | ||
197 | void clkdm_allow_idle_nolock(struct clockdomain *clkdm); | ||
199 | void clkdm_allow_idle(struct clockdomain *clkdm); | 198 | void clkdm_allow_idle(struct clockdomain *clkdm); |
199 | void clkdm_deny_idle_nolock(struct clockdomain *clkdm); | ||
200 | void clkdm_deny_idle(struct clockdomain *clkdm); | 200 | void clkdm_deny_idle(struct clockdomain *clkdm); |
201 | bool clkdm_in_hwsup(struct clockdomain *clkdm); | 201 | bool clkdm_in_hwsup(struct clockdomain *clkdm); |
202 | bool clkdm_missing_idle_reporting(struct clockdomain *clkdm); | 202 | bool clkdm_missing_idle_reporting(struct clockdomain *clkdm); |
203 | 203 | ||
204 | int clkdm_wakeup_nolock(struct clockdomain *clkdm); | ||
204 | int clkdm_wakeup(struct clockdomain *clkdm); | 205 | int clkdm_wakeup(struct clockdomain *clkdm); |
206 | int clkdm_sleep_nolock(struct clockdomain *clkdm); | ||
205 | int clkdm_sleep(struct clockdomain *clkdm); | 207 | int clkdm_sleep(struct clockdomain *clkdm); |
206 | 208 | ||
207 | int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); | 209 | int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); |
@@ -214,8 +216,9 @@ extern void __init omap243x_clockdomains_init(void); | |||
214 | extern void __init omap3xxx_clockdomains_init(void); | 216 | extern void __init omap3xxx_clockdomains_init(void); |
215 | extern void __init am33xx_clockdomains_init(void); | 217 | extern void __init am33xx_clockdomains_init(void); |
216 | extern void __init omap44xx_clockdomains_init(void); | 218 | extern void __init omap44xx_clockdomains_init(void); |
217 | extern void _clkdm_add_autodeps(struct clockdomain *clkdm); | 219 | |
218 | extern void _clkdm_del_autodeps(struct clockdomain *clkdm); | 220 | extern void clkdm_add_autodeps(struct clockdomain *clkdm); |
221 | extern void clkdm_del_autodeps(struct clockdomain *clkdm); | ||
219 | 222 | ||
220 | extern struct clkdm_ops omap2_clkdm_operations; | 223 | extern struct clkdm_ops omap2_clkdm_operations; |
221 | extern struct clkdm_ops omap3_clkdm_operations; | 224 | extern struct clkdm_ops omap3_clkdm_operations; |
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index db650690e9d0..6774a53a3874 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c | |||
@@ -273,9 +273,6 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | |||
273 | 273 | ||
274 | static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm) | 274 | static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm) |
275 | { | 275 | { |
276 | if (atomic_read(&clkdm->usecount) > 0) | ||
277 | _clkdm_add_autodeps(clkdm); | ||
278 | |||
279 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 276 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
280 | clkdm->clktrctrl_mask); | 277 | clkdm->clktrctrl_mask); |
281 | } | 278 | } |
@@ -284,9 +281,6 @@ static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm) | |||
284 | { | 281 | { |
285 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 282 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
286 | clkdm->clktrctrl_mask); | 283 | clkdm->clktrctrl_mask); |
287 | |||
288 | if (atomic_read(&clkdm->usecount) > 0) | ||
289 | _clkdm_del_autodeps(clkdm); | ||
290 | } | 284 | } |
291 | 285 | ||
292 | static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) | 286 | static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) |
@@ -298,18 +292,8 @@ static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) | |||
298 | 292 | ||
299 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 293 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
300 | clkdm->clktrctrl_mask); | 294 | clkdm->clktrctrl_mask); |
301 | 295 | if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | |
302 | if (hwsup) { | 296 | omap2xxx_clkdm_wakeup(clkdm); |
303 | /* Disable HW transitions when we are changing deps */ | ||
304 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
305 | clkdm->clktrctrl_mask); | ||
306 | _clkdm_add_autodeps(clkdm); | ||
307 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
308 | clkdm->clktrctrl_mask); | ||
309 | } else { | ||
310 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | ||
311 | omap2xxx_clkdm_wakeup(clkdm); | ||
312 | } | ||
313 | 297 | ||
314 | return 0; | 298 | return 0; |
315 | } | 299 | } |
@@ -324,17 +308,8 @@ static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm) | |||
324 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 308 | hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
325 | clkdm->clktrctrl_mask); | 309 | clkdm->clktrctrl_mask); |
326 | 310 | ||
327 | if (hwsup) { | 311 | if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_SLEEP) |
328 | /* Disable HW transitions when we are changing deps */ | 312 | omap2xxx_clkdm_sleep(clkdm); |
329 | omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
330 | clkdm->clktrctrl_mask); | ||
331 | _clkdm_del_autodeps(clkdm); | ||
332 | omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | ||
333 | clkdm->clktrctrl_mask); | ||
334 | } else { | ||
335 | if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) | ||
336 | omap2xxx_clkdm_sleep(clkdm); | ||
337 | } | ||
338 | 313 | ||
339 | return 0; | 314 | return 0; |
340 | } | 315 | } |
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index c2086f2e86b6..9061c307d915 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c | |||
@@ -186,7 +186,7 @@ static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) | |||
186 | continue; /* only happens if data is erroneous */ | 186 | continue; /* only happens if data is erroneous */ |
187 | 187 | ||
188 | mask |= 1 << cd->clkdm->dep_bit; | 188 | mask |= 1 << cd->clkdm->dep_bit; |
189 | atomic_set(&cd->sleepdep_usecount, 0); | 189 | cd->sleepdep_usecount = 0; |
190 | } | 190 | } |
191 | omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, | 191 | omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, |
192 | OMAP3430_CM_SLEEPDEP); | 192 | OMAP3430_CM_SLEEPDEP); |
@@ -209,8 +209,8 @@ static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm) | |||
209 | 209 | ||
210 | static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm) | 210 | static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm) |
211 | { | 211 | { |
212 | if (atomic_read(&clkdm->usecount) > 0) | 212 | if (clkdm->usecount > 0) |
213 | _clkdm_add_autodeps(clkdm); | 213 | clkdm_add_autodeps(clkdm); |
214 | 214 | ||
215 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 215 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
216 | clkdm->clktrctrl_mask); | 216 | clkdm->clktrctrl_mask); |
@@ -221,8 +221,8 @@ static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm) | |||
221 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 221 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
222 | clkdm->clktrctrl_mask); | 222 | clkdm->clktrctrl_mask); |
223 | 223 | ||
224 | if (atomic_read(&clkdm->usecount) > 0) | 224 | if (clkdm->usecount > 0) |
225 | _clkdm_del_autodeps(clkdm); | 225 | clkdm_del_autodeps(clkdm); |
226 | } | 226 | } |
227 | 227 | ||
228 | static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) | 228 | static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) |
@@ -250,7 +250,7 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) | |||
250 | /* Disable HW transitions when we are changing deps */ | 250 | /* Disable HW transitions when we are changing deps */ |
251 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 251 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
252 | clkdm->clktrctrl_mask); | 252 | clkdm->clktrctrl_mask); |
253 | _clkdm_add_autodeps(clkdm); | 253 | clkdm_add_autodeps(clkdm); |
254 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 254 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
255 | clkdm->clktrctrl_mask); | 255 | clkdm->clktrctrl_mask); |
256 | } else { | 256 | } else { |
@@ -287,7 +287,7 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) | |||
287 | /* Disable HW transitions when we are changing deps */ | 287 | /* Disable HW transitions when we are changing deps */ |
288 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 288 | omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
289 | clkdm->clktrctrl_mask); | 289 | clkdm->clktrctrl_mask); |
290 | _clkdm_del_autodeps(clkdm); | 290 | clkdm_del_autodeps(clkdm); |
291 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, | 291 | omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, |
292 | clkdm->clktrctrl_mask); | 292 | clkdm->clktrctrl_mask); |
293 | } else { | 293 | } else { |
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 7f9a464f01e9..f0290f5566fe 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c | |||
@@ -393,7 +393,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) | |||
393 | continue; /* only happens if data is erroneous */ | 393 | continue; /* only happens if data is erroneous */ |
394 | 394 | ||
395 | mask |= 1 << cd->clkdm->dep_bit; | 395 | mask |= 1 << cd->clkdm->dep_bit; |
396 | atomic_set(&cd->wkdep_usecount, 0); | 396 | cd->wkdep_usecount = 0; |
397 | } | 397 | } |
398 | 398 | ||
399 | omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, | 399 | omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, |
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 22590dbe8f14..80392fca86c6 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c | |||
@@ -36,40 +36,66 @@ | |||
36 | 36 | ||
37 | /* Mach specific information to be recorded in the C-state driver_data */ | 37 | /* Mach specific information to be recorded in the C-state driver_data */ |
38 | struct omap3_idle_statedata { | 38 | struct omap3_idle_statedata { |
39 | u32 mpu_state; | 39 | u8 mpu_state; |
40 | u32 core_state; | 40 | u8 core_state; |
41 | u8 per_min_state; | ||
42 | u8 flags; | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; | 45 | static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; |
44 | 46 | ||
47 | /* | ||
48 | * Possible flag bits for struct omap3_idle_statedata.flags: | ||
49 | * | ||
50 | * OMAP_CPUIDLE_CX_NO_CLKDM_IDLE: don't allow the MPU clockdomain to go | ||
51 | * inactive. This in turn prevents the MPU DPLL from entering autoidle | ||
52 | * mode, so wakeup latency is greatly reduced, at the cost of additional | ||
53 | * energy consumption. This also prevents the CORE clockdomain from | ||
54 | * entering idle. | ||
55 | */ | ||
56 | #define OMAP_CPUIDLE_CX_NO_CLKDM_IDLE BIT(0) | ||
57 | |||
58 | /* | ||
59 | * Prevent PER OFF if CORE is not in RETention or OFF as this would | ||
60 | * disable PER wakeups completely. | ||
61 | */ | ||
45 | static struct omap3_idle_statedata omap3_idle_data[] = { | 62 | static struct omap3_idle_statedata omap3_idle_data[] = { |
46 | { | 63 | { |
47 | .mpu_state = PWRDM_POWER_ON, | 64 | .mpu_state = PWRDM_POWER_ON, |
48 | .core_state = PWRDM_POWER_ON, | 65 | .core_state = PWRDM_POWER_ON, |
66 | /* In C1 do not allow PER state lower than CORE state */ | ||
67 | .per_min_state = PWRDM_POWER_ON, | ||
68 | .flags = OMAP_CPUIDLE_CX_NO_CLKDM_IDLE, | ||
49 | }, | 69 | }, |
50 | { | 70 | { |
51 | .mpu_state = PWRDM_POWER_ON, | 71 | .mpu_state = PWRDM_POWER_ON, |
52 | .core_state = PWRDM_POWER_ON, | 72 | .core_state = PWRDM_POWER_ON, |
73 | .per_min_state = PWRDM_POWER_RET, | ||
53 | }, | 74 | }, |
54 | { | 75 | { |
55 | .mpu_state = PWRDM_POWER_RET, | 76 | .mpu_state = PWRDM_POWER_RET, |
56 | .core_state = PWRDM_POWER_ON, | 77 | .core_state = PWRDM_POWER_ON, |
78 | .per_min_state = PWRDM_POWER_RET, | ||
57 | }, | 79 | }, |
58 | { | 80 | { |
59 | .mpu_state = PWRDM_POWER_OFF, | 81 | .mpu_state = PWRDM_POWER_OFF, |
60 | .core_state = PWRDM_POWER_ON, | 82 | .core_state = PWRDM_POWER_ON, |
83 | .per_min_state = PWRDM_POWER_RET, | ||
61 | }, | 84 | }, |
62 | { | 85 | { |
63 | .mpu_state = PWRDM_POWER_RET, | 86 | .mpu_state = PWRDM_POWER_RET, |
64 | .core_state = PWRDM_POWER_RET, | 87 | .core_state = PWRDM_POWER_RET, |
88 | .per_min_state = PWRDM_POWER_OFF, | ||
65 | }, | 89 | }, |
66 | { | 90 | { |
67 | .mpu_state = PWRDM_POWER_OFF, | 91 | .mpu_state = PWRDM_POWER_OFF, |
68 | .core_state = PWRDM_POWER_RET, | 92 | .core_state = PWRDM_POWER_RET, |
93 | .per_min_state = PWRDM_POWER_OFF, | ||
69 | }, | 94 | }, |
70 | { | 95 | { |
71 | .mpu_state = PWRDM_POWER_OFF, | 96 | .mpu_state = PWRDM_POWER_OFF, |
72 | .core_state = PWRDM_POWER_OFF, | 97 | .core_state = PWRDM_POWER_OFF, |
98 | .per_min_state = PWRDM_POWER_OFF, | ||
73 | }, | 99 | }, |
74 | }; | 100 | }; |
75 | 101 | ||
@@ -80,27 +106,25 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, | |||
80 | int index) | 106 | int index) |
81 | { | 107 | { |
82 | struct omap3_idle_statedata *cx = &omap3_idle_data[index]; | 108 | struct omap3_idle_statedata *cx = &omap3_idle_data[index]; |
83 | u32 mpu_state = cx->mpu_state, core_state = cx->core_state; | ||
84 | 109 | ||
85 | local_fiq_disable(); | 110 | local_fiq_disable(); |
86 | 111 | ||
87 | pwrdm_set_next_pwrst(mpu_pd, mpu_state); | ||
88 | pwrdm_set_next_pwrst(core_pd, core_state); | ||
89 | |||
90 | if (omap_irq_pending() || need_resched()) | 112 | if (omap_irq_pending() || need_resched()) |
91 | goto return_sleep_time; | 113 | goto return_sleep_time; |
92 | 114 | ||
93 | /* Deny idle for C1 */ | 115 | /* Deny idle for C1 */ |
94 | if (index == 0) { | 116 | if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) { |
95 | clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); | 117 | clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); |
96 | clkdm_deny_idle(core_pd->pwrdm_clkdms[0]); | 118 | } else { |
119 | pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); | ||
120 | pwrdm_set_next_pwrst(core_pd, cx->core_state); | ||
97 | } | 121 | } |
98 | 122 | ||
99 | /* | 123 | /* |
100 | * Call idle CPU PM enter notifier chain so that | 124 | * Call idle CPU PM enter notifier chain so that |
101 | * VFP context is saved. | 125 | * VFP context is saved. |
102 | */ | 126 | */ |
103 | if (mpu_state == PWRDM_POWER_OFF) | 127 | if (cx->mpu_state == PWRDM_POWER_OFF) |
104 | cpu_pm_enter(); | 128 | cpu_pm_enter(); |
105 | 129 | ||
106 | /* Execute ARM wfi */ | 130 | /* Execute ARM wfi */ |
@@ -110,17 +134,15 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, | |||
110 | * Call idle CPU PM enter notifier chain to restore | 134 | * Call idle CPU PM enter notifier chain to restore |
111 | * VFP context. | 135 | * VFP context. |
112 | */ | 136 | */ |
113 | if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) | 137 | if (cx->mpu_state == PWRDM_POWER_OFF && |
138 | pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) | ||
114 | cpu_pm_exit(); | 139 | cpu_pm_exit(); |
115 | 140 | ||
116 | /* Re-allow idle for C1 */ | 141 | /* Re-allow idle for C1 */ |
117 | if (index == 0) { | 142 | if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) |
118 | clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); | 143 | clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); |
119 | clkdm_allow_idle(core_pd->pwrdm_clkdms[0]); | ||
120 | } | ||
121 | 144 | ||
122 | return_sleep_time: | 145 | return_sleep_time: |
123 | |||
124 | local_fiq_enable(); | 146 | local_fiq_enable(); |
125 | 147 | ||
126 | return index; | 148 | return index; |
@@ -185,7 +207,7 @@ static int next_valid_state(struct cpuidle_device *dev, | |||
185 | * Start search from the next (lower) state. | 207 | * Start search from the next (lower) state. |
186 | */ | 208 | */ |
187 | for (idx = index - 1; idx >= 0; idx--) { | 209 | for (idx = index - 1; idx >= 0; idx--) { |
188 | cx = &omap3_idle_data[idx]; | 210 | cx = &omap3_idle_data[idx]; |
189 | if ((cx->mpu_state >= mpu_deepest_state) && | 211 | if ((cx->mpu_state >= mpu_deepest_state) && |
190 | (cx->core_state >= core_deepest_state)) { | 212 | (cx->core_state >= core_deepest_state)) { |
191 | next_index = idx; | 213 | next_index = idx; |
@@ -209,10 +231,9 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
209 | struct cpuidle_driver *drv, | 231 | struct cpuidle_driver *drv, |
210 | int index) | 232 | int index) |
211 | { | 233 | { |
212 | int new_state_idx; | 234 | int new_state_idx, ret; |
213 | u32 core_next_state, per_next_state = 0, per_saved_state = 0; | 235 | u8 per_next_state, per_saved_state; |
214 | struct omap3_idle_statedata *cx; | 236 | struct omap3_idle_statedata *cx; |
215 | int ret; | ||
216 | 237 | ||
217 | /* | 238 | /* |
218 | * Use only C1 if CAM is active. | 239 | * Use only C1 if CAM is active. |
@@ -233,25 +254,13 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
233 | 254 | ||
234 | /* Program PER state */ | 255 | /* Program PER state */ |
235 | cx = &omap3_idle_data[new_state_idx]; | 256 | cx = &omap3_idle_data[new_state_idx]; |
236 | core_next_state = cx->core_state; | ||
237 | per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); | ||
238 | if (new_state_idx == 0) { | ||
239 | /* In C1 do not allow PER state lower than CORE state */ | ||
240 | if (per_next_state < core_next_state) | ||
241 | per_next_state = core_next_state; | ||
242 | } else { | ||
243 | /* | ||
244 | * Prevent PER OFF if CORE is not in RETention or OFF as this | ||
245 | * would disable PER wakeups completely. | ||
246 | */ | ||
247 | if ((per_next_state == PWRDM_POWER_OFF) && | ||
248 | (core_next_state > PWRDM_POWER_RET)) | ||
249 | per_next_state = PWRDM_POWER_RET; | ||
250 | } | ||
251 | 257 | ||
252 | /* Are we changing PER target state? */ | 258 | per_next_state = pwrdm_read_next_pwrst(per_pd); |
253 | if (per_next_state != per_saved_state) | 259 | per_saved_state = per_next_state; |
260 | if (per_next_state < cx->per_min_state) { | ||
261 | per_next_state = cx->per_min_state; | ||
254 | pwrdm_set_next_pwrst(per_pd, per_next_state); | 262 | pwrdm_set_next_pwrst(per_pd, per_next_state); |
263 | } | ||
255 | 264 | ||
256 | ret = omap3_enter_idle(dev, drv, new_state_idx); | 265 | ret = omap3_enter_idle(dev, drv, new_state_idx); |
257 | 266 | ||
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 342d69399ec7..142d9c616f1b 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -62,8 +62,7 @@ static int __init omap3_l3_init(void) | |||
62 | if (!oh) | 62 | if (!oh) |
63 | pr_err("could not look up %s\n", oh_name); | 63 | pr_err("could not look up %s\n", oh_name); |
64 | 64 | ||
65 | pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0, | 65 | pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0); |
66 | NULL, 0, 0); | ||
67 | 66 | ||
68 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); | 67 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); |
69 | 68 | ||
@@ -97,8 +96,7 @@ static int __init omap4_l3_init(void) | |||
97 | pr_err("could not look up %s\n", oh_name); | 96 | pr_err("could not look up %s\n", oh_name); |
98 | } | 97 | } |
99 | 98 | ||
100 | pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, | 99 | pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 0); |
101 | 0, NULL, 0, 0); | ||
102 | 100 | ||
103 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); | 101 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); |
104 | 102 | ||
@@ -317,7 +315,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data | |||
317 | keypad_data = sdp4430_keypad_data; | 315 | keypad_data = sdp4430_keypad_data; |
318 | 316 | ||
319 | pdev = omap_device_build(name, id, oh, keypad_data, | 317 | pdev = omap_device_build(name, id, oh, keypad_data, |
320 | sizeof(struct omap4_keypad_platform_data), NULL, 0, 0); | 318 | sizeof(struct omap4_keypad_platform_data)); |
321 | 319 | ||
322 | if (IS_ERR(pdev)) { | 320 | if (IS_ERR(pdev)) { |
323 | WARN(1, "Can't build omap_device for %s:%s.\n", | 321 | WARN(1, "Can't build omap_device for %s:%s.\n", |
@@ -341,7 +339,7 @@ static inline void __init omap_init_mbox(void) | |||
341 | return; | 339 | return; |
342 | } | 340 | } |
343 | 341 | ||
344 | pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0); | 342 | pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0); |
345 | WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", | 343 | WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", |
346 | __func__, PTR_ERR(pdev)); | 344 | __func__, PTR_ERR(pdev)); |
347 | } | 345 | } |
@@ -381,7 +379,7 @@ static void __init omap_init_mcpdm(void) | |||
381 | return; | 379 | return; |
382 | } | 380 | } |
383 | 381 | ||
384 | pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0, NULL, 0, 0); | 382 | pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0); |
385 | WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n"); | 383 | WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n"); |
386 | } | 384 | } |
387 | #else | 385 | #else |
@@ -402,7 +400,7 @@ static void __init omap_init_dmic(void) | |||
402 | return; | 400 | return; |
403 | } | 401 | } |
404 | 402 | ||
405 | pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0); | 403 | pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0); |
406 | WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n"); | 404 | WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n"); |
407 | } | 405 | } |
408 | #else | 406 | #else |
@@ -428,8 +426,7 @@ static void __init omap_init_hdmi_audio(void) | |||
428 | return; | 426 | return; |
429 | } | 427 | } |
430 | 428 | ||
431 | pdev = omap_device_build("omap-hdmi-audio-dai", | 429 | pdev = omap_device_build("omap-hdmi-audio-dai", -1, oh, NULL, 0, 0); |
432 | -1, oh, NULL, 0, NULL, 0, 0); | ||
433 | WARN(IS_ERR(pdev), | 430 | WARN(IS_ERR(pdev), |
434 | "Can't build omap_device for omap-hdmi-audio-dai.\n"); | 431 | "Can't build omap_device for omap-hdmi-audio-dai.\n"); |
435 | 432 | ||
@@ -473,8 +470,7 @@ static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) | |||
473 | } | 470 | } |
474 | 471 | ||
475 | spi_num++; | 472 | spi_num++; |
476 | pdev = omap_device_build(name, spi_num, oh, pdata, | 473 | pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata)); |
477 | sizeof(*pdata), NULL, 0, 0); | ||
478 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", | 474 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", |
479 | name, oh->name); | 475 | name, oh->name); |
480 | kfree(pdata); | 476 | kfree(pdata); |
@@ -504,7 +500,7 @@ static void omap_init_rng(void) | |||
504 | if (!oh) | 500 | if (!oh) |
505 | return; | 501 | return; |
506 | 502 | ||
507 | pdev = omap_device_build("omap_rng", -1, oh, NULL, 0, NULL, 0, 0); | 503 | pdev = omap_device_build("omap_rng", -1, oh, NULL, 0); |
508 | WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); | 504 | WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); |
509 | } | 505 | } |
510 | 506 | ||
@@ -733,8 +729,7 @@ static void __init omap_init_ocp2scp(void) | |||
733 | 729 | ||
734 | pdata->dev_cnt = dev_cnt; | 730 | pdata->dev_cnt = dev_cnt; |
735 | 731 | ||
736 | pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, | 732 | pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata)); |
737 | 0, false); | ||
738 | if (IS_ERR(pdev)) { | 733 | if (IS_ERR(pdev)) { |
739 | pr_err("Could not build omap_device for %s %s\n", | 734 | pr_err("Could not build omap_device for %s %s\n", |
740 | name, oh_name); | 735 | name, oh_name); |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index cc75aaf6e764..ff37be1f6f93 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
@@ -226,7 +226,7 @@ static struct platform_device *create_dss_pdev(const char *pdev_name, | |||
226 | dev_set_name(&pdev->dev, "%s", pdev->name); | 226 | dev_set_name(&pdev->dev, "%s", pdev->name); |
227 | 227 | ||
228 | ohs[0] = oh; | 228 | ohs[0] = oh; |
229 | od = omap_device_alloc(pdev, ohs, 1, NULL, 0); | 229 | od = omap_device_alloc(pdev, ohs, 1); |
230 | if (IS_ERR(od)) { | 230 | if (IS_ERR(od)) { |
231 | pr_err("Could not alloc omap_device for %s\n", pdev_name); | 231 | pr_err("Could not alloc omap_device for %s\n", pdev_name); |
232 | r = -ENOMEM; | 232 | r = -ENOMEM; |
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 5cd8d7668bec..dab9fc014b97 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c | |||
@@ -248,7 +248,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) | |||
248 | 248 | ||
249 | p->errata = configure_dma_errata(); | 249 | p->errata = configure_dma_errata(); |
250 | 250 | ||
251 | pdev = omap_device_build(name, 0, oh, p, sizeof(*p), NULL, 0, 0); | 251 | pdev = omap_device_build(name, 0, oh, p, sizeof(*p)); |
252 | kfree(p); | 252 | kfree(p); |
253 | if (IS_ERR(pdev)) { | 253 | if (IS_ERR(pdev)) { |
254 | pr_err("%s: Can't build omap_device for %s:%s.\n", | 254 | pr_err("%s: Can't build omap_device for %s:%s.\n", |
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c index 231ed5f2bc81..59a4af779f42 100644 --- a/arch/arm/mach-omap2/drm.c +++ b/arch/arm/mach-omap2/drm.c | |||
@@ -51,8 +51,7 @@ static int __init omap_init_drm(void) | |||
51 | oh = omap_hwmod_lookup("dmm"); | 51 | oh = omap_hwmod_lookup("dmm"); |
52 | 52 | ||
53 | if (oh) { | 53 | if (oh) { |
54 | pdev = omap_device_build(oh->name, -1, oh, NULL, 0, NULL, 0, | 54 | pdev = omap_device_build(oh->name, -1, oh, NULL, 0); |
55 | false); | ||
56 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", | 55 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", |
57 | oh->name); | 56 | oh->name); |
58 | } | 57 | } |
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 40950f5af1f0..7a577145b68b 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c | |||
@@ -132,8 +132,7 @@ static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) | |||
132 | pwrdm = omap_hwmod_get_pwrdm(oh); | 132 | pwrdm = omap_hwmod_get_pwrdm(oh); |
133 | pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); | 133 | pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); |
134 | 134 | ||
135 | pdev = omap_device_build(name, id - 1, oh, pdata, | 135 | pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata)); |
136 | sizeof(*pdata), NULL, 0, false); | ||
137 | kfree(pdata); | 136 | kfree(pdata); |
138 | 137 | ||
139 | if (IS_ERR(pdev)) { | 138 | if (IS_ERR(pdev)) { |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 7911e2824899..8d70bd03c5d8 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -1448,7 +1448,7 @@ static int __init omap_gpmc_init(void) | |||
1448 | return -ENODEV; | 1448 | return -ENODEV; |
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0, NULL, 0, 0); | 1451 | pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0); |
1452 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); | 1452 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); |
1453 | 1453 | ||
1454 | return IS_ERR(pdev) ? PTR_ERR(pdev) : 0; | 1454 | return IS_ERR(pdev) ? PTR_ERR(pdev) : 0; |
diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c index f6e0e7e68f9f..cbc8e3c480e0 100644 --- a/arch/arm/mach-omap2/hdq1w.c +++ b/arch/arm/mach-omap2/hdq1w.c | |||
@@ -88,7 +88,7 @@ static int __init omap_init_hdq(void) | |||
88 | if (!oh) | 88 | if (!oh) |
89 | return 0; | 89 | return 0; |
90 | 90 | ||
91 | pdev = omap_device_build(devname, id, oh, NULL, 0, NULL, 0, 0); | 91 | pdev = omap_device_build(devname, id, oh, NULL, 0); |
92 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", | 92 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", |
93 | devname, oh->name); | 93 | devname, oh->name); |
94 | 94 | ||
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 4a964338992a..2ef1f8714fcf 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c | |||
@@ -522,7 +522,7 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, | |||
522 | } | 522 | } |
523 | dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); | 523 | dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); |
524 | 524 | ||
525 | od = omap_device_alloc(pdev, ohs, 1, NULL, 0); | 525 | od = omap_device_alloc(pdev, ohs, 1); |
526 | if (IS_ERR(od)) { | 526 | if (IS_ERR(od)) { |
527 | pr_err("Could not allocate od for %s\n", name); | 527 | pr_err("Could not allocate od for %s\n", name); |
528 | goto put_pdev; | 528 | goto put_pdev; |
diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c index bcb357e948b7..ef175acaeaa2 100644 --- a/arch/arm/mach-omap2/hwspinlock.c +++ b/arch/arm/mach-omap2/hwspinlock.c | |||
@@ -47,8 +47,7 @@ static int __init hwspinlocks_init(void) | |||
47 | return -EINVAL; | 47 | return -EINVAL; |
48 | 48 | ||
49 | pdev = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata, | 49 | pdev = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata, |
50 | sizeof(struct hwspinlock_pdata), | 50 | sizeof(struct hwspinlock_pdata)); |
51 | NULL, 0, false); | ||
52 | if (IS_ERR(pdev)) { | 51 | if (IS_ERR(pdev)) { |
53 | pr_err("Can't build omap_device for %s:%s\n", dev_name, | 52 | pr_err("Can't build omap_device for %s:%s\n", dev_name, |
54 | oh_name); | 53 | oh_name); |
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index 8fd98576f4d3..d940e53dd9f2 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c | |||
@@ -178,8 +178,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata, | |||
178 | if (cpu_is_omap34xx()) | 178 | if (cpu_is_omap34xx()) |
179 | pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; | 179 | pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; |
180 | pdev = omap_device_build(name, bus_id, oh, pdata, | 180 | pdev = omap_device_build(name, bus_id, oh, pdata, |
181 | sizeof(struct omap_i2c_bus_platform_data), | 181 | sizeof(struct omap_i2c_bus_platform_data)); |
182 | NULL, 0, 0); | ||
183 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); | 182 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); |
184 | 183 | ||
185 | return PTR_RET(pdev); | 184 | return PTR_RET(pdev); |
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 1c0968db43bf..5d8768075dd9 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -102,7 +102,7 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
102 | count++; | 102 | count++; |
103 | } | 103 | } |
104 | pdev = omap_device_build_ss(name, id, oh_device, count, pdata, | 104 | pdev = omap_device_build_ss(name, id, oh_device, count, pdata, |
105 | sizeof(*pdata), NULL, 0, false); | 105 | sizeof(*pdata)); |
106 | kfree(pdata); | 106 | kfree(pdata); |
107 | if (IS_ERR(pdev)) { | 107 | if (IS_ERR(pdev)) { |
108 | pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, | 108 | pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, |
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c index aafdd4ca9f4f..c52d8b4a3e91 100644 --- a/arch/arm/mach-omap2/msdi.c +++ b/arch/arm/mach-omap2/msdi.c | |||
@@ -150,7 +150,7 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) | |||
150 | return; | 150 | return; |
151 | } | 151 | } |
152 | pdev = omap_device_build(dev_name, id, oh, mmc_data[0], | 152 | pdev = omap_device_build(dev_name, id, oh, mmc_data[0], |
153 | sizeof(struct omap_mmc_platform_data), NULL, 0, 0); | 153 | sizeof(struct omap_mmc_platform_data)); |
154 | if (IS_ERR(pdev)) | 154 | if (IS_ERR(pdev)) |
155 | WARN(1, "Can'd build omap_device for %s:%s.\n", | 155 | WARN(1, "Can'd build omap_device for %s:%s.\n", |
156 | dev_name, oh->name); | 156 | dev_name, oh->name); |
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index c20423955bf7..f6daae821ebb 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c | |||
@@ -42,8 +42,7 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused) | |||
42 | pdata->deassert_reset = omap_device_deassert_hardreset; | 42 | pdata->deassert_reset = omap_device_deassert_hardreset; |
43 | } | 43 | } |
44 | 44 | ||
45 | pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata), | 45 | pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata)); |
46 | NULL, 0, 0); | ||
47 | 46 | ||
48 | kfree(pdata); | 47 | kfree(pdata); |
49 | 48 | ||
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index aac46bfdbeb2..8bcb64bcdcdb 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c | |||
@@ -87,37 +87,6 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr) | |||
87 | } | 87 | } |
88 | 88 | ||
89 | /* | 89 | /* |
90 | * Set the CPUx powerdomain's previous power state | ||
91 | */ | ||
92 | static inline void set_cpu_next_pwrst(unsigned int cpu_id, | ||
93 | unsigned int power_state) | ||
94 | { | ||
95 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
96 | |||
97 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Read CPU's previous power state | ||
102 | */ | ||
103 | static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id) | ||
104 | { | ||
105 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
106 | |||
107 | return pwrdm_read_prev_pwrst(pm_info->pwrdm); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Clear the CPUx powerdomain's previous power state | ||
112 | */ | ||
113 | static inline void clear_cpu_prev_pwrst(unsigned int cpu_id) | ||
114 | { | ||
115 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
116 | |||
117 | pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Store the SCU power status value to scratchpad memory | 90 | * Store the SCU power status value to scratchpad memory |
122 | */ | 91 | */ |
123 | static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) | 92 | static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) |
@@ -230,6 +199,7 @@ static void save_l2x0_context(void) | |||
230 | */ | 199 | */ |
231 | int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | 200 | int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) |
232 | { | 201 | { |
202 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); | ||
233 | unsigned int save_state = 0; | 203 | unsigned int save_state = 0; |
234 | unsigned int wakeup_cpu; | 204 | unsigned int wakeup_cpu; |
235 | 205 | ||
@@ -268,7 +238,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | |||
268 | save_state = 2; | 238 | save_state = 2; |
269 | 239 | ||
270 | cpu_clear_prev_logic_pwrst(cpu); | 240 | cpu_clear_prev_logic_pwrst(cpu); |
271 | set_cpu_next_pwrst(cpu, power_state); | 241 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); |
272 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); | 242 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); |
273 | scu_pwrst_prepare(cpu, power_state); | 243 | scu_pwrst_prepare(cpu, power_state); |
274 | l2x0_pwrst_prepare(cpu, save_state); | 244 | l2x0_pwrst_prepare(cpu, save_state); |
@@ -286,7 +256,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | |||
286 | * domain transition | 256 | * domain transition |
287 | */ | 257 | */ |
288 | wakeup_cpu = smp_processor_id(); | 258 | wakeup_cpu = smp_processor_id(); |
289 | set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); | 259 | pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); |
290 | 260 | ||
291 | pwrdm_post_transition(NULL); | 261 | pwrdm_post_transition(NULL); |
292 | 262 | ||
@@ -300,8 +270,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | |||
300 | */ | 270 | */ |
301 | int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) | 271 | int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) |
302 | { | 272 | { |
303 | unsigned int cpu_state = 0; | ||
304 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); | 273 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); |
274 | unsigned int cpu_state = 0; | ||
305 | 275 | ||
306 | if (omap_rev() == OMAP4430_REV_ES1_0) | 276 | if (omap_rev() == OMAP4430_REV_ES1_0) |
307 | return -ENXIO; | 277 | return -ENXIO; |
@@ -309,8 +279,8 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) | |||
309 | if (power_state == PWRDM_POWER_OFF) | 279 | if (power_state == PWRDM_POWER_OFF) |
310 | cpu_state = 1; | 280 | cpu_state = 1; |
311 | 281 | ||
312 | clear_cpu_prev_pwrst(cpu); | 282 | pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); |
313 | set_cpu_next_pwrst(cpu, power_state); | 283 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); |
314 | set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); | 284 | set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); |
315 | scu_pwrst_prepare(cpu, power_state); | 285 | scu_pwrst_prepare(cpu, power_state); |
316 | 286 | ||
@@ -321,7 +291,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) | |||
321 | */ | 291 | */ |
322 | omap4_finish_suspend(cpu_state); | 292 | omap4_finish_suspend(cpu_state); |
323 | 293 | ||
324 | set_cpu_next_pwrst(cpu, PWRDM_POWER_ON); | 294 | pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); |
325 | return 0; | 295 | return 0; |
326 | } | 296 | } |
327 | 297 | ||
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 361677983af0..d9727218dd0a 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -215,7 +215,7 @@ static void __init omap4_smp_init_cpus(void) | |||
215 | * Currently we can't call ioremap here because | 215 | * Currently we can't call ioremap here because |
216 | * SoC detection won't work until after init_early. | 216 | * SoC detection won't work until after init_early. |
217 | */ | 217 | */ |
218 | scu_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE); | 218 | scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base()); |
219 | BUG_ON(!scu_base); | 219 | BUG_ON(!scu_base); |
220 | ncores = scu_get_core_count(scu_base); | 220 | ncores = scu_get_core_count(scu_base); |
221 | } else if (cpu_id == CPU_CORTEX_A15) { | 221 | } else if (cpu_id == CPU_CORTEX_A15) { |
diff --git a/arch/arm/mach-omap2/omap44xx.h b/arch/arm/mach-omap2/omap44xx.h index 43b927b2e2e8..8a515bb74639 100644 --- a/arch/arm/mach-omap2/omap44xx.h +++ b/arch/arm/mach-omap2/omap44xx.h | |||
@@ -40,7 +40,6 @@ | |||
40 | #define OMAP44XX_GIC_DIST_BASE 0x48241000 | 40 | #define OMAP44XX_GIC_DIST_BASE 0x48241000 |
41 | #define OMAP44XX_GIC_CPU_BASE 0x48240100 | 41 | #define OMAP44XX_GIC_CPU_BASE 0x48240100 |
42 | #define OMAP44XX_IRQ_GIC_START 32 | 42 | #define OMAP44XX_IRQ_GIC_START 32 |
43 | #define OMAP44XX_SCU_BASE 0x48240000 | ||
44 | #define OMAP44XX_LOCAL_TWD_BASE 0x48240600 | 43 | #define OMAP44XX_LOCAL_TWD_BASE 0x48240600 |
45 | #define OMAP44XX_L2CACHE_BASE 0x48242000 | 44 | #define OMAP44XX_L2CACHE_BASE 0x48242000 |
46 | #define OMAP44XX_WKUPGEN_BASE 0x48281000 | 45 | #define OMAP44XX_WKUPGEN_BASE 0x48281000 |
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index d109f06785da..381be7ac0c17 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c | |||
@@ -17,68 +17,15 @@ | |||
17 | * to control power management and interconnect properties of their | 17 | * to control power management and interconnect properties of their |
18 | * devices. | 18 | * devices. |
19 | * | 19 | * |
20 | * In the medium- to long-term, this code should either be | 20 | * In the medium- to long-term, this code should be implemented as a |
21 | * a) implemented via arch-specific pointers in platform_data | 21 | * proper omap_bus/omap_device in Linux, no more platform_data func |
22 | * or | 22 | * pointers |
23 | * b) implemented as a proper omap_bus/omap_device in Linux, no more | ||
24 | * platform_data func pointers | ||
25 | * | 23 | * |
26 | * | 24 | * |
27 | * Guidelines for usage by driver authors: | ||
28 | * | ||
29 | * 1. These functions are intended to be used by device drivers via | ||
30 | * function pointers in struct platform_data. As an example, | ||
31 | * omap_device_enable() should be passed to the driver as | ||
32 | * | ||
33 | * struct foo_driver_platform_data { | ||
34 | * ... | ||
35 | * int (*device_enable)(struct platform_device *pdev); | ||
36 | * ... | ||
37 | * } | ||
38 | * | ||
39 | * Note that the generic "device_enable" name is used, rather than | ||
40 | * "omap_device_enable". This is so other architectures can pass in their | ||
41 | * own enable/disable functions here. | ||
42 | * | ||
43 | * This should be populated during device setup: | ||
44 | * | ||
45 | * ... | ||
46 | * pdata->device_enable = omap_device_enable; | ||
47 | * ... | ||
48 | * | ||
49 | * 2. Drivers should first check to ensure the function pointer is not null | ||
50 | * before calling it, as in: | ||
51 | * | ||
52 | * if (pdata->device_enable) | ||
53 | * pdata->device_enable(pdev); | ||
54 | * | ||
55 | * This allows other architectures that don't use similar device_enable()/ | ||
56 | * device_shutdown() functions to execute normally. | ||
57 | * | ||
58 | * ... | ||
59 | * | ||
60 | * Suggested usage by device drivers: | ||
61 | * | ||
62 | * During device initialization: | ||
63 | * device_enable() | ||
64 | * | ||
65 | * During device idle: | ||
66 | * (save remaining device context if necessary) | ||
67 | * device_idle(); | ||
68 | * | ||
69 | * During device resume: | ||
70 | * device_enable(); | ||
71 | * (restore context if necessary) | ||
72 | * | ||
73 | * During device shutdown: | ||
74 | * device_shutdown() | ||
75 | * (device must be reinitialized at this point to use it again) | ||
76 | * | ||
77 | */ | 25 | */ |
78 | #undef DEBUG | 26 | #undef DEBUG |
79 | 27 | ||
80 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
81 | #include <linux/export.h> | ||
82 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
83 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
84 | #include <linux/err.h> | 31 | #include <linux/err.h> |
@@ -93,155 +40,8 @@ | |||
93 | #include "omap_device.h" | 40 | #include "omap_device.h" |
94 | #include "omap_hwmod.h" | 41 | #include "omap_hwmod.h" |
95 | 42 | ||
96 | /* These parameters are passed to _omap_device_{de,}activate() */ | ||
97 | #define USE_WAKEUP_LAT 0 | ||
98 | #define IGNORE_WAKEUP_LAT 1 | ||
99 | |||
100 | static int omap_early_device_register(struct platform_device *pdev); | ||
101 | |||
102 | static struct omap_device_pm_latency omap_default_latency[] = { | ||
103 | { | ||
104 | .deactivate_func = omap_device_idle_hwmods, | ||
105 | .activate_func = omap_device_enable_hwmods, | ||
106 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
107 | } | ||
108 | }; | ||
109 | |||
110 | /* Private functions */ | 43 | /* Private functions */ |
111 | 44 | ||
112 | /** | ||
113 | * _omap_device_activate - increase device readiness | ||
114 | * @od: struct omap_device * | ||
115 | * @ignore_lat: increase to latency target (0) or full readiness (1)? | ||
116 | * | ||
117 | * Increase readiness of omap_device @od (thus decreasing device | ||
118 | * wakeup latency, but consuming more power). If @ignore_lat is | ||
119 | * IGNORE_WAKEUP_LAT, make the omap_device fully active. Otherwise, | ||
120 | * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup | ||
121 | * latency is greater than the requested maximum wakeup latency, step | ||
122 | * backwards in the omap_device_pm_latency table to ensure the | ||
123 | * device's maximum wakeup latency is less than or equal to the | ||
124 | * requested maximum wakeup latency. Returns 0. | ||
125 | */ | ||
126 | static int _omap_device_activate(struct omap_device *od, u8 ignore_lat) | ||
127 | { | ||
128 | struct timespec a, b, c; | ||
129 | |||
130 | dev_dbg(&od->pdev->dev, "omap_device: activating\n"); | ||
131 | |||
132 | while (od->pm_lat_level > 0) { | ||
133 | struct omap_device_pm_latency *odpl; | ||
134 | unsigned long long act_lat = 0; | ||
135 | |||
136 | od->pm_lat_level--; | ||
137 | |||
138 | odpl = od->pm_lats + od->pm_lat_level; | ||
139 | |||
140 | if (!ignore_lat && | ||
141 | (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit)) | ||
142 | break; | ||
143 | |||
144 | read_persistent_clock(&a); | ||
145 | |||
146 | /* XXX check return code */ | ||
147 | odpl->activate_func(od); | ||
148 | |||
149 | read_persistent_clock(&b); | ||
150 | |||
151 | c = timespec_sub(b, a); | ||
152 | act_lat = timespec_to_ns(&c); | ||
153 | |||
154 | dev_dbg(&od->pdev->dev, | ||
155 | "omap_device: pm_lat %d: activate: elapsed time %llu nsec\n", | ||
156 | od->pm_lat_level, act_lat); | ||
157 | |||
158 | if (act_lat > odpl->activate_lat) { | ||
159 | odpl->activate_lat_worst = act_lat; | ||
160 | if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { | ||
161 | odpl->activate_lat = act_lat; | ||
162 | dev_dbg(&od->pdev->dev, | ||
163 | "new worst case activate latency %d: %llu\n", | ||
164 | od->pm_lat_level, act_lat); | ||
165 | } else | ||
166 | dev_warn(&od->pdev->dev, | ||
167 | "activate latency %d higher than expected. (%llu > %d)\n", | ||
168 | od->pm_lat_level, act_lat, | ||
169 | odpl->activate_lat); | ||
170 | } | ||
171 | |||
172 | od->dev_wakeup_lat -= odpl->activate_lat; | ||
173 | } | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * _omap_device_deactivate - decrease device readiness | ||
180 | * @od: struct omap_device * | ||
181 | * @ignore_lat: decrease to latency target (0) or full inactivity (1)? | ||
182 | * | ||
183 | * Decrease readiness of omap_device @od (thus increasing device | ||
184 | * wakeup latency, but conserving power). If @ignore_lat is | ||
185 | * IGNORE_WAKEUP_LAT, make the omap_device fully inactive. Otherwise, | ||
186 | * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup | ||
187 | * latency is less than the requested maximum wakeup latency, step | ||
188 | * forwards in the omap_device_pm_latency table to ensure the device's | ||
189 | * maximum wakeup latency is less than or equal to the requested | ||
190 | * maximum wakeup latency. Returns 0. | ||
191 | */ | ||
192 | static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat) | ||
193 | { | ||
194 | struct timespec a, b, c; | ||
195 | |||
196 | dev_dbg(&od->pdev->dev, "omap_device: deactivating\n"); | ||
197 | |||
198 | while (od->pm_lat_level < od->pm_lats_cnt) { | ||
199 | struct omap_device_pm_latency *odpl; | ||
200 | unsigned long long deact_lat = 0; | ||
201 | |||
202 | odpl = od->pm_lats + od->pm_lat_level; | ||
203 | |||
204 | if (!ignore_lat && | ||
205 | ((od->dev_wakeup_lat + odpl->activate_lat) > | ||
206 | od->_dev_wakeup_lat_limit)) | ||
207 | break; | ||
208 | |||
209 | read_persistent_clock(&a); | ||
210 | |||
211 | /* XXX check return code */ | ||
212 | odpl->deactivate_func(od); | ||
213 | |||
214 | read_persistent_clock(&b); | ||
215 | |||
216 | c = timespec_sub(b, a); | ||
217 | deact_lat = timespec_to_ns(&c); | ||
218 | |||
219 | dev_dbg(&od->pdev->dev, | ||
220 | "omap_device: pm_lat %d: deactivate: elapsed time %llu nsec\n", | ||
221 | od->pm_lat_level, deact_lat); | ||
222 | |||
223 | if (deact_lat > odpl->deactivate_lat) { | ||
224 | odpl->deactivate_lat_worst = deact_lat; | ||
225 | if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { | ||
226 | odpl->deactivate_lat = deact_lat; | ||
227 | dev_dbg(&od->pdev->dev, | ||
228 | "new worst case deactivate latency %d: %llu\n", | ||
229 | od->pm_lat_level, deact_lat); | ||
230 | } else | ||
231 | dev_warn(&od->pdev->dev, | ||
232 | "deactivate latency %d higher than expected. (%llu > %d)\n", | ||
233 | od->pm_lat_level, deact_lat, | ||
234 | odpl->deactivate_lat); | ||
235 | } | ||
236 | |||
237 | od->dev_wakeup_lat += odpl->activate_lat; | ||
238 | |||
239 | od->pm_lat_level++; | ||
240 | } | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static void _add_clkdev(struct omap_device *od, const char *clk_alias, | 45 | static void _add_clkdev(struct omap_device *od, const char *clk_alias, |
246 | const char *clk_name) | 46 | const char *clk_name) |
247 | { | 47 | { |
@@ -316,9 +116,6 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od, | |||
316 | * @oh: ptr to the single omap_hwmod that backs this omap_device | 116 | * @oh: ptr to the single omap_hwmod that backs this omap_device |
317 | * @pdata: platform_data ptr to associate with the platform_device | 117 | * @pdata: platform_data ptr to associate with the platform_device |
318 | * @pdata_len: amount of memory pointed to by @pdata | 118 | * @pdata_len: amount of memory pointed to by @pdata |
319 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | ||
320 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | ||
321 | * @is_early_device: should the device be registered as an early device or not | ||
322 | * | 119 | * |
323 | * Function for building an omap_device already registered from device-tree | 120 | * Function for building an omap_device already registered from device-tree |
324 | * | 121 | * |
@@ -357,7 +154,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) | |||
357 | hwmods[i] = oh; | 154 | hwmods[i] = oh; |
358 | } | 155 | } |
359 | 156 | ||
360 | od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0); | 157 | od = omap_device_alloc(pdev, hwmods, oh_cnt); |
361 | if (!od) { | 158 | if (!od) { |
362 | dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", | 159 | dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", |
363 | oh_name); | 160 | oh_name); |
@@ -408,6 +205,39 @@ static int _omap_device_notifier_call(struct notifier_block *nb, | |||
408 | return NOTIFY_DONE; | 205 | return NOTIFY_DONE; |
409 | } | 206 | } |
410 | 207 | ||
208 | /** | ||
209 | * _omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods | ||
210 | * @od: struct omap_device *od | ||
211 | * | ||
212 | * Enable all underlying hwmods. Returns 0. | ||
213 | */ | ||
214 | static int _omap_device_enable_hwmods(struct omap_device *od) | ||
215 | { | ||
216 | int i; | ||
217 | |||
218 | for (i = 0; i < od->hwmods_cnt; i++) | ||
219 | omap_hwmod_enable(od->hwmods[i]); | ||
220 | |||
221 | /* XXX pass along return value here? */ | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * _omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods | ||
227 | * @od: struct omap_device *od | ||
228 | * | ||
229 | * Idle all underlying hwmods. Returns 0. | ||
230 | */ | ||
231 | static int _omap_device_idle_hwmods(struct omap_device *od) | ||
232 | { | ||
233 | int i; | ||
234 | |||
235 | for (i = 0; i < od->hwmods_cnt; i++) | ||
236 | omap_hwmod_idle(od->hwmods[i]); | ||
237 | |||
238 | /* XXX pass along return value here? */ | ||
239 | return 0; | ||
240 | } | ||
411 | 241 | ||
412 | /* Public functions for use by core code */ | 242 | /* Public functions for use by core code */ |
413 | 243 | ||
@@ -527,18 +357,14 @@ static int _od_fill_dma_resources(struct omap_device *od, | |||
527 | * @oh: ptr to the single omap_hwmod that backs this omap_device | 357 | * @oh: ptr to the single omap_hwmod that backs this omap_device |
528 | * @pdata: platform_data ptr to associate with the platform_device | 358 | * @pdata: platform_data ptr to associate with the platform_device |
529 | * @pdata_len: amount of memory pointed to by @pdata | 359 | * @pdata_len: amount of memory pointed to by @pdata |
530 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | ||
531 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | ||
532 | * | 360 | * |
533 | * Convenience function for allocating an omap_device structure and filling | 361 | * Convenience function for allocating an omap_device structure and filling |
534 | * hwmods, resources and pm_latency attributes. | 362 | * hwmods, and resources. |
535 | * | 363 | * |
536 | * Returns an struct omap_device pointer or ERR_PTR() on error; | 364 | * Returns an struct omap_device pointer or ERR_PTR() on error; |
537 | */ | 365 | */ |
538 | struct omap_device *omap_device_alloc(struct platform_device *pdev, | 366 | struct omap_device *omap_device_alloc(struct platform_device *pdev, |
539 | struct omap_hwmod **ohs, int oh_cnt, | 367 | struct omap_hwmod **ohs, int oh_cnt) |
540 | struct omap_device_pm_latency *pm_lats, | ||
541 | int pm_lats_cnt) | ||
542 | { | 368 | { |
543 | int ret = -ENOMEM; | 369 | int ret = -ENOMEM; |
544 | struct omap_device *od; | 370 | struct omap_device *od; |
@@ -627,18 +453,6 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev, | |||
627 | goto oda_exit3; | 453 | goto oda_exit3; |
628 | 454 | ||
629 | have_everything: | 455 | have_everything: |
630 | if (!pm_lats) { | ||
631 | pm_lats = omap_default_latency; | ||
632 | pm_lats_cnt = ARRAY_SIZE(omap_default_latency); | ||
633 | } | ||
634 | |||
635 | od->pm_lats_cnt = pm_lats_cnt; | ||
636 | od->pm_lats = kmemdup(pm_lats, | ||
637 | sizeof(struct omap_device_pm_latency) * pm_lats_cnt, | ||
638 | GFP_KERNEL); | ||
639 | if (!od->pm_lats) | ||
640 | goto oda_exit3; | ||
641 | |||
642 | pdev->archdata.od = od; | 456 | pdev->archdata.od = od; |
643 | 457 | ||
644 | for (i = 0; i < oh_cnt; i++) { | 458 | for (i = 0; i < oh_cnt; i++) { |
@@ -664,7 +478,6 @@ void omap_device_delete(struct omap_device *od) | |||
664 | return; | 478 | return; |
665 | 479 | ||
666 | od->pdev->archdata.od = NULL; | 480 | od->pdev->archdata.od = NULL; |
667 | kfree(od->pm_lats); | ||
668 | kfree(od->hwmods); | 481 | kfree(od->hwmods); |
669 | kfree(od); | 482 | kfree(od); |
670 | } | 483 | } |
@@ -676,9 +489,6 @@ void omap_device_delete(struct omap_device *od) | |||
676 | * @oh: ptr to the single omap_hwmod that backs this omap_device | 489 | * @oh: ptr to the single omap_hwmod that backs this omap_device |
677 | * @pdata: platform_data ptr to associate with the platform_device | 490 | * @pdata: platform_data ptr to associate with the platform_device |
678 | * @pdata_len: amount of memory pointed to by @pdata | 491 | * @pdata_len: amount of memory pointed to by @pdata |
679 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | ||
680 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | ||
681 | * @is_early_device: should the device be registered as an early device or not | ||
682 | * | 492 | * |
683 | * Convenience function for building and registering a single | 493 | * Convenience function for building and registering a single |
684 | * omap_device record, which in turn builds and registers a | 494 | * omap_device record, which in turn builds and registers a |
@@ -686,11 +496,10 @@ void omap_device_delete(struct omap_device *od) | |||
686 | * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise, | 496 | * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise, |
687 | * passes along the return value of omap_device_build_ss(). | 497 | * passes along the return value of omap_device_build_ss(). |
688 | */ | 498 | */ |
689 | struct platform_device __init *omap_device_build(const char *pdev_name, int pdev_id, | 499 | struct platform_device __init *omap_device_build(const char *pdev_name, |
690 | struct omap_hwmod *oh, void *pdata, | 500 | int pdev_id, |
691 | int pdata_len, | 501 | struct omap_hwmod *oh, |
692 | struct omap_device_pm_latency *pm_lats, | 502 | void *pdata, int pdata_len) |
693 | int pm_lats_cnt, int is_early_device) | ||
694 | { | 503 | { |
695 | struct omap_hwmod *ohs[] = { oh }; | 504 | struct omap_hwmod *ohs[] = { oh }; |
696 | 505 | ||
@@ -698,8 +507,7 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev | |||
698 | return ERR_PTR(-EINVAL); | 507 | return ERR_PTR(-EINVAL); |
699 | 508 | ||
700 | return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, | 509 | return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, |
701 | pdata_len, pm_lats, pm_lats_cnt, | 510 | pdata_len); |
702 | is_early_device); | ||
703 | } | 511 | } |
704 | 512 | ||
705 | /** | 513 | /** |
@@ -709,9 +517,6 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev | |||
709 | * @oh: ptr to the single omap_hwmod that backs this omap_device | 517 | * @oh: ptr to the single omap_hwmod that backs this omap_device |
710 | * @pdata: platform_data ptr to associate with the platform_device | 518 | * @pdata: platform_data ptr to associate with the platform_device |
711 | * @pdata_len: amount of memory pointed to by @pdata | 519 | * @pdata_len: amount of memory pointed to by @pdata |
712 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | ||
713 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | ||
714 | * @is_early_device: should the device be registered as an early device or not | ||
715 | * | 520 | * |
716 | * Convenience function for building and registering an omap_device | 521 | * Convenience function for building and registering an omap_device |
717 | * subsystem record. Subsystem records consist of multiple | 522 | * subsystem record. Subsystem records consist of multiple |
@@ -719,11 +524,11 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev | |||
719 | * platform_device record. Returns an ERR_PTR() on error, or passes | 524 | * platform_device record. Returns an ERR_PTR() on error, or passes |
720 | * along the return value of omap_device_register(). | 525 | * along the return value of omap_device_register(). |
721 | */ | 526 | */ |
722 | struct platform_device __init *omap_device_build_ss(const char *pdev_name, int pdev_id, | 527 | struct platform_device __init *omap_device_build_ss(const char *pdev_name, |
723 | struct omap_hwmod **ohs, int oh_cnt, | 528 | int pdev_id, |
724 | void *pdata, int pdata_len, | 529 | struct omap_hwmod **ohs, |
725 | struct omap_device_pm_latency *pm_lats, | 530 | int oh_cnt, void *pdata, |
726 | int pm_lats_cnt, int is_early_device) | 531 | int pdata_len) |
727 | { | 532 | { |
728 | int ret = -ENOMEM; | 533 | int ret = -ENOMEM; |
729 | struct platform_device *pdev; | 534 | struct platform_device *pdev; |
@@ -747,7 +552,7 @@ struct platform_device __init *omap_device_build_ss(const char *pdev_name, int p | |||
747 | else | 552 | else |
748 | dev_set_name(&pdev->dev, "%s", pdev->name); | 553 | dev_set_name(&pdev->dev, "%s", pdev->name); |
749 | 554 | ||
750 | od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt); | 555 | od = omap_device_alloc(pdev, ohs, oh_cnt); |
751 | if (IS_ERR(od)) | 556 | if (IS_ERR(od)) |
752 | goto odbs_exit1; | 557 | goto odbs_exit1; |
753 | 558 | ||
@@ -755,10 +560,7 @@ struct platform_device __init *omap_device_build_ss(const char *pdev_name, int p | |||
755 | if (ret) | 560 | if (ret) |
756 | goto odbs_exit2; | 561 | goto odbs_exit2; |
757 | 562 | ||
758 | if (is_early_device) | 563 | ret = omap_device_register(pdev); |
759 | ret = omap_early_device_register(pdev); | ||
760 | else | ||
761 | ret = omap_device_register(pdev); | ||
762 | if (ret) | 564 | if (ret) |
763 | goto odbs_exit2; | 565 | goto odbs_exit2; |
764 | 566 | ||
@@ -775,24 +577,6 @@ odbs_exit: | |||
775 | return ERR_PTR(ret); | 577 | return ERR_PTR(ret); |
776 | } | 578 | } |
777 | 579 | ||
778 | /** | ||
779 | * omap_early_device_register - register an omap_device as an early platform | ||
780 | * device. | ||
781 | * @od: struct omap_device * to register | ||
782 | * | ||
783 | * Register the omap_device structure. This currently just calls | ||
784 | * platform_early_add_device() on the underlying platform_device. | ||
785 | * Returns 0 by default. | ||
786 | */ | ||
787 | static int __init omap_early_device_register(struct platform_device *pdev) | ||
788 | { | ||
789 | struct platform_device *devices[1]; | ||
790 | |||
791 | devices[0] = pdev; | ||
792 | early_platform_add_devices(devices, 1); | ||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | #ifdef CONFIG_PM_RUNTIME | 580 | #ifdef CONFIG_PM_RUNTIME |
797 | static int _od_runtime_suspend(struct device *dev) | 581 | static int _od_runtime_suspend(struct device *dev) |
798 | { | 582 | { |
@@ -903,10 +687,9 @@ int omap_device_register(struct platform_device *pdev) | |||
903 | * to be accessible and ready to operate. This generally involves | 687 | * to be accessible and ready to operate. This generally involves |
904 | * enabling clocks, setting SYSCONFIG registers; and in the future may | 688 | * enabling clocks, setting SYSCONFIG registers; and in the future may |
905 | * involve remuxing pins. Device drivers should call this function | 689 | * involve remuxing pins. Device drivers should call this function |
906 | * (through platform_data function pointers) where they would normally | 690 | * indirectly via pm_runtime_get*(). Returns -EINVAL if called when |
907 | * enable clocks, etc. Returns -EINVAL if called when the omap_device | 691 | * the omap_device is already enabled, or passes along the return |
908 | * is already enabled, or passes along the return value of | 692 | * value of _omap_device_enable_hwmods(). |
909 | * _omap_device_activate(). | ||
910 | */ | 693 | */ |
911 | int omap_device_enable(struct platform_device *pdev) | 694 | int omap_device_enable(struct platform_device *pdev) |
912 | { | 695 | { |
@@ -922,14 +705,8 @@ int omap_device_enable(struct platform_device *pdev) | |||
922 | return -EINVAL; | 705 | return -EINVAL; |
923 | } | 706 | } |
924 | 707 | ||
925 | /* Enable everything if we're enabling this device from scratch */ | 708 | ret = _omap_device_enable_hwmods(od); |
926 | if (od->_state == OMAP_DEVICE_STATE_UNKNOWN) | ||
927 | od->pm_lat_level = od->pm_lats_cnt; | ||
928 | |||
929 | ret = _omap_device_activate(od, IGNORE_WAKEUP_LAT); | ||
930 | 709 | ||
931 | od->dev_wakeup_lat = 0; | ||
932 | od->_dev_wakeup_lat_limit = UINT_MAX; | ||
933 | od->_state = OMAP_DEVICE_STATE_ENABLED; | 710 | od->_state = OMAP_DEVICE_STATE_ENABLED; |
934 | 711 | ||
935 | return ret; | 712 | return ret; |
@@ -939,14 +716,10 @@ int omap_device_enable(struct platform_device *pdev) | |||
939 | * omap_device_idle - idle an omap_device | 716 | * omap_device_idle - idle an omap_device |
940 | * @od: struct omap_device * to idle | 717 | * @od: struct omap_device * to idle |
941 | * | 718 | * |
942 | * Idle omap_device @od by calling as many .deactivate_func() entries | 719 | * Idle omap_device @od. Device drivers call this function indirectly |
943 | * in the omap_device's pm_lats table as is possible without exceeding | 720 | * via pm_runtime_put*(). Returns -EINVAL if the omap_device is not |
944 | * the device's maximum wakeup latency limit, pm_lat_limit. Device | ||
945 | * drivers should call this function (through platform_data function | ||
946 | * pointers) where they would normally disable clocks after operations | ||
947 | * complete, etc.. Returns -EINVAL if the omap_device is not | ||
948 | * currently enabled, or passes along the return value of | 721 | * currently enabled, or passes along the return value of |
949 | * _omap_device_deactivate(). | 722 | * _omap_device_idle_hwmods(). |
950 | */ | 723 | */ |
951 | int omap_device_idle(struct platform_device *pdev) | 724 | int omap_device_idle(struct platform_device *pdev) |
952 | { | 725 | { |
@@ -962,7 +735,7 @@ int omap_device_idle(struct platform_device *pdev) | |||
962 | return -EINVAL; | 735 | return -EINVAL; |
963 | } | 736 | } |
964 | 737 | ||
965 | ret = _omap_device_deactivate(od, USE_WAKEUP_LAT); | 738 | ret = _omap_device_idle_hwmods(od); |
966 | 739 | ||
967 | od->_state = OMAP_DEVICE_STATE_IDLE; | 740 | od->_state = OMAP_DEVICE_STATE_IDLE; |
968 | 741 | ||
@@ -970,42 +743,6 @@ int omap_device_idle(struct platform_device *pdev) | |||
970 | } | 743 | } |
971 | 744 | ||
972 | /** | 745 | /** |
973 | * omap_device_shutdown - shut down an omap_device | ||
974 | * @od: struct omap_device * to shut down | ||
975 | * | ||
976 | * Shut down omap_device @od by calling all .deactivate_func() entries | ||
977 | * in the omap_device's pm_lats table and then shutting down all of | ||
978 | * the underlying omap_hwmods. Used when a device is being "removed" | ||
979 | * or a device driver is being unloaded. Returns -EINVAL if the | ||
980 | * omap_device is not currently enabled or idle, or passes along the | ||
981 | * return value of _omap_device_deactivate(). | ||
982 | */ | ||
983 | int omap_device_shutdown(struct platform_device *pdev) | ||
984 | { | ||
985 | int ret, i; | ||
986 | struct omap_device *od; | ||
987 | |||
988 | od = to_omap_device(pdev); | ||
989 | |||
990 | if (od->_state != OMAP_DEVICE_STATE_ENABLED && | ||
991 | od->_state != OMAP_DEVICE_STATE_IDLE) { | ||
992 | dev_warn(&pdev->dev, | ||
993 | "omap_device: %s() called from invalid state %d\n", | ||
994 | __func__, od->_state); | ||
995 | return -EINVAL; | ||
996 | } | ||
997 | |||
998 | ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT); | ||
999 | |||
1000 | for (i = 0; i < od->hwmods_cnt; i++) | ||
1001 | omap_hwmod_shutdown(od->hwmods[i]); | ||
1002 | |||
1003 | od->_state = OMAP_DEVICE_STATE_SHUTDOWN; | ||
1004 | |||
1005 | return ret; | ||
1006 | } | ||
1007 | |||
1008 | /** | ||
1009 | * omap_device_assert_hardreset - set a device's hardreset line | 746 | * omap_device_assert_hardreset - set a device's hardreset line |
1010 | * @pdev: struct platform_device * to reset | 747 | * @pdev: struct platform_device * to reset |
1011 | * @name: const char * name of the reset line | 748 | * @name: const char * name of the reset line |
@@ -1061,86 +798,6 @@ int omap_device_deassert_hardreset(struct platform_device *pdev, | |||
1061 | } | 798 | } |
1062 | 799 | ||
1063 | /** | 800 | /** |
1064 | * omap_device_align_pm_lat - activate/deactivate device to match wakeup lat lim | ||
1065 | * @od: struct omap_device * | ||
1066 | * | ||
1067 | * When a device's maximum wakeup latency limit changes, call some of | ||
1068 | * the .activate_func or .deactivate_func function pointers in the | ||
1069 | * omap_device's pm_lats array to ensure that the device's maximum | ||
1070 | * wakeup latency is less than or equal to the new latency limit. | ||
1071 | * Intended to be called by OMAP PM code whenever a device's maximum | ||
1072 | * wakeup latency limit changes (e.g., via | ||
1073 | * omap_pm_set_dev_wakeup_lat()). Returns 0 if nothing needs to be | ||
1074 | * done (e.g., if the omap_device is not currently idle, or if the | ||
1075 | * wakeup latency is already current with the new limit) or passes | ||
1076 | * along the return value of _omap_device_deactivate() or | ||
1077 | * _omap_device_activate(). | ||
1078 | */ | ||
1079 | int omap_device_align_pm_lat(struct platform_device *pdev, | ||
1080 | u32 new_wakeup_lat_limit) | ||
1081 | { | ||
1082 | int ret = -EINVAL; | ||
1083 | struct omap_device *od; | ||
1084 | |||
1085 | od = to_omap_device(pdev); | ||
1086 | |||
1087 | if (new_wakeup_lat_limit == od->dev_wakeup_lat) | ||
1088 | return 0; | ||
1089 | |||
1090 | od->_dev_wakeup_lat_limit = new_wakeup_lat_limit; | ||
1091 | |||
1092 | if (od->_state != OMAP_DEVICE_STATE_IDLE) | ||
1093 | return 0; | ||
1094 | else if (new_wakeup_lat_limit > od->dev_wakeup_lat) | ||
1095 | ret = _omap_device_deactivate(od, USE_WAKEUP_LAT); | ||
1096 | else if (new_wakeup_lat_limit < od->dev_wakeup_lat) | ||
1097 | ret = _omap_device_activate(od, USE_WAKEUP_LAT); | ||
1098 | |||
1099 | return ret; | ||
1100 | } | ||
1101 | |||
1102 | /** | ||
1103 | * omap_device_get_pwrdm - return the powerdomain * associated with @od | ||
1104 | * @od: struct omap_device * | ||
1105 | * | ||
1106 | * Return the powerdomain associated with the first underlying | ||
1107 | * omap_hwmod for this omap_device. Intended for use by core OMAP PM | ||
1108 | * code. Returns NULL on error or a struct powerdomain * upon | ||
1109 | * success. | ||
1110 | */ | ||
1111 | struct powerdomain *omap_device_get_pwrdm(struct omap_device *od) | ||
1112 | { | ||
1113 | /* | ||
1114 | * XXX Assumes that all omap_hwmod powerdomains are identical. | ||
1115 | * This may not necessarily be true. There should be a sanity | ||
1116 | * check in here to WARN() if any difference appears. | ||
1117 | */ | ||
1118 | if (!od->hwmods_cnt) | ||
1119 | return NULL; | ||
1120 | |||
1121 | return omap_hwmod_get_pwrdm(od->hwmods[0]); | ||
1122 | } | ||
1123 | |||
1124 | /** | ||
1125 | * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base | ||
1126 | * @od: struct omap_device * | ||
1127 | * | ||
1128 | * Return the MPU's virtual address for the base of the hwmod, from | ||
1129 | * the ioremap() that the hwmod code does. Only valid if there is one | ||
1130 | * hwmod associated with this device. Returns NULL if there are zero | ||
1131 | * or more than one hwmods associated with this omap_device; | ||
1132 | * otherwise, passes along the return value from | ||
1133 | * omap_hwmod_get_mpu_rt_va(). | ||
1134 | */ | ||
1135 | void __iomem *omap_device_get_rt_va(struct omap_device *od) | ||
1136 | { | ||
1137 | if (od->hwmods_cnt != 1) | ||
1138 | return NULL; | ||
1139 | |||
1140 | return omap_hwmod_get_mpu_rt_va(od->hwmods[0]); | ||
1141 | } | ||
1142 | |||
1143 | /** | ||
1144 | * omap_device_get_by_hwmod_name() - convert a hwmod name to | 801 | * omap_device_get_by_hwmod_name() - convert a hwmod name to |
1145 | * device pointer. | 802 | * device pointer. |
1146 | * @oh_name: name of the hwmod device | 803 | * @oh_name: name of the hwmod device |
@@ -1174,82 +831,6 @@ struct device *omap_device_get_by_hwmod_name(const char *oh_name) | |||
1174 | 831 | ||
1175 | return &oh->od->pdev->dev; | 832 | return &oh->od->pdev->dev; |
1176 | } | 833 | } |
1177 | EXPORT_SYMBOL(omap_device_get_by_hwmod_name); | ||
1178 | |||
1179 | /* | ||
1180 | * Public functions intended for use in omap_device_pm_latency | ||
1181 | * .activate_func and .deactivate_func function pointers | ||
1182 | */ | ||
1183 | |||
1184 | /** | ||
1185 | * omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods | ||
1186 | * @od: struct omap_device *od | ||
1187 | * | ||
1188 | * Enable all underlying hwmods. Returns 0. | ||
1189 | */ | ||
1190 | int omap_device_enable_hwmods(struct omap_device *od) | ||
1191 | { | ||
1192 | int i; | ||
1193 | |||
1194 | for (i = 0; i < od->hwmods_cnt; i++) | ||
1195 | omap_hwmod_enable(od->hwmods[i]); | ||
1196 | |||
1197 | /* XXX pass along return value here? */ | ||
1198 | return 0; | ||
1199 | } | ||
1200 | |||
1201 | /** | ||
1202 | * omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods | ||
1203 | * @od: struct omap_device *od | ||
1204 | * | ||
1205 | * Idle all underlying hwmods. Returns 0. | ||
1206 | */ | ||
1207 | int omap_device_idle_hwmods(struct omap_device *od) | ||
1208 | { | ||
1209 | int i; | ||
1210 | |||
1211 | for (i = 0; i < od->hwmods_cnt; i++) | ||
1212 | omap_hwmod_idle(od->hwmods[i]); | ||
1213 | |||
1214 | /* XXX pass along return value here? */ | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | /** | ||
1219 | * omap_device_disable_clocks - disable all main and interface clocks | ||
1220 | * @od: struct omap_device *od | ||
1221 | * | ||
1222 | * Disable the main functional clock and interface clock for all of the | ||
1223 | * omap_hwmods associated with the omap_device. Returns 0. | ||
1224 | */ | ||
1225 | int omap_device_disable_clocks(struct omap_device *od) | ||
1226 | { | ||
1227 | int i; | ||
1228 | |||
1229 | for (i = 0; i < od->hwmods_cnt; i++) | ||
1230 | omap_hwmod_disable_clocks(od->hwmods[i]); | ||
1231 | |||
1232 | /* XXX pass along return value here? */ | ||
1233 | return 0; | ||
1234 | } | ||
1235 | |||
1236 | /** | ||
1237 | * omap_device_enable_clocks - enable all main and interface clocks | ||
1238 | * @od: struct omap_device *od | ||
1239 | * | ||
1240 | * Enable the main functional clock and interface clock for all of the | ||
1241 | * omap_hwmods associated with the omap_device. Returns 0. | ||
1242 | */ | ||
1243 | int omap_device_enable_clocks(struct omap_device *od) | ||
1244 | { | ||
1245 | int i; | ||
1246 | |||
1247 | for (i = 0; i < od->hwmods_cnt; i++) | ||
1248 | omap_hwmod_enable_clocks(od->hwmods[i]); | ||
1249 | |||
1250 | /* XXX pass along return value here? */ | ||
1251 | return 0; | ||
1252 | } | ||
1253 | 834 | ||
1254 | static struct notifier_block platform_nb = { | 835 | static struct notifier_block platform_nb = { |
1255 | .notifier_call = _omap_device_notifier_call, | 836 | .notifier_call = _omap_device_notifier_call, |
diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h index 0933c599bf89..044c31d50e5b 100644 --- a/arch/arm/mach-omap2/omap_device.h +++ b/arch/arm/mach-omap2/omap_device.h | |||
@@ -13,20 +13,12 @@ | |||
13 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
14 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
15 | * | 15 | * |
16 | * Eventually this type of functionality should either be | 16 | * This type of functionality should be implemented as a proper |
17 | * a) implemented via arch-specific pointers in platform_device | 17 | * omap_bus/omap_device in Linux. |
18 | * or | ||
19 | * b) implemented as a proper omap_bus/omap_device in Linux, no more | ||
20 | * platform_device | ||
21 | * | 18 | * |
22 | * omap_device differs from omap_hwmod in that it includes external | 19 | * omap_device differs from omap_hwmod in that it includes external |
23 | * (e.g., board- and system-level) integration details. omap_hwmod | 20 | * (e.g., board- and system-level) integration details. omap_hwmod |
24 | * stores hardware data that is invariant for a given OMAP chip. | 21 | * stores hardware data that is invariant for a given OMAP chip. |
25 | * | ||
26 | * To do: | ||
27 | * - GPIO integration | ||
28 | * - regulator integration | ||
29 | * | ||
30 | */ | 22 | */ |
31 | #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H | 23 | #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H |
32 | #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H | 24 | #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H |
@@ -45,19 +37,14 @@ extern struct dev_pm_domain omap_device_pm_domain; | |||
45 | #define OMAP_DEVICE_STATE_SHUTDOWN 3 | 37 | #define OMAP_DEVICE_STATE_SHUTDOWN 3 |
46 | 38 | ||
47 | /* omap_device.flags values */ | 39 | /* omap_device.flags values */ |
48 | #define OMAP_DEVICE_SUSPENDED BIT(0) | 40 | #define OMAP_DEVICE_SUSPENDED BIT(0) |
49 | #define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1) | 41 | #define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1) |
50 | 42 | ||
51 | /** | 43 | /** |
52 | * struct omap_device - omap_device wrapper for platform_devices | 44 | * struct omap_device - omap_device wrapper for platform_devices |
53 | * @pdev: platform_device | 45 | * @pdev: platform_device |
54 | * @hwmods: (one .. many per omap_device) | 46 | * @hwmods: (one .. many per omap_device) |
55 | * @hwmods_cnt: ARRAY_SIZE() of @hwmods | 47 | * @hwmods_cnt: ARRAY_SIZE() of @hwmods |
56 | * @pm_lats: ptr to an omap_device_pm_latency table | ||
57 | * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats | ||
58 | * @pm_lat_level: array index of the last odpl entry executed - -1 if never | ||
59 | * @dev_wakeup_lat: dev wakeup latency in nanoseconds | ||
60 | * @_dev_wakeup_lat_limit: dev wakeup latency limit in nsec - set by OMAP PM | ||
61 | * @_state: one of OMAP_DEVICE_STATE_* (see above) | 48 | * @_state: one of OMAP_DEVICE_STATE_* (see above) |
62 | * @flags: device flags | 49 | * @flags: device flags |
63 | * @_driver_status: one of BUS_NOTIFY_*_DRIVER from <linux/device.h> | 50 | * @_driver_status: one of BUS_NOTIFY_*_DRIVER from <linux/device.h> |
@@ -71,12 +58,7 @@ extern struct dev_pm_domain omap_device_pm_domain; | |||
71 | struct omap_device { | 58 | struct omap_device { |
72 | struct platform_device *pdev; | 59 | struct platform_device *pdev; |
73 | struct omap_hwmod **hwmods; | 60 | struct omap_hwmod **hwmods; |
74 | struct omap_device_pm_latency *pm_lats; | ||
75 | u32 dev_wakeup_lat; | ||
76 | u32 _dev_wakeup_lat_limit; | ||
77 | unsigned long _driver_status; | 61 | unsigned long _driver_status; |
78 | u8 pm_lats_cnt; | ||
79 | s8 pm_lat_level; | ||
80 | u8 hwmods_cnt; | 62 | u8 hwmods_cnt; |
81 | u8 _state; | 63 | u8 _state; |
82 | u8 flags; | 64 | u8 flags; |
@@ -86,36 +68,25 @@ struct omap_device { | |||
86 | 68 | ||
87 | int omap_device_enable(struct platform_device *pdev); | 69 | int omap_device_enable(struct platform_device *pdev); |
88 | int omap_device_idle(struct platform_device *pdev); | 70 | int omap_device_idle(struct platform_device *pdev); |
89 | int omap_device_shutdown(struct platform_device *pdev); | ||
90 | 71 | ||
91 | /* Core code interface */ | 72 | /* Core code interface */ |
92 | 73 | ||
93 | struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, | 74 | struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, |
94 | struct omap_hwmod *oh, void *pdata, | 75 | struct omap_hwmod *oh, void *pdata, |
95 | int pdata_len, | 76 | int pdata_len); |
96 | struct omap_device_pm_latency *pm_lats, | ||
97 | int pm_lats_cnt, int is_early_device); | ||
98 | 77 | ||
99 | struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | 78 | struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, |
100 | struct omap_hwmod **oh, int oh_cnt, | 79 | struct omap_hwmod **oh, int oh_cnt, |
101 | void *pdata, int pdata_len, | 80 | void *pdata, int pdata_len); |
102 | struct omap_device_pm_latency *pm_lats, | ||
103 | int pm_lats_cnt, int is_early_device); | ||
104 | 81 | ||
105 | struct omap_device *omap_device_alloc(struct platform_device *pdev, | 82 | struct omap_device *omap_device_alloc(struct platform_device *pdev, |
106 | struct omap_hwmod **ohs, int oh_cnt, | 83 | struct omap_hwmod **ohs, int oh_cnt); |
107 | struct omap_device_pm_latency *pm_lats, | ||
108 | int pm_lats_cnt); | ||
109 | void omap_device_delete(struct omap_device *od); | 84 | void omap_device_delete(struct omap_device *od); |
110 | int omap_device_register(struct platform_device *pdev); | 85 | int omap_device_register(struct platform_device *pdev); |
111 | 86 | ||
112 | void __iomem *omap_device_get_rt_va(struct omap_device *od); | ||
113 | struct device *omap_device_get_by_hwmod_name(const char *oh_name); | 87 | struct device *omap_device_get_by_hwmod_name(const char *oh_name); |
114 | 88 | ||
115 | /* OMAP PM interface */ | 89 | /* OMAP PM interface */ |
116 | int omap_device_align_pm_lat(struct platform_device *pdev, | ||
117 | u32 new_wakeup_lat_limit); | ||
118 | struct powerdomain *omap_device_get_pwrdm(struct omap_device *od); | ||
119 | int omap_device_get_context_loss_count(struct platform_device *pdev); | 90 | int omap_device_get_context_loss_count(struct platform_device *pdev); |
120 | 91 | ||
121 | /* Other */ | 92 | /* Other */ |
@@ -124,40 +95,6 @@ int omap_device_assert_hardreset(struct platform_device *pdev, | |||
124 | const char *name); | 95 | const char *name); |
125 | int omap_device_deassert_hardreset(struct platform_device *pdev, | 96 | int omap_device_deassert_hardreset(struct platform_device *pdev, |
126 | const char *name); | 97 | const char *name); |
127 | int omap_device_idle_hwmods(struct omap_device *od); | ||
128 | int omap_device_enable_hwmods(struct omap_device *od); | ||
129 | |||
130 | int omap_device_disable_clocks(struct omap_device *od); | ||
131 | int omap_device_enable_clocks(struct omap_device *od); | ||
132 | |||
133 | /* | ||
134 | * Entries should be kept in latency order ascending | ||
135 | * | ||
136 | * deact_lat is the maximum number of microseconds required to complete | ||
137 | * deactivate_func() at the device's slowest OPP. | ||
138 | * | ||
139 | * act_lat is the maximum number of microseconds required to complete | ||
140 | * activate_func() at the device's slowest OPP. | ||
141 | * | ||
142 | * This will result in some suboptimal power management decisions at fast | ||
143 | * OPPs, but avoids having to recompute all device power management decisions | ||
144 | * if the system shifts from a fast OPP to a slow OPP (in order to meet | ||
145 | * latency requirements). | ||
146 | * | ||
147 | * XXX should deactivate_func/activate_func() take platform_device pointers | ||
148 | * rather than omap_device pointers? | ||
149 | */ | ||
150 | struct omap_device_pm_latency { | ||
151 | u32 deactivate_lat; | ||
152 | u32 deactivate_lat_worst; | ||
153 | int (*deactivate_func)(struct omap_device *od); | ||
154 | u32 activate_lat; | ||
155 | u32 activate_lat_worst; | ||
156 | int (*activate_func)(struct omap_device *od); | ||
157 | u32 flags; | ||
158 | }; | ||
159 | |||
160 | #define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1) | ||
161 | 98 | ||
162 | /* Get omap_device pointer from platform_device pointer */ | 99 | /* Get omap_device pointer from platform_device pointer */ |
163 | static inline struct omap_device *to_omap_device(struct platform_device *pdev) | 100 | static inline struct omap_device *to_omap_device(struct platform_device *pdev) |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6e70707cbb34..a8984989dec8 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -139,6 +139,8 @@ | |||
139 | #include <linux/slab.h> | 139 | #include <linux/slab.h> |
140 | #include <linux/bootmem.h> | 140 | #include <linux/bootmem.h> |
141 | 141 | ||
142 | #include <asm/system_misc.h> | ||
143 | |||
142 | #include "clock.h" | 144 | #include "clock.h" |
143 | #include "omap_hwmod.h" | 145 | #include "omap_hwmod.h" |
144 | 146 | ||
@@ -2134,6 +2136,8 @@ static int _enable(struct omap_hwmod *oh) | |||
2134 | _enable_clocks(oh); | 2136 | _enable_clocks(oh); |
2135 | if (soc_ops.enable_module) | 2137 | if (soc_ops.enable_module) |
2136 | soc_ops.enable_module(oh); | 2138 | soc_ops.enable_module(oh); |
2139 | if (oh->flags & HWMOD_BLOCK_WFI) | ||
2140 | disable_hlt(); | ||
2137 | 2141 | ||
2138 | if (soc_ops.update_context_lost) | 2142 | if (soc_ops.update_context_lost) |
2139 | soc_ops.update_context_lost(oh); | 2143 | soc_ops.update_context_lost(oh); |
@@ -2195,6 +2199,8 @@ static int _idle(struct omap_hwmod *oh) | |||
2195 | _idle_sysc(oh); | 2199 | _idle_sysc(oh); |
2196 | _del_initiator_dep(oh, mpu_oh); | 2200 | _del_initiator_dep(oh, mpu_oh); |
2197 | 2201 | ||
2202 | if (oh->flags & HWMOD_BLOCK_WFI) | ||
2203 | enable_hlt(); | ||
2198 | if (soc_ops.disable_module) | 2204 | if (soc_ops.disable_module) |
2199 | soc_ops.disable_module(oh); | 2205 | soc_ops.disable_module(oh); |
2200 | 2206 | ||
@@ -2303,6 +2309,8 @@ static int _shutdown(struct omap_hwmod *oh) | |||
2303 | if (oh->_state == _HWMOD_STATE_ENABLED) { | 2309 | if (oh->_state == _HWMOD_STATE_ENABLED) { |
2304 | _del_initiator_dep(oh, mpu_oh); | 2310 | _del_initiator_dep(oh, mpu_oh); |
2305 | /* XXX what about the other system initiators here? dma, dsp */ | 2311 | /* XXX what about the other system initiators here? dma, dsp */ |
2312 | if (oh->flags & HWMOD_BLOCK_WFI) | ||
2313 | enable_hlt(); | ||
2306 | if (soc_ops.disable_module) | 2314 | if (soc_ops.disable_module) |
2307 | soc_ops.disable_module(oh); | 2315 | soc_ops.disable_module(oh); |
2308 | _disable_clocks(oh); | 2316 | _disable_clocks(oh); |
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 3ae852a522f9..80c00e706d69 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h | |||
@@ -451,6 +451,14 @@ struct omap_hwmod_omap4_prcm { | |||
451 | * enabled. This prevents the hwmod code from being able to | 451 | * enabled. This prevents the hwmod code from being able to |
452 | * enable and reset the IP block early. XXX Eventually it should | 452 | * enable and reset the IP block early. XXX Eventually it should |
453 | * be possible to query the clock framework for this information. | 453 | * be possible to query the clock framework for this information. |
454 | * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work | ||
455 | * correctly if the MPU is allowed to go idle while the | ||
456 | * peripherals are active. This is apparently true for the I2C on | ||
457 | * OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that | ||
458 | * this is really true -- we're probably not configuring something | ||
459 | * correctly, or this is being abused to deal with some PM latency | ||
460 | * issues -- but we're currently suffering from a shortage of | ||
461 | * folks who are able to track these issues down properly. | ||
454 | */ | 462 | */ |
455 | #define HWMOD_SWSUP_SIDLE (1 << 0) | 463 | #define HWMOD_SWSUP_SIDLE (1 << 0) |
456 | #define HWMOD_SWSUP_MSTANDBY (1 << 1) | 464 | #define HWMOD_SWSUP_MSTANDBY (1 << 1) |
@@ -462,6 +470,7 @@ struct omap_hwmod_omap4_prcm { | |||
462 | #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) | 470 | #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) |
463 | #define HWMOD_16BIT_REG (1 << 8) | 471 | #define HWMOD_16BIT_REG (1 << 8) |
464 | #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) | 472 | #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) |
473 | #define HWMOD_BLOCK_WFI (1 << 10) | ||
465 | 474 | ||
466 | /* | 475 | /* |
467 | * omap_hwmod._int_flags definitions | 476 | * omap_hwmod._int_flags definitions |
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index b5efe58c0be0..6a764af6c6d3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c | |||
@@ -121,7 +121,12 @@ static struct omap_hwmod omap2420_i2c1_hwmod = { | |||
121 | }, | 121 | }, |
122 | .class = &i2c_class, | 122 | .class = &i2c_class, |
123 | .dev_attr = &i2c_dev_attr, | 123 | .dev_attr = &i2c_dev_attr, |
124 | .flags = HWMOD_16BIT_REG, | 124 | /* |
125 | * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state | ||
126 | * while a transfer is active seems to cause the I2C block to | ||
127 | * timeout. Why? Good question." | ||
128 | */ | ||
129 | .flags = (HWMOD_16BIT_REG | HWMOD_BLOCK_WFI), | ||
125 | }; | 130 | }; |
126 | 131 | ||
127 | /* I2C2 */ | 132 | /* I2C2 */ |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 624a7e84a685..7ec1083ff604 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c | |||
@@ -616,7 +616,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = { | |||
616 | .clkdm_name = "abe_clkdm", | 616 | .clkdm_name = "abe_clkdm", |
617 | .mpu_irqs = omap44xx_dmic_irqs, | 617 | .mpu_irqs = omap44xx_dmic_irqs, |
618 | .sdma_reqs = omap44xx_dmic_sdma_reqs, | 618 | .sdma_reqs = omap44xx_dmic_sdma_reqs, |
619 | .main_clk = "dmic_fck", | 619 | .main_clk = "func_dmic_abe_gfclk", |
620 | .prcm = { | 620 | .prcm = { |
621 | .omap4 = { | 621 | .omap4 = { |
622 | .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET, | 622 | .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET, |
@@ -1161,7 +1161,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = { | |||
1161 | .class = &omap44xx_gpio_hwmod_class, | 1161 | .class = &omap44xx_gpio_hwmod_class, |
1162 | .clkdm_name = "l4_wkup_clkdm", | 1162 | .clkdm_name = "l4_wkup_clkdm", |
1163 | .mpu_irqs = omap44xx_gpio1_irqs, | 1163 | .mpu_irqs = omap44xx_gpio1_irqs, |
1164 | .main_clk = "gpio1_ick", | 1164 | .main_clk = "l4_wkup_clk_mux_ck", |
1165 | .prcm = { | 1165 | .prcm = { |
1166 | .omap4 = { | 1166 | .omap4 = { |
1167 | .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET, | 1167 | .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET, |
@@ -1190,7 +1190,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = { | |||
1190 | .clkdm_name = "l4_per_clkdm", | 1190 | .clkdm_name = "l4_per_clkdm", |
1191 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | 1191 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, |
1192 | .mpu_irqs = omap44xx_gpio2_irqs, | 1192 | .mpu_irqs = omap44xx_gpio2_irqs, |
1193 | .main_clk = "gpio2_ick", | 1193 | .main_clk = "l4_div_ck", |
1194 | .prcm = { | 1194 | .prcm = { |
1195 | .omap4 = { | 1195 | .omap4 = { |
1196 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET, | 1196 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET, |
@@ -1219,7 +1219,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = { | |||
1219 | .clkdm_name = "l4_per_clkdm", | 1219 | .clkdm_name = "l4_per_clkdm", |
1220 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | 1220 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, |
1221 | .mpu_irqs = omap44xx_gpio3_irqs, | 1221 | .mpu_irqs = omap44xx_gpio3_irqs, |
1222 | .main_clk = "gpio3_ick", | 1222 | .main_clk = "l4_div_ck", |
1223 | .prcm = { | 1223 | .prcm = { |
1224 | .omap4 = { | 1224 | .omap4 = { |
1225 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET, | 1225 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET, |
@@ -1248,7 +1248,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = { | |||
1248 | .clkdm_name = "l4_per_clkdm", | 1248 | .clkdm_name = "l4_per_clkdm", |
1249 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | 1249 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, |
1250 | .mpu_irqs = omap44xx_gpio4_irqs, | 1250 | .mpu_irqs = omap44xx_gpio4_irqs, |
1251 | .main_clk = "gpio4_ick", | 1251 | .main_clk = "l4_div_ck", |
1252 | .prcm = { | 1252 | .prcm = { |
1253 | .omap4 = { | 1253 | .omap4 = { |
1254 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET, | 1254 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET, |
@@ -1277,7 +1277,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = { | |||
1277 | .clkdm_name = "l4_per_clkdm", | 1277 | .clkdm_name = "l4_per_clkdm", |
1278 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | 1278 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, |
1279 | .mpu_irqs = omap44xx_gpio5_irqs, | 1279 | .mpu_irqs = omap44xx_gpio5_irqs, |
1280 | .main_clk = "gpio5_ick", | 1280 | .main_clk = "l4_div_ck", |
1281 | .prcm = { | 1281 | .prcm = { |
1282 | .omap4 = { | 1282 | .omap4 = { |
1283 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET, | 1283 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET, |
@@ -1306,7 +1306,7 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = { | |||
1306 | .clkdm_name = "l4_per_clkdm", | 1306 | .clkdm_name = "l4_per_clkdm", |
1307 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | 1307 | .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, |
1308 | .mpu_irqs = omap44xx_gpio6_irqs, | 1308 | .mpu_irqs = omap44xx_gpio6_irqs, |
1309 | .main_clk = "gpio6_ick", | 1309 | .main_clk = "l4_div_ck", |
1310 | .prcm = { | 1310 | .prcm = { |
1311 | .omap4 = { | 1311 | .omap4 = { |
1312 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET, | 1312 | .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET, |
@@ -1405,7 +1405,7 @@ static struct omap_hwmod omap44xx_gpu_hwmod = { | |||
1405 | .class = &omap44xx_gpu_hwmod_class, | 1405 | .class = &omap44xx_gpu_hwmod_class, |
1406 | .clkdm_name = "l3_gfx_clkdm", | 1406 | .clkdm_name = "l3_gfx_clkdm", |
1407 | .mpu_irqs = omap44xx_gpu_irqs, | 1407 | .mpu_irqs = omap44xx_gpu_irqs, |
1408 | .main_clk = "gpu_fck", | 1408 | .main_clk = "sgx_clk_mux", |
1409 | .prcm = { | 1409 | .prcm = { |
1410 | .omap4 = { | 1410 | .omap4 = { |
1411 | .clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET, | 1411 | .clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET, |
@@ -1446,7 +1446,7 @@ static struct omap_hwmod omap44xx_hdq1w_hwmod = { | |||
1446 | .clkdm_name = "l4_per_clkdm", | 1446 | .clkdm_name = "l4_per_clkdm", |
1447 | .flags = HWMOD_INIT_NO_RESET, /* XXX temporary */ | 1447 | .flags = HWMOD_INIT_NO_RESET, /* XXX temporary */ |
1448 | .mpu_irqs = omap44xx_hdq1w_irqs, | 1448 | .mpu_irqs = omap44xx_hdq1w_irqs, |
1449 | .main_clk = "hdq1w_fck", | 1449 | .main_clk = "func_12m_fclk", |
1450 | .prcm = { | 1450 | .prcm = { |
1451 | .omap4 = { | 1451 | .omap4 = { |
1452 | .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET, | 1452 | .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET, |
@@ -1550,7 +1550,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = { | |||
1550 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, | 1550 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
1551 | .mpu_irqs = omap44xx_i2c1_irqs, | 1551 | .mpu_irqs = omap44xx_i2c1_irqs, |
1552 | .sdma_reqs = omap44xx_i2c1_sdma_reqs, | 1552 | .sdma_reqs = omap44xx_i2c1_sdma_reqs, |
1553 | .main_clk = "i2c1_fck", | 1553 | .main_clk = "func_96m_fclk", |
1554 | .prcm = { | 1554 | .prcm = { |
1555 | .omap4 = { | 1555 | .omap4 = { |
1556 | .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET, | 1556 | .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET, |
@@ -1580,7 +1580,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = { | |||
1580 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, | 1580 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
1581 | .mpu_irqs = omap44xx_i2c2_irqs, | 1581 | .mpu_irqs = omap44xx_i2c2_irqs, |
1582 | .sdma_reqs = omap44xx_i2c2_sdma_reqs, | 1582 | .sdma_reqs = omap44xx_i2c2_sdma_reqs, |
1583 | .main_clk = "i2c2_fck", | 1583 | .main_clk = "func_96m_fclk", |
1584 | .prcm = { | 1584 | .prcm = { |
1585 | .omap4 = { | 1585 | .omap4 = { |
1586 | .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET, | 1586 | .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET, |
@@ -1610,7 +1610,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = { | |||
1610 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, | 1610 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
1611 | .mpu_irqs = omap44xx_i2c3_irqs, | 1611 | .mpu_irqs = omap44xx_i2c3_irqs, |
1612 | .sdma_reqs = omap44xx_i2c3_sdma_reqs, | 1612 | .sdma_reqs = omap44xx_i2c3_sdma_reqs, |
1613 | .main_clk = "i2c3_fck", | 1613 | .main_clk = "func_96m_fclk", |
1614 | .prcm = { | 1614 | .prcm = { |
1615 | .omap4 = { | 1615 | .omap4 = { |
1616 | .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET, | 1616 | .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET, |
@@ -1640,7 +1640,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = { | |||
1640 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, | 1640 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
1641 | .mpu_irqs = omap44xx_i2c4_irqs, | 1641 | .mpu_irqs = omap44xx_i2c4_irqs, |
1642 | .sdma_reqs = omap44xx_i2c4_sdma_reqs, | 1642 | .sdma_reqs = omap44xx_i2c4_sdma_reqs, |
1643 | .main_clk = "i2c4_fck", | 1643 | .main_clk = "func_96m_fclk", |
1644 | .prcm = { | 1644 | .prcm = { |
1645 | .omap4 = { | 1645 | .omap4 = { |
1646 | .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET, | 1646 | .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET, |
@@ -1743,7 +1743,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = { | |||
1743 | .clkdm_name = "iss_clkdm", | 1743 | .clkdm_name = "iss_clkdm", |
1744 | .mpu_irqs = omap44xx_iss_irqs, | 1744 | .mpu_irqs = omap44xx_iss_irqs, |
1745 | .sdma_reqs = omap44xx_iss_sdma_reqs, | 1745 | .sdma_reqs = omap44xx_iss_sdma_reqs, |
1746 | .main_clk = "iss_fck", | 1746 | .main_clk = "ducati_clk_mux_ck", |
1747 | .prcm = { | 1747 | .prcm = { |
1748 | .omap4 = { | 1748 | .omap4 = { |
1749 | .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET, | 1749 | .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET, |
@@ -1785,7 +1785,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = { | |||
1785 | .mpu_irqs = omap44xx_iva_irqs, | 1785 | .mpu_irqs = omap44xx_iva_irqs, |
1786 | .rst_lines = omap44xx_iva_resets, | 1786 | .rst_lines = omap44xx_iva_resets, |
1787 | .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), | 1787 | .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), |
1788 | .main_clk = "iva_fck", | 1788 | .main_clk = "dpll_iva_m5x2_ck", |
1789 | .prcm = { | 1789 | .prcm = { |
1790 | .omap4 = { | 1790 | .omap4 = { |
1791 | .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET, | 1791 | .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET, |
@@ -1829,7 +1829,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = { | |||
1829 | .class = &omap44xx_kbd_hwmod_class, | 1829 | .class = &omap44xx_kbd_hwmod_class, |
1830 | .clkdm_name = "l4_wkup_clkdm", | 1830 | .clkdm_name = "l4_wkup_clkdm", |
1831 | .mpu_irqs = omap44xx_kbd_irqs, | 1831 | .mpu_irqs = omap44xx_kbd_irqs, |
1832 | .main_clk = "kbd_fck", | 1832 | .main_clk = "sys_32k_ck", |
1833 | .prcm = { | 1833 | .prcm = { |
1834 | .omap4 = { | 1834 | .omap4 = { |
1835 | .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET, | 1835 | .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET, |
@@ -1920,7 +1920,7 @@ static struct omap_hwmod omap44xx_mcasp_hwmod = { | |||
1920 | .clkdm_name = "abe_clkdm", | 1920 | .clkdm_name = "abe_clkdm", |
1921 | .mpu_irqs = omap44xx_mcasp_irqs, | 1921 | .mpu_irqs = omap44xx_mcasp_irqs, |
1922 | .sdma_reqs = omap44xx_mcasp_sdma_reqs, | 1922 | .sdma_reqs = omap44xx_mcasp_sdma_reqs, |
1923 | .main_clk = "mcasp_fck", | 1923 | .main_clk = "func_mcasp_abe_gfclk", |
1924 | .prcm = { | 1924 | .prcm = { |
1925 | .omap4 = { | 1925 | .omap4 = { |
1926 | .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET, | 1926 | .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET, |
@@ -1972,7 +1972,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = { | |||
1972 | .clkdm_name = "abe_clkdm", | 1972 | .clkdm_name = "abe_clkdm", |
1973 | .mpu_irqs = omap44xx_mcbsp1_irqs, | 1973 | .mpu_irqs = omap44xx_mcbsp1_irqs, |
1974 | .sdma_reqs = omap44xx_mcbsp1_sdma_reqs, | 1974 | .sdma_reqs = omap44xx_mcbsp1_sdma_reqs, |
1975 | .main_clk = "mcbsp1_fck", | 1975 | .main_clk = "func_mcbsp1_gfclk", |
1976 | .prcm = { | 1976 | .prcm = { |
1977 | .omap4 = { | 1977 | .omap4 = { |
1978 | .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET, | 1978 | .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET, |
@@ -2007,7 +2007,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = { | |||
2007 | .clkdm_name = "abe_clkdm", | 2007 | .clkdm_name = "abe_clkdm", |
2008 | .mpu_irqs = omap44xx_mcbsp2_irqs, | 2008 | .mpu_irqs = omap44xx_mcbsp2_irqs, |
2009 | .sdma_reqs = omap44xx_mcbsp2_sdma_reqs, | 2009 | .sdma_reqs = omap44xx_mcbsp2_sdma_reqs, |
2010 | .main_clk = "mcbsp2_fck", | 2010 | .main_clk = "func_mcbsp2_gfclk", |
2011 | .prcm = { | 2011 | .prcm = { |
2012 | .omap4 = { | 2012 | .omap4 = { |
2013 | .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET, | 2013 | .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET, |
@@ -2042,7 +2042,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = { | |||
2042 | .clkdm_name = "abe_clkdm", | 2042 | .clkdm_name = "abe_clkdm", |
2043 | .mpu_irqs = omap44xx_mcbsp3_irqs, | 2043 | .mpu_irqs = omap44xx_mcbsp3_irqs, |
2044 | .sdma_reqs = omap44xx_mcbsp3_sdma_reqs, | 2044 | .sdma_reqs = omap44xx_mcbsp3_sdma_reqs, |
2045 | .main_clk = "mcbsp3_fck", | 2045 | .main_clk = "func_mcbsp3_gfclk", |
2046 | .prcm = { | 2046 | .prcm = { |
2047 | .omap4 = { | 2047 | .omap4 = { |
2048 | .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET, | 2048 | .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET, |
@@ -2077,7 +2077,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = { | |||
2077 | .clkdm_name = "l4_per_clkdm", | 2077 | .clkdm_name = "l4_per_clkdm", |
2078 | .mpu_irqs = omap44xx_mcbsp4_irqs, | 2078 | .mpu_irqs = omap44xx_mcbsp4_irqs, |
2079 | .sdma_reqs = omap44xx_mcbsp4_sdma_reqs, | 2079 | .sdma_reqs = omap44xx_mcbsp4_sdma_reqs, |
2080 | .main_clk = "mcbsp4_fck", | 2080 | .main_clk = "per_mcbsp4_gfclk", |
2081 | .prcm = { | 2081 | .prcm = { |
2082 | .omap4 = { | 2082 | .omap4 = { |
2083 | .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET, | 2083 | .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET, |
@@ -2140,7 +2140,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { | |||
2140 | .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE, | 2140 | .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE, |
2141 | .mpu_irqs = omap44xx_mcpdm_irqs, | 2141 | .mpu_irqs = omap44xx_mcpdm_irqs, |
2142 | .sdma_reqs = omap44xx_mcpdm_sdma_reqs, | 2142 | .sdma_reqs = omap44xx_mcpdm_sdma_reqs, |
2143 | .main_clk = "mcpdm_fck", | 2143 | .main_clk = "pad_clks_ck", |
2144 | .prcm = { | 2144 | .prcm = { |
2145 | .omap4 = { | 2145 | .omap4 = { |
2146 | .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET, | 2146 | .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET, |
@@ -2201,7 +2201,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = { | |||
2201 | .clkdm_name = "l4_per_clkdm", | 2201 | .clkdm_name = "l4_per_clkdm", |
2202 | .mpu_irqs = omap44xx_mcspi1_irqs, | 2202 | .mpu_irqs = omap44xx_mcspi1_irqs, |
2203 | .sdma_reqs = omap44xx_mcspi1_sdma_reqs, | 2203 | .sdma_reqs = omap44xx_mcspi1_sdma_reqs, |
2204 | .main_clk = "mcspi1_fck", | 2204 | .main_clk = "func_48m_fclk", |
2205 | .prcm = { | 2205 | .prcm = { |
2206 | .omap4 = { | 2206 | .omap4 = { |
2207 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, | 2207 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, |
@@ -2237,7 +2237,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = { | |||
2237 | .clkdm_name = "l4_per_clkdm", | 2237 | .clkdm_name = "l4_per_clkdm", |
2238 | .mpu_irqs = omap44xx_mcspi2_irqs, | 2238 | .mpu_irqs = omap44xx_mcspi2_irqs, |
2239 | .sdma_reqs = omap44xx_mcspi2_sdma_reqs, | 2239 | .sdma_reqs = omap44xx_mcspi2_sdma_reqs, |
2240 | .main_clk = "mcspi2_fck", | 2240 | .main_clk = "func_48m_fclk", |
2241 | .prcm = { | 2241 | .prcm = { |
2242 | .omap4 = { | 2242 | .omap4 = { |
2243 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, | 2243 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, |
@@ -2273,7 +2273,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = { | |||
2273 | .clkdm_name = "l4_per_clkdm", | 2273 | .clkdm_name = "l4_per_clkdm", |
2274 | .mpu_irqs = omap44xx_mcspi3_irqs, | 2274 | .mpu_irqs = omap44xx_mcspi3_irqs, |
2275 | .sdma_reqs = omap44xx_mcspi3_sdma_reqs, | 2275 | .sdma_reqs = omap44xx_mcspi3_sdma_reqs, |
2276 | .main_clk = "mcspi3_fck", | 2276 | .main_clk = "func_48m_fclk", |
2277 | .prcm = { | 2277 | .prcm = { |
2278 | .omap4 = { | 2278 | .omap4 = { |
2279 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, | 2279 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, |
@@ -2307,7 +2307,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = { | |||
2307 | .clkdm_name = "l4_per_clkdm", | 2307 | .clkdm_name = "l4_per_clkdm", |
2308 | .mpu_irqs = omap44xx_mcspi4_irqs, | 2308 | .mpu_irqs = omap44xx_mcspi4_irqs, |
2309 | .sdma_reqs = omap44xx_mcspi4_sdma_reqs, | 2309 | .sdma_reqs = omap44xx_mcspi4_sdma_reqs, |
2310 | .main_clk = "mcspi4_fck", | 2310 | .main_clk = "func_48m_fclk", |
2311 | .prcm = { | 2311 | .prcm = { |
2312 | .omap4 = { | 2312 | .omap4 = { |
2313 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, | 2313 | .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, |
@@ -2363,7 +2363,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = { | |||
2363 | .clkdm_name = "l3_init_clkdm", | 2363 | .clkdm_name = "l3_init_clkdm", |
2364 | .mpu_irqs = omap44xx_mmc1_irqs, | 2364 | .mpu_irqs = omap44xx_mmc1_irqs, |
2365 | .sdma_reqs = omap44xx_mmc1_sdma_reqs, | 2365 | .sdma_reqs = omap44xx_mmc1_sdma_reqs, |
2366 | .main_clk = "mmc1_fck", | 2366 | .main_clk = "hsmmc1_fclk", |
2367 | .prcm = { | 2367 | .prcm = { |
2368 | .omap4 = { | 2368 | .omap4 = { |
2369 | .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET, | 2369 | .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET, |
@@ -2392,7 +2392,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = { | |||
2392 | .clkdm_name = "l3_init_clkdm", | 2392 | .clkdm_name = "l3_init_clkdm", |
2393 | .mpu_irqs = omap44xx_mmc2_irqs, | 2393 | .mpu_irqs = omap44xx_mmc2_irqs, |
2394 | .sdma_reqs = omap44xx_mmc2_sdma_reqs, | 2394 | .sdma_reqs = omap44xx_mmc2_sdma_reqs, |
2395 | .main_clk = "mmc2_fck", | 2395 | .main_clk = "hsmmc2_fclk", |
2396 | .prcm = { | 2396 | .prcm = { |
2397 | .omap4 = { | 2397 | .omap4 = { |
2398 | .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET, | 2398 | .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET, |
@@ -2420,7 +2420,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = { | |||
2420 | .clkdm_name = "l4_per_clkdm", | 2420 | .clkdm_name = "l4_per_clkdm", |
2421 | .mpu_irqs = omap44xx_mmc3_irqs, | 2421 | .mpu_irqs = omap44xx_mmc3_irqs, |
2422 | .sdma_reqs = omap44xx_mmc3_sdma_reqs, | 2422 | .sdma_reqs = omap44xx_mmc3_sdma_reqs, |
2423 | .main_clk = "mmc3_fck", | 2423 | .main_clk = "func_48m_fclk", |
2424 | .prcm = { | 2424 | .prcm = { |
2425 | .omap4 = { | 2425 | .omap4 = { |
2426 | .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET, | 2426 | .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET, |
@@ -2448,7 +2448,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = { | |||
2448 | .clkdm_name = "l4_per_clkdm", | 2448 | .clkdm_name = "l4_per_clkdm", |
2449 | .mpu_irqs = omap44xx_mmc4_irqs, | 2449 | .mpu_irqs = omap44xx_mmc4_irqs, |
2450 | .sdma_reqs = omap44xx_mmc4_sdma_reqs, | 2450 | .sdma_reqs = omap44xx_mmc4_sdma_reqs, |
2451 | .main_clk = "mmc4_fck", | 2451 | .main_clk = "func_48m_fclk", |
2452 | .prcm = { | 2452 | .prcm = { |
2453 | .omap4 = { | 2453 | .omap4 = { |
2454 | .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET, | 2454 | .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET, |
@@ -2476,7 +2476,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = { | |||
2476 | .clkdm_name = "l4_per_clkdm", | 2476 | .clkdm_name = "l4_per_clkdm", |
2477 | .mpu_irqs = omap44xx_mmc5_irqs, | 2477 | .mpu_irqs = omap44xx_mmc5_irqs, |
2478 | .sdma_reqs = omap44xx_mmc5_sdma_reqs, | 2478 | .sdma_reqs = omap44xx_mmc5_sdma_reqs, |
2479 | .main_clk = "mmc5_fck", | 2479 | .main_clk = "func_48m_fclk", |
2480 | .prcm = { | 2480 | .prcm = { |
2481 | .omap4 = { | 2481 | .omap4 = { |
2482 | .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET, | 2482 | .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET, |
@@ -2718,7 +2718,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { | |||
2718 | .name = "ocp2scp_usb_phy", | 2718 | .name = "ocp2scp_usb_phy", |
2719 | .class = &omap44xx_ocp2scp_hwmod_class, | 2719 | .class = &omap44xx_ocp2scp_hwmod_class, |
2720 | .clkdm_name = "l3_init_clkdm", | 2720 | .clkdm_name = "l3_init_clkdm", |
2721 | .main_clk = "ocp2scp_usb_phy_phy_48m", | 2721 | .main_clk = "func_48m_fclk", |
2722 | .prcm = { | 2722 | .prcm = { |
2723 | .omap4 = { | 2723 | .omap4 = { |
2724 | .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, | 2724 | .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, |
@@ -3155,7 +3155,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = { | |||
3155 | .clkdm_name = "l4_wkup_clkdm", | 3155 | .clkdm_name = "l4_wkup_clkdm", |
3156 | .flags = HWMOD_SET_DEFAULT_CLOCKACT, | 3156 | .flags = HWMOD_SET_DEFAULT_CLOCKACT, |
3157 | .mpu_irqs = omap44xx_timer1_irqs, | 3157 | .mpu_irqs = omap44xx_timer1_irqs, |
3158 | .main_clk = "timer1_fck", | 3158 | .main_clk = "dmt1_clk_mux", |
3159 | .prcm = { | 3159 | .prcm = { |
3160 | .omap4 = { | 3160 | .omap4 = { |
3161 | .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, | 3161 | .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, |
@@ -3178,7 +3178,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = { | |||
3178 | .clkdm_name = "l4_per_clkdm", | 3178 | .clkdm_name = "l4_per_clkdm", |
3179 | .flags = HWMOD_SET_DEFAULT_CLOCKACT, | 3179 | .flags = HWMOD_SET_DEFAULT_CLOCKACT, |
3180 | .mpu_irqs = omap44xx_timer2_irqs, | 3180 | .mpu_irqs = omap44xx_timer2_irqs, |
3181 | .main_clk = "timer2_fck", | 3181 | .main_clk = "cm2_dm2_mux", |
3182 | .prcm = { | 3182 | .prcm = { |
3183 | .omap4 = { | 3183 | .omap4 = { |
3184 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET, | 3184 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET, |
@@ -3199,7 +3199,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = { | |||
3199 | .class = &omap44xx_timer_hwmod_class, | 3199 | .class = &omap44xx_timer_hwmod_class, |
3200 | .clkdm_name = "l4_per_clkdm", | 3200 | .clkdm_name = "l4_per_clkdm", |
3201 | .mpu_irqs = omap44xx_timer3_irqs, | 3201 | .mpu_irqs = omap44xx_timer3_irqs, |
3202 | .main_clk = "timer3_fck", | 3202 | .main_clk = "cm2_dm3_mux", |
3203 | .prcm = { | 3203 | .prcm = { |
3204 | .omap4 = { | 3204 | .omap4 = { |
3205 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET, | 3205 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET, |
@@ -3220,7 +3220,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = { | |||
3220 | .class = &omap44xx_timer_hwmod_class, | 3220 | .class = &omap44xx_timer_hwmod_class, |
3221 | .clkdm_name = "l4_per_clkdm", | 3221 | .clkdm_name = "l4_per_clkdm", |
3222 | .mpu_irqs = omap44xx_timer4_irqs, | 3222 | .mpu_irqs = omap44xx_timer4_irqs, |
3223 | .main_clk = "timer4_fck", | 3223 | .main_clk = "cm2_dm4_mux", |
3224 | .prcm = { | 3224 | .prcm = { |
3225 | .omap4 = { | 3225 | .omap4 = { |
3226 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET, | 3226 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET, |
@@ -3241,7 +3241,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = { | |||
3241 | .class = &omap44xx_timer_hwmod_class, | 3241 | .class = &omap44xx_timer_hwmod_class, |
3242 | .clkdm_name = "abe_clkdm", | 3242 | .clkdm_name = "abe_clkdm", |
3243 | .mpu_irqs = omap44xx_timer5_irqs, | 3243 | .mpu_irqs = omap44xx_timer5_irqs, |
3244 | .main_clk = "timer5_fck", | 3244 | .main_clk = "timer5_sync_mux", |
3245 | .prcm = { | 3245 | .prcm = { |
3246 | .omap4 = { | 3246 | .omap4 = { |
3247 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET, | 3247 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET, |
@@ -3263,8 +3263,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = { | |||
3263 | .class = &omap44xx_timer_hwmod_class, | 3263 | .class = &omap44xx_timer_hwmod_class, |
3264 | .clkdm_name = "abe_clkdm", | 3264 | .clkdm_name = "abe_clkdm", |
3265 | .mpu_irqs = omap44xx_timer6_irqs, | 3265 | .mpu_irqs = omap44xx_timer6_irqs, |
3266 | 3266 | .main_clk = "timer6_sync_mux", | |
3267 | .main_clk = "timer6_fck", | ||
3268 | .prcm = { | 3267 | .prcm = { |
3269 | .omap4 = { | 3268 | .omap4 = { |
3270 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET, | 3269 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET, |
@@ -3286,7 +3285,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = { | |||
3286 | .class = &omap44xx_timer_hwmod_class, | 3285 | .class = &omap44xx_timer_hwmod_class, |
3287 | .clkdm_name = "abe_clkdm", | 3286 | .clkdm_name = "abe_clkdm", |
3288 | .mpu_irqs = omap44xx_timer7_irqs, | 3287 | .mpu_irqs = omap44xx_timer7_irqs, |
3289 | .main_clk = "timer7_fck", | 3288 | .main_clk = "timer7_sync_mux", |
3290 | .prcm = { | 3289 | .prcm = { |
3291 | .omap4 = { | 3290 | .omap4 = { |
3292 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET, | 3291 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET, |
@@ -3308,7 +3307,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = { | |||
3308 | .class = &omap44xx_timer_hwmod_class, | 3307 | .class = &omap44xx_timer_hwmod_class, |
3309 | .clkdm_name = "abe_clkdm", | 3308 | .clkdm_name = "abe_clkdm", |
3310 | .mpu_irqs = omap44xx_timer8_irqs, | 3309 | .mpu_irqs = omap44xx_timer8_irqs, |
3311 | .main_clk = "timer8_fck", | 3310 | .main_clk = "timer8_sync_mux", |
3312 | .prcm = { | 3311 | .prcm = { |
3313 | .omap4 = { | 3312 | .omap4 = { |
3314 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET, | 3313 | .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET, |
@@ -3330,7 +3329,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = { | |||
3330 | .class = &omap44xx_timer_hwmod_class, | 3329 | .class = &omap44xx_timer_hwmod_class, |
3331 | .clkdm_name = "l4_per_clkdm", | 3330 | .clkdm_name = "l4_per_clkdm", |
3332 | .mpu_irqs = omap44xx_timer9_irqs, | 3331 | .mpu_irqs = omap44xx_timer9_irqs, |
3333 | .main_clk = "timer9_fck", | 3332 | .main_clk = "cm2_dm9_mux", |
3334 | .prcm = { | 3333 | .prcm = { |
3335 | .omap4 = { | 3334 | .omap4 = { |
3336 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET, | 3335 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET, |
@@ -3353,7 +3352,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = { | |||
3353 | .clkdm_name = "l4_per_clkdm", | 3352 | .clkdm_name = "l4_per_clkdm", |
3354 | .flags = HWMOD_SET_DEFAULT_CLOCKACT, | 3353 | .flags = HWMOD_SET_DEFAULT_CLOCKACT, |
3355 | .mpu_irqs = omap44xx_timer10_irqs, | 3354 | .mpu_irqs = omap44xx_timer10_irqs, |
3356 | .main_clk = "timer10_fck", | 3355 | .main_clk = "cm2_dm10_mux", |
3357 | .prcm = { | 3356 | .prcm = { |
3358 | .omap4 = { | 3357 | .omap4 = { |
3359 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET, | 3358 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET, |
@@ -3375,7 +3374,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = { | |||
3375 | .class = &omap44xx_timer_hwmod_class, | 3374 | .class = &omap44xx_timer_hwmod_class, |
3376 | .clkdm_name = "l4_per_clkdm", | 3375 | .clkdm_name = "l4_per_clkdm", |
3377 | .mpu_irqs = omap44xx_timer11_irqs, | 3376 | .mpu_irqs = omap44xx_timer11_irqs, |
3378 | .main_clk = "timer11_fck", | 3377 | .main_clk = "cm2_dm11_mux", |
3379 | .prcm = { | 3378 | .prcm = { |
3380 | .omap4 = { | 3379 | .omap4 = { |
3381 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET, | 3380 | .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET, |
@@ -3426,7 +3425,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = { | |||
3426 | .clkdm_name = "l4_per_clkdm", | 3425 | .clkdm_name = "l4_per_clkdm", |
3427 | .mpu_irqs = omap44xx_uart1_irqs, | 3426 | .mpu_irqs = omap44xx_uart1_irqs, |
3428 | .sdma_reqs = omap44xx_uart1_sdma_reqs, | 3427 | .sdma_reqs = omap44xx_uart1_sdma_reqs, |
3429 | .main_clk = "uart1_fck", | 3428 | .main_clk = "func_48m_fclk", |
3430 | .prcm = { | 3429 | .prcm = { |
3431 | .omap4 = { | 3430 | .omap4 = { |
3432 | .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET, | 3431 | .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET, |
@@ -3454,7 +3453,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = { | |||
3454 | .clkdm_name = "l4_per_clkdm", | 3453 | .clkdm_name = "l4_per_clkdm", |
3455 | .mpu_irqs = omap44xx_uart2_irqs, | 3454 | .mpu_irqs = omap44xx_uart2_irqs, |
3456 | .sdma_reqs = omap44xx_uart2_sdma_reqs, | 3455 | .sdma_reqs = omap44xx_uart2_sdma_reqs, |
3457 | .main_clk = "uart2_fck", | 3456 | .main_clk = "func_48m_fclk", |
3458 | .prcm = { | 3457 | .prcm = { |
3459 | .omap4 = { | 3458 | .omap4 = { |
3460 | .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET, | 3459 | .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET, |
@@ -3483,7 +3482,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = { | |||
3483 | .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, | 3482 | .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, |
3484 | .mpu_irqs = omap44xx_uart3_irqs, | 3483 | .mpu_irqs = omap44xx_uart3_irqs, |
3485 | .sdma_reqs = omap44xx_uart3_sdma_reqs, | 3484 | .sdma_reqs = omap44xx_uart3_sdma_reqs, |
3486 | .main_clk = "uart3_fck", | 3485 | .main_clk = "func_48m_fclk", |
3487 | .prcm = { | 3486 | .prcm = { |
3488 | .omap4 = { | 3487 | .omap4 = { |
3489 | .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET, | 3488 | .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET, |
@@ -3511,7 +3510,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = { | |||
3511 | .clkdm_name = "l4_per_clkdm", | 3510 | .clkdm_name = "l4_per_clkdm", |
3512 | .mpu_irqs = omap44xx_uart4_irqs, | 3511 | .mpu_irqs = omap44xx_uart4_irqs, |
3513 | .sdma_reqs = omap44xx_uart4_sdma_reqs, | 3512 | .sdma_reqs = omap44xx_uart4_sdma_reqs, |
3514 | .main_clk = "uart4_fck", | 3513 | .main_clk = "func_48m_fclk", |
3515 | .prcm = { | 3514 | .prcm = { |
3516 | .omap4 = { | 3515 | .omap4 = { |
3517 | .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET, | 3516 | .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET, |
@@ -3790,7 +3789,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = { | |||
3790 | .class = &omap44xx_wd_timer_hwmod_class, | 3789 | .class = &omap44xx_wd_timer_hwmod_class, |
3791 | .clkdm_name = "l4_wkup_clkdm", | 3790 | .clkdm_name = "l4_wkup_clkdm", |
3792 | .mpu_irqs = omap44xx_wd_timer2_irqs, | 3791 | .mpu_irqs = omap44xx_wd_timer2_irqs, |
3793 | .main_clk = "wd_timer2_fck", | 3792 | .main_clk = "sys_32k_ck", |
3794 | .prcm = { | 3793 | .prcm = { |
3795 | .omap4 = { | 3794 | .omap4 = { |
3796 | .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET, | 3795 | .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET, |
@@ -3811,7 +3810,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = { | |||
3811 | .class = &omap44xx_wd_timer_hwmod_class, | 3810 | .class = &omap44xx_wd_timer_hwmod_class, |
3812 | .clkdm_name = "abe_clkdm", | 3811 | .clkdm_name = "abe_clkdm", |
3813 | .mpu_irqs = omap44xx_wd_timer3_irqs, | 3812 | .mpu_irqs = omap44xx_wd_timer3_irqs, |
3814 | .main_clk = "wd_timer3_fck", | 3813 | .main_clk = "sys_32k_ck", |
3815 | .prcm = { | 3814 | .prcm = { |
3816 | .omap4 = { | 3815 | .omap4 = { |
3817 | .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET, | 3816 | .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET, |
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index e0ac8a31d4e0..1edd000a8143 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -83,10 +83,8 @@ static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) | |||
83 | strncmp(clkdm->name, "dpll", 4) == 0) | 83 | strncmp(clkdm->name, "dpll", 4) == 0) |
84 | return 0; | 84 | return 0; |
85 | 85 | ||
86 | seq_printf(s, "%s->%s (%d)", clkdm->name, | 86 | seq_printf(s, "%s->%s (%d)\n", clkdm->name, clkdm->pwrdm.ptr->name, |
87 | clkdm->pwrdm.ptr->name, | 87 | clkdm->usecount); |
88 | atomic_read(&clkdm->usecount)); | ||
89 | seq_printf(s, "\n"); | ||
90 | 88 | ||
91 | return 0; | 89 | return 0; |
92 | } | 90 | } |
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 9c65eddd97cc..cd6682df5625 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include "pm.h" | 32 | #include "pm.h" |
33 | #include "twl-common.h" | 33 | #include "twl-common.h" |
34 | 34 | ||
35 | static struct omap_device_pm_latency *pm_lats; | ||
36 | |||
37 | /* | 35 | /* |
38 | * omap_pm_suspend: points to a function that does the SoC-specific | 36 | * omap_pm_suspend: points to a function that does the SoC-specific |
39 | * suspend work | 37 | * suspend work |
@@ -82,7 +80,7 @@ static int __init _init_omap_device(char *name) | |||
82 | __func__, name)) | 80 | __func__, name)) |
83 | return -ENODEV; | 81 | return -ENODEV; |
84 | 82 | ||
85 | pdev = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false); | 83 | pdev = omap_device_build(oh->name, 0, oh, NULL, 0); |
86 | if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n", | 84 | if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n", |
87 | __func__, name)) | 85 | __func__, name)) |
88 | return -ENODEV; | 86 | return -ENODEV; |
@@ -108,80 +106,19 @@ static void __init omap2_init_processor_devices(void) | |||
108 | } | 106 | } |
109 | } | 107 | } |
110 | 108 | ||
111 | /* Types of sleep_switch used in omap_set_pwrdm_state */ | ||
112 | #define FORCEWAKEUP_SWITCH 0 | ||
113 | #define LOWPOWERSTATE_SWITCH 1 | ||
114 | |||
115 | int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) | 109 | int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) |
116 | { | 110 | { |
111 | /* XXX The usecount test is racy */ | ||
117 | if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) && | 112 | if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) && |
118 | !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) | 113 | !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) |
119 | clkdm_allow_idle(clkdm); | 114 | clkdm_allow_idle(clkdm); |
120 | else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && | 115 | else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && |
121 | atomic_read(&clkdm->usecount) == 0) | 116 | clkdm->usecount == 0) |
122 | clkdm_sleep(clkdm); | 117 | clkdm_sleep(clkdm); |
123 | return 0; | 118 | return 0; |
124 | } | 119 | } |
125 | 120 | ||
126 | /* | 121 | /* |
127 | * This sets pwrdm state (other than mpu & core. Currently only ON & | ||
128 | * RET are supported. | ||
129 | */ | ||
130 | int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst) | ||
131 | { | ||
132 | u8 curr_pwrst, next_pwrst; | ||
133 | int sleep_switch = -1, ret = 0, hwsup = 0; | ||
134 | |||
135 | if (!pwrdm || IS_ERR(pwrdm)) | ||
136 | return -EINVAL; | ||
137 | |||
138 | while (!(pwrdm->pwrsts & (1 << pwrst))) { | ||
139 | if (pwrst == PWRDM_POWER_OFF) | ||
140 | return ret; | ||
141 | pwrst--; | ||
142 | } | ||
143 | |||
144 | next_pwrst = pwrdm_read_next_pwrst(pwrdm); | ||
145 | if (next_pwrst == pwrst) | ||
146 | return ret; | ||
147 | |||
148 | curr_pwrst = pwrdm_read_pwrst(pwrdm); | ||
149 | if (curr_pwrst < PWRDM_POWER_ON) { | ||
150 | if ((curr_pwrst > pwrst) && | ||
151 | (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { | ||
152 | sleep_switch = LOWPOWERSTATE_SWITCH; | ||
153 | } else { | ||
154 | hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); | ||
155 | clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); | ||
156 | sleep_switch = FORCEWAKEUP_SWITCH; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | ret = pwrdm_set_next_pwrst(pwrdm, pwrst); | ||
161 | if (ret) | ||
162 | pr_err("%s: unable to set power state of powerdomain: %s\n", | ||
163 | __func__, pwrdm->name); | ||
164 | |||
165 | switch (sleep_switch) { | ||
166 | case FORCEWAKEUP_SWITCH: | ||
167 | if (hwsup) | ||
168 | clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); | ||
169 | else | ||
170 | clkdm_sleep(pwrdm->pwrdm_clkdms[0]); | ||
171 | break; | ||
172 | case LOWPOWERSTATE_SWITCH: | ||
173 | pwrdm_set_lowpwrstchange(pwrdm); | ||
174 | pwrdm_wait_transition(pwrdm); | ||
175 | pwrdm_state_switch(pwrdm); | ||
176 | break; | ||
177 | } | ||
178 | |||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | |||
183 | |||
184 | /* | ||
185 | * This API is to be called during init to set the various voltage | 122 | * This API is to be called during init to set the various voltage |
186 | * domains to the voltage as per the opp table. Typically we boot up | 123 | * domains to the voltage as per the opp table. Typically we boot up |
187 | * at the nominal voltage. So this function finds out the rate of | 124 | * at the nominal voltage. So this function finds out the rate of |
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index c22503b17abd..7bdd22afce69 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -33,7 +33,6 @@ static inline int omap4_idle_init(void) | |||
33 | extern void *omap3_secure_ram_storage; | 33 | extern void *omap3_secure_ram_storage; |
34 | extern void omap3_pm_off_mode_enable(int); | 34 | extern void omap3_pm_off_mode_enable(int); |
35 | extern void omap_sram_idle(void); | 35 | extern void omap_sram_idle(void); |
36 | extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); | ||
37 | extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); | 36 | extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); |
38 | extern int (*omap_pm_suspend)(void); | 37 | extern int (*omap_pm_suspend)(void); |
39 | 38 | ||
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c333fa6dffa8..b2a4df623545 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -90,11 +90,7 @@ static int omap2_enter_full_retention(void) | |||
90 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); | 90 | omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); |
91 | omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); | 91 | omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); |
92 | 92 | ||
93 | /* | 93 | pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); |
94 | * Set MPU powerdomain's next power state to RETENTION; | ||
95 | * preserve logic state during retention | ||
96 | */ | ||
97 | pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); | ||
98 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); | 94 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); |
99 | 95 | ||
100 | /* Workaround to kill USB */ | 96 | /* Workaround to kill USB */ |
@@ -137,15 +133,10 @@ no_sleep: | |||
137 | /* Mask future PRCM-to-MPU interrupts */ | 133 | /* Mask future PRCM-to-MPU interrupts */ |
138 | omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); | 134 | omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); |
139 | 135 | ||
140 | return 0; | 136 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); |
141 | } | 137 | pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON); |
142 | |||
143 | static int omap2_i2c_active(void) | ||
144 | { | ||
145 | u32 l; | ||
146 | 138 | ||
147 | l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); | 139 | return 0; |
148 | return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK); | ||
149 | } | 140 | } |
150 | 141 | ||
151 | static int sti_console_enabled; | 142 | static int sti_console_enabled; |
@@ -172,11 +163,6 @@ static int omap2_allow_mpu_retention(void) | |||
172 | 163 | ||
173 | static void omap2_enter_mpu_retention(void) | 164 | static void omap2_enter_mpu_retention(void) |
174 | { | 165 | { |
175 | /* Putting MPU into the WFI state while a transfer is active | ||
176 | * seems to cause the I2C block to timeout. Why? Good question. */ | ||
177 | if (omap2_i2c_active()) | ||
178 | return; | ||
179 | |||
180 | /* The peripherals seem not to be able to wake up the MPU when | 166 | /* The peripherals seem not to be able to wake up the MPU when |
181 | * it is in retention mode. */ | 167 | * it is in retention mode. */ |
182 | if (omap2_allow_mpu_retention()) { | 168 | if (omap2_allow_mpu_retention()) { |
@@ -186,17 +172,16 @@ static void omap2_enter_mpu_retention(void) | |||
186 | omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); | 172 | omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); |
187 | 173 | ||
188 | /* Try to enter MPU retention */ | 174 | /* Try to enter MPU retention */ |
189 | omap2_prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | | 175 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); |
190 | OMAP_LOGICRETSTATE_MASK, | 176 | |
191 | MPU_MOD, OMAP2_PM_PWSTCTRL); | ||
192 | } else { | 177 | } else { |
193 | /* Block MPU retention */ | 178 | /* Block MPU retention */ |
194 | 179 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); | |
195 | omap2_prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD, | ||
196 | OMAP2_PM_PWSTCTRL); | ||
197 | } | 180 | } |
198 | 181 | ||
199 | omap2_sram_idle(); | 182 | omap2_sram_idle(); |
183 | |||
184 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); | ||
200 | } | 185 | } |
201 | 186 | ||
202 | static int omap2_can_sleep(void) | 187 | static int omap2_can_sleep(void) |
@@ -251,25 +236,17 @@ static void __init prcm_setup_regs(void) | |||
251 | for (i = 0; i < num_mem_banks; i++) | 236 | for (i = 0; i < num_mem_banks; i++) |
252 | pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET); | 237 | pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET); |
253 | 238 | ||
254 | /* Set CORE powerdomain's next power state to RETENTION */ | 239 | pwrdm_set_logic_retst(core_pwrdm, PWRDM_POWER_RET); |
255 | pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); | ||
256 | 240 | ||
257 | /* | ||
258 | * Set MPU powerdomain's next power state to RETENTION; | ||
259 | * preserve logic state during retention | ||
260 | */ | ||
261 | pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); | 241 | pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); |
262 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); | ||
263 | 242 | ||
264 | /* Force-power down DSP, GFX powerdomains */ | 243 | /* Force-power down DSP, GFX powerdomains */ |
265 | 244 | ||
266 | pwrdm = clkdm_get_pwrdm(dsp_clkdm); | 245 | pwrdm = clkdm_get_pwrdm(dsp_clkdm); |
267 | pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); | 246 | pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); |
268 | clkdm_sleep(dsp_clkdm); | ||
269 | 247 | ||
270 | pwrdm = clkdm_get_pwrdm(gfx_clkdm); | 248 | pwrdm = clkdm_get_pwrdm(gfx_clkdm); |
271 | pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); | 249 | pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); |
272 | clkdm_sleep(gfx_clkdm); | ||
273 | 250 | ||
274 | /* Enable hardware-supervised idle for all clkdms */ | 251 | /* Enable hardware-supervised idle for all clkdms */ |
275 | clkdm_for_each(omap_pm_clkdms_setup, NULL); | 252 | clkdm_for_each(omap_pm_clkdms_setup, NULL); |
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c index 75052b3bc943..9debf822687c 100644 --- a/arch/arm/mach-omap2/pmu.c +++ b/arch/arm/mach-omap2/pmu.c | |||
@@ -48,8 +48,7 @@ static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[]) | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0, | 51 | omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0); |
52 | NULL, 0, 0); | ||
53 | WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n", | 52 | WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n", |
54 | dev_name); | 53 | dev_name); |
55 | 54 | ||
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index dea62a9aad07..8e61d80bf6b3 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/spinlock.h> | ||
22 | #include <trace/events/power.h> | 23 | #include <trace/events/power.h> |
23 | 24 | ||
24 | #include "cm2xxx_3xxx.h" | 25 | #include "cm2xxx_3xxx.h" |
@@ -42,6 +43,16 @@ enum { | |||
42 | PWRDM_STATE_PREV, | 43 | PWRDM_STATE_PREV, |
43 | }; | 44 | }; |
44 | 45 | ||
46 | /* | ||
47 | * Types of sleep_switch used internally in omap_set_pwrdm_state() | ||
48 | * and its associated static functions | ||
49 | * | ||
50 | * XXX Better documentation is needed here | ||
51 | */ | ||
52 | #define ALREADYACTIVE_SWITCH 0 | ||
53 | #define FORCEWAKEUP_SWITCH 1 | ||
54 | #define LOWPOWERSTATE_SWITCH 2 | ||
55 | #define ERROR_SWITCH 3 | ||
45 | 56 | ||
46 | /* pwrdm_list contains all registered struct powerdomains */ | 57 | /* pwrdm_list contains all registered struct powerdomains */ |
47 | static LIST_HEAD(pwrdm_list); | 58 | static LIST_HEAD(pwrdm_list); |
@@ -101,6 +112,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm) | |||
101 | pwrdm->voltdm.ptr = voltdm; | 112 | pwrdm->voltdm.ptr = voltdm; |
102 | INIT_LIST_HEAD(&pwrdm->voltdm_node); | 113 | INIT_LIST_HEAD(&pwrdm->voltdm_node); |
103 | voltdm_add_pwrdm(voltdm, pwrdm); | 114 | voltdm_add_pwrdm(voltdm, pwrdm); |
115 | spin_lock_init(&pwrdm->_lock); | ||
104 | 116 | ||
105 | list_add(&pwrdm->node, &pwrdm_list); | 117 | list_add(&pwrdm->node, &pwrdm_list); |
106 | 118 | ||
@@ -112,7 +124,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm) | |||
112 | for (i = 0; i < pwrdm->banks; i++) | 124 | for (i = 0; i < pwrdm->banks; i++) |
113 | pwrdm->ret_mem_off_counter[i] = 0; | 125 | pwrdm->ret_mem_off_counter[i] = 0; |
114 | 126 | ||
115 | pwrdm_wait_transition(pwrdm); | 127 | arch_pwrdm->pwrdm_wait_transition(pwrdm); |
116 | pwrdm->state = pwrdm_read_pwrst(pwrdm); | 128 | pwrdm->state = pwrdm_read_pwrst(pwrdm); |
117 | pwrdm->state_counter[pwrdm->state] = 1; | 129 | pwrdm->state_counter[pwrdm->state] = 1; |
118 | 130 | ||
@@ -143,7 +155,7 @@ static void _update_logic_membank_counters(struct powerdomain *pwrdm) | |||
143 | static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) | 155 | static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) |
144 | { | 156 | { |
145 | 157 | ||
146 | int prev, state, trace_state = 0; | 158 | int prev, next, state, trace_state = 0; |
147 | 159 | ||
148 | if (pwrdm == NULL) | 160 | if (pwrdm == NULL) |
149 | return -EINVAL; | 161 | return -EINVAL; |
@@ -164,9 +176,10 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) | |||
164 | * If the power domain did not hit the desired state, | 176 | * If the power domain did not hit the desired state, |
165 | * generate a trace event with both the desired and hit states | 177 | * generate a trace event with both the desired and hit states |
166 | */ | 178 | */ |
167 | if (state != prev) { | 179 | next = pwrdm_read_next_pwrst(pwrdm); |
180 | if (next != prev) { | ||
168 | trace_state = (PWRDM_TRACE_STATES_FLAG | | 181 | trace_state = (PWRDM_TRACE_STATES_FLAG | |
169 | ((state & OMAP_POWERSTATE_MASK) << 8) | | 182 | ((next & OMAP_POWERSTATE_MASK) << 8) | |
170 | ((prev & OMAP_POWERSTATE_MASK) << 0)); | 183 | ((prev & OMAP_POWERSTATE_MASK) << 0)); |
171 | trace_power_domain_target(pwrdm->name, trace_state, | 184 | trace_power_domain_target(pwrdm->name, trace_state, |
172 | smp_processor_id()); | 185 | smp_processor_id()); |
@@ -199,6 +212,80 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) | |||
199 | return 0; | 212 | return 0; |
200 | } | 213 | } |
201 | 214 | ||
215 | /** | ||
216 | * _pwrdm_save_clkdm_state_and_activate - prepare for power state change | ||
217 | * @pwrdm: struct powerdomain * to operate on | ||
218 | * @curr_pwrst: current power state of @pwrdm | ||
219 | * @pwrst: power state to switch to | ||
220 | * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised | ||
221 | * | ||
222 | * Determine whether the powerdomain needs to be turned on before | ||
223 | * attempting to switch power states. Called by | ||
224 | * omap_set_pwrdm_state(). NOTE that if the powerdomain contains | ||
225 | * multiple clockdomains, this code assumes that the first clockdomain | ||
226 | * supports software-supervised wakeup mode - potentially a problem. | ||
227 | * Returns the power state switch mode currently in use (see the | ||
228 | * "Types of sleep_switch" comment above). | ||
229 | */ | ||
230 | static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, | ||
231 | u8 curr_pwrst, u8 pwrst, | ||
232 | bool *hwsup) | ||
233 | { | ||
234 | u8 sleep_switch; | ||
235 | |||
236 | if (curr_pwrst < 0) { | ||
237 | WARN_ON(1); | ||
238 | sleep_switch = ERROR_SWITCH; | ||
239 | } else if (curr_pwrst < PWRDM_POWER_ON) { | ||
240 | if (curr_pwrst > pwrst && | ||
241 | pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && | ||
242 | arch_pwrdm->pwrdm_set_lowpwrstchange) { | ||
243 | sleep_switch = LOWPOWERSTATE_SWITCH; | ||
244 | } else { | ||
245 | *hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); | ||
246 | clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]); | ||
247 | sleep_switch = FORCEWAKEUP_SWITCH; | ||
248 | } | ||
249 | } else { | ||
250 | sleep_switch = ALREADYACTIVE_SWITCH; | ||
251 | } | ||
252 | |||
253 | return sleep_switch; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change | ||
258 | * @pwrdm: struct powerdomain * to operate on | ||
259 | * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate() | ||
260 | * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode? | ||
261 | * | ||
262 | * Restore the clockdomain state perturbed by | ||
263 | * _pwrdm_save_clkdm_state_and_activate(), and call the power state | ||
264 | * bookkeeping code. Called by omap_set_pwrdm_state(). NOTE that if | ||
265 | * the powerdomain contains multiple clockdomains, this assumes that | ||
266 | * the first associated clockdomain supports either | ||
267 | * hardware-supervised idle control in the register, or | ||
268 | * software-supervised sleep. No return value. | ||
269 | */ | ||
270 | static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm, | ||
271 | u8 sleep_switch, bool hwsup) | ||
272 | { | ||
273 | switch (sleep_switch) { | ||
274 | case FORCEWAKEUP_SWITCH: | ||
275 | if (hwsup) | ||
276 | clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]); | ||
277 | else | ||
278 | clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]); | ||
279 | break; | ||
280 | case LOWPOWERSTATE_SWITCH: | ||
281 | if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && | ||
282 | arch_pwrdm->pwrdm_set_lowpwrstchange) | ||
283 | arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm); | ||
284 | pwrdm_state_switch_nolock(pwrdm); | ||
285 | break; | ||
286 | } | ||
287 | } | ||
288 | |||
202 | /* Public functions */ | 289 | /* Public functions */ |
203 | 290 | ||
204 | /** | 291 | /** |
@@ -275,6 +362,30 @@ int pwrdm_complete_init(void) | |||
275 | } | 362 | } |
276 | 363 | ||
277 | /** | 364 | /** |
365 | * pwrdm_lock - acquire a Linux spinlock on a powerdomain | ||
366 | * @pwrdm: struct powerdomain * to lock | ||
367 | * | ||
368 | * Acquire the powerdomain spinlock on @pwrdm. No return value. | ||
369 | */ | ||
370 | void pwrdm_lock(struct powerdomain *pwrdm) | ||
371 | __acquires(&pwrdm->_lock) | ||
372 | { | ||
373 | spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags); | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * pwrdm_unlock - release a Linux spinlock on a powerdomain | ||
378 | * @pwrdm: struct powerdomain * to unlock | ||
379 | * | ||
380 | * Release the powerdomain spinlock on @pwrdm. No return value. | ||
381 | */ | ||
382 | void pwrdm_unlock(struct powerdomain *pwrdm) | ||
383 | __releases(&pwrdm->_lock) | ||
384 | { | ||
385 | spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags); | ||
386 | } | ||
387 | |||
388 | /** | ||
278 | * pwrdm_lookup - look up a powerdomain by name, return a pointer | 389 | * pwrdm_lookup - look up a powerdomain by name, return a pointer |
279 | * @name: name of powerdomain | 390 | * @name: name of powerdomain |
280 | * | 391 | * |
@@ -920,65 +1031,27 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) | |||
920 | return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; | 1031 | return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; |
921 | } | 1032 | } |
922 | 1033 | ||
923 | /** | 1034 | int pwrdm_state_switch_nolock(struct powerdomain *pwrdm) |
924 | * pwrdm_set_lowpwrstchange - Request a low power state change | ||
925 | * @pwrdm: struct powerdomain * | ||
926 | * | ||
927 | * Allows a powerdomain to transtion to a lower power sleep state | ||
928 | * from an existing sleep state without waking up the powerdomain. | ||
929 | * Returns -EINVAL if the powerdomain pointer is null or if the | ||
930 | * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0 | ||
931 | * upon success. | ||
932 | */ | ||
933 | int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) | ||
934 | { | ||
935 | int ret = -EINVAL; | ||
936 | |||
937 | if (!pwrdm) | ||
938 | return -EINVAL; | ||
939 | |||
940 | if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) | ||
941 | return -EINVAL; | ||
942 | |||
943 | pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n", | ||
944 | pwrdm->name); | ||
945 | |||
946 | if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange) | ||
947 | ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm); | ||
948 | |||
949 | return ret; | ||
950 | } | ||
951 | |||
952 | /** | ||
953 | * pwrdm_wait_transition - wait for powerdomain power transition to finish | ||
954 | * @pwrdm: struct powerdomain * to wait for | ||
955 | * | ||
956 | * If the powerdomain @pwrdm is in the process of a state transition, | ||
957 | * spin until it completes the power transition, or until an iteration | ||
958 | * bailout value is reached. Returns -EINVAL if the powerdomain | ||
959 | * pointer is null, -EAGAIN if the bailout value was reached, or | ||
960 | * returns 0 upon success. | ||
961 | */ | ||
962 | int pwrdm_wait_transition(struct powerdomain *pwrdm) | ||
963 | { | 1035 | { |
964 | int ret = -EINVAL; | 1036 | int ret; |
965 | 1037 | ||
966 | if (!pwrdm) | 1038 | if (!pwrdm || !arch_pwrdm) |
967 | return -EINVAL; | 1039 | return -EINVAL; |
968 | 1040 | ||
969 | if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition) | 1041 | ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); |
970 | ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); | 1042 | if (!ret) |
1043 | ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | ||
971 | 1044 | ||
972 | return ret; | 1045 | return ret; |
973 | } | 1046 | } |
974 | 1047 | ||
975 | int pwrdm_state_switch(struct powerdomain *pwrdm) | 1048 | int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm) |
976 | { | 1049 | { |
977 | int ret; | 1050 | int ret; |
978 | 1051 | ||
979 | ret = pwrdm_wait_transition(pwrdm); | 1052 | pwrdm_lock(pwrdm); |
980 | if (!ret) | 1053 | ret = pwrdm_state_switch_nolock(pwrdm); |
981 | ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | 1054 | pwrdm_unlock(pwrdm); |
982 | 1055 | ||
983 | return ret; | 1056 | return ret; |
984 | } | 1057 | } |
@@ -1004,6 +1077,61 @@ int pwrdm_post_transition(struct powerdomain *pwrdm) | |||
1004 | } | 1077 | } |
1005 | 1078 | ||
1006 | /** | 1079 | /** |
1080 | * omap_set_pwrdm_state - change a powerdomain's current power state | ||
1081 | * @pwrdm: struct powerdomain * to change the power state of | ||
1082 | * @pwrst: power state to change to | ||
1083 | * | ||
1084 | * Change the current hardware power state of the powerdomain | ||
1085 | * represented by @pwrdm to the power state represented by @pwrst. | ||
1086 | * Returns -EINVAL if @pwrdm is null or invalid or if the | ||
1087 | * powerdomain's current power state could not be read, or returns 0 | ||
1088 | * upon success or if @pwrdm does not support @pwrst or any | ||
1089 | * lower-power state. XXX Should not return 0 if the @pwrdm does not | ||
1090 | * support @pwrst or any lower-power state: this should be an error. | ||
1091 | */ | ||
1092 | int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) | ||
1093 | { | ||
1094 | u8 curr_pwrst, next_pwrst, sleep_switch; | ||
1095 | int ret = 0; | ||
1096 | bool hwsup = false; | ||
1097 | |||
1098 | if (!pwrdm || IS_ERR(pwrdm)) | ||
1099 | return -EINVAL; | ||
1100 | |||
1101 | while (!(pwrdm->pwrsts & (1 << pwrst))) { | ||
1102 | if (pwrst == PWRDM_POWER_OFF) | ||
1103 | return ret; | ||
1104 | pwrst--; | ||
1105 | } | ||
1106 | |||
1107 | pwrdm_lock(pwrdm); | ||
1108 | |||
1109 | curr_pwrst = pwrdm_read_pwrst(pwrdm); | ||
1110 | next_pwrst = pwrdm_read_next_pwrst(pwrdm); | ||
1111 | if (curr_pwrst == pwrst && next_pwrst == pwrst) | ||
1112 | goto osps_out; | ||
1113 | |||
1114 | sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst, | ||
1115 | pwrst, &hwsup); | ||
1116 | if (sleep_switch == ERROR_SWITCH) { | ||
1117 | ret = -EINVAL; | ||
1118 | goto osps_out; | ||
1119 | } | ||
1120 | |||
1121 | ret = pwrdm_set_next_pwrst(pwrdm, pwrst); | ||
1122 | if (ret) | ||
1123 | pr_err("%s: unable to set power state of powerdomain: %s\n", | ||
1124 | __func__, pwrdm->name); | ||
1125 | |||
1126 | _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup); | ||
1127 | |||
1128 | osps_out: | ||
1129 | pwrdm_unlock(pwrdm); | ||
1130 | |||
1131 | return ret; | ||
1132 | } | ||
1133 | |||
1134 | /** | ||
1007 | * pwrdm_get_context_loss_count - get powerdomain's context loss count | 1135 | * pwrdm_get_context_loss_count - get powerdomain's context loss count |
1008 | * @pwrdm: struct powerdomain * to wait for | 1136 | * @pwrdm: struct powerdomain * to wait for |
1009 | * | 1137 | * |
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 5277d56eb37f..140c36074fed 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h | |||
@@ -19,8 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
22 | 22 | #include <linux/spinlock.h> | |
23 | #include <linux/atomic.h> | ||
24 | 23 | ||
25 | #include "voltage.h" | 24 | #include "voltage.h" |
26 | 25 | ||
@@ -44,18 +43,20 @@ | |||
44 | #define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) | 43 | #define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) |
45 | 44 | ||
46 | 45 | ||
47 | /* Powerdomain flags */ | 46 | /* |
48 | #define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */ | 47 | * Powerdomain flags (struct powerdomain.flags) |
49 | #define PWRDM_HAS_MPU_QUIRK (1 << 1) /* MPU pwr domain has MEM bank 0 bits | 48 | * |
50 | * in MEM bank 1 position. This is | 49 | * PWRDM_HAS_HDWR_SAR - powerdomain has hardware save-and-restore support |
51 | * true for OMAP3430 | 50 | * |
52 | */ | 51 | * PWRDM_HAS_MPU_QUIRK - MPU pwr domain has MEM bank 0 bits in MEM |
53 | #define PWRDM_HAS_LOWPOWERSTATECHANGE (1 << 2) /* | 52 | * bank 1 position. This is true for OMAP3430 |
54 | * support to transition from a | 53 | * |
55 | * sleep state to a lower sleep | 54 | * PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state |
56 | * state without waking up the | 55 | * to a lower sleep state without waking up the powerdomain |
57 | * powerdomain | 56 | */ |
58 | */ | 57 | #define PWRDM_HAS_HDWR_SAR BIT(0) |
58 | #define PWRDM_HAS_MPU_QUIRK BIT(1) | ||
59 | #define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2) | ||
59 | 60 | ||
60 | /* | 61 | /* |
61 | * Number of memory banks that are power-controllable. On OMAP4430, the | 62 | * Number of memory banks that are power-controllable. On OMAP4430, the |
@@ -103,6 +104,8 @@ struct powerdomain; | |||
103 | * @state_counter: | 104 | * @state_counter: |
104 | * @timer: | 105 | * @timer: |
105 | * @state_timer: | 106 | * @state_timer: |
107 | * @_lock: spinlock used to serialize powerdomain and some clockdomain ops | ||
108 | * @_lock_flags: stored flags when @_lock is taken | ||
106 | * | 109 | * |
107 | * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h. | 110 | * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h. |
108 | */ | 111 | */ |
@@ -127,7 +130,8 @@ struct powerdomain { | |||
127 | unsigned state_counter[PWRDM_MAX_PWRSTS]; | 130 | unsigned state_counter[PWRDM_MAX_PWRSTS]; |
128 | unsigned ret_logic_off_counter; | 131 | unsigned ret_logic_off_counter; |
129 | unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; | 132 | unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; |
130 | 133 | spinlock_t _lock; | |
134 | unsigned long _lock_flags; | ||
131 | const u8 pwrstctrl_offs; | 135 | const u8 pwrstctrl_offs; |
132 | const u8 pwrstst_offs; | 136 | const u8 pwrstst_offs; |
133 | const u32 logicretstate_mask; | 137 | const u32 logicretstate_mask; |
@@ -162,6 +166,16 @@ struct powerdomain { | |||
162 | * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd | 166 | * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd |
163 | * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep | 167 | * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep |
164 | * @pwrdm_wait_transition: Wait for a pd state transition to complete | 168 | * @pwrdm_wait_transition: Wait for a pd state transition to complete |
169 | * | ||
170 | * Regarding @pwrdm_set_lowpwrstchange: On the OMAP2 and 3-family | ||
171 | * chips, a powerdomain's power state is not allowed to directly | ||
172 | * transition from one low-power state (e.g., CSWR) to another | ||
173 | * low-power state (e.g., OFF) without first waking up the | ||
174 | * powerdomain. This wastes energy. So OMAP4 chips support the | ||
175 | * ability to transition a powerdomain power state directly from one | ||
176 | * low-power state to another. The function pointed to by | ||
177 | * @pwrdm_set_lowpwrstchange is intended to configure the OMAP4 | ||
178 | * hardware powerdomain state machine to enable this feature. | ||
165 | */ | 179 | */ |
166 | struct pwrdm_ops { | 180 | struct pwrdm_ops { |
167 | int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst); | 181 | int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst); |
@@ -225,15 +239,15 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm); | |||
225 | int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm); | 239 | int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm); |
226 | bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); | 240 | bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); |
227 | 241 | ||
228 | int pwrdm_wait_transition(struct powerdomain *pwrdm); | 242 | int pwrdm_state_switch_nolock(struct powerdomain *pwrdm); |
229 | |||
230 | int pwrdm_state_switch(struct powerdomain *pwrdm); | 243 | int pwrdm_state_switch(struct powerdomain *pwrdm); |
231 | int pwrdm_pre_transition(struct powerdomain *pwrdm); | 244 | int pwrdm_pre_transition(struct powerdomain *pwrdm); |
232 | int pwrdm_post_transition(struct powerdomain *pwrdm); | 245 | int pwrdm_post_transition(struct powerdomain *pwrdm); |
233 | int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm); | ||
234 | int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); | 246 | int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); |
235 | bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); | 247 | bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); |
236 | 248 | ||
249 | extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state); | ||
250 | |||
237 | extern void omap242x_powerdomains_init(void); | 251 | extern void omap242x_powerdomains_init(void); |
238 | extern void omap243x_powerdomains_init(void); | 252 | extern void omap243x_powerdomains_init(void); |
239 | extern void omap3xxx_powerdomains_init(void); | 253 | extern void omap3xxx_powerdomains_init(void); |
@@ -253,5 +267,7 @@ extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank); | |||
253 | extern struct powerdomain wkup_omap2_pwrdm; | 267 | extern struct powerdomain wkup_omap2_pwrdm; |
254 | extern struct powerdomain gfx_omap2_pwrdm; | 268 | extern struct powerdomain gfx_omap2_pwrdm; |
255 | 269 | ||
270 | extern void pwrdm_lock(struct powerdomain *pwrdm); | ||
271 | extern void pwrdm_unlock(struct powerdomain *pwrdm); | ||
256 | 272 | ||
257 | #endif | 273 | #endif |
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c index d3a5399091ad..7b946f1005b1 100644 --- a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c | |||
@@ -54,12 +54,12 @@ struct powerdomain gfx_omap2_pwrdm = { | |||
54 | .pwrsts_mem_on = { | 54 | .pwrsts_mem_on = { |
55 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 55 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
56 | }, | 56 | }, |
57 | .voltdm = { .name = "core" }, | 57 | .voltdm = { .name = "core" }, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct powerdomain wkup_omap2_pwrdm = { | 60 | struct powerdomain wkup_omap2_pwrdm = { |
61 | .name = "wkup_pwrdm", | 61 | .name = "wkup_pwrdm", |
62 | .prcm_offs = WKUP_MOD, | 62 | .prcm_offs = WKUP_MOD, |
63 | .pwrsts = PWRSTS_ON, | 63 | .pwrsts = PWRSTS_ON, |
64 | .voltdm = { .name = "wakeup" }, | 64 | .voltdm = { .name = "wakeup" }, |
65 | }; | 65 | }; |
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c index ba520d4f7c7b..578eef86fcf2 100644 --- a/arch/arm/mach-omap2/powerdomains2xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c | |||
@@ -38,7 +38,7 @@ static struct powerdomain dsp_pwrdm = { | |||
38 | .pwrsts_mem_on = { | 38 | .pwrsts_mem_on = { |
39 | [0] = PWRSTS_ON, | 39 | [0] = PWRSTS_ON, |
40 | }, | 40 | }, |
41 | .voltdm = { .name = "core" }, | 41 | .voltdm = { .name = "core" }, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static struct powerdomain mpu_24xx_pwrdm = { | 44 | static struct powerdomain mpu_24xx_pwrdm = { |
@@ -53,13 +53,14 @@ static struct powerdomain mpu_24xx_pwrdm = { | |||
53 | .pwrsts_mem_on = { | 53 | .pwrsts_mem_on = { |
54 | [0] = PWRSTS_ON, | 54 | [0] = PWRSTS_ON, |
55 | }, | 55 | }, |
56 | .voltdm = { .name = "core" }, | 56 | .voltdm = { .name = "core" }, |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static struct powerdomain core_24xx_pwrdm = { | 59 | static struct powerdomain core_24xx_pwrdm = { |
60 | .name = "core_pwrdm", | 60 | .name = "core_pwrdm", |
61 | .prcm_offs = CORE_MOD, | 61 | .prcm_offs = CORE_MOD, |
62 | .pwrsts = PWRSTS_OFF_RET_ON, | 62 | .pwrsts = PWRSTS_OFF_RET_ON, |
63 | .pwrsts_logic_ret = PWRSTS_RET, | ||
63 | .banks = 3, | 64 | .banks = 3, |
64 | .pwrsts_mem_ret = { | 65 | .pwrsts_mem_ret = { |
65 | [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ | 66 | [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ |
@@ -71,7 +72,7 @@ static struct powerdomain core_24xx_pwrdm = { | |||
71 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ | 72 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ |
72 | [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */ | 73 | [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */ |
73 | }, | 74 | }, |
74 | .voltdm = { .name = "core" }, | 75 | .voltdm = { .name = "core" }, |
75 | }; | 76 | }; |
76 | 77 | ||
77 | 78 | ||
@@ -93,7 +94,7 @@ static struct powerdomain mdm_pwrdm = { | |||
93 | .pwrsts_mem_on = { | 94 | .pwrsts_mem_on = { |
94 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 95 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
95 | }, | 96 | }, |
96 | .voltdm = { .name = "core" }, | 97 | .voltdm = { .name = "core" }, |
97 | }; | 98 | }; |
98 | 99 | ||
99 | /* | 100 | /* |
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index 8b23d234fb55..f0e14e9efe5a 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c | |||
@@ -50,7 +50,7 @@ static struct powerdomain iva2_pwrdm = { | |||
50 | [2] = PWRSTS_OFF_ON, | 50 | [2] = PWRSTS_OFF_ON, |
51 | [3] = PWRSTS_ON, | 51 | [3] = PWRSTS_ON, |
52 | }, | 52 | }, |
53 | .voltdm = { .name = "mpu_iva" }, | 53 | .voltdm = { .name = "mpu_iva" }, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct powerdomain mpu_3xxx_pwrdm = { | 56 | static struct powerdomain mpu_3xxx_pwrdm = { |
@@ -66,7 +66,7 @@ static struct powerdomain mpu_3xxx_pwrdm = { | |||
66 | .pwrsts_mem_on = { | 66 | .pwrsts_mem_on = { |
67 | [0] = PWRSTS_OFF_ON, | 67 | [0] = PWRSTS_OFF_ON, |
68 | }, | 68 | }, |
69 | .voltdm = { .name = "mpu_iva" }, | 69 | .voltdm = { .name = "mpu_iva" }, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static struct powerdomain mpu_am35x_pwrdm = { | 72 | static struct powerdomain mpu_am35x_pwrdm = { |
@@ -82,7 +82,7 @@ static struct powerdomain mpu_am35x_pwrdm = { | |||
82 | .pwrsts_mem_on = { | 82 | .pwrsts_mem_on = { |
83 | [0] = PWRSTS_ON, | 83 | [0] = PWRSTS_ON, |
84 | }, | 84 | }, |
85 | .voltdm = { .name = "mpu_iva" }, | 85 | .voltdm = { .name = "mpu_iva" }, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* | 88 | /* |
@@ -109,7 +109,7 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = { | |||
109 | [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ | 109 | [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ |
110 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ | 110 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ |
111 | }, | 111 | }, |
112 | .voltdm = { .name = "core" }, | 112 | .voltdm = { .name = "core" }, |
113 | }; | 113 | }; |
114 | 114 | ||
115 | static struct powerdomain core_3xxx_es3_1_pwrdm = { | 115 | static struct powerdomain core_3xxx_es3_1_pwrdm = { |
@@ -131,7 +131,7 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = { | |||
131 | [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ | 131 | [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ |
132 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ | 132 | [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ |
133 | }, | 133 | }, |
134 | .voltdm = { .name = "core" }, | 134 | .voltdm = { .name = "core" }, |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct powerdomain core_am35x_pwrdm = { | 137 | static struct powerdomain core_am35x_pwrdm = { |
@@ -148,7 +148,7 @@ static struct powerdomain core_am35x_pwrdm = { | |||
148 | [0] = PWRSTS_ON, /* MEM1ONSTATE */ | 148 | [0] = PWRSTS_ON, /* MEM1ONSTATE */ |
149 | [1] = PWRSTS_ON, /* MEM2ONSTATE */ | 149 | [1] = PWRSTS_ON, /* MEM2ONSTATE */ |
150 | }, | 150 | }, |
151 | .voltdm = { .name = "core" }, | 151 | .voltdm = { .name = "core" }, |
152 | }; | 152 | }; |
153 | 153 | ||
154 | static struct powerdomain dss_pwrdm = { | 154 | static struct powerdomain dss_pwrdm = { |
@@ -163,7 +163,7 @@ static struct powerdomain dss_pwrdm = { | |||
163 | .pwrsts_mem_on = { | 163 | .pwrsts_mem_on = { |
164 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 164 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
165 | }, | 165 | }, |
166 | .voltdm = { .name = "core" }, | 166 | .voltdm = { .name = "core" }, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static struct powerdomain dss_am35x_pwrdm = { | 169 | static struct powerdomain dss_am35x_pwrdm = { |
@@ -178,7 +178,7 @@ static struct powerdomain dss_am35x_pwrdm = { | |||
178 | .pwrsts_mem_on = { | 178 | .pwrsts_mem_on = { |
179 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 179 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
180 | }, | 180 | }, |
181 | .voltdm = { .name = "core" }, | 181 | .voltdm = { .name = "core" }, |
182 | }; | 182 | }; |
183 | 183 | ||
184 | /* | 184 | /* |
@@ -199,7 +199,7 @@ static struct powerdomain sgx_pwrdm = { | |||
199 | .pwrsts_mem_on = { | 199 | .pwrsts_mem_on = { |
200 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 200 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
201 | }, | 201 | }, |
202 | .voltdm = { .name = "core" }, | 202 | .voltdm = { .name = "core" }, |
203 | }; | 203 | }; |
204 | 204 | ||
205 | static struct powerdomain sgx_am35x_pwrdm = { | 205 | static struct powerdomain sgx_am35x_pwrdm = { |
@@ -214,7 +214,7 @@ static struct powerdomain sgx_am35x_pwrdm = { | |||
214 | .pwrsts_mem_on = { | 214 | .pwrsts_mem_on = { |
215 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 215 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
216 | }, | 216 | }, |
217 | .voltdm = { .name = "core" }, | 217 | .voltdm = { .name = "core" }, |
218 | }; | 218 | }; |
219 | 219 | ||
220 | static struct powerdomain cam_pwrdm = { | 220 | static struct powerdomain cam_pwrdm = { |
@@ -229,7 +229,7 @@ static struct powerdomain cam_pwrdm = { | |||
229 | .pwrsts_mem_on = { | 229 | .pwrsts_mem_on = { |
230 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 230 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
231 | }, | 231 | }, |
232 | .voltdm = { .name = "core" }, | 232 | .voltdm = { .name = "core" }, |
233 | }; | 233 | }; |
234 | 234 | ||
235 | static struct powerdomain per_pwrdm = { | 235 | static struct powerdomain per_pwrdm = { |
@@ -244,7 +244,7 @@ static struct powerdomain per_pwrdm = { | |||
244 | .pwrsts_mem_on = { | 244 | .pwrsts_mem_on = { |
245 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 245 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
246 | }, | 246 | }, |
247 | .voltdm = { .name = "core" }, | 247 | .voltdm = { .name = "core" }, |
248 | }; | 248 | }; |
249 | 249 | ||
250 | static struct powerdomain per_am35x_pwrdm = { | 250 | static struct powerdomain per_am35x_pwrdm = { |
@@ -259,13 +259,13 @@ static struct powerdomain per_am35x_pwrdm = { | |||
259 | .pwrsts_mem_on = { | 259 | .pwrsts_mem_on = { |
260 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 260 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
261 | }, | 261 | }, |
262 | .voltdm = { .name = "core" }, | 262 | .voltdm = { .name = "core" }, |
263 | }; | 263 | }; |
264 | 264 | ||
265 | static struct powerdomain emu_pwrdm = { | 265 | static struct powerdomain emu_pwrdm = { |
266 | .name = "emu_pwrdm", | 266 | .name = "emu_pwrdm", |
267 | .prcm_offs = OMAP3430_EMU_MOD, | 267 | .prcm_offs = OMAP3430_EMU_MOD, |
268 | .voltdm = { .name = "core" }, | 268 | .voltdm = { .name = "core" }, |
269 | }; | 269 | }; |
270 | 270 | ||
271 | static struct powerdomain neon_pwrdm = { | 271 | static struct powerdomain neon_pwrdm = { |
@@ -273,7 +273,7 @@ static struct powerdomain neon_pwrdm = { | |||
273 | .prcm_offs = OMAP3430_NEON_MOD, | 273 | .prcm_offs = OMAP3430_NEON_MOD, |
274 | .pwrsts = PWRSTS_OFF_RET_ON, | 274 | .pwrsts = PWRSTS_OFF_RET_ON, |
275 | .pwrsts_logic_ret = PWRSTS_RET, | 275 | .pwrsts_logic_ret = PWRSTS_RET, |
276 | .voltdm = { .name = "mpu_iva" }, | 276 | .voltdm = { .name = "mpu_iva" }, |
277 | }; | 277 | }; |
278 | 278 | ||
279 | static struct powerdomain neon_am35x_pwrdm = { | 279 | static struct powerdomain neon_am35x_pwrdm = { |
@@ -281,7 +281,7 @@ static struct powerdomain neon_am35x_pwrdm = { | |||
281 | .prcm_offs = OMAP3430_NEON_MOD, | 281 | .prcm_offs = OMAP3430_NEON_MOD, |
282 | .pwrsts = PWRSTS_ON, | 282 | .pwrsts = PWRSTS_ON, |
283 | .pwrsts_logic_ret = PWRSTS_ON, | 283 | .pwrsts_logic_ret = PWRSTS_ON, |
284 | .voltdm = { .name = "mpu_iva" }, | 284 | .voltdm = { .name = "mpu_iva" }, |
285 | }; | 285 | }; |
286 | 286 | ||
287 | static struct powerdomain usbhost_pwrdm = { | 287 | static struct powerdomain usbhost_pwrdm = { |
@@ -303,37 +303,37 @@ static struct powerdomain usbhost_pwrdm = { | |||
303 | .pwrsts_mem_on = { | 303 | .pwrsts_mem_on = { |
304 | [0] = PWRSTS_ON, /* MEMONSTATE */ | 304 | [0] = PWRSTS_ON, /* MEMONSTATE */ |
305 | }, | 305 | }, |
306 | .voltdm = { .name = "core" }, | 306 | .voltdm = { .name = "core" }, |
307 | }; | 307 | }; |
308 | 308 | ||
309 | static struct powerdomain dpll1_pwrdm = { | 309 | static struct powerdomain dpll1_pwrdm = { |
310 | .name = "dpll1_pwrdm", | 310 | .name = "dpll1_pwrdm", |
311 | .prcm_offs = MPU_MOD, | 311 | .prcm_offs = MPU_MOD, |
312 | .voltdm = { .name = "mpu_iva" }, | 312 | .voltdm = { .name = "mpu_iva" }, |
313 | }; | 313 | }; |
314 | 314 | ||
315 | static struct powerdomain dpll2_pwrdm = { | 315 | static struct powerdomain dpll2_pwrdm = { |
316 | .name = "dpll2_pwrdm", | 316 | .name = "dpll2_pwrdm", |
317 | .prcm_offs = OMAP3430_IVA2_MOD, | 317 | .prcm_offs = OMAP3430_IVA2_MOD, |
318 | .voltdm = { .name = "mpu_iva" }, | 318 | .voltdm = { .name = "mpu_iva" }, |
319 | }; | 319 | }; |
320 | 320 | ||
321 | static struct powerdomain dpll3_pwrdm = { | 321 | static struct powerdomain dpll3_pwrdm = { |
322 | .name = "dpll3_pwrdm", | 322 | .name = "dpll3_pwrdm", |
323 | .prcm_offs = PLL_MOD, | 323 | .prcm_offs = PLL_MOD, |
324 | .voltdm = { .name = "core" }, | 324 | .voltdm = { .name = "core" }, |
325 | }; | 325 | }; |
326 | 326 | ||
327 | static struct powerdomain dpll4_pwrdm = { | 327 | static struct powerdomain dpll4_pwrdm = { |
328 | .name = "dpll4_pwrdm", | 328 | .name = "dpll4_pwrdm", |
329 | .prcm_offs = PLL_MOD, | 329 | .prcm_offs = PLL_MOD, |
330 | .voltdm = { .name = "core" }, | 330 | .voltdm = { .name = "core" }, |
331 | }; | 331 | }; |
332 | 332 | ||
333 | static struct powerdomain dpll5_pwrdm = { | 333 | static struct powerdomain dpll5_pwrdm = { |
334 | .name = "dpll5_pwrdm", | 334 | .name = "dpll5_pwrdm", |
335 | .prcm_offs = PLL_MOD, | 335 | .prcm_offs = PLL_MOD, |
336 | .voltdm = { .name = "core" }, | 336 | .voltdm = { .name = "core" }, |
337 | }; | 337 | }; |
338 | 338 | ||
339 | /* As powerdomains are added or removed above, this list must also be changed */ | 339 | /* As powerdomains are added or removed above, this list must also be changed */ |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index a3e121f94a86..947f6adfed0c 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c | |||
@@ -210,6 +210,7 @@ int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, | |||
210 | PM_WKDEP, (1 << clkdm2->dep_bit)); | 210 | PM_WKDEP, (1 << clkdm2->dep_bit)); |
211 | } | 211 | } |
212 | 212 | ||
213 | /* XXX Caller must hold the clkdm's powerdomain lock */ | ||
213 | int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) | 214 | int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) |
214 | { | 215 | { |
215 | struct clkdm_dep *cd; | 216 | struct clkdm_dep *cd; |
@@ -221,7 +222,7 @@ int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) | |||
221 | 222 | ||
222 | /* PRM accesses are slow, so minimize them */ | 223 | /* PRM accesses are slow, so minimize them */ |
223 | mask |= 1 << cd->clkdm->dep_bit; | 224 | mask |= 1 << cd->clkdm->dep_bit; |
224 | atomic_set(&cd->wkdep_usecount, 0); | 225 | cd->wkdep_usecount = 0; |
225 | } | 226 | } |
226 | 227 | ||
227 | omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, | 228 | omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 24e9ad3cb993..8396b5b7e912 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -316,8 +316,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, | |||
316 | if (WARN_ON(!oh)) | 316 | if (WARN_ON(!oh)) |
317 | return; | 317 | return; |
318 | 318 | ||
319 | pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size, | 319 | pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size); |
320 | NULL, 0, false); | ||
321 | if (IS_ERR(pdev)) { | 320 | if (IS_ERR(pdev)) { |
322 | WARN(1, "Could not build omap_device for %s: %s.\n", name, | 321 | WARN(1, "Could not build omap_device for %s: %s.\n", name, |
323 | oh->name); | 322 | oh->name); |
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index b9753fe27232..bb829e065400 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c | |||
@@ -152,8 +152,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) | |||
152 | 152 | ||
153 | sr_data->enable_on_init = sr_enable_on_init; | 153 | sr_data->enable_on_init = sr_enable_on_init; |
154 | 154 | ||
155 | pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), | 155 | pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), 0); |
156 | NULL, 0, 0); | ||
157 | if (IS_ERR(pdev)) | 156 | if (IS_ERR(pdev)) |
158 | pr_warning("%s: Could not build omap_device for %s: %s.\n\n", | 157 | pr_warning("%s: Could not build omap_device for %s: %s.\n\n", |
159 | __func__, name, oh->name); | 158 | __func__, name, oh->name); |
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 72c2ca1e3f70..2bdd4cf17a8f 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -683,8 +683,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) | |||
683 | pdata->timer_errata = omap_dm_timer_get_errata(); | 683 | pdata->timer_errata = omap_dm_timer_get_errata(); |
684 | pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; | 684 | pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; |
685 | 685 | ||
686 | pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), | 686 | pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata)); |
687 | NULL, 0, 0); | ||
688 | 687 | ||
689 | if (IS_ERR(pdev)) { | 688 | if (IS_ERR(pdev)) { |
690 | pr_err("%s: Can't build omap_device for %s: %s.\n", | 689 | pr_err("%s: Can't build omap_device for %s: %s.\n", |
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 2e44e8a22884..5706bdccf45e 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c | |||
@@ -37,19 +37,6 @@ | |||
37 | #define USBHS_UHH_HWMODNAME "usb_host_hs" | 37 | #define USBHS_UHH_HWMODNAME "usb_host_hs" |
38 | #define USBHS_TLL_HWMODNAME "usb_tll_hs" | 38 | #define USBHS_TLL_HWMODNAME "usb_tll_hs" |
39 | 39 | ||
40 | static struct usbhs_omap_platform_data usbhs_data; | ||
41 | static struct usbtll_omap_platform_data usbtll_data; | ||
42 | static struct ehci_hcd_omap_platform_data ehci_data; | ||
43 | static struct ohci_hcd_omap_platform_data ohci_data; | ||
44 | |||
45 | static struct omap_device_pm_latency omap_uhhtll_latency[] = { | ||
46 | { | ||
47 | .deactivate_func = omap_device_idle_hwmods, | ||
48 | .activate_func = omap_device_enable_hwmods, | ||
49 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
50 | }, | ||
51 | }; | ||
52 | |||
53 | /* MUX settings for EHCI pins */ | 40 | /* MUX settings for EHCI pins */ |
54 | /* | 41 | /* |
55 | * setup_ehci_io_mux - initialize IO pad mux for USBHOST | 42 | * setup_ehci_io_mux - initialize IO pad mux for USBHOST |
@@ -485,32 +472,18 @@ void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) | |||
485 | } | 472 | } |
486 | } | 473 | } |
487 | 474 | ||
488 | void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | 475 | void __init usbhs_init(struct usbhs_omap_platform_data *pdata) |
489 | { | 476 | { |
490 | struct omap_hwmod *uhh_hwm, *tll_hwm; | 477 | struct omap_hwmod *uhh_hwm, *tll_hwm; |
491 | struct platform_device *pdev; | 478 | struct platform_device *pdev; |
492 | int bus_id = -1; | 479 | int bus_id = -1; |
493 | int i; | ||
494 | |||
495 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) { | ||
496 | usbhs_data.port_mode[i] = pdata->port_mode[i]; | ||
497 | usbtll_data.port_mode[i] = pdata->port_mode[i]; | ||
498 | ohci_data.port_mode[i] = pdata->port_mode[i]; | ||
499 | ehci_data.port_mode[i] = pdata->port_mode[i]; | ||
500 | ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i]; | ||
501 | ehci_data.regulator[i] = pdata->regulator[i]; | ||
502 | } | ||
503 | ehci_data.phy_reset = pdata->phy_reset; | ||
504 | ohci_data.es2_compatibility = pdata->es2_compatibility; | ||
505 | usbhs_data.ehci_data = &ehci_data; | ||
506 | usbhs_data.ohci_data = &ohci_data; | ||
507 | 480 | ||
508 | if (cpu_is_omap34xx()) { | 481 | if (cpu_is_omap34xx()) { |
509 | setup_ehci_io_mux(pdata->port_mode); | 482 | setup_ehci_io_mux(pdata->port_mode); |
510 | setup_ohci_io_mux(pdata->port_mode); | 483 | setup_ohci_io_mux(pdata->port_mode); |
511 | 484 | ||
512 | if (omap_rev() <= OMAP3430_REV_ES2_1) | 485 | if (omap_rev() <= OMAP3430_REV_ES2_1) |
513 | usbhs_data.single_ulpi_bypass = true; | 486 | pdata->single_ulpi_bypass = true; |
514 | 487 | ||
515 | } else if (cpu_is_omap44xx()) { | 488 | } else if (cpu_is_omap44xx()) { |
516 | setup_4430ehci_io_mux(pdata->port_mode); | 489 | setup_4430ehci_io_mux(pdata->port_mode); |
@@ -530,9 +503,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | |||
530 | } | 503 | } |
531 | 504 | ||
532 | pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm, | 505 | pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm, |
533 | &usbtll_data, sizeof(usbtll_data), | 506 | pdata, sizeof(*pdata)); |
534 | omap_uhhtll_latency, | ||
535 | ARRAY_SIZE(omap_uhhtll_latency), false); | ||
536 | if (IS_ERR(pdev)) { | 507 | if (IS_ERR(pdev)) { |
537 | pr_err("Could not build hwmod device %s\n", | 508 | pr_err("Could not build hwmod device %s\n", |
538 | USBHS_TLL_HWMODNAME); | 509 | USBHS_TLL_HWMODNAME); |
@@ -540,9 +511,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | |||
540 | } | 511 | } |
541 | 512 | ||
542 | pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm, | 513 | pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm, |
543 | &usbhs_data, sizeof(usbhs_data), | 514 | pdata, sizeof(*pdata)); |
544 | omap_uhhtll_latency, | ||
545 | ARRAY_SIZE(omap_uhhtll_latency), false); | ||
546 | if (IS_ERR(pdev)) { | 515 | if (IS_ERR(pdev)) { |
547 | pr_err("Could not build hwmod devices %s\n", | 516 | pr_err("Could not build hwmod devices %s\n", |
548 | USBHS_UHH_HWMODNAME); | 517 | USBHS_UHH_HWMODNAME); |
@@ -552,7 +521,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | |||
552 | 521 | ||
553 | #else | 522 | #else |
554 | 523 | ||
555 | void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | 524 | void __init usbhs_init(struct usbhs_omap_platform_data *pdata) |
556 | { | 525 | { |
557 | } | 526 | } |
558 | 527 | ||
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 9d27e3f8a09c..3242a554ad6b 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c | |||
@@ -105,7 +105,7 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) | |||
105 | return; | 105 | return; |
106 | 106 | ||
107 | pdev = omap_device_build(name, bus_id, oh, &musb_plat, | 107 | pdev = omap_device_build(name, bus_id, oh, &musb_plat, |
108 | sizeof(musb_plat), NULL, 0, false); | 108 | sizeof(musb_plat)); |
109 | if (IS_ERR(pdev)) { | 109 | if (IS_ERR(pdev)) { |
110 | pr_err("Could not build omap_device for %s %s\n", | 110 | pr_err("Could not build omap_device for %s %s\n", |
111 | name, oh_name); | 111 | name, oh_name); |
diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h index 9b986ead7c45..3319f5cf47a3 100644 --- a/arch/arm/mach-omap2/usb.h +++ b/arch/arm/mach-omap2/usb.h | |||
@@ -53,26 +53,8 @@ | |||
53 | #define USBPHY_OTGSESSEND_EN (1 << 20) | 53 | #define USBPHY_OTGSESSEND_EN (1 << 20) |
54 | #define USBPHY_DATA_POLARITY (1 << 23) | 54 | #define USBPHY_DATA_POLARITY (1 << 23) |
55 | 55 | ||
56 | struct usbhs_omap_board_data { | ||
57 | enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; | ||
58 | |||
59 | /* have to be valid if phy_reset is true and portx is in phy mode */ | ||
60 | int reset_gpio_port[OMAP3_HS_USB_PORTS]; | ||
61 | |||
62 | /* Set this to true for ES2.x silicon */ | ||
63 | unsigned es2_compatibility:1; | ||
64 | |||
65 | unsigned phy_reset:1; | ||
66 | |||
67 | /* | ||
68 | * Regulators for USB PHYs. | ||
69 | * Each PHY can have a separate regulator. | ||
70 | */ | ||
71 | struct regulator *regulator[OMAP3_HS_USB_PORTS]; | ||
72 | }; | ||
73 | |||
74 | extern void usb_musb_init(struct omap_musb_board_data *board_data); | 56 | extern void usb_musb_init(struct omap_musb_board_data *board_data); |
75 | extern void usbhs_init(const struct usbhs_omap_board_data *pdata); | 57 | extern void usbhs_init(struct usbhs_omap_platform_data *pdata); |
76 | 58 | ||
77 | extern void am35x_musb_reset(void); | 59 | extern void am35x_musb_reset(void); |
78 | extern void am35x_musb_phy_power(u8 on); | 60 | extern void am35x_musb_phy_power(u8 on); |
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c index 70240a54995c..d15c7bbab8e2 100644 --- a/arch/arm/mach-omap2/wd_timer.c +++ b/arch/arm/mach-omap2/wd_timer.c | |||
@@ -124,8 +124,7 @@ static int __init omap_init_wdt(void) | |||
124 | pdata.read_reset_sources = prm_read_reset_sources; | 124 | pdata.read_reset_sources = prm_read_reset_sources; |
125 | 125 | ||
126 | pdev = omap_device_build(dev_name, id, oh, &pdata, | 126 | pdev = omap_device_build(dev_name, id, oh, &pdata, |
127 | sizeof(struct omap_wd_timer_platform_data), | 127 | sizeof(struct omap_wd_timer_platform_data)); |
128 | NULL, 0, 0); | ||
129 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", | 128 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", |
130 | dev_name, oh->name); | 129 | dev_name, oh->name); |
131 | return 0; | 130 | return 0; |
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig index 558ccfb8d458..4f7379fe01e2 100644 --- a/arch/arm/mach-prima2/Kconfig +++ b/arch/arm/mach-prima2/Kconfig | |||
@@ -11,6 +11,16 @@ config ARCH_PRIMA2 | |||
11 | help | 11 | help |
12 | Support for CSR SiRFSoC ARM Cortex A9 Platform | 12 | Support for CSR SiRFSoC ARM Cortex A9 Platform |
13 | 13 | ||
14 | config ARCH_MARCO | ||
15 | bool "CSR SiRFSoC MARCO ARM Cortex A9 Platform" | ||
16 | default y | ||
17 | select ARM_GIC | ||
18 | select CPU_V7 | ||
19 | select HAVE_SMP | ||
20 | select SMP_ON_UP | ||
21 | help | ||
22 | Support for CSR SiRFSoC ARM Cortex A9 Platform | ||
23 | |||
14 | endmenu | 24 | endmenu |
15 | 25 | ||
16 | config SIRF_IRQ | 26 | config SIRF_IRQ |
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile index fc9ce22e2b5a..bfe360cbd177 100644 --- a/arch/arm/mach-prima2/Makefile +++ b/arch/arm/mach-prima2/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-y := timer.o | ||
2 | obj-y += rstc.o | 1 | obj-y += rstc.o |
3 | obj-y += common.o | 2 | obj-y += common.o |
4 | obj-y += rtciobrg.o | 3 | obj-y += rtciobrg.o |
@@ -6,3 +5,7 @@ obj-$(CONFIG_DEBUG_LL) += lluart.o | |||
6 | obj-$(CONFIG_CACHE_L2X0) += l2x0.o | 5 | obj-$(CONFIG_CACHE_L2X0) += l2x0.o |
7 | obj-$(CONFIG_SUSPEND) += pm.o sleep.o | 6 | obj-$(CONFIG_SUSPEND) += pm.o sleep.o |
8 | obj-$(CONFIG_SIRF_IRQ) += irq.o | 7 | obj-$(CONFIG_SIRF_IRQ) += irq.o |
8 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | ||
9 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
10 | obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o | ||
11 | obj-$(CONFIG_ARCH_MARCO) += timer-marco.o | ||
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c index ed3570e5eb8f..2d57aa479a7b 100644 --- a/arch/arm/mach-prima2/common.c +++ b/arch/arm/mach-prima2/common.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/irqchip.h> | ||
11 | #include <asm/sizes.h> | 12 | #include <asm/sizes.h> |
12 | #include <asm/mach-types.h> | 13 | #include <asm/mach-types.h> |
13 | #include <asm/mach/arch.h> | 14 | #include <asm/mach/arch.h> |
@@ -30,6 +31,12 @@ void __init sirfsoc_init_late(void) | |||
30 | sirfsoc_pm_init(); | 31 | sirfsoc_pm_init(); |
31 | } | 32 | } |
32 | 33 | ||
34 | static __init void sirfsoc_map_io(void) | ||
35 | { | ||
36 | sirfsoc_map_lluart(); | ||
37 | sirfsoc_map_scu(); | ||
38 | } | ||
39 | |||
33 | #ifdef CONFIG_ARCH_PRIMA2 | 40 | #ifdef CONFIG_ARCH_PRIMA2 |
34 | static const char *prima2_dt_match[] __initdata = { | 41 | static const char *prima2_dt_match[] __initdata = { |
35 | "sirf,prima2", | 42 | "sirf,prima2", |
@@ -38,9 +45,12 @@ static const char *prima2_dt_match[] __initdata = { | |||
38 | 45 | ||
39 | DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") | 46 | DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") |
40 | /* Maintainer: Barry Song <baohua.song@csr.com> */ | 47 | /* Maintainer: Barry Song <baohua.song@csr.com> */ |
41 | .map_io = sirfsoc_map_lluart, | 48 | .map_io = sirfsoc_map_io, |
42 | .init_irq = sirfsoc_of_irq_init, | 49 | .init_irq = sirfsoc_of_irq_init, |
43 | .init_time = sirfsoc_timer_init, | 50 | .init_time = sirfsoc_prima2_timer_init, |
51 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
52 | .handle_irq = sirfsoc_handle_irq, | ||
53 | #endif | ||
44 | .dma_zone_size = SZ_256M, | 54 | .dma_zone_size = SZ_256M, |
45 | .init_machine = sirfsoc_mach_init, | 55 | .init_machine = sirfsoc_mach_init, |
46 | .init_late = sirfsoc_init_late, | 56 | .init_late = sirfsoc_init_late, |
@@ -48,3 +58,22 @@ DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") | |||
48 | .restart = sirfsoc_restart, | 58 | .restart = sirfsoc_restart, |
49 | MACHINE_END | 59 | MACHINE_END |
50 | #endif | 60 | #endif |
61 | |||
62 | #ifdef CONFIG_ARCH_MARCO | ||
63 | static const char *marco_dt_match[] __initdata = { | ||
64 | "sirf,marco", | ||
65 | NULL | ||
66 | }; | ||
67 | |||
68 | DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)") | ||
69 | /* Maintainer: Barry Song <baohua.song@csr.com> */ | ||
70 | .smp = smp_ops(sirfsoc_smp_ops), | ||
71 | .map_io = sirfsoc_map_io, | ||
72 | .init_irq = irqchip_init, | ||
73 | .init_time = sirfsoc_marco_timer_init, | ||
74 | .init_machine = sirfsoc_mach_init, | ||
75 | .init_late = sirfsoc_init_late, | ||
76 | .dt_compat = marco_dt_match, | ||
77 | .restart = sirfsoc_restart, | ||
78 | MACHINE_END | ||
79 | #endif | ||
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h index 9c75f124e3cf..b7c26b62e4a7 100644 --- a/arch/arm/mach-prima2/common.h +++ b/arch/arm/mach-prima2/common.h | |||
@@ -11,12 +11,19 @@ | |||
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <asm/mach/time.h> | 13 | #include <asm/mach/time.h> |
14 | #include <asm/exception.h> | ||
14 | 15 | ||
15 | extern void sirfsoc_timer_init(void); | 16 | extern void sirfsoc_prima2_timer_init(void); |
17 | extern void sirfsoc_marco_timer_init(void); | ||
18 | |||
19 | extern struct smp_operations sirfsoc_smp_ops; | ||
20 | extern void sirfsoc_secondary_startup(void); | ||
21 | extern void sirfsoc_cpu_die(unsigned int cpu); | ||
16 | 22 | ||
17 | extern void __init sirfsoc_of_irq_init(void); | 23 | extern void __init sirfsoc_of_irq_init(void); |
18 | extern void __init sirfsoc_of_clk_init(void); | 24 | extern void __init sirfsoc_of_clk_init(void); |
19 | extern void sirfsoc_restart(char, const char *); | 25 | extern void sirfsoc_restart(char, const char *); |
26 | extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs); | ||
20 | 27 | ||
21 | #ifndef CONFIG_DEBUG_LL | 28 | #ifndef CONFIG_DEBUG_LL |
22 | static inline void sirfsoc_map_lluart(void) {} | 29 | static inline void sirfsoc_map_lluart(void) {} |
@@ -24,6 +31,12 @@ static inline void sirfsoc_map_lluart(void) {} | |||
24 | extern void __init sirfsoc_map_lluart(void); | 31 | extern void __init sirfsoc_map_lluart(void); |
25 | #endif | 32 | #endif |
26 | 33 | ||
34 | #ifndef CONFIG_SMP | ||
35 | static inline void sirfsoc_map_scu(void) {} | ||
36 | #else | ||
37 | extern void sirfsoc_map_scu(void); | ||
38 | #endif | ||
39 | |||
27 | #ifdef CONFIG_SUSPEND | 40 | #ifdef CONFIG_SUSPEND |
28 | extern int sirfsoc_pm_init(void); | 41 | extern int sirfsoc_pm_init(void); |
29 | #else | 42 | #else |
diff --git a/arch/arm/mach-prima2/headsmp.S b/arch/arm/mach-prima2/headsmp.S new file mode 100644 index 000000000000..5b8a408d8921 --- /dev/null +++ b/arch/arm/mach-prima2/headsmp.S | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * Entry of the second core for CSR Marco dual-core SMP SoCs | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/linkage.h> | ||
10 | #include <linux/init.h> | ||
11 | |||
12 | __CPUINIT | ||
13 | |||
14 | /* | ||
15 | * SIRFSOC specific entry point for secondary CPUs. This provides | ||
16 | * a "holding pen" into which all secondary cores are held until we're | ||
17 | * ready for them to initialise. | ||
18 | */ | ||
19 | ENTRY(sirfsoc_secondary_startup) | ||
20 | bl v7_invalidate_l1 | ||
21 | mrc p15, 0, r0, c0, c0, 5 | ||
22 | and r0, r0, #15 | ||
23 | adr r4, 1f | ||
24 | ldmia r4, {r5, r6} | ||
25 | sub r4, r4, r5 | ||
26 | add r6, r6, r4 | ||
27 | pen: ldr r7, [r6] | ||
28 | cmp r7, r0 | ||
29 | bne pen | ||
30 | |||
31 | /* | ||
32 | * we've been released from the holding pen: secondary_stack | ||
33 | * should now contain the SVC stack for this core | ||
34 | */ | ||
35 | b secondary_startup | ||
36 | ENDPROC(sirfsoc_secondary_startup) | ||
37 | |||
38 | .align | ||
39 | 1: .long . | ||
40 | .long pen_release | ||
diff --git a/arch/arm/mach-prima2/hotplug.c b/arch/arm/mach-prima2/hotplug.c new file mode 100644 index 000000000000..f4b17cbababd --- /dev/null +++ b/arch/arm/mach-prima2/hotplug.c | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * CPU hotplug support for CSR Marco dual-core SMP SoCs | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/smp.h> | ||
12 | |||
13 | #include <asm/cacheflush.h> | ||
14 | #include <asm/smp_plat.h> | ||
15 | |||
16 | static inline void platform_do_lowpower(unsigned int cpu) | ||
17 | { | ||
18 | flush_cache_all(); | ||
19 | |||
20 | /* we put the platform to just WFI */ | ||
21 | for (;;) { | ||
22 | __asm__ __volatile__("dsb\n\t" "wfi\n\t" | ||
23 | : : : "memory"); | ||
24 | if (pen_release == cpu_logical_map(cpu)) { | ||
25 | /* | ||
26 | * OK, proper wakeup, we're done | ||
27 | */ | ||
28 | break; | ||
29 | } | ||
30 | } | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * platform-specific code to shutdown a CPU | ||
35 | * | ||
36 | * Called with IRQs disabled | ||
37 | */ | ||
38 | void __ref sirfsoc_cpu_die(unsigned int cpu) | ||
39 | { | ||
40 | platform_do_lowpower(cpu); | ||
41 | } | ||
diff --git a/arch/arm/mach-prima2/include/mach/irqs.h b/arch/arm/mach-prima2/include/mach/irqs.h index f6014a07541f..b778a0f248ed 100644 --- a/arch/arm/mach-prima2/include/mach/irqs.h +++ b/arch/arm/mach-prima2/include/mach/irqs.h | |||
@@ -10,8 +10,8 @@ | |||
10 | #define __ASM_ARCH_IRQS_H | 10 | #define __ASM_ARCH_IRQS_H |
11 | 11 | ||
12 | #define SIRFSOC_INTENAL_IRQ_START 0 | 12 | #define SIRFSOC_INTENAL_IRQ_START 0 |
13 | #define SIRFSOC_INTENAL_IRQ_END 59 | 13 | #define SIRFSOC_INTENAL_IRQ_END 127 |
14 | #define SIRFSOC_GPIO_IRQ_START (SIRFSOC_INTENAL_IRQ_END + 1) | 14 | #define SIRFSOC_GPIO_IRQ_START (SIRFSOC_INTENAL_IRQ_END + 1) |
15 | #define NR_IRQS 220 | 15 | #define NR_IRQS 288 |
16 | 16 | ||
17 | #endif | 17 | #endif |
diff --git a/arch/arm/mach-prima2/include/mach/uart.h b/arch/arm/mach-prima2/include/mach/uart.h index c98b4d5ac24a..c10510d01a44 100644 --- a/arch/arm/mach-prima2/include/mach/uart.h +++ b/arch/arm/mach-prima2/include/mach/uart.h | |||
@@ -10,7 +10,13 @@ | |||
10 | #define __MACH_PRIMA2_SIRFSOC_UART_H | 10 | #define __MACH_PRIMA2_SIRFSOC_UART_H |
11 | 11 | ||
12 | /* UART-1: used as serial debug port */ | 12 | /* UART-1: used as serial debug port */ |
13 | #if defined(CONFIG_DEBUG_SIRFPRIMA2_UART1) | ||
13 | #define SIRFSOC_UART1_PA_BASE 0xb0060000 | 14 | #define SIRFSOC_UART1_PA_BASE 0xb0060000 |
15 | #elif defined(CONFIG_DEBUG_SIRFMARCO_UART1) | ||
16 | #define SIRFSOC_UART1_PA_BASE 0xcc060000 | ||
17 | #else | ||
18 | #define SIRFSOC_UART1_PA_BASE 0 | ||
19 | #endif | ||
14 | #define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000) | 20 | #define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000) |
15 | #define SIRFSOC_UART1_SIZE SZ_4K | 21 | #define SIRFSOC_UART1_SIZE SZ_4K |
16 | 22 | ||
diff --git a/arch/arm/mach-prima2/include/mach/uncompress.h b/arch/arm/mach-prima2/include/mach/uncompress.h index f72ca26ab4fe..d1513a33709a 100644 --- a/arch/arm/mach-prima2/include/mach/uncompress.h +++ b/arch/arm/mach-prima2/include/mach/uncompress.h | |||
@@ -23,6 +23,9 @@ static __inline__ void putc(char c) | |||
23 | * during kernel decompression, all mappings are flat: | 23 | * during kernel decompression, all mappings are flat: |
24 | * virt_addr == phys_addr | 24 | * virt_addr == phys_addr |
25 | */ | 25 | */ |
26 | if (!SIRFSOC_UART1_PA_BASE) | ||
27 | return; | ||
28 | |||
26 | while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) | 29 | while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) |
27 | & SIRFSOC_UART1_TXFIFO_FULL) | 30 | & SIRFSOC_UART1_TXFIFO_FULL) |
28 | barrier(); | 31 | barrier(); |
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c index 7dee9176e77a..6c0f3e9c43fb 100644 --- a/arch/arm/mach-prima2/irq.c +++ b/arch/arm/mach-prima2/irq.c | |||
@@ -9,17 +9,19 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <mach/hardware.h> | ||
13 | #include <asm/mach/irq.h> | ||
14 | #include <linux/of.h> | 12 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 13 | #include <linux/of_address.h> |
16 | #include <linux/irqdomain.h> | 14 | #include <linux/irqdomain.h> |
17 | #include <linux/syscore_ops.h> | 15 | #include <linux/syscore_ops.h> |
16 | #include <asm/mach/irq.h> | ||
17 | #include <asm/exception.h> | ||
18 | #include <mach/hardware.h> | ||
18 | 19 | ||
19 | #define SIRFSOC_INT_RISC_MASK0 0x0018 | 20 | #define SIRFSOC_INT_RISC_MASK0 0x0018 |
20 | #define SIRFSOC_INT_RISC_MASK1 0x001C | 21 | #define SIRFSOC_INT_RISC_MASK1 0x001C |
21 | #define SIRFSOC_INT_RISC_LEVEL0 0x0020 | 22 | #define SIRFSOC_INT_RISC_LEVEL0 0x0020 |
22 | #define SIRFSOC_INT_RISC_LEVEL1 0x0024 | 23 | #define SIRFSOC_INT_RISC_LEVEL1 0x0024 |
24 | #define SIRFSOC_INIT_IRQ_ID 0x0038 | ||
23 | 25 | ||
24 | void __iomem *sirfsoc_intc_base; | 26 | void __iomem *sirfsoc_intc_base; |
25 | 27 | ||
@@ -52,6 +54,16 @@ static __init void sirfsoc_irq_init(void) | |||
52 | writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); | 54 | writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); |
53 | } | 55 | } |
54 | 56 | ||
57 | asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) | ||
58 | { | ||
59 | u32 irqstat, irqnr; | ||
60 | |||
61 | irqstat = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INIT_IRQ_ID); | ||
62 | irqnr = irqstat & 0xff; | ||
63 | |||
64 | handle_IRQ(irqnr, regs); | ||
65 | } | ||
66 | |||
55 | static struct of_device_id intc_ids[] = { | 67 | static struct of_device_id intc_ids[] = { |
56 | { .compatible = "sirf,prima2-intc" }, | 68 | { .compatible = "sirf,prima2-intc" }, |
57 | {}, | 69 | {}, |
diff --git a/arch/arm/mach-prima2/l2x0.c b/arch/arm/mach-prima2/l2x0.c index c99837797d76..cbcbe9cb094c 100644 --- a/arch/arm/mach-prima2/l2x0.c +++ b/arch/arm/mach-prima2/l2x0.c | |||
@@ -11,19 +11,38 @@ | |||
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <asm/hardware/cache-l2x0.h> | 12 | #include <asm/hardware/cache-l2x0.h> |
13 | 13 | ||
14 | static struct of_device_id prima2_l2x0_ids[] = { | 14 | struct l2x0_aux |
15 | { .compatible = "sirf,prima2-pl310-cache" }, | 15 | { |
16 | u32 val; | ||
17 | u32 mask; | ||
18 | }; | ||
19 | |||
20 | static struct l2x0_aux prima2_l2x0_aux __initconst = { | ||
21 | .val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT, | ||
22 | .mask = 0, | ||
23 | }; | ||
24 | |||
25 | static struct l2x0_aux marco_l2x0_aux __initconst = { | ||
26 | .val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | | ||
27 | (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT), | ||
28 | .mask = L2X0_AUX_CTRL_MASK, | ||
29 | }; | ||
30 | |||
31 | static struct of_device_id sirf_l2x0_ids[] __initconst = { | ||
32 | { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, }, | ||
33 | { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, }, | ||
16 | {}, | 34 | {}, |
17 | }; | 35 | }; |
18 | 36 | ||
19 | static int __init sirfsoc_l2x0_init(void) | 37 | static int __init sirfsoc_l2x0_init(void) |
20 | { | 38 | { |
21 | struct device_node *np; | 39 | struct device_node *np; |
40 | const struct l2x0_aux *aux; | ||
22 | 41 | ||
23 | np = of_find_matching_node(NULL, prima2_l2x0_ids); | 42 | np = of_find_matching_node(NULL, sirf_l2x0_ids); |
24 | if (np) { | 43 | if (np) { |
25 | pr_info("Initializing prima2 L2 cache\n"); | 44 | aux = of_match_node(sirf_l2x0_ids, np)->data; |
26 | return l2x0_of_init(0x40000, 0); | 45 | return l2x0_of_init(aux->val, aux->mask); |
27 | } | 46 | } |
28 | 47 | ||
29 | return 0; | 48 | return 0; |
diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c new file mode 100644 index 000000000000..4b788310f6a6 --- /dev/null +++ b/arch/arm/mach-prima2/platsmp.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * plat smp support for CSR Marco dual-core SMP SoCs | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/smp.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <linux/of.h> | ||
13 | #include <linux/of_address.h> | ||
14 | #include <linux/irqchip/arm-gic.h> | ||
15 | #include <asm/page.h> | ||
16 | #include <asm/mach/map.h> | ||
17 | #include <asm/smp_plat.h> | ||
18 | #include <asm/smp_scu.h> | ||
19 | #include <asm/cacheflush.h> | ||
20 | #include <asm/cputype.h> | ||
21 | #include <mach/map.h> | ||
22 | |||
23 | #include "common.h" | ||
24 | |||
25 | static void __iomem *scu_base; | ||
26 | static void __iomem *rsc_base; | ||
27 | |||
28 | static DEFINE_SPINLOCK(boot_lock); | ||
29 | |||
30 | static struct map_desc scu_io_desc __initdata = { | ||
31 | .length = SZ_4K, | ||
32 | .type = MT_DEVICE, | ||
33 | }; | ||
34 | |||
35 | void __init sirfsoc_map_scu(void) | ||
36 | { | ||
37 | unsigned long base; | ||
38 | |||
39 | /* Get SCU base */ | ||
40 | asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); | ||
41 | |||
42 | scu_io_desc.virtual = SIRFSOC_VA(base); | ||
43 | scu_io_desc.pfn = __phys_to_pfn(base); | ||
44 | iotable_init(&scu_io_desc, 1); | ||
45 | |||
46 | scu_base = (void __iomem *)SIRFSOC_VA(base); | ||
47 | } | ||
48 | |||
49 | static void __cpuinit sirfsoc_secondary_init(unsigned int cpu) | ||
50 | { | ||
51 | /* | ||
52 | * if any interrupts are already enabled for the primary | ||
53 | * core (e.g. timer irq), then they will not have been enabled | ||
54 | * for us: do so | ||
55 | */ | ||
56 | gic_secondary_init(0); | ||
57 | |||
58 | /* | ||
59 | * let the primary processor know we're out of the | ||
60 | * pen, then head off into the C entry point | ||
61 | */ | ||
62 | pen_release = -1; | ||
63 | smp_wmb(); | ||
64 | |||
65 | /* | ||
66 | * Synchronise with the boot thread. | ||
67 | */ | ||
68 | spin_lock(&boot_lock); | ||
69 | spin_unlock(&boot_lock); | ||
70 | } | ||
71 | |||
72 | static struct of_device_id rsc_ids[] = { | ||
73 | { .compatible = "sirf,marco-rsc" }, | ||
74 | {}, | ||
75 | }; | ||
76 | |||
77 | static int __cpuinit sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
78 | { | ||
79 | unsigned long timeout; | ||
80 | struct device_node *np; | ||
81 | |||
82 | np = of_find_matching_node(NULL, rsc_ids); | ||
83 | if (!np) | ||
84 | return -ENODEV; | ||
85 | |||
86 | rsc_base = of_iomap(np, 0); | ||
87 | if (!rsc_base) | ||
88 | return -ENOMEM; | ||
89 | |||
90 | /* | ||
91 | * write the address of secondary startup into the sram register | ||
92 | * at offset 0x2C, then write the magic number 0x3CAF5D62 to the | ||
93 | * RSC register at offset 0x28, which is what boot rom code is | ||
94 | * waiting for. This would wake up the secondary core from WFE | ||
95 | */ | ||
96 | #define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2C | ||
97 | __raw_writel(virt_to_phys(sirfsoc_secondary_startup), | ||
98 | rsc_base + SIRFSOC_CPU1_JUMPADDR_OFFSET); | ||
99 | |||
100 | #define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x28 | ||
101 | __raw_writel(0x3CAF5D62, | ||
102 | rsc_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET); | ||
103 | |||
104 | /* make sure write buffer is drained */ | ||
105 | mb(); | ||
106 | |||
107 | spin_lock(&boot_lock); | ||
108 | |||
109 | /* | ||
110 | * The secondary processor is waiting to be released from | ||
111 | * the holding pen - release it, then wait for it to flag | ||
112 | * that it has been released by resetting pen_release. | ||
113 | * | ||
114 | * Note that "pen_release" is the hardware CPU ID, whereas | ||
115 | * "cpu" is Linux's internal ID. | ||
116 | */ | ||
117 | pen_release = cpu_logical_map(cpu); | ||
118 | __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); | ||
119 | outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); | ||
120 | |||
121 | /* | ||
122 | * Send the secondary CPU SEV, thereby causing the boot monitor to read | ||
123 | * the JUMPADDR and WAKEMAGIC, and branch to the address found there. | ||
124 | */ | ||
125 | dsb_sev(); | ||
126 | |||
127 | timeout = jiffies + (1 * HZ); | ||
128 | while (time_before(jiffies, timeout)) { | ||
129 | smp_rmb(); | ||
130 | if (pen_release == -1) | ||
131 | break; | ||
132 | |||
133 | udelay(10); | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * now the secondary core is starting up let it run its | ||
138 | * calibrations, then wait for it to finish | ||
139 | */ | ||
140 | spin_unlock(&boot_lock); | ||
141 | |||
142 | return pen_release != -1 ? -ENOSYS : 0; | ||
143 | } | ||
144 | |||
145 | static void __init sirfsoc_smp_prepare_cpus(unsigned int max_cpus) | ||
146 | { | ||
147 | scu_enable(scu_base); | ||
148 | } | ||
149 | |||
150 | struct smp_operations sirfsoc_smp_ops __initdata = { | ||
151 | .smp_prepare_cpus = sirfsoc_smp_prepare_cpus, | ||
152 | .smp_secondary_init = sirfsoc_secondary_init, | ||
153 | .smp_boot_secondary = sirfsoc_boot_secondary, | ||
154 | #ifdef CONFIG_HOTPLUG_CPU | ||
155 | .cpu_die = sirfsoc_cpu_die, | ||
156 | #endif | ||
157 | }; | ||
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c index 762adb73ab7c..435019ca0a48 100644 --- a/arch/arm/mach-prima2/rstc.c +++ b/arch/arm/mach-prima2/rstc.c | |||
@@ -19,6 +19,7 @@ static DEFINE_MUTEX(rstc_lock); | |||
19 | 19 | ||
20 | static struct of_device_id rstc_ids[] = { | 20 | static struct of_device_id rstc_ids[] = { |
21 | { .compatible = "sirf,prima2-rstc" }, | 21 | { .compatible = "sirf,prima2-rstc" }, |
22 | { .compatible = "sirf,marco-rstc" }, | ||
22 | {}, | 23 | {}, |
23 | }; | 24 | }; |
24 | 25 | ||
@@ -42,27 +43,37 @@ early_initcall(sirfsoc_of_rstc_init); | |||
42 | 43 | ||
43 | int sirfsoc_reset_device(struct device *dev) | 44 | int sirfsoc_reset_device(struct device *dev) |
44 | { | 45 | { |
45 | const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL); | 46 | u32 reset_bit; |
46 | unsigned int reset_bit; | ||
47 | 47 | ||
48 | if (!prop) | 48 | if (of_property_read_u32(dev->of_node, "reset-bit", &reset_bit)) |
49 | return -ENODEV; | 49 | return -EINVAL; |
50 | |||
51 | reset_bit = be32_to_cpup(prop); | ||
52 | 50 | ||
53 | mutex_lock(&rstc_lock); | 51 | mutex_lock(&rstc_lock); |
54 | 52 | ||
55 | /* | 53 | if (of_device_is_compatible(dev->of_node, "sirf,prima2-rstc")) { |
56 | * Writing 1 to this bit resets corresponding block. Writing 0 to this | 54 | /* |
57 | * bit de-asserts reset signal of the corresponding block. | 55 | * Writing 1 to this bit resets corresponding block. Writing 0 to this |
58 | * datasheet doesn't require explicit delay between the set and clear | 56 | * bit de-asserts reset signal of the corresponding block. |
59 | * of reset bit. it could be shorter if tests pass. | 57 | * datasheet doesn't require explicit delay between the set and clear |
60 | */ | 58 | * of reset bit. it could be shorter if tests pass. |
61 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, | 59 | */ |
62 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 60 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, |
63 | msleep(10); | 61 | sirfsoc_rstc_base + (reset_bit / 32) * 4); |
64 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, | 62 | msleep(10); |
65 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 63 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, |
64 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | ||
65 | } else { | ||
66 | /* | ||
67 | * For MARCO and POLO | ||
68 | * Writing 1 to SET register resets corresponding block. Writing 1 to CLEAR | ||
69 | * register de-asserts reset signal of the corresponding block. | ||
70 | * datasheet doesn't require explicit delay between the set and clear | ||
71 | * of reset bit. it could be shorter if tests pass. | ||
72 | */ | ||
73 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); | ||
74 | msleep(10); | ||
75 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); | ||
76 | } | ||
66 | 77 | ||
67 | mutex_unlock(&rstc_lock); | 78 | mutex_unlock(&rstc_lock); |
68 | 79 | ||
diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c index 557353602130..9f2da2eec4dc 100644 --- a/arch/arm/mach-prima2/rtciobrg.c +++ b/arch/arm/mach-prima2/rtciobrg.c | |||
@@ -104,6 +104,7 @@ EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel); | |||
104 | 104 | ||
105 | static const struct of_device_id rtciobrg_ids[] = { | 105 | static const struct of_device_id rtciobrg_ids[] = { |
106 | { .compatible = "sirf,prima2-rtciobg" }, | 106 | { .compatible = "sirf,prima2-rtciobg" }, |
107 | { .compatible = "sirf,marco-rtciobg" }, | ||
107 | {} | 108 | {} |
108 | }; | 109 | }; |
109 | 110 | ||
diff --git a/arch/arm/mach-prima2/timer-marco.c b/arch/arm/mach-prima2/timer-marco.c new file mode 100644 index 000000000000..f4eea2e97eb0 --- /dev/null +++ b/arch/arm/mach-prima2/timer-marco.c | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | * System timer for CSR SiRFprimaII | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/clockchips.h> | ||
12 | #include <linux/clocksource.h> | ||
13 | #include <linux/bitops.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_irq.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <asm/sched_clock.h> | ||
21 | #include <asm/localtimer.h> | ||
22 | #include <asm/mach/time.h> | ||
23 | |||
24 | #include "common.h" | ||
25 | |||
26 | #define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 | ||
27 | #define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004 | ||
28 | #define SIRFSOC_TIMER_MATCH_0 0x0018 | ||
29 | #define SIRFSOC_TIMER_MATCH_1 0x001c | ||
30 | #define SIRFSOC_TIMER_COUNTER_0 0x0048 | ||
31 | #define SIRFSOC_TIMER_COUNTER_1 0x004c | ||
32 | #define SIRFSOC_TIMER_INTR_STATUS 0x0060 | ||
33 | #define SIRFSOC_TIMER_WATCHDOG_EN 0x0064 | ||
34 | #define SIRFSOC_TIMER_64COUNTER_CTRL 0x0068 | ||
35 | #define SIRFSOC_TIMER_64COUNTER_LO 0x006c | ||
36 | #define SIRFSOC_TIMER_64COUNTER_HI 0x0070 | ||
37 | #define SIRFSOC_TIMER_64COUNTER_LOAD_LO 0x0074 | ||
38 | #define SIRFSOC_TIMER_64COUNTER_LOAD_HI 0x0078 | ||
39 | #define SIRFSOC_TIMER_64COUNTER_RLATCHED_LO 0x007c | ||
40 | #define SIRFSOC_TIMER_64COUNTER_RLATCHED_HI 0x0080 | ||
41 | |||
42 | #define SIRFSOC_TIMER_REG_CNT 6 | ||
43 | |||
44 | static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = { | ||
45 | SIRFSOC_TIMER_WATCHDOG_EN, | ||
46 | SIRFSOC_TIMER_32COUNTER_0_CTRL, | ||
47 | SIRFSOC_TIMER_32COUNTER_1_CTRL, | ||
48 | SIRFSOC_TIMER_64COUNTER_CTRL, | ||
49 | SIRFSOC_TIMER_64COUNTER_RLATCHED_LO, | ||
50 | SIRFSOC_TIMER_64COUNTER_RLATCHED_HI, | ||
51 | }; | ||
52 | |||
53 | static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT]; | ||
54 | |||
55 | static void __iomem *sirfsoc_timer_base; | ||
56 | static void __init sirfsoc_of_timer_map(void); | ||
57 | |||
58 | /* disable count and interrupt */ | ||
59 | static inline void sirfsoc_timer_count_disable(int idx) | ||
60 | { | ||
61 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) & ~0x7, | ||
62 | sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx); | ||
63 | } | ||
64 | |||
65 | /* enable count and interrupt */ | ||
66 | static inline void sirfsoc_timer_count_enable(int idx) | ||
67 | { | ||
68 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) | 0x7, | ||
69 | sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx); | ||
70 | } | ||
71 | |||
72 | /* timer interrupt handler */ | ||
73 | static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id) | ||
74 | { | ||
75 | struct clock_event_device *ce = dev_id; | ||
76 | int cpu = smp_processor_id(); | ||
77 | |||
78 | /* clear timer interrupt */ | ||
79 | writel_relaxed(BIT(cpu), sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); | ||
80 | |||
81 | if (ce->mode == CLOCK_EVT_MODE_ONESHOT) | ||
82 | sirfsoc_timer_count_disable(cpu); | ||
83 | |||
84 | ce->event_handler(ce); | ||
85 | |||
86 | return IRQ_HANDLED; | ||
87 | } | ||
88 | |||
89 | /* read 64-bit timer counter */ | ||
90 | static cycle_t sirfsoc_timer_read(struct clocksource *cs) | ||
91 | { | ||
92 | u64 cycles; | ||
93 | |||
94 | writel_relaxed((readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) | | ||
95 | BIT(0)) & ~BIT(1), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
96 | |||
97 | cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_HI); | ||
98 | cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_LO); | ||
99 | |||
100 | return cycles; | ||
101 | } | ||
102 | |||
103 | static int sirfsoc_timer_set_next_event(unsigned long delta, | ||
104 | struct clock_event_device *ce) | ||
105 | { | ||
106 | int cpu = smp_processor_id(); | ||
107 | |||
108 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0 + | ||
109 | 4 * cpu); | ||
110 | writel_relaxed(delta, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0 + | ||
111 | 4 * cpu); | ||
112 | |||
113 | /* enable the tick */ | ||
114 | sirfsoc_timer_count_enable(cpu); | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void sirfsoc_timer_set_mode(enum clock_event_mode mode, | ||
120 | struct clock_event_device *ce) | ||
121 | { | ||
122 | switch (mode) { | ||
123 | case CLOCK_EVT_MODE_ONESHOT: | ||
124 | /* enable in set_next_event */ | ||
125 | break; | ||
126 | default: | ||
127 | break; | ||
128 | } | ||
129 | |||
130 | sirfsoc_timer_count_disable(smp_processor_id()); | ||
131 | } | ||
132 | |||
133 | static void sirfsoc_clocksource_suspend(struct clocksource *cs) | ||
134 | { | ||
135 | int i; | ||
136 | |||
137 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) | ||
138 | sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | ||
139 | } | ||
140 | |||
141 | static void sirfsoc_clocksource_resume(struct clocksource *cs) | ||
142 | { | ||
143 | int i; | ||
144 | |||
145 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) | ||
146 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | ||
147 | |||
148 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], | ||
149 | sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO); | ||
150 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], | ||
151 | sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI); | ||
152 | |||
153 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) | | ||
154 | BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
155 | } | ||
156 | |||
157 | static struct clock_event_device sirfsoc_clockevent = { | ||
158 | .name = "sirfsoc_clockevent", | ||
159 | .rating = 200, | ||
160 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
161 | .set_mode = sirfsoc_timer_set_mode, | ||
162 | .set_next_event = sirfsoc_timer_set_next_event, | ||
163 | }; | ||
164 | |||
165 | static struct clocksource sirfsoc_clocksource = { | ||
166 | .name = "sirfsoc_clocksource", | ||
167 | .rating = 200, | ||
168 | .mask = CLOCKSOURCE_MASK(64), | ||
169 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
170 | .read = sirfsoc_timer_read, | ||
171 | .suspend = sirfsoc_clocksource_suspend, | ||
172 | .resume = sirfsoc_clocksource_resume, | ||
173 | }; | ||
174 | |||
175 | static struct irqaction sirfsoc_timer_irq = { | ||
176 | .name = "sirfsoc_timer0", | ||
177 | .flags = IRQF_TIMER | IRQF_NOBALANCING, | ||
178 | .handler = sirfsoc_timer_interrupt, | ||
179 | .dev_id = &sirfsoc_clockevent, | ||
180 | }; | ||
181 | |||
182 | #ifdef CONFIG_LOCAL_TIMERS | ||
183 | |||
184 | static struct irqaction sirfsoc_timer1_irq = { | ||
185 | .name = "sirfsoc_timer1", | ||
186 | .flags = IRQF_TIMER | IRQF_NOBALANCING, | ||
187 | .handler = sirfsoc_timer_interrupt, | ||
188 | }; | ||
189 | |||
190 | static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce) | ||
191 | { | ||
192 | /* Use existing clock_event for cpu 0 */ | ||
193 | if (!smp_processor_id()) | ||
194 | return 0; | ||
195 | |||
196 | ce->irq = sirfsoc_timer1_irq.irq; | ||
197 | ce->name = "local_timer"; | ||
198 | ce->features = sirfsoc_clockevent.features; | ||
199 | ce->rating = sirfsoc_clockevent.rating; | ||
200 | ce->set_mode = sirfsoc_timer_set_mode; | ||
201 | ce->set_next_event = sirfsoc_timer_set_next_event; | ||
202 | ce->shift = sirfsoc_clockevent.shift; | ||
203 | ce->mult = sirfsoc_clockevent.mult; | ||
204 | ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns; | ||
205 | ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns; | ||
206 | |||
207 | sirfsoc_timer1_irq.dev_id = ce; | ||
208 | BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq)); | ||
209 | irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1)); | ||
210 | |||
211 | clockevents_register_device(ce); | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static void sirfsoc_local_timer_stop(struct clock_event_device *ce) | ||
216 | { | ||
217 | sirfsoc_timer_count_disable(1); | ||
218 | |||
219 | remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); | ||
220 | } | ||
221 | |||
222 | static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = { | ||
223 | .setup = sirfsoc_local_timer_setup, | ||
224 | .stop = sirfsoc_local_timer_stop, | ||
225 | }; | ||
226 | #endif /* CONFIG_LOCAL_TIMERS */ | ||
227 | |||
228 | static void __init sirfsoc_clockevent_init(void) | ||
229 | { | ||
230 | clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60); | ||
231 | |||
232 | sirfsoc_clockevent.max_delta_ns = | ||
233 | clockevent_delta2ns(-2, &sirfsoc_clockevent); | ||
234 | sirfsoc_clockevent.min_delta_ns = | ||
235 | clockevent_delta2ns(2, &sirfsoc_clockevent); | ||
236 | |||
237 | sirfsoc_clockevent.cpumask = cpumask_of(0); | ||
238 | clockevents_register_device(&sirfsoc_clockevent); | ||
239 | #ifdef CONFIG_LOCAL_TIMERS | ||
240 | local_timer_register(&sirfsoc_local_timer_ops); | ||
241 | #endif | ||
242 | } | ||
243 | |||
244 | /* initialize the kernel jiffy timer source */ | ||
245 | void __init sirfsoc_marco_timer_init(void) | ||
246 | { | ||
247 | unsigned long rate; | ||
248 | u32 timer_div; | ||
249 | struct clk *clk; | ||
250 | |||
251 | /* initialize clocking early, we want to set the OS timer */ | ||
252 | sirfsoc_of_clk_init(); | ||
253 | |||
254 | /* timer's input clock is io clock */ | ||
255 | clk = clk_get_sys("io", NULL); | ||
256 | |||
257 | BUG_ON(IS_ERR(clk)); | ||
258 | rate = clk_get_rate(clk); | ||
259 | |||
260 | BUG_ON(rate < CLOCK_TICK_RATE); | ||
261 | BUG_ON(rate % CLOCK_TICK_RATE); | ||
262 | |||
263 | sirfsoc_of_timer_map(); | ||
264 | |||
265 | /* Initialize the timer dividers */ | ||
266 | timer_div = rate / CLOCK_TICK_RATE - 1; | ||
267 | writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
268 | writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL); | ||
269 | writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL); | ||
270 | |||
271 | /* Initialize timer counters to 0 */ | ||
272 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO); | ||
273 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI); | ||
274 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) | | ||
275 | BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
276 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0); | ||
277 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_1); | ||
278 | |||
279 | /* Clear all interrupts */ | ||
280 | writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); | ||
281 | |||
282 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); | ||
283 | |||
284 | BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); | ||
285 | |||
286 | sirfsoc_clockevent_init(); | ||
287 | } | ||
288 | |||
289 | static struct of_device_id timer_ids[] = { | ||
290 | { .compatible = "sirf,marco-tick" }, | ||
291 | {}, | ||
292 | }; | ||
293 | |||
294 | static void __init sirfsoc_of_timer_map(void) | ||
295 | { | ||
296 | struct device_node *np; | ||
297 | |||
298 | np = of_find_matching_node(NULL, timer_ids); | ||
299 | if (!np) | ||
300 | return; | ||
301 | sirfsoc_timer_base = of_iomap(np, 0); | ||
302 | if (!sirfsoc_timer_base) | ||
303 | panic("unable to map timer cpu registers\n"); | ||
304 | |||
305 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); | ||
306 | if (!sirfsoc_timer_irq.irq) | ||
307 | panic("No irq passed for timer0 via DT\n"); | ||
308 | |||
309 | #ifdef CONFIG_LOCAL_TIMERS | ||
310 | sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); | ||
311 | if (!sirfsoc_timer1_irq.irq) | ||
312 | panic("No irq passed for timer1 via DT\n"); | ||
313 | #endif | ||
314 | |||
315 | of_node_put(np); | ||
316 | } | ||
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer-prima2.c index a7a2c199c3ea..6da584f8a949 100644 --- a/arch/arm/mach-prima2/timer.c +++ b/arch/arm/mach-prima2/timer-prima2.c | |||
@@ -181,7 +181,7 @@ static void __init sirfsoc_clockevent_init(void) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | /* initialize the kernel jiffy timer source */ | 183 | /* initialize the kernel jiffy timer source */ |
184 | void __init sirfsoc_timer_init(void) | 184 | void __init sirfsoc_prima2_timer_init(void) |
185 | { | 185 | { |
186 | unsigned long rate; | 186 | unsigned long rate; |
187 | struct clk *clk; | 187 | struct clk *clk; |
@@ -220,14 +220,14 @@ static struct of_device_id timer_ids[] = { | |||
220 | {}, | 220 | {}, |
221 | }; | 221 | }; |
222 | 222 | ||
223 | void __init sirfsoc_of_timer_map(void) | 223 | static void __init sirfsoc_of_timer_map(void) |
224 | { | 224 | { |
225 | struct device_node *np; | 225 | struct device_node *np; |
226 | const unsigned int *intspec; | 226 | const unsigned int *intspec; |
227 | 227 | ||
228 | np = of_find_matching_node(NULL, timer_ids); | 228 | np = of_find_matching_node(NULL, timer_ids); |
229 | if (!np) | 229 | if (!np) |
230 | panic("unable to find compatible timer node in dtb\n"); | 230 | return; |
231 | sirfsoc_timer_base = of_iomap(np, 0); | 231 | sirfsoc_timer_base = of_iomap(np, 0); |
232 | if (!sirfsoc_timer_base) | 232 | if (!sirfsoc_timer_base) |
233 | panic("unable to map timer cpu registers\n"); | 233 | panic("unable to map timer cpu registers\n"); |
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index a1e931337d41..e1fac57514b9 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
@@ -15,7 +15,7 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o | |||
15 | # SMP objects | 15 | # SMP objects |
16 | smp-y := platsmp.o headsmp.o | 16 | smp-y := platsmp.o headsmp.o |
17 | smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 17 | smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
18 | smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o | 18 | smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-sh73a0.o |
19 | smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o | 19 | smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o |
20 | smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o | 20 | smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o |
21 | 21 | ||
@@ -30,6 +30,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o | |||
30 | obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o | 30 | obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o |
31 | obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o | 31 | obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o |
32 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o | 32 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o |
33 | obj-$(CONFIG_ARCH_SH73A0) += pm-sh73a0.o | ||
33 | 34 | ||
34 | # Board objects | 35 | # Board objects |
35 | obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o | 36 | obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o |
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 6bcf3cbd9223..81d91fda2d90 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c | |||
@@ -1181,6 +1181,8 @@ static void __init eva_init(void) | |||
1181 | rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device); | 1181 | rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device); |
1182 | if (usb) | 1182 | if (usb) |
1183 | rmobile_add_device_to_domain("A3SP", usb); | 1183 | rmobile_add_device_to_domain("A3SP", usb); |
1184 | |||
1185 | r8a7740_pm_init(); | ||
1184 | } | 1186 | } |
1185 | 1187 | ||
1186 | static void __init eva_earlytimer_init(void) | 1188 | static void __init eva_earlytimer_init(void) |
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 5394d804a716..3efff2e7b1e7 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c | |||
@@ -772,6 +772,8 @@ static void __init kzm_init(void) | |||
772 | 772 | ||
773 | sh73a0_add_standard_devices(); | 773 | sh73a0_add_standard_devices(); |
774 | platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices)); | 774 | platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices)); |
775 | |||
776 | sh73a0_pm_init(); | ||
775 | } | 777 | } |
776 | 778 | ||
777 | static void kzm9g_restart(char mode, const char *cmd) | 779 | static void kzm9g_restart(char mode, const char *cmd) |
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index eac49d59782f..19ce885a3b43 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c | |||
@@ -581,10 +581,14 @@ static struct clk_lookup lookups[] = { | |||
581 | 581 | ||
582 | /* MSTP32 clocks */ | 582 | /* MSTP32 clocks */ |
583 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), | 583 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), |
584 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP111]), | 584 | CLKDEV_DEV_ID("sh_tmu.3", &mstp_clks[MSTP111]), |
585 | CLKDEV_DEV_ID("sh_tmu.4", &mstp_clks[MSTP111]), | ||
586 | CLKDEV_DEV_ID("sh_tmu.5", &mstp_clks[MSTP111]), | ||
585 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), | 587 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), |
586 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), | 588 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), |
587 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), | 589 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), |
590 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), | ||
591 | CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP125]), | ||
588 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), | 592 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), |
589 | CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), | 593 | CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), |
590 | 594 | ||
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index c019609da660..1db36537255c 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c | |||
@@ -162,6 +162,7 @@ static struct clk_lookup lookups[] = { | |||
162 | CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ | 162 | CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ |
163 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */ | 163 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */ |
164 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */ | 164 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */ |
165 | CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP016]), /* TMU02 */ | ||
165 | CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ | 166 | CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ |
166 | CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ | 167 | CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ |
167 | CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ | 168 | CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 3ca6757b129a..45d21fe317f4 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -544,6 +544,7 @@ static struct clk_lookup lookups[] = { | |||
544 | 544 | ||
545 | /* MSTP32 clocks */ | 545 | /* MSTP32 clocks */ |
546 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ | 546 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ |
547 | CLKDEV_DEV_ID("fff30000.i2c", &mstp_clks[MSTP001]), /* IIC2 */ | ||
547 | CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */ | 548 | CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */ |
548 | CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ | 549 | CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ |
549 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ | 550 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ |
@@ -556,6 +557,7 @@ static struct clk_lookup lookups[] = { | |||
556 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */ | 557 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */ |
557 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ | 558 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ |
558 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ | 559 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ |
560 | CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]), /* IIC0 */ | ||
559 | CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */ | 561 | CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */ |
560 | CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ | 562 | CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ |
561 | CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ | 563 | CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ |
@@ -577,18 +579,25 @@ static struct clk_lookup lookups[] = { | |||
577 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ | 579 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ |
578 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ | 580 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ |
579 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ | 581 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ |
582 | CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]), /* IIC1 */ | ||
580 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ | 583 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ |
581 | CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */ | 584 | CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */ |
582 | CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */ | 585 | CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */ |
583 | CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */ | 586 | CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */ |
584 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ | 587 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ |
588 | CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */ | ||
585 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ | 589 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ |
590 | CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */ | ||
586 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ | 591 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ |
592 | CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMC */ | ||
587 | CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */ | 593 | CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */ |
588 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ | 594 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ |
595 | CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), /* SDHI2 */ | ||
589 | CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ | 596 | CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ |
590 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ | 597 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ |
598 | CLKDEV_DEV_ID("e6d20000.i2c", &mstp_clks[MSTP411]), /* IIC3 */ | ||
591 | CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ | 599 | CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ |
600 | CLKDEV_DEV_ID("e6d30000.i2c", &mstp_clks[MSTP410]), /* IIC4 */ | ||
592 | CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */ | 601 | CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */ |
593 | CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ | 602 | CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ |
594 | CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ | 603 | CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ |
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 516ff7f3e434..afa5423a0f93 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c | |||
@@ -264,17 +264,17 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2, | |||
264 | SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags) | 264 | SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags) |
265 | 265 | ||
266 | static struct clk div4_clks[DIV4_NR] = { | 266 | static struct clk div4_clks[DIV4_NR] = { |
267 | [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT), | 267 | [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT), |
268 | [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT), | 268 | [DIV4_ZG] = DIV4(FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT), |
269 | [DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT), | 269 | [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), |
270 | [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT), | 270 | [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT), |
271 | [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0), | 271 | [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0), |
272 | [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0), | 272 | [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0), |
273 | [DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0), | 273 | [DIV4_Z] = DIV4(FRQCRB, 24, 0x97f, 0), |
274 | [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0), | 274 | [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0), |
275 | [DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0), | 275 | [DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0), |
276 | [DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0), | 276 | [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0), |
277 | [DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0), | 277 | [DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0), |
278 | }; | 278 | }; |
279 | 279 | ||
280 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, | 280 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, |
@@ -525,6 +525,13 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
525 | [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ | 525 | [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ |
526 | }; | 526 | }; |
527 | 527 | ||
528 | /* The lookups structure below includes duplicate entries for some clocks | ||
529 | * with alternate names. | ||
530 | * - The traditional name used when a device is initialised with platform data | ||
531 | * - The name used when a device is initialised using device tree | ||
532 | * The longer-term aim is to remove these duplicates, and indeed the | ||
533 | * lookups table entirely, by describing clocks using device tree. | ||
534 | */ | ||
528 | static struct clk_lookup lookups[] = { | 535 | static struct clk_lookup lookups[] = { |
529 | /* main clocks */ | 536 | /* main clocks */ |
530 | CLKDEV_CON_ID("r_clk", &r_clk), | 537 | CLKDEV_CON_ID("r_clk", &r_clk), |
@@ -545,6 +552,7 @@ static struct clk_lookup lookups[] = { | |||
545 | 552 | ||
546 | /* MSTP32 clocks */ | 553 | /* MSTP32 clocks */ |
547 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ | 554 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ |
555 | CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */ | ||
548 | CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */ | 556 | CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */ |
549 | CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */ | 557 | CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */ |
550 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */ | 558 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */ |
@@ -553,6 +561,7 @@ static struct clk_lookup lookups[] = { | |||
553 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ | 561 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ |
554 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ | 562 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ |
555 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ | 563 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ |
564 | CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */ | ||
556 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ | 565 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ |
557 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ | 566 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */ |
558 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ | 567 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */ |
@@ -569,17 +578,21 @@ static struct clk_lookup lookups[] = { | |||
569 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */ | 578 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */ |
570 | CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ | 579 | CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ |
571 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ | 580 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ |
581 | CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */ | ||
572 | CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ | 582 | CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ |
573 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ | 583 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ |
574 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ | 584 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ |
575 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ | 585 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ |
586 | CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */ | ||
576 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ | 587 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ |
577 | CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ | 588 | CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ |
578 | CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ | 589 | CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ |
579 | CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ | 590 | CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ |
580 | CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */ | 591 | CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */ |
581 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ | 592 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ |
593 | CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */ | ||
582 | CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ | 594 | CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ |
595 | CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */ | ||
583 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ | 596 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ |
584 | }; | 597 | }; |
585 | 598 | ||
diff --git a/arch/arm/mach-shmobile/headsmp-sh73a0.S b/arch/arm/mach-shmobile/headsmp-sh73a0.S new file mode 100644 index 000000000000..bec4c0d9b713 --- /dev/null +++ b/arch/arm/mach-shmobile/headsmp-sh73a0.S | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * SMP support for SoC sh73a0 | ||
3 | * | ||
4 | * Copyright (C) 2012 Bastian Hecht | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation; either version 2 of | ||
9 | * the License, or (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
19 | * MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/linkage.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <asm/memory.h> | ||
25 | |||
26 | __CPUINIT | ||
27 | /* | ||
28 | * Reset vector for secondary CPUs. | ||
29 | * | ||
30 | * First we turn on L1 cache coherency for our CPU. Then we jump to | ||
31 | * shmobile_invalidate_start that invalidates the cache and hands over control | ||
32 | * to the common ARM startup code. | ||
33 | * This function will be mapped to address 0 by the SBAR register. | ||
34 | * A normal branch is out of range here so we need a long jump. We jump to | ||
35 | * the physical address as the MMU is still turned off. | ||
36 | */ | ||
37 | .align 12 | ||
38 | ENTRY(sh73a0_secondary_vector) | ||
39 | mrc p15, 0, r0, c0, c0, 5 @ read MIPDR | ||
40 | and r0, r0, #3 @ mask out cpu ID | ||
41 | lsl r0, r0, #3 @ we will shift by cpu_id * 8 bits | ||
42 | mov r1, #0xf0000000 @ SCU base address | ||
43 | ldr r2, [r1, #8] @ SCU Power Status Register | ||
44 | mov r3, #3 | ||
45 | bic r2, r2, r3, lsl r0 @ Clear bits of our CPU (Run Mode) | ||
46 | str r2, [r1, #8] @ write back | ||
47 | |||
48 | ldr pc, 1f | ||
49 | 1: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET | ||
50 | ENDPROC(sh73a0_secondary_vector) | ||
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index b202c1272526..96001fd49b6c 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S | |||
@@ -16,54 +16,6 @@ | |||
16 | 16 | ||
17 | __CPUINIT | 17 | __CPUINIT |
18 | 18 | ||
19 | /* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks! | ||
20 | * | ||
21 | * The secondary kernel init calls v7_flush_dcache_all before it enables | ||
22 | * the L1; however, the L1 comes out of reset in an undefined state, so | ||
23 | * the clean + invalidate performed by v7_flush_dcache_all causes a bunch | ||
24 | * of cache lines with uninitialized data and uninitialized tags to get | ||
25 | * written out to memory, which does really unpleasant things to the main | ||
26 | * processor. We fix this by performing an invalidate, rather than a | ||
27 | * clean + invalidate, before jumping into the kernel. | ||
28 | * | ||
29 | * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs | ||
30 | * to be called for both secondary cores startup and primary core resume | ||
31 | * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S. | ||
32 | */ | ||
33 | ENTRY(v7_invalidate_l1) | ||
34 | mov r0, #0 | ||
35 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
36 | mcr p15, 2, r0, c0, c0, 0 | ||
37 | mrc p15, 1, r0, c0, c0, 0 | ||
38 | |||
39 | ldr r1, =0x7fff | ||
40 | and r2, r1, r0, lsr #13 | ||
41 | |||
42 | ldr r1, =0x3ff | ||
43 | |||
44 | and r3, r1, r0, lsr #3 @ NumWays - 1 | ||
45 | add r2, r2, #1 @ NumSets | ||
46 | |||
47 | and r0, r0, #0x7 | ||
48 | add r0, r0, #4 @ SetShift | ||
49 | |||
50 | clz r1, r3 @ WayShift | ||
51 | add r4, r3, #1 @ NumWays | ||
52 | 1: sub r2, r2, #1 @ NumSets-- | ||
53 | mov r3, r4 @ Temp = NumWays | ||
54 | 2: subs r3, r3, #1 @ Temp-- | ||
55 | mov r5, r3, lsl r1 | ||
56 | mov r6, r2, lsl r0 | ||
57 | orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) | ||
58 | mcr p15, 0, r5, c7, c6, 2 | ||
59 | bgt 2b | ||
60 | cmp r2, #0 | ||
61 | bgt 1b | ||
62 | dsb | ||
63 | isb | ||
64 | mov pc, lr | ||
65 | ENDPROC(v7_invalidate_l1) | ||
66 | |||
67 | ENTRY(shmobile_invalidate_start) | 19 | ENTRY(shmobile_invalidate_start) |
68 | bl v7_invalidate_l1 | 20 | bl v7_invalidate_l1 |
69 | b secondary_startup | 21 | b secondary_startup |
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c index b09a0bdbf813..a1524e3367b0 100644 --- a/arch/arm/mach-shmobile/hotplug.c +++ b/arch/arm/mach-shmobile/hotplug.c | |||
@@ -56,6 +56,12 @@ int shmobile_cpu_disable(unsigned int cpu) | |||
56 | return cpu == 0 ? -EPERM : 0; | 56 | return cpu == 0 ? -EPERM : 0; |
57 | } | 57 | } |
58 | 58 | ||
59 | int shmobile_cpu_disable_any(unsigned int cpu) | ||
60 | { | ||
61 | cpumask_clear_cpu(cpu, &dead_cpus); | ||
62 | return 0; | ||
63 | } | ||
64 | |||
59 | int shmobile_cpu_is_dead(unsigned int cpu) | 65 | int shmobile_cpu_is_dead(unsigned int cpu) |
60 | { | 66 | { |
61 | return cpumask_test_cpu(cpu, &dead_cpus); | 67 | return cpumask_test_cpu(cpu, &dead_cpus); |
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index a57439eec11a..e48606d8a2be 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h | |||
@@ -23,6 +23,8 @@ extern void sh7372_map_io(void); | |||
23 | extern void sh7372_earlytimer_init(void); | 23 | extern void sh7372_earlytimer_init(void); |
24 | extern void sh7372_add_early_devices(void); | 24 | extern void sh7372_add_early_devices(void); |
25 | extern void sh7372_add_standard_devices(void); | 25 | extern void sh7372_add_standard_devices(void); |
26 | extern void sh7372_add_early_devices_dt(void); | ||
27 | extern void sh7372_add_standard_devices_dt(void); | ||
26 | extern void sh7372_clock_init(void); | 28 | extern void sh7372_clock_init(void); |
27 | extern void sh7372_pinmux_init(void); | 29 | extern void sh7372_pinmux_init(void); |
28 | extern void sh7372_pm_init(void); | 30 | extern void sh7372_pm_init(void); |
@@ -32,12 +34,17 @@ extern struct clk sh7372_extal1_clk; | |||
32 | extern struct clk sh7372_extal2_clk; | 34 | extern struct clk sh7372_extal2_clk; |
33 | 35 | ||
34 | extern void sh73a0_init_irq(void); | 36 | extern void sh73a0_init_irq(void); |
37 | extern void sh73a0_init_irq_dt(void); | ||
35 | extern void sh73a0_map_io(void); | 38 | extern void sh73a0_map_io(void); |
36 | extern void sh73a0_earlytimer_init(void); | 39 | extern void sh73a0_earlytimer_init(void); |
37 | extern void sh73a0_add_early_devices(void); | 40 | extern void sh73a0_add_early_devices(void); |
41 | extern void sh73a0_add_early_devices_dt(void); | ||
38 | extern void sh73a0_add_standard_devices(void); | 42 | extern void sh73a0_add_standard_devices(void); |
43 | extern void sh73a0_add_standard_devices_dt(void); | ||
39 | extern void sh73a0_clock_init(void); | 44 | extern void sh73a0_clock_init(void); |
40 | extern void sh73a0_pinmux_init(void); | 45 | extern void sh73a0_pinmux_init(void); |
46 | extern void sh73a0_pm_init(void); | ||
47 | extern void sh73a0_secondary_vector(void); | ||
41 | extern struct clk sh73a0_extal1_clk; | 48 | extern struct clk sh73a0_extal1_clk; |
42 | extern struct clk sh73a0_extal2_clk; | 49 | extern struct clk sh73a0_extal2_clk; |
43 | extern struct clk sh73a0_extcki_clk; | 50 | extern struct clk sh73a0_extcki_clk; |
@@ -49,6 +56,7 @@ extern void r8a7740_add_early_devices(void); | |||
49 | extern void r8a7740_add_standard_devices(void); | 56 | extern void r8a7740_add_standard_devices(void); |
50 | extern void r8a7740_clock_init(u8 md_ck); | 57 | extern void r8a7740_clock_init(u8 md_ck); |
51 | extern void r8a7740_pinmux_init(void); | 58 | extern void r8a7740_pinmux_init(void); |
59 | extern void r8a7740_pm_init(void); | ||
52 | 60 | ||
53 | extern void r8a7779_init_irq(void); | 61 | extern void r8a7779_init_irq(void); |
54 | extern void r8a7779_map_io(void); | 62 | extern void r8a7779_map_io(void); |
@@ -76,6 +84,7 @@ static inline int shmobile_cpuidle_init(void) { return 0; } | |||
76 | 84 | ||
77 | extern void shmobile_cpu_die(unsigned int cpu); | 85 | extern void shmobile_cpu_die(unsigned int cpu); |
78 | extern int shmobile_cpu_disable(unsigned int cpu); | 86 | extern int shmobile_cpu_disable(unsigned int cpu); |
87 | extern int shmobile_cpu_disable_any(unsigned int cpu); | ||
79 | 88 | ||
80 | #ifdef CONFIG_HOTPLUG_CPU | 89 | #ifdef CONFIG_HOTPLUG_CPU |
81 | extern int shmobile_cpu_is_dead(unsigned int cpu); | 90 | extern int shmobile_cpu_is_dead(unsigned int cpu); |
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index 978369973be4..91faba666d46 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/sh_intc.h> | 25 | #include <linux/sh_intc.h> |
26 | #include <linux/irqchip.h> | ||
26 | #include <linux/irqchip/arm-gic.h> | 27 | #include <linux/irqchip/arm-gic.h> |
27 | #include <mach/intc.h> | 28 | #include <mach/intc.h> |
28 | #include <mach/irqs.h> | 29 | #include <mach/irqs.h> |
@@ -315,11 +316,6 @@ static int intca_gic_set_type(struct irq_data *data, unsigned int type) | |||
315 | return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type); | 316 | return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type); |
316 | } | 317 | } |
317 | 318 | ||
318 | static int intca_gic_set_wake(struct irq_data *data, unsigned int on) | ||
319 | { | ||
320 | return irq_cbp(irq_set_wake, to_intca_reloc_irq(data), on); | ||
321 | } | ||
322 | |||
323 | #ifdef CONFIG_SMP | 319 | #ifdef CONFIG_SMP |
324 | static int intca_gic_set_affinity(struct irq_data *data, | 320 | static int intca_gic_set_affinity(struct irq_data *data, |
325 | const struct cpumask *cpumask, | 321 | const struct cpumask *cpumask, |
@@ -339,7 +335,7 @@ struct irq_chip intca_gic_irq_chip = { | |||
339 | .irq_disable = intca_gic_disable, | 335 | .irq_disable = intca_gic_disable, |
340 | .irq_shutdown = intca_gic_disable, | 336 | .irq_shutdown = intca_gic_disable, |
341 | .irq_set_type = intca_gic_set_type, | 337 | .irq_set_type = intca_gic_set_type, |
342 | .irq_set_wake = intca_gic_set_wake, | 338 | .irq_set_wake = sh73a0_set_wake, |
343 | #ifdef CONFIG_SMP | 339 | #ifdef CONFIG_SMP |
344 | .irq_set_affinity = intca_gic_set_affinity, | 340 | .irq_set_affinity = intca_gic_set_affinity, |
345 | #endif | 341 | #endif |
@@ -464,3 +460,11 @@ void __init sh73a0_init_irq(void) | |||
464 | sh73a0_pint1_cascade.handler = sh73a0_pint1_demux; | 460 | sh73a0_pint1_cascade.handler = sh73a0_pint1_demux; |
465 | setup_irq(gic_spi(34), &sh73a0_pint1_cascade); | 461 | setup_irq(gic_spi(34), &sh73a0_pint1_cascade); |
466 | } | 462 | } |
463 | |||
464 | #ifdef CONFIG_OF | ||
465 | void __init sh73a0_init_irq_dt(void) | ||
466 | { | ||
467 | irqchip_init(); | ||
468 | gic_arch_extn.irq_set_wake = sh73a0_set_wake; | ||
469 | } | ||
470 | #endif | ||
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c index 21e5316d2d88..40b87aa1d448 100644 --- a/arch/arm/mach-shmobile/pm-r8a7740.c +++ b/arch/arm/mach-shmobile/pm-r8a7740.c | |||
@@ -9,7 +9,9 @@ | |||
9 | * for more details. | 9 | * for more details. |
10 | */ | 10 | */ |
11 | #include <linux/console.h> | 11 | #include <linux/console.h> |
12 | #include <linux/suspend.h> | ||
12 | #include <mach/pm-rmobile.h> | 13 | #include <mach/pm-rmobile.h> |
14 | #include <mach/common.h> | ||
13 | 15 | ||
14 | #ifdef CONFIG_PM | 16 | #ifdef CONFIG_PM |
15 | static int r8a7740_pd_a4s_suspend(void) | 17 | static int r8a7740_pd_a4s_suspend(void) |
@@ -58,3 +60,23 @@ void __init r8a7740_init_pm_domains(void) | |||
58 | } | 60 | } |
59 | 61 | ||
60 | #endif /* CONFIG_PM */ | 62 | #endif /* CONFIG_PM */ |
63 | |||
64 | #ifdef CONFIG_SUSPEND | ||
65 | static int r8a7740_enter_suspend(suspend_state_t suspend_state) | ||
66 | { | ||
67 | cpu_do_idle(); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static void r8a7740_suspend_init(void) | ||
72 | { | ||
73 | shmobile_suspend_ops.enter = r8a7740_enter_suspend; | ||
74 | } | ||
75 | #else | ||
76 | static void r8a7740_suspend_init(void) {} | ||
77 | #endif | ||
78 | |||
79 | void __init r8a7740_pm_init(void) | ||
80 | { | ||
81 | r8a7740_suspend_init(); | ||
82 | } | ||
diff --git a/arch/arm/mach-shmobile/pm-sh73a0.c b/arch/arm/mach-shmobile/pm-sh73a0.c new file mode 100644 index 000000000000..99086e98fbbc --- /dev/null +++ b/arch/arm/mach-shmobile/pm-sh73a0.c | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * sh73a0 Power management support | ||
3 | * | ||
4 | * Copyright (C) 2012 Bastian Hecht <hechtb+renesas@gmail.com> | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/suspend.h> | ||
12 | #include <mach/common.h> | ||
13 | |||
14 | #ifdef CONFIG_SUSPEND | ||
15 | static int sh73a0_enter_suspend(suspend_state_t suspend_state) | ||
16 | { | ||
17 | cpu_do_idle(); | ||
18 | return 0; | ||
19 | } | ||
20 | |||
21 | static void sh73a0_suspend_init(void) | ||
22 | { | ||
23 | shmobile_suspend_ops.enter = sh73a0_enter_suspend; | ||
24 | } | ||
25 | #else | ||
26 | static void sh73a0_suspend_init(void) {} | ||
27 | #endif | ||
28 | |||
29 | void __init sh73a0_pm_init(void) | ||
30 | { | ||
31 | sh73a0_suspend_init(); | ||
32 | } | ||
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index b580979923eb..30ac79c7c687 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/serial_sci.h> | 27 | #include <linux/serial_sci.h> |
28 | #include <linux/sh_dma.h> | 28 | #include <linux/sh_dma.h> |
29 | #include <linux/sh_timer.h> | 29 | #include <linux/sh_timer.h> |
30 | #include <linux/dma-mapping.h> | ||
31 | #include <mach/dma-register.h> | 30 | #include <mach/dma-register.h> |
32 | #include <mach/r8a7740.h> | 31 | #include <mach/r8a7740.h> |
33 | #include <mach/pm-rmobile.h> | 32 | #include <mach/pm-rmobile.h> |
@@ -288,6 +287,97 @@ static struct platform_device cmt10_device = { | |||
288 | .num_resources = ARRAY_SIZE(cmt10_resources), | 287 | .num_resources = ARRAY_SIZE(cmt10_resources), |
289 | }; | 288 | }; |
290 | 289 | ||
290 | /* TMU */ | ||
291 | static struct sh_timer_config tmu00_platform_data = { | ||
292 | .name = "TMU00", | ||
293 | .channel_offset = 0x4, | ||
294 | .timer_bit = 0, | ||
295 | .clockevent_rating = 200, | ||
296 | }; | ||
297 | |||
298 | static struct resource tmu00_resources[] = { | ||
299 | [0] = { | ||
300 | .name = "TMU00", | ||
301 | .start = 0xfff80008, | ||
302 | .end = 0xfff80014 - 1, | ||
303 | .flags = IORESOURCE_MEM, | ||
304 | }, | ||
305 | [1] = { | ||
306 | .start = intcs_evt2irq(0xe80), | ||
307 | .flags = IORESOURCE_IRQ, | ||
308 | }, | ||
309 | }; | ||
310 | |||
311 | static struct platform_device tmu00_device = { | ||
312 | .name = "sh_tmu", | ||
313 | .id = 0, | ||
314 | .dev = { | ||
315 | .platform_data = &tmu00_platform_data, | ||
316 | }, | ||
317 | .resource = tmu00_resources, | ||
318 | .num_resources = ARRAY_SIZE(tmu00_resources), | ||
319 | }; | ||
320 | |||
321 | static struct sh_timer_config tmu01_platform_data = { | ||
322 | .name = "TMU01", | ||
323 | .channel_offset = 0x10, | ||
324 | .timer_bit = 1, | ||
325 | .clocksource_rating = 200, | ||
326 | }; | ||
327 | |||
328 | static struct resource tmu01_resources[] = { | ||
329 | [0] = { | ||
330 | .name = "TMU01", | ||
331 | .start = 0xfff80014, | ||
332 | .end = 0xfff80020 - 1, | ||
333 | .flags = IORESOURCE_MEM, | ||
334 | }, | ||
335 | [1] = { | ||
336 | .start = intcs_evt2irq(0xea0), | ||
337 | .flags = IORESOURCE_IRQ, | ||
338 | }, | ||
339 | }; | ||
340 | |||
341 | static struct platform_device tmu01_device = { | ||
342 | .name = "sh_tmu", | ||
343 | .id = 1, | ||
344 | .dev = { | ||
345 | .platform_data = &tmu01_platform_data, | ||
346 | }, | ||
347 | .resource = tmu01_resources, | ||
348 | .num_resources = ARRAY_SIZE(tmu01_resources), | ||
349 | }; | ||
350 | |||
351 | static struct sh_timer_config tmu02_platform_data = { | ||
352 | .name = "TMU02", | ||
353 | .channel_offset = 0x1C, | ||
354 | .timer_bit = 2, | ||
355 | .clocksource_rating = 200, | ||
356 | }; | ||
357 | |||
358 | static struct resource tmu02_resources[] = { | ||
359 | [0] = { | ||
360 | .name = "TMU02", | ||
361 | .start = 0xfff80020, | ||
362 | .end = 0xfff8002C - 1, | ||
363 | .flags = IORESOURCE_MEM, | ||
364 | }, | ||
365 | [1] = { | ||
366 | .start = intcs_evt2irq(0xec0), | ||
367 | .flags = IORESOURCE_IRQ, | ||
368 | }, | ||
369 | }; | ||
370 | |||
371 | static struct platform_device tmu02_device = { | ||
372 | .name = "sh_tmu", | ||
373 | .id = 2, | ||
374 | .dev = { | ||
375 | .platform_data = &tmu02_platform_data, | ||
376 | }, | ||
377 | .resource = tmu02_resources, | ||
378 | .num_resources = ARRAY_SIZE(tmu02_resources), | ||
379 | }; | ||
380 | |||
291 | static struct platform_device *r8a7740_early_devices[] __initdata = { | 381 | static struct platform_device *r8a7740_early_devices[] __initdata = { |
292 | &scif0_device, | 382 | &scif0_device, |
293 | &scif1_device, | 383 | &scif1_device, |
@@ -299,6 +389,9 @@ static struct platform_device *r8a7740_early_devices[] __initdata = { | |||
299 | &scif7_device, | 389 | &scif7_device, |
300 | &scifb_device, | 390 | &scifb_device, |
301 | &cmt10_device, | 391 | &cmt10_device, |
392 | &tmu00_device, | ||
393 | &tmu01_device, | ||
394 | &tmu02_device, | ||
302 | }; | 395 | }; |
303 | 396 | ||
304 | /* DMA */ | 397 | /* DMA */ |
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 344eb79658f9..c54ff9b29fe5 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c | |||
@@ -91,8 +91,7 @@ static struct plat_sci_port scif0_platform_data = { | |||
91 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 91 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
92 | .scbrr_algo_id = SCBRR_ALGO_2, | 92 | .scbrr_algo_id = SCBRR_ALGO_2, |
93 | .type = PORT_SCIF, | 93 | .type = PORT_SCIF, |
94 | .irqs = { gic_spi(88), gic_spi(88), | 94 | .irqs = SCIx_IRQ_MUXED(gic_spi(88)), |
95 | gic_spi(88), gic_spi(88) }, | ||
96 | }; | 95 | }; |
97 | 96 | ||
98 | static struct platform_device scif0_device = { | 97 | static struct platform_device scif0_device = { |
@@ -109,8 +108,7 @@ static struct plat_sci_port scif1_platform_data = { | |||
109 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 108 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
110 | .scbrr_algo_id = SCBRR_ALGO_2, | 109 | .scbrr_algo_id = SCBRR_ALGO_2, |
111 | .type = PORT_SCIF, | 110 | .type = PORT_SCIF, |
112 | .irqs = { gic_spi(89), gic_spi(89), | 111 | .irqs = SCIx_IRQ_MUXED(gic_spi(89)), |
113 | gic_spi(89), gic_spi(89) }, | ||
114 | }; | 112 | }; |
115 | 113 | ||
116 | static struct platform_device scif1_device = { | 114 | static struct platform_device scif1_device = { |
@@ -127,8 +125,7 @@ static struct plat_sci_port scif2_platform_data = { | |||
127 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 125 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
128 | .scbrr_algo_id = SCBRR_ALGO_2, | 126 | .scbrr_algo_id = SCBRR_ALGO_2, |
129 | .type = PORT_SCIF, | 127 | .type = PORT_SCIF, |
130 | .irqs = { gic_spi(90), gic_spi(90), | 128 | .irqs = SCIx_IRQ_MUXED(gic_spi(90)), |
131 | gic_spi(90), gic_spi(90) }, | ||
132 | }; | 129 | }; |
133 | 130 | ||
134 | static struct platform_device scif2_device = { | 131 | static struct platform_device scif2_device = { |
@@ -145,8 +142,7 @@ static struct plat_sci_port scif3_platform_data = { | |||
145 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 142 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
146 | .scbrr_algo_id = SCBRR_ALGO_2, | 143 | .scbrr_algo_id = SCBRR_ALGO_2, |
147 | .type = PORT_SCIF, | 144 | .type = PORT_SCIF, |
148 | .irqs = { gic_spi(91), gic_spi(91), | 145 | .irqs = SCIx_IRQ_MUXED(gic_spi(91)), |
149 | gic_spi(91), gic_spi(91) }, | ||
150 | }; | 146 | }; |
151 | 147 | ||
152 | static struct platform_device scif3_device = { | 148 | static struct platform_device scif3_device = { |
@@ -163,8 +159,7 @@ static struct plat_sci_port scif4_platform_data = { | |||
163 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 159 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
164 | .scbrr_algo_id = SCBRR_ALGO_2, | 160 | .scbrr_algo_id = SCBRR_ALGO_2, |
165 | .type = PORT_SCIF, | 161 | .type = PORT_SCIF, |
166 | .irqs = { gic_spi(92), gic_spi(92), | 162 | .irqs = SCIx_IRQ_MUXED(gic_spi(92)), |
167 | gic_spi(92), gic_spi(92) }, | ||
168 | }; | 163 | }; |
169 | 164 | ||
170 | static struct platform_device scif4_device = { | 165 | static struct platform_device scif4_device = { |
@@ -181,8 +176,7 @@ static struct plat_sci_port scif5_platform_data = { | |||
181 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 176 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
182 | .scbrr_algo_id = SCBRR_ALGO_2, | 177 | .scbrr_algo_id = SCBRR_ALGO_2, |
183 | .type = PORT_SCIF, | 178 | .type = PORT_SCIF, |
184 | .irqs = { gic_spi(93), gic_spi(93), | 179 | .irqs = SCIx_IRQ_MUXED(gic_spi(93)), |
185 | gic_spi(93), gic_spi(93) }, | ||
186 | }; | 180 | }; |
187 | 181 | ||
188 | static struct platform_device scif5_device = { | 182 | static struct platform_device scif5_device = { |
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 48f7f583647a..2ecd6681692f 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/of_platform.h> | ||
26 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
27 | #include <linux/input.h> | 28 | #include <linux/input.h> |
28 | #include <linux/io.h> | 29 | #include <linux/io.h> |
@@ -779,7 +780,7 @@ static struct platform_device pmu_device = { | |||
779 | .resource = pmu_resources, | 780 | .resource = pmu_resources, |
780 | }; | 781 | }; |
781 | 782 | ||
782 | static struct platform_device *sh73a0_early_devices[] __initdata = { | 783 | static struct platform_device *sh73a0_early_devices_dt[] __initdata = { |
783 | &scif0_device, | 784 | &scif0_device, |
784 | &scif1_device, | 785 | &scif1_device, |
785 | &scif2_device, | 786 | &scif2_device, |
@@ -790,6 +791,9 @@ static struct platform_device *sh73a0_early_devices[] __initdata = { | |||
790 | &scif7_device, | 791 | &scif7_device, |
791 | &scif8_device, | 792 | &scif8_device, |
792 | &cmt10_device, | 793 | &cmt10_device, |
794 | }; | ||
795 | |||
796 | static struct platform_device *sh73a0_early_devices[] __initdata = { | ||
793 | &tmu00_device, | 797 | &tmu00_device, |
794 | &tmu01_device, | 798 | &tmu01_device, |
795 | }; | 799 | }; |
@@ -812,6 +816,8 @@ void __init sh73a0_add_standard_devices(void) | |||
812 | /* Clear software reset bit on SY-DMAC module */ | 816 | /* Clear software reset bit on SY-DMAC module */ |
813 | __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); | 817 | __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); |
814 | 818 | ||
819 | platform_add_devices(sh73a0_early_devices_dt, | ||
820 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
815 | platform_add_devices(sh73a0_early_devices, | 821 | platform_add_devices(sh73a0_early_devices, |
816 | ARRAY_SIZE(sh73a0_early_devices)); | 822 | ARRAY_SIZE(sh73a0_early_devices)); |
817 | platform_add_devices(sh73a0_late_devices, | 823 | platform_add_devices(sh73a0_late_devices, |
@@ -830,9 +836,63 @@ void __init sh73a0_earlytimer_init(void) | |||
830 | 836 | ||
831 | void __init sh73a0_add_early_devices(void) | 837 | void __init sh73a0_add_early_devices(void) |
832 | { | 838 | { |
839 | early_platform_add_devices(sh73a0_early_devices_dt, | ||
840 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
833 | early_platform_add_devices(sh73a0_early_devices, | 841 | early_platform_add_devices(sh73a0_early_devices, |
834 | ARRAY_SIZE(sh73a0_early_devices)); | 842 | ARRAY_SIZE(sh73a0_early_devices)); |
835 | 843 | ||
836 | /* setup early console here as well */ | 844 | /* setup early console here as well */ |
837 | shmobile_setup_console(); | 845 | shmobile_setup_console(); |
838 | } | 846 | } |
847 | |||
848 | #ifdef CONFIG_USE_OF | ||
849 | |||
850 | /* Please note that the clock initialisation shcheme used in | ||
851 | * sh73a0_add_early_devices_dt() and sh73a0_add_standard_devices_dt() | ||
852 | * does not work with SMP as there is a yet to be resolved lock-up in | ||
853 | * workqueue initialisation. | ||
854 | * | ||
855 | * CONFIG_SMP should be disabled when using this code. | ||
856 | */ | ||
857 | |||
858 | void __init sh73a0_add_early_devices_dt(void) | ||
859 | { | ||
860 | shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */ | ||
861 | |||
862 | early_platform_add_devices(sh73a0_early_devices_dt, | ||
863 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
864 | |||
865 | /* setup early console here as well */ | ||
866 | shmobile_setup_console(); | ||
867 | } | ||
868 | |||
869 | static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = { | ||
870 | {}, | ||
871 | }; | ||
872 | |||
873 | void __init sh73a0_add_standard_devices_dt(void) | ||
874 | { | ||
875 | /* clocks are setup late during boot in the case of DT */ | ||
876 | sh73a0_clock_init(); | ||
877 | |||
878 | platform_add_devices(sh73a0_early_devices_dt, | ||
879 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
880 | of_platform_populate(NULL, of_default_bus_match_table, | ||
881 | sh73a0_auxdata_lookup, NULL); | ||
882 | } | ||
883 | |||
884 | static const char *sh73a0_boards_compat_dt[] __initdata = { | ||
885 | "renesas,sh73a0", | ||
886 | NULL, | ||
887 | }; | ||
888 | |||
889 | DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") | ||
890 | .map_io = sh73a0_map_io, | ||
891 | .init_early = sh73a0_add_early_devices_dt, | ||
892 | .nr_irqs = NR_IRQS_LEGACY, | ||
893 | .init_irq = sh73a0_init_irq_dt, | ||
894 | .init_machine = sh73a0_add_standard_devices_dt, | ||
895 | .init_time = shmobile_timer_init, | ||
896 | .dt_compat = sh73a0_boards_compat_dt, | ||
897 | MACHINE_END | ||
898 | #endif /* CONFIG_USE_OF */ | ||
diff --git a/arch/arm/mach-shmobile/sleep-sh7372.S b/arch/arm/mach-shmobile/sleep-sh7372.S index 1d564674451d..a9df53b69ab8 100644 --- a/arch/arm/mach-shmobile/sleep-sh7372.S +++ b/arch/arm/mach-shmobile/sleep-sh7372.S | |||
@@ -59,17 +59,19 @@ sh7372_do_idle_sysc: | |||
59 | mcr p15, 0, r0, c1, c0, 0 | 59 | mcr p15, 0, r0, c1, c0, 0 |
60 | isb | 60 | isb |
61 | 61 | ||
62 | /* | ||
63 | * Clean and invalidate data cache again. | ||
64 | */ | ||
65 | ldr r1, kernel_flush | ||
66 | blx r1 | ||
67 | |||
62 | /* disable L2 cache in the aux control register */ | 68 | /* disable L2 cache in the aux control register */ |
63 | mrc p15, 0, r10, c1, c0, 1 | 69 | mrc p15, 0, r10, c1, c0, 1 |
64 | bic r10, r10, #2 | 70 | bic r10, r10, #2 |
65 | mcr p15, 0, r10, c1, c0, 1 | 71 | mcr p15, 0, r10, c1, c0, 1 |
72 | isb | ||
66 | 73 | ||
67 | /* | 74 | /* |
68 | * Invalidate data cache again. | ||
69 | */ | ||
70 | ldr r1, kernel_flush | ||
71 | blx r1 | ||
72 | /* | ||
73 | * The kernel doesn't interwork: v7_flush_dcache_all in particluar will | 75 | * The kernel doesn't interwork: v7_flush_dcache_all in particluar will |
74 | * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. | 76 | * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. |
75 | * This sequence switches back to ARM. Note that .align may insert a | 77 | * This sequence switches back to ARM. Note that .align may insert a |
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 5c5bcb595350..acb46a94ccdf 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/irqchip/arm-gic.h> | 26 | #include <linux/irqchip/arm-gic.h> |
27 | #include <mach/common.h> | 27 | #include <mach/common.h> |
28 | #include <asm/cacheflush.h> | ||
28 | #include <asm/smp_plat.h> | 29 | #include <asm/smp_plat.h> |
29 | #include <mach/sh73a0.h> | 30 | #include <mach/sh73a0.h> |
30 | #include <asm/smp_scu.h> | 31 | #include <asm/smp_scu.h> |
@@ -36,14 +37,13 @@ | |||
36 | #define SBAR IOMEM(0xe6180020) | 37 | #define SBAR IOMEM(0xe6180020) |
37 | #define APARMBAREA IOMEM(0xe6f10020) | 38 | #define APARMBAREA IOMEM(0xe6f10020) |
38 | 39 | ||
40 | #define PSTR_SHUTDOWN_MODE 3 | ||
41 | |||
39 | static void __iomem *scu_base_addr(void) | 42 | static void __iomem *scu_base_addr(void) |
40 | { | 43 | { |
41 | return (void __iomem *)0xf0000000; | 44 | return (void __iomem *)0xf0000000; |
42 | } | 45 | } |
43 | 46 | ||
44 | static DEFINE_SPINLOCK(scu_lock); | ||
45 | static unsigned long tmp; | ||
46 | |||
47 | #ifdef CONFIG_HAVE_ARM_TWD | 47 | #ifdef CONFIG_HAVE_ARM_TWD |
48 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); | 48 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); |
49 | void __init sh73a0_register_twd(void) | 49 | void __init sh73a0_register_twd(void) |
@@ -52,20 +52,6 @@ void __init sh73a0_register_twd(void) | |||
52 | } | 52 | } |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) | ||
56 | { | ||
57 | void __iomem *scu_base = scu_base_addr(); | ||
58 | |||
59 | spin_lock(&scu_lock); | ||
60 | tmp = __raw_readl(scu_base + 8); | ||
61 | tmp &= ~clr; | ||
62 | tmp |= set; | ||
63 | spin_unlock(&scu_lock); | ||
64 | |||
65 | /* disable cache coherency after releasing the lock */ | ||
66 | __raw_writel(tmp, scu_base + 8); | ||
67 | } | ||
68 | |||
69 | static unsigned int __init sh73a0_get_core_count(void) | 55 | static unsigned int __init sh73a0_get_core_count(void) |
70 | { | 56 | { |
71 | void __iomem *scu_base = scu_base_addr(); | 57 | void __iomem *scu_base = scu_base_addr(); |
@@ -82,9 +68,6 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct | |||
82 | { | 68 | { |
83 | cpu = cpu_logical_map(cpu); | 69 | cpu = cpu_logical_map(cpu); |
84 | 70 | ||
85 | /* enable cache coherency */ | ||
86 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); | ||
87 | |||
88 | if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) | 71 | if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) |
89 | __raw_writel(1 << cpu, WUPCR); /* wake up */ | 72 | __raw_writel(1 << cpu, WUPCR); /* wake up */ |
90 | else | 73 | else |
@@ -95,16 +78,14 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct | |||
95 | 78 | ||
96 | static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) | 79 | static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) |
97 | { | 80 | { |
98 | int cpu = cpu_logical_map(0); | ||
99 | |||
100 | scu_enable(scu_base_addr()); | 81 | scu_enable(scu_base_addr()); |
101 | 82 | ||
102 | /* Map the reset vector (in headsmp.S) */ | 83 | /* Map the reset vector (in headsmp-sh73a0.S) */ |
103 | __raw_writel(0, APARMBAREA); /* 4k */ | 84 | __raw_writel(0, APARMBAREA); /* 4k */ |
104 | __raw_writel(__pa(shmobile_secondary_vector), SBAR); | 85 | __raw_writel(__pa(sh73a0_secondary_vector), SBAR); |
105 | 86 | ||
106 | /* enable cache coherency on CPU0 */ | 87 | /* enable cache coherency on booting CPU */ |
107 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); | 88 | scu_power_mode(scu_base_addr(), SCU_PM_NORMAL); |
108 | } | 89 | } |
109 | 90 | ||
110 | static void __init sh73a0_smp_init_cpus(void) | 91 | static void __init sh73a0_smp_init_cpus(void) |
@@ -114,16 +95,20 @@ static void __init sh73a0_smp_init_cpus(void) | |||
114 | shmobile_smp_init_cpus(ncores); | 95 | shmobile_smp_init_cpus(ncores); |
115 | } | 96 | } |
116 | 97 | ||
117 | static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu) | 98 | #ifdef CONFIG_HOTPLUG_CPU |
99 | static int sh73a0_cpu_kill(unsigned int cpu) | ||
118 | { | 100 | { |
101 | |||
119 | int k; | 102 | int k; |
103 | u32 pstr; | ||
120 | 104 | ||
121 | /* this function is running on another CPU than the offline target, | 105 | /* |
122 | * here we need wait for shutdown code in platform_cpu_die() to | 106 | * wait until the power status register confirms the shutdown of the |
123 | * finish before asking SoC-specific code to power off the CPU core. | 107 | * offline target |
124 | */ | 108 | */ |
125 | for (k = 0; k < 1000; k++) { | 109 | for (k = 0; k < 1000; k++) { |
126 | if (shmobile_cpu_is_dead(cpu)) | 110 | pstr = (__raw_readl(PSTR) >> (4 * cpu)) & 3; |
111 | if (pstr == PSTR_SHUTDOWN_MODE) | ||
127 | return 1; | 112 | return 1; |
128 | 113 | ||
129 | mdelay(1); | 114 | mdelay(1); |
@@ -132,6 +117,23 @@ static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu) | |||
132 | return 0; | 117 | return 0; |
133 | } | 118 | } |
134 | 119 | ||
120 | static void sh73a0_cpu_die(unsigned int cpu) | ||
121 | { | ||
122 | /* | ||
123 | * The ARM MPcore does not issue a cache coherency request for the L1 | ||
124 | * cache when powering off single CPUs. We must take care of this and | ||
125 | * further caches. | ||
126 | */ | ||
127 | dsb(); | ||
128 | flush_cache_all(); | ||
129 | |||
130 | /* Set power off mode. This takes the CPU out of the MP cluster */ | ||
131 | scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF); | ||
132 | |||
133 | /* Enter shutdown mode */ | ||
134 | cpu_do_idle(); | ||
135 | } | ||
136 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
135 | 137 | ||
136 | struct smp_operations sh73a0_smp_ops __initdata = { | 138 | struct smp_operations sh73a0_smp_ops __initdata = { |
137 | .smp_init_cpus = sh73a0_smp_init_cpus, | 139 | .smp_init_cpus = sh73a0_smp_init_cpus, |
@@ -140,7 +142,7 @@ struct smp_operations sh73a0_smp_ops __initdata = { | |||
140 | .smp_boot_secondary = sh73a0_boot_secondary, | 142 | .smp_boot_secondary = sh73a0_boot_secondary, |
141 | #ifdef CONFIG_HOTPLUG_CPU | 143 | #ifdef CONFIG_HOTPLUG_CPU |
142 | .cpu_kill = sh73a0_cpu_kill, | 144 | .cpu_kill = sh73a0_cpu_kill, |
143 | .cpu_die = shmobile_cpu_die, | 145 | .cpu_die = sh73a0_cpu_die, |
144 | .cpu_disable = shmobile_cpu_disable, | 146 | .cpu_disable = shmobile_cpu_disable_any, |
145 | #endif | 147 | #endif |
146 | }; | 148 | }; |
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index fdbe54a11555..3d16d4dff01b 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <asm/arch_timer.h> | ||
23 | #include <asm/mach/time.h> | 24 | #include <asm/mach/time.h> |
24 | #include <asm/smp_twd.h> | 25 | #include <asm/smp_twd.h> |
25 | 26 | ||
@@ -62,4 +63,6 @@ void __init shmobile_earlytimer_init(void) | |||
62 | 63 | ||
63 | void __init shmobile_timer_init(void) | 64 | void __init shmobile_timer_init(void) |
64 | { | 65 | { |
66 | arch_timer_of_register(); | ||
67 | arch_timer_sched_clock_init(); | ||
65 | } | 68 | } |
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h index 9941caa94931..315edff610f2 100644 --- a/arch/arm/mach-socfpga/core.h +++ b/arch/arm/mach-socfpga/core.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #ifndef __MACH_CORE_H | 20 | #ifndef __MACH_CORE_H |
21 | #define __MACH_CORE_H | 21 | #define __MACH_CORE_H |
22 | 22 | ||
23 | extern void secondary_startup(void); | 23 | extern void socfpga_secondary_startup(void); |
24 | extern void __iomem *socfpga_scu_base_addr; | 24 | extern void __iomem *socfpga_scu_base_addr; |
25 | 25 | ||
26 | extern void socfpga_init_clocks(void); | 26 | extern void socfpga_init_clocks(void); |
@@ -29,6 +29,8 @@ extern void socfpga_sysmgr_init(void); | |||
29 | extern struct smp_operations socfpga_smp_ops; | 29 | extern struct smp_operations socfpga_smp_ops; |
30 | extern char secondary_trampoline, secondary_trampoline_end; | 30 | extern char secondary_trampoline, secondary_trampoline_end; |
31 | 31 | ||
32 | extern unsigned long cpu1start_addr; | ||
33 | |||
32 | #define SOCFPGA_SCU_VIRT_BASE 0xfffec000 | 34 | #define SOCFPGA_SCU_VIRT_BASE 0xfffec000 |
33 | 35 | ||
34 | #endif | 36 | #endif |
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S index f09b1283ffca..9004bfb1756e 100644 --- a/arch/arm/mach-socfpga/headsmp.S +++ b/arch/arm/mach-socfpga/headsmp.S | |||
@@ -13,13 +13,21 @@ | |||
13 | __CPUINIT | 13 | __CPUINIT |
14 | .arch armv7-a | 14 | .arch armv7-a |
15 | 15 | ||
16 | #define CPU1_START_ADDR 0xffd08010 | ||
17 | |||
18 | ENTRY(secondary_trampoline) | 16 | ENTRY(secondary_trampoline) |
19 | movw r0, #:lower16:CPU1_START_ADDR | 17 | movw r2, #:lower16:cpu1start_addr |
20 | movt r0, #:upper16:CPU1_START_ADDR | 18 | movt r2, #:upper16:cpu1start_addr |
19 | |||
20 | /* The socfpga VT cannot handle a 0xC0000000 page offset when loading | ||
21 | the cpu1start_addr, we bit clear it. Tested on HW and VT. */ | ||
22 | bic r2, r2, #0x40000000 | ||
21 | 23 | ||
24 | ldr r0, [r2] | ||
22 | ldr r1, [r0] | 25 | ldr r1, [r0] |
23 | bx r1 | 26 | bx r1 |
24 | 27 | ||
25 | ENTRY(secondary_trampoline_end) | 28 | ENTRY(secondary_trampoline_end) |
29 | |||
30 | ENTRY(socfpga_secondary_startup) | ||
31 | bl v7_invalidate_l1 | ||
32 | b secondary_startup | ||
33 | ENDPROC(socfpga_secondary_startup) | ||
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c index 4e9e69d9e7de..84c60fa8daa0 100644 --- a/arch/arm/mach-socfpga/platsmp.c +++ b/arch/arm/mach-socfpga/platsmp.c | |||
@@ -47,16 +47,19 @@ static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct | |||
47 | { | 47 | { |
48 | int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; | 48 | int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; |
49 | 49 | ||
50 | memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | 50 | if (cpu1start_addr) { |
51 | memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | ||
51 | 52 | ||
52 | __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10)); | 53 | __raw_writel(virt_to_phys(socfpga_secondary_startup), |
54 | (sys_manager_base_addr + (cpu1start_addr & 0x000000ff))); | ||
53 | 55 | ||
54 | flush_cache_all(); | 56 | flush_cache_all(); |
55 | smp_wmb(); | 57 | smp_wmb(); |
56 | outer_clean_range(0, trampoline_size); | 58 | outer_clean_range(0, trampoline_size); |
57 | 59 | ||
58 | /* This will release CPU #1 out of reset.*/ | 60 | /* This will release CPU #1 out of reset.*/ |
59 | __raw_writel(0, rst_manager_base_addr + 0x10); | 61 | __raw_writel(0, rst_manager_base_addr + 0x10); |
62 | } | ||
60 | 63 | ||
61 | return 0; | 64 | return 0; |
62 | } | 65 | } |
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index 27d68468a027..1042c023cf24 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c | |||
@@ -29,6 +29,7 @@ | |||
29 | void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); | 29 | void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); |
30 | void __iomem *sys_manager_base_addr; | 30 | void __iomem *sys_manager_base_addr; |
31 | void __iomem *rst_manager_base_addr; | 31 | void __iomem *rst_manager_base_addr; |
32 | unsigned long cpu1start_addr; | ||
32 | 33 | ||
33 | static struct map_desc scu_io_desc __initdata = { | 34 | static struct map_desc scu_io_desc __initdata = { |
34 | .virtual = SOCFPGA_SCU_VIRT_BASE, | 35 | .virtual = SOCFPGA_SCU_VIRT_BASE, |
@@ -67,6 +68,11 @@ void __init socfpga_sysmgr_init(void) | |||
67 | struct device_node *np; | 68 | struct device_node *np; |
68 | 69 | ||
69 | np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr"); | 70 | np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr"); |
71 | |||
72 | if (of_property_read_u32(np, "cpu1-start-addr", | ||
73 | (u32 *) &cpu1start_addr)) | ||
74 | pr_err("SMP: Need cpu1-start-addr in device tree.\n"); | ||
75 | |||
70 | sys_manager_base_addr = of_iomap(np, 0); | 76 | sys_manager_base_addr = of_iomap(np, 0); |
71 | 77 | ||
72 | np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); | 78 | np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); |
@@ -93,7 +99,6 @@ static void __init socfpga_cyclone5_init(void) | |||
93 | 99 | ||
94 | static const char *altera_dt_match[] = { | 100 | static const char *altera_dt_match[] = { |
95 | "altr,socfpga", | 101 | "altr,socfpga", |
96 | "altr,socfpga-cyclone5", | ||
97 | NULL | 102 | NULL |
98 | }; | 103 | }; |
99 | 104 | ||
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 1ec7f80e2af5..d1c4893894ce 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
@@ -4,7 +4,7 @@ comment "NVIDIA Tegra options" | |||
4 | 4 | ||
5 | config ARCH_TEGRA_2x_SOC | 5 | config ARCH_TEGRA_2x_SOC |
6 | bool "Enable support for Tegra20 family" | 6 | bool "Enable support for Tegra20 family" |
7 | select ARCH_REQUIRE_GPIOLIB | 7 | select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP |
8 | select ARM_ERRATA_720789 | 8 | select ARM_ERRATA_720789 |
9 | select ARM_ERRATA_742230 if SMP | 9 | select ARM_ERRATA_742230 if SMP |
10 | select ARM_ERRATA_751472 | 10 | select ARM_ERRATA_751472 |
@@ -26,7 +26,6 @@ config ARCH_TEGRA_2x_SOC | |||
26 | 26 | ||
27 | config ARCH_TEGRA_3x_SOC | 27 | config ARCH_TEGRA_3x_SOC |
28 | bool "Enable support for Tegra30 family" | 28 | bool "Enable support for Tegra30 family" |
29 | select ARCH_REQUIRE_GPIOLIB | ||
30 | select ARM_ERRATA_743622 | 29 | select ARM_ERRATA_743622 |
31 | select ARM_ERRATA_751472 | 30 | select ARM_ERRATA_751472 |
32 | select ARM_ERRATA_754322 | 31 | select ARM_ERRATA_754322 |
@@ -44,6 +43,18 @@ config ARCH_TEGRA_3x_SOC | |||
44 | Support for NVIDIA Tegra T30 processor family, based on the | 43 | Support for NVIDIA Tegra T30 processor family, based on the |
45 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller | 44 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller |
46 | 45 | ||
46 | config ARCH_TEGRA_114_SOC | ||
47 | bool "Enable support for Tegra114 family" | ||
48 | select ARM_ARCH_TIMER | ||
49 | select ARM_GIC | ||
50 | select ARM_L1_CACHE_SHIFT_6 | ||
51 | select CPU_V7 | ||
52 | select PINCTRL | ||
53 | select PINCTRL_TEGRA114 | ||
54 | help | ||
55 | Support for NVIDIA Tegra T114 processor family, based on the | ||
56 | ARM CortexA15MP CPU | ||
57 | |||
47 | config TEGRA_PCI | 58 | config TEGRA_PCI |
48 | bool "PCI Express support" | 59 | bool "PCI Express support" |
49 | depends on ARCH_TEGRA_2x_SOC | 60 | depends on ARCH_TEGRA_2x_SOC |
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index f0520961bafe..f6b46ae2b7f8 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | obj-y += common.o | 1 | obj-y += common.o |
2 | obj-y += io.o | 2 | obj-y += io.o |
3 | obj-y += irq.o | 3 | obj-y += irq.o |
4 | obj-y += clock.o | ||
5 | obj-y += fuse.o | 4 | obj-y += fuse.o |
6 | obj-y += pmc.o | 5 | obj-y += pmc.o |
7 | obj-y += flowctrl.o | 6 | obj-y += flowctrl.o |
@@ -12,16 +11,12 @@ obj-y += reset.o | |||
12 | obj-y += reset-handler.o | 11 | obj-y += reset-handler.o |
13 | obj-y += sleep.o | 12 | obj-y += sleep.o |
14 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | 13 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o |
15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o | ||
16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o | ||
17 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o | 14 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o |
18 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o | 15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o |
19 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o | 16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o |
20 | ifeq ($(CONFIG_CPU_IDLE),y) | 17 | ifeq ($(CONFIG_CPU_IDLE),y) |
21 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o | 18 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o |
22 | endif | 19 | endif |
23 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o | ||
24 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o | ||
25 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o | 20 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o |
26 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o | 21 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o |
27 | ifeq ($(CONFIG_CPU_IDLE),y) | 22 | ifeq ($(CONFIG_CPU_IDLE),y) |
@@ -34,6 +29,10 @@ obj-$(CONFIG_TEGRA_PCI) += pcie.o | |||
34 | 29 | ||
35 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o | 30 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o |
36 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o | 31 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o |
32 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o | ||
33 | ifeq ($(CONFIG_CPU_IDLE),y) | ||
34 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o | ||
35 | endif | ||
37 | 36 | ||
38 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-harmony-pcie.o | 37 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-harmony-pcie.o |
39 | 38 | ||
diff --git a/arch/arm/mach-tegra/board-dt-tegra114.c b/arch/arm/mach-tegra/board-dt-tegra114.c new file mode 100644 index 000000000000..085d63637b62 --- /dev/null +++ b/arch/arm/mach-tegra/board-dt-tegra114.c | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * NVIDIA Tegra114 device tree board support | ||
3 | * | ||
4 | * Copyright (C) 2013 NVIDIA Corporation | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <linux/clocksource.h> | ||
20 | |||
21 | #include <asm/mach/arch.h> | ||
22 | |||
23 | #include "board.h" | ||
24 | #include "common.h" | ||
25 | |||
26 | static void __init tegra114_dt_init(void) | ||
27 | { | ||
28 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | ||
29 | } | ||
30 | |||
31 | static const char * const tegra114_dt_board_compat[] = { | ||
32 | "nvidia,tegra114", | ||
33 | NULL, | ||
34 | }; | ||
35 | |||
36 | DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)") | ||
37 | .smp = smp_ops(tegra_smp_ops), | ||
38 | .map_io = tegra_map_common_io, | ||
39 | .init_early = tegra114_init_early, | ||
40 | .init_irq = tegra_dt_init_irq, | ||
41 | .init_time = clocksource_of_init, | ||
42 | .init_machine = tegra114_dt_init, | ||
43 | .init_late = tegra_init_late, | ||
44 | .restart = tegra_assert_system_reset, | ||
45 | .dt_compat = tegra114_dt_board_compat, | ||
46 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index d320f7ad7350..a0edf2510280 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <asm/setup.h> | 40 | #include <asm/setup.h> |
41 | 41 | ||
42 | #include "board.h" | 42 | #include "board.h" |
43 | #include "clock.h" | ||
44 | #include "common.h" | 43 | #include "common.h" |
45 | #include "iomap.h" | 44 | #include "iomap.h" |
46 | 45 | ||
@@ -69,70 +68,17 @@ static struct tegra_ehci_platform_data tegra_ehci3_pdata = { | |||
69 | }; | 68 | }; |
70 | 69 | ||
71 | static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { | 70 | static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { |
72 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), | 71 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0", |
73 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), | ||
74 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), | ||
75 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL), | ||
76 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL), | ||
77 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL), | ||
78 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL), | ||
79 | OF_DEV_AUXDATA("nvidia,tegra20-i2c-dvc", TEGRA_DVC_BASE, "tegra-i2c.3", NULL), | ||
80 | OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra20-i2s.0", NULL), | ||
81 | OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra20-i2s.1", NULL), | ||
82 | OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra20-das", NULL), | ||
83 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0", | ||
84 | &tegra_ehci1_pdata), | 72 | &tegra_ehci1_pdata), |
85 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1", | 73 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1", |
86 | &tegra_ehci2_pdata), | 74 | &tegra_ehci2_pdata), |
87 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", | 75 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2", |
88 | &tegra_ehci3_pdata), | 76 | &tegra_ehci3_pdata), |
89 | OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL), | ||
90 | OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL), | ||
91 | OF_DEV_AUXDATA("nvidia,tegra20-sflash", 0x7000c380, "spi", NULL), | ||
92 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D400, "spi_tegra.0", NULL), | ||
93 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D600, "spi_tegra.1", NULL), | ||
94 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D800, "spi_tegra.2", NULL), | ||
95 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000DA00, "spi_tegra.3", NULL), | ||
96 | OF_DEV_AUXDATA("nvidia,tegra20-host1x", 0x50000000, "host1x", NULL), | ||
97 | OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54200000, "tegradc.0", NULL), | ||
98 | OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54240000, "tegradc.1", NULL), | ||
99 | OF_DEV_AUXDATA("nvidia,tegra20-hdmi", 0x54280000, "hdmi", NULL), | ||
100 | OF_DEV_AUXDATA("nvidia,tegra20-dsi", 0x54300000, "dsi", NULL), | ||
101 | OF_DEV_AUXDATA("nvidia,tegra20-tvo", 0x542c0000, "tvo", NULL), | ||
102 | {} | 77 | {} |
103 | }; | 78 | }; |
104 | 79 | ||
105 | static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { | ||
106 | /* name parent rate enabled */ | ||
107 | { "uarta", "pll_p", 216000000, true }, | ||
108 | { "uartd", "pll_p", 216000000, true }, | ||
109 | { "usbd", "clk_m", 12000000, false }, | ||
110 | { "usb2", "clk_m", 12000000, false }, | ||
111 | { "usb3", "clk_m", 12000000, false }, | ||
112 | { "pll_a", "pll_p_out1", 56448000, true }, | ||
113 | { "pll_a_out0", "pll_a", 11289600, true }, | ||
114 | { "cdev1", NULL, 0, true }, | ||
115 | { "blink", "clk_32k", 32768, true }, | ||
116 | { "i2s1", "pll_a_out0", 11289600, false}, | ||
117 | { "i2s2", "pll_a_out0", 11289600, false}, | ||
118 | { "sdmmc1", "pll_p", 48000000, false}, | ||
119 | { "sdmmc3", "pll_p", 48000000, false}, | ||
120 | { "sdmmc4", "pll_p", 48000000, false}, | ||
121 | { "spi", "pll_p", 20000000, false }, | ||
122 | { "sbc1", "pll_p", 100000000, false }, | ||
123 | { "sbc2", "pll_p", 100000000, false }, | ||
124 | { "sbc3", "pll_p", 100000000, false }, | ||
125 | { "sbc4", "pll_p", 100000000, false }, | ||
126 | { "host1x", "pll_c", 150000000, false }, | ||
127 | { "disp1", "pll_p", 600000000, false }, | ||
128 | { "disp2", "pll_p", 600000000, false }, | ||
129 | { NULL, NULL, 0, 0}, | ||
130 | }; | ||
131 | |||
132 | static void __init tegra_dt_init(void) | 80 | static void __init tegra_dt_init(void) |
133 | { | 81 | { |
134 | tegra_clk_init_from_table(tegra_dt_clk_init_table); | ||
135 | |||
136 | /* | 82 | /* |
137 | * Finished with the static registrations now; fill in the missing | 83 | * Finished with the static registrations now; fill in the missing |
138 | * devices | 84 | * devices |
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 97e1f67fc31d..bf68567e549d 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c | |||
@@ -34,72 +34,12 @@ | |||
34 | #include <asm/mach/arch.h> | 34 | #include <asm/mach/arch.h> |
35 | 35 | ||
36 | #include "board.h" | 36 | #include "board.h" |
37 | #include "clock.h" | ||
38 | #include "common.h" | 37 | #include "common.h" |
39 | #include "iomap.h" | 38 | #include "iomap.h" |
40 | 39 | ||
41 | static struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { | ||
42 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), | ||
43 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL), | ||
44 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL), | ||
45 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL), | ||
46 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL), | ||
47 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL), | ||
48 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL), | ||
49 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL), | ||
50 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), | ||
51 | OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL), | ||
52 | OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL), | ||
53 | OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL), | ||
54 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D400, "spi_tegra.0", NULL), | ||
55 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D600, "spi_tegra.1", NULL), | ||
56 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D800, "spi_tegra.2", NULL), | ||
57 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DA00, "spi_tegra.3", NULL), | ||
58 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DC00, "spi_tegra.4", NULL), | ||
59 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DE00, "spi_tegra.5", NULL), | ||
60 | OF_DEV_AUXDATA("nvidia,tegra30-host1x", 0x50000000, "host1x", NULL), | ||
61 | OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54200000, "tegradc.0", NULL), | ||
62 | OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54240000, "tegradc.1", NULL), | ||
63 | OF_DEV_AUXDATA("nvidia,tegra30-hdmi", 0x54280000, "hdmi", NULL), | ||
64 | OF_DEV_AUXDATA("nvidia,tegra30-dsi", 0x54300000, "dsi", NULL), | ||
65 | OF_DEV_AUXDATA("nvidia,tegra30-tvo", 0x542c0000, "tvo", NULL), | ||
66 | {} | ||
67 | }; | ||
68 | |||
69 | static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { | ||
70 | /* name parent rate enabled */ | ||
71 | { "uarta", "pll_p", 408000000, true }, | ||
72 | { "pll_a", "pll_p_out1", 564480000, true }, | ||
73 | { "pll_a_out0", "pll_a", 11289600, true }, | ||
74 | { "extern1", "pll_a_out0", 0, true }, | ||
75 | { "clk_out_1", "extern1", 0, true }, | ||
76 | { "blink", "clk_32k", 32768, true }, | ||
77 | { "i2s0", "pll_a_out0", 11289600, false}, | ||
78 | { "i2s1", "pll_a_out0", 11289600, false}, | ||
79 | { "i2s2", "pll_a_out0", 11289600, false}, | ||
80 | { "i2s3", "pll_a_out0", 11289600, false}, | ||
81 | { "i2s4", "pll_a_out0", 11289600, false}, | ||
82 | { "sdmmc1", "pll_p", 48000000, false}, | ||
83 | { "sdmmc3", "pll_p", 48000000, false}, | ||
84 | { "sdmmc4", "pll_p", 48000000, false}, | ||
85 | { "sbc1", "pll_p", 100000000, false}, | ||
86 | { "sbc2", "pll_p", 100000000, false}, | ||
87 | { "sbc3", "pll_p", 100000000, false}, | ||
88 | { "sbc4", "pll_p", 100000000, false}, | ||
89 | { "sbc5", "pll_p", 100000000, false}, | ||
90 | { "sbc6", "pll_p", 100000000, false}, | ||
91 | { "host1x", "pll_c", 150000000, false}, | ||
92 | { "disp1", "pll_p", 600000000, false}, | ||
93 | { "disp2", "pll_p", 600000000, false}, | ||
94 | { NULL, NULL, 0, 0}, | ||
95 | }; | ||
96 | |||
97 | static void __init tegra30_dt_init(void) | 40 | static void __init tegra30_dt_init(void) |
98 | { | 41 | { |
99 | tegra_clk_init_from_table(tegra_dt_clk_init_table); | 42 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
100 | |||
101 | of_platform_populate(NULL, of_default_bus_match_table, | ||
102 | tegra30_auxdata_lookup, NULL); | ||
103 | } | 43 | } |
104 | 44 | ||
105 | static const char *tegra30_dt_board_compat[] = { | 45 | static const char *tegra30_dt_board_compat[] = { |
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index da8f5a3c4240..86851c81a350 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-tegra/board.h | 2 | * arch/arm/mach-tegra/board.h |
3 | * | 3 | * |
4 | * Copyright (c) 2013 NVIDIA Corporation. All rights reserved. | ||
4 | * Copyright (C) 2010 Google, Inc. | 5 | * Copyright (C) 2010 Google, Inc. |
5 | * | 6 | * |
6 | * Author: | 7 | * Author: |
@@ -27,6 +28,7 @@ void tegra_assert_system_reset(char mode, const char *cmd); | |||
27 | 28 | ||
28 | void __init tegra20_init_early(void); | 29 | void __init tegra20_init_early(void); |
29 | void __init tegra30_init_early(void); | 30 | void __init tegra30_init_early(void); |
31 | void __init tegra114_init_early(void); | ||
30 | void __init tegra_map_common_io(void); | 32 | void __init tegra_map_common_io(void); |
31 | void __init tegra_init_irq(void); | 33 | void __init tegra_init_irq(void); |
32 | void __init tegra_dt_init_irq(void); | 34 | void __init tegra_dt_init_irq(void); |
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c deleted file mode 100644 index 867bf8bf5561..000000000000 --- a/arch/arm/mach-tegra/clock.c +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright (C) 2010 Google, Inc. | ||
4 | * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * Author: | ||
7 | * Colin Cross <ccross@google.com> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/clkdev.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/list.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/seq_file.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #include "board.h" | ||
31 | #include "clock.h" | ||
32 | #include "tegra_cpu_car.h" | ||
33 | |||
34 | /* Global data of Tegra CPU CAR ops */ | ||
35 | struct tegra_cpu_car_ops *tegra_cpu_car_ops; | ||
36 | |||
37 | /* | ||
38 | * Locking: | ||
39 | * | ||
40 | * An additional mutex, clock_list_lock, is used to protect the list of all | ||
41 | * clocks. | ||
42 | * | ||
43 | */ | ||
44 | static DEFINE_MUTEX(clock_list_lock); | ||
45 | static LIST_HEAD(clocks); | ||
46 | |||
47 | void tegra_clk_add(struct clk *clk) | ||
48 | { | ||
49 | struct clk_tegra *c = to_clk_tegra(__clk_get_hw(clk)); | ||
50 | |||
51 | mutex_lock(&clock_list_lock); | ||
52 | list_add(&c->node, &clocks); | ||
53 | mutex_unlock(&clock_list_lock); | ||
54 | } | ||
55 | |||
56 | struct clk *tegra_get_clock_by_name(const char *name) | ||
57 | { | ||
58 | struct clk_tegra *c; | ||
59 | struct clk *ret = NULL; | ||
60 | mutex_lock(&clock_list_lock); | ||
61 | list_for_each_entry(c, &clocks, node) { | ||
62 | if (strcmp(__clk_get_name(c->hw.clk), name) == 0) { | ||
63 | ret = c->hw.clk; | ||
64 | break; | ||
65 | } | ||
66 | } | ||
67 | mutex_unlock(&clock_list_lock); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table) | ||
72 | { | ||
73 | struct clk *c; | ||
74 | struct clk *p; | ||
75 | struct clk *parent; | ||
76 | |||
77 | int ret = 0; | ||
78 | |||
79 | c = tegra_get_clock_by_name(table->name); | ||
80 | |||
81 | if (!c) { | ||
82 | pr_warn("Unable to initialize clock %s\n", | ||
83 | table->name); | ||
84 | return -ENODEV; | ||
85 | } | ||
86 | |||
87 | parent = clk_get_parent(c); | ||
88 | |||
89 | if (table->parent) { | ||
90 | p = tegra_get_clock_by_name(table->parent); | ||
91 | if (!p) { | ||
92 | pr_warn("Unable to find parent %s of clock %s\n", | ||
93 | table->parent, table->name); | ||
94 | return -ENODEV; | ||
95 | } | ||
96 | |||
97 | if (parent != p) { | ||
98 | ret = clk_set_parent(c, p); | ||
99 | if (ret) { | ||
100 | pr_warn("Unable to set parent %s of clock %s: %d\n", | ||
101 | table->parent, table->name, ret); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | if (table->rate && table->rate != clk_get_rate(c)) { | ||
108 | ret = clk_set_rate(c, table->rate); | ||
109 | if (ret) { | ||
110 | pr_warn("Unable to set clock %s to rate %lu: %d\n", | ||
111 | table->name, table->rate, ret); | ||
112 | return -EINVAL; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | if (table->enabled) { | ||
117 | ret = clk_prepare_enable(c); | ||
118 | if (ret) { | ||
119 | pr_warn("Unable to enable clock %s: %d\n", | ||
120 | table->name, ret); | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | void tegra_clk_init_from_table(struct tegra_clk_init_table *table) | ||
129 | { | ||
130 | for (; table->name; table++) | ||
131 | tegra_clk_init_one_from_table(table); | ||
132 | } | ||
133 | |||
134 | void tegra_periph_reset_deassert(struct clk *c) | ||
135 | { | ||
136 | struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c)); | ||
137 | BUG_ON(!clk->reset); | ||
138 | clk->reset(__clk_get_hw(c), false); | ||
139 | } | ||
140 | EXPORT_SYMBOL(tegra_periph_reset_deassert); | ||
141 | |||
142 | void tegra_periph_reset_assert(struct clk *c) | ||
143 | { | ||
144 | struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c)); | ||
145 | BUG_ON(!clk->reset); | ||
146 | clk->reset(__clk_get_hw(c), true); | ||
147 | } | ||
148 | EXPORT_SYMBOL(tegra_periph_reset_assert); | ||
149 | |||
150 | /* Several extended clock configuration bits (e.g., clock routing, clock | ||
151 | * phase control) are included in PLL and peripheral clock source | ||
152 | * registers. */ | ||
153 | int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | ||
154 | { | ||
155 | int ret = 0; | ||
156 | struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c)); | ||
157 | |||
158 | if (!clk->clk_cfg_ex) { | ||
159 | ret = -ENOSYS; | ||
160 | goto out; | ||
161 | } | ||
162 | ret = clk->clk_cfg_ex(__clk_get_hw(c), p, setting); | ||
163 | |||
164 | out: | ||
165 | return ret; | ||
166 | } | ||
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h deleted file mode 100644 index 2aa37f5c44c0..000000000000 --- a/arch/arm/mach-tegra/clock.h +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/include/mach/clock.h | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved. | ||
6 | * | ||
7 | * Author: | ||
8 | * Colin Cross <ccross@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #ifndef __MACH_TEGRA_CLOCK_H | ||
22 | #define __MACH_TEGRA_CLOCK_H | ||
23 | |||
24 | #include <linux/clk-provider.h> | ||
25 | #include <linux/clkdev.h> | ||
26 | #include <linux/list.h> | ||
27 | |||
28 | #include <mach/clk.h> | ||
29 | |||
30 | #define DIV_BUS (1 << 0) | ||
31 | #define DIV_U71 (1 << 1) | ||
32 | #define DIV_U71_FIXED (1 << 2) | ||
33 | #define DIV_2 (1 << 3) | ||
34 | #define DIV_U16 (1 << 4) | ||
35 | #define PLL_FIXED (1 << 5) | ||
36 | #define PLL_HAS_CPCON (1 << 6) | ||
37 | #define MUX (1 << 7) | ||
38 | #define PLLD (1 << 8) | ||
39 | #define PERIPH_NO_RESET (1 << 9) | ||
40 | #define PERIPH_NO_ENB (1 << 10) | ||
41 | #define PERIPH_EMC_ENB (1 << 11) | ||
42 | #define PERIPH_MANUAL_RESET (1 << 12) | ||
43 | #define PLL_ALT_MISC_REG (1 << 13) | ||
44 | #define PLLU (1 << 14) | ||
45 | #define PLLX (1 << 15) | ||
46 | #define MUX_PWM (1 << 16) | ||
47 | #define MUX8 (1 << 17) | ||
48 | #define DIV_U71_UART (1 << 18) | ||
49 | #define MUX_CLK_OUT (1 << 19) | ||
50 | #define PLLM (1 << 20) | ||
51 | #define DIV_U71_INT (1 << 21) | ||
52 | #define DIV_U71_IDLE (1 << 22) | ||
53 | #define ENABLE_ON_INIT (1 << 28) | ||
54 | #define PERIPH_ON_APB (1 << 29) | ||
55 | |||
56 | struct clk_tegra; | ||
57 | #define to_clk_tegra(_hw) container_of(_hw, struct clk_tegra, hw) | ||
58 | |||
59 | struct clk_mux_sel { | ||
60 | struct clk *input; | ||
61 | u32 value; | ||
62 | }; | ||
63 | |||
64 | struct clk_pll_freq_table { | ||
65 | unsigned long input_rate; | ||
66 | unsigned long output_rate; | ||
67 | u16 n; | ||
68 | u16 m; | ||
69 | u8 p; | ||
70 | u8 cpcon; | ||
71 | }; | ||
72 | |||
73 | enum clk_state { | ||
74 | UNINITIALIZED = 0, | ||
75 | ON, | ||
76 | OFF, | ||
77 | }; | ||
78 | |||
79 | struct clk_tegra { | ||
80 | /* node for master clocks list */ | ||
81 | struct list_head node; /* node for list of all clocks */ | ||
82 | struct clk_lookup lookup; | ||
83 | struct clk_hw hw; | ||
84 | |||
85 | bool set; | ||
86 | unsigned long fixed_rate; | ||
87 | unsigned long max_rate; | ||
88 | unsigned long min_rate; | ||
89 | u32 flags; | ||
90 | const char *name; | ||
91 | |||
92 | enum clk_state state; | ||
93 | u32 div; | ||
94 | u32 mul; | ||
95 | |||
96 | u32 reg; | ||
97 | u32 reg_shift; | ||
98 | |||
99 | struct list_head shared_bus_list; | ||
100 | |||
101 | union { | ||
102 | struct { | ||
103 | unsigned int clk_num; | ||
104 | } periph; | ||
105 | struct { | ||
106 | unsigned long input_min; | ||
107 | unsigned long input_max; | ||
108 | unsigned long cf_min; | ||
109 | unsigned long cf_max; | ||
110 | unsigned long vco_min; | ||
111 | unsigned long vco_max; | ||
112 | const struct clk_pll_freq_table *freq_table; | ||
113 | int lock_delay; | ||
114 | unsigned long fixed_rate; | ||
115 | } pll; | ||
116 | struct { | ||
117 | u32 sel; | ||
118 | u32 reg_mask; | ||
119 | } mux; | ||
120 | struct { | ||
121 | struct clk *main; | ||
122 | struct clk *backup; | ||
123 | } cpu; | ||
124 | struct { | ||
125 | struct list_head node; | ||
126 | bool enabled; | ||
127 | unsigned long rate; | ||
128 | } shared_bus_user; | ||
129 | } u; | ||
130 | |||
131 | void (*reset)(struct clk_hw *, bool); | ||
132 | int (*clk_cfg_ex)(struct clk_hw *, enum tegra_clk_ex_param, u32); | ||
133 | }; | ||
134 | |||
135 | struct clk_duplicate { | ||
136 | const char *name; | ||
137 | struct clk_lookup lookup; | ||
138 | }; | ||
139 | |||
140 | struct tegra_clk_init_table { | ||
141 | const char *name; | ||
142 | const char *parent; | ||
143 | unsigned long rate; | ||
144 | bool enabled; | ||
145 | }; | ||
146 | |||
147 | void tegra_clk_add(struct clk *c); | ||
148 | void tegra2_init_clocks(void); | ||
149 | void tegra30_init_clocks(void); | ||
150 | struct clk *tegra_get_clock_by_name(const char *name); | ||
151 | void tegra_clk_init_from_table(struct tegra_clk_init_table *table); | ||
152 | |||
153 | #endif | ||
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 8f0ffe97ffee..5449a3f2977b 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-tegra/common.c | 2 | * arch/arm/mach-tegra/common.c |
3 | * | 3 | * |
4 | * Copyright (c) 2013 NVIDIA Corporation. All rights reserved. | ||
4 | * Copyright (C) 2010 Google, Inc. | 5 | * Copyright (C) 2010 Google, Inc. |
5 | * | 6 | * |
6 | * Author: | 7 | * Author: |
@@ -22,13 +23,13 @@ | |||
22 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
24 | #include <linux/irqchip.h> | 25 | #include <linux/irqchip.h> |
26 | #include <linux/clk/tegra.h> | ||
25 | 27 | ||
26 | #include <asm/hardware/cache-l2x0.h> | 28 | #include <asm/hardware/cache-l2x0.h> |
27 | 29 | ||
28 | #include <mach/powergate.h> | 30 | #include <mach/powergate.h> |
29 | 31 | ||
30 | #include "board.h" | 32 | #include "board.h" |
31 | #include "clock.h" | ||
32 | #include "common.h" | 33 | #include "common.h" |
33 | #include "fuse.h" | 34 | #include "fuse.h" |
34 | #include "iomap.h" | 35 | #include "iomap.h" |
@@ -59,6 +60,7 @@ u32 tegra_uart_config[4] = { | |||
59 | #ifdef CONFIG_OF | 60 | #ifdef CONFIG_OF |
60 | void __init tegra_dt_init_irq(void) | 61 | void __init tegra_dt_init_irq(void) |
61 | { | 62 | { |
63 | tegra_clocks_init(); | ||
62 | tegra_init_irq(); | 64 | tegra_init_irq(); |
63 | irqchip_init(); | 65 | irqchip_init(); |
64 | } | 66 | } |
@@ -74,43 +76,6 @@ void tegra_assert_system_reset(char mode, const char *cmd) | |||
74 | writel_relaxed(reg, reset); | 76 | writel_relaxed(reg, reset); |
75 | } | 77 | } |
76 | 78 | ||
77 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
78 | static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = { | ||
79 | /* name parent rate enabled */ | ||
80 | { "clk_m", NULL, 0, true }, | ||
81 | { "pll_p", "clk_m", 216000000, true }, | ||
82 | { "pll_p_out1", "pll_p", 28800000, true }, | ||
83 | { "pll_p_out2", "pll_p", 48000000, true }, | ||
84 | { "pll_p_out3", "pll_p", 72000000, true }, | ||
85 | { "pll_p_out4", "pll_p", 24000000, true }, | ||
86 | { "pll_c", "clk_m", 600000000, true }, | ||
87 | { "pll_c_out1", "pll_c", 120000000, true }, | ||
88 | { "sclk", "pll_c_out1", 120000000, true }, | ||
89 | { "hclk", "sclk", 120000000, true }, | ||
90 | { "pclk", "hclk", 60000000, true }, | ||
91 | { "csite", NULL, 0, true }, | ||
92 | { "emc", NULL, 0, true }, | ||
93 | { "cpu", NULL, 0, true }, | ||
94 | { NULL, NULL, 0, 0}, | ||
95 | }; | ||
96 | #endif | ||
97 | |||
98 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
99 | static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = { | ||
100 | /* name parent rate enabled */ | ||
101 | { "clk_m", NULL, 0, true }, | ||
102 | { "pll_p", "pll_ref", 408000000, true }, | ||
103 | { "pll_p_out1", "pll_p", 9600000, true }, | ||
104 | { "pll_p_out4", "pll_p", 102000000, true }, | ||
105 | { "sclk", "pll_p_out4", 102000000, true }, | ||
106 | { "hclk", "sclk", 102000000, true }, | ||
107 | { "pclk", "hclk", 51000000, true }, | ||
108 | { "csite", NULL, 0, true }, | ||
109 | { NULL, NULL, 0, 0}, | ||
110 | }; | ||
111 | #endif | ||
112 | |||
113 | |||
114 | static void __init tegra_init_cache(void) | 79 | static void __init tegra_init_cache(void) |
115 | { | 80 | { |
116 | #ifdef CONFIG_CACHE_L2X0 | 81 | #ifdef CONFIG_CACHE_L2X0 |
@@ -129,35 +94,39 @@ static void __init tegra_init_cache(void) | |||
129 | 94 | ||
130 | } | 95 | } |
131 | 96 | ||
132 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 97 | static void __init tegra_init_early(void) |
133 | void __init tegra20_init_early(void) | ||
134 | { | 98 | { |
135 | tegra_cpu_reset_handler_init(); | 99 | tegra_cpu_reset_handler_init(); |
136 | tegra_apb_io_init(); | 100 | tegra_apb_io_init(); |
137 | tegra_init_fuse(); | 101 | tegra_init_fuse(); |
138 | tegra2_init_clocks(); | ||
139 | tegra_clk_init_from_table(tegra20_clk_init_table); | ||
140 | tegra_init_cache(); | 102 | tegra_init_cache(); |
141 | tegra_pmc_init(); | 103 | tegra_pmc_init(); |
142 | tegra_powergate_init(); | 104 | tegra_powergate_init(); |
105 | } | ||
106 | |||
107 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
108 | void __init tegra20_init_early(void) | ||
109 | { | ||
110 | tegra_init_early(); | ||
143 | tegra20_hotplug_init(); | 111 | tegra20_hotplug_init(); |
144 | } | 112 | } |
145 | #endif | 113 | #endif |
114 | |||
146 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | 115 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC |
147 | void __init tegra30_init_early(void) | 116 | void __init tegra30_init_early(void) |
148 | { | 117 | { |
149 | tegra_cpu_reset_handler_init(); | 118 | tegra_init_early(); |
150 | tegra_apb_io_init(); | ||
151 | tegra_init_fuse(); | ||
152 | tegra30_init_clocks(); | ||
153 | tegra_clk_init_from_table(tegra30_clk_init_table); | ||
154 | tegra_init_cache(); | ||
155 | tegra_pmc_init(); | ||
156 | tegra_powergate_init(); | ||
157 | tegra30_hotplug_init(); | 119 | tegra30_hotplug_init(); |
158 | } | 120 | } |
159 | #endif | 121 | #endif |
160 | 122 | ||
123 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | ||
124 | void __init tegra114_init_early(void) | ||
125 | { | ||
126 | tegra_init_early(); | ||
127 | } | ||
128 | #endif | ||
129 | |||
161 | void __init tegra_init_late(void) | 130 | void __init tegra_init_late(void) |
162 | { | 131 | { |
163 | tegra_powergate_debugfs_init(); | 132 | tegra_powergate_debugfs_init(); |
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index ece29ab15b59..e3d6e15ff188 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c | |||
@@ -265,7 +265,7 @@ static int __init tegra_cpufreq_init(void) | |||
265 | if (IS_ERR(pll_x_clk)) | 265 | if (IS_ERR(pll_x_clk)) |
266 | return PTR_ERR(pll_x_clk); | 266 | return PTR_ERR(pll_x_clk); |
267 | 267 | ||
268 | pll_p_clk = clk_get_sys(NULL, "pll_p"); | 268 | pll_p_clk = clk_get_sys(NULL, "pll_p_cclk"); |
269 | if (IS_ERR(pll_p_clk)) | 269 | if (IS_ERR(pll_p_clk)) |
270 | return PTR_ERR(pll_p_clk); | 270 | return PTR_ERR(pll_p_clk); |
271 | 271 | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c new file mode 100644 index 000000000000..0f4e8c483b34 --- /dev/null +++ b/arch/arm/mach-tegra/cpuidle-tegra114.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/cpuidle.h> | ||
20 | |||
21 | #include <asm/cpuidle.h> | ||
22 | |||
23 | static struct cpuidle_driver tegra_idle_driver = { | ||
24 | .name = "tegra_idle", | ||
25 | .owner = THIS_MODULE, | ||
26 | .en_core_tk_irqen = 1, | ||
27 | .state_count = 1, | ||
28 | .states = { | ||
29 | [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), | ||
30 | }, | ||
31 | }; | ||
32 | |||
33 | static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); | ||
34 | |||
35 | int __init tegra114_cpuidle_init(void) | ||
36 | { | ||
37 | int ret; | ||
38 | unsigned int cpu; | ||
39 | struct cpuidle_device *dev; | ||
40 | struct cpuidle_driver *drv = &tegra_idle_driver; | ||
41 | |||
42 | ret = cpuidle_register_driver(&tegra_idle_driver); | ||
43 | if (ret) { | ||
44 | pr_err("CPUidle driver registration failed\n"); | ||
45 | return ret; | ||
46 | } | ||
47 | |||
48 | for_each_possible_cpu(cpu) { | ||
49 | dev = &per_cpu(tegra_idle_device, cpu); | ||
50 | dev->cpu = cpu; | ||
51 | |||
52 | dev->state_count = drv->state_count; | ||
53 | ret = cpuidle_register_device(dev); | ||
54 | if (ret) { | ||
55 | pr_err("CPU%u: CPUidle device registration failed\n", | ||
56 | cpu); | ||
57 | return ret; | ||
58 | } | ||
59 | } | ||
60 | return 0; | ||
61 | } | ||
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c index d32e8b0dbd4f..825ced4f7a40 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra20.c +++ b/arch/arm/mach-tegra/cpuidle-tegra20.c | |||
@@ -22,21 +22,199 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/cpuidle.h> | 24 | #include <linux/cpuidle.h> |
25 | #include <linux/cpu_pm.h> | ||
26 | #include <linux/clockchips.h> | ||
27 | #include <linux/clk/tegra.h> | ||
25 | 28 | ||
26 | #include <asm/cpuidle.h> | 29 | #include <asm/cpuidle.h> |
30 | #include <asm/proc-fns.h> | ||
31 | #include <asm/suspend.h> | ||
32 | #include <asm/smp_plat.h> | ||
33 | |||
34 | #include "pm.h" | ||
35 | #include "sleep.h" | ||
36 | #include "iomap.h" | ||
37 | #include "irq.h" | ||
38 | #include "flowctrl.h" | ||
39 | |||
40 | #ifdef CONFIG_PM_SLEEP | ||
41 | static bool abort_flag; | ||
42 | static atomic_t abort_barrier; | ||
43 | static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, | ||
44 | struct cpuidle_driver *drv, | ||
45 | int index); | ||
46 | #endif | ||
47 | |||
48 | static struct cpuidle_state tegra_idle_states[] = { | ||
49 | [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), | ||
50 | #ifdef CONFIG_PM_SLEEP | ||
51 | [1] = { | ||
52 | .enter = tegra20_idle_lp2_coupled, | ||
53 | .exit_latency = 5000, | ||
54 | .target_residency = 10000, | ||
55 | .power_usage = 0, | ||
56 | .flags = CPUIDLE_FLAG_TIME_VALID | | ||
57 | CPUIDLE_FLAG_COUPLED, | ||
58 | .name = "powered-down", | ||
59 | .desc = "CPU power gated", | ||
60 | }, | ||
61 | #endif | ||
62 | }; | ||
27 | 63 | ||
28 | static struct cpuidle_driver tegra_idle_driver = { | 64 | static struct cpuidle_driver tegra_idle_driver = { |
29 | .name = "tegra_idle", | 65 | .name = "tegra_idle", |
30 | .owner = THIS_MODULE, | 66 | .owner = THIS_MODULE, |
31 | .en_core_tk_irqen = 1, | 67 | .en_core_tk_irqen = 1, |
32 | .state_count = 1, | ||
33 | .states = { | ||
34 | [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), | ||
35 | }, | ||
36 | }; | 68 | }; |
37 | 69 | ||
38 | static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); | 70 | static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); |
39 | 71 | ||
72 | #ifdef CONFIG_PM_SLEEP | ||
73 | #ifdef CONFIG_SMP | ||
74 | static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); | ||
75 | |||
76 | static int tegra20_reset_sleeping_cpu_1(void) | ||
77 | { | ||
78 | int ret = 0; | ||
79 | |||
80 | tegra_pen_lock(); | ||
81 | |||
82 | if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE) | ||
83 | tegra20_cpu_shutdown(1); | ||
84 | else | ||
85 | ret = -EINVAL; | ||
86 | |||
87 | tegra_pen_unlock(); | ||
88 | |||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static void tegra20_wake_cpu1_from_reset(void) | ||
93 | { | ||
94 | tegra_pen_lock(); | ||
95 | |||
96 | tegra20_cpu_clear_resettable(); | ||
97 | |||
98 | /* enable cpu clock on cpu */ | ||
99 | tegra_enable_cpu_clock(1); | ||
100 | |||
101 | /* take the CPU out of reset */ | ||
102 | tegra_cpu_out_of_reset(1); | ||
103 | |||
104 | /* unhalt the cpu */ | ||
105 | flowctrl_write_cpu_halt(1, 0); | ||
106 | |||
107 | tegra_pen_unlock(); | ||
108 | } | ||
109 | |||
110 | static int tegra20_reset_cpu_1(void) | ||
111 | { | ||
112 | if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1()) | ||
113 | return 0; | ||
114 | |||
115 | tegra20_wake_cpu1_from_reset(); | ||
116 | return -EBUSY; | ||
117 | } | ||
118 | #else | ||
119 | static inline void tegra20_wake_cpu1_from_reset(void) | ||
120 | { | ||
121 | } | ||
122 | |||
123 | static inline int tegra20_reset_cpu_1(void) | ||
124 | { | ||
125 | return 0; | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev, | ||
130 | struct cpuidle_driver *drv, | ||
131 | int index) | ||
132 | { | ||
133 | struct cpuidle_state *state = &drv->states[index]; | ||
134 | u32 cpu_on_time = state->exit_latency; | ||
135 | u32 cpu_off_time = state->target_residency - state->exit_latency; | ||
136 | |||
137 | while (tegra20_cpu_is_resettable_soon()) | ||
138 | cpu_relax(); | ||
139 | |||
140 | if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready()) | ||
141 | return false; | ||
142 | |||
143 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); | ||
144 | |||
145 | tegra_idle_lp2_last(cpu_on_time, cpu_off_time); | ||
146 | |||
147 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); | ||
148 | |||
149 | if (cpu_online(1)) | ||
150 | tegra20_wake_cpu1_from_reset(); | ||
151 | |||
152 | return true; | ||
153 | } | ||
154 | |||
155 | #ifdef CONFIG_SMP | ||
156 | static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, | ||
157 | struct cpuidle_driver *drv, | ||
158 | int index) | ||
159 | { | ||
160 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); | ||
161 | |||
162 | cpu_suspend(0, tegra20_sleep_cpu_secondary_finish); | ||
163 | |||
164 | tegra20_cpu_clear_resettable(); | ||
165 | |||
166 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); | ||
167 | |||
168 | return true; | ||
169 | } | ||
170 | #else | ||
171 | static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, | ||
172 | struct cpuidle_driver *drv, | ||
173 | int index) | ||
174 | { | ||
175 | return true; | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, | ||
180 | struct cpuidle_driver *drv, | ||
181 | int index) | ||
182 | { | ||
183 | u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; | ||
184 | bool entered_lp2 = false; | ||
185 | |||
186 | if (tegra_pending_sgi()) | ||
187 | ACCESS_ONCE(abort_flag) = true; | ||
188 | |||
189 | cpuidle_coupled_parallel_barrier(dev, &abort_barrier); | ||
190 | |||
191 | if (abort_flag) { | ||
192 | cpuidle_coupled_parallel_barrier(dev, &abort_barrier); | ||
193 | abort_flag = false; /* clean flag for next coming */ | ||
194 | return -EINTR; | ||
195 | } | ||
196 | |||
197 | local_fiq_disable(); | ||
198 | |||
199 | tegra_set_cpu_in_lp2(cpu); | ||
200 | cpu_pm_enter(); | ||
201 | |||
202 | if (cpu == 0) | ||
203 | entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index); | ||
204 | else | ||
205 | entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index); | ||
206 | |||
207 | cpu_pm_exit(); | ||
208 | tegra_clear_cpu_in_lp2(cpu); | ||
209 | |||
210 | local_fiq_enable(); | ||
211 | |||
212 | smp_rmb(); | ||
213 | |||
214 | return entered_lp2 ? index : 0; | ||
215 | } | ||
216 | #endif | ||
217 | |||
40 | int __init tegra20_cpuidle_init(void) | 218 | int __init tegra20_cpuidle_init(void) |
41 | { | 219 | { |
42 | int ret; | 220 | int ret; |
@@ -44,6 +222,14 @@ int __init tegra20_cpuidle_init(void) | |||
44 | struct cpuidle_device *dev; | 222 | struct cpuidle_device *dev; |
45 | struct cpuidle_driver *drv = &tegra_idle_driver; | 223 | struct cpuidle_driver *drv = &tegra_idle_driver; |
46 | 224 | ||
225 | #ifdef CONFIG_PM_SLEEP | ||
226 | tegra_tear_down_cpu = tegra20_tear_down_cpu; | ||
227 | #endif | ||
228 | |||
229 | drv->state_count = ARRAY_SIZE(tegra_idle_states); | ||
230 | memcpy(drv->states, tegra_idle_states, | ||
231 | drv->state_count * sizeof(drv->states[0])); | ||
232 | |||
47 | ret = cpuidle_register_driver(&tegra_idle_driver); | 233 | ret = cpuidle_register_driver(&tegra_idle_driver); |
48 | if (ret) { | 234 | if (ret) { |
49 | pr_err("CPUidle driver registration failed\n"); | 235 | pr_err("CPUidle driver registration failed\n"); |
@@ -53,6 +239,9 @@ int __init tegra20_cpuidle_init(void) | |||
53 | for_each_possible_cpu(cpu) { | 239 | for_each_possible_cpu(cpu) { |
54 | dev = &per_cpu(tegra_idle_device, cpu); | 240 | dev = &per_cpu(tegra_idle_device, cpu); |
55 | dev->cpu = cpu; | 241 | dev->cpu = cpu; |
242 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED | ||
243 | dev->coupled_cpus = *cpu_possible_mask; | ||
244 | #endif | ||
56 | 245 | ||
57 | dev->state_count = drv->state_count; | 246 | dev->state_count = drv->state_count; |
58 | ret = cpuidle_register_device(dev); | 247 | ret = cpuidle_register_device(dev); |
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c index 82530bd9b8c2..8b50cf4ddd6f 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra30.c +++ b/arch/arm/mach-tegra/cpuidle-tegra30.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cpuidle.h> | 24 | #include <linux/cpuidle.h> |
25 | #include <linux/cpu_pm.h> | 25 | #include <linux/cpu_pm.h> |
26 | #include <linux/clockchips.h> | 26 | #include <linux/clockchips.h> |
27 | #include <linux/clk/tegra.h> | ||
27 | 28 | ||
28 | #include <asm/cpuidle.h> | 29 | #include <asm/cpuidle.h> |
29 | #include <asm/proc-fns.h> | 30 | #include <asm/proc-fns.h> |
@@ -32,7 +33,6 @@ | |||
32 | 33 | ||
33 | #include "pm.h" | 34 | #include "pm.h" |
34 | #include "sleep.h" | 35 | #include "sleep.h" |
35 | #include "tegra_cpu_car.h" | ||
36 | 36 | ||
37 | #ifdef CONFIG_PM_SLEEP | 37 | #ifdef CONFIG_PM_SLEEP |
38 | static int tegra30_idle_lp2(struct cpuidle_device *dev, | 38 | static int tegra30_idle_lp2(struct cpuidle_device *dev, |
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index d0651397aec7..4b744c4661e2 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c | |||
@@ -38,6 +38,9 @@ static int __init tegra_cpuidle_init(void) | |||
38 | case TEGRA30: | 38 | case TEGRA30: |
39 | ret = tegra30_cpuidle_init(); | 39 | ret = tegra30_cpuidle_init(); |
40 | break; | 40 | break; |
41 | case TEGRA114: | ||
42 | ret = tegra114_cpuidle_init(); | ||
43 | break; | ||
41 | default: | 44 | default: |
42 | ret = -ENODEV; | 45 | ret = -ENODEV; |
43 | break; | 46 | break; |
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h index 496204d34e55..d733f75d0208 100644 --- a/arch/arm/mach-tegra/cpuidle.h +++ b/arch/arm/mach-tegra/cpuidle.h | |||
@@ -29,4 +29,10 @@ int tegra30_cpuidle_init(void); | |||
29 | static inline int tegra30_cpuidle_init(void) { return -ENODEV; } | 29 | static inline int tegra30_cpuidle_init(void) { return -ENODEV; } |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | ||
33 | int tegra114_cpuidle_init(void); | ||
34 | #else | ||
35 | static inline int tegra114_cpuidle_init(void) { return -ENODEV; } | ||
36 | #endif | ||
37 | |||
32 | #endif | 38 | #endif |
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c index 5393eb2cae21..b477ef310dcd 100644 --- a/arch/arm/mach-tegra/flowctrl.c +++ b/arch/arm/mach-tegra/flowctrl.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "flowctrl.h" | 26 | #include "flowctrl.h" |
27 | #include "iomap.h" | 27 | #include "iomap.h" |
28 | #include "fuse.h" | ||
28 | 29 | ||
29 | static u8 flowctrl_offset_halt_cpu[] = { | 30 | static u8 flowctrl_offset_halt_cpu[] = { |
30 | FLOW_CTRL_HALT_CPU0_EVENTS, | 31 | FLOW_CTRL_HALT_CPU0_EVENTS, |
@@ -75,11 +76,26 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid) | |||
75 | int i; | 76 | int i; |
76 | 77 | ||
77 | reg = flowctrl_read_cpu_csr(cpuid); | 78 | reg = flowctrl_read_cpu_csr(cpuid); |
78 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ | 79 | switch (tegra_chip_id) { |
79 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ | 80 | case TEGRA20: |
81 | /* clear wfe bitmap */ | ||
82 | reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP; | ||
83 | /* clear wfi bitmap */ | ||
84 | reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP; | ||
85 | /* pwr gating on wfe */ | ||
86 | reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid; | ||
87 | break; | ||
88 | case TEGRA30: | ||
89 | /* clear wfe bitmap */ | ||
90 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; | ||
91 | /* clear wfi bitmap */ | ||
92 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; | ||
93 | /* pwr gating on wfi */ | ||
94 | reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid; | ||
95 | break; | ||
96 | } | ||
80 | reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */ | 97 | reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */ |
81 | reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event flag */ | 98 | reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event flag */ |
82 | reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid; /* pwr gating on wfi */ | ||
83 | reg |= FLOW_CTRL_CSR_ENABLE; /* pwr gating */ | 99 | reg |= FLOW_CTRL_CSR_ENABLE; /* pwr gating */ |
84 | flowctrl_write_cpu_csr(cpuid, reg); | 100 | flowctrl_write_cpu_csr(cpuid, reg); |
85 | 101 | ||
@@ -99,8 +115,20 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid) | |||
99 | 115 | ||
100 | /* Disable powergating via flow controller for CPU0 */ | 116 | /* Disable powergating via flow controller for CPU0 */ |
101 | reg = flowctrl_read_cpu_csr(cpuid); | 117 | reg = flowctrl_read_cpu_csr(cpuid); |
102 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ | 118 | switch (tegra_chip_id) { |
103 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ | 119 | case TEGRA20: |
120 | /* clear wfe bitmap */ | ||
121 | reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP; | ||
122 | /* clear wfi bitmap */ | ||
123 | reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP; | ||
124 | break; | ||
125 | case TEGRA30: | ||
126 | /* clear wfe bitmap */ | ||
127 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; | ||
128 | /* clear wfi bitmap */ | ||
129 | reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; | ||
130 | break; | ||
131 | } | ||
104 | reg &= ~FLOW_CTRL_CSR_ENABLE; /* clear enable */ | 132 | reg &= ~FLOW_CTRL_CSR_ENABLE; /* clear enable */ |
105 | reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr */ | 133 | reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr */ |
106 | reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event */ | 134 | reg |= FLOW_CTRL_CSR_EVENT_FLAG; /* clear event */ |
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h index 0798dec1832d..67eab56699bd 100644 --- a/arch/arm/mach-tegra/flowctrl.h +++ b/arch/arm/mach-tegra/flowctrl.h | |||
@@ -34,6 +34,10 @@ | |||
34 | #define FLOW_CTRL_HALT_CPU1_EVENTS 0x14 | 34 | #define FLOW_CTRL_HALT_CPU1_EVENTS 0x14 |
35 | #define FLOW_CTRL_CPU1_CSR 0x18 | 35 | #define FLOW_CTRL_CPU1_CSR 0x18 |
36 | 36 | ||
37 | #define TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 (1 << 4) | ||
38 | #define TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP (3 << 4) | ||
39 | #define TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP 0 | ||
40 | |||
37 | #define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 (1 << 8) | 41 | #define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 (1 << 8) |
38 | #define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4) | 42 | #define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4) |
39 | #define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8) | 43 | #define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8) |
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c index 8121742711fe..f7db0782a6b6 100644 --- a/arch/arm/mach-tegra/fuse.c +++ b/arch/arm/mach-tegra/fuse.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/export.h> | 22 | #include <linux/export.h> |
23 | #include <linux/tegra-soc.h> | ||
23 | 24 | ||
24 | #include "fuse.h" | 25 | #include "fuse.h" |
25 | #include "iomap.h" | 26 | #include "iomap.h" |
@@ -105,6 +106,11 @@ static void tegra_get_process_id(void) | |||
105 | tegra_core_process_id = (reg >> 12) & 3; | 106 | tegra_core_process_id = (reg >> 12) & 3; |
106 | } | 107 | } |
107 | 108 | ||
109 | u32 tegra_read_chipid(void) | ||
110 | { | ||
111 | return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804); | ||
112 | } | ||
113 | |||
108 | void tegra_init_fuse(void) | 114 | void tegra_init_fuse(void) |
109 | { | 115 | { |
110 | u32 id; | 116 | u32 id; |
@@ -119,7 +125,7 @@ void tegra_init_fuse(void) | |||
119 | reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT); | 125 | reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT); |
120 | tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT; | 126 | tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT; |
121 | 127 | ||
122 | id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804); | 128 | id = tegra_read_chipid(); |
123 | tegra_chip_id = (id >> 8) & 0xff; | 129 | tegra_chip_id = (id >> 8) & 0xff; |
124 | 130 | ||
125 | switch (tegra_chip_id) { | 131 | switch (tegra_chip_id) { |
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h index ff1383dd61a7..da78434678c7 100644 --- a/arch/arm/mach-tegra/fuse.h +++ b/arch/arm/mach-tegra/fuse.h | |||
@@ -37,6 +37,7 @@ enum tegra_revision { | |||
37 | 37 | ||
38 | #define TEGRA20 0x20 | 38 | #define TEGRA20 0x20 |
39 | #define TEGRA30 0x30 | 39 | #define TEGRA30 0x30 |
40 | #define TEGRA114 0x35 | ||
40 | 41 | ||
41 | extern int tegra_sku_id; | 42 | extern int tegra_sku_id; |
42 | extern int tegra_cpu_process_id; | 43 | extern int tegra_cpu_process_id; |
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S index b2834810b02b..fd473f2b4c3d 100644 --- a/arch/arm/mach-tegra/headsmp.S +++ b/arch/arm/mach-tegra/headsmp.S | |||
@@ -5,49 +5,6 @@ | |||
5 | 5 | ||
6 | .section ".text.head", "ax" | 6 | .section ".text.head", "ax" |
7 | 7 | ||
8 | /* | ||
9 | * Tegra specific entry point for secondary CPUs. | ||
10 | * The secondary kernel init calls v7_flush_dcache_all before it enables | ||
11 | * the L1; however, the L1 comes out of reset in an undefined state, so | ||
12 | * the clean + invalidate performed by v7_flush_dcache_all causes a bunch | ||
13 | * of cache lines with uninitialized data and uninitialized tags to get | ||
14 | * written out to memory, which does really unpleasant things to the main | ||
15 | * processor. We fix this by performing an invalidate, rather than a | ||
16 | * clean + invalidate, before jumping into the kernel. | ||
17 | */ | ||
18 | ENTRY(v7_invalidate_l1) | ||
19 | mov r0, #0 | ||
20 | mcr p15, 2, r0, c0, c0, 0 | ||
21 | mrc p15, 1, r0, c0, c0, 0 | ||
22 | |||
23 | ldr r1, =0x7fff | ||
24 | and r2, r1, r0, lsr #13 | ||
25 | |||
26 | ldr r1, =0x3ff | ||
27 | |||
28 | and r3, r1, r0, lsr #3 @ NumWays - 1 | ||
29 | add r2, r2, #1 @ NumSets | ||
30 | |||
31 | and r0, r0, #0x7 | ||
32 | add r0, r0, #4 @ SetShift | ||
33 | |||
34 | clz r1, r3 @ WayShift | ||
35 | add r4, r3, #1 @ NumWays | ||
36 | 1: sub r2, r2, #1 @ NumSets-- | ||
37 | mov r3, r4 @ Temp = NumWays | ||
38 | 2: subs r3, r3, #1 @ Temp-- | ||
39 | mov r5, r3, lsl r1 | ||
40 | mov r6, r2, lsl r0 | ||
41 | orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) | ||
42 | mcr p15, 0, r5, c7, c6, 2 | ||
43 | bgt 2b | ||
44 | cmp r2, #0 | ||
45 | bgt 1b | ||
46 | dsb | ||
47 | isb | ||
48 | mov pc, lr | ||
49 | ENDPROC(v7_invalidate_l1) | ||
50 | |||
51 | ENTRY(tegra_secondary_startup) | 8 | ENTRY(tegra_secondary_startup) |
52 | bl v7_invalidate_l1 | 9 | bl v7_invalidate_l1 |
53 | /* Enable coresight */ | 10 | /* Enable coresight */ |
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index 6a27de4001ee..a599f6e36dea 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c | |||
@@ -10,12 +10,12 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <linux/clk/tegra.h> | ||
13 | 14 | ||
14 | #include <asm/cacheflush.h> | 15 | #include <asm/cacheflush.h> |
15 | #include <asm/smp_plat.h> | 16 | #include <asm/smp_plat.h> |
16 | 17 | ||
17 | #include "sleep.h" | 18 | #include "sleep.h" |
18 | #include "tegra_cpu_car.h" | ||
19 | 19 | ||
20 | static void (*tegra_hotplug_shutdown)(void); | 20 | static void (*tegra_hotplug_shutdown)(void); |
21 | 21 | ||
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h deleted file mode 100644 index 95f3a547c770..000000000000 --- a/arch/arm/mach-tegra/include/mach/clk.h +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/include/mach/clk.h | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * | ||
6 | * Author: | ||
7 | * Erik Gilling <konkers@google.com> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #ifndef __MACH_CLK_H | ||
21 | #define __MACH_CLK_H | ||
22 | |||
23 | struct clk; | ||
24 | |||
25 | enum tegra_clk_ex_param { | ||
26 | TEGRA_CLK_VI_INP_SEL, | ||
27 | TEGRA_CLK_DTV_INVERT, | ||
28 | TEGRA_CLK_NAND_PAD_DIV2_ENB, | ||
29 | TEGRA_CLK_PLLD_CSI_OUT_ENB, | ||
30 | TEGRA_CLK_PLLD_DSI_OUT_ENB, | ||
31 | TEGRA_CLK_PLLD_MIPI_MUX_SEL, | ||
32 | }; | ||
33 | |||
34 | void tegra_periph_reset_deassert(struct clk *c); | ||
35 | void tegra_periph_reset_assert(struct clk *c); | ||
36 | |||
37 | #ifndef CONFIG_COMMON_CLK | ||
38 | unsigned long clk_get_rate_all_locked(struct clk *c); | ||
39 | #endif | ||
40 | |||
41 | void tegra2_sdmmc_tap_delay(struct clk *c, int delay); | ||
42 | int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting); | ||
43 | |||
44 | #endif | ||
diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h index db8be51cad80..399fbca27102 100644 --- a/arch/arm/mach-tegra/iomap.h +++ b/arch/arm/mach-tegra/iomap.h | |||
@@ -240,15 +240,6 @@ | |||
240 | #define TEGRA_CSITE_BASE 0x70040000 | 240 | #define TEGRA_CSITE_BASE 0x70040000 |
241 | #define TEGRA_CSITE_SIZE SZ_256K | 241 | #define TEGRA_CSITE_SIZE SZ_256K |
242 | 242 | ||
243 | #define TEGRA_USB_BASE 0xC5000000 | ||
244 | #define TEGRA_USB_SIZE SZ_16K | ||
245 | |||
246 | #define TEGRA_USB2_BASE 0xC5004000 | ||
247 | #define TEGRA_USB2_SIZE SZ_16K | ||
248 | |||
249 | #define TEGRA_USB3_BASE 0xC5008000 | ||
250 | #define TEGRA_USB3_SIZE SZ_16K | ||
251 | |||
252 | #define TEGRA_SDMMC1_BASE 0xC8000000 | 243 | #define TEGRA_SDMMC1_BASE 0xC8000000 |
253 | #define TEGRA_SDMMC1_SIZE SZ_512 | 244 | #define TEGRA_SDMMC1_SIZE SZ_512 |
254 | 245 | ||
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 2ff2128cb9d8..1952e82797cc 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c | |||
@@ -44,6 +44,8 @@ | |||
44 | 44 | ||
45 | #define FIRST_LEGACY_IRQ 32 | 45 | #define FIRST_LEGACY_IRQ 32 |
46 | 46 | ||
47 | #define SGI_MASK 0xFFFF | ||
48 | |||
47 | static int num_ictlrs; | 49 | static int num_ictlrs; |
48 | 50 | ||
49 | static void __iomem *ictlr_reg_base[] = { | 51 | static void __iomem *ictlr_reg_base[] = { |
@@ -54,6 +56,19 @@ static void __iomem *ictlr_reg_base[] = { | |||
54 | IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), | 56 | IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), |
55 | }; | 57 | }; |
56 | 58 | ||
59 | bool tegra_pending_sgi(void) | ||
60 | { | ||
61 | u32 pending_set; | ||
62 | void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); | ||
63 | |||
64 | pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET); | ||
65 | |||
66 | if (pending_set & SGI_MASK) | ||
67 | return true; | ||
68 | |||
69 | return false; | ||
70 | } | ||
71 | |||
57 | static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) | 72 | static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) |
58 | { | 73 | { |
59 | void __iomem *base; | 74 | void __iomem *base; |
diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h new file mode 100644 index 000000000000..5142649bba05 --- /dev/null +++ b/arch/arm/mach-tegra/irq.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA Corporation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __TEGRA_IRQ_H | ||
18 | #define __TEGRA_IRQ_H | ||
19 | |||
20 | bool tegra_pending_sgi(void); | ||
21 | |||
22 | #endif | ||
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index bffcd643d7a3..b60165f1ca02 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c | |||
@@ -33,11 +33,11 @@ | |||
33 | #include <linux/clk.h> | 33 | #include <linux/clk.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/export.h> | 35 | #include <linux/export.h> |
36 | #include <linux/clk/tegra.h> | ||
36 | 37 | ||
37 | #include <asm/sizes.h> | 38 | #include <asm/sizes.h> |
38 | #include <asm/mach/pci.h> | 39 | #include <asm/mach/pci.h> |
39 | 40 | ||
40 | #include <mach/clk.h> | ||
41 | #include <mach/powergate.h> | 41 | #include <mach/powergate.h> |
42 | 42 | ||
43 | #include "board.h" | 43 | #include "board.h" |
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 3c4a43c892a5..2c6b3d55213b 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/irqchip/arm-gic.h> | 21 | #include <linux/irqchip/arm-gic.h> |
22 | #include <linux/clk/tegra.h> | ||
22 | 23 | ||
23 | #include <asm/cacheflush.h> | 24 | #include <asm/cacheflush.h> |
24 | #include <asm/mach-types.h> | 25 | #include <asm/mach-types.h> |
@@ -30,7 +31,6 @@ | |||
30 | #include "fuse.h" | 31 | #include "fuse.h" |
31 | #include "flowctrl.h" | 32 | #include "flowctrl.h" |
32 | #include "reset.h" | 33 | #include "reset.h" |
33 | #include "tegra_cpu_car.h" | ||
34 | 34 | ||
35 | #include "common.h" | 35 | #include "common.h" |
36 | #include "iomap.h" | 36 | #include "iomap.h" |
@@ -38,7 +38,6 @@ | |||
38 | extern void tegra_secondary_startup(void); | 38 | extern void tegra_secondary_startup(void); |
39 | 39 | ||
40 | static cpumask_t tegra_cpu_init_mask; | 40 | static cpumask_t tegra_cpu_init_mask; |
41 | static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); | ||
42 | 41 | ||
43 | #define EVP_CPU_RESET_VECTOR \ | 42 | #define EVP_CPU_RESET_VECTOR \ |
44 | (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) | 43 | (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) |
@@ -177,34 +176,16 @@ done: | |||
177 | return status; | 176 | return status; |
178 | } | 177 | } |
179 | 178 | ||
180 | /* | ||
181 | * Initialise the CPU possible map early - this describes the CPUs | ||
182 | * which may be present or become present in the system. | ||
183 | */ | ||
184 | static void __init tegra_smp_init_cpus(void) | ||
185 | { | ||
186 | unsigned int i, ncores = scu_get_core_count(scu_base); | ||
187 | |||
188 | if (ncores > nr_cpu_ids) { | ||
189 | pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", | ||
190 | ncores, nr_cpu_ids); | ||
191 | ncores = nr_cpu_ids; | ||
192 | } | ||
193 | |||
194 | for (i = 0; i < ncores; i++) | ||
195 | set_cpu_possible(i, true); | ||
196 | } | ||
197 | |||
198 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) | 179 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) |
199 | { | 180 | { |
200 | /* Always mark the boot CPU (CPU0) as initialized. */ | 181 | /* Always mark the boot CPU (CPU0) as initialized. */ |
201 | cpumask_set_cpu(0, &tegra_cpu_init_mask); | 182 | cpumask_set_cpu(0, &tegra_cpu_init_mask); |
202 | 183 | ||
203 | scu_enable(scu_base); | 184 | if (scu_a9_has_base()) |
185 | scu_enable(IO_ADDRESS(scu_a9_get_base())); | ||
204 | } | 186 | } |
205 | 187 | ||
206 | struct smp_operations tegra_smp_ops __initdata = { | 188 | struct smp_operations tegra_smp_ops __initdata = { |
207 | .smp_init_cpus = tegra_smp_init_cpus, | ||
208 | .smp_prepare_cpus = tegra_smp_prepare_cpus, | 189 | .smp_prepare_cpus = tegra_smp_prepare_cpus, |
209 | .smp_secondary_init = tegra_secondary_init, | 190 | .smp_secondary_init = tegra_secondary_init, |
210 | .smp_boot_secondary = tegra_boot_secondary, | 191 | .smp_boot_secondary = tegra_boot_secondary, |
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 498d70b33775..523604de666f 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cpu_pm.h> | 24 | #include <linux/cpu_pm.h> |
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/clk/tegra.h> | ||
27 | 28 | ||
28 | #include <asm/smp_plat.h> | 29 | #include <asm/smp_plat.h> |
29 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
@@ -35,8 +36,8 @@ | |||
35 | #include "iomap.h" | 36 | #include "iomap.h" |
36 | #include "reset.h" | 37 | #include "reset.h" |
37 | #include "flowctrl.h" | 38 | #include "flowctrl.h" |
39 | #include "fuse.h" | ||
38 | #include "sleep.h" | 40 | #include "sleep.h" |
39 | #include "tegra_cpu_car.h" | ||
40 | 41 | ||
41 | #define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */ | 42 | #define TEGRA_POWER_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */ |
42 | 43 | ||
@@ -173,6 +174,8 @@ bool tegra_set_cpu_in_lp2(int phy_cpu_id) | |||
173 | 174 | ||
174 | if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) | 175 | if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) |
175 | last_cpu = true; | 176 | last_cpu = true; |
177 | else if (tegra_chip_id == TEGRA20 && phy_cpu_id == 1) | ||
178 | tegra20_cpu_set_resettable_soon(); | ||
176 | 179 | ||
177 | spin_unlock(&tegra_lp2_lock); | 180 | spin_unlock(&tegra_lp2_lock); |
178 | return last_cpu; | 181 | return last_cpu; |
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index 2cc1185d902e..c6bc8f85759c 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c | |||
@@ -26,8 +26,8 @@ | |||
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/seq_file.h> | 27 | #include <linux/seq_file.h> |
28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | #include <linux/clk/tegra.h> | ||
29 | 30 | ||
30 | #include <mach/clk.h> | ||
31 | #include <mach/powergate.h> | 31 | #include <mach/powergate.h> |
32 | 32 | ||
33 | #include "fuse.h" | 33 | #include "fuse.h" |
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S index ad2ca07d0578..9f6bfafdd512 100644 --- a/arch/arm/mach-tegra/sleep-tegra20.S +++ b/arch/arm/mach-tegra/sleep-tegra20.S | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/linkage.h> | 21 | #include <linux/linkage.h> |
22 | 22 | ||
23 | #include <asm/assembler.h> | 23 | #include <asm/assembler.h> |
24 | #include <asm/proc-fns.h> | ||
25 | #include <asm/cp15.h> | ||
24 | 26 | ||
25 | #include "sleep.h" | 27 | #include "sleep.h" |
26 | #include "flowctrl.h" | 28 | #include "flowctrl.h" |
@@ -55,6 +57,9 @@ ENDPROC(tegra20_hotplug_shutdown) | |||
55 | ENTRY(tegra20_cpu_shutdown) | 57 | ENTRY(tegra20_cpu_shutdown) |
56 | cmp r0, #0 | 58 | cmp r0, #0 |
57 | moveq pc, lr @ must not be called for CPU 0 | 59 | moveq pc, lr @ must not be called for CPU 0 |
60 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | ||
61 | mov r12, #CPU_RESETTABLE | ||
62 | str r12, [r1] | ||
58 | 63 | ||
59 | cpu_to_halt_reg r1, r0 | 64 | cpu_to_halt_reg r1, r0 |
60 | ldr r3, =TEGRA_FLOW_CTRL_VIRT | 65 | ldr r3, =TEGRA_FLOW_CTRL_VIRT |
@@ -75,3 +80,198 @@ ENTRY(tegra20_cpu_shutdown) | |||
75 | mov pc, lr | 80 | mov pc, lr |
76 | ENDPROC(tegra20_cpu_shutdown) | 81 | ENDPROC(tegra20_cpu_shutdown) |
77 | #endif | 82 | #endif |
83 | |||
84 | #ifdef CONFIG_PM_SLEEP | ||
85 | /* | ||
86 | * tegra_pen_lock | ||
87 | * | ||
88 | * spinlock implementation with no atomic test-and-set and no coherence | ||
89 | * using Peterson's algorithm on strongly-ordered registers | ||
90 | * used to synchronize a cpu waking up from wfi with entering lp2 on idle | ||
91 | * | ||
92 | * The reference link of Peterson's algorithm: | ||
93 | * http://en.wikipedia.org/wiki/Peterson's_algorithm | ||
94 | * | ||
95 | * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm) | ||
96 | * on cpu 0: | ||
97 | * r2 = flag[0] (in SCRATCH38) | ||
98 | * r3 = flag[1] (in SCRATCH39) | ||
99 | * on cpu1: | ||
100 | * r2 = flag[1] (in SCRATCH39) | ||
101 | * r3 = flag[0] (in SCRATCH38) | ||
102 | * | ||
103 | * must be called with MMU on | ||
104 | * corrupts r0-r3, r12 | ||
105 | */ | ||
106 | ENTRY(tegra_pen_lock) | ||
107 | mov32 r3, TEGRA_PMC_VIRT | ||
108 | cpu_id r0 | ||
109 | add r1, r3, #PMC_SCRATCH37 | ||
110 | cmp r0, #0 | ||
111 | addeq r2, r3, #PMC_SCRATCH38 | ||
112 | addeq r3, r3, #PMC_SCRATCH39 | ||
113 | addne r2, r3, #PMC_SCRATCH39 | ||
114 | addne r3, r3, #PMC_SCRATCH38 | ||
115 | |||
116 | mov r12, #1 | ||
117 | str r12, [r2] @ flag[cpu] = 1 | ||
118 | dsb | ||
119 | str r12, [r1] @ !turn = cpu | ||
120 | 1: dsb | ||
121 | ldr r12, [r3] | ||
122 | cmp r12, #1 @ flag[!cpu] == 1? | ||
123 | ldreq r12, [r1] | ||
124 | cmpeq r12, r0 @ !turn == cpu? | ||
125 | beq 1b @ while !turn == cpu && flag[!cpu] == 1 | ||
126 | |||
127 | mov pc, lr @ locked | ||
128 | ENDPROC(tegra_pen_lock) | ||
129 | |||
130 | ENTRY(tegra_pen_unlock) | ||
131 | dsb | ||
132 | mov32 r3, TEGRA_PMC_VIRT | ||
133 | cpu_id r0 | ||
134 | cmp r0, #0 | ||
135 | addeq r2, r3, #PMC_SCRATCH38 | ||
136 | addne r2, r3, #PMC_SCRATCH39 | ||
137 | mov r12, #0 | ||
138 | str r12, [r2] | ||
139 | mov pc, lr | ||
140 | ENDPROC(tegra_pen_unlock) | ||
141 | |||
142 | /* | ||
143 | * tegra20_cpu_clear_resettable(void) | ||
144 | * | ||
145 | * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when | ||
146 | * it is expected that the secondary CPU will be idle soon. | ||
147 | */ | ||
148 | ENTRY(tegra20_cpu_clear_resettable) | ||
149 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | ||
150 | mov r12, #CPU_NOT_RESETTABLE | ||
151 | str r12, [r1] | ||
152 | mov pc, lr | ||
153 | ENDPROC(tegra20_cpu_clear_resettable) | ||
154 | |||
155 | /* | ||
156 | * tegra20_cpu_set_resettable_soon(void) | ||
157 | * | ||
158 | * Called to set the "resettable soon" flag in PMC_SCRATCH41 when | ||
159 | * it is expected that the secondary CPU will be idle soon. | ||
160 | */ | ||
161 | ENTRY(tegra20_cpu_set_resettable_soon) | ||
162 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | ||
163 | mov r12, #CPU_RESETTABLE_SOON | ||
164 | str r12, [r1] | ||
165 | mov pc, lr | ||
166 | ENDPROC(tegra20_cpu_set_resettable_soon) | ||
167 | |||
168 | /* | ||
169 | * tegra20_cpu_is_resettable_soon(void) | ||
170 | * | ||
171 | * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been | ||
172 | * set because it is expected that the secondary CPU will be idle soon. | ||
173 | */ | ||
174 | ENTRY(tegra20_cpu_is_resettable_soon) | ||
175 | mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 | ||
176 | ldr r12, [r1] | ||
177 | cmp r12, #CPU_RESETTABLE_SOON | ||
178 | moveq r0, #1 | ||
179 | movne r0, #0 | ||
180 | mov pc, lr | ||
181 | ENDPROC(tegra20_cpu_is_resettable_soon) | ||
182 | |||
183 | /* | ||
184 | * tegra20_sleep_cpu_secondary_finish(unsigned long v2p) | ||
185 | * | ||
186 | * Enters WFI on secondary CPU by exiting coherency. | ||
187 | */ | ||
188 | ENTRY(tegra20_sleep_cpu_secondary_finish) | ||
189 | stmfd sp!, {r4-r11, lr} | ||
190 | |||
191 | mrc p15, 0, r11, c1, c0, 1 @ save actlr before exiting coherency | ||
192 | |||
193 | /* Flush and disable the L1 data cache */ | ||
194 | bl tegra_disable_clean_inv_dcache | ||
195 | |||
196 | mov32 r0, TEGRA_PMC_VIRT + PMC_SCRATCH41 | ||
197 | mov r3, #CPU_RESETTABLE | ||
198 | str r3, [r0] | ||
199 | |||
200 | bl cpu_do_idle | ||
201 | |||
202 | /* | ||
203 | * cpu may be reset while in wfi, which will return through | ||
204 | * tegra_resume to cpu_resume | ||
205 | * or interrupt may wake wfi, which will return here | ||
206 | * cpu state is unchanged - MMU is on, cache is on, coherency | ||
207 | * is off, and the data cache is off | ||
208 | * | ||
209 | * r11 contains the original actlr | ||
210 | */ | ||
211 | |||
212 | bl tegra_pen_lock | ||
213 | |||
214 | mov32 r3, TEGRA_PMC_VIRT | ||
215 | add r0, r3, #PMC_SCRATCH41 | ||
216 | mov r3, #CPU_NOT_RESETTABLE | ||
217 | str r3, [r0] | ||
218 | |||
219 | bl tegra_pen_unlock | ||
220 | |||
221 | /* Re-enable the data cache */ | ||
222 | mrc p15, 0, r10, c1, c0, 0 | ||
223 | orr r10, r10, #CR_C | ||
224 | mcr p15, 0, r10, c1, c0, 0 | ||
225 | isb | ||
226 | |||
227 | mcr p15, 0, r11, c1, c0, 1 @ reenable coherency | ||
228 | |||
229 | /* Invalidate the TLBs & BTAC */ | ||
230 | mov r1, #0 | ||
231 | mcr p15, 0, r1, c8, c3, 0 @ invalidate shared TLBs | ||
232 | mcr p15, 0, r1, c7, c1, 6 @ invalidate shared BTAC | ||
233 | dsb | ||
234 | isb | ||
235 | |||
236 | /* the cpu was running with coherency disabled, | ||
237 | * caches may be out of date */ | ||
238 | bl v7_flush_kern_cache_louis | ||
239 | |||
240 | ldmfd sp!, {r4 - r11, pc} | ||
241 | ENDPROC(tegra20_sleep_cpu_secondary_finish) | ||
242 | |||
243 | /* | ||
244 | * tegra20_tear_down_cpu | ||
245 | * | ||
246 | * Switches the CPU cluster to PLL-P and enters sleep. | ||
247 | */ | ||
248 | ENTRY(tegra20_tear_down_cpu) | ||
249 | bl tegra_switch_cpu_to_pllp | ||
250 | b tegra20_enter_sleep | ||
251 | ENDPROC(tegra20_tear_down_cpu) | ||
252 | |||
253 | /* | ||
254 | * tegra20_enter_sleep | ||
255 | * | ||
256 | * uses flow controller to enter sleep state | ||
257 | * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1 | ||
258 | * executes from SDRAM with target state is LP2 | ||
259 | */ | ||
260 | tegra20_enter_sleep: | ||
261 | mov32 r6, TEGRA_FLOW_CTRL_BASE | ||
262 | |||
263 | mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT | ||
264 | orr r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ | ||
265 | cpu_id r1 | ||
266 | cpu_to_halt_reg r1, r1 | ||
267 | str r0, [r6, r1] | ||
268 | dsb | ||
269 | ldr r0, [r6, r1] /* memory barrier */ | ||
270 | |||
271 | halted: | ||
272 | dsb | ||
273 | wfe /* CPU should be power gated here */ | ||
274 | isb | ||
275 | b halted | ||
276 | |||
277 | #endif | ||
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S index addae357da3f..364d84523fba 100644 --- a/arch/arm/mach-tegra/sleep.S +++ b/arch/arm/mach-tegra/sleep.S | |||
@@ -34,6 +34,9 @@ | |||
34 | #include "flowctrl.h" | 34 | #include "flowctrl.h" |
35 | #include "sleep.h" | 35 | #include "sleep.h" |
36 | 36 | ||
37 | #define CLK_RESET_CCLK_BURST 0x20 | ||
38 | #define CLK_RESET_CCLK_DIVIDER 0x24 | ||
39 | |||
37 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) | 40 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) |
38 | /* | 41 | /* |
39 | * tegra_disable_clean_inv_dcache | 42 | * tegra_disable_clean_inv_dcache |
@@ -110,4 +113,20 @@ ENTRY(tegra_shut_off_mmu) | |||
110 | mov pc, r0 | 113 | mov pc, r0 |
111 | ENDPROC(tegra_shut_off_mmu) | 114 | ENDPROC(tegra_shut_off_mmu) |
112 | .popsection | 115 | .popsection |
116 | |||
117 | /* | ||
118 | * tegra_switch_cpu_to_pllp | ||
119 | * | ||
120 | * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp | ||
121 | */ | ||
122 | ENTRY(tegra_switch_cpu_to_pllp) | ||
123 | /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */ | ||
124 | mov32 r5, TEGRA_CLK_RESET_BASE | ||
125 | mov r0, #(2 << 28) @ burst policy = run mode | ||
126 | orr r0, r0, #(4 << 4) @ use PLLP in run mode burst | ||
127 | str r0, [r5, #CLK_RESET_CCLK_BURST] | ||
128 | mov r0, #0 | ||
129 | str r0, [r5, #CLK_RESET_CCLK_DIVIDER] | ||
130 | mov pc, lr | ||
131 | ENDPROC(tegra_switch_cpu_to_pllp) | ||
113 | #endif | 132 | #endif |
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index 56505c381ea8..4ffae541726e 100644 --- a/arch/arm/mach-tegra/sleep.h +++ b/arch/arm/mach-tegra/sleep.h | |||
@@ -25,6 +25,19 @@ | |||
25 | + IO_PPSB_VIRT) | 25 | + IO_PPSB_VIRT) |
26 | #define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \ | 26 | #define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \ |
27 | + IO_PPSB_VIRT) | 27 | + IO_PPSB_VIRT) |
28 | #define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT) | ||
29 | |||
30 | /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */ | ||
31 | #define PMC_SCRATCH37 0x130 | ||
32 | #define PMC_SCRATCH38 0x134 | ||
33 | #define PMC_SCRATCH39 0x138 | ||
34 | #define PMC_SCRATCH41 0x140 | ||
35 | |||
36 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
37 | #define CPU_RESETTABLE 2 | ||
38 | #define CPU_RESETTABLE_SOON 1 | ||
39 | #define CPU_NOT_RESETTABLE 0 | ||
40 | #endif | ||
28 | 41 | ||
29 | #ifdef __ASSEMBLY__ | 42 | #ifdef __ASSEMBLY__ |
30 | /* returns the offset of the flow controller halt register for a cpu */ | 43 | /* returns the offset of the flow controller halt register for a cpu */ |
@@ -104,6 +117,8 @@ exit_l2_resume: | |||
104 | .endm | 117 | .endm |
105 | #endif /* CONFIG_CACHE_L2X0 */ | 118 | #endif /* CONFIG_CACHE_L2X0 */ |
106 | #else | 119 | #else |
120 | void tegra_pen_lock(void); | ||
121 | void tegra_pen_unlock(void); | ||
107 | void tegra_resume(void); | 122 | void tegra_resume(void); |
108 | int tegra_sleep_cpu_finish(unsigned long); | 123 | int tegra_sleep_cpu_finish(unsigned long); |
109 | void tegra_disable_clean_inv_dcache(void); | 124 | void tegra_disable_clean_inv_dcache(void); |
@@ -116,6 +131,17 @@ static inline void tegra20_hotplug_init(void) {} | |||
116 | static inline void tegra30_hotplug_init(void) {} | 131 | static inline void tegra30_hotplug_init(void) {} |
117 | #endif | 132 | #endif |
118 | 133 | ||
134 | void tegra20_cpu_shutdown(int cpu); | ||
135 | int tegra20_cpu_is_resettable_soon(void); | ||
136 | void tegra20_cpu_clear_resettable(void); | ||
137 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
138 | void tegra20_cpu_set_resettable_soon(void); | ||
139 | #else | ||
140 | static inline void tegra20_cpu_set_resettable_soon(void) {} | ||
141 | #endif | ||
142 | |||
143 | int tegra20_sleep_cpu_secondary_finish(unsigned long); | ||
144 | void tegra20_tear_down_cpu(void); | ||
119 | int tegra30_sleep_cpu_secondary_finish(unsigned long); | 145 | int tegra30_sleep_cpu_secondary_finish(unsigned long); |
120 | void tegra30_tear_down_cpu(void); | 146 | void tegra30_tear_down_cpu(void); |
121 | 147 | ||
diff --git a/arch/arm/mach-tegra/tegra20_clocks.c b/arch/arm/mach-tegra/tegra20_clocks.c deleted file mode 100644 index 4eb6bc81a87b..000000000000 --- a/arch/arm/mach-tegra/tegra20_clocks.c +++ /dev/null | |||
@@ -1,1623 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/tegra20_clocks.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved. | ||
6 | * | ||
7 | * Author: | ||
8 | * Colin Cross <ccross@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/clkdev.h> | ||
28 | #include <linux/clk.h> | ||
29 | |||
30 | #include "clock.h" | ||
31 | #include "fuse.h" | ||
32 | #include "iomap.h" | ||
33 | #include "tegra2_emc.h" | ||
34 | #include "tegra_cpu_car.h" | ||
35 | |||
36 | #define RST_DEVICES 0x004 | ||
37 | #define RST_DEVICES_SET 0x300 | ||
38 | #define RST_DEVICES_CLR 0x304 | ||
39 | #define RST_DEVICES_NUM 3 | ||
40 | |||
41 | #define CLK_OUT_ENB 0x010 | ||
42 | #define CLK_OUT_ENB_SET 0x320 | ||
43 | #define CLK_OUT_ENB_CLR 0x324 | ||
44 | #define CLK_OUT_ENB_NUM 3 | ||
45 | |||
46 | #define CLK_MASK_ARM 0x44 | ||
47 | #define MISC_CLK_ENB 0x48 | ||
48 | |||
49 | #define OSC_CTRL 0x50 | ||
50 | #define OSC_CTRL_OSC_FREQ_MASK (3<<30) | ||
51 | #define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) | ||
52 | #define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) | ||
53 | #define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) | ||
54 | #define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) | ||
55 | #define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) | ||
56 | |||
57 | #define OSC_FREQ_DET 0x58 | ||
58 | #define OSC_FREQ_DET_TRIG (1<<31) | ||
59 | |||
60 | #define OSC_FREQ_DET_STATUS 0x5C | ||
61 | #define OSC_FREQ_DET_BUSY (1<<31) | ||
62 | #define OSC_FREQ_DET_CNT_MASK 0xFFFF | ||
63 | |||
64 | #define PERIPH_CLK_SOURCE_I2S1 0x100 | ||
65 | #define PERIPH_CLK_SOURCE_EMC 0x19c | ||
66 | #define PERIPH_CLK_SOURCE_OSC 0x1fc | ||
67 | #define PERIPH_CLK_SOURCE_NUM \ | ||
68 | ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4) | ||
69 | |||
70 | #define PERIPH_CLK_SOURCE_MASK (3<<30) | ||
71 | #define PERIPH_CLK_SOURCE_SHIFT 30 | ||
72 | #define PERIPH_CLK_SOURCE_PWM_MASK (7<<28) | ||
73 | #define PERIPH_CLK_SOURCE_PWM_SHIFT 28 | ||
74 | #define PERIPH_CLK_SOURCE_ENABLE (1<<28) | ||
75 | #define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF | ||
76 | #define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF | ||
77 | #define PERIPH_CLK_SOURCE_DIV_SHIFT 0 | ||
78 | |||
79 | #define SDMMC_CLK_INT_FB_SEL (1 << 23) | ||
80 | #define SDMMC_CLK_INT_FB_DLY_SHIFT 16 | ||
81 | #define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT) | ||
82 | |||
83 | #define PLL_BASE 0x0 | ||
84 | #define PLL_BASE_BYPASS (1<<31) | ||
85 | #define PLL_BASE_ENABLE (1<<30) | ||
86 | #define PLL_BASE_REF_ENABLE (1<<29) | ||
87 | #define PLL_BASE_OVERRIDE (1<<28) | ||
88 | #define PLL_BASE_DIVP_MASK (0x7<<20) | ||
89 | #define PLL_BASE_DIVP_SHIFT 20 | ||
90 | #define PLL_BASE_DIVN_MASK (0x3FF<<8) | ||
91 | #define PLL_BASE_DIVN_SHIFT 8 | ||
92 | #define PLL_BASE_DIVM_MASK (0x1F) | ||
93 | #define PLL_BASE_DIVM_SHIFT 0 | ||
94 | |||
95 | #define PLL_OUT_RATIO_MASK (0xFF<<8) | ||
96 | #define PLL_OUT_RATIO_SHIFT 8 | ||
97 | #define PLL_OUT_OVERRIDE (1<<2) | ||
98 | #define PLL_OUT_CLKEN (1<<1) | ||
99 | #define PLL_OUT_RESET_DISABLE (1<<0) | ||
100 | |||
101 | #define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc) | ||
102 | |||
103 | #define PLL_MISC_DCCON_SHIFT 20 | ||
104 | #define PLL_MISC_CPCON_SHIFT 8 | ||
105 | #define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT) | ||
106 | #define PLL_MISC_LFCON_SHIFT 4 | ||
107 | #define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT) | ||
108 | #define PLL_MISC_VCOCON_SHIFT 0 | ||
109 | #define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT) | ||
110 | |||
111 | #define PLLU_BASE_POST_DIV (1<<20) | ||
112 | |||
113 | #define PLLD_MISC_CLKENABLE (1<<30) | ||
114 | #define PLLD_MISC_DIV_RST (1<<23) | ||
115 | #define PLLD_MISC_DCCON_SHIFT 12 | ||
116 | |||
117 | #define PLLE_MISC_READY (1 << 15) | ||
118 | |||
119 | #define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4) | ||
120 | #define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8) | ||
121 | #define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32)) | ||
122 | |||
123 | #define SUPER_CLK_MUX 0x00 | ||
124 | #define SUPER_STATE_SHIFT 28 | ||
125 | #define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT) | ||
126 | #define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT) | ||
127 | #define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT) | ||
128 | #define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT) | ||
129 | #define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT) | ||
130 | #define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT) | ||
131 | #define SUPER_SOURCE_MASK 0xF | ||
132 | #define SUPER_FIQ_SOURCE_SHIFT 12 | ||
133 | #define SUPER_IRQ_SOURCE_SHIFT 8 | ||
134 | #define SUPER_RUN_SOURCE_SHIFT 4 | ||
135 | #define SUPER_IDLE_SOURCE_SHIFT 0 | ||
136 | |||
137 | #define SUPER_CLK_DIVIDER 0x04 | ||
138 | |||
139 | #define BUS_CLK_DISABLE (1<<3) | ||
140 | #define BUS_CLK_DIV_MASK 0x3 | ||
141 | |||
142 | #define PMC_CTRL 0x0 | ||
143 | #define PMC_CTRL_BLINK_ENB (1 << 7) | ||
144 | |||
145 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
146 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20) | ||
147 | |||
148 | #define PMC_BLINK_TIMER_DATA_ON_SHIFT 0 | ||
149 | #define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff | ||
150 | #define PMC_BLINK_TIMER_ENB (1 << 15) | ||
151 | #define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16 | ||
152 | #define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff | ||
153 | |||
154 | /* Tegra CPU clock and reset control regs */ | ||
155 | #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c | ||
156 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 | ||
157 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344 | ||
158 | |||
159 | #define CPU_CLOCK(cpu) (0x1 << (8 + cpu)) | ||
160 | #define CPU_RESET(cpu) (0x1111ul << (cpu)) | ||
161 | |||
162 | static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); | ||
163 | static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); | ||
164 | |||
165 | /* | ||
166 | * Some clocks share a register with other clocks. Any clock op that | ||
167 | * non-atomically modifies a register used by another clock must lock | ||
168 | * clock_register_lock first. | ||
169 | */ | ||
170 | static DEFINE_SPINLOCK(clock_register_lock); | ||
171 | |||
172 | /* | ||
173 | * Some peripheral clocks share an enable bit, so refcount the enable bits | ||
174 | * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U | ||
175 | */ | ||
176 | static int tegra_periph_clk_enable_refcount[3 * 32]; | ||
177 | |||
178 | #define clk_writel(value, reg) \ | ||
179 | __raw_writel(value, reg_clk_base + (reg)) | ||
180 | #define clk_readl(reg) \ | ||
181 | __raw_readl(reg_clk_base + (reg)) | ||
182 | #define pmc_writel(value, reg) \ | ||
183 | __raw_writel(value, reg_pmc_base + (reg)) | ||
184 | #define pmc_readl(reg) \ | ||
185 | __raw_readl(reg_pmc_base + (reg)) | ||
186 | |||
187 | static unsigned long clk_measure_input_freq(void) | ||
188 | { | ||
189 | u32 clock_autodetect; | ||
190 | clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET); | ||
191 | do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY); | ||
192 | clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS); | ||
193 | if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) { | ||
194 | return 12000000; | ||
195 | } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) { | ||
196 | return 13000000; | ||
197 | } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) { | ||
198 | return 19200000; | ||
199 | } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) { | ||
200 | return 26000000; | ||
201 | } else { | ||
202 | pr_err("%s: Unexpected clock autodetect value %d", | ||
203 | __func__, clock_autodetect); | ||
204 | BUG(); | ||
205 | return 0; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate) | ||
210 | { | ||
211 | s64 divider_u71 = parent_rate * 2; | ||
212 | divider_u71 += rate - 1; | ||
213 | do_div(divider_u71, rate); | ||
214 | |||
215 | if (divider_u71 - 2 < 0) | ||
216 | return 0; | ||
217 | |||
218 | if (divider_u71 - 2 > 255) | ||
219 | return -EINVAL; | ||
220 | |||
221 | return divider_u71 - 2; | ||
222 | } | ||
223 | |||
224 | static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate) | ||
225 | { | ||
226 | s64 divider_u16; | ||
227 | |||
228 | divider_u16 = parent_rate; | ||
229 | divider_u16 += rate - 1; | ||
230 | do_div(divider_u16, rate); | ||
231 | |||
232 | if (divider_u16 - 1 < 0) | ||
233 | return 0; | ||
234 | |||
235 | if (divider_u16 - 1 > 0xFFFF) | ||
236 | return -EINVAL; | ||
237 | |||
238 | return divider_u16 - 1; | ||
239 | } | ||
240 | |||
241 | static unsigned long tegra_clk_fixed_recalc_rate(struct clk_hw *hw, | ||
242 | unsigned long parent_rate) | ||
243 | { | ||
244 | return to_clk_tegra(hw)->fixed_rate; | ||
245 | } | ||
246 | |||
247 | struct clk_ops tegra_clk_32k_ops = { | ||
248 | .recalc_rate = tegra_clk_fixed_recalc_rate, | ||
249 | }; | ||
250 | |||
251 | /* clk_m functions */ | ||
252 | static unsigned long tegra20_clk_m_recalc_rate(struct clk_hw *hw, | ||
253 | unsigned long prate) | ||
254 | { | ||
255 | if (!to_clk_tegra(hw)->fixed_rate) | ||
256 | to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq(); | ||
257 | return to_clk_tegra(hw)->fixed_rate; | ||
258 | } | ||
259 | |||
260 | static void tegra20_clk_m_init(struct clk_hw *hw) | ||
261 | { | ||
262 | struct clk_tegra *c = to_clk_tegra(hw); | ||
263 | u32 osc_ctrl = clk_readl(OSC_CTRL); | ||
264 | u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK; | ||
265 | |||
266 | switch (c->fixed_rate) { | ||
267 | case 12000000: | ||
268 | auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ; | ||
269 | break; | ||
270 | case 13000000: | ||
271 | auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ; | ||
272 | break; | ||
273 | case 19200000: | ||
274 | auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ; | ||
275 | break; | ||
276 | case 26000000: | ||
277 | auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ; | ||
278 | break; | ||
279 | default: | ||
280 | BUG(); | ||
281 | } | ||
282 | clk_writel(auto_clock_control, OSC_CTRL); | ||
283 | } | ||
284 | |||
285 | struct clk_ops tegra_clk_m_ops = { | ||
286 | .init = tegra20_clk_m_init, | ||
287 | .recalc_rate = tegra20_clk_m_recalc_rate, | ||
288 | }; | ||
289 | |||
290 | /* super clock functions */ | ||
291 | /* "super clocks" on tegra have two-stage muxes and a clock skipping | ||
292 | * super divider. We will ignore the clock skipping divider, since we | ||
293 | * can't lower the voltage when using the clock skip, but we can if we | ||
294 | * lower the PLL frequency. | ||
295 | */ | ||
296 | static int tegra20_super_clk_is_enabled(struct clk_hw *hw) | ||
297 | { | ||
298 | struct clk_tegra *c = to_clk_tegra(hw); | ||
299 | u32 val; | ||
300 | |||
301 | val = clk_readl(c->reg + SUPER_CLK_MUX); | ||
302 | BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && | ||
303 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); | ||
304 | c->state = ON; | ||
305 | return c->state; | ||
306 | } | ||
307 | |||
308 | static int tegra20_super_clk_enable(struct clk_hw *hw) | ||
309 | { | ||
310 | struct clk_tegra *c = to_clk_tegra(hw); | ||
311 | clk_writel(0, c->reg + SUPER_CLK_DIVIDER); | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static void tegra20_super_clk_disable(struct clk_hw *hw) | ||
316 | { | ||
317 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
318 | |||
319 | /* oops - don't disable the CPU clock! */ | ||
320 | BUG(); | ||
321 | } | ||
322 | |||
323 | static u8 tegra20_super_clk_get_parent(struct clk_hw *hw) | ||
324 | { | ||
325 | struct clk_tegra *c = to_clk_tegra(hw); | ||
326 | int val = clk_readl(c->reg + SUPER_CLK_MUX); | ||
327 | int source; | ||
328 | int shift; | ||
329 | |||
330 | BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && | ||
331 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); | ||
332 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? | ||
333 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; | ||
334 | source = (val >> shift) & SUPER_SOURCE_MASK; | ||
335 | return source; | ||
336 | } | ||
337 | |||
338 | static int tegra20_super_clk_set_parent(struct clk_hw *hw, u8 index) | ||
339 | { | ||
340 | struct clk_tegra *c = to_clk_tegra(hw); | ||
341 | u32 val = clk_readl(c->reg + SUPER_CLK_MUX); | ||
342 | int shift; | ||
343 | |||
344 | BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && | ||
345 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); | ||
346 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? | ||
347 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; | ||
348 | val &= ~(SUPER_SOURCE_MASK << shift); | ||
349 | val |= index << shift; | ||
350 | |||
351 | clk_writel(val, c->reg); | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | /* FIX ME: Need to switch parents to change the source PLL rate */ | ||
357 | static unsigned long tegra20_super_clk_recalc_rate(struct clk_hw *hw, | ||
358 | unsigned long prate) | ||
359 | { | ||
360 | return prate; | ||
361 | } | ||
362 | |||
363 | static long tegra20_super_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
364 | unsigned long *prate) | ||
365 | { | ||
366 | return *prate; | ||
367 | } | ||
368 | |||
369 | static int tegra20_super_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
370 | unsigned long parent_rate) | ||
371 | { | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | struct clk_ops tegra_super_ops = { | ||
376 | .is_enabled = tegra20_super_clk_is_enabled, | ||
377 | .enable = tegra20_super_clk_enable, | ||
378 | .disable = tegra20_super_clk_disable, | ||
379 | .set_parent = tegra20_super_clk_set_parent, | ||
380 | .get_parent = tegra20_super_clk_get_parent, | ||
381 | .set_rate = tegra20_super_clk_set_rate, | ||
382 | .round_rate = tegra20_super_clk_round_rate, | ||
383 | .recalc_rate = tegra20_super_clk_recalc_rate, | ||
384 | }; | ||
385 | |||
386 | static unsigned long tegra20_twd_clk_recalc_rate(struct clk_hw *hw, | ||
387 | unsigned long parent_rate) | ||
388 | { | ||
389 | struct clk_tegra *c = to_clk_tegra(hw); | ||
390 | u64 rate = parent_rate; | ||
391 | |||
392 | if (c->mul != 0 && c->div != 0) { | ||
393 | rate *= c->mul; | ||
394 | rate += c->div - 1; /* round up */ | ||
395 | do_div(rate, c->div); | ||
396 | } | ||
397 | |||
398 | return rate; | ||
399 | } | ||
400 | |||
401 | struct clk_ops tegra_twd_ops = { | ||
402 | .recalc_rate = tegra20_twd_clk_recalc_rate, | ||
403 | }; | ||
404 | |||
405 | static u8 tegra20_cop_clk_get_parent(struct clk_hw *hw) | ||
406 | { | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | struct clk_ops tegra_cop_ops = { | ||
411 | .get_parent = tegra20_cop_clk_get_parent, | ||
412 | }; | ||
413 | |||
414 | /* virtual cop clock functions. Used to acquire the fake 'cop' clock to | ||
415 | * reset the COP block (i.e. AVP) */ | ||
416 | void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert) | ||
417 | { | ||
418 | unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR; | ||
419 | |||
420 | pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert"); | ||
421 | clk_writel(1 << 1, reg); | ||
422 | } | ||
423 | |||
424 | /* bus clock functions */ | ||
425 | static int tegra20_bus_clk_is_enabled(struct clk_hw *hw) | ||
426 | { | ||
427 | struct clk_tegra *c = to_clk_tegra(hw); | ||
428 | u32 val = clk_readl(c->reg); | ||
429 | |||
430 | c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON; | ||
431 | return c->state; | ||
432 | } | ||
433 | |||
434 | static int tegra20_bus_clk_enable(struct clk_hw *hw) | ||
435 | { | ||
436 | struct clk_tegra *c = to_clk_tegra(hw); | ||
437 | unsigned long flags; | ||
438 | u32 val; | ||
439 | |||
440 | spin_lock_irqsave(&clock_register_lock, flags); | ||
441 | |||
442 | val = clk_readl(c->reg); | ||
443 | val &= ~(BUS_CLK_DISABLE << c->reg_shift); | ||
444 | clk_writel(val, c->reg); | ||
445 | |||
446 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static void tegra20_bus_clk_disable(struct clk_hw *hw) | ||
452 | { | ||
453 | struct clk_tegra *c = to_clk_tegra(hw); | ||
454 | unsigned long flags; | ||
455 | u32 val; | ||
456 | |||
457 | spin_lock_irqsave(&clock_register_lock, flags); | ||
458 | |||
459 | val = clk_readl(c->reg); | ||
460 | val |= BUS_CLK_DISABLE << c->reg_shift; | ||
461 | clk_writel(val, c->reg); | ||
462 | |||
463 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
464 | } | ||
465 | |||
466 | static unsigned long tegra20_bus_clk_recalc_rate(struct clk_hw *hw, | ||
467 | unsigned long prate) | ||
468 | { | ||
469 | struct clk_tegra *c = to_clk_tegra(hw); | ||
470 | u32 val = clk_readl(c->reg); | ||
471 | u64 rate = prate; | ||
472 | |||
473 | c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1; | ||
474 | c->mul = 1; | ||
475 | |||
476 | if (c->mul != 0 && c->div != 0) { | ||
477 | rate *= c->mul; | ||
478 | rate += c->div - 1; /* round up */ | ||
479 | do_div(rate, c->div); | ||
480 | } | ||
481 | return rate; | ||
482 | } | ||
483 | |||
484 | static int tegra20_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
485 | unsigned long parent_rate) | ||
486 | { | ||
487 | struct clk_tegra *c = to_clk_tegra(hw); | ||
488 | int ret = -EINVAL; | ||
489 | unsigned long flags; | ||
490 | u32 val; | ||
491 | int i; | ||
492 | |||
493 | spin_lock_irqsave(&clock_register_lock, flags); | ||
494 | |||
495 | val = clk_readl(c->reg); | ||
496 | for (i = 1; i <= 4; i++) { | ||
497 | if (rate == parent_rate / i) { | ||
498 | val &= ~(BUS_CLK_DIV_MASK << c->reg_shift); | ||
499 | val |= (i - 1) << c->reg_shift; | ||
500 | clk_writel(val, c->reg); | ||
501 | c->div = i; | ||
502 | c->mul = 1; | ||
503 | ret = 0; | ||
504 | break; | ||
505 | } | ||
506 | } | ||
507 | |||
508 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
509 | |||
510 | return ret; | ||
511 | } | ||
512 | |||
513 | static long tegra20_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
514 | unsigned long *prate) | ||
515 | { | ||
516 | unsigned long parent_rate = *prate; | ||
517 | s64 divider; | ||
518 | |||
519 | if (rate >= parent_rate) | ||
520 | return rate; | ||
521 | |||
522 | divider = parent_rate; | ||
523 | divider += rate - 1; | ||
524 | do_div(divider, rate); | ||
525 | |||
526 | if (divider < 0) | ||
527 | return divider; | ||
528 | |||
529 | if (divider > 4) | ||
530 | divider = 4; | ||
531 | do_div(parent_rate, divider); | ||
532 | |||
533 | return parent_rate; | ||
534 | } | ||
535 | |||
536 | struct clk_ops tegra_bus_ops = { | ||
537 | .is_enabled = tegra20_bus_clk_is_enabled, | ||
538 | .enable = tegra20_bus_clk_enable, | ||
539 | .disable = tegra20_bus_clk_disable, | ||
540 | .set_rate = tegra20_bus_clk_set_rate, | ||
541 | .round_rate = tegra20_bus_clk_round_rate, | ||
542 | .recalc_rate = tegra20_bus_clk_recalc_rate, | ||
543 | }; | ||
544 | |||
545 | /* Blink output functions */ | ||
546 | static int tegra20_blink_clk_is_enabled(struct clk_hw *hw) | ||
547 | { | ||
548 | struct clk_tegra *c = to_clk_tegra(hw); | ||
549 | u32 val; | ||
550 | |||
551 | val = pmc_readl(PMC_CTRL); | ||
552 | c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF; | ||
553 | return c->state; | ||
554 | } | ||
555 | |||
556 | static unsigned long tegra20_blink_clk_recalc_rate(struct clk_hw *hw, | ||
557 | unsigned long prate) | ||
558 | { | ||
559 | struct clk_tegra *c = to_clk_tegra(hw); | ||
560 | u64 rate = prate; | ||
561 | u32 val; | ||
562 | |||
563 | c->mul = 1; | ||
564 | val = pmc_readl(c->reg); | ||
565 | |||
566 | if (val & PMC_BLINK_TIMER_ENB) { | ||
567 | unsigned int on_off; | ||
568 | |||
569 | on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) & | ||
570 | PMC_BLINK_TIMER_DATA_ON_MASK; | ||
571 | val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT; | ||
572 | val &= PMC_BLINK_TIMER_DATA_OFF_MASK; | ||
573 | on_off += val; | ||
574 | /* each tick in the blink timer is 4 32KHz clocks */ | ||
575 | c->div = on_off * 4; | ||
576 | } else { | ||
577 | c->div = 1; | ||
578 | } | ||
579 | |||
580 | if (c->mul != 0 && c->div != 0) { | ||
581 | rate *= c->mul; | ||
582 | rate += c->div - 1; /* round up */ | ||
583 | do_div(rate, c->div); | ||
584 | } | ||
585 | return rate; | ||
586 | } | ||
587 | |||
588 | static int tegra20_blink_clk_enable(struct clk_hw *hw) | ||
589 | { | ||
590 | u32 val; | ||
591 | |||
592 | val = pmc_readl(PMC_DPD_PADS_ORIDE); | ||
593 | pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); | ||
594 | |||
595 | val = pmc_readl(PMC_CTRL); | ||
596 | pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL); | ||
597 | |||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static void tegra20_blink_clk_disable(struct clk_hw *hw) | ||
602 | { | ||
603 | u32 val; | ||
604 | |||
605 | val = pmc_readl(PMC_CTRL); | ||
606 | pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL); | ||
607 | |||
608 | val = pmc_readl(PMC_DPD_PADS_ORIDE); | ||
609 | pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); | ||
610 | } | ||
611 | |||
612 | static int tegra20_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
613 | unsigned long parent_rate) | ||
614 | { | ||
615 | struct clk_tegra *c = to_clk_tegra(hw); | ||
616 | |||
617 | if (rate >= parent_rate) { | ||
618 | c->div = 1; | ||
619 | pmc_writel(0, c->reg); | ||
620 | } else { | ||
621 | unsigned int on_off; | ||
622 | u32 val; | ||
623 | |||
624 | on_off = DIV_ROUND_UP(parent_rate / 8, rate); | ||
625 | c->div = on_off * 8; | ||
626 | |||
627 | val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) << | ||
628 | PMC_BLINK_TIMER_DATA_ON_SHIFT; | ||
629 | on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK; | ||
630 | on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT; | ||
631 | val |= on_off; | ||
632 | val |= PMC_BLINK_TIMER_ENB; | ||
633 | pmc_writel(val, c->reg); | ||
634 | } | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | static long tegra20_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
640 | unsigned long *prate) | ||
641 | { | ||
642 | int div; | ||
643 | int mul; | ||
644 | long round_rate = *prate; | ||
645 | |||
646 | mul = 1; | ||
647 | |||
648 | if (rate >= *prate) { | ||
649 | div = 1; | ||
650 | } else { | ||
651 | div = DIV_ROUND_UP(*prate / 8, rate); | ||
652 | div *= 8; | ||
653 | } | ||
654 | |||
655 | round_rate *= mul; | ||
656 | round_rate += div - 1; | ||
657 | do_div(round_rate, div); | ||
658 | |||
659 | return round_rate; | ||
660 | } | ||
661 | |||
662 | struct clk_ops tegra_blink_clk_ops = { | ||
663 | .is_enabled = tegra20_blink_clk_is_enabled, | ||
664 | .enable = tegra20_blink_clk_enable, | ||
665 | .disable = tegra20_blink_clk_disable, | ||
666 | .set_rate = tegra20_blink_clk_set_rate, | ||
667 | .round_rate = tegra20_blink_clk_round_rate, | ||
668 | .recalc_rate = tegra20_blink_clk_recalc_rate, | ||
669 | }; | ||
670 | |||
671 | /* PLL Functions */ | ||
672 | static int tegra20_pll_clk_wait_for_lock(struct clk_tegra *c) | ||
673 | { | ||
674 | udelay(c->u.pll.lock_delay); | ||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | static int tegra20_pll_clk_is_enabled(struct clk_hw *hw) | ||
679 | { | ||
680 | struct clk_tegra *c = to_clk_tegra(hw); | ||
681 | u32 val = clk_readl(c->reg + PLL_BASE); | ||
682 | |||
683 | c->state = (val & PLL_BASE_ENABLE) ? ON : OFF; | ||
684 | return c->state; | ||
685 | } | ||
686 | |||
687 | static unsigned long tegra20_pll_clk_recalc_rate(struct clk_hw *hw, | ||
688 | unsigned long prate) | ||
689 | { | ||
690 | struct clk_tegra *c = to_clk_tegra(hw); | ||
691 | u32 val = clk_readl(c->reg + PLL_BASE); | ||
692 | u64 rate = prate; | ||
693 | |||
694 | if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) { | ||
695 | const struct clk_pll_freq_table *sel; | ||
696 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
697 | if (sel->input_rate == prate && | ||
698 | sel->output_rate == c->u.pll.fixed_rate) { | ||
699 | c->mul = sel->n; | ||
700 | c->div = sel->m * sel->p; | ||
701 | break; | ||
702 | } | ||
703 | } | ||
704 | pr_err("Clock %s has unknown fixed frequency\n", | ||
705 | __clk_get_name(hw->clk)); | ||
706 | BUG(); | ||
707 | } else if (val & PLL_BASE_BYPASS) { | ||
708 | c->mul = 1; | ||
709 | c->div = 1; | ||
710 | } else { | ||
711 | c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT; | ||
712 | c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT; | ||
713 | if (c->flags & PLLU) | ||
714 | c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2; | ||
715 | else | ||
716 | c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1; | ||
717 | } | ||
718 | |||
719 | if (c->mul != 0 && c->div != 0) { | ||
720 | rate *= c->mul; | ||
721 | rate += c->div - 1; /* round up */ | ||
722 | do_div(rate, c->div); | ||
723 | } | ||
724 | return rate; | ||
725 | } | ||
726 | |||
727 | static int tegra20_pll_clk_enable(struct clk_hw *hw) | ||
728 | { | ||
729 | struct clk_tegra *c = to_clk_tegra(hw); | ||
730 | u32 val; | ||
731 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
732 | |||
733 | val = clk_readl(c->reg + PLL_BASE); | ||
734 | val &= ~PLL_BASE_BYPASS; | ||
735 | val |= PLL_BASE_ENABLE; | ||
736 | clk_writel(val, c->reg + PLL_BASE); | ||
737 | |||
738 | tegra20_pll_clk_wait_for_lock(c); | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | static void tegra20_pll_clk_disable(struct clk_hw *hw) | ||
744 | { | ||
745 | struct clk_tegra *c = to_clk_tegra(hw); | ||
746 | u32 val; | ||
747 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
748 | |||
749 | val = clk_readl(c->reg); | ||
750 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); | ||
751 | clk_writel(val, c->reg); | ||
752 | } | ||
753 | |||
754 | static int tegra20_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
755 | unsigned long parent_rate) | ||
756 | { | ||
757 | struct clk_tegra *c = to_clk_tegra(hw); | ||
758 | unsigned long input_rate = parent_rate; | ||
759 | const struct clk_pll_freq_table *sel; | ||
760 | u32 val; | ||
761 | |||
762 | pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate); | ||
763 | |||
764 | if (c->flags & PLL_FIXED) { | ||
765 | int ret = 0; | ||
766 | if (rate != c->u.pll.fixed_rate) { | ||
767 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", | ||
768 | __func__, __clk_get_name(hw->clk), | ||
769 | c->u.pll.fixed_rate, rate); | ||
770 | ret = -EINVAL; | ||
771 | } | ||
772 | return ret; | ||
773 | } | ||
774 | |||
775 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
776 | if (sel->input_rate == input_rate && sel->output_rate == rate) { | ||
777 | c->mul = sel->n; | ||
778 | c->div = sel->m * sel->p; | ||
779 | |||
780 | val = clk_readl(c->reg + PLL_BASE); | ||
781 | if (c->flags & PLL_FIXED) | ||
782 | val |= PLL_BASE_OVERRIDE; | ||
783 | val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK | | ||
784 | PLL_BASE_DIVM_MASK); | ||
785 | val |= (sel->m << PLL_BASE_DIVM_SHIFT) | | ||
786 | (sel->n << PLL_BASE_DIVN_SHIFT); | ||
787 | BUG_ON(sel->p < 1 || sel->p > 2); | ||
788 | if (c->flags & PLLU) { | ||
789 | if (sel->p == 1) | ||
790 | val |= PLLU_BASE_POST_DIV; | ||
791 | } else { | ||
792 | if (sel->p == 2) | ||
793 | val |= 1 << PLL_BASE_DIVP_SHIFT; | ||
794 | } | ||
795 | clk_writel(val, c->reg + PLL_BASE); | ||
796 | |||
797 | if (c->flags & PLL_HAS_CPCON) { | ||
798 | val = clk_readl(c->reg + PLL_MISC(c)); | ||
799 | val &= ~PLL_MISC_CPCON_MASK; | ||
800 | val |= sel->cpcon << PLL_MISC_CPCON_SHIFT; | ||
801 | clk_writel(val, c->reg + PLL_MISC(c)); | ||
802 | } | ||
803 | |||
804 | if (c->state == ON) | ||
805 | tegra20_pll_clk_enable(hw); | ||
806 | return 0; | ||
807 | } | ||
808 | } | ||
809 | return -EINVAL; | ||
810 | } | ||
811 | |||
812 | static long tegra20_pll_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
813 | unsigned long *prate) | ||
814 | { | ||
815 | struct clk_tegra *c = to_clk_tegra(hw); | ||
816 | const struct clk_pll_freq_table *sel; | ||
817 | unsigned long input_rate = *prate; | ||
818 | u64 output_rate = *prate; | ||
819 | int mul; | ||
820 | int div; | ||
821 | |||
822 | if (c->flags & PLL_FIXED) | ||
823 | return c->u.pll.fixed_rate; | ||
824 | |||
825 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) | ||
826 | if (sel->input_rate == input_rate && sel->output_rate == rate) { | ||
827 | mul = sel->n; | ||
828 | div = sel->m * sel->p; | ||
829 | break; | ||
830 | } | ||
831 | |||
832 | if (sel->input_rate == 0) | ||
833 | return -EINVAL; | ||
834 | |||
835 | output_rate *= mul; | ||
836 | output_rate += div - 1; /* round up */ | ||
837 | do_div(output_rate, div); | ||
838 | |||
839 | return output_rate; | ||
840 | } | ||
841 | |||
842 | struct clk_ops tegra_pll_ops = { | ||
843 | .is_enabled = tegra20_pll_clk_is_enabled, | ||
844 | .enable = tegra20_pll_clk_enable, | ||
845 | .disable = tegra20_pll_clk_disable, | ||
846 | .set_rate = tegra20_pll_clk_set_rate, | ||
847 | .recalc_rate = tegra20_pll_clk_recalc_rate, | ||
848 | .round_rate = tegra20_pll_clk_round_rate, | ||
849 | }; | ||
850 | |||
851 | static void tegra20_pllx_clk_init(struct clk_hw *hw) | ||
852 | { | ||
853 | struct clk_tegra *c = to_clk_tegra(hw); | ||
854 | |||
855 | if (tegra_sku_id == 7) | ||
856 | c->max_rate = 750000000; | ||
857 | } | ||
858 | |||
859 | struct clk_ops tegra_pllx_ops = { | ||
860 | .init = tegra20_pllx_clk_init, | ||
861 | .is_enabled = tegra20_pll_clk_is_enabled, | ||
862 | .enable = tegra20_pll_clk_enable, | ||
863 | .disable = tegra20_pll_clk_disable, | ||
864 | .set_rate = tegra20_pll_clk_set_rate, | ||
865 | .recalc_rate = tegra20_pll_clk_recalc_rate, | ||
866 | .round_rate = tegra20_pll_clk_round_rate, | ||
867 | }; | ||
868 | |||
869 | static int tegra20_plle_clk_enable(struct clk_hw *hw) | ||
870 | { | ||
871 | struct clk_tegra *c = to_clk_tegra(hw); | ||
872 | u32 val; | ||
873 | |||
874 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
875 | |||
876 | mdelay(1); | ||
877 | |||
878 | val = clk_readl(c->reg + PLL_BASE); | ||
879 | if (!(val & PLLE_MISC_READY)) | ||
880 | return -EBUSY; | ||
881 | |||
882 | val = clk_readl(c->reg + PLL_BASE); | ||
883 | val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS; | ||
884 | clk_writel(val, c->reg + PLL_BASE); | ||
885 | |||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | struct clk_ops tegra_plle_ops = { | ||
890 | .is_enabled = tegra20_pll_clk_is_enabled, | ||
891 | .enable = tegra20_plle_clk_enable, | ||
892 | .set_rate = tegra20_pll_clk_set_rate, | ||
893 | .recalc_rate = tegra20_pll_clk_recalc_rate, | ||
894 | .round_rate = tegra20_pll_clk_round_rate, | ||
895 | }; | ||
896 | |||
897 | /* Clock divider ops */ | ||
898 | static int tegra20_pll_div_clk_is_enabled(struct clk_hw *hw) | ||
899 | { | ||
900 | struct clk_tegra *c = to_clk_tegra(hw); | ||
901 | u32 val = clk_readl(c->reg); | ||
902 | |||
903 | val >>= c->reg_shift; | ||
904 | c->state = (val & PLL_OUT_CLKEN) ? ON : OFF; | ||
905 | if (!(val & PLL_OUT_RESET_DISABLE)) | ||
906 | c->state = OFF; | ||
907 | return c->state; | ||
908 | } | ||
909 | |||
910 | static unsigned long tegra20_pll_div_clk_recalc_rate(struct clk_hw *hw, | ||
911 | unsigned long prate) | ||
912 | { | ||
913 | struct clk_tegra *c = to_clk_tegra(hw); | ||
914 | u64 rate = prate; | ||
915 | u32 val = clk_readl(c->reg); | ||
916 | u32 divu71; | ||
917 | |||
918 | val >>= c->reg_shift; | ||
919 | |||
920 | if (c->flags & DIV_U71) { | ||
921 | divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT; | ||
922 | c->div = (divu71 + 2); | ||
923 | c->mul = 2; | ||
924 | } else if (c->flags & DIV_2) { | ||
925 | c->div = 2; | ||
926 | c->mul = 1; | ||
927 | } else { | ||
928 | c->div = 1; | ||
929 | c->mul = 1; | ||
930 | } | ||
931 | |||
932 | rate *= c->mul; | ||
933 | rate += c->div - 1; /* round up */ | ||
934 | do_div(rate, c->div); | ||
935 | |||
936 | return rate; | ||
937 | } | ||
938 | |||
939 | static int tegra20_pll_div_clk_enable(struct clk_hw *hw) | ||
940 | { | ||
941 | struct clk_tegra *c = to_clk_tegra(hw); | ||
942 | unsigned long flags; | ||
943 | u32 new_val; | ||
944 | u32 val; | ||
945 | |||
946 | pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk)); | ||
947 | |||
948 | if (c->flags & DIV_U71) { | ||
949 | spin_lock_irqsave(&clock_register_lock, flags); | ||
950 | val = clk_readl(c->reg); | ||
951 | new_val = val >> c->reg_shift; | ||
952 | new_val &= 0xFFFF; | ||
953 | |||
954 | new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE; | ||
955 | |||
956 | val &= ~(0xFFFF << c->reg_shift); | ||
957 | val |= new_val << c->reg_shift; | ||
958 | clk_writel(val, c->reg); | ||
959 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
960 | return 0; | ||
961 | } else if (c->flags & DIV_2) { | ||
962 | BUG_ON(!(c->flags & PLLD)); | ||
963 | spin_lock_irqsave(&clock_register_lock, flags); | ||
964 | val = clk_readl(c->reg); | ||
965 | val &= ~PLLD_MISC_DIV_RST; | ||
966 | clk_writel(val, c->reg); | ||
967 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
968 | return 0; | ||
969 | } | ||
970 | return -EINVAL; | ||
971 | } | ||
972 | |||
973 | static void tegra20_pll_div_clk_disable(struct clk_hw *hw) | ||
974 | { | ||
975 | struct clk_tegra *c = to_clk_tegra(hw); | ||
976 | unsigned long flags; | ||
977 | u32 new_val; | ||
978 | u32 val; | ||
979 | |||
980 | pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk)); | ||
981 | |||
982 | if (c->flags & DIV_U71) { | ||
983 | spin_lock_irqsave(&clock_register_lock, flags); | ||
984 | val = clk_readl(c->reg); | ||
985 | new_val = val >> c->reg_shift; | ||
986 | new_val &= 0xFFFF; | ||
987 | |||
988 | new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE); | ||
989 | |||
990 | val &= ~(0xFFFF << c->reg_shift); | ||
991 | val |= new_val << c->reg_shift; | ||
992 | clk_writel(val, c->reg); | ||
993 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
994 | } else if (c->flags & DIV_2) { | ||
995 | BUG_ON(!(c->flags & PLLD)); | ||
996 | spin_lock_irqsave(&clock_register_lock, flags); | ||
997 | val = clk_readl(c->reg); | ||
998 | val |= PLLD_MISC_DIV_RST; | ||
999 | clk_writel(val, c->reg); | ||
1000 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
1001 | } | ||
1002 | } | ||
1003 | |||
1004 | static int tegra20_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1005 | unsigned long parent_rate) | ||
1006 | { | ||
1007 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1008 | unsigned long flags; | ||
1009 | int divider_u71; | ||
1010 | u32 new_val; | ||
1011 | u32 val; | ||
1012 | |||
1013 | pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate); | ||
1014 | |||
1015 | if (c->flags & DIV_U71) { | ||
1016 | divider_u71 = clk_div71_get_divider(parent_rate, rate); | ||
1017 | if (divider_u71 >= 0) { | ||
1018 | spin_lock_irqsave(&clock_register_lock, flags); | ||
1019 | val = clk_readl(c->reg); | ||
1020 | new_val = val >> c->reg_shift; | ||
1021 | new_val &= 0xFFFF; | ||
1022 | if (c->flags & DIV_U71_FIXED) | ||
1023 | new_val |= PLL_OUT_OVERRIDE; | ||
1024 | new_val &= ~PLL_OUT_RATIO_MASK; | ||
1025 | new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT; | ||
1026 | |||
1027 | val &= ~(0xFFFF << c->reg_shift); | ||
1028 | val |= new_val << c->reg_shift; | ||
1029 | clk_writel(val, c->reg); | ||
1030 | c->div = divider_u71 + 2; | ||
1031 | c->mul = 2; | ||
1032 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
1033 | return 0; | ||
1034 | } | ||
1035 | } else if (c->flags & DIV_2) { | ||
1036 | if (parent_rate == rate * 2) | ||
1037 | return 0; | ||
1038 | } | ||
1039 | return -EINVAL; | ||
1040 | } | ||
1041 | |||
1042 | static long tegra20_pll_div_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1043 | unsigned long *prate) | ||
1044 | { | ||
1045 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1046 | unsigned long parent_rate = *prate; | ||
1047 | int divider; | ||
1048 | |||
1049 | pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate); | ||
1050 | |||
1051 | if (c->flags & DIV_U71) { | ||
1052 | divider = clk_div71_get_divider(parent_rate, rate); | ||
1053 | if (divider < 0) | ||
1054 | return divider; | ||
1055 | return DIV_ROUND_UP(parent_rate * 2, divider + 2); | ||
1056 | } else if (c->flags & DIV_2) { | ||
1057 | return DIV_ROUND_UP(parent_rate, 2); | ||
1058 | } | ||
1059 | return -EINVAL; | ||
1060 | } | ||
1061 | |||
1062 | struct clk_ops tegra_pll_div_ops = { | ||
1063 | .is_enabled = tegra20_pll_div_clk_is_enabled, | ||
1064 | .enable = tegra20_pll_div_clk_enable, | ||
1065 | .disable = tegra20_pll_div_clk_disable, | ||
1066 | .set_rate = tegra20_pll_div_clk_set_rate, | ||
1067 | .round_rate = tegra20_pll_div_clk_round_rate, | ||
1068 | .recalc_rate = tegra20_pll_div_clk_recalc_rate, | ||
1069 | }; | ||
1070 | |||
1071 | /* Periph clk ops */ | ||
1072 | |||
1073 | static int tegra20_periph_clk_is_enabled(struct clk_hw *hw) | ||
1074 | { | ||
1075 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1076 | |||
1077 | c->state = ON; | ||
1078 | |||
1079 | if (!c->u.periph.clk_num) | ||
1080 | goto out; | ||
1081 | |||
1082 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & | ||
1083 | PERIPH_CLK_TO_ENB_BIT(c))) | ||
1084 | c->state = OFF; | ||
1085 | |||
1086 | if (!(c->flags & PERIPH_NO_RESET)) | ||
1087 | if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) & | ||
1088 | PERIPH_CLK_TO_ENB_BIT(c)) | ||
1089 | c->state = OFF; | ||
1090 | |||
1091 | out: | ||
1092 | return c->state; | ||
1093 | } | ||
1094 | |||
1095 | static int tegra20_periph_clk_enable(struct clk_hw *hw) | ||
1096 | { | ||
1097 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1098 | unsigned long flags; | ||
1099 | u32 val; | ||
1100 | |||
1101 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
1102 | |||
1103 | if (!c->u.periph.clk_num) | ||
1104 | return 0; | ||
1105 | |||
1106 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; | ||
1107 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) | ||
1108 | return 0; | ||
1109 | |||
1110 | spin_lock_irqsave(&clock_register_lock, flags); | ||
1111 | |||
1112 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | ||
1113 | CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); | ||
1114 | if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET)) | ||
1115 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | ||
1116 | RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); | ||
1117 | if (c->flags & PERIPH_EMC_ENB) { | ||
1118 | /* The EMC peripheral clock has 2 extra enable bits */ | ||
1119 | /* FIXME: Do they need to be disabled? */ | ||
1120 | val = clk_readl(c->reg); | ||
1121 | val |= 0x3 << 24; | ||
1122 | clk_writel(val, c->reg); | ||
1123 | } | ||
1124 | |||
1125 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
1126 | |||
1127 | return 0; | ||
1128 | } | ||
1129 | |||
1130 | static void tegra20_periph_clk_disable(struct clk_hw *hw) | ||
1131 | { | ||
1132 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1133 | unsigned long flags; | ||
1134 | |||
1135 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
1136 | |||
1137 | if (!c->u.periph.clk_num) | ||
1138 | return; | ||
1139 | |||
1140 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--; | ||
1141 | |||
1142 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0) | ||
1143 | return; | ||
1144 | |||
1145 | spin_lock_irqsave(&clock_register_lock, flags); | ||
1146 | |||
1147 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | ||
1148 | CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); | ||
1149 | |||
1150 | spin_unlock_irqrestore(&clock_register_lock, flags); | ||
1151 | } | ||
1152 | |||
1153 | void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert) | ||
1154 | { | ||
1155 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1156 | unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR; | ||
1157 | |||
1158 | pr_debug("%s %s on clock %s\n", __func__, | ||
1159 | assert ? "assert" : "deassert", __clk_get_name(hw->clk)); | ||
1160 | |||
1161 | BUG_ON(!c->u.periph.clk_num); | ||
1162 | |||
1163 | if (!(c->flags & PERIPH_NO_RESET)) | ||
1164 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | ||
1165 | base + PERIPH_CLK_TO_ENB_SET_REG(c)); | ||
1166 | } | ||
1167 | |||
1168 | static int tegra20_periph_clk_set_parent(struct clk_hw *hw, u8 index) | ||
1169 | { | ||
1170 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1171 | u32 val; | ||
1172 | u32 mask; | ||
1173 | u32 shift; | ||
1174 | |||
1175 | pr_debug("%s: %s %d\n", __func__, __clk_get_name(hw->clk), index); | ||
1176 | |||
1177 | if (c->flags & MUX_PWM) { | ||
1178 | shift = PERIPH_CLK_SOURCE_PWM_SHIFT; | ||
1179 | mask = PERIPH_CLK_SOURCE_PWM_MASK; | ||
1180 | } else { | ||
1181 | shift = PERIPH_CLK_SOURCE_SHIFT; | ||
1182 | mask = PERIPH_CLK_SOURCE_MASK; | ||
1183 | } | ||
1184 | |||
1185 | val = clk_readl(c->reg); | ||
1186 | val &= ~mask; | ||
1187 | val |= (index) << shift; | ||
1188 | |||
1189 | clk_writel(val, c->reg); | ||
1190 | |||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | static u8 tegra20_periph_clk_get_parent(struct clk_hw *hw) | ||
1195 | { | ||
1196 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1197 | u32 val = clk_readl(c->reg); | ||
1198 | u32 mask; | ||
1199 | u32 shift; | ||
1200 | |||
1201 | if (c->flags & MUX_PWM) { | ||
1202 | shift = PERIPH_CLK_SOURCE_PWM_SHIFT; | ||
1203 | mask = PERIPH_CLK_SOURCE_PWM_MASK; | ||
1204 | } else { | ||
1205 | shift = PERIPH_CLK_SOURCE_SHIFT; | ||
1206 | mask = PERIPH_CLK_SOURCE_MASK; | ||
1207 | } | ||
1208 | |||
1209 | if (c->flags & MUX) | ||
1210 | return (val & mask) >> shift; | ||
1211 | else | ||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1215 | static unsigned long tegra20_periph_clk_recalc_rate(struct clk_hw *hw, | ||
1216 | unsigned long prate) | ||
1217 | { | ||
1218 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1219 | unsigned long rate = prate; | ||
1220 | u32 val = clk_readl(c->reg); | ||
1221 | |||
1222 | if (c->flags & DIV_U71) { | ||
1223 | u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK; | ||
1224 | c->div = divu71 + 2; | ||
1225 | c->mul = 2; | ||
1226 | } else if (c->flags & DIV_U16) { | ||
1227 | u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK; | ||
1228 | c->div = divu16 + 1; | ||
1229 | c->mul = 1; | ||
1230 | } else { | ||
1231 | c->div = 1; | ||
1232 | c->mul = 1; | ||
1233 | return rate; | ||
1234 | } | ||
1235 | |||
1236 | if (c->mul != 0 && c->div != 0) { | ||
1237 | rate *= c->mul; | ||
1238 | rate += c->div - 1; /* round up */ | ||
1239 | do_div(rate, c->div); | ||
1240 | } | ||
1241 | |||
1242 | return rate; | ||
1243 | } | ||
1244 | |||
1245 | static int tegra20_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1246 | unsigned long parent_rate) | ||
1247 | { | ||
1248 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1249 | u32 val; | ||
1250 | int divider; | ||
1251 | |||
1252 | val = clk_readl(c->reg); | ||
1253 | |||
1254 | if (c->flags & DIV_U71) { | ||
1255 | divider = clk_div71_get_divider(parent_rate, rate); | ||
1256 | |||
1257 | if (divider >= 0) { | ||
1258 | val = clk_readl(c->reg); | ||
1259 | val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK; | ||
1260 | val |= divider; | ||
1261 | clk_writel(val, c->reg); | ||
1262 | c->div = divider + 2; | ||
1263 | c->mul = 2; | ||
1264 | return 0; | ||
1265 | } | ||
1266 | } else if (c->flags & DIV_U16) { | ||
1267 | divider = clk_div16_get_divider(parent_rate, rate); | ||
1268 | if (divider >= 0) { | ||
1269 | val = clk_readl(c->reg); | ||
1270 | val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK; | ||
1271 | val |= divider; | ||
1272 | clk_writel(val, c->reg); | ||
1273 | c->div = divider + 1; | ||
1274 | c->mul = 1; | ||
1275 | return 0; | ||
1276 | } | ||
1277 | } else if (parent_rate <= rate) { | ||
1278 | c->div = 1; | ||
1279 | c->mul = 1; | ||
1280 | return 0; | ||
1281 | } | ||
1282 | |||
1283 | return -EINVAL; | ||
1284 | } | ||
1285 | |||
1286 | static long tegra20_periph_clk_round_rate(struct clk_hw *hw, | ||
1287 | unsigned long rate, unsigned long *prate) | ||
1288 | { | ||
1289 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1290 | unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk)); | ||
1291 | int divider; | ||
1292 | |||
1293 | pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate); | ||
1294 | |||
1295 | if (prate) | ||
1296 | parent_rate = *prate; | ||
1297 | |||
1298 | if (c->flags & DIV_U71) { | ||
1299 | divider = clk_div71_get_divider(parent_rate, rate); | ||
1300 | if (divider < 0) | ||
1301 | return divider; | ||
1302 | |||
1303 | return DIV_ROUND_UP(parent_rate * 2, divider + 2); | ||
1304 | } else if (c->flags & DIV_U16) { | ||
1305 | divider = clk_div16_get_divider(parent_rate, rate); | ||
1306 | if (divider < 0) | ||
1307 | return divider; | ||
1308 | return DIV_ROUND_UP(parent_rate, divider + 1); | ||
1309 | } | ||
1310 | return -EINVAL; | ||
1311 | } | ||
1312 | |||
1313 | struct clk_ops tegra_periph_clk_ops = { | ||
1314 | .is_enabled = tegra20_periph_clk_is_enabled, | ||
1315 | .enable = tegra20_periph_clk_enable, | ||
1316 | .disable = tegra20_periph_clk_disable, | ||
1317 | .set_parent = tegra20_periph_clk_set_parent, | ||
1318 | .get_parent = tegra20_periph_clk_get_parent, | ||
1319 | .set_rate = tegra20_periph_clk_set_rate, | ||
1320 | .round_rate = tegra20_periph_clk_round_rate, | ||
1321 | .recalc_rate = tegra20_periph_clk_recalc_rate, | ||
1322 | }; | ||
1323 | |||
1324 | /* External memory controller clock ops */ | ||
1325 | static void tegra20_emc_clk_init(struct clk_hw *hw) | ||
1326 | { | ||
1327 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1328 | c->max_rate = __clk_get_rate(hw->clk); | ||
1329 | } | ||
1330 | |||
1331 | static long tegra20_emc_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1332 | unsigned long *prate) | ||
1333 | { | ||
1334 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1335 | long emc_rate; | ||
1336 | long clk_rate; | ||
1337 | |||
1338 | /* | ||
1339 | * The slowest entry in the EMC clock table that is at least as | ||
1340 | * fast as rate. | ||
1341 | */ | ||
1342 | emc_rate = tegra_emc_round_rate(rate); | ||
1343 | if (emc_rate < 0) | ||
1344 | return c->max_rate; | ||
1345 | |||
1346 | /* | ||
1347 | * The fastest rate the PLL will generate that is at most the | ||
1348 | * requested rate. | ||
1349 | */ | ||
1350 | clk_rate = tegra20_periph_clk_round_rate(hw, emc_rate, NULL); | ||
1351 | |||
1352 | /* | ||
1353 | * If this fails, and emc_rate > clk_rate, it's because the maximum | ||
1354 | * rate in the EMC tables is larger than the maximum rate of the EMC | ||
1355 | * clock. The EMC clock's max rate is the rate it was running when the | ||
1356 | * kernel booted. Such a mismatch is probably due to using the wrong | ||
1357 | * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25. | ||
1358 | */ | ||
1359 | WARN_ONCE(emc_rate != clk_rate, | ||
1360 | "emc_rate %ld != clk_rate %ld", | ||
1361 | emc_rate, clk_rate); | ||
1362 | |||
1363 | return emc_rate; | ||
1364 | } | ||
1365 | |||
1366 | static int tegra20_emc_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1367 | unsigned long parent_rate) | ||
1368 | { | ||
1369 | int ret; | ||
1370 | |||
1371 | /* | ||
1372 | * The Tegra2 memory controller has an interlock with the clock | ||
1373 | * block that allows memory shadowed registers to be updated, | ||
1374 | * and then transfer them to the main registers at the same | ||
1375 | * time as the clock update without glitches. | ||
1376 | */ | ||
1377 | ret = tegra_emc_set_rate(rate); | ||
1378 | if (ret < 0) | ||
1379 | return ret; | ||
1380 | |||
1381 | ret = tegra20_periph_clk_set_rate(hw, rate, parent_rate); | ||
1382 | udelay(1); | ||
1383 | |||
1384 | return ret; | ||
1385 | } | ||
1386 | |||
1387 | struct clk_ops tegra_emc_clk_ops = { | ||
1388 | .init = tegra20_emc_clk_init, | ||
1389 | .is_enabled = tegra20_periph_clk_is_enabled, | ||
1390 | .enable = tegra20_periph_clk_enable, | ||
1391 | .disable = tegra20_periph_clk_disable, | ||
1392 | .set_parent = tegra20_periph_clk_set_parent, | ||
1393 | .get_parent = tegra20_periph_clk_get_parent, | ||
1394 | .set_rate = tegra20_emc_clk_set_rate, | ||
1395 | .round_rate = tegra20_emc_clk_round_rate, | ||
1396 | .recalc_rate = tegra20_periph_clk_recalc_rate, | ||
1397 | }; | ||
1398 | |||
1399 | /* Clock doubler ops */ | ||
1400 | static int tegra20_clk_double_is_enabled(struct clk_hw *hw) | ||
1401 | { | ||
1402 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1403 | |||
1404 | c->state = ON; | ||
1405 | |||
1406 | if (!c->u.periph.clk_num) | ||
1407 | goto out; | ||
1408 | |||
1409 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & | ||
1410 | PERIPH_CLK_TO_ENB_BIT(c))) | ||
1411 | c->state = OFF; | ||
1412 | |||
1413 | out: | ||
1414 | return c->state; | ||
1415 | }; | ||
1416 | |||
1417 | static unsigned long tegra20_clk_double_recalc_rate(struct clk_hw *hw, | ||
1418 | unsigned long prate) | ||
1419 | { | ||
1420 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1421 | u64 rate = prate; | ||
1422 | |||
1423 | c->mul = 2; | ||
1424 | c->div = 1; | ||
1425 | |||
1426 | rate *= c->mul; | ||
1427 | rate += c->div - 1; /* round up */ | ||
1428 | do_div(rate, c->div); | ||
1429 | |||
1430 | return rate; | ||
1431 | } | ||
1432 | |||
1433 | static long tegra20_clk_double_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1434 | unsigned long *prate) | ||
1435 | { | ||
1436 | unsigned long output_rate = *prate; | ||
1437 | |||
1438 | do_div(output_rate, 2); | ||
1439 | return output_rate; | ||
1440 | } | ||
1441 | |||
1442 | static int tegra20_clk_double_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1443 | unsigned long parent_rate) | ||
1444 | { | ||
1445 | if (rate != 2 * parent_rate) | ||
1446 | return -EINVAL; | ||
1447 | return 0; | ||
1448 | } | ||
1449 | |||
1450 | struct clk_ops tegra_clk_double_ops = { | ||
1451 | .is_enabled = tegra20_clk_double_is_enabled, | ||
1452 | .enable = tegra20_periph_clk_enable, | ||
1453 | .disable = tegra20_periph_clk_disable, | ||
1454 | .set_rate = tegra20_clk_double_set_rate, | ||
1455 | .recalc_rate = tegra20_clk_double_recalc_rate, | ||
1456 | .round_rate = tegra20_clk_double_round_rate, | ||
1457 | }; | ||
1458 | |||
1459 | /* Audio sync clock ops */ | ||
1460 | static int tegra20_audio_sync_clk_is_enabled(struct clk_hw *hw) | ||
1461 | { | ||
1462 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1463 | u32 val = clk_readl(c->reg); | ||
1464 | |||
1465 | c->state = (val & (1<<4)) ? OFF : ON; | ||
1466 | return c->state; | ||
1467 | } | ||
1468 | |||
1469 | static int tegra20_audio_sync_clk_enable(struct clk_hw *hw) | ||
1470 | { | ||
1471 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1472 | |||
1473 | clk_writel(0, c->reg); | ||
1474 | return 0; | ||
1475 | } | ||
1476 | |||
1477 | static void tegra20_audio_sync_clk_disable(struct clk_hw *hw) | ||
1478 | { | ||
1479 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1480 | clk_writel(1, c->reg); | ||
1481 | } | ||
1482 | |||
1483 | static u8 tegra20_audio_sync_clk_get_parent(struct clk_hw *hw) | ||
1484 | { | ||
1485 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1486 | u32 val = clk_readl(c->reg); | ||
1487 | int source; | ||
1488 | |||
1489 | source = val & 0xf; | ||
1490 | return source; | ||
1491 | } | ||
1492 | |||
1493 | static int tegra20_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index) | ||
1494 | { | ||
1495 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1496 | u32 val; | ||
1497 | |||
1498 | val = clk_readl(c->reg); | ||
1499 | val &= ~0xf; | ||
1500 | val |= index; | ||
1501 | |||
1502 | clk_writel(val, c->reg); | ||
1503 | |||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1507 | struct clk_ops tegra_audio_sync_clk_ops = { | ||
1508 | .is_enabled = tegra20_audio_sync_clk_is_enabled, | ||
1509 | .enable = tegra20_audio_sync_clk_enable, | ||
1510 | .disable = tegra20_audio_sync_clk_disable, | ||
1511 | .set_parent = tegra20_audio_sync_clk_set_parent, | ||
1512 | .get_parent = tegra20_audio_sync_clk_get_parent, | ||
1513 | }; | ||
1514 | |||
1515 | /* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */ | ||
1516 | |||
1517 | static int tegra20_cdev_clk_is_enabled(struct clk_hw *hw) | ||
1518 | { | ||
1519 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1520 | /* We could un-tristate the cdev1 or cdev2 pingroup here; this is | ||
1521 | * currently done in the pinmux code. */ | ||
1522 | c->state = ON; | ||
1523 | |||
1524 | BUG_ON(!c->u.periph.clk_num); | ||
1525 | |||
1526 | if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & | ||
1527 | PERIPH_CLK_TO_ENB_BIT(c))) | ||
1528 | c->state = OFF; | ||
1529 | return c->state; | ||
1530 | } | ||
1531 | |||
1532 | static int tegra20_cdev_clk_enable(struct clk_hw *hw) | ||
1533 | { | ||
1534 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1535 | BUG_ON(!c->u.periph.clk_num); | ||
1536 | |||
1537 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | ||
1538 | CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); | ||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1542 | static void tegra20_cdev_clk_disable(struct clk_hw *hw) | ||
1543 | { | ||
1544 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1545 | BUG_ON(!c->u.periph.clk_num); | ||
1546 | |||
1547 | clk_writel(PERIPH_CLK_TO_ENB_BIT(c), | ||
1548 | CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); | ||
1549 | } | ||
1550 | |||
1551 | static unsigned long tegra20_cdev_recalc_rate(struct clk_hw *hw, | ||
1552 | unsigned long prate) | ||
1553 | { | ||
1554 | return to_clk_tegra(hw)->fixed_rate; | ||
1555 | } | ||
1556 | |||
1557 | struct clk_ops tegra_cdev_clk_ops = { | ||
1558 | .is_enabled = tegra20_cdev_clk_is_enabled, | ||
1559 | .enable = tegra20_cdev_clk_enable, | ||
1560 | .disable = tegra20_cdev_clk_disable, | ||
1561 | .recalc_rate = tegra20_cdev_recalc_rate, | ||
1562 | }; | ||
1563 | |||
1564 | /* Tegra20 CPU clock and reset control functions */ | ||
1565 | static void tegra20_wait_cpu_in_reset(u32 cpu) | ||
1566 | { | ||
1567 | unsigned int reg; | ||
1568 | |||
1569 | do { | ||
1570 | reg = readl(reg_clk_base + | ||
1571 | TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
1572 | cpu_relax(); | ||
1573 | } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ | ||
1574 | |||
1575 | return; | ||
1576 | } | ||
1577 | |||
1578 | static void tegra20_put_cpu_in_reset(u32 cpu) | ||
1579 | { | ||
1580 | writel(CPU_RESET(cpu), | ||
1581 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
1582 | dmb(); | ||
1583 | } | ||
1584 | |||
1585 | static void tegra20_cpu_out_of_reset(u32 cpu) | ||
1586 | { | ||
1587 | writel(CPU_RESET(cpu), | ||
1588 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); | ||
1589 | wmb(); | ||
1590 | } | ||
1591 | |||
1592 | static void tegra20_enable_cpu_clock(u32 cpu) | ||
1593 | { | ||
1594 | unsigned int reg; | ||
1595 | |||
1596 | reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1597 | writel(reg & ~CPU_CLOCK(cpu), | ||
1598 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1599 | barrier(); | ||
1600 | reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1601 | } | ||
1602 | |||
1603 | static void tegra20_disable_cpu_clock(u32 cpu) | ||
1604 | { | ||
1605 | unsigned int reg; | ||
1606 | |||
1607 | reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1608 | writel(reg | CPU_CLOCK(cpu), | ||
1609 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1610 | } | ||
1611 | |||
1612 | static struct tegra_cpu_car_ops tegra20_cpu_car_ops = { | ||
1613 | .wait_for_reset = tegra20_wait_cpu_in_reset, | ||
1614 | .put_in_reset = tegra20_put_cpu_in_reset, | ||
1615 | .out_of_reset = tegra20_cpu_out_of_reset, | ||
1616 | .enable_clock = tegra20_enable_cpu_clock, | ||
1617 | .disable_clock = tegra20_disable_cpu_clock, | ||
1618 | }; | ||
1619 | |||
1620 | void __init tegra20_cpu_car_ops_init(void) | ||
1621 | { | ||
1622 | tegra_cpu_car_ops = &tegra20_cpu_car_ops; | ||
1623 | } | ||
diff --git a/arch/arm/mach-tegra/tegra20_clocks.h b/arch/arm/mach-tegra/tegra20_clocks.h deleted file mode 100644 index 8bfd31bcc490..000000000000 --- a/arch/arm/mach-tegra/tegra20_clocks.h +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __MACH_TEGRA20_CLOCK_H | ||
18 | #define __MACH_TEGRA20_CLOCK_H | ||
19 | |||
20 | extern struct clk_ops tegra_clk_32k_ops; | ||
21 | extern struct clk_ops tegra_pll_ops; | ||
22 | extern struct clk_ops tegra_clk_m_ops; | ||
23 | extern struct clk_ops tegra_pll_div_ops; | ||
24 | extern struct clk_ops tegra_pllx_ops; | ||
25 | extern struct clk_ops tegra_plle_ops; | ||
26 | extern struct clk_ops tegra_clk_double_ops; | ||
27 | extern struct clk_ops tegra_cdev_clk_ops; | ||
28 | extern struct clk_ops tegra_audio_sync_clk_ops; | ||
29 | extern struct clk_ops tegra_super_ops; | ||
30 | extern struct clk_ops tegra_cpu_ops; | ||
31 | extern struct clk_ops tegra_twd_ops; | ||
32 | extern struct clk_ops tegra_cop_ops; | ||
33 | extern struct clk_ops tegra_bus_ops; | ||
34 | extern struct clk_ops tegra_blink_clk_ops; | ||
35 | extern struct clk_ops tegra_emc_clk_ops; | ||
36 | extern struct clk_ops tegra_periph_clk_ops; | ||
37 | extern struct clk_ops tegra_clk_shared_bus_ops; | ||
38 | |||
39 | void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert); | ||
40 | void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert); | ||
41 | |||
42 | #endif | ||
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c b/arch/arm/mach-tegra/tegra20_clocks_data.c deleted file mode 100644 index a23a0734e352..000000000000 --- a/arch/arm/mach-tegra/tegra20_clocks_data.c +++ /dev/null | |||
@@ -1,1143 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/tegra2_clocks.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved. | ||
6 | * | ||
7 | * Author: | ||
8 | * Colin Cross <ccross@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/clk-private.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/list.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/clk.h> | ||
29 | |||
30 | #include "clock.h" | ||
31 | #include "fuse.h" | ||
32 | #include "tegra2_emc.h" | ||
33 | #include "tegra20_clocks.h" | ||
34 | #include "tegra_cpu_car.h" | ||
35 | |||
36 | /* Clock definitions */ | ||
37 | |||
38 | #define DEFINE_CLK_TEGRA(_name, _rate, _ops, _flags, \ | ||
39 | _parent_names, _parents, _parent) \ | ||
40 | static struct clk tegra_##_name = { \ | ||
41 | .hw = &tegra_##_name##_hw.hw, \ | ||
42 | .name = #_name, \ | ||
43 | .rate = _rate, \ | ||
44 | .ops = _ops, \ | ||
45 | .flags = _flags, \ | ||
46 | .parent_names = _parent_names, \ | ||
47 | .parents = _parents, \ | ||
48 | .num_parents = ARRAY_SIZE(_parent_names), \ | ||
49 | .parent = _parent, \ | ||
50 | }; | ||
51 | |||
52 | static struct clk tegra_clk_32k; | ||
53 | static struct clk_tegra tegra_clk_32k_hw = { | ||
54 | .hw = { | ||
55 | .clk = &tegra_clk_32k, | ||
56 | }, | ||
57 | .fixed_rate = 32768, | ||
58 | }; | ||
59 | |||
60 | static struct clk tegra_clk_32k = { | ||
61 | .name = "clk_32k", | ||
62 | .rate = 32768, | ||
63 | .ops = &tegra_clk_32k_ops, | ||
64 | .hw = &tegra_clk_32k_hw.hw, | ||
65 | .flags = CLK_IS_ROOT, | ||
66 | }; | ||
67 | |||
68 | static struct clk tegra_clk_m; | ||
69 | static struct clk_tegra tegra_clk_m_hw = { | ||
70 | .hw = { | ||
71 | .clk = &tegra_clk_m, | ||
72 | }, | ||
73 | .flags = ENABLE_ON_INIT, | ||
74 | .reg = 0x1fc, | ||
75 | .reg_shift = 28, | ||
76 | .max_rate = 26000000, | ||
77 | .fixed_rate = 0, | ||
78 | }; | ||
79 | |||
80 | static struct clk tegra_clk_m = { | ||
81 | .name = "clk_m", | ||
82 | .ops = &tegra_clk_m_ops, | ||
83 | .hw = &tegra_clk_m_hw.hw, | ||
84 | .flags = CLK_IS_ROOT, | ||
85 | }; | ||
86 | |||
87 | #define DEFINE_PLL(_name, _flags, _reg, _max_rate, _input_min, \ | ||
88 | _input_max, _cf_min, _cf_max, _vco_min, \ | ||
89 | _vco_max, _freq_table, _lock_delay, _ops, \ | ||
90 | _fixed_rate, _parent) \ | ||
91 | static const char *tegra_##_name##_parent_names[] = { \ | ||
92 | #_parent, \ | ||
93 | }; \ | ||
94 | static struct clk *tegra_##_name##_parents[] = { \ | ||
95 | &tegra_##_parent, \ | ||
96 | }; \ | ||
97 | static struct clk tegra_##_name; \ | ||
98 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
99 | .hw = { \ | ||
100 | .clk = &tegra_##_name, \ | ||
101 | }, \ | ||
102 | .flags = _flags, \ | ||
103 | .reg = _reg, \ | ||
104 | .max_rate = _max_rate, \ | ||
105 | .u.pll = { \ | ||
106 | .input_min = _input_min, \ | ||
107 | .input_max = _input_max, \ | ||
108 | .cf_min = _cf_min, \ | ||
109 | .cf_max = _cf_max, \ | ||
110 | .vco_min = _vco_min, \ | ||
111 | .vco_max = _vco_max, \ | ||
112 | .freq_table = _freq_table, \ | ||
113 | .lock_delay = _lock_delay, \ | ||
114 | .fixed_rate = _fixed_rate, \ | ||
115 | }, \ | ||
116 | }; \ | ||
117 | static struct clk tegra_##_name = { \ | ||
118 | .name = #_name, \ | ||
119 | .ops = &_ops, \ | ||
120 | .hw = &tegra_##_name##_hw.hw, \ | ||
121 | .parent = &tegra_##_parent, \ | ||
122 | .parent_names = tegra_##_name##_parent_names, \ | ||
123 | .parents = tegra_##_name##_parents, \ | ||
124 | .num_parents = 1, \ | ||
125 | }; | ||
126 | |||
127 | #define DEFINE_PLL_OUT(_name, _flags, _reg, _reg_shift, \ | ||
128 | _max_rate, _ops, _parent, _clk_flags) \ | ||
129 | static const char *tegra_##_name##_parent_names[] = { \ | ||
130 | #_parent, \ | ||
131 | }; \ | ||
132 | static struct clk *tegra_##_name##_parents[] = { \ | ||
133 | &tegra_##_parent, \ | ||
134 | }; \ | ||
135 | static struct clk tegra_##_name; \ | ||
136 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
137 | .hw = { \ | ||
138 | .clk = &tegra_##_name, \ | ||
139 | }, \ | ||
140 | .flags = _flags, \ | ||
141 | .reg = _reg, \ | ||
142 | .max_rate = _max_rate, \ | ||
143 | .reg_shift = _reg_shift, \ | ||
144 | }; \ | ||
145 | static struct clk tegra_##_name = { \ | ||
146 | .name = #_name, \ | ||
147 | .ops = &tegra_pll_div_ops, \ | ||
148 | .hw = &tegra_##_name##_hw.hw, \ | ||
149 | .parent = &tegra_##_parent, \ | ||
150 | .parent_names = tegra_##_name##_parent_names, \ | ||
151 | .parents = tegra_##_name##_parents, \ | ||
152 | .num_parents = 1, \ | ||
153 | .flags = _clk_flags, \ | ||
154 | }; | ||
155 | |||
156 | |||
157 | static struct clk_pll_freq_table tegra_pll_s_freq_table[] = { | ||
158 | {32768, 12000000, 366, 1, 1, 0}, | ||
159 | {32768, 13000000, 397, 1, 1, 0}, | ||
160 | {32768, 19200000, 586, 1, 1, 0}, | ||
161 | {32768, 26000000, 793, 1, 1, 0}, | ||
162 | {0, 0, 0, 0, 0, 0}, | ||
163 | }; | ||
164 | |||
165 | DEFINE_PLL(pll_s, PLL_ALT_MISC_REG, 0xf0, 26000000, 32768, 32768, 0, | ||
166 | 0, 12000000, 26000000, tegra_pll_s_freq_table, 300, | ||
167 | tegra_pll_ops, 0, clk_32k); | ||
168 | |||
169 | static struct clk_pll_freq_table tegra_pll_c_freq_table[] = { | ||
170 | { 12000000, 600000000, 600, 12, 1, 8 }, | ||
171 | { 13000000, 600000000, 600, 13, 1, 8 }, | ||
172 | { 19200000, 600000000, 500, 16, 1, 6 }, | ||
173 | { 26000000, 600000000, 600, 26, 1, 8 }, | ||
174 | { 0, 0, 0, 0, 0, 0 }, | ||
175 | }; | ||
176 | |||
177 | DEFINE_PLL(pll_c, PLL_HAS_CPCON, 0x80, 600000000, 2000000, 31000000, 1000000, | ||
178 | 6000000, 20000000, 1400000000, tegra_pll_c_freq_table, 300, | ||
179 | tegra_pll_ops, 0, clk_m); | ||
180 | |||
181 | DEFINE_PLL_OUT(pll_c_out1, DIV_U71, 0x84, 0, 600000000, | ||
182 | tegra_pll_div_ops, pll_c, 0); | ||
183 | |||
184 | static struct clk_pll_freq_table tegra_pll_m_freq_table[] = { | ||
185 | { 12000000, 666000000, 666, 12, 1, 8}, | ||
186 | { 13000000, 666000000, 666, 13, 1, 8}, | ||
187 | { 19200000, 666000000, 555, 16, 1, 8}, | ||
188 | { 26000000, 666000000, 666, 26, 1, 8}, | ||
189 | { 12000000, 600000000, 600, 12, 1, 8}, | ||
190 | { 13000000, 600000000, 600, 13, 1, 8}, | ||
191 | { 19200000, 600000000, 375, 12, 1, 6}, | ||
192 | { 26000000, 600000000, 600, 26, 1, 8}, | ||
193 | { 0, 0, 0, 0, 0, 0 }, | ||
194 | }; | ||
195 | |||
196 | DEFINE_PLL(pll_m, PLL_HAS_CPCON, 0x90, 800000000, 2000000, 31000000, 1000000, | ||
197 | 6000000, 20000000, 1200000000, tegra_pll_m_freq_table, 300, | ||
198 | tegra_pll_ops, 0, clk_m); | ||
199 | |||
200 | DEFINE_PLL_OUT(pll_m_out1, DIV_U71, 0x94, 0, 600000000, | ||
201 | tegra_pll_div_ops, pll_m, 0); | ||
202 | |||
203 | static struct clk_pll_freq_table tegra_pll_p_freq_table[] = { | ||
204 | { 12000000, 216000000, 432, 12, 2, 8}, | ||
205 | { 13000000, 216000000, 432, 13, 2, 8}, | ||
206 | { 19200000, 216000000, 90, 4, 2, 1}, | ||
207 | { 26000000, 216000000, 432, 26, 2, 8}, | ||
208 | { 12000000, 432000000, 432, 12, 1, 8}, | ||
209 | { 13000000, 432000000, 432, 13, 1, 8}, | ||
210 | { 19200000, 432000000, 90, 4, 1, 1}, | ||
211 | { 26000000, 432000000, 432, 26, 1, 8}, | ||
212 | { 0, 0, 0, 0, 0, 0 }, | ||
213 | }; | ||
214 | |||
215 | |||
216 | DEFINE_PLL(pll_p, ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, 0xa0, 432000000, | ||
217 | 2000000, 31000000, 1000000, 6000000, 20000000, 1400000000, | ||
218 | tegra_pll_p_freq_table, 300, tegra_pll_ops, 216000000, clk_m); | ||
219 | |||
220 | DEFINE_PLL_OUT(pll_p_out1, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, 0, | ||
221 | 432000000, tegra_pll_div_ops, pll_p, 0); | ||
222 | DEFINE_PLL_OUT(pll_p_out2, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, 16, | ||
223 | 432000000, tegra_pll_div_ops, pll_p, 0); | ||
224 | DEFINE_PLL_OUT(pll_p_out3, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, 0, | ||
225 | 432000000, tegra_pll_div_ops, pll_p, 0); | ||
226 | DEFINE_PLL_OUT(pll_p_out4, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, 16, | ||
227 | 432000000, tegra_pll_div_ops, pll_p, 0); | ||
228 | |||
229 | static struct clk_pll_freq_table tegra_pll_a_freq_table[] = { | ||
230 | { 28800000, 56448000, 49, 25, 1, 1}, | ||
231 | { 28800000, 73728000, 64, 25, 1, 1}, | ||
232 | { 28800000, 24000000, 5, 6, 1, 1}, | ||
233 | { 0, 0, 0, 0, 0, 0 }, | ||
234 | }; | ||
235 | |||
236 | DEFINE_PLL(pll_a, PLL_HAS_CPCON, 0xb0, 73728000, 2000000, 31000000, 1000000, | ||
237 | 6000000, 20000000, 1400000000, tegra_pll_a_freq_table, 300, | ||
238 | tegra_pll_ops, 0, pll_p_out1); | ||
239 | |||
240 | DEFINE_PLL_OUT(pll_a_out0, DIV_U71, 0xb4, 0, 73728000, | ||
241 | tegra_pll_div_ops, pll_a, 0); | ||
242 | |||
243 | static struct clk_pll_freq_table tegra_pll_d_freq_table[] = { | ||
244 | { 12000000, 216000000, 216, 12, 1, 4}, | ||
245 | { 13000000, 216000000, 216, 13, 1, 4}, | ||
246 | { 19200000, 216000000, 135, 12, 1, 3}, | ||
247 | { 26000000, 216000000, 216, 26, 1, 4}, | ||
248 | |||
249 | { 12000000, 297000000, 99, 4, 1, 4 }, | ||
250 | { 12000000, 339000000, 113, 4, 1, 4 }, | ||
251 | |||
252 | { 12000000, 594000000, 594, 12, 1, 8}, | ||
253 | { 13000000, 594000000, 594, 13, 1, 8}, | ||
254 | { 19200000, 594000000, 495, 16, 1, 8}, | ||
255 | { 26000000, 594000000, 594, 26, 1, 8}, | ||
256 | |||
257 | { 12000000, 616000000, 616, 12, 1, 8}, | ||
258 | |||
259 | { 12000000, 1000000000, 1000, 12, 1, 12}, | ||
260 | { 13000000, 1000000000, 1000, 13, 1, 12}, | ||
261 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
262 | { 26000000, 1000000000, 1000, 26, 1, 12}, | ||
263 | |||
264 | { 0, 0, 0, 0, 0, 0 }, | ||
265 | }; | ||
266 | |||
267 | DEFINE_PLL(pll_d, PLL_HAS_CPCON | PLLD, 0xd0, 1000000000, 2000000, 40000000, | ||
268 | 1000000, 6000000, 40000000, 1000000000, tegra_pll_d_freq_table, | ||
269 | 1000, tegra_pll_ops, 0, clk_m); | ||
270 | |||
271 | DEFINE_PLL_OUT(pll_d_out0, DIV_2 | PLLD, 0, 0, 500000000, | ||
272 | tegra_pll_div_ops, pll_d, CLK_SET_RATE_PARENT); | ||
273 | |||
274 | static struct clk_pll_freq_table tegra_pll_u_freq_table[] = { | ||
275 | { 12000000, 480000000, 960, 12, 2, 0}, | ||
276 | { 13000000, 480000000, 960, 13, 2, 0}, | ||
277 | { 19200000, 480000000, 200, 4, 2, 0}, | ||
278 | { 26000000, 480000000, 960, 26, 2, 0}, | ||
279 | { 0, 0, 0, 0, 0, 0 }, | ||
280 | }; | ||
281 | |||
282 | DEFINE_PLL(pll_u, PLLU, 0xc0, 480000000, 2000000, 40000000, 1000000, 6000000, | ||
283 | 48000000, 960000000, tegra_pll_u_freq_table, 1000, | ||
284 | tegra_pll_ops, 0, clk_m); | ||
285 | |||
286 | static struct clk_pll_freq_table tegra_pll_x_freq_table[] = { | ||
287 | /* 1 GHz */ | ||
288 | { 12000000, 1000000000, 1000, 12, 1, 12}, | ||
289 | { 13000000, 1000000000, 1000, 13, 1, 12}, | ||
290 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
291 | { 26000000, 1000000000, 1000, 26, 1, 12}, | ||
292 | |||
293 | /* 912 MHz */ | ||
294 | { 12000000, 912000000, 912, 12, 1, 12}, | ||
295 | { 13000000, 912000000, 912, 13, 1, 12}, | ||
296 | { 19200000, 912000000, 760, 16, 1, 8}, | ||
297 | { 26000000, 912000000, 912, 26, 1, 12}, | ||
298 | |||
299 | /* 816 MHz */ | ||
300 | { 12000000, 816000000, 816, 12, 1, 12}, | ||
301 | { 13000000, 816000000, 816, 13, 1, 12}, | ||
302 | { 19200000, 816000000, 680, 16, 1, 8}, | ||
303 | { 26000000, 816000000, 816, 26, 1, 12}, | ||
304 | |||
305 | /* 760 MHz */ | ||
306 | { 12000000, 760000000, 760, 12, 1, 12}, | ||
307 | { 13000000, 760000000, 760, 13, 1, 12}, | ||
308 | { 19200000, 760000000, 950, 24, 1, 8}, | ||
309 | { 26000000, 760000000, 760, 26, 1, 12}, | ||
310 | |||
311 | /* 750 MHz */ | ||
312 | { 12000000, 750000000, 750, 12, 1, 12}, | ||
313 | { 13000000, 750000000, 750, 13, 1, 12}, | ||
314 | { 19200000, 750000000, 625, 16, 1, 8}, | ||
315 | { 26000000, 750000000, 750, 26, 1, 12}, | ||
316 | |||
317 | /* 608 MHz */ | ||
318 | { 12000000, 608000000, 608, 12, 1, 12}, | ||
319 | { 13000000, 608000000, 608, 13, 1, 12}, | ||
320 | { 19200000, 608000000, 380, 12, 1, 8}, | ||
321 | { 26000000, 608000000, 608, 26, 1, 12}, | ||
322 | |||
323 | /* 456 MHz */ | ||
324 | { 12000000, 456000000, 456, 12, 1, 12}, | ||
325 | { 13000000, 456000000, 456, 13, 1, 12}, | ||
326 | { 19200000, 456000000, 380, 16, 1, 8}, | ||
327 | { 26000000, 456000000, 456, 26, 1, 12}, | ||
328 | |||
329 | /* 312 MHz */ | ||
330 | { 12000000, 312000000, 312, 12, 1, 12}, | ||
331 | { 13000000, 312000000, 312, 13, 1, 12}, | ||
332 | { 19200000, 312000000, 260, 16, 1, 8}, | ||
333 | { 26000000, 312000000, 312, 26, 1, 12}, | ||
334 | |||
335 | { 0, 0, 0, 0, 0, 0 }, | ||
336 | }; | ||
337 | |||
338 | DEFINE_PLL(pll_x, PLL_HAS_CPCON | PLL_ALT_MISC_REG, 0xe0, 1000000000, 2000000, | ||
339 | 31000000, 1000000, 6000000, 20000000, 1200000000, | ||
340 | tegra_pll_x_freq_table, 300, tegra_pllx_ops, 0, clk_m); | ||
341 | |||
342 | static struct clk_pll_freq_table tegra_pll_e_freq_table[] = { | ||
343 | { 12000000, 100000000, 200, 24, 1, 0 }, | ||
344 | { 0, 0, 0, 0, 0, 0 }, | ||
345 | }; | ||
346 | |||
347 | DEFINE_PLL(pll_e, PLL_ALT_MISC_REG, 0xe8, 100000000, 12000000, 12000000, 0, 0, | ||
348 | 0, 0, tegra_pll_e_freq_table, 0, tegra_plle_ops, 0, clk_m); | ||
349 | |||
350 | static const char *tegra_common_parent_names[] = { | ||
351 | "clk_m", | ||
352 | }; | ||
353 | |||
354 | static struct clk *tegra_common_parents[] = { | ||
355 | &tegra_clk_m, | ||
356 | }; | ||
357 | |||
358 | static struct clk tegra_clk_d; | ||
359 | static struct clk_tegra tegra_clk_d_hw = { | ||
360 | .hw = { | ||
361 | .clk = &tegra_clk_d, | ||
362 | }, | ||
363 | .flags = PERIPH_NO_RESET, | ||
364 | .reg = 0x34, | ||
365 | .reg_shift = 12, | ||
366 | .max_rate = 52000000, | ||
367 | .u.periph = { | ||
368 | .clk_num = 90, | ||
369 | }, | ||
370 | }; | ||
371 | |||
372 | static struct clk tegra_clk_d = { | ||
373 | .name = "clk_d", | ||
374 | .hw = &tegra_clk_d_hw.hw, | ||
375 | .ops = &tegra_clk_double_ops, | ||
376 | .parent = &tegra_clk_m, | ||
377 | .parent_names = tegra_common_parent_names, | ||
378 | .parents = tegra_common_parents, | ||
379 | .num_parents = ARRAY_SIZE(tegra_common_parent_names), | ||
380 | }; | ||
381 | |||
382 | static struct clk tegra_cdev1; | ||
383 | static struct clk_tegra tegra_cdev1_hw = { | ||
384 | .hw = { | ||
385 | .clk = &tegra_cdev1, | ||
386 | }, | ||
387 | .fixed_rate = 26000000, | ||
388 | .u.periph = { | ||
389 | .clk_num = 94, | ||
390 | }, | ||
391 | }; | ||
392 | static struct clk tegra_cdev1 = { | ||
393 | .name = "cdev1", | ||
394 | .hw = &tegra_cdev1_hw.hw, | ||
395 | .ops = &tegra_cdev_clk_ops, | ||
396 | .flags = CLK_IS_ROOT, | ||
397 | }; | ||
398 | |||
399 | /* dap_mclk2, belongs to the cdev2 pingroup. */ | ||
400 | static struct clk tegra_cdev2; | ||
401 | static struct clk_tegra tegra_cdev2_hw = { | ||
402 | .hw = { | ||
403 | .clk = &tegra_cdev2, | ||
404 | }, | ||
405 | .fixed_rate = 26000000, | ||
406 | .u.periph = { | ||
407 | .clk_num = 93, | ||
408 | }, | ||
409 | }; | ||
410 | static struct clk tegra_cdev2 = { | ||
411 | .name = "cdev2", | ||
412 | .hw = &tegra_cdev2_hw.hw, | ||
413 | .ops = &tegra_cdev_clk_ops, | ||
414 | .flags = CLK_IS_ROOT, | ||
415 | }; | ||
416 | |||
417 | /* initialized before peripheral clocks */ | ||
418 | static struct clk_mux_sel mux_audio_sync_clk[8+1]; | ||
419 | static const struct audio_sources { | ||
420 | const char *name; | ||
421 | int value; | ||
422 | } mux_audio_sync_clk_sources[] = { | ||
423 | { .name = "spdif_in", .value = 0 }, | ||
424 | { .name = "i2s1", .value = 1 }, | ||
425 | { .name = "i2s2", .value = 2 }, | ||
426 | { .name = "pll_a_out0", .value = 4 }, | ||
427 | #if 0 /* FIXME: not implemented */ | ||
428 | { .name = "ac97", .value = 3 }, | ||
429 | { .name = "ext_audio_clk2", .value = 5 }, | ||
430 | { .name = "ext_audio_clk1", .value = 6 }, | ||
431 | { .name = "ext_vimclk", .value = 7 }, | ||
432 | #endif | ||
433 | { NULL, 0 } | ||
434 | }; | ||
435 | |||
436 | static const char *audio_parent_names[] = { | ||
437 | "spdif_in", | ||
438 | "i2s1", | ||
439 | "i2s2", | ||
440 | "dummy", | ||
441 | "pll_a_out0", | ||
442 | "dummy", | ||
443 | "dummy", | ||
444 | "dummy", | ||
445 | }; | ||
446 | |||
447 | static struct clk *audio_parents[] = { | ||
448 | NULL, | ||
449 | NULL, | ||
450 | NULL, | ||
451 | NULL, | ||
452 | NULL, | ||
453 | NULL, | ||
454 | NULL, | ||
455 | NULL, | ||
456 | }; | ||
457 | |||
458 | static struct clk tegra_audio; | ||
459 | static struct clk_tegra tegra_audio_hw = { | ||
460 | .hw = { | ||
461 | .clk = &tegra_audio, | ||
462 | }, | ||
463 | .reg = 0x38, | ||
464 | .max_rate = 73728000, | ||
465 | }; | ||
466 | DEFINE_CLK_TEGRA(audio, 0, &tegra_audio_sync_clk_ops, 0, audio_parent_names, | ||
467 | audio_parents, NULL); | ||
468 | |||
469 | static const char *audio_2x_parent_names[] = { | ||
470 | "audio", | ||
471 | }; | ||
472 | |||
473 | static struct clk *audio_2x_parents[] = { | ||
474 | &tegra_audio, | ||
475 | }; | ||
476 | |||
477 | static struct clk tegra_audio_2x; | ||
478 | static struct clk_tegra tegra_audio_2x_hw = { | ||
479 | .hw = { | ||
480 | .clk = &tegra_audio_2x, | ||
481 | }, | ||
482 | .flags = PERIPH_NO_RESET, | ||
483 | .max_rate = 48000000, | ||
484 | .reg = 0x34, | ||
485 | .reg_shift = 8, | ||
486 | .u.periph = { | ||
487 | .clk_num = 89, | ||
488 | }, | ||
489 | }; | ||
490 | DEFINE_CLK_TEGRA(audio_2x, 0, &tegra_clk_double_ops, 0, audio_2x_parent_names, | ||
491 | audio_2x_parents, &tegra_audio); | ||
492 | |||
493 | static struct clk_lookup tegra_audio_clk_lookups[] = { | ||
494 | { .con_id = "audio", .clk = &tegra_audio }, | ||
495 | { .con_id = "audio_2x", .clk = &tegra_audio_2x } | ||
496 | }; | ||
497 | |||
498 | /* This is called after peripheral clocks are initialized, as the | ||
499 | * audio_sync clock depends on some of the peripheral clocks. | ||
500 | */ | ||
501 | |||
502 | static void init_audio_sync_clock_mux(void) | ||
503 | { | ||
504 | int i; | ||
505 | struct clk_mux_sel *sel = mux_audio_sync_clk; | ||
506 | const struct audio_sources *src = mux_audio_sync_clk_sources; | ||
507 | struct clk_lookup *lookup; | ||
508 | |||
509 | for (i = 0; src->name; i++, sel++, src++) { | ||
510 | sel->input = tegra_get_clock_by_name(src->name); | ||
511 | if (!sel->input) | ||
512 | pr_err("%s: could not find clk %s\n", __func__, | ||
513 | src->name); | ||
514 | audio_parents[src->value] = sel->input; | ||
515 | sel->value = src->value; | ||
516 | } | ||
517 | |||
518 | lookup = tegra_audio_clk_lookups; | ||
519 | for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) { | ||
520 | struct clk *c = lookup->clk; | ||
521 | struct clk_tegra *clk = to_clk_tegra(c->hw); | ||
522 | __clk_init(NULL, c); | ||
523 | INIT_LIST_HEAD(&clk->shared_bus_list); | ||
524 | clk->lookup.con_id = lookup->con_id; | ||
525 | clk->lookup.clk = c; | ||
526 | clkdev_add(&clk->lookup); | ||
527 | tegra_clk_add(c); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | static const char *mux_cclk[] = { | ||
532 | "clk_m", | ||
533 | "pll_c", | ||
534 | "clk_32k", | ||
535 | "pll_m", | ||
536 | "pll_p", | ||
537 | "pll_p_out4", | ||
538 | "pll_p_out3", | ||
539 | "clk_d", | ||
540 | "pll_x", | ||
541 | }; | ||
542 | |||
543 | |||
544 | static struct clk *mux_cclk_p[] = { | ||
545 | &tegra_clk_m, | ||
546 | &tegra_pll_c, | ||
547 | &tegra_clk_32k, | ||
548 | &tegra_pll_m, | ||
549 | &tegra_pll_p, | ||
550 | &tegra_pll_p_out4, | ||
551 | &tegra_pll_p_out3, | ||
552 | &tegra_clk_d, | ||
553 | &tegra_pll_x, | ||
554 | }; | ||
555 | |||
556 | static const char *mux_sclk[] = { | ||
557 | "clk_m", | ||
558 | "pll_c_out1", | ||
559 | "pll_p_out4", | ||
560 | "pllp_p_out3", | ||
561 | "pll_p_out2", | ||
562 | "clk_d", | ||
563 | "clk_32k", | ||
564 | "pll_m_out1", | ||
565 | }; | ||
566 | |||
567 | static struct clk *mux_sclk_p[] = { | ||
568 | &tegra_clk_m, | ||
569 | &tegra_pll_c_out1, | ||
570 | &tegra_pll_p_out4, | ||
571 | &tegra_pll_p_out3, | ||
572 | &tegra_pll_p_out2, | ||
573 | &tegra_clk_d, | ||
574 | &tegra_clk_32k, | ||
575 | &tegra_pll_m_out1, | ||
576 | }; | ||
577 | |||
578 | static struct clk tegra_cclk; | ||
579 | static struct clk_tegra tegra_cclk_hw = { | ||
580 | .hw = { | ||
581 | .clk = &tegra_cclk, | ||
582 | }, | ||
583 | .reg = 0x20, | ||
584 | .max_rate = 1000000000, | ||
585 | }; | ||
586 | DEFINE_CLK_TEGRA(cclk, 0, &tegra_super_ops, 0, mux_cclk, | ||
587 | mux_cclk_p, NULL); | ||
588 | |||
589 | static const char *mux_twd[] = { | ||
590 | "cclk", | ||
591 | }; | ||
592 | |||
593 | static struct clk *mux_twd_p[] = { | ||
594 | &tegra_cclk, | ||
595 | }; | ||
596 | |||
597 | static struct clk tegra_clk_twd; | ||
598 | static struct clk_tegra tegra_clk_twd_hw = { | ||
599 | .hw = { | ||
600 | .clk = &tegra_clk_twd, | ||
601 | }, | ||
602 | .max_rate = 1000000000, | ||
603 | .mul = 1, | ||
604 | .div = 4, | ||
605 | }; | ||
606 | |||
607 | static struct clk tegra_clk_twd = { | ||
608 | .name = "twd", | ||
609 | .ops = &tegra_twd_ops, | ||
610 | .hw = &tegra_clk_twd_hw.hw, | ||
611 | .parent = &tegra_cclk, | ||
612 | .parent_names = mux_twd, | ||
613 | .parents = mux_twd_p, | ||
614 | .num_parents = ARRAY_SIZE(mux_twd), | ||
615 | }; | ||
616 | |||
617 | static struct clk tegra_sclk; | ||
618 | static struct clk_tegra tegra_sclk_hw = { | ||
619 | .hw = { | ||
620 | .clk = &tegra_sclk, | ||
621 | }, | ||
622 | .reg = 0x28, | ||
623 | .max_rate = 240000000, | ||
624 | .min_rate = 120000000, | ||
625 | }; | ||
626 | DEFINE_CLK_TEGRA(sclk, 0, &tegra_super_ops, 0, mux_sclk, | ||
627 | mux_sclk_p, NULL); | ||
628 | |||
629 | static const char *tegra_cop_parent_names[] = { | ||
630 | "tegra_sclk", | ||
631 | }; | ||
632 | |||
633 | static struct clk *tegra_cop_parents[] = { | ||
634 | &tegra_sclk, | ||
635 | }; | ||
636 | |||
637 | static struct clk tegra_cop; | ||
638 | static struct clk_tegra tegra_cop_hw = { | ||
639 | .hw = { | ||
640 | .clk = &tegra_cop, | ||
641 | }, | ||
642 | .max_rate = 240000000, | ||
643 | .reset = &tegra2_cop_clk_reset, | ||
644 | }; | ||
645 | DEFINE_CLK_TEGRA(cop, 0, &tegra_cop_ops, CLK_SET_RATE_PARENT, | ||
646 | tegra_cop_parent_names, tegra_cop_parents, &tegra_sclk); | ||
647 | |||
648 | static const char *tegra_hclk_parent_names[] = { | ||
649 | "tegra_sclk", | ||
650 | }; | ||
651 | |||
652 | static struct clk *tegra_hclk_parents[] = { | ||
653 | &tegra_sclk, | ||
654 | }; | ||
655 | |||
656 | static struct clk tegra_hclk; | ||
657 | static struct clk_tegra tegra_hclk_hw = { | ||
658 | .hw = { | ||
659 | .clk = &tegra_hclk, | ||
660 | }, | ||
661 | .flags = DIV_BUS, | ||
662 | .reg = 0x30, | ||
663 | .reg_shift = 4, | ||
664 | .max_rate = 240000000, | ||
665 | }; | ||
666 | DEFINE_CLK_TEGRA(hclk, 0, &tegra_bus_ops, 0, tegra_hclk_parent_names, | ||
667 | tegra_hclk_parents, &tegra_sclk); | ||
668 | |||
669 | static const char *tegra_pclk_parent_names[] = { | ||
670 | "tegra_hclk", | ||
671 | }; | ||
672 | |||
673 | static struct clk *tegra_pclk_parents[] = { | ||
674 | &tegra_hclk, | ||
675 | }; | ||
676 | |||
677 | static struct clk tegra_pclk; | ||
678 | static struct clk_tegra tegra_pclk_hw = { | ||
679 | .hw = { | ||
680 | .clk = &tegra_pclk, | ||
681 | }, | ||
682 | .flags = DIV_BUS, | ||
683 | .reg = 0x30, | ||
684 | .reg_shift = 0, | ||
685 | .max_rate = 120000000, | ||
686 | }; | ||
687 | DEFINE_CLK_TEGRA(pclk, 0, &tegra_bus_ops, 0, tegra_pclk_parent_names, | ||
688 | tegra_pclk_parents, &tegra_hclk); | ||
689 | |||
690 | static const char *tegra_blink_parent_names[] = { | ||
691 | "clk_32k", | ||
692 | }; | ||
693 | |||
694 | static struct clk *tegra_blink_parents[] = { | ||
695 | &tegra_clk_32k, | ||
696 | }; | ||
697 | |||
698 | static struct clk tegra_blink; | ||
699 | static struct clk_tegra tegra_blink_hw = { | ||
700 | .hw = { | ||
701 | .clk = &tegra_blink, | ||
702 | }, | ||
703 | .reg = 0x40, | ||
704 | .max_rate = 32768, | ||
705 | }; | ||
706 | DEFINE_CLK_TEGRA(blink, 0, &tegra_blink_clk_ops, 0, tegra_blink_parent_names, | ||
707 | tegra_blink_parents, &tegra_clk_32k); | ||
708 | |||
709 | static const char *mux_pllm_pllc_pllp_plla[] = { | ||
710 | "pll_m", | ||
711 | "pll_c", | ||
712 | "pll_p", | ||
713 | "pll_a_out0", | ||
714 | }; | ||
715 | |||
716 | static struct clk *mux_pllm_pllc_pllp_plla_p[] = { | ||
717 | &tegra_pll_m, | ||
718 | &tegra_pll_c, | ||
719 | &tegra_pll_p, | ||
720 | &tegra_pll_a_out0, | ||
721 | }; | ||
722 | |||
723 | static const char *mux_pllm_pllc_pllp_clkm[] = { | ||
724 | "pll_m", | ||
725 | "pll_c", | ||
726 | "pll_p", | ||
727 | "clk_m", | ||
728 | }; | ||
729 | |||
730 | static struct clk *mux_pllm_pllc_pllp_clkm_p[] = { | ||
731 | &tegra_pll_m, | ||
732 | &tegra_pll_c, | ||
733 | &tegra_pll_p, | ||
734 | &tegra_clk_m, | ||
735 | }; | ||
736 | |||
737 | static const char *mux_pllp_pllc_pllm_clkm[] = { | ||
738 | "pll_p", | ||
739 | "pll_c", | ||
740 | "pll_m", | ||
741 | "clk_m", | ||
742 | }; | ||
743 | |||
744 | static struct clk *mux_pllp_pllc_pllm_clkm_p[] = { | ||
745 | &tegra_pll_p, | ||
746 | &tegra_pll_c, | ||
747 | &tegra_pll_m, | ||
748 | &tegra_clk_m, | ||
749 | }; | ||
750 | |||
751 | static const char *mux_pllaout0_audio2x_pllp_clkm[] = { | ||
752 | "pll_a_out0", | ||
753 | "audio_2x", | ||
754 | "pll_p", | ||
755 | "clk_m", | ||
756 | }; | ||
757 | |||
758 | static struct clk *mux_pllaout0_audio2x_pllp_clkm_p[] = { | ||
759 | &tegra_pll_a_out0, | ||
760 | &tegra_audio_2x, | ||
761 | &tegra_pll_p, | ||
762 | &tegra_clk_m, | ||
763 | }; | ||
764 | |||
765 | static const char *mux_pllp_plld_pllc_clkm[] = { | ||
766 | "pllp", | ||
767 | "pll_d_out0", | ||
768 | "pll_c", | ||
769 | "clk_m", | ||
770 | }; | ||
771 | |||
772 | static struct clk *mux_pllp_plld_pllc_clkm_p[] = { | ||
773 | &tegra_pll_p, | ||
774 | &tegra_pll_d_out0, | ||
775 | &tegra_pll_c, | ||
776 | &tegra_clk_m, | ||
777 | }; | ||
778 | |||
779 | static const char *mux_pllp_pllc_audio_clkm_clk32[] = { | ||
780 | "pll_p", | ||
781 | "pll_c", | ||
782 | "audio", | ||
783 | "clk_m", | ||
784 | "clk_32k", | ||
785 | }; | ||
786 | |||
787 | static struct clk *mux_pllp_pllc_audio_clkm_clk32_p[] = { | ||
788 | &tegra_pll_p, | ||
789 | &tegra_pll_c, | ||
790 | &tegra_audio, | ||
791 | &tegra_clk_m, | ||
792 | &tegra_clk_32k, | ||
793 | }; | ||
794 | |||
795 | static const char *mux_pllp_pllc_pllm[] = { | ||
796 | "pll_p", | ||
797 | "pll_c", | ||
798 | "pll_m" | ||
799 | }; | ||
800 | |||
801 | static struct clk *mux_pllp_pllc_pllm_p[] = { | ||
802 | &tegra_pll_p, | ||
803 | &tegra_pll_c, | ||
804 | &tegra_pll_m, | ||
805 | }; | ||
806 | |||
807 | static const char *mux_clk_m[] = { | ||
808 | "clk_m", | ||
809 | }; | ||
810 | |||
811 | static struct clk *mux_clk_m_p[] = { | ||
812 | &tegra_clk_m, | ||
813 | }; | ||
814 | |||
815 | static const char *mux_pllp_out3[] = { | ||
816 | "pll_p_out3", | ||
817 | }; | ||
818 | |||
819 | static struct clk *mux_pllp_out3_p[] = { | ||
820 | &tegra_pll_p_out3, | ||
821 | }; | ||
822 | |||
823 | static const char *mux_plld[] = { | ||
824 | "pll_d", | ||
825 | }; | ||
826 | |||
827 | static struct clk *mux_plld_p[] = { | ||
828 | &tegra_pll_d, | ||
829 | }; | ||
830 | |||
831 | static const char *mux_clk_32k[] = { | ||
832 | "clk_32k", | ||
833 | }; | ||
834 | |||
835 | static struct clk *mux_clk_32k_p[] = { | ||
836 | &tegra_clk_32k, | ||
837 | }; | ||
838 | |||
839 | static const char *mux_pclk[] = { | ||
840 | "pclk", | ||
841 | }; | ||
842 | |||
843 | static struct clk *mux_pclk_p[] = { | ||
844 | &tegra_pclk, | ||
845 | }; | ||
846 | |||
847 | static struct clk tegra_emc; | ||
848 | static struct clk_tegra tegra_emc_hw = { | ||
849 | .hw = { | ||
850 | .clk = &tegra_emc, | ||
851 | }, | ||
852 | .reg = 0x19c, | ||
853 | .max_rate = 800000000, | ||
854 | .flags = MUX | DIV_U71 | PERIPH_EMC_ENB, | ||
855 | .reset = &tegra2_periph_clk_reset, | ||
856 | .u.periph = { | ||
857 | .clk_num = 57, | ||
858 | }, | ||
859 | }; | ||
860 | DEFINE_CLK_TEGRA(emc, 0, &tegra_emc_clk_ops, 0, mux_pllm_pllc_pllp_clkm, | ||
861 | mux_pllm_pllc_pllp_clkm_p, NULL); | ||
862 | |||
863 | #define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, \ | ||
864 | _max, _inputs, _flags) \ | ||
865 | static struct clk tegra_##_name; \ | ||
866 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
867 | .hw = { \ | ||
868 | .clk = &tegra_##_name, \ | ||
869 | }, \ | ||
870 | .lookup = { \ | ||
871 | .dev_id = _dev, \ | ||
872 | .con_id = _con, \ | ||
873 | }, \ | ||
874 | .reg = _reg, \ | ||
875 | .flags = _flags, \ | ||
876 | .max_rate = _max, \ | ||
877 | .u.periph = { \ | ||
878 | .clk_num = _clk_num, \ | ||
879 | }, \ | ||
880 | .reset = tegra2_periph_clk_reset, \ | ||
881 | }; \ | ||
882 | static struct clk tegra_##_name = { \ | ||
883 | .name = #_name, \ | ||
884 | .ops = &tegra_periph_clk_ops, \ | ||
885 | .hw = &tegra_##_name##_hw.hw, \ | ||
886 | .parent_names = _inputs, \ | ||
887 | .parents = _inputs##_p, \ | ||
888 | .num_parents = ARRAY_SIZE(_inputs), \ | ||
889 | }; | ||
890 | |||
891 | PERIPH_CLK(apbdma, "tegra-apbdma", NULL, 34, 0, 108000000, mux_pclk, 0); | ||
892 | PERIPH_CLK(rtc, "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET); | ||
893 | PERIPH_CLK(timer, "timer", NULL, 5, 0, 26000000, mux_clk_m, 0); | ||
894 | PERIPH_CLK(i2s1, "tegra20-i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71); | ||
895 | PERIPH_CLK(i2s2, "tegra20-i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71); | ||
896 | PERIPH_CLK(spdif_out, "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71); | ||
897 | PERIPH_CLK(spdif_in, "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71); | ||
898 | PERIPH_CLK(pwm, "tegra-pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71 | MUX_PWM); | ||
899 | PERIPH_CLK(spi, "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
900 | PERIPH_CLK(xio, "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
901 | PERIPH_CLK(twc, "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
902 | PERIPH_CLK(sbc1, "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
903 | PERIPH_CLK(sbc2, "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
904 | PERIPH_CLK(sbc3, "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
905 | PERIPH_CLK(sbc4, "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
906 | PERIPH_CLK(ide, "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
907 | PERIPH_CLK(ndflash, "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
908 | PERIPH_CLK(vfir, "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
909 | PERIPH_CLK(sdmmc1, "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
910 | PERIPH_CLK(sdmmc2, "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
911 | PERIPH_CLK(sdmmc3, "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
912 | PERIPH_CLK(sdmmc4, "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
913 | PERIPH_CLK(vcp, "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0); | ||
914 | PERIPH_CLK(bsea, "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0); | ||
915 | PERIPH_CLK(bsev, "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0); | ||
916 | PERIPH_CLK(vde, "tegra-avp", "vde", 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage and process_id */ | ||
917 | PERIPH_CLK(csite, "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* max rate ??? */ | ||
918 | /* FIXME: what is la? */ | ||
919 | PERIPH_CLK(la, "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
920 | PERIPH_CLK(owr, "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
921 | PERIPH_CLK(nor, "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
922 | PERIPH_CLK(mipi, "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
923 | PERIPH_CLK(i2c1, "tegra-i2c.0", "div-clk", 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16); | ||
924 | PERIPH_CLK(i2c2, "tegra-i2c.1", "div-clk", 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16); | ||
925 | PERIPH_CLK(i2c3, "tegra-i2c.2", "div-clk", 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16); | ||
926 | PERIPH_CLK(dvc, "tegra-i2c.3", "div-clk", 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16); | ||
927 | PERIPH_CLK(uarta, "tegra-uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX); | ||
928 | PERIPH_CLK(uartb, "tegra-uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX); | ||
929 | PERIPH_CLK(uartc, "tegra-uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX); | ||
930 | PERIPH_CLK(uartd, "tegra-uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX); | ||
931 | PERIPH_CLK(uarte, "tegra-uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX); | ||
932 | PERIPH_CLK(3d, "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET); /* scales with voltage and process_id */ | ||
933 | PERIPH_CLK(2d, "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */ | ||
934 | PERIPH_CLK(vi, "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */ | ||
935 | PERIPH_CLK(vi_sensor, "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET); /* scales with voltage and process_id */ | ||
936 | PERIPH_CLK(epp, "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */ | ||
937 | PERIPH_CLK(mpe, "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */ | ||
938 | PERIPH_CLK(host1x, "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71); /* scales with voltage and process_id */ | ||
939 | PERIPH_CLK(cve, "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
940 | PERIPH_CLK(tvo, "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
941 | PERIPH_CLK(hdmi, "hdmi", NULL, 51, 0x18c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
942 | PERIPH_CLK(tvdac, "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
943 | PERIPH_CLK(disp1, "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX); /* scales with voltage and process_id */ | ||
944 | PERIPH_CLK(disp2, "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX); /* scales with voltage and process_id */ | ||
945 | PERIPH_CLK(usbd, "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0); /* requires min voltage */ | ||
946 | PERIPH_CLK(usb2, "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0); /* requires min voltage */ | ||
947 | PERIPH_CLK(usb3, "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0); /* requires min voltage */ | ||
948 | PERIPH_CLK(dsi, "dsi", NULL, 48, 0, 500000000, mux_plld, 0); /* scales with voltage */ | ||
949 | PERIPH_CLK(csi, "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0); | ||
950 | PERIPH_CLK(isp, "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0); /* same frequency as VI */ | ||
951 | PERIPH_CLK(csus, "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET); | ||
952 | PERIPH_CLK(pex, NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET); | ||
953 | PERIPH_CLK(afi, NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET); | ||
954 | PERIPH_CLK(pcie_xclk, NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET); | ||
955 | |||
956 | static struct clk *tegra_list_clks[] = { | ||
957 | &tegra_apbdma, | ||
958 | &tegra_rtc, | ||
959 | &tegra_timer, | ||
960 | &tegra_i2s1, | ||
961 | &tegra_i2s2, | ||
962 | &tegra_spdif_out, | ||
963 | &tegra_spdif_in, | ||
964 | &tegra_pwm, | ||
965 | &tegra_spi, | ||
966 | &tegra_xio, | ||
967 | &tegra_twc, | ||
968 | &tegra_sbc1, | ||
969 | &tegra_sbc2, | ||
970 | &tegra_sbc3, | ||
971 | &tegra_sbc4, | ||
972 | &tegra_ide, | ||
973 | &tegra_ndflash, | ||
974 | &tegra_vfir, | ||
975 | &tegra_sdmmc1, | ||
976 | &tegra_sdmmc2, | ||
977 | &tegra_sdmmc3, | ||
978 | &tegra_sdmmc4, | ||
979 | &tegra_vcp, | ||
980 | &tegra_bsea, | ||
981 | &tegra_bsev, | ||
982 | &tegra_vde, | ||
983 | &tegra_csite, | ||
984 | &tegra_la, | ||
985 | &tegra_owr, | ||
986 | &tegra_nor, | ||
987 | &tegra_mipi, | ||
988 | &tegra_i2c1, | ||
989 | &tegra_i2c2, | ||
990 | &tegra_i2c3, | ||
991 | &tegra_dvc, | ||
992 | &tegra_uarta, | ||
993 | &tegra_uartb, | ||
994 | &tegra_uartc, | ||
995 | &tegra_uartd, | ||
996 | &tegra_uarte, | ||
997 | &tegra_3d, | ||
998 | &tegra_2d, | ||
999 | &tegra_vi, | ||
1000 | &tegra_vi_sensor, | ||
1001 | &tegra_epp, | ||
1002 | &tegra_mpe, | ||
1003 | &tegra_host1x, | ||
1004 | &tegra_cve, | ||
1005 | &tegra_tvo, | ||
1006 | &tegra_hdmi, | ||
1007 | &tegra_tvdac, | ||
1008 | &tegra_disp1, | ||
1009 | &tegra_disp2, | ||
1010 | &tegra_usbd, | ||
1011 | &tegra_usb2, | ||
1012 | &tegra_usb3, | ||
1013 | &tegra_dsi, | ||
1014 | &tegra_csi, | ||
1015 | &tegra_isp, | ||
1016 | &tegra_csus, | ||
1017 | &tegra_pex, | ||
1018 | &tegra_afi, | ||
1019 | &tegra_pcie_xclk, | ||
1020 | }; | ||
1021 | |||
1022 | #define CLK_DUPLICATE(_name, _dev, _con) \ | ||
1023 | { \ | ||
1024 | .name = _name, \ | ||
1025 | .lookup = { \ | ||
1026 | .dev_id = _dev, \ | ||
1027 | .con_id = _con, \ | ||
1028 | }, \ | ||
1029 | } | ||
1030 | |||
1031 | /* Some clocks may be used by different drivers depending on the board | ||
1032 | * configuration. List those here to register them twice in the clock lookup | ||
1033 | * table under two names. | ||
1034 | */ | ||
1035 | static struct clk_duplicate tegra_clk_duplicates[] = { | ||
1036 | CLK_DUPLICATE("uarta", "serial8250.0", NULL), | ||
1037 | CLK_DUPLICATE("uartb", "serial8250.1", NULL), | ||
1038 | CLK_DUPLICATE("uartc", "serial8250.2", NULL), | ||
1039 | CLK_DUPLICATE("uartd", "serial8250.3", NULL), | ||
1040 | CLK_DUPLICATE("uarte", "serial8250.4", NULL), | ||
1041 | CLK_DUPLICATE("usbd", "utmip-pad", NULL), | ||
1042 | CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL), | ||
1043 | CLK_DUPLICATE("usbd", "tegra-otg", NULL), | ||
1044 | CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"), | ||
1045 | CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"), | ||
1046 | CLK_DUPLICATE("epp", "tegra_grhost", "epp"), | ||
1047 | CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"), | ||
1048 | CLK_DUPLICATE("cop", "tegra-avp", "cop"), | ||
1049 | CLK_DUPLICATE("vde", "tegra-aes", "vde"), | ||
1050 | CLK_DUPLICATE("cclk", NULL, "cpu"), | ||
1051 | CLK_DUPLICATE("twd", "smp_twd", NULL), | ||
1052 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.0", "fast-clk"), | ||
1053 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"), | ||
1054 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"), | ||
1055 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"), | ||
1056 | CLK_DUPLICATE("pll_p", "tegradc.0", "parent"), | ||
1057 | CLK_DUPLICATE("pll_p", "tegradc.1", "parent"), | ||
1058 | CLK_DUPLICATE("pll_d_out0", "hdmi", "parent"), | ||
1059 | }; | ||
1060 | |||
1061 | #define CLK(dev, con, ck) \ | ||
1062 | { \ | ||
1063 | .dev_id = dev, \ | ||
1064 | .con_id = con, \ | ||
1065 | .clk = ck, \ | ||
1066 | } | ||
1067 | |||
1068 | static struct clk *tegra_ptr_clks[] = { | ||
1069 | &tegra_clk_32k, | ||
1070 | &tegra_pll_s, | ||
1071 | &tegra_clk_m, | ||
1072 | &tegra_pll_m, | ||
1073 | &tegra_pll_m_out1, | ||
1074 | &tegra_pll_c, | ||
1075 | &tegra_pll_c_out1, | ||
1076 | &tegra_pll_p, | ||
1077 | &tegra_pll_p_out1, | ||
1078 | &tegra_pll_p_out2, | ||
1079 | &tegra_pll_p_out3, | ||
1080 | &tegra_pll_p_out4, | ||
1081 | &tegra_pll_a, | ||
1082 | &tegra_pll_a_out0, | ||
1083 | &tegra_pll_d, | ||
1084 | &tegra_pll_d_out0, | ||
1085 | &tegra_pll_u, | ||
1086 | &tegra_pll_x, | ||
1087 | &tegra_pll_e, | ||
1088 | &tegra_cclk, | ||
1089 | &tegra_clk_twd, | ||
1090 | &tegra_sclk, | ||
1091 | &tegra_hclk, | ||
1092 | &tegra_pclk, | ||
1093 | &tegra_clk_d, | ||
1094 | &tegra_cdev1, | ||
1095 | &tegra_cdev2, | ||
1096 | &tegra_blink, | ||
1097 | &tegra_cop, | ||
1098 | &tegra_emc, | ||
1099 | }; | ||
1100 | |||
1101 | static void tegra2_init_one_clock(struct clk *c) | ||
1102 | { | ||
1103 | struct clk_tegra *clk = to_clk_tegra(c->hw); | ||
1104 | int ret; | ||
1105 | |||
1106 | ret = __clk_init(NULL, c); | ||
1107 | if (ret) | ||
1108 | pr_err("clk init failed %s\n", __clk_get_name(c)); | ||
1109 | |||
1110 | INIT_LIST_HEAD(&clk->shared_bus_list); | ||
1111 | if (!clk->lookup.dev_id && !clk->lookup.con_id) | ||
1112 | clk->lookup.con_id = c->name; | ||
1113 | clk->lookup.clk = c; | ||
1114 | clkdev_add(&clk->lookup); | ||
1115 | tegra_clk_add(c); | ||
1116 | } | ||
1117 | |||
1118 | void __init tegra2_init_clocks(void) | ||
1119 | { | ||
1120 | int i; | ||
1121 | struct clk *c; | ||
1122 | |||
1123 | for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++) | ||
1124 | tegra2_init_one_clock(tegra_ptr_clks[i]); | ||
1125 | |||
1126 | for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++) | ||
1127 | tegra2_init_one_clock(tegra_list_clks[i]); | ||
1128 | |||
1129 | for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) { | ||
1130 | c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name); | ||
1131 | if (!c) { | ||
1132 | pr_err("%s: Unknown duplicate clock %s\n", __func__, | ||
1133 | tegra_clk_duplicates[i].name); | ||
1134 | continue; | ||
1135 | } | ||
1136 | |||
1137 | tegra_clk_duplicates[i].lookup.clk = c; | ||
1138 | clkdev_add(&tegra_clk_duplicates[i].lookup); | ||
1139 | } | ||
1140 | |||
1141 | init_audio_sync_clock_mux(); | ||
1142 | tegra20_cpu_car_ops_init(); | ||
1143 | } | ||
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c deleted file mode 100644 index d7147779f8ea..000000000000 --- a/arch/arm/mach-tegra/tegra30_clocks.c +++ /dev/null | |||
@@ -1,2506 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/tegra30_clocks.c | ||
3 | * | ||
4 | * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/clk.h> | ||
29 | #include <linux/cpufreq.h> | ||
30 | #include <linux/syscore_ops.h> | ||
31 | |||
32 | #include <asm/clkdev.h> | ||
33 | |||
34 | #include <mach/powergate.h> | ||
35 | |||
36 | #include "clock.h" | ||
37 | #include "fuse.h" | ||
38 | #include "iomap.h" | ||
39 | #include "tegra_cpu_car.h" | ||
40 | |||
41 | #define USE_PLL_LOCK_BITS 0 | ||
42 | |||
43 | #define RST_DEVICES_L 0x004 | ||
44 | #define RST_DEVICES_H 0x008 | ||
45 | #define RST_DEVICES_U 0x00C | ||
46 | #define RST_DEVICES_V 0x358 | ||
47 | #define RST_DEVICES_W 0x35C | ||
48 | #define RST_DEVICES_SET_L 0x300 | ||
49 | #define RST_DEVICES_CLR_L 0x304 | ||
50 | #define RST_DEVICES_SET_V 0x430 | ||
51 | #define RST_DEVICES_CLR_V 0x434 | ||
52 | #define RST_DEVICES_NUM 5 | ||
53 | |||
54 | #define CLK_OUT_ENB_L 0x010 | ||
55 | #define CLK_OUT_ENB_H 0x014 | ||
56 | #define CLK_OUT_ENB_U 0x018 | ||
57 | #define CLK_OUT_ENB_V 0x360 | ||
58 | #define CLK_OUT_ENB_W 0x364 | ||
59 | #define CLK_OUT_ENB_SET_L 0x320 | ||
60 | #define CLK_OUT_ENB_CLR_L 0x324 | ||
61 | #define CLK_OUT_ENB_SET_V 0x440 | ||
62 | #define CLK_OUT_ENB_CLR_V 0x444 | ||
63 | #define CLK_OUT_ENB_NUM 5 | ||
64 | |||
65 | #define RST_DEVICES_V_SWR_CPULP_RST_DIS (0x1 << 1) | ||
66 | #define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN (0x1 << 1) | ||
67 | |||
68 | #define PERIPH_CLK_TO_BIT(c) (1 << (c->u.periph.clk_num % 32)) | ||
69 | #define PERIPH_CLK_TO_RST_REG(c) \ | ||
70 | periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4) | ||
71 | #define PERIPH_CLK_TO_RST_SET_REG(c) \ | ||
72 | periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8) | ||
73 | #define PERIPH_CLK_TO_RST_CLR_REG(c) \ | ||
74 | periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8) | ||
75 | |||
76 | #define PERIPH_CLK_TO_ENB_REG(c) \ | ||
77 | periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4) | ||
78 | #define PERIPH_CLK_TO_ENB_SET_REG(c) \ | ||
79 | periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8) | ||
80 | #define PERIPH_CLK_TO_ENB_CLR_REG(c) \ | ||
81 | periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8) | ||
82 | |||
83 | #define CLK_MASK_ARM 0x44 | ||
84 | #define MISC_CLK_ENB 0x48 | ||
85 | |||
86 | #define OSC_CTRL 0x50 | ||
87 | #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) | ||
88 | #define OSC_CTRL_OSC_FREQ_13MHZ (0x0<<28) | ||
89 | #define OSC_CTRL_OSC_FREQ_19_2MHZ (0x4<<28) | ||
90 | #define OSC_CTRL_OSC_FREQ_12MHZ (0x8<<28) | ||
91 | #define OSC_CTRL_OSC_FREQ_26MHZ (0xC<<28) | ||
92 | #define OSC_CTRL_OSC_FREQ_16_8MHZ (0x1<<28) | ||
93 | #define OSC_CTRL_OSC_FREQ_38_4MHZ (0x5<<28) | ||
94 | #define OSC_CTRL_OSC_FREQ_48MHZ (0x9<<28) | ||
95 | #define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) | ||
96 | |||
97 | #define OSC_CTRL_PLL_REF_DIV_MASK (3<<26) | ||
98 | #define OSC_CTRL_PLL_REF_DIV_1 (0<<26) | ||
99 | #define OSC_CTRL_PLL_REF_DIV_2 (1<<26) | ||
100 | #define OSC_CTRL_PLL_REF_DIV_4 (2<<26) | ||
101 | |||
102 | #define OSC_FREQ_DET 0x58 | ||
103 | #define OSC_FREQ_DET_TRIG (1<<31) | ||
104 | |||
105 | #define OSC_FREQ_DET_STATUS 0x5C | ||
106 | #define OSC_FREQ_DET_BUSY (1<<31) | ||
107 | #define OSC_FREQ_DET_CNT_MASK 0xFFFF | ||
108 | |||
109 | #define PERIPH_CLK_SOURCE_I2S1 0x100 | ||
110 | #define PERIPH_CLK_SOURCE_EMC 0x19c | ||
111 | #define PERIPH_CLK_SOURCE_OSC 0x1fc | ||
112 | #define PERIPH_CLK_SOURCE_NUM1 \ | ||
113 | ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4) | ||
114 | |||
115 | #define PERIPH_CLK_SOURCE_G3D2 0x3b0 | ||
116 | #define PERIPH_CLK_SOURCE_SE 0x42c | ||
117 | #define PERIPH_CLK_SOURCE_NUM2 \ | ||
118 | ((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1) | ||
119 | |||
120 | #define AUDIO_DLY_CLK 0x49c | ||
121 | #define AUDIO_SYNC_CLK_SPDIF 0x4b4 | ||
122 | #define PERIPH_CLK_SOURCE_NUM3 \ | ||
123 | ((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1) | ||
124 | |||
125 | #define PERIPH_CLK_SOURCE_NUM (PERIPH_CLK_SOURCE_NUM1 + \ | ||
126 | PERIPH_CLK_SOURCE_NUM2 + \ | ||
127 | PERIPH_CLK_SOURCE_NUM3) | ||
128 | |||
129 | #define CPU_SOFTRST_CTRL 0x380 | ||
130 | |||
131 | #define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF | ||
132 | #define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF | ||
133 | #define PERIPH_CLK_SOURCE_DIV_SHIFT 0 | ||
134 | #define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT 8 | ||
135 | #define PERIPH_CLK_SOURCE_DIVIDLE_VAL 50 | ||
136 | #define PERIPH_CLK_UART_DIV_ENB (1<<24) | ||
137 | #define PERIPH_CLK_VI_SEL_EX_SHIFT 24 | ||
138 | #define PERIPH_CLK_VI_SEL_EX_MASK (0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT) | ||
139 | #define PERIPH_CLK_NAND_DIV_EX_ENB (1<<8) | ||
140 | #define PERIPH_CLK_DTV_POLARITY_INV (1<<25) | ||
141 | |||
142 | #define AUDIO_SYNC_SOURCE_MASK 0x0F | ||
143 | #define AUDIO_SYNC_DISABLE_BIT 0x10 | ||
144 | #define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c) ((c->reg_shift - 24) * 4) | ||
145 | |||
146 | #define PLL_BASE 0x0 | ||
147 | #define PLL_BASE_BYPASS (1<<31) | ||
148 | #define PLL_BASE_ENABLE (1<<30) | ||
149 | #define PLL_BASE_REF_ENABLE (1<<29) | ||
150 | #define PLL_BASE_OVERRIDE (1<<28) | ||
151 | #define PLL_BASE_LOCK (1<<27) | ||
152 | #define PLL_BASE_DIVP_MASK (0x7<<20) | ||
153 | #define PLL_BASE_DIVP_SHIFT 20 | ||
154 | #define PLL_BASE_DIVN_MASK (0x3FF<<8) | ||
155 | #define PLL_BASE_DIVN_SHIFT 8 | ||
156 | #define PLL_BASE_DIVM_MASK (0x1F) | ||
157 | #define PLL_BASE_DIVM_SHIFT 0 | ||
158 | |||
159 | #define PLL_OUT_RATIO_MASK (0xFF<<8) | ||
160 | #define PLL_OUT_RATIO_SHIFT 8 | ||
161 | #define PLL_OUT_OVERRIDE (1<<2) | ||
162 | #define PLL_OUT_CLKEN (1<<1) | ||
163 | #define PLL_OUT_RESET_DISABLE (1<<0) | ||
164 | |||
165 | #define PLL_MISC(c) \ | ||
166 | (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc) | ||
167 | #define PLL_MISC_LOCK_ENABLE(c) \ | ||
168 | (((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18)) | ||
169 | |||
170 | #define PLL_MISC_DCCON_SHIFT 20 | ||
171 | #define PLL_MISC_CPCON_SHIFT 8 | ||
172 | #define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT) | ||
173 | #define PLL_MISC_LFCON_SHIFT 4 | ||
174 | #define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT) | ||
175 | #define PLL_MISC_VCOCON_SHIFT 0 | ||
176 | #define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT) | ||
177 | #define PLLD_MISC_CLKENABLE (1<<30) | ||
178 | |||
179 | #define PLLU_BASE_POST_DIV (1<<20) | ||
180 | |||
181 | #define PLLD_BASE_DSIB_MUX_SHIFT 25 | ||
182 | #define PLLD_BASE_DSIB_MUX_MASK (1<<PLLD_BASE_DSIB_MUX_SHIFT) | ||
183 | #define PLLD_BASE_CSI_CLKENABLE (1<<26) | ||
184 | #define PLLD_MISC_DSI_CLKENABLE (1<<30) | ||
185 | #define PLLD_MISC_DIV_RST (1<<23) | ||
186 | #define PLLD_MISC_DCCON_SHIFT 12 | ||
187 | |||
188 | #define PLLDU_LFCON_SET_DIVN 600 | ||
189 | |||
190 | /* FIXME: OUT_OF_TABLE_CPCON per pll */ | ||
191 | #define OUT_OF_TABLE_CPCON 0x8 | ||
192 | |||
193 | #define SUPER_CLK_MUX 0x00 | ||
194 | #define SUPER_STATE_SHIFT 28 | ||
195 | #define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT) | ||
196 | #define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT) | ||
197 | #define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT) | ||
198 | #define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT) | ||
199 | #define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT) | ||
200 | #define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT) | ||
201 | #define SUPER_LP_DIV2_BYPASS (0x1 << 16) | ||
202 | #define SUPER_SOURCE_MASK 0xF | ||
203 | #define SUPER_FIQ_SOURCE_SHIFT 12 | ||
204 | #define SUPER_IRQ_SOURCE_SHIFT 8 | ||
205 | #define SUPER_RUN_SOURCE_SHIFT 4 | ||
206 | #define SUPER_IDLE_SOURCE_SHIFT 0 | ||
207 | |||
208 | #define SUPER_CLK_DIVIDER 0x04 | ||
209 | #define SUPER_CLOCK_DIV_U71_SHIFT 16 | ||
210 | #define SUPER_CLOCK_DIV_U71_MASK (0xff << SUPER_CLOCK_DIV_U71_SHIFT) | ||
211 | /* guarantees safe cpu backup */ | ||
212 | #define SUPER_CLOCK_DIV_U71_MIN 0x2 | ||
213 | |||
214 | #define BUS_CLK_DISABLE (1<<3) | ||
215 | #define BUS_CLK_DIV_MASK 0x3 | ||
216 | |||
217 | #define PMC_CTRL 0x0 | ||
218 | #define PMC_CTRL_BLINK_ENB (1 << 7) | ||
219 | |||
220 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
221 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20) | ||
222 | |||
223 | #define PMC_BLINK_TIMER_DATA_ON_SHIFT 0 | ||
224 | #define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff | ||
225 | #define PMC_BLINK_TIMER_ENB (1 << 15) | ||
226 | #define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16 | ||
227 | #define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff | ||
228 | |||
229 | #define PMC_PLLP_WB0_OVERRIDE 0xf8 | ||
230 | #define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE (1 << 12) | ||
231 | |||
232 | #define UTMIP_PLL_CFG2 0x488 | ||
233 | #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6) | ||
234 | #define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) | ||
235 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN (1 << 0) | ||
236 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN (1 << 2) | ||
237 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN (1 << 4) | ||
238 | |||
239 | #define UTMIP_PLL_CFG1 0x484 | ||
240 | #define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) | ||
241 | #define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) | ||
242 | #define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN (1 << 14) | ||
243 | #define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN (1 << 12) | ||
244 | #define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN (1 << 16) | ||
245 | |||
246 | #define PLLE_BASE_CML_ENABLE (1<<31) | ||
247 | #define PLLE_BASE_ENABLE (1<<30) | ||
248 | #define PLLE_BASE_DIVCML_SHIFT 24 | ||
249 | #define PLLE_BASE_DIVCML_MASK (0xf<<PLLE_BASE_DIVCML_SHIFT) | ||
250 | #define PLLE_BASE_DIVP_SHIFT 16 | ||
251 | #define PLLE_BASE_DIVP_MASK (0x3f<<PLLE_BASE_DIVP_SHIFT) | ||
252 | #define PLLE_BASE_DIVN_SHIFT 8 | ||
253 | #define PLLE_BASE_DIVN_MASK (0xFF<<PLLE_BASE_DIVN_SHIFT) | ||
254 | #define PLLE_BASE_DIVM_SHIFT 0 | ||
255 | #define PLLE_BASE_DIVM_MASK (0xFF<<PLLE_BASE_DIVM_SHIFT) | ||
256 | #define PLLE_BASE_DIV_MASK \ | ||
257 | (PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \ | ||
258 | PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK) | ||
259 | #define PLLE_BASE_DIV(m, n, p, cml) \ | ||
260 | (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \ | ||
261 | ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT)) | ||
262 | |||
263 | #define PLLE_MISC_SETUP_BASE_SHIFT 16 | ||
264 | #define PLLE_MISC_SETUP_BASE_MASK (0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT) | ||
265 | #define PLLE_MISC_READY (1<<15) | ||
266 | #define PLLE_MISC_LOCK (1<<11) | ||
267 | #define PLLE_MISC_LOCK_ENABLE (1<<9) | ||
268 | #define PLLE_MISC_SETUP_EX_SHIFT 2 | ||
269 | #define PLLE_MISC_SETUP_EX_MASK (0x3<<PLLE_MISC_SETUP_EX_SHIFT) | ||
270 | #define PLLE_MISC_SETUP_MASK \ | ||
271 | (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK) | ||
272 | #define PLLE_MISC_SETUP_VALUE \ | ||
273 | ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT)) | ||
274 | |||
275 | #define PLLE_SS_CTRL 0x68 | ||
276 | #define PLLE_SS_INCINTRV_SHIFT 24 | ||
277 | #define PLLE_SS_INCINTRV_MASK (0x3f<<PLLE_SS_INCINTRV_SHIFT) | ||
278 | #define PLLE_SS_INC_SHIFT 16 | ||
279 | #define PLLE_SS_INC_MASK (0xff<<PLLE_SS_INC_SHIFT) | ||
280 | #define PLLE_SS_MAX_SHIFT 0 | ||
281 | #define PLLE_SS_MAX_MASK (0x1ff<<PLLE_SS_MAX_SHIFT) | ||
282 | #define PLLE_SS_COEFFICIENTS_MASK \ | ||
283 | (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK) | ||
284 | #define PLLE_SS_COEFFICIENTS_12MHZ \ | ||
285 | ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \ | ||
286 | (0x24<<PLLE_SS_MAX_SHIFT)) | ||
287 | #define PLLE_SS_DISABLE ((1<<12) | (1<<11) | (1<<10)) | ||
288 | |||
289 | #define PLLE_AUX 0x48c | ||
290 | #define PLLE_AUX_PLLP_SEL (1<<2) | ||
291 | #define PLLE_AUX_CML_SATA_ENABLE (1<<1) | ||
292 | #define PLLE_AUX_CML_PCIE_ENABLE (1<<0) | ||
293 | |||
294 | #define PMC_SATA_PWRGT 0x1ac | ||
295 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE (1<<5) | ||
296 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1<<4) | ||
297 | |||
298 | #define ROUND_DIVIDER_UP 0 | ||
299 | #define ROUND_DIVIDER_DOWN 1 | ||
300 | |||
301 | /* FIXME: recommended safety delay after lock is detected */ | ||
302 | #define PLL_POST_LOCK_DELAY 100 | ||
303 | |||
304 | /* Tegra CPU clock and reset control regs */ | ||
305 | #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c | ||
306 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 | ||
307 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344 | ||
308 | #define TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR 0x34c | ||
309 | #define TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 | ||
310 | |||
311 | #define CPU_CLOCK(cpu) (0x1 << (8 + cpu)) | ||
312 | #define CPU_RESET(cpu) (0x1111ul << (cpu)) | ||
313 | |||
314 | #define CLK_RESET_CCLK_BURST 0x20 | ||
315 | #define CLK_RESET_CCLK_DIVIDER 0x24 | ||
316 | #define CLK_RESET_PLLX_BASE 0xe0 | ||
317 | #define CLK_RESET_PLLX_MISC 0xe4 | ||
318 | |||
319 | #define CLK_RESET_SOURCE_CSITE 0x1d4 | ||
320 | |||
321 | #define CLK_RESET_CCLK_BURST_POLICY_SHIFT 28 | ||
322 | #define CLK_RESET_CCLK_RUN_POLICY_SHIFT 4 | ||
323 | #define CLK_RESET_CCLK_IDLE_POLICY_SHIFT 0 | ||
324 | #define CLK_RESET_CCLK_IDLE_POLICY 1 | ||
325 | #define CLK_RESET_CCLK_RUN_POLICY 2 | ||
326 | #define CLK_RESET_CCLK_BURST_POLICY_PLLX 8 | ||
327 | |||
328 | #ifdef CONFIG_PM_SLEEP | ||
329 | static struct cpu_clk_suspend_context { | ||
330 | u32 pllx_misc; | ||
331 | u32 pllx_base; | ||
332 | |||
333 | u32 cpu_burst; | ||
334 | u32 clk_csite_src; | ||
335 | u32 cclk_divider; | ||
336 | } tegra30_cpu_clk_sctx; | ||
337 | #endif | ||
338 | |||
339 | /** | ||
340 | * Structure defining the fields for USB UTMI clocks Parameters. | ||
341 | */ | ||
342 | struct utmi_clk_param { | ||
343 | /* Oscillator Frequency in KHz */ | ||
344 | u32 osc_frequency; | ||
345 | /* UTMIP PLL Enable Delay Count */ | ||
346 | u8 enable_delay_count; | ||
347 | /* UTMIP PLL Stable count */ | ||
348 | u8 stable_count; | ||
349 | /* UTMIP PLL Active delay count */ | ||
350 | u8 active_delay_count; | ||
351 | /* UTMIP PLL Xtal frequency count */ | ||
352 | u8 xtal_freq_count; | ||
353 | }; | ||
354 | |||
355 | static const struct utmi_clk_param utmi_parameters[] = { | ||
356 | { | ||
357 | .osc_frequency = 13000000, | ||
358 | .enable_delay_count = 0x02, | ||
359 | .stable_count = 0x33, | ||
360 | .active_delay_count = 0x05, | ||
361 | .xtal_freq_count = 0x7F | ||
362 | }, | ||
363 | { | ||
364 | .osc_frequency = 19200000, | ||
365 | .enable_delay_count = 0x03, | ||
366 | .stable_count = 0x4B, | ||
367 | .active_delay_count = 0x06, | ||
368 | .xtal_freq_count = 0xBB}, | ||
369 | { | ||
370 | .osc_frequency = 12000000, | ||
371 | .enable_delay_count = 0x02, | ||
372 | .stable_count = 0x2F, | ||
373 | .active_delay_count = 0x04, | ||
374 | .xtal_freq_count = 0x76 | ||
375 | }, | ||
376 | { | ||
377 | .osc_frequency = 26000000, | ||
378 | .enable_delay_count = 0x04, | ||
379 | .stable_count = 0x66, | ||
380 | .active_delay_count = 0x09, | ||
381 | .xtal_freq_count = 0xFE | ||
382 | }, | ||
383 | { | ||
384 | .osc_frequency = 16800000, | ||
385 | .enable_delay_count = 0x03, | ||
386 | .stable_count = 0x41, | ||
387 | .active_delay_count = 0x0A, | ||
388 | .xtal_freq_count = 0xA4 | ||
389 | }, | ||
390 | }; | ||
391 | |||
392 | static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); | ||
393 | static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); | ||
394 | static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE); | ||
395 | |||
396 | #define MISC_GP_HIDREV 0x804 | ||
397 | |||
398 | /* | ||
399 | * Some peripheral clocks share an enable bit, so refcount the enable bits | ||
400 | * in registers CLK_ENABLE_L, ... CLK_ENABLE_W | ||
401 | */ | ||
402 | static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32]; | ||
403 | |||
404 | #define clk_writel(value, reg) \ | ||
405 | __raw_writel(value, reg_clk_base + (reg)) | ||
406 | #define clk_readl(reg) \ | ||
407 | __raw_readl(reg_clk_base + (reg)) | ||
408 | #define pmc_writel(value, reg) \ | ||
409 | __raw_writel(value, reg_pmc_base + (reg)) | ||
410 | #define pmc_readl(reg) \ | ||
411 | __raw_readl(reg_pmc_base + (reg)) | ||
412 | #define chipid_readl() \ | ||
413 | __raw_readl(misc_gp_hidrev_base + MISC_GP_HIDREV) | ||
414 | |||
415 | #define clk_writel_delay(value, reg) \ | ||
416 | do { \ | ||
417 | __raw_writel((value), reg_clk_base + (reg)); \ | ||
418 | udelay(2); \ | ||
419 | } while (0) | ||
420 | |||
421 | static inline int clk_set_div(struct clk_tegra *c, u32 n) | ||
422 | { | ||
423 | struct clk *clk = c->hw.clk; | ||
424 | |||
425 | return clk_set_rate(clk, | ||
426 | (__clk_get_rate(__clk_get_parent(clk)) + n - 1) / n); | ||
427 | } | ||
428 | |||
429 | static inline u32 periph_clk_to_reg( | ||
430 | struct clk_tegra *c, u32 reg_L, u32 reg_V, int offs) | ||
431 | { | ||
432 | u32 reg = c->u.periph.clk_num / 32; | ||
433 | BUG_ON(reg >= RST_DEVICES_NUM); | ||
434 | if (reg < 3) | ||
435 | reg = reg_L + (reg * offs); | ||
436 | else | ||
437 | reg = reg_V + ((reg - 3) * offs); | ||
438 | return reg; | ||
439 | } | ||
440 | |||
441 | static unsigned long clk_measure_input_freq(void) | ||
442 | { | ||
443 | u32 clock_autodetect; | ||
444 | clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET); | ||
445 | do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY); | ||
446 | clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS); | ||
447 | if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) { | ||
448 | return 12000000; | ||
449 | } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) { | ||
450 | return 13000000; | ||
451 | } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) { | ||
452 | return 19200000; | ||
453 | } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) { | ||
454 | return 26000000; | ||
455 | } else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3) { | ||
456 | return 16800000; | ||
457 | } else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3) { | ||
458 | return 38400000; | ||
459 | } else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3) { | ||
460 | return 48000000; | ||
461 | } else { | ||
462 | pr_err("%s: Unexpected clock autodetect value %d", __func__, | ||
463 | clock_autodetect); | ||
464 | BUG(); | ||
465 | return 0; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate, | ||
470 | u32 flags, u32 round_mode) | ||
471 | { | ||
472 | s64 divider_u71 = parent_rate; | ||
473 | if (!rate) | ||
474 | return -EINVAL; | ||
475 | |||
476 | if (!(flags & DIV_U71_INT)) | ||
477 | divider_u71 *= 2; | ||
478 | if (round_mode == ROUND_DIVIDER_UP) | ||
479 | divider_u71 += rate - 1; | ||
480 | do_div(divider_u71, rate); | ||
481 | if (flags & DIV_U71_INT) | ||
482 | divider_u71 *= 2; | ||
483 | |||
484 | if (divider_u71 - 2 < 0) | ||
485 | return 0; | ||
486 | |||
487 | if (divider_u71 - 2 > 255) | ||
488 | return -EINVAL; | ||
489 | |||
490 | return divider_u71 - 2; | ||
491 | } | ||
492 | |||
493 | static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate) | ||
494 | { | ||
495 | s64 divider_u16; | ||
496 | |||
497 | divider_u16 = parent_rate; | ||
498 | if (!rate) | ||
499 | return -EINVAL; | ||
500 | divider_u16 += rate - 1; | ||
501 | do_div(divider_u16, rate); | ||
502 | |||
503 | if (divider_u16 - 1 < 0) | ||
504 | return 0; | ||
505 | |||
506 | if (divider_u16 - 1 > 0xFFFF) | ||
507 | return -EINVAL; | ||
508 | |||
509 | return divider_u16 - 1; | ||
510 | } | ||
511 | |||
512 | static unsigned long tegra30_clk_fixed_recalc_rate(struct clk_hw *hw, | ||
513 | unsigned long parent_rate) | ||
514 | { | ||
515 | return to_clk_tegra(hw)->fixed_rate; | ||
516 | } | ||
517 | |||
518 | struct clk_ops tegra30_clk_32k_ops = { | ||
519 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
520 | }; | ||
521 | |||
522 | /* clk_m functions */ | ||
523 | static unsigned long tegra30_clk_m_recalc_rate(struct clk_hw *hw, | ||
524 | unsigned long parent_rate) | ||
525 | { | ||
526 | if (!to_clk_tegra(hw)->fixed_rate) | ||
527 | to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq(); | ||
528 | return to_clk_tegra(hw)->fixed_rate; | ||
529 | } | ||
530 | |||
531 | static void tegra30_clk_m_init(struct clk_hw *hw) | ||
532 | { | ||
533 | u32 osc_ctrl = clk_readl(OSC_CTRL); | ||
534 | u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK; | ||
535 | u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; | ||
536 | |||
537 | switch (to_clk_tegra(hw)->fixed_rate) { | ||
538 | case 12000000: | ||
539 | auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ; | ||
540 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
541 | break; | ||
542 | case 13000000: | ||
543 | auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ; | ||
544 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
545 | break; | ||
546 | case 19200000: | ||
547 | auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ; | ||
548 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
549 | break; | ||
550 | case 26000000: | ||
551 | auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ; | ||
552 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
553 | break; | ||
554 | case 16800000: | ||
555 | auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ; | ||
556 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
557 | break; | ||
558 | case 38400000: | ||
559 | auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ; | ||
560 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2); | ||
561 | break; | ||
562 | case 48000000: | ||
563 | auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ; | ||
564 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); | ||
565 | break; | ||
566 | default: | ||
567 | pr_err("%s: Unexpected clock rate %ld", __func__, | ||
568 | to_clk_tegra(hw)->fixed_rate); | ||
569 | BUG(); | ||
570 | } | ||
571 | clk_writel(auto_clock_control, OSC_CTRL); | ||
572 | } | ||
573 | |||
574 | struct clk_ops tegra30_clk_m_ops = { | ||
575 | .init = tegra30_clk_m_init, | ||
576 | .recalc_rate = tegra30_clk_m_recalc_rate, | ||
577 | }; | ||
578 | |||
579 | static unsigned long tegra30_clk_m_div_recalc_rate(struct clk_hw *hw, | ||
580 | unsigned long parent_rate) | ||
581 | { | ||
582 | struct clk_tegra *c = to_clk_tegra(hw); | ||
583 | u64 rate = parent_rate; | ||
584 | |||
585 | if (c->mul != 0 && c->div != 0) { | ||
586 | rate *= c->mul; | ||
587 | rate += c->div - 1; /* round up */ | ||
588 | do_div(rate, c->div); | ||
589 | } | ||
590 | |||
591 | return rate; | ||
592 | } | ||
593 | |||
594 | struct clk_ops tegra_clk_m_div_ops = { | ||
595 | .recalc_rate = tegra30_clk_m_div_recalc_rate, | ||
596 | }; | ||
597 | |||
598 | /* PLL reference divider functions */ | ||
599 | static unsigned long tegra30_pll_ref_recalc_rate(struct clk_hw *hw, | ||
600 | unsigned long parent_rate) | ||
601 | { | ||
602 | struct clk_tegra *c = to_clk_tegra(hw); | ||
603 | unsigned long rate = parent_rate; | ||
604 | u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK; | ||
605 | |||
606 | switch (pll_ref_div) { | ||
607 | case OSC_CTRL_PLL_REF_DIV_1: | ||
608 | c->div = 1; | ||
609 | break; | ||
610 | case OSC_CTRL_PLL_REF_DIV_2: | ||
611 | c->div = 2; | ||
612 | break; | ||
613 | case OSC_CTRL_PLL_REF_DIV_4: | ||
614 | c->div = 4; | ||
615 | break; | ||
616 | default: | ||
617 | pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div); | ||
618 | BUG(); | ||
619 | } | ||
620 | c->mul = 1; | ||
621 | |||
622 | if (c->mul != 0 && c->div != 0) { | ||
623 | rate *= c->mul; | ||
624 | rate += c->div - 1; /* round up */ | ||
625 | do_div(rate, c->div); | ||
626 | } | ||
627 | |||
628 | return rate; | ||
629 | } | ||
630 | |||
631 | struct clk_ops tegra_pll_ref_ops = { | ||
632 | .recalc_rate = tegra30_pll_ref_recalc_rate, | ||
633 | }; | ||
634 | |||
635 | /* super clock functions */ | ||
636 | /* "super clocks" on tegra30 have two-stage muxes, fractional 7.1 divider and | ||
637 | * clock skipping super divider. We will ignore the clock skipping divider, | ||
638 | * since we can't lower the voltage when using the clock skip, but we can if | ||
639 | * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock | ||
640 | * only when its parent is a fixed rate PLL, since we can't change PLL rate | ||
641 | * in this case. | ||
642 | */ | ||
643 | static void tegra30_super_clk_init(struct clk_hw *hw) | ||
644 | { | ||
645 | struct clk_tegra *c = to_clk_tegra(hw); | ||
646 | struct clk_tegra *p = | ||
647 | to_clk_tegra(__clk_get_hw(__clk_get_parent(hw->clk))); | ||
648 | |||
649 | c->state = ON; | ||
650 | if (c->flags & DIV_U71) { | ||
651 | /* Init safe 7.1 divider value (does not affect PLLX path) */ | ||
652 | clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT, | ||
653 | c->reg + SUPER_CLK_DIVIDER); | ||
654 | c->mul = 2; | ||
655 | c->div = 2; | ||
656 | if (!(p->flags & PLLX)) | ||
657 | c->div += SUPER_CLOCK_DIV_U71_MIN; | ||
658 | } else | ||
659 | clk_writel(0, c->reg + SUPER_CLK_DIVIDER); | ||
660 | } | ||
661 | |||
662 | static u8 tegra30_super_clk_get_parent(struct clk_hw *hw) | ||
663 | { | ||
664 | struct clk_tegra *c = to_clk_tegra(hw); | ||
665 | u32 val; | ||
666 | int source; | ||
667 | int shift; | ||
668 | |||
669 | val = clk_readl(c->reg + SUPER_CLK_MUX); | ||
670 | BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && | ||
671 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); | ||
672 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? | ||
673 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; | ||
674 | source = (val >> shift) & SUPER_SOURCE_MASK; | ||
675 | if (c->flags & DIV_2) | ||
676 | source |= val & SUPER_LP_DIV2_BYPASS; | ||
677 | |||
678 | return source; | ||
679 | } | ||
680 | |||
681 | static int tegra30_super_clk_set_parent(struct clk_hw *hw, u8 index) | ||
682 | { | ||
683 | struct clk_tegra *c = to_clk_tegra(hw); | ||
684 | struct clk_tegra *p = | ||
685 | to_clk_tegra(__clk_get_hw(clk_get_parent(hw->clk))); | ||
686 | u32 val; | ||
687 | int shift; | ||
688 | |||
689 | val = clk_readl(c->reg + SUPER_CLK_MUX); | ||
690 | BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && | ||
691 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); | ||
692 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? | ||
693 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; | ||
694 | |||
695 | /* For LP mode super-clock switch between PLLX direct | ||
696 | and divided-by-2 outputs is allowed only when other | ||
697 | than PLLX clock source is current parent */ | ||
698 | if ((c->flags & DIV_2) && (p->flags & PLLX) && | ||
699 | ((index ^ val) & SUPER_LP_DIV2_BYPASS)) { | ||
700 | if (p->flags & PLLX) | ||
701 | return -EINVAL; | ||
702 | val ^= SUPER_LP_DIV2_BYPASS; | ||
703 | clk_writel_delay(val, c->reg); | ||
704 | } | ||
705 | val &= ~(SUPER_SOURCE_MASK << shift); | ||
706 | val |= (index & SUPER_SOURCE_MASK) << shift; | ||
707 | |||
708 | /* 7.1 divider for CPU super-clock does not affect | ||
709 | PLLX path */ | ||
710 | if (c->flags & DIV_U71) { | ||
711 | u32 div = 0; | ||
712 | if (!(p->flags & PLLX)) { | ||
713 | div = clk_readl(c->reg + | ||
714 | SUPER_CLK_DIVIDER); | ||
715 | div &= SUPER_CLOCK_DIV_U71_MASK; | ||
716 | div >>= SUPER_CLOCK_DIV_U71_SHIFT; | ||
717 | } | ||
718 | c->div = div + 2; | ||
719 | c->mul = 2; | ||
720 | } | ||
721 | clk_writel_delay(val, c->reg); | ||
722 | |||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | /* | ||
727 | * Do not use super clocks "skippers", since dividing using a clock skipper | ||
728 | * does not allow the voltage to be scaled down. Instead adjust the rate of | ||
729 | * the parent clock. This requires that the parent of a super clock have no | ||
730 | * other children, otherwise the rate will change underneath the other | ||
731 | * children. Special case: if fixed rate PLL is CPU super clock parent the | ||
732 | * rate of this PLL can't be changed, and it has many other children. In | ||
733 | * this case use 7.1 fractional divider to adjust the super clock rate. | ||
734 | */ | ||
735 | static int tegra30_super_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
736 | unsigned long parent_rate) | ||
737 | { | ||
738 | struct clk_tegra *c = to_clk_tegra(hw); | ||
739 | struct clk *parent = __clk_get_parent(hw->clk); | ||
740 | struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent)); | ||
741 | |||
742 | if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) { | ||
743 | int div = clk_div71_get_divider(parent_rate, | ||
744 | rate, c->flags, ROUND_DIVIDER_DOWN); | ||
745 | div = max(div, SUPER_CLOCK_DIV_U71_MIN); | ||
746 | |||
747 | clk_writel(div << SUPER_CLOCK_DIV_U71_SHIFT, | ||
748 | c->reg + SUPER_CLK_DIVIDER); | ||
749 | c->div = div + 2; | ||
750 | c->mul = 2; | ||
751 | return 0; | ||
752 | } | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static unsigned long tegra30_super_clk_recalc_rate(struct clk_hw *hw, | ||
757 | unsigned long parent_rate) | ||
758 | { | ||
759 | struct clk_tegra *c = to_clk_tegra(hw); | ||
760 | u64 rate = parent_rate; | ||
761 | |||
762 | if (c->mul != 0 && c->div != 0) { | ||
763 | rate *= c->mul; | ||
764 | rate += c->div - 1; /* round up */ | ||
765 | do_div(rate, c->div); | ||
766 | } | ||
767 | |||
768 | return rate; | ||
769 | } | ||
770 | |||
771 | static long tegra30_super_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
772 | unsigned long *prate) | ||
773 | { | ||
774 | struct clk_tegra *c = to_clk_tegra(hw); | ||
775 | struct clk *parent = __clk_get_parent(hw->clk); | ||
776 | struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent)); | ||
777 | int mul = 2; | ||
778 | int div; | ||
779 | |||
780 | if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) { | ||
781 | div = clk_div71_get_divider(*prate, | ||
782 | rate, c->flags, ROUND_DIVIDER_DOWN); | ||
783 | div = max(div, SUPER_CLOCK_DIV_U71_MIN) + 2; | ||
784 | rate = *prate * mul; | ||
785 | rate += div - 1; /* round up */ | ||
786 | do_div(rate, c->div); | ||
787 | |||
788 | return rate; | ||
789 | } | ||
790 | return *prate; | ||
791 | } | ||
792 | |||
793 | struct clk_ops tegra30_super_ops = { | ||
794 | .init = tegra30_super_clk_init, | ||
795 | .set_parent = tegra30_super_clk_set_parent, | ||
796 | .get_parent = tegra30_super_clk_get_parent, | ||
797 | .recalc_rate = tegra30_super_clk_recalc_rate, | ||
798 | .round_rate = tegra30_super_clk_round_rate, | ||
799 | .set_rate = tegra30_super_clk_set_rate, | ||
800 | }; | ||
801 | |||
802 | static unsigned long tegra30_twd_clk_recalc_rate(struct clk_hw *hw, | ||
803 | unsigned long parent_rate) | ||
804 | { | ||
805 | struct clk_tegra *c = to_clk_tegra(hw); | ||
806 | u64 rate = parent_rate; | ||
807 | |||
808 | if (c->mul != 0 && c->div != 0) { | ||
809 | rate *= c->mul; | ||
810 | rate += c->div - 1; /* round up */ | ||
811 | do_div(rate, c->div); | ||
812 | } | ||
813 | |||
814 | return rate; | ||
815 | } | ||
816 | |||
817 | struct clk_ops tegra30_twd_ops = { | ||
818 | .recalc_rate = tegra30_twd_clk_recalc_rate, | ||
819 | }; | ||
820 | |||
821 | /* bus clock functions */ | ||
822 | static int tegra30_bus_clk_is_enabled(struct clk_hw *hw) | ||
823 | { | ||
824 | struct clk_tegra *c = to_clk_tegra(hw); | ||
825 | u32 val = clk_readl(c->reg); | ||
826 | |||
827 | c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON; | ||
828 | return c->state; | ||
829 | } | ||
830 | |||
831 | static int tegra30_bus_clk_enable(struct clk_hw *hw) | ||
832 | { | ||
833 | struct clk_tegra *c = to_clk_tegra(hw); | ||
834 | u32 val; | ||
835 | |||
836 | val = clk_readl(c->reg); | ||
837 | val &= ~(BUS_CLK_DISABLE << c->reg_shift); | ||
838 | clk_writel(val, c->reg); | ||
839 | |||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | static void tegra30_bus_clk_disable(struct clk_hw *hw) | ||
844 | { | ||
845 | struct clk_tegra *c = to_clk_tegra(hw); | ||
846 | u32 val; | ||
847 | |||
848 | val = clk_readl(c->reg); | ||
849 | val |= BUS_CLK_DISABLE << c->reg_shift; | ||
850 | clk_writel(val, c->reg); | ||
851 | } | ||
852 | |||
853 | static unsigned long tegra30_bus_clk_recalc_rate(struct clk_hw *hw, | ||
854 | unsigned long prate) | ||
855 | { | ||
856 | struct clk_tegra *c = to_clk_tegra(hw); | ||
857 | u32 val = clk_readl(c->reg); | ||
858 | u64 rate = prate; | ||
859 | |||
860 | c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1; | ||
861 | c->mul = 1; | ||
862 | |||
863 | if (c->mul != 0 && c->div != 0) { | ||
864 | rate *= c->mul; | ||
865 | rate += c->div - 1; /* round up */ | ||
866 | do_div(rate, c->div); | ||
867 | } | ||
868 | return rate; | ||
869 | } | ||
870 | |||
871 | static int tegra30_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
872 | unsigned long parent_rate) | ||
873 | { | ||
874 | struct clk_tegra *c = to_clk_tegra(hw); | ||
875 | int ret = -EINVAL; | ||
876 | u32 val; | ||
877 | int i; | ||
878 | |||
879 | val = clk_readl(c->reg); | ||
880 | for (i = 1; i <= 4; i++) { | ||
881 | if (rate == parent_rate / i) { | ||
882 | val &= ~(BUS_CLK_DIV_MASK << c->reg_shift); | ||
883 | val |= (i - 1) << c->reg_shift; | ||
884 | clk_writel(val, c->reg); | ||
885 | c->div = i; | ||
886 | c->mul = 1; | ||
887 | ret = 0; | ||
888 | break; | ||
889 | } | ||
890 | } | ||
891 | |||
892 | return ret; | ||
893 | } | ||
894 | |||
895 | static long tegra30_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
896 | unsigned long *prate) | ||
897 | { | ||
898 | unsigned long parent_rate = *prate; | ||
899 | s64 divider; | ||
900 | |||
901 | if (rate >= parent_rate) | ||
902 | return parent_rate; | ||
903 | |||
904 | divider = parent_rate; | ||
905 | divider += rate - 1; | ||
906 | do_div(divider, rate); | ||
907 | |||
908 | if (divider < 0) | ||
909 | return divider; | ||
910 | |||
911 | if (divider > 4) | ||
912 | divider = 4; | ||
913 | do_div(parent_rate, divider); | ||
914 | |||
915 | return parent_rate; | ||
916 | } | ||
917 | |||
918 | struct clk_ops tegra30_bus_ops = { | ||
919 | .is_enabled = tegra30_bus_clk_is_enabled, | ||
920 | .enable = tegra30_bus_clk_enable, | ||
921 | .disable = tegra30_bus_clk_disable, | ||
922 | .set_rate = tegra30_bus_clk_set_rate, | ||
923 | .round_rate = tegra30_bus_clk_round_rate, | ||
924 | .recalc_rate = tegra30_bus_clk_recalc_rate, | ||
925 | }; | ||
926 | |||
927 | /* Blink output functions */ | ||
928 | static int tegra30_blink_clk_is_enabled(struct clk_hw *hw) | ||
929 | { | ||
930 | struct clk_tegra *c = to_clk_tegra(hw); | ||
931 | u32 val; | ||
932 | |||
933 | val = pmc_readl(PMC_CTRL); | ||
934 | c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF; | ||
935 | return c->state; | ||
936 | } | ||
937 | |||
938 | static int tegra30_blink_clk_enable(struct clk_hw *hw) | ||
939 | { | ||
940 | u32 val; | ||
941 | |||
942 | val = pmc_readl(PMC_DPD_PADS_ORIDE); | ||
943 | pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); | ||
944 | |||
945 | val = pmc_readl(PMC_CTRL); | ||
946 | pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL); | ||
947 | |||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | static void tegra30_blink_clk_disable(struct clk_hw *hw) | ||
952 | { | ||
953 | u32 val; | ||
954 | |||
955 | val = pmc_readl(PMC_CTRL); | ||
956 | pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL); | ||
957 | |||
958 | val = pmc_readl(PMC_DPD_PADS_ORIDE); | ||
959 | pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); | ||
960 | } | ||
961 | |||
962 | static int tegra30_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
963 | unsigned long parent_rate) | ||
964 | { | ||
965 | struct clk_tegra *c = to_clk_tegra(hw); | ||
966 | |||
967 | if (rate >= parent_rate) { | ||
968 | c->div = 1; | ||
969 | pmc_writel(0, c->reg); | ||
970 | } else { | ||
971 | unsigned int on_off; | ||
972 | u32 val; | ||
973 | |||
974 | on_off = DIV_ROUND_UP(parent_rate / 8, rate); | ||
975 | c->div = on_off * 8; | ||
976 | |||
977 | val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) << | ||
978 | PMC_BLINK_TIMER_DATA_ON_SHIFT; | ||
979 | on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK; | ||
980 | on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT; | ||
981 | val |= on_off; | ||
982 | val |= PMC_BLINK_TIMER_ENB; | ||
983 | pmc_writel(val, c->reg); | ||
984 | } | ||
985 | |||
986 | return 0; | ||
987 | } | ||
988 | |||
989 | static unsigned long tegra30_blink_clk_recalc_rate(struct clk_hw *hw, | ||
990 | unsigned long parent_rate) | ||
991 | { | ||
992 | struct clk_tegra *c = to_clk_tegra(hw); | ||
993 | u64 rate = parent_rate; | ||
994 | u32 val; | ||
995 | u32 mul; | ||
996 | u32 div; | ||
997 | u32 on_off; | ||
998 | |||
999 | mul = 1; | ||
1000 | val = pmc_readl(c->reg); | ||
1001 | |||
1002 | if (val & PMC_BLINK_TIMER_ENB) { | ||
1003 | on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) & | ||
1004 | PMC_BLINK_TIMER_DATA_ON_MASK; | ||
1005 | val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT; | ||
1006 | val &= PMC_BLINK_TIMER_DATA_OFF_MASK; | ||
1007 | on_off += val; | ||
1008 | /* each tick in the blink timer is 4 32KHz clocks */ | ||
1009 | div = on_off * 4; | ||
1010 | } else { | ||
1011 | div = 1; | ||
1012 | } | ||
1013 | |||
1014 | if (mul != 0 && div != 0) { | ||
1015 | rate *= mul; | ||
1016 | rate += div - 1; /* round up */ | ||
1017 | do_div(rate, div); | ||
1018 | } | ||
1019 | return rate; | ||
1020 | } | ||
1021 | |||
1022 | static long tegra30_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1023 | unsigned long *prate) | ||
1024 | { | ||
1025 | int div; | ||
1026 | int mul; | ||
1027 | long round_rate = *prate; | ||
1028 | |||
1029 | mul = 1; | ||
1030 | |||
1031 | if (rate >= *prate) { | ||
1032 | div = 1; | ||
1033 | } else { | ||
1034 | div = DIV_ROUND_UP(*prate / 8, rate); | ||
1035 | div *= 8; | ||
1036 | } | ||
1037 | |||
1038 | round_rate *= mul; | ||
1039 | round_rate += div - 1; | ||
1040 | do_div(round_rate, div); | ||
1041 | |||
1042 | return round_rate; | ||
1043 | } | ||
1044 | |||
1045 | struct clk_ops tegra30_blink_clk_ops = { | ||
1046 | .is_enabled = tegra30_blink_clk_is_enabled, | ||
1047 | .enable = tegra30_blink_clk_enable, | ||
1048 | .disable = tegra30_blink_clk_disable, | ||
1049 | .recalc_rate = tegra30_blink_clk_recalc_rate, | ||
1050 | .round_rate = tegra30_blink_clk_round_rate, | ||
1051 | .set_rate = tegra30_blink_clk_set_rate, | ||
1052 | }; | ||
1053 | |||
1054 | static void tegra30_utmi_param_configure(struct clk_hw *hw) | ||
1055 | { | ||
1056 | unsigned long main_rate = | ||
1057 | __clk_get_rate(__clk_get_parent(__clk_get_parent(hw->clk))); | ||
1058 | u32 reg; | ||
1059 | int i; | ||
1060 | |||
1061 | for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { | ||
1062 | if (main_rate == utmi_parameters[i].osc_frequency) | ||
1063 | break; | ||
1064 | } | ||
1065 | |||
1066 | if (i >= ARRAY_SIZE(utmi_parameters)) { | ||
1067 | pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate); | ||
1068 | return; | ||
1069 | } | ||
1070 | |||
1071 | reg = clk_readl(UTMIP_PLL_CFG2); | ||
1072 | |||
1073 | /* Program UTMIP PLL stable and active counts */ | ||
1074 | /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */ | ||
1075 | reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); | ||
1076 | reg |= UTMIP_PLL_CFG2_STABLE_COUNT( | ||
1077 | utmi_parameters[i].stable_count); | ||
1078 | |||
1079 | reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); | ||
1080 | |||
1081 | reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT( | ||
1082 | utmi_parameters[i].active_delay_count); | ||
1083 | |||
1084 | /* Remove power downs from UTMIP PLL control bits */ | ||
1085 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; | ||
1086 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; | ||
1087 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN; | ||
1088 | |||
1089 | clk_writel(reg, UTMIP_PLL_CFG2); | ||
1090 | |||
1091 | /* Program UTMIP PLL delay and oscillator frequency counts */ | ||
1092 | reg = clk_readl(UTMIP_PLL_CFG1); | ||
1093 | reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); | ||
1094 | |||
1095 | reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT( | ||
1096 | utmi_parameters[i].enable_delay_count); | ||
1097 | |||
1098 | reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); | ||
1099 | reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT( | ||
1100 | utmi_parameters[i].xtal_freq_count); | ||
1101 | |||
1102 | /* Remove power downs from UTMIP PLL control bits */ | ||
1103 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; | ||
1104 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN; | ||
1105 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; | ||
1106 | |||
1107 | clk_writel(reg, UTMIP_PLL_CFG1); | ||
1108 | } | ||
1109 | |||
1110 | /* PLL Functions */ | ||
1111 | static int tegra30_pll_clk_wait_for_lock(struct clk_tegra *c, u32 lock_reg, | ||
1112 | u32 lock_bit) | ||
1113 | { | ||
1114 | int ret = 0; | ||
1115 | |||
1116 | #if USE_PLL_LOCK_BITS | ||
1117 | int i; | ||
1118 | for (i = 0; i < c->u.pll.lock_delay; i++) { | ||
1119 | if (clk_readl(lock_reg) & lock_bit) { | ||
1120 | udelay(PLL_POST_LOCK_DELAY); | ||
1121 | return 0; | ||
1122 | } | ||
1123 | udelay(2); /* timeout = 2 * lock time */ | ||
1124 | } | ||
1125 | pr_err("Timed out waiting for lock bit on pll %s", | ||
1126 | __clk_get_name(hw->clk)); | ||
1127 | ret = -1; | ||
1128 | #else | ||
1129 | udelay(c->u.pll.lock_delay); | ||
1130 | #endif | ||
1131 | return ret; | ||
1132 | } | ||
1133 | |||
1134 | static int tegra30_pll_clk_is_enabled(struct clk_hw *hw) | ||
1135 | { | ||
1136 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1137 | u32 val = clk_readl(c->reg + PLL_BASE); | ||
1138 | |||
1139 | c->state = (val & PLL_BASE_ENABLE) ? ON : OFF; | ||
1140 | return c->state; | ||
1141 | } | ||
1142 | |||
1143 | static void tegra30_pll_clk_init(struct clk_hw *hw) | ||
1144 | { | ||
1145 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1146 | |||
1147 | if (c->flags & PLLU) | ||
1148 | tegra30_utmi_param_configure(hw); | ||
1149 | } | ||
1150 | |||
1151 | static int tegra30_pll_clk_enable(struct clk_hw *hw) | ||
1152 | { | ||
1153 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1154 | u32 val; | ||
1155 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
1156 | |||
1157 | #if USE_PLL_LOCK_BITS | ||
1158 | val = clk_readl(c->reg + PLL_MISC(c)); | ||
1159 | val |= PLL_MISC_LOCK_ENABLE(c); | ||
1160 | clk_writel(val, c->reg + PLL_MISC(c)); | ||
1161 | #endif | ||
1162 | val = clk_readl(c->reg + PLL_BASE); | ||
1163 | val &= ~PLL_BASE_BYPASS; | ||
1164 | val |= PLL_BASE_ENABLE; | ||
1165 | clk_writel(val, c->reg + PLL_BASE); | ||
1166 | |||
1167 | if (c->flags & PLLM) { | ||
1168 | val = pmc_readl(PMC_PLLP_WB0_OVERRIDE); | ||
1169 | val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | ||
1170 | pmc_writel(val, PMC_PLLP_WB0_OVERRIDE); | ||
1171 | } | ||
1172 | |||
1173 | tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK); | ||
1174 | |||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | static void tegra30_pll_clk_disable(struct clk_hw *hw) | ||
1179 | { | ||
1180 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1181 | u32 val; | ||
1182 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); | ||
1183 | |||
1184 | val = clk_readl(c->reg); | ||
1185 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); | ||
1186 | clk_writel(val, c->reg); | ||
1187 | |||
1188 | if (c->flags & PLLM) { | ||
1189 | val = pmc_readl(PMC_PLLP_WB0_OVERRIDE); | ||
1190 | val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | ||
1191 | pmc_writel(val, PMC_PLLP_WB0_OVERRIDE); | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | static int tegra30_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1196 | unsigned long parent_rate) | ||
1197 | { | ||
1198 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1199 | u32 val, p_div, old_base; | ||
1200 | unsigned long input_rate; | ||
1201 | const struct clk_pll_freq_table *sel; | ||
1202 | struct clk_pll_freq_table cfg; | ||
1203 | |||
1204 | if (c->flags & PLL_FIXED) { | ||
1205 | int ret = 0; | ||
1206 | if (rate != c->u.pll.fixed_rate) { | ||
1207 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", | ||
1208 | __func__, __clk_get_name(hw->clk), | ||
1209 | c->u.pll.fixed_rate, rate); | ||
1210 | ret = -EINVAL; | ||
1211 | } | ||
1212 | return ret; | ||
1213 | } | ||
1214 | |||
1215 | if (c->flags & PLLM) { | ||
1216 | if (rate != __clk_get_rate(hw->clk)) { | ||
1217 | pr_err("%s: Can not change memory %s rate in flight\n", | ||
1218 | __func__, __clk_get_name(hw->clk)); | ||
1219 | return -EINVAL; | ||
1220 | } | ||
1221 | } | ||
1222 | |||
1223 | p_div = 0; | ||
1224 | input_rate = parent_rate; | ||
1225 | |||
1226 | /* Check if the target rate is tabulated */ | ||
1227 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
1228 | if (sel->input_rate == input_rate && sel->output_rate == rate) { | ||
1229 | if (c->flags & PLLU) { | ||
1230 | BUG_ON(sel->p < 1 || sel->p > 2); | ||
1231 | if (sel->p == 1) | ||
1232 | p_div = PLLU_BASE_POST_DIV; | ||
1233 | } else { | ||
1234 | BUG_ON(sel->p < 1); | ||
1235 | for (val = sel->p; val > 1; val >>= 1) | ||
1236 | p_div++; | ||
1237 | p_div <<= PLL_BASE_DIVP_SHIFT; | ||
1238 | } | ||
1239 | break; | ||
1240 | } | ||
1241 | } | ||
1242 | |||
1243 | /* Configure out-of-table rate */ | ||
1244 | if (sel->input_rate == 0) { | ||
1245 | unsigned long cfreq; | ||
1246 | BUG_ON(c->flags & PLLU); | ||
1247 | sel = &cfg; | ||
1248 | |||
1249 | switch (input_rate) { | ||
1250 | case 12000000: | ||
1251 | case 26000000: | ||
1252 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000; | ||
1253 | break; | ||
1254 | case 13000000: | ||
1255 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000; | ||
1256 | break; | ||
1257 | case 16800000: | ||
1258 | case 19200000: | ||
1259 | cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000; | ||
1260 | break; | ||
1261 | default: | ||
1262 | pr_err("%s: Unexpected reference rate %lu\n", | ||
1263 | __func__, input_rate); | ||
1264 | BUG(); | ||
1265 | } | ||
1266 | |||
1267 | /* Raise VCO to guarantee 0.5% accuracy */ | ||
1268 | for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq; | ||
1269 | cfg.output_rate <<= 1) | ||
1270 | p_div++; | ||
1271 | |||
1272 | cfg.p = 0x1 << p_div; | ||
1273 | cfg.m = input_rate / cfreq; | ||
1274 | cfg.n = cfg.output_rate / cfreq; | ||
1275 | cfg.cpcon = OUT_OF_TABLE_CPCON; | ||
1276 | |||
1277 | if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) || | ||
1278 | (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) || | ||
1279 | (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) || | ||
1280 | (cfg.output_rate > c->u.pll.vco_max)) { | ||
1281 | pr_err("%s: Failed to set %s out-of-table rate %lu\n", | ||
1282 | __func__, __clk_get_name(hw->clk), rate); | ||
1283 | return -EINVAL; | ||
1284 | } | ||
1285 | p_div <<= PLL_BASE_DIVP_SHIFT; | ||
1286 | } | ||
1287 | |||
1288 | c->mul = sel->n; | ||
1289 | c->div = sel->m * sel->p; | ||
1290 | |||
1291 | old_base = val = clk_readl(c->reg + PLL_BASE); | ||
1292 | val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK | | ||
1293 | ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK)); | ||
1294 | val |= (sel->m << PLL_BASE_DIVM_SHIFT) | | ||
1295 | (sel->n << PLL_BASE_DIVN_SHIFT) | p_div; | ||
1296 | if (val == old_base) | ||
1297 | return 0; | ||
1298 | |||
1299 | if (c->state == ON) { | ||
1300 | tegra30_pll_clk_disable(hw); | ||
1301 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); | ||
1302 | } | ||
1303 | clk_writel(val, c->reg + PLL_BASE); | ||
1304 | |||
1305 | if (c->flags & PLL_HAS_CPCON) { | ||
1306 | val = clk_readl(c->reg + PLL_MISC(c)); | ||
1307 | val &= ~PLL_MISC_CPCON_MASK; | ||
1308 | val |= sel->cpcon << PLL_MISC_CPCON_SHIFT; | ||
1309 | if (c->flags & (PLLU | PLLD)) { | ||
1310 | val &= ~PLL_MISC_LFCON_MASK; | ||
1311 | if (sel->n >= PLLDU_LFCON_SET_DIVN) | ||
1312 | val |= 0x1 << PLL_MISC_LFCON_SHIFT; | ||
1313 | } else if (c->flags & (PLLX | PLLM)) { | ||
1314 | val &= ~(0x1 << PLL_MISC_DCCON_SHIFT); | ||
1315 | if (rate >= (c->u.pll.vco_max >> 1)) | ||
1316 | val |= 0x1 << PLL_MISC_DCCON_SHIFT; | ||
1317 | } | ||
1318 | clk_writel(val, c->reg + PLL_MISC(c)); | ||
1319 | } | ||
1320 | |||
1321 | if (c->state == ON) | ||
1322 | tegra30_pll_clk_enable(hw); | ||
1323 | |||
1324 | c->u.pll.fixed_rate = rate; | ||
1325 | |||
1326 | return 0; | ||
1327 | } | ||
1328 | |||
1329 | static long tegra30_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1330 | unsigned long *prate) | ||
1331 | { | ||
1332 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1333 | unsigned long input_rate = *prate; | ||
1334 | u64 output_rate = *prate; | ||
1335 | const struct clk_pll_freq_table *sel; | ||
1336 | struct clk_pll_freq_table cfg; | ||
1337 | int mul; | ||
1338 | int div; | ||
1339 | u32 p_div; | ||
1340 | u32 val; | ||
1341 | |||
1342 | if (c->flags & PLL_FIXED) | ||
1343 | return c->u.pll.fixed_rate; | ||
1344 | |||
1345 | if (c->flags & PLLM) | ||
1346 | return __clk_get_rate(hw->clk); | ||
1347 | |||
1348 | p_div = 0; | ||
1349 | /* Check if the target rate is tabulated */ | ||
1350 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
1351 | if (sel->input_rate == input_rate && sel->output_rate == rate) { | ||
1352 | if (c->flags & PLLU) { | ||
1353 | BUG_ON(sel->p < 1 || sel->p > 2); | ||
1354 | if (sel->p == 1) | ||
1355 | p_div = PLLU_BASE_POST_DIV; | ||
1356 | } else { | ||
1357 | BUG_ON(sel->p < 1); | ||
1358 | for (val = sel->p; val > 1; val >>= 1) | ||
1359 | p_div++; | ||
1360 | p_div <<= PLL_BASE_DIVP_SHIFT; | ||
1361 | } | ||
1362 | break; | ||
1363 | } | ||
1364 | } | ||
1365 | |||
1366 | if (sel->input_rate == 0) { | ||
1367 | unsigned long cfreq; | ||
1368 | BUG_ON(c->flags & PLLU); | ||
1369 | sel = &cfg; | ||
1370 | |||
1371 | switch (input_rate) { | ||
1372 | case 12000000: | ||
1373 | case 26000000: | ||
1374 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000; | ||
1375 | break; | ||
1376 | case 13000000: | ||
1377 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000; | ||
1378 | break; | ||
1379 | case 16800000: | ||
1380 | case 19200000: | ||
1381 | cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000; | ||
1382 | break; | ||
1383 | default: | ||
1384 | pr_err("%s: Unexpected reference rate %lu\n", | ||
1385 | __func__, input_rate); | ||
1386 | BUG(); | ||
1387 | } | ||
1388 | |||
1389 | /* Raise VCO to guarantee 0.5% accuracy */ | ||
1390 | for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq; | ||
1391 | cfg.output_rate <<= 1) | ||
1392 | p_div++; | ||
1393 | |||
1394 | cfg.p = 0x1 << p_div; | ||
1395 | cfg.m = input_rate / cfreq; | ||
1396 | cfg.n = cfg.output_rate / cfreq; | ||
1397 | } | ||
1398 | |||
1399 | mul = sel->n; | ||
1400 | div = sel->m * sel->p; | ||
1401 | |||
1402 | output_rate *= mul; | ||
1403 | output_rate += div - 1; /* round up */ | ||
1404 | do_div(output_rate, div); | ||
1405 | |||
1406 | return output_rate; | ||
1407 | } | ||
1408 | |||
1409 | static unsigned long tegra30_pll_recalc_rate(struct clk_hw *hw, | ||
1410 | unsigned long parent_rate) | ||
1411 | { | ||
1412 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1413 | u64 rate = parent_rate; | ||
1414 | u32 val = clk_readl(c->reg + PLL_BASE); | ||
1415 | |||
1416 | if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) { | ||
1417 | const struct clk_pll_freq_table *sel; | ||
1418 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
1419 | if (sel->input_rate == parent_rate && | ||
1420 | sel->output_rate == c->u.pll.fixed_rate) { | ||
1421 | c->mul = sel->n; | ||
1422 | c->div = sel->m * sel->p; | ||
1423 | break; | ||
1424 | } | ||
1425 | } | ||
1426 | pr_err("Clock %s has unknown fixed frequency\n", | ||
1427 | __clk_get_name(hw->clk)); | ||
1428 | BUG(); | ||
1429 | } else if (val & PLL_BASE_BYPASS) { | ||
1430 | c->mul = 1; | ||
1431 | c->div = 1; | ||
1432 | } else { | ||
1433 | c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT; | ||
1434 | c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT; | ||
1435 | if (c->flags & PLLU) | ||
1436 | c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2; | ||
1437 | else | ||
1438 | c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >> | ||
1439 | PLL_BASE_DIVP_SHIFT)); | ||
1440 | } | ||
1441 | |||
1442 | if (c->mul != 0 && c->div != 0) { | ||
1443 | rate *= c->mul; | ||
1444 | rate += c->div - 1; /* round up */ | ||
1445 | do_div(rate, c->div); | ||
1446 | } | ||
1447 | |||
1448 | return rate; | ||
1449 | } | ||
1450 | |||
1451 | struct clk_ops tegra30_pll_ops = { | ||
1452 | .is_enabled = tegra30_pll_clk_is_enabled, | ||
1453 | .init = tegra30_pll_clk_init, | ||
1454 | .enable = tegra30_pll_clk_enable, | ||
1455 | .disable = tegra30_pll_clk_disable, | ||
1456 | .recalc_rate = tegra30_pll_recalc_rate, | ||
1457 | .round_rate = tegra30_pll_round_rate, | ||
1458 | .set_rate = tegra30_pll_clk_set_rate, | ||
1459 | }; | ||
1460 | |||
1461 | int tegra30_plld_clk_cfg_ex(struct clk_hw *hw, | ||
1462 | enum tegra_clk_ex_param p, u32 setting) | ||
1463 | { | ||
1464 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1465 | u32 val, mask, reg; | ||
1466 | |||
1467 | switch (p) { | ||
1468 | case TEGRA_CLK_PLLD_CSI_OUT_ENB: | ||
1469 | mask = PLLD_BASE_CSI_CLKENABLE; | ||
1470 | reg = c->reg + PLL_BASE; | ||
1471 | break; | ||
1472 | case TEGRA_CLK_PLLD_DSI_OUT_ENB: | ||
1473 | mask = PLLD_MISC_DSI_CLKENABLE; | ||
1474 | reg = c->reg + PLL_MISC(c); | ||
1475 | break; | ||
1476 | case TEGRA_CLK_PLLD_MIPI_MUX_SEL: | ||
1477 | if (!(c->flags & PLL_ALT_MISC_REG)) { | ||
1478 | mask = PLLD_BASE_DSIB_MUX_MASK; | ||
1479 | reg = c->reg + PLL_BASE; | ||
1480 | break; | ||
1481 | } | ||
1482 | /* fall through - error since PLLD2 does not have MUX_SEL control */ | ||
1483 | default: | ||
1484 | return -EINVAL; | ||
1485 | } | ||
1486 | |||
1487 | val = clk_readl(reg); | ||
1488 | if (setting) | ||
1489 | val |= mask; | ||
1490 | else | ||
1491 | val &= ~mask; | ||
1492 | clk_writel(val, reg); | ||
1493 | return 0; | ||
1494 | } | ||
1495 | |||
1496 | static int tegra30_plle_clk_is_enabled(struct clk_hw *hw) | ||
1497 | { | ||
1498 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1499 | u32 val; | ||
1500 | |||
1501 | val = clk_readl(c->reg + PLL_BASE); | ||
1502 | c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF; | ||
1503 | return c->state; | ||
1504 | } | ||
1505 | |||
1506 | static void tegra30_plle_clk_disable(struct clk_hw *hw) | ||
1507 | { | ||
1508 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1509 | u32 val; | ||
1510 | |||
1511 | val = clk_readl(c->reg + PLL_BASE); | ||
1512 | val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE); | ||
1513 | clk_writel(val, c->reg + PLL_BASE); | ||
1514 | } | ||
1515 | |||
1516 | static void tegra30_plle_training(struct clk_tegra *c) | ||
1517 | { | ||
1518 | u32 val; | ||
1519 | |||
1520 | /* PLLE is already disabled, and setup cleared; | ||
1521 | * create falling edge on PLLE IDDQ input */ | ||
1522 | val = pmc_readl(PMC_SATA_PWRGT); | ||
1523 | val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; | ||
1524 | pmc_writel(val, PMC_SATA_PWRGT); | ||
1525 | |||
1526 | val = pmc_readl(PMC_SATA_PWRGT); | ||
1527 | val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; | ||
1528 | pmc_writel(val, PMC_SATA_PWRGT); | ||
1529 | |||
1530 | val = pmc_readl(PMC_SATA_PWRGT); | ||
1531 | val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; | ||
1532 | pmc_writel(val, PMC_SATA_PWRGT); | ||
1533 | |||
1534 | do { | ||
1535 | val = clk_readl(c->reg + PLL_MISC(c)); | ||
1536 | } while (!(val & PLLE_MISC_READY)); | ||
1537 | } | ||
1538 | |||
1539 | static int tegra30_plle_configure(struct clk_hw *hw, bool force_training) | ||
1540 | { | ||
1541 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1542 | struct clk *parent = __clk_get_parent(hw->clk); | ||
1543 | const struct clk_pll_freq_table *sel; | ||
1544 | u32 val; | ||
1545 | |||
1546 | unsigned long rate = c->u.pll.fixed_rate; | ||
1547 | unsigned long input_rate = __clk_get_rate(parent); | ||
1548 | |||
1549 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
1550 | if (sel->input_rate == input_rate && sel->output_rate == rate) | ||
1551 | break; | ||
1552 | } | ||
1553 | |||
1554 | if (sel->input_rate == 0) | ||
1555 | return -ENOSYS; | ||
1556 | |||
1557 | /* disable PLLE, clear setup fiels */ | ||
1558 | tegra30_plle_clk_disable(hw); | ||
1559 | |||
1560 | val = clk_readl(c->reg + PLL_MISC(c)); | ||
1561 | val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK); | ||
1562 | clk_writel(val, c->reg + PLL_MISC(c)); | ||
1563 | |||
1564 | /* training */ | ||
1565 | val = clk_readl(c->reg + PLL_MISC(c)); | ||
1566 | if (force_training || (!(val & PLLE_MISC_READY))) | ||
1567 | tegra30_plle_training(c); | ||
1568 | |||
1569 | /* configure dividers, setup, disable SS */ | ||
1570 | val = clk_readl(c->reg + PLL_BASE); | ||
1571 | val &= ~PLLE_BASE_DIV_MASK; | ||
1572 | val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon); | ||
1573 | clk_writel(val, c->reg + PLL_BASE); | ||
1574 | c->mul = sel->n; | ||
1575 | c->div = sel->m * sel->p; | ||
1576 | |||
1577 | val = clk_readl(c->reg + PLL_MISC(c)); | ||
1578 | val |= PLLE_MISC_SETUP_VALUE; | ||
1579 | val |= PLLE_MISC_LOCK_ENABLE; | ||
1580 | clk_writel(val, c->reg + PLL_MISC(c)); | ||
1581 | |||
1582 | val = clk_readl(PLLE_SS_CTRL); | ||
1583 | val |= PLLE_SS_DISABLE; | ||
1584 | clk_writel(val, PLLE_SS_CTRL); | ||
1585 | |||
1586 | /* enable and lock PLLE*/ | ||
1587 | val = clk_readl(c->reg + PLL_BASE); | ||
1588 | val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE); | ||
1589 | clk_writel(val, c->reg + PLL_BASE); | ||
1590 | |||
1591 | tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK); | ||
1592 | |||
1593 | return 0; | ||
1594 | } | ||
1595 | |||
1596 | static int tegra30_plle_clk_enable(struct clk_hw *hw) | ||
1597 | { | ||
1598 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1599 | |||
1600 | return tegra30_plle_configure(hw, !c->set); | ||
1601 | } | ||
1602 | |||
1603 | static unsigned long tegra30_plle_clk_recalc_rate(struct clk_hw *hw, | ||
1604 | unsigned long parent_rate) | ||
1605 | { | ||
1606 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1607 | unsigned long rate = parent_rate; | ||
1608 | u32 val; | ||
1609 | |||
1610 | val = clk_readl(c->reg + PLL_BASE); | ||
1611 | c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT; | ||
1612 | c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT; | ||
1613 | c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT; | ||
1614 | |||
1615 | if (c->mul != 0 && c->div != 0) { | ||
1616 | rate *= c->mul; | ||
1617 | rate += c->div - 1; /* round up */ | ||
1618 | do_div(rate, c->div); | ||
1619 | } | ||
1620 | return rate; | ||
1621 | } | ||
1622 | |||
1623 | struct clk_ops tegra30_plle_ops = { | ||
1624 | .is_enabled = tegra30_plle_clk_is_enabled, | ||
1625 | .enable = tegra30_plle_clk_enable, | ||
1626 | .disable = tegra30_plle_clk_disable, | ||
1627 | .recalc_rate = tegra30_plle_clk_recalc_rate, | ||
1628 | }; | ||
1629 | |||
1630 | /* Clock divider ops */ | ||
1631 | static int tegra30_pll_div_clk_is_enabled(struct clk_hw *hw) | ||
1632 | { | ||
1633 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1634 | |||
1635 | if (c->flags & DIV_U71) { | ||
1636 | u32 val = clk_readl(c->reg); | ||
1637 | val >>= c->reg_shift; | ||
1638 | c->state = (val & PLL_OUT_CLKEN) ? ON : OFF; | ||
1639 | if (!(val & PLL_OUT_RESET_DISABLE)) | ||
1640 | c->state = OFF; | ||
1641 | } else { | ||
1642 | c->state = ON; | ||
1643 | } | ||
1644 | return c->state; | ||
1645 | } | ||
1646 | |||
1647 | static int tegra30_pll_div_clk_enable(struct clk_hw *hw) | ||
1648 | { | ||
1649 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1650 | u32 val; | ||
1651 | u32 new_val; | ||
1652 | |||
1653 | pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk)); | ||
1654 | if (c->flags & DIV_U71) { | ||
1655 | val = clk_readl(c->reg); | ||
1656 | new_val = val >> c->reg_shift; | ||
1657 | new_val &= 0xFFFF; | ||
1658 | |||
1659 | new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE; | ||
1660 | |||
1661 | val &= ~(0xFFFF << c->reg_shift); | ||
1662 | val |= new_val << c->reg_shift; | ||
1663 | clk_writel_delay(val, c->reg); | ||
1664 | return 0; | ||
1665 | } else if (c->flags & DIV_2) { | ||
1666 | return 0; | ||
1667 | } | ||
1668 | return -EINVAL; | ||
1669 | } | ||
1670 | |||
1671 | static void tegra30_pll_div_clk_disable(struct clk_hw *hw) | ||
1672 | { | ||
1673 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1674 | u32 val; | ||
1675 | u32 new_val; | ||
1676 | |||
1677 | pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk)); | ||
1678 | if (c->flags & DIV_U71) { | ||
1679 | val = clk_readl(c->reg); | ||
1680 | new_val = val >> c->reg_shift; | ||
1681 | new_val &= 0xFFFF; | ||
1682 | |||
1683 | new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE); | ||
1684 | |||
1685 | val &= ~(0xFFFF << c->reg_shift); | ||
1686 | val |= new_val << c->reg_shift; | ||
1687 | clk_writel_delay(val, c->reg); | ||
1688 | } | ||
1689 | } | ||
1690 | |||
1691 | static int tegra30_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1692 | unsigned long parent_rate) | ||
1693 | { | ||
1694 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1695 | u32 val; | ||
1696 | u32 new_val; | ||
1697 | int divider_u71; | ||
1698 | |||
1699 | if (c->flags & DIV_U71) { | ||
1700 | divider_u71 = clk_div71_get_divider( | ||
1701 | parent_rate, rate, c->flags, ROUND_DIVIDER_UP); | ||
1702 | if (divider_u71 >= 0) { | ||
1703 | val = clk_readl(c->reg); | ||
1704 | new_val = val >> c->reg_shift; | ||
1705 | new_val &= 0xFFFF; | ||
1706 | if (c->flags & DIV_U71_FIXED) | ||
1707 | new_val |= PLL_OUT_OVERRIDE; | ||
1708 | new_val &= ~PLL_OUT_RATIO_MASK; | ||
1709 | new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT; | ||
1710 | |||
1711 | val &= ~(0xFFFF << c->reg_shift); | ||
1712 | val |= new_val << c->reg_shift; | ||
1713 | clk_writel_delay(val, c->reg); | ||
1714 | c->div = divider_u71 + 2; | ||
1715 | c->mul = 2; | ||
1716 | c->fixed_rate = rate; | ||
1717 | return 0; | ||
1718 | } | ||
1719 | } else if (c->flags & DIV_2) { | ||
1720 | c->fixed_rate = rate; | ||
1721 | return 0; | ||
1722 | } | ||
1723 | |||
1724 | return -EINVAL; | ||
1725 | } | ||
1726 | |||
1727 | static unsigned long tegra30_pll_div_clk_recalc_rate(struct clk_hw *hw, | ||
1728 | unsigned long parent_rate) | ||
1729 | { | ||
1730 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1731 | u64 rate = parent_rate; | ||
1732 | |||
1733 | if (c->flags & DIV_U71) { | ||
1734 | u32 divu71; | ||
1735 | u32 val = clk_readl(c->reg); | ||
1736 | val >>= c->reg_shift; | ||
1737 | |||
1738 | divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT; | ||
1739 | c->div = (divu71 + 2); | ||
1740 | c->mul = 2; | ||
1741 | } else if (c->flags & DIV_2) { | ||
1742 | if (c->flags & (PLLD | PLLX)) { | ||
1743 | c->div = 2; | ||
1744 | c->mul = 1; | ||
1745 | } else | ||
1746 | BUG(); | ||
1747 | } else { | ||
1748 | c->div = 1; | ||
1749 | c->mul = 1; | ||
1750 | } | ||
1751 | if (c->mul != 0 && c->div != 0) { | ||
1752 | rate *= c->mul; | ||
1753 | rate += c->div - 1; /* round up */ | ||
1754 | do_div(rate, c->div); | ||
1755 | } | ||
1756 | |||
1757 | return rate; | ||
1758 | } | ||
1759 | |||
1760 | static long tegra30_pll_div_clk_round_rate(struct clk_hw *hw, | ||
1761 | unsigned long rate, unsigned long *prate) | ||
1762 | { | ||
1763 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1764 | unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk)); | ||
1765 | int divider; | ||
1766 | |||
1767 | if (prate) | ||
1768 | parent_rate = *prate; | ||
1769 | |||
1770 | if (c->flags & DIV_U71) { | ||
1771 | divider = clk_div71_get_divider( | ||
1772 | parent_rate, rate, c->flags, ROUND_DIVIDER_UP); | ||
1773 | if (divider < 0) | ||
1774 | return divider; | ||
1775 | return DIV_ROUND_UP(parent_rate * 2, divider + 2); | ||
1776 | } else if (c->flags & DIV_2) { | ||
1777 | *prate = rate * 2; | ||
1778 | return rate; | ||
1779 | } | ||
1780 | |||
1781 | return -EINVAL; | ||
1782 | } | ||
1783 | |||
1784 | struct clk_ops tegra30_pll_div_ops = { | ||
1785 | .is_enabled = tegra30_pll_div_clk_is_enabled, | ||
1786 | .enable = tegra30_pll_div_clk_enable, | ||
1787 | .disable = tegra30_pll_div_clk_disable, | ||
1788 | .set_rate = tegra30_pll_div_clk_set_rate, | ||
1789 | .recalc_rate = tegra30_pll_div_clk_recalc_rate, | ||
1790 | .round_rate = tegra30_pll_div_clk_round_rate, | ||
1791 | }; | ||
1792 | |||
1793 | /* Periph clk ops */ | ||
1794 | static inline u32 periph_clk_source_mask(struct clk_tegra *c) | ||
1795 | { | ||
1796 | if (c->flags & MUX8) | ||
1797 | return 7 << 29; | ||
1798 | else if (c->flags & MUX_PWM) | ||
1799 | return 3 << 28; | ||
1800 | else if (c->flags & MUX_CLK_OUT) | ||
1801 | return 3 << (c->u.periph.clk_num + 4); | ||
1802 | else if (c->flags & PLLD) | ||
1803 | return PLLD_BASE_DSIB_MUX_MASK; | ||
1804 | else | ||
1805 | return 3 << 30; | ||
1806 | } | ||
1807 | |||
1808 | static inline u32 periph_clk_source_shift(struct clk_tegra *c) | ||
1809 | { | ||
1810 | if (c->flags & MUX8) | ||
1811 | return 29; | ||
1812 | else if (c->flags & MUX_PWM) | ||
1813 | return 28; | ||
1814 | else if (c->flags & MUX_CLK_OUT) | ||
1815 | return c->u.periph.clk_num + 4; | ||
1816 | else if (c->flags & PLLD) | ||
1817 | return PLLD_BASE_DSIB_MUX_SHIFT; | ||
1818 | else | ||
1819 | return 30; | ||
1820 | } | ||
1821 | |||
1822 | static int tegra30_periph_clk_is_enabled(struct clk_hw *hw) | ||
1823 | { | ||
1824 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1825 | |||
1826 | c->state = ON; | ||
1827 | if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) | ||
1828 | c->state = OFF; | ||
1829 | if (!(c->flags & PERIPH_NO_RESET)) | ||
1830 | if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c)) | ||
1831 | c->state = OFF; | ||
1832 | return c->state; | ||
1833 | } | ||
1834 | |||
1835 | static int tegra30_periph_clk_enable(struct clk_hw *hw) | ||
1836 | { | ||
1837 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1838 | |||
1839 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; | ||
1840 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) | ||
1841 | return 0; | ||
1842 | |||
1843 | clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c)); | ||
1844 | if (!(c->flags & PERIPH_NO_RESET) && | ||
1845 | !(c->flags & PERIPH_MANUAL_RESET)) { | ||
1846 | if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & | ||
1847 | PERIPH_CLK_TO_BIT(c)) { | ||
1848 | udelay(5); /* reset propagation delay */ | ||
1849 | clk_writel(PERIPH_CLK_TO_BIT(c), | ||
1850 | PERIPH_CLK_TO_RST_CLR_REG(c)); | ||
1851 | } | ||
1852 | } | ||
1853 | return 0; | ||
1854 | } | ||
1855 | |||
1856 | static void tegra30_periph_clk_disable(struct clk_hw *hw) | ||
1857 | { | ||
1858 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1859 | unsigned long val; | ||
1860 | |||
1861 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--; | ||
1862 | |||
1863 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0) | ||
1864 | return; | ||
1865 | |||
1866 | /* If peripheral is in the APB bus then read the APB bus to | ||
1867 | * flush the write operation in apb bus. This will avoid the | ||
1868 | * peripheral access after disabling clock*/ | ||
1869 | if (c->flags & PERIPH_ON_APB) | ||
1870 | val = chipid_readl(); | ||
1871 | |||
1872 | clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c)); | ||
1873 | } | ||
1874 | |||
1875 | void tegra30_periph_clk_reset(struct clk_hw *hw, bool assert) | ||
1876 | { | ||
1877 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1878 | unsigned long val; | ||
1879 | |||
1880 | if (!(c->flags & PERIPH_NO_RESET)) { | ||
1881 | if (assert) { | ||
1882 | /* If peripheral is in the APB bus then read the APB | ||
1883 | * bus to flush the write operation in apb bus. This | ||
1884 | * will avoid the peripheral access after disabling | ||
1885 | * clock */ | ||
1886 | if (c->flags & PERIPH_ON_APB) | ||
1887 | val = chipid_readl(); | ||
1888 | |||
1889 | clk_writel(PERIPH_CLK_TO_BIT(c), | ||
1890 | PERIPH_CLK_TO_RST_SET_REG(c)); | ||
1891 | } else | ||
1892 | clk_writel(PERIPH_CLK_TO_BIT(c), | ||
1893 | PERIPH_CLK_TO_RST_CLR_REG(c)); | ||
1894 | } | ||
1895 | } | ||
1896 | |||
1897 | static int tegra30_periph_clk_set_parent(struct clk_hw *hw, u8 index) | ||
1898 | { | ||
1899 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1900 | u32 val; | ||
1901 | |||
1902 | if (!(c->flags & MUX)) | ||
1903 | return (index == 0) ? 0 : (-EINVAL); | ||
1904 | |||
1905 | val = clk_readl(c->reg); | ||
1906 | val &= ~periph_clk_source_mask(c); | ||
1907 | val |= (index << periph_clk_source_shift(c)); | ||
1908 | clk_writel_delay(val, c->reg); | ||
1909 | return 0; | ||
1910 | } | ||
1911 | |||
1912 | static u8 tegra30_periph_clk_get_parent(struct clk_hw *hw) | ||
1913 | { | ||
1914 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1915 | u32 val = clk_readl(c->reg); | ||
1916 | int source = (val & periph_clk_source_mask(c)) >> | ||
1917 | periph_clk_source_shift(c); | ||
1918 | |||
1919 | if (!(c->flags & MUX)) | ||
1920 | return 0; | ||
1921 | |||
1922 | return source; | ||
1923 | } | ||
1924 | |||
1925 | static int tegra30_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1926 | unsigned long parent_rate) | ||
1927 | { | ||
1928 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1929 | u32 val; | ||
1930 | int divider; | ||
1931 | |||
1932 | if (c->flags & DIV_U71) { | ||
1933 | divider = clk_div71_get_divider( | ||
1934 | parent_rate, rate, c->flags, ROUND_DIVIDER_UP); | ||
1935 | if (divider >= 0) { | ||
1936 | val = clk_readl(c->reg); | ||
1937 | val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK; | ||
1938 | val |= divider; | ||
1939 | if (c->flags & DIV_U71_UART) { | ||
1940 | if (divider) | ||
1941 | val |= PERIPH_CLK_UART_DIV_ENB; | ||
1942 | else | ||
1943 | val &= ~PERIPH_CLK_UART_DIV_ENB; | ||
1944 | } | ||
1945 | clk_writel_delay(val, c->reg); | ||
1946 | c->div = divider + 2; | ||
1947 | c->mul = 2; | ||
1948 | return 0; | ||
1949 | } | ||
1950 | } else if (c->flags & DIV_U16) { | ||
1951 | divider = clk_div16_get_divider(parent_rate, rate); | ||
1952 | if (divider >= 0) { | ||
1953 | val = clk_readl(c->reg); | ||
1954 | val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK; | ||
1955 | val |= divider; | ||
1956 | clk_writel_delay(val, c->reg); | ||
1957 | c->div = divider + 1; | ||
1958 | c->mul = 1; | ||
1959 | return 0; | ||
1960 | } | ||
1961 | } else if (parent_rate <= rate) { | ||
1962 | c->div = 1; | ||
1963 | c->mul = 1; | ||
1964 | return 0; | ||
1965 | } | ||
1966 | return -EINVAL; | ||
1967 | } | ||
1968 | |||
1969 | static long tegra30_periph_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1970 | unsigned long *prate) | ||
1971 | { | ||
1972 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1973 | unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk)); | ||
1974 | int divider; | ||
1975 | |||
1976 | if (prate) | ||
1977 | parent_rate = *prate; | ||
1978 | |||
1979 | if (c->flags & DIV_U71) { | ||
1980 | divider = clk_div71_get_divider( | ||
1981 | parent_rate, rate, c->flags, ROUND_DIVIDER_UP); | ||
1982 | if (divider < 0) | ||
1983 | return divider; | ||
1984 | |||
1985 | return DIV_ROUND_UP(parent_rate * 2, divider + 2); | ||
1986 | } else if (c->flags & DIV_U16) { | ||
1987 | divider = clk_div16_get_divider(parent_rate, rate); | ||
1988 | if (divider < 0) | ||
1989 | return divider; | ||
1990 | return DIV_ROUND_UP(parent_rate, divider + 1); | ||
1991 | } | ||
1992 | return -EINVAL; | ||
1993 | } | ||
1994 | |||
1995 | static unsigned long tegra30_periph_clk_recalc_rate(struct clk_hw *hw, | ||
1996 | unsigned long parent_rate) | ||
1997 | { | ||
1998 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1999 | u64 rate = parent_rate; | ||
2000 | u32 val = clk_readl(c->reg); | ||
2001 | |||
2002 | if (c->flags & DIV_U71) { | ||
2003 | u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK; | ||
2004 | if ((c->flags & DIV_U71_UART) && | ||
2005 | (!(val & PERIPH_CLK_UART_DIV_ENB))) { | ||
2006 | divu71 = 0; | ||
2007 | } | ||
2008 | if (c->flags & DIV_U71_IDLE) { | ||
2009 | val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK << | ||
2010 | PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); | ||
2011 | val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL << | ||
2012 | PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); | ||
2013 | clk_writel(val, c->reg); | ||
2014 | } | ||
2015 | c->div = divu71 + 2; | ||
2016 | c->mul = 2; | ||
2017 | } else if (c->flags & DIV_U16) { | ||
2018 | u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK; | ||
2019 | c->div = divu16 + 1; | ||
2020 | c->mul = 1; | ||
2021 | } else { | ||
2022 | c->div = 1; | ||
2023 | c->mul = 1; | ||
2024 | } | ||
2025 | |||
2026 | if (c->mul != 0 && c->div != 0) { | ||
2027 | rate *= c->mul; | ||
2028 | rate += c->div - 1; /* round up */ | ||
2029 | do_div(rate, c->div); | ||
2030 | } | ||
2031 | return rate; | ||
2032 | } | ||
2033 | |||
2034 | struct clk_ops tegra30_periph_clk_ops = { | ||
2035 | .is_enabled = tegra30_periph_clk_is_enabled, | ||
2036 | .enable = tegra30_periph_clk_enable, | ||
2037 | .disable = tegra30_periph_clk_disable, | ||
2038 | .set_parent = tegra30_periph_clk_set_parent, | ||
2039 | .get_parent = tegra30_periph_clk_get_parent, | ||
2040 | .set_rate = tegra30_periph_clk_set_rate, | ||
2041 | .round_rate = tegra30_periph_clk_round_rate, | ||
2042 | .recalc_rate = tegra30_periph_clk_recalc_rate, | ||
2043 | }; | ||
2044 | |||
2045 | static int tegra30_dsib_clk_set_parent(struct clk_hw *hw, u8 index) | ||
2046 | { | ||
2047 | struct clk *d = clk_get_sys(NULL, "pll_d"); | ||
2048 | /* The DSIB parent selection bit is in PLLD base register */ | ||
2049 | tegra_clk_cfg_ex( | ||
2050 | d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, index); | ||
2051 | |||
2052 | return 0; | ||
2053 | } | ||
2054 | |||
2055 | struct clk_ops tegra30_dsib_clk_ops = { | ||
2056 | .is_enabled = tegra30_periph_clk_is_enabled, | ||
2057 | .enable = &tegra30_periph_clk_enable, | ||
2058 | .disable = &tegra30_periph_clk_disable, | ||
2059 | .set_parent = &tegra30_dsib_clk_set_parent, | ||
2060 | .get_parent = &tegra30_periph_clk_get_parent, | ||
2061 | .set_rate = &tegra30_periph_clk_set_rate, | ||
2062 | .round_rate = &tegra30_periph_clk_round_rate, | ||
2063 | .recalc_rate = &tegra30_periph_clk_recalc_rate, | ||
2064 | }; | ||
2065 | |||
2066 | /* Periph extended clock configuration ops */ | ||
2067 | int tegra30_vi_clk_cfg_ex(struct clk_hw *hw, | ||
2068 | enum tegra_clk_ex_param p, u32 setting) | ||
2069 | { | ||
2070 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2071 | |||
2072 | if (p == TEGRA_CLK_VI_INP_SEL) { | ||
2073 | u32 val = clk_readl(c->reg); | ||
2074 | val &= ~PERIPH_CLK_VI_SEL_EX_MASK; | ||
2075 | val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) & | ||
2076 | PERIPH_CLK_VI_SEL_EX_MASK; | ||
2077 | clk_writel(val, c->reg); | ||
2078 | return 0; | ||
2079 | } | ||
2080 | return -EINVAL; | ||
2081 | } | ||
2082 | |||
2083 | int tegra30_nand_clk_cfg_ex(struct clk_hw *hw, | ||
2084 | enum tegra_clk_ex_param p, u32 setting) | ||
2085 | { | ||
2086 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2087 | |||
2088 | if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) { | ||
2089 | u32 val = clk_readl(c->reg); | ||
2090 | if (setting) | ||
2091 | val |= PERIPH_CLK_NAND_DIV_EX_ENB; | ||
2092 | else | ||
2093 | val &= ~PERIPH_CLK_NAND_DIV_EX_ENB; | ||
2094 | clk_writel(val, c->reg); | ||
2095 | return 0; | ||
2096 | } | ||
2097 | return -EINVAL; | ||
2098 | } | ||
2099 | |||
2100 | int tegra30_dtv_clk_cfg_ex(struct clk_hw *hw, | ||
2101 | enum tegra_clk_ex_param p, u32 setting) | ||
2102 | { | ||
2103 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2104 | |||
2105 | if (p == TEGRA_CLK_DTV_INVERT) { | ||
2106 | u32 val = clk_readl(c->reg); | ||
2107 | if (setting) | ||
2108 | val |= PERIPH_CLK_DTV_POLARITY_INV; | ||
2109 | else | ||
2110 | val &= ~PERIPH_CLK_DTV_POLARITY_INV; | ||
2111 | clk_writel(val, c->reg); | ||
2112 | return 0; | ||
2113 | } | ||
2114 | return -EINVAL; | ||
2115 | } | ||
2116 | |||
2117 | /* Output clock ops */ | ||
2118 | |||
2119 | static DEFINE_SPINLOCK(clk_out_lock); | ||
2120 | |||
2121 | static int tegra30_clk_out_is_enabled(struct clk_hw *hw) | ||
2122 | { | ||
2123 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2124 | u32 val = pmc_readl(c->reg); | ||
2125 | |||
2126 | c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF; | ||
2127 | c->mul = 1; | ||
2128 | c->div = 1; | ||
2129 | return c->state; | ||
2130 | } | ||
2131 | |||
2132 | static int tegra30_clk_out_enable(struct clk_hw *hw) | ||
2133 | { | ||
2134 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2135 | u32 val; | ||
2136 | unsigned long flags; | ||
2137 | |||
2138 | spin_lock_irqsave(&clk_out_lock, flags); | ||
2139 | val = pmc_readl(c->reg); | ||
2140 | val |= (0x1 << c->u.periph.clk_num); | ||
2141 | pmc_writel(val, c->reg); | ||
2142 | spin_unlock_irqrestore(&clk_out_lock, flags); | ||
2143 | |||
2144 | return 0; | ||
2145 | } | ||
2146 | |||
2147 | static void tegra30_clk_out_disable(struct clk_hw *hw) | ||
2148 | { | ||
2149 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2150 | u32 val; | ||
2151 | unsigned long flags; | ||
2152 | |||
2153 | spin_lock_irqsave(&clk_out_lock, flags); | ||
2154 | val = pmc_readl(c->reg); | ||
2155 | val &= ~(0x1 << c->u.periph.clk_num); | ||
2156 | pmc_writel(val, c->reg); | ||
2157 | spin_unlock_irqrestore(&clk_out_lock, flags); | ||
2158 | } | ||
2159 | |||
2160 | static int tegra30_clk_out_set_parent(struct clk_hw *hw, u8 index) | ||
2161 | { | ||
2162 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2163 | u32 val; | ||
2164 | unsigned long flags; | ||
2165 | |||
2166 | spin_lock_irqsave(&clk_out_lock, flags); | ||
2167 | val = pmc_readl(c->reg); | ||
2168 | val &= ~periph_clk_source_mask(c); | ||
2169 | val |= (index << periph_clk_source_shift(c)); | ||
2170 | pmc_writel(val, c->reg); | ||
2171 | spin_unlock_irqrestore(&clk_out_lock, flags); | ||
2172 | |||
2173 | return 0; | ||
2174 | } | ||
2175 | |||
2176 | static u8 tegra30_clk_out_get_parent(struct clk_hw *hw) | ||
2177 | { | ||
2178 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2179 | u32 val = pmc_readl(c->reg); | ||
2180 | int source; | ||
2181 | |||
2182 | source = (val & periph_clk_source_mask(c)) >> | ||
2183 | periph_clk_source_shift(c); | ||
2184 | return source; | ||
2185 | } | ||
2186 | |||
2187 | struct clk_ops tegra_clk_out_ops = { | ||
2188 | .is_enabled = tegra30_clk_out_is_enabled, | ||
2189 | .enable = tegra30_clk_out_enable, | ||
2190 | .disable = tegra30_clk_out_disable, | ||
2191 | .set_parent = tegra30_clk_out_set_parent, | ||
2192 | .get_parent = tegra30_clk_out_get_parent, | ||
2193 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
2194 | }; | ||
2195 | |||
2196 | /* Clock doubler ops */ | ||
2197 | static int tegra30_clk_double_is_enabled(struct clk_hw *hw) | ||
2198 | { | ||
2199 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2200 | |||
2201 | c->state = ON; | ||
2202 | if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) | ||
2203 | c->state = OFF; | ||
2204 | return c->state; | ||
2205 | }; | ||
2206 | |||
2207 | static int tegra30_clk_double_set_rate(struct clk_hw *hw, unsigned long rate, | ||
2208 | unsigned long parent_rate) | ||
2209 | { | ||
2210 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2211 | u32 val; | ||
2212 | |||
2213 | if (rate == parent_rate) { | ||
2214 | val = clk_readl(c->reg) | (0x1 << c->reg_shift); | ||
2215 | clk_writel(val, c->reg); | ||
2216 | c->mul = 1; | ||
2217 | c->div = 1; | ||
2218 | return 0; | ||
2219 | } else if (rate == 2 * parent_rate) { | ||
2220 | val = clk_readl(c->reg) & (~(0x1 << c->reg_shift)); | ||
2221 | clk_writel(val, c->reg); | ||
2222 | c->mul = 2; | ||
2223 | c->div = 1; | ||
2224 | return 0; | ||
2225 | } | ||
2226 | return -EINVAL; | ||
2227 | } | ||
2228 | |||
2229 | static unsigned long tegra30_clk_double_recalc_rate(struct clk_hw *hw, | ||
2230 | unsigned long parent_rate) | ||
2231 | { | ||
2232 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2233 | u64 rate = parent_rate; | ||
2234 | |||
2235 | u32 val = clk_readl(c->reg); | ||
2236 | c->mul = val & (0x1 << c->reg_shift) ? 1 : 2; | ||
2237 | c->div = 1; | ||
2238 | |||
2239 | if (c->mul != 0 && c->div != 0) { | ||
2240 | rate *= c->mul; | ||
2241 | rate += c->div - 1; /* round up */ | ||
2242 | do_div(rate, c->div); | ||
2243 | } | ||
2244 | |||
2245 | return rate; | ||
2246 | } | ||
2247 | |||
2248 | static long tegra30_clk_double_round_rate(struct clk_hw *hw, unsigned long rate, | ||
2249 | unsigned long *prate) | ||
2250 | { | ||
2251 | unsigned long output_rate = *prate; | ||
2252 | |||
2253 | do_div(output_rate, 2); | ||
2254 | return output_rate; | ||
2255 | } | ||
2256 | |||
2257 | struct clk_ops tegra30_clk_double_ops = { | ||
2258 | .is_enabled = tegra30_clk_double_is_enabled, | ||
2259 | .enable = tegra30_periph_clk_enable, | ||
2260 | .disable = tegra30_periph_clk_disable, | ||
2261 | .recalc_rate = tegra30_clk_double_recalc_rate, | ||
2262 | .round_rate = tegra30_clk_double_round_rate, | ||
2263 | .set_rate = tegra30_clk_double_set_rate, | ||
2264 | }; | ||
2265 | |||
2266 | /* Audio sync clock ops */ | ||
2267 | struct clk_ops tegra_sync_source_ops = { | ||
2268 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
2269 | }; | ||
2270 | |||
2271 | static int tegra30_audio_sync_clk_is_enabled(struct clk_hw *hw) | ||
2272 | { | ||
2273 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2274 | u32 val = clk_readl(c->reg); | ||
2275 | c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON; | ||
2276 | return c->state; | ||
2277 | } | ||
2278 | |||
2279 | static int tegra30_audio_sync_clk_enable(struct clk_hw *hw) | ||
2280 | { | ||
2281 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2282 | u32 val = clk_readl(c->reg); | ||
2283 | clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg); | ||
2284 | return 0; | ||
2285 | } | ||
2286 | |||
2287 | static void tegra30_audio_sync_clk_disable(struct clk_hw *hw) | ||
2288 | { | ||
2289 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2290 | u32 val = clk_readl(c->reg); | ||
2291 | clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg); | ||
2292 | } | ||
2293 | |||
2294 | static int tegra30_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index) | ||
2295 | { | ||
2296 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2297 | u32 val; | ||
2298 | |||
2299 | val = clk_readl(c->reg); | ||
2300 | val &= ~AUDIO_SYNC_SOURCE_MASK; | ||
2301 | val |= index; | ||
2302 | |||
2303 | clk_writel(val, c->reg); | ||
2304 | return 0; | ||
2305 | } | ||
2306 | |||
2307 | static u8 tegra30_audio_sync_clk_get_parent(struct clk_hw *hw) | ||
2308 | { | ||
2309 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2310 | u32 val = clk_readl(c->reg); | ||
2311 | int source; | ||
2312 | |||
2313 | source = val & AUDIO_SYNC_SOURCE_MASK; | ||
2314 | return source; | ||
2315 | } | ||
2316 | |||
2317 | struct clk_ops tegra30_audio_sync_clk_ops = { | ||
2318 | .is_enabled = tegra30_audio_sync_clk_is_enabled, | ||
2319 | .enable = tegra30_audio_sync_clk_enable, | ||
2320 | .disable = tegra30_audio_sync_clk_disable, | ||
2321 | .set_parent = tegra30_audio_sync_clk_set_parent, | ||
2322 | .get_parent = tegra30_audio_sync_clk_get_parent, | ||
2323 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
2324 | }; | ||
2325 | |||
2326 | /* cml0 (pcie), and cml1 (sata) clock ops */ | ||
2327 | static int tegra30_cml_clk_is_enabled(struct clk_hw *hw) | ||
2328 | { | ||
2329 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2330 | u32 val = clk_readl(c->reg); | ||
2331 | c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF; | ||
2332 | return c->state; | ||
2333 | } | ||
2334 | |||
2335 | static int tegra30_cml_clk_enable(struct clk_hw *hw) | ||
2336 | { | ||
2337 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2338 | |||
2339 | u32 val = clk_readl(c->reg); | ||
2340 | val |= (0x1 << c->u.periph.clk_num); | ||
2341 | clk_writel(val, c->reg); | ||
2342 | |||
2343 | return 0; | ||
2344 | } | ||
2345 | |||
2346 | static void tegra30_cml_clk_disable(struct clk_hw *hw) | ||
2347 | { | ||
2348 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2349 | |||
2350 | u32 val = clk_readl(c->reg); | ||
2351 | val &= ~(0x1 << c->u.periph.clk_num); | ||
2352 | clk_writel(val, c->reg); | ||
2353 | } | ||
2354 | |||
2355 | struct clk_ops tegra_cml_clk_ops = { | ||
2356 | .is_enabled = tegra30_cml_clk_is_enabled, | ||
2357 | .enable = tegra30_cml_clk_enable, | ||
2358 | .disable = tegra30_cml_clk_disable, | ||
2359 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
2360 | }; | ||
2361 | |||
2362 | struct clk_ops tegra_pciex_clk_ops = { | ||
2363 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
2364 | }; | ||
2365 | |||
2366 | /* Tegra30 CPU clock and reset control functions */ | ||
2367 | static void tegra30_wait_cpu_in_reset(u32 cpu) | ||
2368 | { | ||
2369 | unsigned int reg; | ||
2370 | |||
2371 | do { | ||
2372 | reg = readl(reg_clk_base + | ||
2373 | TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); | ||
2374 | cpu_relax(); | ||
2375 | } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ | ||
2376 | |||
2377 | return; | ||
2378 | } | ||
2379 | |||
2380 | static void tegra30_put_cpu_in_reset(u32 cpu) | ||
2381 | { | ||
2382 | writel(CPU_RESET(cpu), | ||
2383 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
2384 | dmb(); | ||
2385 | } | ||
2386 | |||
2387 | static void tegra30_cpu_out_of_reset(u32 cpu) | ||
2388 | { | ||
2389 | writel(CPU_RESET(cpu), | ||
2390 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); | ||
2391 | wmb(); | ||
2392 | } | ||
2393 | |||
2394 | static void tegra30_enable_cpu_clock(u32 cpu) | ||
2395 | { | ||
2396 | unsigned int reg; | ||
2397 | |||
2398 | writel(CPU_CLOCK(cpu), | ||
2399 | reg_clk_base + TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); | ||
2400 | reg = readl(reg_clk_base + | ||
2401 | TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); | ||
2402 | } | ||
2403 | |||
2404 | static void tegra30_disable_cpu_clock(u32 cpu) | ||
2405 | { | ||
2406 | |||
2407 | unsigned int reg; | ||
2408 | |||
2409 | reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
2410 | writel(reg | CPU_CLOCK(cpu), | ||
2411 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
2412 | } | ||
2413 | |||
2414 | #ifdef CONFIG_PM_SLEEP | ||
2415 | static bool tegra30_cpu_rail_off_ready(void) | ||
2416 | { | ||
2417 | unsigned int cpu_rst_status; | ||
2418 | int cpu_pwr_status; | ||
2419 | |||
2420 | cpu_rst_status = readl(reg_clk_base + | ||
2421 | TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); | ||
2422 | cpu_pwr_status = tegra_powergate_is_powered(TEGRA_POWERGATE_CPU1) || | ||
2423 | tegra_powergate_is_powered(TEGRA_POWERGATE_CPU2) || | ||
2424 | tegra_powergate_is_powered(TEGRA_POWERGATE_CPU3); | ||
2425 | |||
2426 | if (((cpu_rst_status & 0xE) != 0xE) || cpu_pwr_status) | ||
2427 | return false; | ||
2428 | |||
2429 | return true; | ||
2430 | } | ||
2431 | |||
2432 | static void tegra30_cpu_clock_suspend(void) | ||
2433 | { | ||
2434 | /* switch coresite to clk_m, save off original source */ | ||
2435 | tegra30_cpu_clk_sctx.clk_csite_src = | ||
2436 | readl(reg_clk_base + CLK_RESET_SOURCE_CSITE); | ||
2437 | writel(3<<30, reg_clk_base + CLK_RESET_SOURCE_CSITE); | ||
2438 | |||
2439 | tegra30_cpu_clk_sctx.cpu_burst = | ||
2440 | readl(reg_clk_base + CLK_RESET_CCLK_BURST); | ||
2441 | tegra30_cpu_clk_sctx.pllx_base = | ||
2442 | readl(reg_clk_base + CLK_RESET_PLLX_BASE); | ||
2443 | tegra30_cpu_clk_sctx.pllx_misc = | ||
2444 | readl(reg_clk_base + CLK_RESET_PLLX_MISC); | ||
2445 | tegra30_cpu_clk_sctx.cclk_divider = | ||
2446 | readl(reg_clk_base + CLK_RESET_CCLK_DIVIDER); | ||
2447 | } | ||
2448 | |||
2449 | static void tegra30_cpu_clock_resume(void) | ||
2450 | { | ||
2451 | unsigned int reg, policy; | ||
2452 | |||
2453 | /* Is CPU complex already running on PLLX? */ | ||
2454 | reg = readl(reg_clk_base + CLK_RESET_CCLK_BURST); | ||
2455 | policy = (reg >> CLK_RESET_CCLK_BURST_POLICY_SHIFT) & 0xF; | ||
2456 | |||
2457 | if (policy == CLK_RESET_CCLK_IDLE_POLICY) | ||
2458 | reg = (reg >> CLK_RESET_CCLK_IDLE_POLICY_SHIFT) & 0xF; | ||
2459 | else if (policy == CLK_RESET_CCLK_RUN_POLICY) | ||
2460 | reg = (reg >> CLK_RESET_CCLK_RUN_POLICY_SHIFT) & 0xF; | ||
2461 | else | ||
2462 | BUG(); | ||
2463 | |||
2464 | if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) { | ||
2465 | /* restore PLLX settings if CPU is on different PLL */ | ||
2466 | writel(tegra30_cpu_clk_sctx.pllx_misc, | ||
2467 | reg_clk_base + CLK_RESET_PLLX_MISC); | ||
2468 | writel(tegra30_cpu_clk_sctx.pllx_base, | ||
2469 | reg_clk_base + CLK_RESET_PLLX_BASE); | ||
2470 | |||
2471 | /* wait for PLL stabilization if PLLX was enabled */ | ||
2472 | if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) | ||
2473 | udelay(300); | ||
2474 | } | ||
2475 | |||
2476 | /* | ||
2477 | * Restore original burst policy setting for calls resulting from CPU | ||
2478 | * LP2 in idle or system suspend. | ||
2479 | */ | ||
2480 | writel(tegra30_cpu_clk_sctx.cclk_divider, | ||
2481 | reg_clk_base + CLK_RESET_CCLK_DIVIDER); | ||
2482 | writel(tegra30_cpu_clk_sctx.cpu_burst, | ||
2483 | reg_clk_base + CLK_RESET_CCLK_BURST); | ||
2484 | |||
2485 | writel(tegra30_cpu_clk_sctx.clk_csite_src, | ||
2486 | reg_clk_base + CLK_RESET_SOURCE_CSITE); | ||
2487 | } | ||
2488 | #endif | ||
2489 | |||
2490 | static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { | ||
2491 | .wait_for_reset = tegra30_wait_cpu_in_reset, | ||
2492 | .put_in_reset = tegra30_put_cpu_in_reset, | ||
2493 | .out_of_reset = tegra30_cpu_out_of_reset, | ||
2494 | .enable_clock = tegra30_enable_cpu_clock, | ||
2495 | .disable_clock = tegra30_disable_cpu_clock, | ||
2496 | #ifdef CONFIG_PM_SLEEP | ||
2497 | .rail_off_ready = tegra30_cpu_rail_off_ready, | ||
2498 | .suspend = tegra30_cpu_clock_suspend, | ||
2499 | .resume = tegra30_cpu_clock_resume, | ||
2500 | #endif | ||
2501 | }; | ||
2502 | |||
2503 | void __init tegra30_cpu_car_ops_init(void) | ||
2504 | { | ||
2505 | tegra_cpu_car_ops = &tegra30_cpu_car_ops; | ||
2506 | } | ||
diff --git a/arch/arm/mach-tegra/tegra30_clocks.h b/arch/arm/mach-tegra/tegra30_clocks.h deleted file mode 100644 index 7a34adb2f72d..000000000000 --- a/arch/arm/mach-tegra/tegra30_clocks.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __MACH_TEGRA30_CLOCK_H | ||
18 | #define __MACH_TEGRA30_CLOCK_H | ||
19 | |||
20 | extern struct clk_ops tegra30_clk_32k_ops; | ||
21 | extern struct clk_ops tegra30_clk_m_ops; | ||
22 | extern struct clk_ops tegra_clk_m_div_ops; | ||
23 | extern struct clk_ops tegra_pll_ref_ops; | ||
24 | extern struct clk_ops tegra30_pll_ops; | ||
25 | extern struct clk_ops tegra30_pll_div_ops; | ||
26 | extern struct clk_ops tegra_plld_ops; | ||
27 | extern struct clk_ops tegra30_plle_ops; | ||
28 | extern struct clk_ops tegra_cml_clk_ops; | ||
29 | extern struct clk_ops tegra_pciex_clk_ops; | ||
30 | extern struct clk_ops tegra_sync_source_ops; | ||
31 | extern struct clk_ops tegra30_audio_sync_clk_ops; | ||
32 | extern struct clk_ops tegra30_clk_double_ops; | ||
33 | extern struct clk_ops tegra_clk_out_ops; | ||
34 | extern struct clk_ops tegra30_super_ops; | ||
35 | extern struct clk_ops tegra30_blink_clk_ops; | ||
36 | extern struct clk_ops tegra30_twd_ops; | ||
37 | extern struct clk_ops tegra30_bus_ops; | ||
38 | extern struct clk_ops tegra30_periph_clk_ops; | ||
39 | extern struct clk_ops tegra30_dsib_clk_ops; | ||
40 | extern struct clk_ops tegra_nand_clk_ops; | ||
41 | extern struct clk_ops tegra_vi_clk_ops; | ||
42 | extern struct clk_ops tegra_dtv_clk_ops; | ||
43 | extern struct clk_ops tegra_clk_shared_bus_ops; | ||
44 | |||
45 | int tegra30_plld_clk_cfg_ex(struct clk_hw *hw, | ||
46 | enum tegra_clk_ex_param p, u32 setting); | ||
47 | void tegra30_periph_clk_reset(struct clk_hw *hw, bool assert); | ||
48 | int tegra30_vi_clk_cfg_ex(struct clk_hw *hw, | ||
49 | enum tegra_clk_ex_param p, u32 setting); | ||
50 | int tegra30_nand_clk_cfg_ex(struct clk_hw *hw, | ||
51 | enum tegra_clk_ex_param p, u32 setting); | ||
52 | int tegra30_dtv_clk_cfg_ex(struct clk_hw *hw, | ||
53 | enum tegra_clk_ex_param p, u32 setting); | ||
54 | #endif | ||
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c b/arch/arm/mach-tegra/tegra30_clocks_data.c deleted file mode 100644 index 741d264d5ecb..000000000000 --- a/arch/arm/mach-tegra/tegra30_clocks_data.c +++ /dev/null | |||
@@ -1,1425 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/tegra30_clocks.c | ||
3 | * | ||
4 | * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/clk-private.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/list.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/clk.h> | ||
30 | #include <linux/cpufreq.h> | ||
31 | |||
32 | #include "clock.h" | ||
33 | #include "fuse.h" | ||
34 | #include "tegra30_clocks.h" | ||
35 | #include "tegra_cpu_car.h" | ||
36 | |||
37 | #define DEFINE_CLK_TEGRA(_name, _rate, _ops, _flags, \ | ||
38 | _parent_names, _parents, _parent) \ | ||
39 | static struct clk tegra_##_name = { \ | ||
40 | .hw = &tegra_##_name##_hw.hw, \ | ||
41 | .name = #_name, \ | ||
42 | .rate = _rate, \ | ||
43 | .ops = _ops, \ | ||
44 | .flags = _flags, \ | ||
45 | .parent_names = _parent_names, \ | ||
46 | .parents = _parents, \ | ||
47 | .num_parents = ARRAY_SIZE(_parent_names), \ | ||
48 | .parent = _parent, \ | ||
49 | }; | ||
50 | |||
51 | static struct clk tegra_clk_32k; | ||
52 | static struct clk_tegra tegra_clk_32k_hw = { | ||
53 | .hw = { | ||
54 | .clk = &tegra_clk_32k, | ||
55 | }, | ||
56 | .fixed_rate = 32768, | ||
57 | }; | ||
58 | static struct clk tegra_clk_32k = { | ||
59 | .name = "clk_32k", | ||
60 | .hw = &tegra_clk_32k_hw.hw, | ||
61 | .ops = &tegra30_clk_32k_ops, | ||
62 | .flags = CLK_IS_ROOT, | ||
63 | }; | ||
64 | |||
65 | static struct clk tegra_clk_m; | ||
66 | static struct clk_tegra tegra_clk_m_hw = { | ||
67 | .hw = { | ||
68 | .clk = &tegra_clk_m, | ||
69 | }, | ||
70 | .flags = ENABLE_ON_INIT, | ||
71 | .reg = 0x1fc, | ||
72 | .reg_shift = 28, | ||
73 | .max_rate = 48000000, | ||
74 | }; | ||
75 | static struct clk tegra_clk_m = { | ||
76 | .name = "clk_m", | ||
77 | .hw = &tegra_clk_m_hw.hw, | ||
78 | .ops = &tegra30_clk_m_ops, | ||
79 | .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, | ||
80 | }; | ||
81 | |||
82 | static const char *clk_m_div_parent_names[] = { | ||
83 | "clk_m", | ||
84 | }; | ||
85 | |||
86 | static struct clk *clk_m_div_parents[] = { | ||
87 | &tegra_clk_m, | ||
88 | }; | ||
89 | |||
90 | static struct clk tegra_clk_m_div2; | ||
91 | static struct clk_tegra tegra_clk_m_div2_hw = { | ||
92 | .hw = { | ||
93 | .clk = &tegra_clk_m_div2, | ||
94 | }, | ||
95 | .mul = 1, | ||
96 | .div = 2, | ||
97 | .max_rate = 24000000, | ||
98 | }; | ||
99 | DEFINE_CLK_TEGRA(clk_m_div2, 0, &tegra_clk_m_div_ops, 0, | ||
100 | clk_m_div_parent_names, clk_m_div_parents, &tegra_clk_m); | ||
101 | |||
102 | static struct clk tegra_clk_m_div4; | ||
103 | static struct clk_tegra tegra_clk_m_div4_hw = { | ||
104 | .hw = { | ||
105 | .clk = &tegra_clk_m_div4, | ||
106 | }, | ||
107 | .mul = 1, | ||
108 | .div = 4, | ||
109 | .max_rate = 12000000, | ||
110 | }; | ||
111 | DEFINE_CLK_TEGRA(clk_m_div4, 0, &tegra_clk_m_div_ops, 0, | ||
112 | clk_m_div_parent_names, clk_m_div_parents, &tegra_clk_m); | ||
113 | |||
114 | static struct clk tegra_pll_ref; | ||
115 | static struct clk_tegra tegra_pll_ref_hw = { | ||
116 | .hw = { | ||
117 | .clk = &tegra_pll_ref, | ||
118 | }, | ||
119 | .flags = ENABLE_ON_INIT, | ||
120 | .max_rate = 26000000, | ||
121 | }; | ||
122 | DEFINE_CLK_TEGRA(pll_ref, 0, &tegra_pll_ref_ops, 0, clk_m_div_parent_names, | ||
123 | clk_m_div_parents, &tegra_clk_m); | ||
124 | |||
125 | #define DEFINE_PLL(_name, _flags, _reg, _max_rate, _input_min, \ | ||
126 | _input_max, _cf_min, _cf_max, _vco_min, \ | ||
127 | _vco_max, _freq_table, _lock_delay, _ops, \ | ||
128 | _fixed_rate, _clk_cfg_ex, _parent) \ | ||
129 | static struct clk tegra_##_name; \ | ||
130 | static const char *_name##_parent_names[] = { \ | ||
131 | #_parent, \ | ||
132 | }; \ | ||
133 | static struct clk *_name##_parents[] = { \ | ||
134 | &tegra_##_parent, \ | ||
135 | }; \ | ||
136 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
137 | .hw = { \ | ||
138 | .clk = &tegra_##_name, \ | ||
139 | }, \ | ||
140 | .flags = _flags, \ | ||
141 | .reg = _reg, \ | ||
142 | .max_rate = _max_rate, \ | ||
143 | .u.pll = { \ | ||
144 | .input_min = _input_min, \ | ||
145 | .input_max = _input_max, \ | ||
146 | .cf_min = _cf_min, \ | ||
147 | .cf_max = _cf_max, \ | ||
148 | .vco_min = _vco_min, \ | ||
149 | .vco_max = _vco_max, \ | ||
150 | .freq_table = _freq_table, \ | ||
151 | .lock_delay = _lock_delay, \ | ||
152 | .fixed_rate = _fixed_rate, \ | ||
153 | }, \ | ||
154 | .clk_cfg_ex = _clk_cfg_ex, \ | ||
155 | }; \ | ||
156 | DEFINE_CLK_TEGRA(_name, 0, &_ops, CLK_IGNORE_UNUSED, \ | ||
157 | _name##_parent_names, _name##_parents, \ | ||
158 | &tegra_##_parent); | ||
159 | |||
160 | #define DEFINE_PLL_OUT(_name, _flags, _reg, _reg_shift, \ | ||
161 | _max_rate, _ops, _parent, _clk_flags) \ | ||
162 | static const char *_name##_parent_names[] = { \ | ||
163 | #_parent, \ | ||
164 | }; \ | ||
165 | static struct clk *_name##_parents[] = { \ | ||
166 | &tegra_##_parent, \ | ||
167 | }; \ | ||
168 | static struct clk tegra_##_name; \ | ||
169 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
170 | .hw = { \ | ||
171 | .clk = &tegra_##_name, \ | ||
172 | }, \ | ||
173 | .flags = _flags, \ | ||
174 | .reg = _reg, \ | ||
175 | .max_rate = _max_rate, \ | ||
176 | .reg_shift = _reg_shift, \ | ||
177 | }; \ | ||
178 | DEFINE_CLK_TEGRA(_name, 0, &tegra30_pll_div_ops, \ | ||
179 | _clk_flags, _name##_parent_names, \ | ||
180 | _name##_parents, &tegra_##_parent); | ||
181 | |||
182 | static struct clk_pll_freq_table tegra_pll_c_freq_table[] = { | ||
183 | { 12000000, 1040000000, 520, 6, 1, 8}, | ||
184 | { 13000000, 1040000000, 480, 6, 1, 8}, | ||
185 | { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */ | ||
186 | { 19200000, 1040000000, 325, 6, 1, 6}, | ||
187 | { 26000000, 1040000000, 520, 13, 1, 8}, | ||
188 | |||
189 | { 12000000, 832000000, 416, 6, 1, 8}, | ||
190 | { 13000000, 832000000, 832, 13, 1, 8}, | ||
191 | { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */ | ||
192 | { 19200000, 832000000, 260, 6, 1, 8}, | ||
193 | { 26000000, 832000000, 416, 13, 1, 8}, | ||
194 | |||
195 | { 12000000, 624000000, 624, 12, 1, 8}, | ||
196 | { 13000000, 624000000, 624, 13, 1, 8}, | ||
197 | { 16800000, 600000000, 520, 14, 1, 8}, | ||
198 | { 19200000, 624000000, 520, 16, 1, 8}, | ||
199 | { 26000000, 624000000, 624, 26, 1, 8}, | ||
200 | |||
201 | { 12000000, 600000000, 600, 12, 1, 8}, | ||
202 | { 13000000, 600000000, 600, 13, 1, 8}, | ||
203 | { 16800000, 600000000, 500, 14, 1, 8}, | ||
204 | { 19200000, 600000000, 375, 12, 1, 6}, | ||
205 | { 26000000, 600000000, 600, 26, 1, 8}, | ||
206 | |||
207 | { 12000000, 520000000, 520, 12, 1, 8}, | ||
208 | { 13000000, 520000000, 520, 13, 1, 8}, | ||
209 | { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */ | ||
210 | { 19200000, 520000000, 325, 12, 1, 6}, | ||
211 | { 26000000, 520000000, 520, 26, 1, 8}, | ||
212 | |||
213 | { 12000000, 416000000, 416, 12, 1, 8}, | ||
214 | { 13000000, 416000000, 416, 13, 1, 8}, | ||
215 | { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */ | ||
216 | { 19200000, 416000000, 260, 12, 1, 6}, | ||
217 | { 26000000, 416000000, 416, 26, 1, 8}, | ||
218 | { 0, 0, 0, 0, 0, 0 }, | ||
219 | }; | ||
220 | |||
221 | DEFINE_PLL(pll_c, PLL_HAS_CPCON, 0x80, 1400000000, 2000000, 31000000, 1000000, | ||
222 | 6000000, 20000000, 1400000000, tegra_pll_c_freq_table, 300, | ||
223 | tegra30_pll_ops, 0, NULL, pll_ref); | ||
224 | |||
225 | DEFINE_PLL_OUT(pll_c_out1, DIV_U71, 0x84, 0, 700000000, | ||
226 | tegra30_pll_div_ops, pll_c, CLK_IGNORE_UNUSED); | ||
227 | |||
228 | static struct clk_pll_freq_table tegra_pll_m_freq_table[] = { | ||
229 | { 12000000, 666000000, 666, 12, 1, 8}, | ||
230 | { 13000000, 666000000, 666, 13, 1, 8}, | ||
231 | { 16800000, 666000000, 555, 14, 1, 8}, | ||
232 | { 19200000, 666000000, 555, 16, 1, 8}, | ||
233 | { 26000000, 666000000, 666, 26, 1, 8}, | ||
234 | { 12000000, 600000000, 600, 12, 1, 8}, | ||
235 | { 13000000, 600000000, 600, 13, 1, 8}, | ||
236 | { 16800000, 600000000, 500, 14, 1, 8}, | ||
237 | { 19200000, 600000000, 375, 12, 1, 6}, | ||
238 | { 26000000, 600000000, 600, 26, 1, 8}, | ||
239 | { 0, 0, 0, 0, 0, 0 }, | ||
240 | }; | ||
241 | |||
242 | DEFINE_PLL(pll_m, PLL_HAS_CPCON | PLLM, 0x90, 800000000, 2000000, 31000000, | ||
243 | 1000000, 6000000, 20000000, 1200000000, tegra_pll_m_freq_table, | ||
244 | 300, tegra30_pll_ops, 0, NULL, pll_ref); | ||
245 | |||
246 | DEFINE_PLL_OUT(pll_m_out1, DIV_U71, 0x94, 0, 600000000, | ||
247 | tegra30_pll_div_ops, pll_m, CLK_IGNORE_UNUSED); | ||
248 | |||
249 | static struct clk_pll_freq_table tegra_pll_p_freq_table[] = { | ||
250 | { 12000000, 216000000, 432, 12, 2, 8}, | ||
251 | { 13000000, 216000000, 432, 13, 2, 8}, | ||
252 | { 16800000, 216000000, 360, 14, 2, 8}, | ||
253 | { 19200000, 216000000, 360, 16, 2, 8}, | ||
254 | { 26000000, 216000000, 432, 26, 2, 8}, | ||
255 | { 0, 0, 0, 0, 0, 0 }, | ||
256 | }; | ||
257 | |||
258 | DEFINE_PLL(pll_p, ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, 0xa0, 432000000, | ||
259 | 2000000, 31000000, 1000000, 6000000, 20000000, 1400000000, | ||
260 | tegra_pll_p_freq_table, 300, tegra30_pll_ops, 408000000, NULL, | ||
261 | pll_ref); | ||
262 | |||
263 | DEFINE_PLL_OUT(pll_p_out1, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, | ||
264 | 0, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED); | ||
265 | DEFINE_PLL_OUT(pll_p_out2, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa4, | ||
266 | 16, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED); | ||
267 | DEFINE_PLL_OUT(pll_p_out3, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, | ||
268 | 0, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED); | ||
269 | DEFINE_PLL_OUT(pll_p_out4, ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, 0xa8, | ||
270 | 16, 432000000, tegra30_pll_div_ops, pll_p, CLK_IGNORE_UNUSED); | ||
271 | |||
272 | static struct clk_pll_freq_table tegra_pll_a_freq_table[] = { | ||
273 | { 9600000, 564480000, 294, 5, 1, 4}, | ||
274 | { 9600000, 552960000, 288, 5, 1, 4}, | ||
275 | { 9600000, 24000000, 5, 2, 1, 1}, | ||
276 | |||
277 | { 28800000, 56448000, 49, 25, 1, 1}, | ||
278 | { 28800000, 73728000, 64, 25, 1, 1}, | ||
279 | { 28800000, 24000000, 5, 6, 1, 1}, | ||
280 | { 0, 0, 0, 0, 0, 0 }, | ||
281 | }; | ||
282 | |||
283 | DEFINE_PLL(pll_a, PLL_HAS_CPCON, 0xb0, 700000000, 2000000, 31000000, 1000000, | ||
284 | 6000000, 20000000, 1400000000, tegra_pll_a_freq_table, | ||
285 | 300, tegra30_pll_ops, 0, NULL, pll_p_out1); | ||
286 | |||
287 | DEFINE_PLL_OUT(pll_a_out0, DIV_U71, 0xb4, 0, 100000000, tegra30_pll_div_ops, | ||
288 | pll_a, CLK_IGNORE_UNUSED); | ||
289 | |||
290 | static struct clk_pll_freq_table tegra_pll_d_freq_table[] = { | ||
291 | { 12000000, 216000000, 216, 12, 1, 4}, | ||
292 | { 13000000, 216000000, 216, 13, 1, 4}, | ||
293 | { 16800000, 216000000, 180, 14, 1, 4}, | ||
294 | { 19200000, 216000000, 180, 16, 1, 4}, | ||
295 | { 26000000, 216000000, 216, 26, 1, 4}, | ||
296 | |||
297 | { 12000000, 594000000, 594, 12, 1, 8}, | ||
298 | { 13000000, 594000000, 594, 13, 1, 8}, | ||
299 | { 16800000, 594000000, 495, 14, 1, 8}, | ||
300 | { 19200000, 594000000, 495, 16, 1, 8}, | ||
301 | { 26000000, 594000000, 594, 26, 1, 8}, | ||
302 | |||
303 | { 12000000, 1000000000, 1000, 12, 1, 12}, | ||
304 | { 13000000, 1000000000, 1000, 13, 1, 12}, | ||
305 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
306 | { 26000000, 1000000000, 1000, 26, 1, 12}, | ||
307 | |||
308 | { 0, 0, 0, 0, 0, 0 }, | ||
309 | }; | ||
310 | |||
311 | DEFINE_PLL(pll_d, PLL_HAS_CPCON | PLLD, 0xd0, 1000000000, 2000000, 40000000, | ||
312 | 1000000, 6000000, 40000000, 1000000000, tegra_pll_d_freq_table, | ||
313 | 1000, tegra30_pll_ops, 0, tegra30_plld_clk_cfg_ex, pll_ref); | ||
314 | |||
315 | DEFINE_PLL_OUT(pll_d_out0, DIV_2 | PLLD, 0, 0, 500000000, tegra30_pll_div_ops, | ||
316 | pll_d, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED); | ||
317 | |||
318 | DEFINE_PLL(pll_d2, PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD, 0x4b8, 1000000000, | ||
319 | 2000000, 40000000, 1000000, 6000000, 40000000, 1000000000, | ||
320 | tegra_pll_d_freq_table, 1000, tegra30_pll_ops, 0, NULL, | ||
321 | pll_ref); | ||
322 | |||
323 | DEFINE_PLL_OUT(pll_d2_out0, DIV_2 | PLLD, 0, 0, 500000000, tegra30_pll_div_ops, | ||
324 | pll_d2, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED); | ||
325 | |||
326 | static struct clk_pll_freq_table tegra_pll_u_freq_table[] = { | ||
327 | { 12000000, 480000000, 960, 12, 2, 12}, | ||
328 | { 13000000, 480000000, 960, 13, 2, 12}, | ||
329 | { 16800000, 480000000, 400, 7, 2, 5}, | ||
330 | { 19200000, 480000000, 200, 4, 2, 3}, | ||
331 | { 26000000, 480000000, 960, 26, 2, 12}, | ||
332 | { 0, 0, 0, 0, 0, 0 }, | ||
333 | }; | ||
334 | |||
335 | DEFINE_PLL(pll_u, PLL_HAS_CPCON | PLLU, 0xc0, 480000000, 2000000, 40000000, | ||
336 | 1000000, 6000000, 48000000, 960000000, tegra_pll_u_freq_table, | ||
337 | 1000, tegra30_pll_ops, 0, NULL, pll_ref); | ||
338 | |||
339 | static struct clk_pll_freq_table tegra_pll_x_freq_table[] = { | ||
340 | /* 1.7 GHz */ | ||
341 | { 12000000, 1700000000, 850, 6, 1, 8}, | ||
342 | { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */ | ||
343 | { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */ | ||
344 | { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */ | ||
345 | { 26000000, 1700000000, 850, 13, 1, 8}, | ||
346 | |||
347 | /* 1.6 GHz */ | ||
348 | { 12000000, 1600000000, 800, 6, 1, 8}, | ||
349 | { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */ | ||
350 | { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */ | ||
351 | { 19200000, 1600000000, 500, 6, 1, 8}, | ||
352 | { 26000000, 1600000000, 800, 13, 1, 8}, | ||
353 | |||
354 | /* 1.5 GHz */ | ||
355 | { 12000000, 1500000000, 750, 6, 1, 8}, | ||
356 | { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */ | ||
357 | { 16800000, 1500000000, 625, 7, 1, 8}, | ||
358 | { 19200000, 1500000000, 625, 8, 1, 8}, | ||
359 | { 26000000, 1500000000, 750, 13, 1, 8}, | ||
360 | |||
361 | /* 1.4 GHz */ | ||
362 | { 12000000, 1400000000, 700, 6, 1, 8}, | ||
363 | { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */ | ||
364 | { 16800000, 1400000000, 1000, 12, 1, 8}, | ||
365 | { 19200000, 1400000000, 875, 12, 1, 8}, | ||
366 | { 26000000, 1400000000, 700, 13, 1, 8}, | ||
367 | |||
368 | /* 1.3 GHz */ | ||
369 | { 12000000, 1300000000, 975, 9, 1, 8}, | ||
370 | { 13000000, 1300000000, 1000, 10, 1, 8}, | ||
371 | { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */ | ||
372 | { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */ | ||
373 | { 26000000, 1300000000, 650, 13, 1, 8}, | ||
374 | |||
375 | /* 1.2 GHz */ | ||
376 | { 12000000, 1200000000, 1000, 10, 1, 8}, | ||
377 | { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */ | ||
378 | { 16800000, 1200000000, 1000, 14, 1, 8}, | ||
379 | { 19200000, 1200000000, 1000, 16, 1, 8}, | ||
380 | { 26000000, 1200000000, 600, 13, 1, 8}, | ||
381 | |||
382 | /* 1.1 GHz */ | ||
383 | { 12000000, 1100000000, 825, 9, 1, 8}, | ||
384 | { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */ | ||
385 | { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */ | ||
386 | { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */ | ||
387 | { 26000000, 1100000000, 550, 13, 1, 8}, | ||
388 | |||
389 | /* 1 GHz */ | ||
390 | { 12000000, 1000000000, 1000, 12, 1, 8}, | ||
391 | { 13000000, 1000000000, 1000, 13, 1, 8}, | ||
392 | { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */ | ||
393 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
394 | { 26000000, 1000000000, 1000, 26, 1, 8}, | ||
395 | |||
396 | { 0, 0, 0, 0, 0, 0 }, | ||
397 | }; | ||
398 | |||
399 | DEFINE_PLL(pll_x, PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX, 0xe0, 1700000000, | ||
400 | 2000000, 31000000, 1000000, 6000000, 20000000, 1700000000, | ||
401 | tegra_pll_x_freq_table, 300, tegra30_pll_ops, 0, NULL, pll_ref); | ||
402 | |||
403 | DEFINE_PLL_OUT(pll_x_out0, DIV_2 | PLLX, 0, 0, 850000000, tegra30_pll_div_ops, | ||
404 | pll_x, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED); | ||
405 | |||
406 | static struct clk_pll_freq_table tegra_pll_e_freq_table[] = { | ||
407 | /* PLLE special case: use cpcon field to store cml divider value */ | ||
408 | { 12000000, 100000000, 150, 1, 18, 11}, | ||
409 | { 216000000, 100000000, 200, 18, 24, 13}, | ||
410 | { 0, 0, 0, 0, 0, 0 }, | ||
411 | }; | ||
412 | |||
413 | DEFINE_PLL(pll_e, PLL_ALT_MISC_REG, 0xe8, 100000000, 2000000, 216000000, | ||
414 | 12000000, 12000000, 1200000000, 2400000000U, | ||
415 | tegra_pll_e_freq_table, 300, tegra30_plle_ops, 100000000, NULL, | ||
416 | pll_ref); | ||
417 | |||
418 | static const char *mux_plle[] = { | ||
419 | "pll_e", | ||
420 | }; | ||
421 | |||
422 | static struct clk *mux_plle_p[] = { | ||
423 | &tegra_pll_e, | ||
424 | }; | ||
425 | |||
426 | static struct clk tegra_cml0; | ||
427 | static struct clk_tegra tegra_cml0_hw = { | ||
428 | .hw = { | ||
429 | .clk = &tegra_cml0, | ||
430 | }, | ||
431 | .reg = 0x48c, | ||
432 | .fixed_rate = 100000000, | ||
433 | .u.periph = { | ||
434 | .clk_num = 0, | ||
435 | }, | ||
436 | }; | ||
437 | DEFINE_CLK_TEGRA(cml0, 0, &tegra_cml_clk_ops, 0, mux_plle, | ||
438 | mux_plle_p, &tegra_pll_e); | ||
439 | |||
440 | static struct clk tegra_cml1; | ||
441 | static struct clk_tegra tegra_cml1_hw = { | ||
442 | .hw = { | ||
443 | .clk = &tegra_cml1, | ||
444 | }, | ||
445 | .reg = 0x48c, | ||
446 | .fixed_rate = 100000000, | ||
447 | .u.periph = { | ||
448 | .clk_num = 1, | ||
449 | }, | ||
450 | }; | ||
451 | DEFINE_CLK_TEGRA(cml1, 0, &tegra_cml_clk_ops, 0, mux_plle, | ||
452 | mux_plle_p, &tegra_pll_e); | ||
453 | |||
454 | static struct clk tegra_pciex; | ||
455 | static struct clk_tegra tegra_pciex_hw = { | ||
456 | .hw = { | ||
457 | .clk = &tegra_pciex, | ||
458 | }, | ||
459 | .reg = 0x48c, | ||
460 | .fixed_rate = 100000000, | ||
461 | .reset = tegra30_periph_clk_reset, | ||
462 | .u.periph = { | ||
463 | .clk_num = 74, | ||
464 | }, | ||
465 | }; | ||
466 | DEFINE_CLK_TEGRA(pciex, 0, &tegra_pciex_clk_ops, 0, mux_plle, | ||
467 | mux_plle_p, &tegra_pll_e); | ||
468 | |||
469 | #define SYNC_SOURCE(_name) \ | ||
470 | static struct clk tegra_##_name##_sync; \ | ||
471 | static struct clk_tegra tegra_##_name##_sync_hw = { \ | ||
472 | .hw = { \ | ||
473 | .clk = &tegra_##_name##_sync, \ | ||
474 | }, \ | ||
475 | .max_rate = 24000000, \ | ||
476 | .fixed_rate = 24000000, \ | ||
477 | }; \ | ||
478 | static struct clk tegra_##_name##_sync = { \ | ||
479 | .name = #_name "_sync", \ | ||
480 | .hw = &tegra_##_name##_sync_hw.hw, \ | ||
481 | .ops = &tegra_sync_source_ops, \ | ||
482 | .flags = CLK_IS_ROOT, \ | ||
483 | }; | ||
484 | |||
485 | SYNC_SOURCE(spdif_in); | ||
486 | SYNC_SOURCE(i2s0); | ||
487 | SYNC_SOURCE(i2s1); | ||
488 | SYNC_SOURCE(i2s2); | ||
489 | SYNC_SOURCE(i2s3); | ||
490 | SYNC_SOURCE(i2s4); | ||
491 | SYNC_SOURCE(vimclk); | ||
492 | |||
493 | static struct clk *tegra_sync_source_list[] = { | ||
494 | &tegra_spdif_in_sync, | ||
495 | &tegra_i2s0_sync, | ||
496 | &tegra_i2s1_sync, | ||
497 | &tegra_i2s2_sync, | ||
498 | &tegra_i2s3_sync, | ||
499 | &tegra_i2s4_sync, | ||
500 | &tegra_vimclk_sync, | ||
501 | }; | ||
502 | |||
503 | static const char *mux_audio_sync_clk[] = { | ||
504 | "spdif_in_sync", | ||
505 | "i2s0_sync", | ||
506 | "i2s1_sync", | ||
507 | "i2s2_sync", | ||
508 | "i2s3_sync", | ||
509 | "i2s4_sync", | ||
510 | "vimclk_sync", | ||
511 | }; | ||
512 | |||
513 | #define AUDIO_SYNC_CLK(_name, _index) \ | ||
514 | static struct clk tegra_##_name; \ | ||
515 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
516 | .hw = { \ | ||
517 | .clk = &tegra_##_name, \ | ||
518 | }, \ | ||
519 | .max_rate = 24000000, \ | ||
520 | .reg = 0x4A0 + (_index) * 4, \ | ||
521 | }; \ | ||
522 | static struct clk tegra_##_name = { \ | ||
523 | .name = #_name, \ | ||
524 | .ops = &tegra30_audio_sync_clk_ops, \ | ||
525 | .hw = &tegra_##_name##_hw.hw, \ | ||
526 | .parent_names = mux_audio_sync_clk, \ | ||
527 | .parents = tegra_sync_source_list, \ | ||
528 | .num_parents = ARRAY_SIZE(mux_audio_sync_clk), \ | ||
529 | }; | ||
530 | |||
531 | AUDIO_SYNC_CLK(audio0, 0); | ||
532 | AUDIO_SYNC_CLK(audio1, 1); | ||
533 | AUDIO_SYNC_CLK(audio2, 2); | ||
534 | AUDIO_SYNC_CLK(audio3, 3); | ||
535 | AUDIO_SYNC_CLK(audio4, 4); | ||
536 | AUDIO_SYNC_CLK(audio5, 5); | ||
537 | |||
538 | static struct clk *tegra_clk_audio_list[] = { | ||
539 | &tegra_audio0, | ||
540 | &tegra_audio1, | ||
541 | &tegra_audio2, | ||
542 | &tegra_audio3, | ||
543 | &tegra_audio4, | ||
544 | &tegra_audio5, /* SPDIF */ | ||
545 | }; | ||
546 | |||
547 | #define AUDIO_SYNC_2X_CLK(_name, _index) \ | ||
548 | static const char *_name##_parent_names[] = { \ | ||
549 | "tegra_" #_name, \ | ||
550 | }; \ | ||
551 | static struct clk *_name##_parents[] = { \ | ||
552 | &tegra_##_name, \ | ||
553 | }; \ | ||
554 | static struct clk tegra_##_name##_2x; \ | ||
555 | static struct clk_tegra tegra_##_name##_2x_hw = { \ | ||
556 | .hw = { \ | ||
557 | .clk = &tegra_##_name##_2x, \ | ||
558 | }, \ | ||
559 | .flags = PERIPH_NO_RESET, \ | ||
560 | .max_rate = 48000000, \ | ||
561 | .reg = 0x49C, \ | ||
562 | .reg_shift = 24 + (_index), \ | ||
563 | .u.periph = { \ | ||
564 | .clk_num = 113 + (_index), \ | ||
565 | }, \ | ||
566 | }; \ | ||
567 | static struct clk tegra_##_name##_2x = { \ | ||
568 | .name = #_name "_2x", \ | ||
569 | .ops = &tegra30_clk_double_ops, \ | ||
570 | .hw = &tegra_##_name##_2x_hw.hw, \ | ||
571 | .parent_names = _name##_parent_names, \ | ||
572 | .parents = _name##_parents, \ | ||
573 | .parent = &tegra_##_name, \ | ||
574 | .num_parents = 1, \ | ||
575 | }; | ||
576 | |||
577 | AUDIO_SYNC_2X_CLK(audio0, 0); | ||
578 | AUDIO_SYNC_2X_CLK(audio1, 1); | ||
579 | AUDIO_SYNC_2X_CLK(audio2, 2); | ||
580 | AUDIO_SYNC_2X_CLK(audio3, 3); | ||
581 | AUDIO_SYNC_2X_CLK(audio4, 4); | ||
582 | AUDIO_SYNC_2X_CLK(audio5, 5); /* SPDIF */ | ||
583 | |||
584 | static struct clk *tegra_clk_audio_2x_list[] = { | ||
585 | &tegra_audio0_2x, | ||
586 | &tegra_audio1_2x, | ||
587 | &tegra_audio2_2x, | ||
588 | &tegra_audio3_2x, | ||
589 | &tegra_audio4_2x, | ||
590 | &tegra_audio5_2x, /* SPDIF */ | ||
591 | }; | ||
592 | |||
593 | #define MUX_I2S_SPDIF(_id) \ | ||
594 | static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { \ | ||
595 | "pll_a_out0", \ | ||
596 | #_id "_2x", \ | ||
597 | "pll_p", \ | ||
598 | "clk_m", \ | ||
599 | }; \ | ||
600 | static struct clk *mux_pllaout0_##_id##_2x_pllp_clkm_p[] = { \ | ||
601 | &tegra_pll_a_out0, \ | ||
602 | &tegra_##_id##_2x, \ | ||
603 | &tegra_pll_p, \ | ||
604 | &tegra_clk_m, \ | ||
605 | }; | ||
606 | |||
607 | MUX_I2S_SPDIF(audio0); | ||
608 | MUX_I2S_SPDIF(audio1); | ||
609 | MUX_I2S_SPDIF(audio2); | ||
610 | MUX_I2S_SPDIF(audio3); | ||
611 | MUX_I2S_SPDIF(audio4); | ||
612 | MUX_I2S_SPDIF(audio5); /* SPDIF */ | ||
613 | |||
614 | static struct clk tegra_extern1; | ||
615 | static struct clk tegra_extern2; | ||
616 | static struct clk tegra_extern3; | ||
617 | |||
618 | /* External clock outputs (through PMC) */ | ||
619 | #define MUX_EXTERN_OUT(_id) \ | ||
620 | static const char *mux_clkm_clkm2_clkm4_extern##_id[] = { \ | ||
621 | "clk_m", \ | ||
622 | "clk_m_div2", \ | ||
623 | "clk_m_div4", \ | ||
624 | "extern" #_id, \ | ||
625 | }; \ | ||
626 | static struct clk *mux_clkm_clkm2_clkm4_extern##_id##_p[] = { \ | ||
627 | &tegra_clk_m, \ | ||
628 | &tegra_clk_m_div2, \ | ||
629 | &tegra_clk_m_div4, \ | ||
630 | &tegra_extern##_id, \ | ||
631 | }; | ||
632 | |||
633 | MUX_EXTERN_OUT(1); | ||
634 | MUX_EXTERN_OUT(2); | ||
635 | MUX_EXTERN_OUT(3); | ||
636 | |||
637 | #define CLK_OUT_CLK(_name, _index) \ | ||
638 | static struct clk tegra_##_name; \ | ||
639 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
640 | .hw = { \ | ||
641 | .clk = &tegra_##_name, \ | ||
642 | }, \ | ||
643 | .lookup = { \ | ||
644 | .dev_id = #_name, \ | ||
645 | .con_id = "extern" #_index, \ | ||
646 | }, \ | ||
647 | .flags = MUX_CLK_OUT, \ | ||
648 | .fixed_rate = 216000000, \ | ||
649 | .reg = 0x1a8, \ | ||
650 | .u.periph = { \ | ||
651 | .clk_num = (_index - 1) * 8 + 2, \ | ||
652 | }, \ | ||
653 | }; \ | ||
654 | static struct clk tegra_##_name = { \ | ||
655 | .name = #_name, \ | ||
656 | .ops = &tegra_clk_out_ops, \ | ||
657 | .hw = &tegra_##_name##_hw.hw, \ | ||
658 | .parent_names = mux_clkm_clkm2_clkm4_extern##_index, \ | ||
659 | .parents = mux_clkm_clkm2_clkm4_extern##_index##_p, \ | ||
660 | .num_parents = ARRAY_SIZE(mux_clkm_clkm2_clkm4_extern##_index),\ | ||
661 | }; | ||
662 | |||
663 | CLK_OUT_CLK(clk_out_1, 1); | ||
664 | CLK_OUT_CLK(clk_out_2, 2); | ||
665 | CLK_OUT_CLK(clk_out_3, 3); | ||
666 | |||
667 | static struct clk *tegra_clk_out_list[] = { | ||
668 | &tegra_clk_out_1, | ||
669 | &tegra_clk_out_2, | ||
670 | &tegra_clk_out_3, | ||
671 | }; | ||
672 | |||
673 | static const char *mux_sclk[] = { | ||
674 | "clk_m", | ||
675 | "pll_c_out1", | ||
676 | "pll_p_out4", | ||
677 | "pll_p_out3", | ||
678 | "pll_p_out2", | ||
679 | "dummy", | ||
680 | "clk_32k", | ||
681 | "pll_m_out1", | ||
682 | }; | ||
683 | |||
684 | static struct clk *mux_sclk_p[] = { | ||
685 | &tegra_clk_m, | ||
686 | &tegra_pll_c_out1, | ||
687 | &tegra_pll_p_out4, | ||
688 | &tegra_pll_p_out3, | ||
689 | &tegra_pll_p_out2, | ||
690 | NULL, | ||
691 | &tegra_clk_32k, | ||
692 | &tegra_pll_m_out1, | ||
693 | }; | ||
694 | |||
695 | static struct clk tegra_clk_sclk; | ||
696 | static struct clk_tegra tegra_clk_sclk_hw = { | ||
697 | .hw = { | ||
698 | .clk = &tegra_clk_sclk, | ||
699 | }, | ||
700 | .reg = 0x28, | ||
701 | .max_rate = 334000000, | ||
702 | .min_rate = 40000000, | ||
703 | }; | ||
704 | |||
705 | static struct clk tegra_clk_sclk = { | ||
706 | .name = "sclk", | ||
707 | .ops = &tegra30_super_ops, | ||
708 | .hw = &tegra_clk_sclk_hw.hw, | ||
709 | .parent_names = mux_sclk, | ||
710 | .parents = mux_sclk_p, | ||
711 | .num_parents = ARRAY_SIZE(mux_sclk), | ||
712 | }; | ||
713 | |||
714 | static const char *tegra_hclk_parent_names[] = { | ||
715 | "tegra_sclk", | ||
716 | }; | ||
717 | |||
718 | static struct clk *tegra_hclk_parents[] = { | ||
719 | &tegra_clk_sclk, | ||
720 | }; | ||
721 | |||
722 | static struct clk tegra_hclk; | ||
723 | static struct clk_tegra tegra_hclk_hw = { | ||
724 | .hw = { | ||
725 | .clk = &tegra_hclk, | ||
726 | }, | ||
727 | .flags = DIV_BUS, | ||
728 | .reg = 0x30, | ||
729 | .reg_shift = 4, | ||
730 | .max_rate = 378000000, | ||
731 | .min_rate = 12000000, | ||
732 | }; | ||
733 | DEFINE_CLK_TEGRA(hclk, 0, &tegra30_bus_ops, 0, tegra_hclk_parent_names, | ||
734 | tegra_hclk_parents, &tegra_clk_sclk); | ||
735 | |||
736 | static const char *tegra_pclk_parent_names[] = { | ||
737 | "tegra_hclk", | ||
738 | }; | ||
739 | |||
740 | static struct clk *tegra_pclk_parents[] = { | ||
741 | &tegra_hclk, | ||
742 | }; | ||
743 | |||
744 | static struct clk tegra_pclk; | ||
745 | static struct clk_tegra tegra_pclk_hw = { | ||
746 | .hw = { | ||
747 | .clk = &tegra_pclk, | ||
748 | }, | ||
749 | .flags = DIV_BUS, | ||
750 | .reg = 0x30, | ||
751 | .reg_shift = 0, | ||
752 | .max_rate = 167000000, | ||
753 | .min_rate = 12000000, | ||
754 | }; | ||
755 | DEFINE_CLK_TEGRA(pclk, 0, &tegra30_bus_ops, 0, tegra_pclk_parent_names, | ||
756 | tegra_pclk_parents, &tegra_hclk); | ||
757 | |||
758 | static const char *mux_blink[] = { | ||
759 | "clk_32k", | ||
760 | }; | ||
761 | |||
762 | static struct clk *mux_blink_p[] = { | ||
763 | &tegra_clk_32k, | ||
764 | }; | ||
765 | |||
766 | static struct clk tegra_clk_blink; | ||
767 | static struct clk_tegra tegra_clk_blink_hw = { | ||
768 | .hw = { | ||
769 | .clk = &tegra_clk_blink, | ||
770 | }, | ||
771 | .reg = 0x40, | ||
772 | .max_rate = 32768, | ||
773 | }; | ||
774 | static struct clk tegra_clk_blink = { | ||
775 | .name = "blink", | ||
776 | .ops = &tegra30_blink_clk_ops, | ||
777 | .hw = &tegra_clk_blink_hw.hw, | ||
778 | .parent = &tegra_clk_32k, | ||
779 | .parent_names = mux_blink, | ||
780 | .parents = mux_blink_p, | ||
781 | .num_parents = ARRAY_SIZE(mux_blink), | ||
782 | }; | ||
783 | |||
784 | static const char *mux_pllm_pllc_pllp_plla[] = { | ||
785 | "pll_m", | ||
786 | "pll_c", | ||
787 | "pll_p", | ||
788 | "pll_a_out0", | ||
789 | }; | ||
790 | |||
791 | static const char *mux_pllp_pllc_pllm_clkm[] = { | ||
792 | "pll_p", | ||
793 | "pll_c", | ||
794 | "pll_m", | ||
795 | "clk_m", | ||
796 | }; | ||
797 | |||
798 | static const char *mux_pllp_clkm[] = { | ||
799 | "pll_p", | ||
800 | "dummy", | ||
801 | "dummy", | ||
802 | "clk_m", | ||
803 | }; | ||
804 | |||
805 | static const char *mux_pllp_plld_pllc_clkm[] = { | ||
806 | "pll_p", | ||
807 | "pll_d_out0", | ||
808 | "pll_c", | ||
809 | "clk_m", | ||
810 | }; | ||
811 | |||
812 | static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { | ||
813 | "pll_p", | ||
814 | "pll_m", | ||
815 | "pll_d_out0", | ||
816 | "pll_a_out0", | ||
817 | "pll_c", | ||
818 | "pll_d2_out0", | ||
819 | "clk_m", | ||
820 | }; | ||
821 | |||
822 | static const char *mux_plla_pllc_pllp_clkm[] = { | ||
823 | "pll_a_out0", | ||
824 | "dummy", | ||
825 | "pll_p", | ||
826 | "clk_m" | ||
827 | }; | ||
828 | |||
829 | static const char *mux_pllp_pllc_clk32_clkm[] = { | ||
830 | "pll_p", | ||
831 | "pll_c", | ||
832 | "clk_32k", | ||
833 | "clk_m", | ||
834 | }; | ||
835 | |||
836 | static const char *mux_pllp_pllc_clkm_clk32[] = { | ||
837 | "pll_p", | ||
838 | "pll_c", | ||
839 | "clk_m", | ||
840 | "clk_32k", | ||
841 | }; | ||
842 | |||
843 | static const char *mux_pllp_pllc_pllm[] = { | ||
844 | "pll_p", | ||
845 | "pll_c", | ||
846 | "pll_m", | ||
847 | }; | ||
848 | |||
849 | static const char *mux_clk_m[] = { | ||
850 | "clk_m", | ||
851 | }; | ||
852 | |||
853 | static const char *mux_pllp_out3[] = { | ||
854 | "pll_p_out3", | ||
855 | }; | ||
856 | |||
857 | static const char *mux_plld_out0[] = { | ||
858 | "pll_d_out0", | ||
859 | }; | ||
860 | |||
861 | static const char *mux_plld_out0_plld2_out0[] = { | ||
862 | "pll_d_out0", | ||
863 | "pll_d2_out0", | ||
864 | }; | ||
865 | |||
866 | static const char *mux_clk_32k[] = { | ||
867 | "clk_32k", | ||
868 | }; | ||
869 | |||
870 | static const char *mux_plla_clk32_pllp_clkm_plle[] = { | ||
871 | "pll_a_out0", | ||
872 | "clk_32k", | ||
873 | "pll_p", | ||
874 | "clk_m", | ||
875 | "pll_e", | ||
876 | }; | ||
877 | |||
878 | static const char *mux_cclk_g[] = { | ||
879 | "clk_m", | ||
880 | "pll_c", | ||
881 | "clk_32k", | ||
882 | "pll_m", | ||
883 | "pll_p", | ||
884 | "pll_p_out4", | ||
885 | "pll_p_out3", | ||
886 | "dummy", | ||
887 | "pll_x", | ||
888 | }; | ||
889 | |||
890 | static struct clk *mux_pllm_pllc_pllp_plla_p[] = { | ||
891 | &tegra_pll_m, | ||
892 | &tegra_pll_c, | ||
893 | &tegra_pll_p, | ||
894 | &tegra_pll_a_out0, | ||
895 | }; | ||
896 | |||
897 | static struct clk *mux_pllp_pllc_pllm_clkm_p[] = { | ||
898 | &tegra_pll_p, | ||
899 | &tegra_pll_c, | ||
900 | &tegra_pll_m, | ||
901 | &tegra_clk_m, | ||
902 | }; | ||
903 | |||
904 | static struct clk *mux_pllp_clkm_p[] = { | ||
905 | &tegra_pll_p, | ||
906 | NULL, | ||
907 | NULL, | ||
908 | &tegra_clk_m, | ||
909 | }; | ||
910 | |||
911 | static struct clk *mux_pllp_plld_pllc_clkm_p[] = { | ||
912 | &tegra_pll_p, | ||
913 | &tegra_pll_d_out0, | ||
914 | &tegra_pll_c, | ||
915 | &tegra_clk_m, | ||
916 | }; | ||
917 | |||
918 | static struct clk *mux_pllp_pllm_plld_plla_pllc_plld2_clkm_p[] = { | ||
919 | &tegra_pll_p, | ||
920 | &tegra_pll_m, | ||
921 | &tegra_pll_d_out0, | ||
922 | &tegra_pll_a_out0, | ||
923 | &tegra_pll_c, | ||
924 | &tegra_pll_d2_out0, | ||
925 | &tegra_clk_m, | ||
926 | }; | ||
927 | |||
928 | static struct clk *mux_plla_pllc_pllp_clkm_p[] = { | ||
929 | &tegra_pll_a_out0, | ||
930 | NULL, | ||
931 | &tegra_pll_p, | ||
932 | &tegra_clk_m, | ||
933 | }; | ||
934 | |||
935 | static struct clk *mux_pllp_pllc_clk32_clkm_p[] = { | ||
936 | &tegra_pll_p, | ||
937 | &tegra_pll_c, | ||
938 | &tegra_clk_32k, | ||
939 | &tegra_clk_m, | ||
940 | }; | ||
941 | |||
942 | static struct clk *mux_pllp_pllc_clkm_clk32_p[] = { | ||
943 | &tegra_pll_p, | ||
944 | &tegra_pll_c, | ||
945 | &tegra_clk_m, | ||
946 | &tegra_clk_32k, | ||
947 | }; | ||
948 | |||
949 | static struct clk *mux_pllp_pllc_pllm_p[] = { | ||
950 | &tegra_pll_p, | ||
951 | &tegra_pll_c, | ||
952 | &tegra_pll_m, | ||
953 | }; | ||
954 | |||
955 | static struct clk *mux_clk_m_p[] = { | ||
956 | &tegra_clk_m, | ||
957 | }; | ||
958 | |||
959 | static struct clk *mux_pllp_out3_p[] = { | ||
960 | &tegra_pll_p_out3, | ||
961 | }; | ||
962 | |||
963 | static struct clk *mux_plld_out0_p[] = { | ||
964 | &tegra_pll_d_out0, | ||
965 | }; | ||
966 | |||
967 | static struct clk *mux_plld_out0_plld2_out0_p[] = { | ||
968 | &tegra_pll_d_out0, | ||
969 | &tegra_pll_d2_out0, | ||
970 | }; | ||
971 | |||
972 | static struct clk *mux_clk_32k_p[] = { | ||
973 | &tegra_clk_32k, | ||
974 | }; | ||
975 | |||
976 | static struct clk *mux_plla_clk32_pllp_clkm_plle_p[] = { | ||
977 | &tegra_pll_a_out0, | ||
978 | &tegra_clk_32k, | ||
979 | &tegra_pll_p, | ||
980 | &tegra_clk_m, | ||
981 | &tegra_pll_e, | ||
982 | }; | ||
983 | |||
984 | static struct clk *mux_cclk_g_p[] = { | ||
985 | &tegra_clk_m, | ||
986 | &tegra_pll_c, | ||
987 | &tegra_clk_32k, | ||
988 | &tegra_pll_m, | ||
989 | &tegra_pll_p, | ||
990 | &tegra_pll_p_out4, | ||
991 | &tegra_pll_p_out3, | ||
992 | NULL, | ||
993 | &tegra_pll_x, | ||
994 | }; | ||
995 | |||
996 | static struct clk tegra_clk_cclk_g; | ||
997 | static struct clk_tegra tegra_clk_cclk_g_hw = { | ||
998 | .hw = { | ||
999 | .clk = &tegra_clk_cclk_g, | ||
1000 | }, | ||
1001 | .flags = DIV_U71 | DIV_U71_INT, | ||
1002 | .reg = 0x368, | ||
1003 | .max_rate = 1700000000, | ||
1004 | }; | ||
1005 | static struct clk tegra_clk_cclk_g = { | ||
1006 | .name = "cclk_g", | ||
1007 | .ops = &tegra30_super_ops, | ||
1008 | .hw = &tegra_clk_cclk_g_hw.hw, | ||
1009 | .parent_names = mux_cclk_g, | ||
1010 | .parents = mux_cclk_g_p, | ||
1011 | .num_parents = ARRAY_SIZE(mux_cclk_g), | ||
1012 | }; | ||
1013 | |||
1014 | static const char *mux_twd[] = { | ||
1015 | "cclk_g", | ||
1016 | }; | ||
1017 | |||
1018 | static struct clk *mux_twd_p[] = { | ||
1019 | &tegra_clk_cclk_g, | ||
1020 | }; | ||
1021 | |||
1022 | static struct clk tegra30_clk_twd; | ||
1023 | static struct clk_tegra tegra30_clk_twd_hw = { | ||
1024 | .hw = { | ||
1025 | .clk = &tegra30_clk_twd, | ||
1026 | }, | ||
1027 | .max_rate = 1400000000, | ||
1028 | .mul = 1, | ||
1029 | .div = 2, | ||
1030 | }; | ||
1031 | |||
1032 | static struct clk tegra30_clk_twd = { | ||
1033 | .name = "twd", | ||
1034 | .ops = &tegra30_twd_ops, | ||
1035 | .hw = &tegra30_clk_twd_hw.hw, | ||
1036 | .parent = &tegra_clk_cclk_g, | ||
1037 | .parent_names = mux_twd, | ||
1038 | .parents = mux_twd_p, | ||
1039 | .num_parents = ARRAY_SIZE(mux_twd), | ||
1040 | }; | ||
1041 | |||
1042 | #define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, \ | ||
1043 | _max, _inputs, _flags) \ | ||
1044 | static struct clk tegra_##_name; \ | ||
1045 | static struct clk_tegra tegra_##_name##_hw = { \ | ||
1046 | .hw = { \ | ||
1047 | .clk = &tegra_##_name, \ | ||
1048 | }, \ | ||
1049 | .lookup = { \ | ||
1050 | .dev_id = _dev, \ | ||
1051 | .con_id = _con, \ | ||
1052 | }, \ | ||
1053 | .reg = _reg, \ | ||
1054 | .flags = _flags, \ | ||
1055 | .max_rate = _max, \ | ||
1056 | .u.periph = { \ | ||
1057 | .clk_num = _clk_num, \ | ||
1058 | }, \ | ||
1059 | .reset = &tegra30_periph_clk_reset, \ | ||
1060 | }; \ | ||
1061 | static struct clk tegra_##_name = { \ | ||
1062 | .name = #_name, \ | ||
1063 | .ops = &tegra30_periph_clk_ops, \ | ||
1064 | .hw = &tegra_##_name##_hw.hw, \ | ||
1065 | .parent_names = _inputs, \ | ||
1066 | .parents = _inputs##_p, \ | ||
1067 | .num_parents = ARRAY_SIZE(_inputs), \ | ||
1068 | }; | ||
1069 | |||
1070 | PERIPH_CLK(apbdma, "tegra-apbdma", NULL, 34, 0, 26000000, mux_clk_m, 0); | ||
1071 | PERIPH_CLK(rtc, "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB); | ||
1072 | PERIPH_CLK(kbc, "tegra-kbc", NULL, 36, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB); | ||
1073 | PERIPH_CLK(timer, "timer", NULL, 5, 0, 26000000, mux_clk_m, 0); | ||
1074 | PERIPH_CLK(kfuse, "kfuse-tegra", NULL, 40, 0, 26000000, mux_clk_m, 0); | ||
1075 | PERIPH_CLK(fuse, "fuse-tegra", "fuse", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB); | ||
1076 | PERIPH_CLK(fuse_burn, "fuse-tegra", "fuse_burn", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB); | ||
1077 | PERIPH_CLK(apbif, "tegra30-ahub", "apbif", 107, 0, 26000000, mux_clk_m, 0); | ||
1078 | PERIPH_CLK(i2s0, "tegra30-i2s.0", NULL, 30, 0x1d8, 26000000, mux_pllaout0_audio0_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1079 | PERIPH_CLK(i2s1, "tegra30-i2s.1", NULL, 11, 0x100, 26000000, mux_pllaout0_audio1_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1080 | PERIPH_CLK(i2s2, "tegra30-i2s.2", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1081 | PERIPH_CLK(i2s3, "tegra30-i2s.3", NULL, 101, 0x3bc, 26000000, mux_pllaout0_audio3_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1082 | PERIPH_CLK(i2s4, "tegra30-i2s.4", NULL, 102, 0x3c0, 26000000, mux_pllaout0_audio4_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1083 | PERIPH_CLK(spdif_out, "tegra30-spdif", "spdif_out", 10, 0x108, 100000000, mux_pllaout0_audio5_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1084 | PERIPH_CLK(spdif_in, "tegra30-spdif", "spdif_in", 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1085 | PERIPH_CLK(pwm, "tegra-pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_clk32_clkm, MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB); | ||
1086 | PERIPH_CLK(d_audio, "tegra30-ahub", "d_audio", 106, 0x3d0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71); | ||
1087 | PERIPH_CLK(dam0, "tegra30-dam.0", NULL, 108, 0x3d8, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71); | ||
1088 | PERIPH_CLK(dam1, "tegra30-dam.1", NULL, 109, 0x3dc, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71); | ||
1089 | PERIPH_CLK(dam2, "tegra30-dam.2", NULL, 110, 0x3e0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71); | ||
1090 | PERIPH_CLK(hda, "tegra30-hda", "hda", 125, 0x428, 108000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
1091 | PERIPH_CLK(hda2codec_2x, "tegra30-hda", "hda2codec", 111, 0x3e4, 48000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
1092 | PERIPH_CLK(hda2hdmi, "tegra30-hda", "hda2hdmi", 128, 0, 48000000, mux_clk_m, 0); | ||
1093 | PERIPH_CLK(sbc1, "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1094 | PERIPH_CLK(sbc2, "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1095 | PERIPH_CLK(sbc3, "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1096 | PERIPH_CLK(sbc4, "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1097 | PERIPH_CLK(sbc5, "spi_tegra.4", NULL, 104, 0x3c8, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1098 | PERIPH_CLK(sbc6, "spi_tegra.5", NULL, 105, 0x3cc, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1099 | PERIPH_CLK(sata_oob, "tegra_sata_oob", NULL, 123, 0x420, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
1100 | PERIPH_CLK(sata, "tegra_sata", NULL, 124, 0x424, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
1101 | PERIPH_CLK(sata_cold, "tegra_sata_cold", NULL, 129, 0, 48000000, mux_clk_m, 0); | ||
1102 | PERIPH_CLK(ndflash, "tegra_nand", NULL, 13, 0x160, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
1103 | PERIPH_CLK(ndspeed, "tegra_nand_speed", NULL, 80, 0x3f8, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
1104 | PERIPH_CLK(vfir, "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1105 | PERIPH_CLK(sdmmc1, "sdhci-tegra.0", NULL, 14, 0x150, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
1106 | PERIPH_CLK(sdmmc2, "sdhci-tegra.1", NULL, 9, 0x154, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
1107 | PERIPH_CLK(sdmmc3, "sdhci-tegra.2", NULL, 69, 0x1bc, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
1108 | PERIPH_CLK(sdmmc4, "sdhci-tegra.3", NULL, 15, 0x164, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage */ | ||
1109 | PERIPH_CLK(vcp, "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0); | ||
1110 | PERIPH_CLK(bsea, "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0); | ||
1111 | PERIPH_CLK(bsev, "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0); | ||
1112 | PERIPH_CLK(vde, "vde", NULL, 61, 0x1c8, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT); | ||
1113 | PERIPH_CLK(csite, "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* max rate ??? */ | ||
1114 | PERIPH_CLK(la, "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); | ||
1115 | PERIPH_CLK(owr, "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1116 | PERIPH_CLK(nor, "nor", NULL, 42, 0x1d0, 127000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
1117 | PERIPH_CLK(mipi, "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); /* scales with voltage */ | ||
1118 | PERIPH_CLK(i2c1, "tegra-i2c.0", "div-clk", 12, 0x124, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB); | ||
1119 | PERIPH_CLK(i2c2, "tegra-i2c.1", "div-clk", 54, 0x198, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB); | ||
1120 | PERIPH_CLK(i2c3, "tegra-i2c.2", "div-clk", 67, 0x1b8, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB); | ||
1121 | PERIPH_CLK(i2c4, "tegra-i2c.3", "div-clk", 103, 0x3c4, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB); | ||
1122 | PERIPH_CLK(i2c5, "tegra-i2c.4", "div-clk", 47, 0x128, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB); | ||
1123 | PERIPH_CLK(uarta, "tegra-uart.0", NULL, 6, 0x178, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB); | ||
1124 | PERIPH_CLK(uartb, "tegra-uart.1", NULL, 7, 0x17c, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB); | ||
1125 | PERIPH_CLK(uartc, "tegra-uart.2", NULL, 55, 0x1a0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB); | ||
1126 | PERIPH_CLK(uartd, "tegra-uart.3", NULL, 65, 0x1c0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB); | ||
1127 | PERIPH_CLK(uarte, "tegra-uart.4", NULL, 66, 0x1c4, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB); | ||
1128 | PERIPH_CLK(vi, "tegra_camera", "vi", 20, 0x148, 425000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT); | ||
1129 | PERIPH_CLK(3d, "3d", NULL, 24, 0x158, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET); | ||
1130 | PERIPH_CLK(3d2, "3d2", NULL, 98, 0x3b0, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET); | ||
1131 | PERIPH_CLK(2d, "2d", NULL, 21, 0x15c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE); | ||
1132 | PERIPH_CLK(vi_sensor, "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET); | ||
1133 | PERIPH_CLK(epp, "epp", NULL, 19, 0x16c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT); | ||
1134 | PERIPH_CLK(mpe, "mpe", NULL, 60, 0x170, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT); | ||
1135 | PERIPH_CLK(host1x, "host1x", NULL, 28, 0x180, 260000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT); | ||
1136 | PERIPH_CLK(cve, "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
1137 | PERIPH_CLK(tvo, "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
1138 | PERIPH_CLK(dtv, "dtv", NULL, 79, 0x1dc, 250000000, mux_clk_m, 0); | ||
1139 | PERIPH_CLK(hdmi, "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8 | DIV_U71); | ||
1140 | PERIPH_CLK(tvdac, "tvdac", NULL, 53, 0x194, 220000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71); /* requires min voltage */ | ||
1141 | PERIPH_CLK(disp1, "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8); | ||
1142 | PERIPH_CLK(disp2, "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8); | ||
1143 | PERIPH_CLK(usbd, "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0); /* requires min voltage */ | ||
1144 | PERIPH_CLK(usb2, "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0); /* requires min voltage */ | ||
1145 | PERIPH_CLK(usb3, "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0); /* requires min voltage */ | ||
1146 | PERIPH_CLK(dsia, "tegradc.0", "dsia", 48, 0, 500000000, mux_plld_out0, 0); | ||
1147 | PERIPH_CLK(csi, "tegra_camera", "csi", 52, 0, 102000000, mux_pllp_out3, 0); | ||
1148 | PERIPH_CLK(isp, "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0); /* same frequency as VI */ | ||
1149 | PERIPH_CLK(csus, "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET); | ||
1150 | PERIPH_CLK(tsensor, "tegra-tsensor", NULL, 100, 0x3b8, 216000000, mux_pllp_pllc_clkm_clk32, MUX | DIV_U71); | ||
1151 | PERIPH_CLK(actmon, "actmon", NULL, 119, 0x3e8, 216000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71); | ||
1152 | PERIPH_CLK(extern1, "extern1", NULL, 120, 0x3ec, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71); | ||
1153 | PERIPH_CLK(extern2, "extern2", NULL, 121, 0x3f0, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71); | ||
1154 | PERIPH_CLK(extern3, "extern3", NULL, 122, 0x3f4, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71); | ||
1155 | PERIPH_CLK(i2cslow, "i2cslow", NULL, 81, 0x3fc, 26000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71 | PERIPH_ON_APB); | ||
1156 | PERIPH_CLK(pcie, "tegra-pcie", "pcie", 70, 0, 250000000, mux_clk_m, 0); | ||
1157 | PERIPH_CLK(afi, "tegra-pcie", "afi", 72, 0, 250000000, mux_clk_m, 0); | ||
1158 | PERIPH_CLK(se, "se", NULL, 127, 0x42c, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT); | ||
1159 | |||
1160 | static struct clk tegra_dsib; | ||
1161 | static struct clk_tegra tegra_dsib_hw = { | ||
1162 | .hw = { | ||
1163 | .clk = &tegra_dsib, | ||
1164 | }, | ||
1165 | .lookup = { | ||
1166 | .dev_id = "tegradc.1", | ||
1167 | .con_id = "dsib", | ||
1168 | }, | ||
1169 | .reg = 0xd0, | ||
1170 | .flags = MUX | PLLD, | ||
1171 | .max_rate = 500000000, | ||
1172 | .u.periph = { | ||
1173 | .clk_num = 82, | ||
1174 | }, | ||
1175 | .reset = &tegra30_periph_clk_reset, | ||
1176 | }; | ||
1177 | static struct clk tegra_dsib = { | ||
1178 | .name = "dsib", | ||
1179 | .ops = &tegra30_dsib_clk_ops, | ||
1180 | .hw = &tegra_dsib_hw.hw, | ||
1181 | .parent_names = mux_plld_out0_plld2_out0, | ||
1182 | .parents = mux_plld_out0_plld2_out0_p, | ||
1183 | .num_parents = ARRAY_SIZE(mux_plld_out0_plld2_out0), | ||
1184 | }; | ||
1185 | |||
1186 | static struct clk *tegra_list_clks[] = { | ||
1187 | &tegra_apbdma, | ||
1188 | &tegra_rtc, | ||
1189 | &tegra_kbc, | ||
1190 | &tegra_timer, | ||
1191 | &tegra_kfuse, | ||
1192 | &tegra_fuse, | ||
1193 | &tegra_fuse_burn, | ||
1194 | &tegra_apbif, | ||
1195 | &tegra_i2s0, | ||
1196 | &tegra_i2s1, | ||
1197 | &tegra_i2s2, | ||
1198 | &tegra_i2s3, | ||
1199 | &tegra_i2s4, | ||
1200 | &tegra_spdif_out, | ||
1201 | &tegra_spdif_in, | ||
1202 | &tegra_pwm, | ||
1203 | &tegra_d_audio, | ||
1204 | &tegra_dam0, | ||
1205 | &tegra_dam1, | ||
1206 | &tegra_dam2, | ||
1207 | &tegra_hda, | ||
1208 | &tegra_hda2codec_2x, | ||
1209 | &tegra_hda2hdmi, | ||
1210 | &tegra_sbc1, | ||
1211 | &tegra_sbc2, | ||
1212 | &tegra_sbc3, | ||
1213 | &tegra_sbc4, | ||
1214 | &tegra_sbc5, | ||
1215 | &tegra_sbc6, | ||
1216 | &tegra_sata_oob, | ||
1217 | &tegra_sata, | ||
1218 | &tegra_sata_cold, | ||
1219 | &tegra_ndflash, | ||
1220 | &tegra_ndspeed, | ||
1221 | &tegra_vfir, | ||
1222 | &tegra_sdmmc1, | ||
1223 | &tegra_sdmmc2, | ||
1224 | &tegra_sdmmc3, | ||
1225 | &tegra_sdmmc4, | ||
1226 | &tegra_vcp, | ||
1227 | &tegra_bsea, | ||
1228 | &tegra_bsev, | ||
1229 | &tegra_vde, | ||
1230 | &tegra_csite, | ||
1231 | &tegra_la, | ||
1232 | &tegra_owr, | ||
1233 | &tegra_nor, | ||
1234 | &tegra_mipi, | ||
1235 | &tegra_i2c1, | ||
1236 | &tegra_i2c2, | ||
1237 | &tegra_i2c3, | ||
1238 | &tegra_i2c4, | ||
1239 | &tegra_i2c5, | ||
1240 | &tegra_uarta, | ||
1241 | &tegra_uartb, | ||
1242 | &tegra_uartc, | ||
1243 | &tegra_uartd, | ||
1244 | &tegra_uarte, | ||
1245 | &tegra_vi, | ||
1246 | &tegra_3d, | ||
1247 | &tegra_3d2, | ||
1248 | &tegra_2d, | ||
1249 | &tegra_vi_sensor, | ||
1250 | &tegra_epp, | ||
1251 | &tegra_mpe, | ||
1252 | &tegra_host1x, | ||
1253 | &tegra_cve, | ||
1254 | &tegra_tvo, | ||
1255 | &tegra_dtv, | ||
1256 | &tegra_hdmi, | ||
1257 | &tegra_tvdac, | ||
1258 | &tegra_disp1, | ||
1259 | &tegra_disp2, | ||
1260 | &tegra_usbd, | ||
1261 | &tegra_usb2, | ||
1262 | &tegra_usb3, | ||
1263 | &tegra_dsia, | ||
1264 | &tegra_dsib, | ||
1265 | &tegra_csi, | ||
1266 | &tegra_isp, | ||
1267 | &tegra_csus, | ||
1268 | &tegra_tsensor, | ||
1269 | &tegra_actmon, | ||
1270 | &tegra_extern1, | ||
1271 | &tegra_extern2, | ||
1272 | &tegra_extern3, | ||
1273 | &tegra_i2cslow, | ||
1274 | &tegra_pcie, | ||
1275 | &tegra_afi, | ||
1276 | &tegra_se, | ||
1277 | }; | ||
1278 | |||
1279 | #define CLK_DUPLICATE(_name, _dev, _con) \ | ||
1280 | { \ | ||
1281 | .name = _name, \ | ||
1282 | .lookup = { \ | ||
1283 | .dev_id = _dev, \ | ||
1284 | .con_id = _con, \ | ||
1285 | }, \ | ||
1286 | } | ||
1287 | |||
1288 | /* Some clocks may be used by different drivers depending on the board | ||
1289 | * configuration. List those here to register them twice in the clock lookup | ||
1290 | * table under two names. | ||
1291 | */ | ||
1292 | static struct clk_duplicate tegra_clk_duplicates[] = { | ||
1293 | CLK_DUPLICATE("uarta", "serial8250.0", NULL), | ||
1294 | CLK_DUPLICATE("uartb", "serial8250.1", NULL), | ||
1295 | CLK_DUPLICATE("uartc", "serial8250.2", NULL), | ||
1296 | CLK_DUPLICATE("uartd", "serial8250.3", NULL), | ||
1297 | CLK_DUPLICATE("uarte", "serial8250.4", NULL), | ||
1298 | CLK_DUPLICATE("usbd", "utmip-pad", NULL), | ||
1299 | CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL), | ||
1300 | CLK_DUPLICATE("usbd", "tegra-otg", NULL), | ||
1301 | CLK_DUPLICATE("dsib", "tegradc.0", "dsib"), | ||
1302 | CLK_DUPLICATE("dsia", "tegradc.1", "dsia"), | ||
1303 | CLK_DUPLICATE("bsev", "tegra-avp", "bsev"), | ||
1304 | CLK_DUPLICATE("bsev", "nvavp", "bsev"), | ||
1305 | CLK_DUPLICATE("vde", "tegra-aes", "vde"), | ||
1306 | CLK_DUPLICATE("bsea", "tegra-aes", "bsea"), | ||
1307 | CLK_DUPLICATE("bsea", "nvavp", "bsea"), | ||
1308 | CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL), | ||
1309 | CLK_DUPLICATE("cml0", "tegra_pcie", "cml"), | ||
1310 | CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"), | ||
1311 | CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL), | ||
1312 | CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL), | ||
1313 | CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL), | ||
1314 | CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL), | ||
1315 | CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL), | ||
1316 | CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL), | ||
1317 | CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL), | ||
1318 | CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL), | ||
1319 | CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL), | ||
1320 | CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL), | ||
1321 | CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL), | ||
1322 | CLK_DUPLICATE("twd", "smp_twd", NULL), | ||
1323 | CLK_DUPLICATE("vcp", "nvavp", "vcp"), | ||
1324 | CLK_DUPLICATE("i2s0", NULL, "i2s0"), | ||
1325 | CLK_DUPLICATE("i2s1", NULL, "i2s1"), | ||
1326 | CLK_DUPLICATE("i2s2", NULL, "i2s2"), | ||
1327 | CLK_DUPLICATE("i2s3", NULL, "i2s3"), | ||
1328 | CLK_DUPLICATE("i2s4", NULL, "i2s4"), | ||
1329 | CLK_DUPLICATE("dam0", NULL, "dam0"), | ||
1330 | CLK_DUPLICATE("dam1", NULL, "dam1"), | ||
1331 | CLK_DUPLICATE("dam2", NULL, "dam2"), | ||
1332 | CLK_DUPLICATE("spdif_in", NULL, "spdif_in"), | ||
1333 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.0", "fast-clk"), | ||
1334 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"), | ||
1335 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"), | ||
1336 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"), | ||
1337 | CLK_DUPLICATE("pll_p_out3", "tegra-i2c.4", "fast-clk"), | ||
1338 | CLK_DUPLICATE("pll_p", "tegradc.0", "parent"), | ||
1339 | CLK_DUPLICATE("pll_p", "tegradc.1", "parent"), | ||
1340 | CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"), | ||
1341 | }; | ||
1342 | |||
1343 | static struct clk *tegra_ptr_clks[] = { | ||
1344 | &tegra_clk_32k, | ||
1345 | &tegra_clk_m, | ||
1346 | &tegra_clk_m_div2, | ||
1347 | &tegra_clk_m_div4, | ||
1348 | &tegra_pll_ref, | ||
1349 | &tegra_pll_m, | ||
1350 | &tegra_pll_m_out1, | ||
1351 | &tegra_pll_c, | ||
1352 | &tegra_pll_c_out1, | ||
1353 | &tegra_pll_p, | ||
1354 | &tegra_pll_p_out1, | ||
1355 | &tegra_pll_p_out2, | ||
1356 | &tegra_pll_p_out3, | ||
1357 | &tegra_pll_p_out4, | ||
1358 | &tegra_pll_a, | ||
1359 | &tegra_pll_a_out0, | ||
1360 | &tegra_pll_d, | ||
1361 | &tegra_pll_d_out0, | ||
1362 | &tegra_pll_d2, | ||
1363 | &tegra_pll_d2_out0, | ||
1364 | &tegra_pll_u, | ||
1365 | &tegra_pll_x, | ||
1366 | &tegra_pll_x_out0, | ||
1367 | &tegra_pll_e, | ||
1368 | &tegra_clk_cclk_g, | ||
1369 | &tegra_cml0, | ||
1370 | &tegra_cml1, | ||
1371 | &tegra_pciex, | ||
1372 | &tegra_clk_sclk, | ||
1373 | &tegra_hclk, | ||
1374 | &tegra_pclk, | ||
1375 | &tegra_clk_blink, | ||
1376 | &tegra30_clk_twd, | ||
1377 | }; | ||
1378 | |||
1379 | static void tegra30_init_one_clock(struct clk *c) | ||
1380 | { | ||
1381 | struct clk_tegra *clk = to_clk_tegra(c->hw); | ||
1382 | __clk_init(NULL, c); | ||
1383 | INIT_LIST_HEAD(&clk->shared_bus_list); | ||
1384 | if (!clk->lookup.dev_id && !clk->lookup.con_id) | ||
1385 | clk->lookup.con_id = c->name; | ||
1386 | clk->lookup.clk = c; | ||
1387 | clkdev_add(&clk->lookup); | ||
1388 | tegra_clk_add(c); | ||
1389 | } | ||
1390 | |||
1391 | void __init tegra30_init_clocks(void) | ||
1392 | { | ||
1393 | int i; | ||
1394 | struct clk *c; | ||
1395 | |||
1396 | for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++) | ||
1397 | tegra30_init_one_clock(tegra_ptr_clks[i]); | ||
1398 | |||
1399 | for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++) | ||
1400 | tegra30_init_one_clock(tegra_list_clks[i]); | ||
1401 | |||
1402 | for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) { | ||
1403 | c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name); | ||
1404 | if (!c) { | ||
1405 | pr_err("%s: Unknown duplicate clock %s\n", __func__, | ||
1406 | tegra_clk_duplicates[i].name); | ||
1407 | continue; | ||
1408 | } | ||
1409 | |||
1410 | tegra_clk_duplicates[i].lookup.clk = c; | ||
1411 | clkdev_add(&tegra_clk_duplicates[i].lookup); | ||
1412 | } | ||
1413 | |||
1414 | for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++) | ||
1415 | tegra30_init_one_clock(tegra_sync_source_list[i]); | ||
1416 | for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++) | ||
1417 | tegra30_init_one_clock(tegra_clk_audio_list[i]); | ||
1418 | for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++) | ||
1419 | tegra30_init_one_clock(tegra_clk_audio_2x_list[i]); | ||
1420 | |||
1421 | for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) | ||
1422 | tegra30_init_one_clock(tegra_clk_out_list[i]); | ||
1423 | |||
1424 | tegra30_cpu_car_ops_init(); | ||
1425 | } | ||
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig index 7a602069bab9..e3e94b2fa145 100644 --- a/arch/arm/mach-vt8500/Kconfig +++ b/arch/arm/mach-vt8500/Kconfig | |||
@@ -16,3 +16,19 @@ config ARCH_WM8505 | |||
16 | select ARCH_VT8500 | 16 | select ARCH_VT8500 |
17 | select CPU_ARM926T | 17 | select CPU_ARM926T |
18 | help | 18 | help |
19 | |||
20 | config ARCH_WM8750 | ||
21 | bool "WonderMedia WM8750" | ||
22 | depends on ARCH_MULTI_V6 | ||
23 | select ARCH_VT8500 | ||
24 | select CPU_V6 | ||
25 | help | ||
26 | Support for WonderMedia WM8750 System-on-Chip. | ||
27 | |||
28 | config ARCH_WM8850 | ||
29 | bool "WonderMedia WM8850" | ||
30 | depends on ARCH_MULTI_V7 | ||
31 | select ARCH_VT8500 | ||
32 | select CPU_V7 | ||
33 | help | ||
34 | Support for WonderMedia WM8850 System-on-Chip. | ||
diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c index fe99b709f11f..49e80053d828 100644 --- a/arch/arm/mach-vt8500/vt8500.c +++ b/arch/arm/mach-vt8500/vt8500.c | |||
@@ -180,6 +180,8 @@ static const char * const vt8500_dt_compat[] = { | |||
180 | "via,vt8500", | 180 | "via,vt8500", |
181 | "wm,wm8650", | 181 | "wm,wm8650", |
182 | "wm,wm8505", | 182 | "wm,wm8505", |
183 | "wm,wm8750", | ||
184 | "wm,wm8850", | ||
183 | }; | 185 | }; |
184 | 186 | ||
185 | DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") | 187 | DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 7539ec275065..15451ee4acc8 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -19,6 +19,52 @@ | |||
19 | #include "proc-macros.S" | 19 | #include "proc-macros.S" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * The secondary kernel init calls v7_flush_dcache_all before it enables | ||
23 | * the L1; however, the L1 comes out of reset in an undefined state, so | ||
24 | * the clean + invalidate performed by v7_flush_dcache_all causes a bunch | ||
25 | * of cache lines with uninitialized data and uninitialized tags to get | ||
26 | * written out to memory, which does really unpleasant things to the main | ||
27 | * processor. We fix this by performing an invalidate, rather than a | ||
28 | * clean + invalidate, before jumping into the kernel. | ||
29 | * | ||
30 | * This function is cloned from arch/arm/mach-tegra/headsmp.S, and needs | ||
31 | * to be called for both secondary cores startup and primary core resume | ||
32 | * procedures. | ||
33 | */ | ||
34 | ENTRY(v7_invalidate_l1) | ||
35 | mov r0, #0 | ||
36 | mcr p15, 2, r0, c0, c0, 0 | ||
37 | mrc p15, 1, r0, c0, c0, 0 | ||
38 | |||
39 | ldr r1, =0x7fff | ||
40 | and r2, r1, r0, lsr #13 | ||
41 | |||
42 | ldr r1, =0x3ff | ||
43 | |||
44 | and r3, r1, r0, lsr #3 @ NumWays - 1 | ||
45 | add r2, r2, #1 @ NumSets | ||
46 | |||
47 | and r0, r0, #0x7 | ||
48 | add r0, r0, #4 @ SetShift | ||
49 | |||
50 | clz r1, r3 @ WayShift | ||
51 | add r4, r3, #1 @ NumWays | ||
52 | 1: sub r2, r2, #1 @ NumSets-- | ||
53 | mov r3, r4 @ Temp = NumWays | ||
54 | 2: subs r3, r3, #1 @ Temp-- | ||
55 | mov r5, r3, lsl r1 | ||
56 | mov r6, r2, lsl r0 | ||
57 | orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) | ||
58 | mcr p15, 0, r5, c7, c6, 2 | ||
59 | bgt 2b | ||
60 | cmp r2, #0 | ||
61 | bgt 1b | ||
62 | dsb | ||
63 | isb | ||
64 | mov pc, lr | ||
65 | ENDPROC(v7_invalidate_l1) | ||
66 | |||
67 | /* | ||
22 | * v7_flush_icache_all() | 68 | * v7_flush_icache_all() |
23 | * | 69 | * |
24 | * Flush the whole I-cache. | 70 | * Flush the whole I-cache. |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 14fde73ea6ff..300d4775d926 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -26,6 +26,8 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o | |||
26 | obj-$(CONFIG_ARCH_U8500) += ux500/ | 26 | obj-$(CONFIG_ARCH_U8500) += ux500/ |
27 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o | 27 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o |
28 | obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o | 28 | obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o |
29 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ | ||
30 | |||
29 | obj-$(CONFIG_X86) += x86/ | 31 | obj-$(CONFIG_X86) += x86/ |
30 | 32 | ||
31 | # Chip specific | 33 | # Chip specific |
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c index e69991aab43a..792bc57a9db7 100644 --- a/drivers/clk/clk-bcm2835.c +++ b/drivers/clk/clk-bcm2835.c | |||
@@ -20,6 +20,13 @@ | |||
20 | #include <linux/clk-provider.h> | 20 | #include <linux/clk-provider.h> |
21 | #include <linux/clkdev.h> | 21 | #include <linux/clkdev.h> |
22 | #include <linux/clk/bcm2835.h> | 22 | #include <linux/clk/bcm2835.h> |
23 | #include <linux/clk-provider.h> | ||
24 | #include <linux/of.h> | ||
25 | |||
26 | static const __initconst struct of_device_id clk_match[] = { | ||
27 | { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, | ||
28 | { } | ||
29 | }; | ||
23 | 30 | ||
24 | /* | 31 | /* |
25 | * These are fixed clocks. They're probably not all root clocks and it may | 32 | * These are fixed clocks. They're probably not all root clocks and it may |
@@ -56,4 +63,6 @@ void __init bcm2835_init_clocks(void) | |||
56 | ret = clk_register_clkdev(clk, NULL, "20215000.uart"); | 63 | ret = clk_register_clkdev(clk, NULL, "20215000.uart"); |
57 | if (ret) | 64 | if (ret) |
58 | pr_err("uart1_pclk alias not registered\n"); | 65 | pr_err("uart1_pclk alias not registered\n"); |
66 | |||
67 | of_clk_init(clk_match); | ||
59 | } | 68 | } |
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 126370a62ce2..76ce6c6d1113 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c | |||
@@ -238,7 +238,7 @@ int __init mx28_clocks_init(void) | |||
238 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 238 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); |
239 | } | 239 | } |
240 | 240 | ||
241 | clk_register_clkdev(clks[clk32k], NULL, "timrot"); | 241 | clk_register_clkdev(clks[xbus], NULL, "timrot"); |
242 | clk_register_clkdev(clks[enet_out], NULL, "enet_out"); | 242 | clk_register_clkdev(clks[enet_out], NULL, "enet_out"); |
243 | 243 | ||
244 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | 244 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) |
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile new file mode 100644 index 000000000000..2b41b0f4f731 --- /dev/null +++ b/drivers/clk/tegra/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | obj-y += clk.o | ||
2 | obj-y += clk-audio-sync.o | ||
3 | obj-y += clk-divider.o | ||
4 | obj-y += clk-periph.o | ||
5 | obj-y += clk-periph-gate.o | ||
6 | obj-y += clk-pll.o | ||
7 | obj-y += clk-pll-out.o | ||
8 | obj-y += clk-super.o | ||
9 | |||
10 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o | ||
11 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o | ||
diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c new file mode 100644 index 000000000000..c0f7843e80e6 --- /dev/null +++ b/drivers/clk/tegra/clk-audio-sync.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk-provider.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/err.h> | ||
20 | |||
21 | #include "clk.h" | ||
22 | |||
23 | static unsigned long clk_sync_source_recalc_rate(struct clk_hw *hw, | ||
24 | unsigned long parent_rate) | ||
25 | { | ||
26 | struct tegra_clk_sync_source *sync = to_clk_sync_source(hw); | ||
27 | |||
28 | return sync->rate; | ||
29 | } | ||
30 | |||
31 | static long clk_sync_source_round_rate(struct clk_hw *hw, unsigned long rate, | ||
32 | unsigned long *prate) | ||
33 | { | ||
34 | struct tegra_clk_sync_source *sync = to_clk_sync_source(hw); | ||
35 | |||
36 | if (rate > sync->max_rate) | ||
37 | return -EINVAL; | ||
38 | else | ||
39 | return rate; | ||
40 | } | ||
41 | |||
42 | static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate, | ||
43 | unsigned long parent_rate) | ||
44 | { | ||
45 | struct tegra_clk_sync_source *sync = to_clk_sync_source(hw); | ||
46 | |||
47 | sync->rate = rate; | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | const struct clk_ops tegra_clk_sync_source_ops = { | ||
52 | .round_rate = clk_sync_source_round_rate, | ||
53 | .set_rate = clk_sync_source_set_rate, | ||
54 | .recalc_rate = clk_sync_source_recalc_rate, | ||
55 | }; | ||
56 | |||
57 | struct clk *tegra_clk_register_sync_source(const char *name, | ||
58 | unsigned long rate, unsigned long max_rate) | ||
59 | { | ||
60 | struct tegra_clk_sync_source *sync; | ||
61 | struct clk_init_data init; | ||
62 | struct clk *clk; | ||
63 | |||
64 | sync = kzalloc(sizeof(*sync), GFP_KERNEL); | ||
65 | if (!sync) { | ||
66 | pr_err("%s: could not allocate sync source clk\n", __func__); | ||
67 | return ERR_PTR(-ENOMEM); | ||
68 | } | ||
69 | |||
70 | sync->rate = rate; | ||
71 | sync->max_rate = max_rate; | ||
72 | |||
73 | init.ops = &tegra_clk_sync_source_ops; | ||
74 | init.name = name; | ||
75 | init.flags = CLK_IS_ROOT; | ||
76 | init.parent_names = NULL; | ||
77 | init.num_parents = 0; | ||
78 | |||
79 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
80 | sync->hw.init = &init; | ||
81 | |||
82 | clk = clk_register(NULL, &sync->hw); | ||
83 | if (IS_ERR(clk)) | ||
84 | kfree(sync); | ||
85 | |||
86 | return clk; | ||
87 | } | ||
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c new file mode 100644 index 000000000000..4d75b1f37e3a --- /dev/null +++ b/drivers/clk/tegra/clk-divider.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/clk-provider.h> | ||
22 | #include <linux/clk.h> | ||
23 | |||
24 | #include "clk.h" | ||
25 | |||
26 | #define pll_out_override(p) (BIT((p->shift - 6))) | ||
27 | #define div_mask(d) ((1 << (d->width)) - 1) | ||
28 | #define get_mul(d) (1 << d->frac_width) | ||
29 | #define get_max_div(d) div_mask(d) | ||
30 | |||
31 | #define PERIPH_CLK_UART_DIV_ENB BIT(24) | ||
32 | |||
33 | static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate, | ||
34 | unsigned long parent_rate) | ||
35 | { | ||
36 | s64 divider_ux1 = parent_rate; | ||
37 | u8 flags = divider->flags; | ||
38 | int mul; | ||
39 | |||
40 | if (!rate) | ||
41 | return 0; | ||
42 | |||
43 | mul = get_mul(divider); | ||
44 | |||
45 | if (!(flags & TEGRA_DIVIDER_INT)) | ||
46 | divider_ux1 *= mul; | ||
47 | |||
48 | if (flags & TEGRA_DIVIDER_ROUND_UP) | ||
49 | divider_ux1 += rate - 1; | ||
50 | |||
51 | do_div(divider_ux1, rate); | ||
52 | |||
53 | if (flags & TEGRA_DIVIDER_INT) | ||
54 | divider_ux1 *= mul; | ||
55 | |||
56 | divider_ux1 -= mul; | ||
57 | |||
58 | if (divider_ux1 < 0) | ||
59 | return 0; | ||
60 | |||
61 | if (divider_ux1 > get_max_div(divider)) | ||
62 | return -EINVAL; | ||
63 | |||
64 | return divider_ux1; | ||
65 | } | ||
66 | |||
67 | static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw, | ||
68 | unsigned long parent_rate) | ||
69 | { | ||
70 | struct tegra_clk_frac_div *divider = to_clk_frac_div(hw); | ||
71 | u32 reg; | ||
72 | int div, mul; | ||
73 | u64 rate = parent_rate; | ||
74 | |||
75 | reg = readl_relaxed(divider->reg) >> divider->shift; | ||
76 | div = reg & div_mask(divider); | ||
77 | |||
78 | mul = get_mul(divider); | ||
79 | div += mul; | ||
80 | |||
81 | rate *= mul; | ||
82 | rate += div - 1; | ||
83 | do_div(rate, div); | ||
84 | |||
85 | return rate; | ||
86 | } | ||
87 | |||
88 | static long clk_frac_div_round_rate(struct clk_hw *hw, unsigned long rate, | ||
89 | unsigned long *prate) | ||
90 | { | ||
91 | struct tegra_clk_frac_div *divider = to_clk_frac_div(hw); | ||
92 | int div, mul; | ||
93 | unsigned long output_rate = *prate; | ||
94 | |||
95 | if (!rate) | ||
96 | return output_rate; | ||
97 | |||
98 | div = get_div(divider, rate, output_rate); | ||
99 | if (div < 0) | ||
100 | return *prate; | ||
101 | |||
102 | mul = get_mul(divider); | ||
103 | |||
104 | return DIV_ROUND_UP(output_rate * mul, div + mul); | ||
105 | } | ||
106 | |||
107 | static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate, | ||
108 | unsigned long parent_rate) | ||
109 | { | ||
110 | struct tegra_clk_frac_div *divider = to_clk_frac_div(hw); | ||
111 | int div; | ||
112 | unsigned long flags = 0; | ||
113 | u32 val; | ||
114 | |||
115 | div = get_div(divider, rate, parent_rate); | ||
116 | if (div < 0) | ||
117 | return div; | ||
118 | |||
119 | if (divider->lock) | ||
120 | spin_lock_irqsave(divider->lock, flags); | ||
121 | |||
122 | val = readl_relaxed(divider->reg); | ||
123 | val &= ~(div_mask(divider) << divider->shift); | ||
124 | val |= div << divider->shift; | ||
125 | |||
126 | if (divider->flags & TEGRA_DIVIDER_UART) { | ||
127 | if (div) | ||
128 | val |= PERIPH_CLK_UART_DIV_ENB; | ||
129 | else | ||
130 | val &= ~PERIPH_CLK_UART_DIV_ENB; | ||
131 | } | ||
132 | |||
133 | if (divider->flags & TEGRA_DIVIDER_FIXED) | ||
134 | val |= pll_out_override(divider); | ||
135 | |||
136 | writel_relaxed(val, divider->reg); | ||
137 | |||
138 | if (divider->lock) | ||
139 | spin_unlock_irqrestore(divider->lock, flags); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | const struct clk_ops tegra_clk_frac_div_ops = { | ||
145 | .recalc_rate = clk_frac_div_recalc_rate, | ||
146 | .set_rate = clk_frac_div_set_rate, | ||
147 | .round_rate = clk_frac_div_round_rate, | ||
148 | }; | ||
149 | |||
150 | struct clk *tegra_clk_register_divider(const char *name, | ||
151 | const char *parent_name, void __iomem *reg, | ||
152 | unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width, | ||
153 | u8 frac_width, spinlock_t *lock) | ||
154 | { | ||
155 | struct tegra_clk_frac_div *divider; | ||
156 | struct clk *clk; | ||
157 | struct clk_init_data init; | ||
158 | |||
159 | divider = kzalloc(sizeof(*divider), GFP_KERNEL); | ||
160 | if (!divider) { | ||
161 | pr_err("%s: could not allocate fractional divider clk\n", | ||
162 | __func__); | ||
163 | return ERR_PTR(-ENOMEM); | ||
164 | } | ||
165 | |||
166 | init.name = name; | ||
167 | init.ops = &tegra_clk_frac_div_ops; | ||
168 | init.flags = flags; | ||
169 | init.parent_names = parent_name ? &parent_name : NULL; | ||
170 | init.num_parents = parent_name ? 1 : 0; | ||
171 | |||
172 | divider->reg = reg; | ||
173 | divider->shift = shift; | ||
174 | divider->width = width; | ||
175 | divider->frac_width = frac_width; | ||
176 | divider->lock = lock; | ||
177 | divider->flags = clk_divider_flags; | ||
178 | |||
179 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
180 | divider->hw.init = &init; | ||
181 | |||
182 | clk = clk_register(NULL, ÷r->hw); | ||
183 | if (IS_ERR(clk)) | ||
184 | kfree(divider); | ||
185 | |||
186 | return clk; | ||
187 | } | ||
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c new file mode 100644 index 000000000000..6dd533251e7b --- /dev/null +++ b/drivers/clk/tegra/clk-periph-gate.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/clk-provider.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/tegra-soc.h> | ||
24 | |||
25 | #include "clk.h" | ||
26 | |||
27 | static DEFINE_SPINLOCK(periph_ref_lock); | ||
28 | |||
29 | /* Macros to assist peripheral gate clock */ | ||
30 | #define read_enb(gate) \ | ||
31 | readl_relaxed(gate->clk_base + (gate->regs->enb_reg)) | ||
32 | #define write_enb_set(val, gate) \ | ||
33 | writel_relaxed(val, gate->clk_base + (gate->regs->enb_set_reg)) | ||
34 | #define write_enb_clr(val, gate) \ | ||
35 | writel_relaxed(val, gate->clk_base + (gate->regs->enb_clr_reg)) | ||
36 | |||
37 | #define read_rst(gate) \ | ||
38 | readl_relaxed(gate->clk_base + (gate->regs->rst_reg)) | ||
39 | #define write_rst_set(val, gate) \ | ||
40 | writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg)) | ||
41 | #define write_rst_clr(val, gate) \ | ||
42 | writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg)) | ||
43 | |||
44 | #define periph_clk_to_bit(periph) (1 << (gate->clk_num % 32)) | ||
45 | |||
46 | /* Peripheral gate clock ops */ | ||
47 | static int clk_periph_is_enabled(struct clk_hw *hw) | ||
48 | { | ||
49 | struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); | ||
50 | int state = 1; | ||
51 | |||
52 | if (!(read_enb(gate) & periph_clk_to_bit(gate))) | ||
53 | state = 0; | ||
54 | |||
55 | if (!(gate->flags & TEGRA_PERIPH_NO_RESET)) | ||
56 | if (read_rst(gate) & periph_clk_to_bit(gate)) | ||
57 | state = 0; | ||
58 | |||
59 | return state; | ||
60 | } | ||
61 | |||
62 | static int clk_periph_enable(struct clk_hw *hw) | ||
63 | { | ||
64 | struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); | ||
65 | unsigned long flags = 0; | ||
66 | |||
67 | spin_lock_irqsave(&periph_ref_lock, flags); | ||
68 | |||
69 | gate->enable_refcnt[gate->clk_num]++; | ||
70 | if (gate->enable_refcnt[gate->clk_num] > 1) { | ||
71 | spin_unlock_irqrestore(&periph_ref_lock, flags); | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | write_enb_set(periph_clk_to_bit(gate), gate); | ||
76 | udelay(2); | ||
77 | |||
78 | if (!(gate->flags & TEGRA_PERIPH_NO_RESET) && | ||
79 | !(gate->flags & TEGRA_PERIPH_MANUAL_RESET)) { | ||
80 | if (read_rst(gate) & periph_clk_to_bit(gate)) { | ||
81 | udelay(5); /* reset propogation delay */ | ||
82 | write_rst_clr(periph_clk_to_bit(gate), gate); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | spin_unlock_irqrestore(&periph_ref_lock, flags); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static void clk_periph_disable(struct clk_hw *hw) | ||
92 | { | ||
93 | struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); | ||
94 | unsigned long flags = 0; | ||
95 | |||
96 | spin_lock_irqsave(&periph_ref_lock, flags); | ||
97 | |||
98 | gate->enable_refcnt[gate->clk_num]--; | ||
99 | if (gate->enable_refcnt[gate->clk_num] > 0) { | ||
100 | spin_unlock_irqrestore(&periph_ref_lock, flags); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * If peripheral is in the APB bus then read the APB bus to | ||
106 | * flush the write operation in apb bus. This will avoid the | ||
107 | * peripheral access after disabling clock | ||
108 | */ | ||
109 | if (gate->flags & TEGRA_PERIPH_ON_APB) | ||
110 | tegra_read_chipid(); | ||
111 | |||
112 | write_enb_clr(periph_clk_to_bit(gate), gate); | ||
113 | |||
114 | spin_unlock_irqrestore(&periph_ref_lock, flags); | ||
115 | } | ||
116 | |||
117 | void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert) | ||
118 | { | ||
119 | if (gate->flags & TEGRA_PERIPH_NO_RESET) | ||
120 | return; | ||
121 | |||
122 | if (assert) { | ||
123 | /* | ||
124 | * If peripheral is in the APB bus then read the APB bus to | ||
125 | * flush the write operation in apb bus. This will avoid the | ||
126 | * peripheral access after disabling clock | ||
127 | */ | ||
128 | if (gate->flags & TEGRA_PERIPH_ON_APB) | ||
129 | tegra_read_chipid(); | ||
130 | |||
131 | write_rst_set(periph_clk_to_bit(gate), gate); | ||
132 | } else { | ||
133 | write_rst_clr(periph_clk_to_bit(gate), gate); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | const struct clk_ops tegra_clk_periph_gate_ops = { | ||
138 | .is_enabled = clk_periph_is_enabled, | ||
139 | .enable = clk_periph_enable, | ||
140 | .disable = clk_periph_disable, | ||
141 | }; | ||
142 | |||
143 | struct clk *tegra_clk_register_periph_gate(const char *name, | ||
144 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, | ||
145 | unsigned long flags, int clk_num, | ||
146 | struct tegra_clk_periph_regs *pregs, int *enable_refcnt) | ||
147 | { | ||
148 | struct tegra_clk_periph_gate *gate; | ||
149 | struct clk *clk; | ||
150 | struct clk_init_data init; | ||
151 | |||
152 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | ||
153 | if (!gate) { | ||
154 | pr_err("%s: could not allocate periph gate clk\n", __func__); | ||
155 | return ERR_PTR(-ENOMEM); | ||
156 | } | ||
157 | |||
158 | init.name = name; | ||
159 | init.flags = flags; | ||
160 | init.parent_names = parent_name ? &parent_name : NULL; | ||
161 | init.num_parents = parent_name ? 1 : 0; | ||
162 | init.ops = &tegra_clk_periph_gate_ops; | ||
163 | |||
164 | gate->magic = TEGRA_CLK_PERIPH_GATE_MAGIC; | ||
165 | gate->clk_base = clk_base; | ||
166 | gate->clk_num = clk_num; | ||
167 | gate->flags = gate_flags; | ||
168 | gate->enable_refcnt = enable_refcnt; | ||
169 | gate->regs = pregs; | ||
170 | |||
171 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
172 | gate->hw.init = &init; | ||
173 | |||
174 | clk = clk_register(NULL, &gate->hw); | ||
175 | if (IS_ERR(clk)) | ||
176 | kfree(gate); | ||
177 | |||
178 | return clk; | ||
179 | } | ||
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c new file mode 100644 index 000000000000..788486e6331a --- /dev/null +++ b/drivers/clk/tegra/clk-periph.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/clk-provider.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/err.h> | ||
21 | |||
22 | #include "clk.h" | ||
23 | |||
24 | static u8 clk_periph_get_parent(struct clk_hw *hw) | ||
25 | { | ||
26 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
27 | const struct clk_ops *mux_ops = periph->mux_ops; | ||
28 | struct clk_hw *mux_hw = &periph->mux.hw; | ||
29 | |||
30 | mux_hw->clk = hw->clk; | ||
31 | |||
32 | return mux_ops->get_parent(mux_hw); | ||
33 | } | ||
34 | |||
35 | static int clk_periph_set_parent(struct clk_hw *hw, u8 index) | ||
36 | { | ||
37 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
38 | const struct clk_ops *mux_ops = periph->mux_ops; | ||
39 | struct clk_hw *mux_hw = &periph->mux.hw; | ||
40 | |||
41 | mux_hw->clk = hw->clk; | ||
42 | |||
43 | return mux_ops->set_parent(mux_hw, index); | ||
44 | } | ||
45 | |||
46 | static unsigned long clk_periph_recalc_rate(struct clk_hw *hw, | ||
47 | unsigned long parent_rate) | ||
48 | { | ||
49 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
50 | const struct clk_ops *div_ops = periph->div_ops; | ||
51 | struct clk_hw *div_hw = &periph->divider.hw; | ||
52 | |||
53 | div_hw->clk = hw->clk; | ||
54 | |||
55 | return div_ops->recalc_rate(div_hw, parent_rate); | ||
56 | } | ||
57 | |||
58 | static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate, | ||
59 | unsigned long *prate) | ||
60 | { | ||
61 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
62 | const struct clk_ops *div_ops = periph->div_ops; | ||
63 | struct clk_hw *div_hw = &periph->divider.hw; | ||
64 | |||
65 | div_hw->clk = hw->clk; | ||
66 | |||
67 | return div_ops->round_rate(div_hw, rate, prate); | ||
68 | } | ||
69 | |||
70 | static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate, | ||
71 | unsigned long parent_rate) | ||
72 | { | ||
73 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
74 | const struct clk_ops *div_ops = periph->div_ops; | ||
75 | struct clk_hw *div_hw = &periph->divider.hw; | ||
76 | |||
77 | div_hw->clk = hw->clk; | ||
78 | |||
79 | return div_ops->set_rate(div_hw, rate, parent_rate); | ||
80 | } | ||
81 | |||
82 | static int clk_periph_is_enabled(struct clk_hw *hw) | ||
83 | { | ||
84 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
85 | const struct clk_ops *gate_ops = periph->gate_ops; | ||
86 | struct clk_hw *gate_hw = &periph->gate.hw; | ||
87 | |||
88 | gate_hw->clk = hw->clk; | ||
89 | |||
90 | return gate_ops->is_enabled(gate_hw); | ||
91 | } | ||
92 | |||
93 | static int clk_periph_enable(struct clk_hw *hw) | ||
94 | { | ||
95 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
96 | const struct clk_ops *gate_ops = periph->gate_ops; | ||
97 | struct clk_hw *gate_hw = &periph->gate.hw; | ||
98 | |||
99 | gate_hw->clk = hw->clk; | ||
100 | |||
101 | return gate_ops->enable(gate_hw); | ||
102 | } | ||
103 | |||
104 | static void clk_periph_disable(struct clk_hw *hw) | ||
105 | { | ||
106 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
107 | const struct clk_ops *gate_ops = periph->gate_ops; | ||
108 | struct clk_hw *gate_hw = &periph->gate.hw; | ||
109 | |||
110 | gate_ops->disable(gate_hw); | ||
111 | } | ||
112 | |||
113 | void tegra_periph_reset_deassert(struct clk *c) | ||
114 | { | ||
115 | struct clk_hw *hw = __clk_get_hw(c); | ||
116 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
117 | struct tegra_clk_periph_gate *gate; | ||
118 | |||
119 | if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { | ||
120 | gate = to_clk_periph_gate(hw); | ||
121 | if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { | ||
122 | WARN_ON(1); | ||
123 | return; | ||
124 | } | ||
125 | } else { | ||
126 | gate = &periph->gate; | ||
127 | } | ||
128 | |||
129 | tegra_periph_reset(gate, 0); | ||
130 | } | ||
131 | |||
132 | void tegra_periph_reset_assert(struct clk *c) | ||
133 | { | ||
134 | struct clk_hw *hw = __clk_get_hw(c); | ||
135 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
136 | struct tegra_clk_periph_gate *gate; | ||
137 | |||
138 | if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { | ||
139 | gate = to_clk_periph_gate(hw); | ||
140 | if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { | ||
141 | WARN_ON(1); | ||
142 | return; | ||
143 | } | ||
144 | } else { | ||
145 | gate = &periph->gate; | ||
146 | } | ||
147 | |||
148 | tegra_periph_reset(gate, 1); | ||
149 | } | ||
150 | |||
151 | const struct clk_ops tegra_clk_periph_ops = { | ||
152 | .get_parent = clk_periph_get_parent, | ||
153 | .set_parent = clk_periph_set_parent, | ||
154 | .recalc_rate = clk_periph_recalc_rate, | ||
155 | .round_rate = clk_periph_round_rate, | ||
156 | .set_rate = clk_periph_set_rate, | ||
157 | .is_enabled = clk_periph_is_enabled, | ||
158 | .enable = clk_periph_enable, | ||
159 | .disable = clk_periph_disable, | ||
160 | }; | ||
161 | |||
162 | const struct clk_ops tegra_clk_periph_nodiv_ops = { | ||
163 | .get_parent = clk_periph_get_parent, | ||
164 | .set_parent = clk_periph_set_parent, | ||
165 | .is_enabled = clk_periph_is_enabled, | ||
166 | .enable = clk_periph_enable, | ||
167 | .disable = clk_periph_disable, | ||
168 | }; | ||
169 | |||
170 | static struct clk *_tegra_clk_register_periph(const char *name, | ||
171 | const char **parent_names, int num_parents, | ||
172 | struct tegra_clk_periph *periph, | ||
173 | void __iomem *clk_base, u32 offset, bool div) | ||
174 | { | ||
175 | struct clk *clk; | ||
176 | struct clk_init_data init; | ||
177 | |||
178 | init.name = name; | ||
179 | init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; | ||
180 | init.flags = div ? 0 : CLK_SET_RATE_PARENT; | ||
181 | init.parent_names = parent_names; | ||
182 | init.num_parents = num_parents; | ||
183 | |||
184 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
185 | periph->hw.init = &init; | ||
186 | periph->magic = TEGRA_CLK_PERIPH_MAGIC; | ||
187 | periph->mux.reg = clk_base + offset; | ||
188 | periph->divider.reg = div ? (clk_base + offset) : NULL; | ||
189 | periph->gate.clk_base = clk_base; | ||
190 | |||
191 | clk = clk_register(NULL, &periph->hw); | ||
192 | if (IS_ERR(clk)) | ||
193 | return clk; | ||
194 | |||
195 | periph->mux.hw.clk = clk; | ||
196 | periph->divider.hw.clk = div ? clk : NULL; | ||
197 | periph->gate.hw.clk = clk; | ||
198 | |||
199 | return clk; | ||
200 | } | ||
201 | |||
202 | struct clk *tegra_clk_register_periph(const char *name, | ||
203 | const char **parent_names, int num_parents, | ||
204 | struct tegra_clk_periph *periph, void __iomem *clk_base, | ||
205 | u32 offset) | ||
206 | { | ||
207 | return _tegra_clk_register_periph(name, parent_names, num_parents, | ||
208 | periph, clk_base, offset, true); | ||
209 | } | ||
210 | |||
211 | struct clk *tegra_clk_register_periph_nodiv(const char *name, | ||
212 | const char **parent_names, int num_parents, | ||
213 | struct tegra_clk_periph *periph, void __iomem *clk_base, | ||
214 | u32 offset) | ||
215 | { | ||
216 | return _tegra_clk_register_periph(name, parent_names, num_parents, | ||
217 | periph, clk_base, offset, false); | ||
218 | } | ||
diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c new file mode 100644 index 000000000000..3598987a451d --- /dev/null +++ b/drivers/clk/tegra/clk-pll-out.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/clk-provider.h> | ||
23 | #include <linux/clk.h> | ||
24 | |||
25 | #include "clk.h" | ||
26 | |||
27 | #define pll_out_enb(p) (BIT(p->enb_bit_idx)) | ||
28 | #define pll_out_rst(p) (BIT(p->rst_bit_idx)) | ||
29 | |||
30 | static int clk_pll_out_is_enabled(struct clk_hw *hw) | ||
31 | { | ||
32 | struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw); | ||
33 | u32 val = readl_relaxed(pll_out->reg); | ||
34 | int state; | ||
35 | |||
36 | state = (val & pll_out_enb(pll_out)) ? 1 : 0; | ||
37 | if (!(val & (pll_out_rst(pll_out)))) | ||
38 | state = 0; | ||
39 | return state; | ||
40 | } | ||
41 | |||
42 | static int clk_pll_out_enable(struct clk_hw *hw) | ||
43 | { | ||
44 | struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw); | ||
45 | unsigned long flags = 0; | ||
46 | u32 val; | ||
47 | |||
48 | if (pll_out->lock) | ||
49 | spin_lock_irqsave(pll_out->lock, flags); | ||
50 | |||
51 | val = readl_relaxed(pll_out->reg); | ||
52 | |||
53 | val |= (pll_out_enb(pll_out) | pll_out_rst(pll_out)); | ||
54 | |||
55 | writel_relaxed(val, pll_out->reg); | ||
56 | udelay(2); | ||
57 | |||
58 | if (pll_out->lock) | ||
59 | spin_unlock_irqrestore(pll_out->lock, flags); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void clk_pll_out_disable(struct clk_hw *hw) | ||
65 | { | ||
66 | struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw); | ||
67 | unsigned long flags = 0; | ||
68 | u32 val; | ||
69 | |||
70 | if (pll_out->lock) | ||
71 | spin_lock_irqsave(pll_out->lock, flags); | ||
72 | |||
73 | val = readl_relaxed(pll_out->reg); | ||
74 | |||
75 | val &= ~(pll_out_enb(pll_out) | pll_out_rst(pll_out)); | ||
76 | |||
77 | writel_relaxed(val, pll_out->reg); | ||
78 | udelay(2); | ||
79 | |||
80 | if (pll_out->lock) | ||
81 | spin_unlock_irqrestore(pll_out->lock, flags); | ||
82 | } | ||
83 | |||
84 | const struct clk_ops tegra_clk_pll_out_ops = { | ||
85 | .is_enabled = clk_pll_out_is_enabled, | ||
86 | .enable = clk_pll_out_enable, | ||
87 | .disable = clk_pll_out_disable, | ||
88 | }; | ||
89 | |||
90 | struct clk *tegra_clk_register_pll_out(const char *name, | ||
91 | const char *parent_name, void __iomem *reg, u8 enb_bit_idx, | ||
92 | u8 rst_bit_idx, unsigned long flags, u8 pll_out_flags, | ||
93 | spinlock_t *lock) | ||
94 | { | ||
95 | struct tegra_clk_pll_out *pll_out; | ||
96 | struct clk *clk; | ||
97 | struct clk_init_data init; | ||
98 | |||
99 | pll_out = kzalloc(sizeof(*pll_out), GFP_KERNEL); | ||
100 | if (!pll_out) | ||
101 | return ERR_PTR(-ENOMEM); | ||
102 | |||
103 | init.name = name; | ||
104 | init.ops = &tegra_clk_pll_out_ops; | ||
105 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
106 | init.num_parents = (parent_name ? 1 : 0); | ||
107 | init.flags = flags; | ||
108 | |||
109 | pll_out->reg = reg; | ||
110 | pll_out->enb_bit_idx = enb_bit_idx; | ||
111 | pll_out->rst_bit_idx = rst_bit_idx; | ||
112 | pll_out->flags = pll_out_flags; | ||
113 | pll_out->lock = lock; | ||
114 | |||
115 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
116 | pll_out->hw.init = &init; | ||
117 | |||
118 | clk = clk_register(NULL, &pll_out->hw); | ||
119 | if (IS_ERR(clk)) | ||
120 | kfree(pll_out); | ||
121 | |||
122 | return clk; | ||
123 | } | ||
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c new file mode 100644 index 000000000000..165f24734c1b --- /dev/null +++ b/drivers/clk/tegra/clk-pll.c | |||
@@ -0,0 +1,648 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/slab.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/clk-provider.h> | ||
22 | #include <linux/clk.h> | ||
23 | |||
24 | #include "clk.h" | ||
25 | |||
26 | #define PLL_BASE_BYPASS BIT(31) | ||
27 | #define PLL_BASE_ENABLE BIT(30) | ||
28 | #define PLL_BASE_REF_ENABLE BIT(29) | ||
29 | #define PLL_BASE_OVERRIDE BIT(28) | ||
30 | |||
31 | #define PLL_BASE_DIVP_SHIFT 20 | ||
32 | #define PLL_BASE_DIVP_WIDTH 3 | ||
33 | #define PLL_BASE_DIVN_SHIFT 8 | ||
34 | #define PLL_BASE_DIVN_WIDTH 10 | ||
35 | #define PLL_BASE_DIVM_SHIFT 0 | ||
36 | #define PLL_BASE_DIVM_WIDTH 5 | ||
37 | #define PLLU_POST_DIVP_MASK 0x1 | ||
38 | |||
39 | #define PLL_MISC_DCCON_SHIFT 20 | ||
40 | #define PLL_MISC_CPCON_SHIFT 8 | ||
41 | #define PLL_MISC_CPCON_WIDTH 4 | ||
42 | #define PLL_MISC_CPCON_MASK ((1 << PLL_MISC_CPCON_WIDTH) - 1) | ||
43 | #define PLL_MISC_LFCON_SHIFT 4 | ||
44 | #define PLL_MISC_LFCON_WIDTH 4 | ||
45 | #define PLL_MISC_LFCON_MASK ((1 << PLL_MISC_LFCON_WIDTH) - 1) | ||
46 | #define PLL_MISC_VCOCON_SHIFT 0 | ||
47 | #define PLL_MISC_VCOCON_WIDTH 4 | ||
48 | #define PLL_MISC_VCOCON_MASK ((1 << PLL_MISC_VCOCON_WIDTH) - 1) | ||
49 | |||
50 | #define OUT_OF_TABLE_CPCON 8 | ||
51 | |||
52 | #define PMC_PLLP_WB0_OVERRIDE 0xf8 | ||
53 | #define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12) | ||
54 | #define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11) | ||
55 | |||
56 | #define PLL_POST_LOCK_DELAY 50 | ||
57 | |||
58 | #define PLLDU_LFCON_SET_DIVN 600 | ||
59 | |||
60 | #define PLLE_BASE_DIVCML_SHIFT 24 | ||
61 | #define PLLE_BASE_DIVCML_WIDTH 4 | ||
62 | #define PLLE_BASE_DIVP_SHIFT 16 | ||
63 | #define PLLE_BASE_DIVP_WIDTH 7 | ||
64 | #define PLLE_BASE_DIVN_SHIFT 8 | ||
65 | #define PLLE_BASE_DIVN_WIDTH 8 | ||
66 | #define PLLE_BASE_DIVM_SHIFT 0 | ||
67 | #define PLLE_BASE_DIVM_WIDTH 8 | ||
68 | |||
69 | #define PLLE_MISC_SETUP_BASE_SHIFT 16 | ||
70 | #define PLLE_MISC_SETUP_BASE_MASK (0xffff << PLLE_MISC_SETUP_BASE_SHIFT) | ||
71 | #define PLLE_MISC_LOCK_ENABLE BIT(9) | ||
72 | #define PLLE_MISC_READY BIT(15) | ||
73 | #define PLLE_MISC_SETUP_EX_SHIFT 2 | ||
74 | #define PLLE_MISC_SETUP_EX_MASK (3 << PLLE_MISC_SETUP_EX_SHIFT) | ||
75 | #define PLLE_MISC_SETUP_MASK (PLLE_MISC_SETUP_BASE_MASK | \ | ||
76 | PLLE_MISC_SETUP_EX_MASK) | ||
77 | #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) | ||
78 | |||
79 | #define PLLE_SS_CTRL 0x68 | ||
80 | #define PLLE_SS_DISABLE (7 << 10) | ||
81 | |||
82 | #define PMC_SATA_PWRGT 0x1ac | ||
83 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) | ||
84 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) | ||
85 | |||
86 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) | ||
87 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) | ||
88 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) | ||
89 | |||
90 | #define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset) | ||
91 | #define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p) | ||
92 | #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) | ||
93 | |||
94 | #define mask(w) ((1 << (w)) - 1) | ||
95 | #define divm_mask(p) mask(p->divm_width) | ||
96 | #define divn_mask(p) mask(p->divn_width) | ||
97 | #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ | ||
98 | mask(p->divp_width)) | ||
99 | |||
100 | #define divm_max(p) (divm_mask(p)) | ||
101 | #define divn_max(p) (divn_mask(p)) | ||
102 | #define divp_max(p) (1 << (divp_mask(p))) | ||
103 | |||
104 | static void clk_pll_enable_lock(struct tegra_clk_pll *pll) | ||
105 | { | ||
106 | u32 val; | ||
107 | |||
108 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) | ||
109 | return; | ||
110 | |||
111 | val = pll_readl_misc(pll); | ||
112 | val |= BIT(pll->params->lock_enable_bit_idx); | ||
113 | pll_writel_misc(val, pll); | ||
114 | } | ||
115 | |||
116 | static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll, | ||
117 | void __iomem *lock_addr, u32 lock_bit_idx) | ||
118 | { | ||
119 | int i; | ||
120 | u32 val; | ||
121 | |||
122 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { | ||
123 | udelay(pll->params->lock_delay); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | for (i = 0; i < pll->params->lock_delay; i++) { | ||
128 | val = readl_relaxed(lock_addr); | ||
129 | if (val & BIT(lock_bit_idx)) { | ||
130 | udelay(PLL_POST_LOCK_DELAY); | ||
131 | return 0; | ||
132 | } | ||
133 | udelay(2); /* timeout = 2 * lock time */ | ||
134 | } | ||
135 | |||
136 | pr_err("%s: Timed out waiting for pll %s lock\n", __func__, | ||
137 | __clk_get_name(pll->hw.clk)); | ||
138 | |||
139 | return -1; | ||
140 | } | ||
141 | |||
142 | static int clk_pll_is_enabled(struct clk_hw *hw) | ||
143 | { | ||
144 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
145 | u32 val; | ||
146 | |||
147 | if (pll->flags & TEGRA_PLLM) { | ||
148 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | ||
149 | if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) | ||
150 | return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; | ||
151 | } | ||
152 | |||
153 | val = pll_readl_base(pll); | ||
154 | |||
155 | return val & PLL_BASE_ENABLE ? 1 : 0; | ||
156 | } | ||
157 | |||
158 | static int _clk_pll_enable(struct clk_hw *hw) | ||
159 | { | ||
160 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
161 | u32 val; | ||
162 | |||
163 | clk_pll_enable_lock(pll); | ||
164 | |||
165 | val = pll_readl_base(pll); | ||
166 | val &= ~PLL_BASE_BYPASS; | ||
167 | val |= PLL_BASE_ENABLE; | ||
168 | pll_writel_base(val, pll); | ||
169 | |||
170 | if (pll->flags & TEGRA_PLLM) { | ||
171 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | ||
172 | val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | ||
173 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | ||
174 | } | ||
175 | |||
176 | clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg, | ||
177 | pll->params->lock_bit_idx); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static void _clk_pll_disable(struct clk_hw *hw) | ||
183 | { | ||
184 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
185 | u32 val; | ||
186 | |||
187 | val = pll_readl_base(pll); | ||
188 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); | ||
189 | pll_writel_base(val, pll); | ||
190 | |||
191 | if (pll->flags & TEGRA_PLLM) { | ||
192 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | ||
193 | val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | ||
194 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | static int clk_pll_enable(struct clk_hw *hw) | ||
199 | { | ||
200 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
201 | unsigned long flags = 0; | ||
202 | int ret; | ||
203 | |||
204 | if (pll->lock) | ||
205 | spin_lock_irqsave(pll->lock, flags); | ||
206 | |||
207 | ret = _clk_pll_enable(hw); | ||
208 | |||
209 | if (pll->lock) | ||
210 | spin_unlock_irqrestore(pll->lock, flags); | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | static void clk_pll_disable(struct clk_hw *hw) | ||
216 | { | ||
217 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
218 | unsigned long flags = 0; | ||
219 | |||
220 | if (pll->lock) | ||
221 | spin_lock_irqsave(pll->lock, flags); | ||
222 | |||
223 | _clk_pll_disable(hw); | ||
224 | |||
225 | if (pll->lock) | ||
226 | spin_unlock_irqrestore(pll->lock, flags); | ||
227 | } | ||
228 | |||
229 | static int _get_table_rate(struct clk_hw *hw, | ||
230 | struct tegra_clk_pll_freq_table *cfg, | ||
231 | unsigned long rate, unsigned long parent_rate) | ||
232 | { | ||
233 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
234 | struct tegra_clk_pll_freq_table *sel; | ||
235 | |||
236 | for (sel = pll->freq_table; sel->input_rate != 0; sel++) | ||
237 | if (sel->input_rate == parent_rate && | ||
238 | sel->output_rate == rate) | ||
239 | break; | ||
240 | |||
241 | if (sel->input_rate == 0) | ||
242 | return -EINVAL; | ||
243 | |||
244 | BUG_ON(sel->p < 1); | ||
245 | |||
246 | cfg->input_rate = sel->input_rate; | ||
247 | cfg->output_rate = sel->output_rate; | ||
248 | cfg->m = sel->m; | ||
249 | cfg->n = sel->n; | ||
250 | cfg->p = sel->p; | ||
251 | cfg->cpcon = sel->cpcon; | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | ||
257 | unsigned long rate, unsigned long parent_rate) | ||
258 | { | ||
259 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
260 | unsigned long cfreq; | ||
261 | u32 p_div = 0; | ||
262 | |||
263 | switch (parent_rate) { | ||
264 | case 12000000: | ||
265 | case 26000000: | ||
266 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000; | ||
267 | break; | ||
268 | case 13000000: | ||
269 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000; | ||
270 | break; | ||
271 | case 16800000: | ||
272 | case 19200000: | ||
273 | cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000; | ||
274 | break; | ||
275 | case 9600000: | ||
276 | case 28800000: | ||
277 | /* | ||
278 | * PLL_P_OUT1 rate is not listed in PLLA table | ||
279 | */ | ||
280 | cfreq = parent_rate/(parent_rate/1000000); | ||
281 | break; | ||
282 | default: | ||
283 | pr_err("%s Unexpected reference rate %lu\n", | ||
284 | __func__, parent_rate); | ||
285 | BUG(); | ||
286 | } | ||
287 | |||
288 | /* Raise VCO to guarantee 0.5% accuracy */ | ||
289 | for (cfg->output_rate = rate; cfg->output_rate < 200 * cfreq; | ||
290 | cfg->output_rate <<= 1) | ||
291 | p_div++; | ||
292 | |||
293 | cfg->p = 1 << p_div; | ||
294 | cfg->m = parent_rate / cfreq; | ||
295 | cfg->n = cfg->output_rate / cfreq; | ||
296 | cfg->cpcon = OUT_OF_TABLE_CPCON; | ||
297 | |||
298 | if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || | ||
299 | cfg->p > divp_max(pll) || cfg->output_rate > pll->params->vco_max) { | ||
300 | pr_err("%s: Failed to set %s rate %lu\n", | ||
301 | __func__, __clk_get_name(hw->clk), rate); | ||
302 | return -EINVAL; | ||
303 | } | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | ||
309 | unsigned long rate) | ||
310 | { | ||
311 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
312 | unsigned long flags = 0; | ||
313 | u32 divp, val, old_base; | ||
314 | int state; | ||
315 | |||
316 | divp = __ffs(cfg->p); | ||
317 | |||
318 | if (pll->flags & TEGRA_PLLU) | ||
319 | divp ^= 1; | ||
320 | |||
321 | if (pll->lock) | ||
322 | spin_lock_irqsave(pll->lock, flags); | ||
323 | |||
324 | old_base = val = pll_readl_base(pll); | ||
325 | val &= ~((divm_mask(pll) << pll->divm_shift) | | ||
326 | (divn_mask(pll) << pll->divn_shift) | | ||
327 | (divp_mask(pll) << pll->divp_shift)); | ||
328 | val |= ((cfg->m << pll->divm_shift) | | ||
329 | (cfg->n << pll->divn_shift) | | ||
330 | (divp << pll->divp_shift)); | ||
331 | if (val == old_base) { | ||
332 | if (pll->lock) | ||
333 | spin_unlock_irqrestore(pll->lock, flags); | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | state = clk_pll_is_enabled(hw); | ||
338 | |||
339 | if (state) { | ||
340 | _clk_pll_disable(hw); | ||
341 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); | ||
342 | } | ||
343 | pll_writel_base(val, pll); | ||
344 | |||
345 | if (pll->flags & TEGRA_PLL_HAS_CPCON) { | ||
346 | val = pll_readl_misc(pll); | ||
347 | val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); | ||
348 | val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; | ||
349 | if (pll->flags & TEGRA_PLL_SET_LFCON) { | ||
350 | val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); | ||
351 | if (cfg->n >= PLLDU_LFCON_SET_DIVN) | ||
352 | val |= 0x1 << PLL_MISC_LFCON_SHIFT; | ||
353 | } else if (pll->flags & TEGRA_PLL_SET_DCCON) { | ||
354 | val &= ~(0x1 << PLL_MISC_DCCON_SHIFT); | ||
355 | if (rate >= (pll->params->vco_max >> 1)) | ||
356 | val |= 0x1 << PLL_MISC_DCCON_SHIFT; | ||
357 | } | ||
358 | pll_writel_misc(val, pll); | ||
359 | } | ||
360 | |||
361 | if (pll->lock) | ||
362 | spin_unlock_irqrestore(pll->lock, flags); | ||
363 | |||
364 | if (state) | ||
365 | clk_pll_enable(hw); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
371 | unsigned long parent_rate) | ||
372 | { | ||
373 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
374 | struct tegra_clk_pll_freq_table cfg; | ||
375 | |||
376 | if (pll->flags & TEGRA_PLL_FIXED) { | ||
377 | if (rate != pll->fixed_rate) { | ||
378 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", | ||
379 | __func__, __clk_get_name(hw->clk), | ||
380 | pll->fixed_rate, rate); | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && | ||
387 | _calc_rate(hw, &cfg, rate, parent_rate)) | ||
388 | return -EINVAL; | ||
389 | |||
390 | return _program_pll(hw, &cfg, rate); | ||
391 | } | ||
392 | |||
393 | static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
394 | unsigned long *prate) | ||
395 | { | ||
396 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
397 | struct tegra_clk_pll_freq_table cfg; | ||
398 | u64 output_rate = *prate; | ||
399 | |||
400 | if (pll->flags & TEGRA_PLL_FIXED) | ||
401 | return pll->fixed_rate; | ||
402 | |||
403 | /* PLLM is used for memory; we do not change rate */ | ||
404 | if (pll->flags & TEGRA_PLLM) | ||
405 | return __clk_get_rate(hw->clk); | ||
406 | |||
407 | if (_get_table_rate(hw, &cfg, rate, *prate) && | ||
408 | _calc_rate(hw, &cfg, rate, *prate)) | ||
409 | return -EINVAL; | ||
410 | |||
411 | output_rate *= cfg.n; | ||
412 | do_div(output_rate, cfg.m * cfg.p); | ||
413 | |||
414 | return output_rate; | ||
415 | } | ||
416 | |||
417 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | ||
418 | unsigned long parent_rate) | ||
419 | { | ||
420 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
421 | u32 val = pll_readl_base(pll); | ||
422 | u32 divn = 0, divm = 0, divp = 0; | ||
423 | u64 rate = parent_rate; | ||
424 | |||
425 | if (val & PLL_BASE_BYPASS) | ||
426 | return parent_rate; | ||
427 | |||
428 | if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { | ||
429 | struct tegra_clk_pll_freq_table sel; | ||
430 | if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) { | ||
431 | pr_err("Clock %s has unknown fixed frequency\n", | ||
432 | __clk_get_name(hw->clk)); | ||
433 | BUG(); | ||
434 | } | ||
435 | return pll->fixed_rate; | ||
436 | } | ||
437 | |||
438 | divp = (val >> pll->divp_shift) & (divp_mask(pll)); | ||
439 | if (pll->flags & TEGRA_PLLU) | ||
440 | divp ^= 1; | ||
441 | |||
442 | divn = (val >> pll->divn_shift) & (divn_mask(pll)); | ||
443 | divm = (val >> pll->divm_shift) & (divm_mask(pll)); | ||
444 | divm *= (1 << divp); | ||
445 | |||
446 | rate *= divn; | ||
447 | do_div(rate, divm); | ||
448 | return rate; | ||
449 | } | ||
450 | |||
451 | static int clk_plle_training(struct tegra_clk_pll *pll) | ||
452 | { | ||
453 | u32 val; | ||
454 | unsigned long timeout; | ||
455 | |||
456 | if (!pll->pmc) | ||
457 | return -ENOSYS; | ||
458 | |||
459 | /* | ||
460 | * PLLE is already disabled, and setup cleared; | ||
461 | * create falling edge on PLLE IDDQ input. | ||
462 | */ | ||
463 | val = readl(pll->pmc + PMC_SATA_PWRGT); | ||
464 | val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; | ||
465 | writel(val, pll->pmc + PMC_SATA_PWRGT); | ||
466 | |||
467 | val = readl(pll->pmc + PMC_SATA_PWRGT); | ||
468 | val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; | ||
469 | writel(val, pll->pmc + PMC_SATA_PWRGT); | ||
470 | |||
471 | val = readl(pll->pmc + PMC_SATA_PWRGT); | ||
472 | val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; | ||
473 | writel(val, pll->pmc + PMC_SATA_PWRGT); | ||
474 | |||
475 | val = pll_readl_misc(pll); | ||
476 | |||
477 | timeout = jiffies + msecs_to_jiffies(100); | ||
478 | while (1) { | ||
479 | val = pll_readl_misc(pll); | ||
480 | if (val & PLLE_MISC_READY) | ||
481 | break; | ||
482 | if (time_after(jiffies, timeout)) { | ||
483 | pr_err("%s: timeout waiting for PLLE\n", __func__); | ||
484 | return -EBUSY; | ||
485 | } | ||
486 | udelay(300); | ||
487 | } | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int clk_plle_enable(struct clk_hw *hw) | ||
493 | { | ||
494 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
495 | unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); | ||
496 | struct tegra_clk_pll_freq_table sel; | ||
497 | u32 val; | ||
498 | int err; | ||
499 | |||
500 | if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) | ||
501 | return -EINVAL; | ||
502 | |||
503 | clk_pll_disable(hw); | ||
504 | |||
505 | val = pll_readl_misc(pll); | ||
506 | val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK); | ||
507 | pll_writel_misc(val, pll); | ||
508 | |||
509 | val = pll_readl_misc(pll); | ||
510 | if (!(val & PLLE_MISC_READY)) { | ||
511 | err = clk_plle_training(pll); | ||
512 | if (err) | ||
513 | return err; | ||
514 | } | ||
515 | |||
516 | if (pll->flags & TEGRA_PLLE_CONFIGURE) { | ||
517 | /* configure dividers */ | ||
518 | val = pll_readl_base(pll); | ||
519 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | ||
520 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); | ||
521 | val |= sel.m << pll->divm_shift; | ||
522 | val |= sel.n << pll->divn_shift; | ||
523 | val |= sel.p << pll->divp_shift; | ||
524 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; | ||
525 | pll_writel_base(val, pll); | ||
526 | } | ||
527 | |||
528 | val = pll_readl_misc(pll); | ||
529 | val |= PLLE_MISC_SETUP_VALUE; | ||
530 | val |= PLLE_MISC_LOCK_ENABLE; | ||
531 | pll_writel_misc(val, pll); | ||
532 | |||
533 | val = readl(pll->clk_base + PLLE_SS_CTRL); | ||
534 | val |= PLLE_SS_DISABLE; | ||
535 | writel(val, pll->clk_base + PLLE_SS_CTRL); | ||
536 | |||
537 | val |= pll_readl_base(pll); | ||
538 | val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE); | ||
539 | pll_writel_base(val, pll); | ||
540 | |||
541 | clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg, | ||
542 | pll->params->lock_bit_idx); | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static unsigned long clk_plle_recalc_rate(struct clk_hw *hw, | ||
547 | unsigned long parent_rate) | ||
548 | { | ||
549 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
550 | u32 val = pll_readl_base(pll); | ||
551 | u32 divn = 0, divm = 0, divp = 0; | ||
552 | u64 rate = parent_rate; | ||
553 | |||
554 | divp = (val >> pll->divp_shift) & (divp_mask(pll)); | ||
555 | divn = (val >> pll->divn_shift) & (divn_mask(pll)); | ||
556 | divm = (val >> pll->divm_shift) & (divm_mask(pll)); | ||
557 | divm *= divp; | ||
558 | |||
559 | rate *= divn; | ||
560 | do_div(rate, divm); | ||
561 | return rate; | ||
562 | } | ||
563 | |||
564 | const struct clk_ops tegra_clk_pll_ops = { | ||
565 | .is_enabled = clk_pll_is_enabled, | ||
566 | .enable = clk_pll_enable, | ||
567 | .disable = clk_pll_disable, | ||
568 | .recalc_rate = clk_pll_recalc_rate, | ||
569 | .round_rate = clk_pll_round_rate, | ||
570 | .set_rate = clk_pll_set_rate, | ||
571 | }; | ||
572 | |||
573 | const struct clk_ops tegra_clk_plle_ops = { | ||
574 | .recalc_rate = clk_plle_recalc_rate, | ||
575 | .is_enabled = clk_pll_is_enabled, | ||
576 | .disable = clk_pll_disable, | ||
577 | .enable = clk_plle_enable, | ||
578 | }; | ||
579 | |||
580 | static struct clk *_tegra_clk_register_pll(const char *name, | ||
581 | const char *parent_name, void __iomem *clk_base, | ||
582 | void __iomem *pmc, unsigned long flags, | ||
583 | unsigned long fixed_rate, | ||
584 | struct tegra_clk_pll_params *pll_params, u8 pll_flags, | ||
585 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock, | ||
586 | const struct clk_ops *ops) | ||
587 | { | ||
588 | struct tegra_clk_pll *pll; | ||
589 | struct clk *clk; | ||
590 | struct clk_init_data init; | ||
591 | |||
592 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); | ||
593 | if (!pll) | ||
594 | return ERR_PTR(-ENOMEM); | ||
595 | |||
596 | init.name = name; | ||
597 | init.ops = ops; | ||
598 | init.flags = flags; | ||
599 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
600 | init.num_parents = (parent_name ? 1 : 0); | ||
601 | |||
602 | pll->clk_base = clk_base; | ||
603 | pll->pmc = pmc; | ||
604 | |||
605 | pll->freq_table = freq_table; | ||
606 | pll->params = pll_params; | ||
607 | pll->fixed_rate = fixed_rate; | ||
608 | pll->flags = pll_flags; | ||
609 | pll->lock = lock; | ||
610 | |||
611 | pll->divp_shift = PLL_BASE_DIVP_SHIFT; | ||
612 | pll->divp_width = PLL_BASE_DIVP_WIDTH; | ||
613 | pll->divn_shift = PLL_BASE_DIVN_SHIFT; | ||
614 | pll->divn_width = PLL_BASE_DIVN_WIDTH; | ||
615 | pll->divm_shift = PLL_BASE_DIVM_SHIFT; | ||
616 | pll->divm_width = PLL_BASE_DIVM_WIDTH; | ||
617 | |||
618 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
619 | pll->hw.init = &init; | ||
620 | |||
621 | clk = clk_register(NULL, &pll->hw); | ||
622 | if (IS_ERR(clk)) | ||
623 | kfree(pll); | ||
624 | |||
625 | return clk; | ||
626 | } | ||
627 | |||
628 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | ||
629 | void __iomem *clk_base, void __iomem *pmc, | ||
630 | unsigned long flags, unsigned long fixed_rate, | ||
631 | struct tegra_clk_pll_params *pll_params, u8 pll_flags, | ||
632 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
633 | { | ||
634 | return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, | ||
635 | flags, fixed_rate, pll_params, pll_flags, freq_table, | ||
636 | lock, &tegra_clk_pll_ops); | ||
637 | } | ||
638 | |||
639 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | ||
640 | void __iomem *clk_base, void __iomem *pmc, | ||
641 | unsigned long flags, unsigned long fixed_rate, | ||
642 | struct tegra_clk_pll_params *pll_params, u8 pll_flags, | ||
643 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
644 | { | ||
645 | return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, | ||
646 | flags, fixed_rate, pll_params, pll_flags, freq_table, | ||
647 | lock, &tegra_clk_plle_ops); | ||
648 | } | ||
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c new file mode 100644 index 000000000000..7ad48a832334 --- /dev/null +++ b/drivers/clk/tegra/clk-super.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/clk-provider.h> | ||
23 | #include <linux/clk.h> | ||
24 | |||
25 | #include "clk.h" | ||
26 | |||
27 | #define SUPER_STATE_IDLE 0 | ||
28 | #define SUPER_STATE_RUN 1 | ||
29 | #define SUPER_STATE_IRQ 2 | ||
30 | #define SUPER_STATE_FIQ 3 | ||
31 | |||
32 | #define SUPER_STATE_SHIFT 28 | ||
33 | #define SUPER_STATE_MASK ((BIT(SUPER_STATE_IDLE) | BIT(SUPER_STATE_RUN) | \ | ||
34 | BIT(SUPER_STATE_IRQ) | BIT(SUPER_STATE_FIQ)) \ | ||
35 | << SUPER_STATE_SHIFT) | ||
36 | |||
37 | #define SUPER_LP_DIV2_BYPASS (1 << 16) | ||
38 | |||
39 | #define super_state(s) (BIT(s) << SUPER_STATE_SHIFT) | ||
40 | #define super_state_to_src_shift(m, s) ((m->width * s)) | ||
41 | #define super_state_to_src_mask(m) (((1 << m->width) - 1)) | ||
42 | |||
43 | static u8 clk_super_get_parent(struct clk_hw *hw) | ||
44 | { | ||
45 | struct tegra_clk_super_mux *mux = to_clk_super_mux(hw); | ||
46 | u32 val, state; | ||
47 | u8 source, shift; | ||
48 | |||
49 | val = readl_relaxed(mux->reg); | ||
50 | |||
51 | state = val & SUPER_STATE_MASK; | ||
52 | |||
53 | BUG_ON((state != super_state(SUPER_STATE_RUN)) && | ||
54 | (state != super_state(SUPER_STATE_IDLE))); | ||
55 | shift = (state == super_state(SUPER_STATE_IDLE)) ? | ||
56 | super_state_to_src_shift(mux, SUPER_STATE_IDLE) : | ||
57 | super_state_to_src_shift(mux, SUPER_STATE_RUN); | ||
58 | |||
59 | source = (val >> shift) & super_state_to_src_mask(mux); | ||
60 | |||
61 | /* | ||
62 | * If LP_DIV2_BYPASS is not set and PLLX is current parent then | ||
63 | * PLLX/2 is the input source to CCLKLP. | ||
64 | */ | ||
65 | if ((mux->flags & TEGRA_DIVIDER_2) && !(val & SUPER_LP_DIV2_BYPASS) && | ||
66 | (source == mux->pllx_index)) | ||
67 | source = mux->div2_index; | ||
68 | |||
69 | return source; | ||
70 | } | ||
71 | |||
72 | static int clk_super_set_parent(struct clk_hw *hw, u8 index) | ||
73 | { | ||
74 | struct tegra_clk_super_mux *mux = to_clk_super_mux(hw); | ||
75 | u32 val, state; | ||
76 | u8 parent_index, shift; | ||
77 | |||
78 | val = readl_relaxed(mux->reg); | ||
79 | state = val & SUPER_STATE_MASK; | ||
80 | BUG_ON((state != super_state(SUPER_STATE_RUN)) && | ||
81 | (state != super_state(SUPER_STATE_IDLE))); | ||
82 | shift = (state == super_state(SUPER_STATE_IDLE)) ? | ||
83 | super_state_to_src_shift(mux, SUPER_STATE_IDLE) : | ||
84 | super_state_to_src_shift(mux, SUPER_STATE_RUN); | ||
85 | |||
86 | /* | ||
87 | * For LP mode super-clock switch between PLLX direct | ||
88 | * and divided-by-2 outputs is allowed only when other | ||
89 | * than PLLX clock source is current parent. | ||
90 | */ | ||
91 | if ((mux->flags & TEGRA_DIVIDER_2) && ((index == mux->div2_index) || | ||
92 | (index == mux->pllx_index))) { | ||
93 | parent_index = clk_super_get_parent(hw); | ||
94 | if ((parent_index == mux->div2_index) || | ||
95 | (parent_index == mux->pllx_index)) | ||
96 | return -EINVAL; | ||
97 | |||
98 | val ^= SUPER_LP_DIV2_BYPASS; | ||
99 | writel_relaxed(val, mux->reg); | ||
100 | udelay(2); | ||
101 | |||
102 | if (index == mux->div2_index) | ||
103 | index = mux->pllx_index; | ||
104 | } | ||
105 | val &= ~((super_state_to_src_mask(mux)) << shift); | ||
106 | val |= (index & (super_state_to_src_mask(mux))) << shift; | ||
107 | |||
108 | writel_relaxed(val, mux->reg); | ||
109 | udelay(2); | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | const struct clk_ops tegra_clk_super_ops = { | ||
114 | .get_parent = clk_super_get_parent, | ||
115 | .set_parent = clk_super_set_parent, | ||
116 | }; | ||
117 | |||
118 | struct clk *tegra_clk_register_super_mux(const char *name, | ||
119 | const char **parent_names, u8 num_parents, | ||
120 | unsigned long flags, void __iomem *reg, u8 clk_super_flags, | ||
121 | u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock) | ||
122 | { | ||
123 | struct tegra_clk_super_mux *super; | ||
124 | struct clk *clk; | ||
125 | struct clk_init_data init; | ||
126 | |||
127 | super = kzalloc(sizeof(*super), GFP_KERNEL); | ||
128 | if (!super) { | ||
129 | pr_err("%s: could not allocate super clk\n", __func__); | ||
130 | return ERR_PTR(-ENOMEM); | ||
131 | } | ||
132 | |||
133 | init.name = name; | ||
134 | init.ops = &tegra_clk_super_ops; | ||
135 | init.flags = flags; | ||
136 | init.parent_names = parent_names; | ||
137 | init.num_parents = num_parents; | ||
138 | |||
139 | super->reg = reg; | ||
140 | super->pllx_index = pllx_index; | ||
141 | super->div2_index = div2_index; | ||
142 | super->lock = lock; | ||
143 | super->width = width; | ||
144 | super->flags = clk_super_flags; | ||
145 | |||
146 | /* Data in .init is copied by clk_register(), so stack variable OK */ | ||
147 | super->hw.init = &init; | ||
148 | |||
149 | clk = clk_register(NULL, &super->hw); | ||
150 | if (IS_ERR(clk)) | ||
151 | kfree(super); | ||
152 | |||
153 | return clk; | ||
154 | } | ||
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c new file mode 100644 index 000000000000..5d41569883a7 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra20.c | |||
@@ -0,0 +1,1349 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/clkdev.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/clk/tegra.h> | ||
24 | #include <linux/delay.h> | ||
25 | |||
26 | #include "clk.h" | ||
27 | |||
28 | #define RST_DEVICES_L 0x004 | ||
29 | #define RST_DEVICES_H 0x008 | ||
30 | #define RST_DEVICES_U 0x00c | ||
31 | #define RST_DEVICES_SET_L 0x300 | ||
32 | #define RST_DEVICES_CLR_L 0x304 | ||
33 | #define RST_DEVICES_SET_H 0x308 | ||
34 | #define RST_DEVICES_CLR_H 0x30c | ||
35 | #define RST_DEVICES_SET_U 0x310 | ||
36 | #define RST_DEVICES_CLR_U 0x314 | ||
37 | #define RST_DEVICES_NUM 3 | ||
38 | |||
39 | #define CLK_OUT_ENB_L 0x010 | ||
40 | #define CLK_OUT_ENB_H 0x014 | ||
41 | #define CLK_OUT_ENB_U 0x018 | ||
42 | #define CLK_OUT_ENB_SET_L 0x320 | ||
43 | #define CLK_OUT_ENB_CLR_L 0x324 | ||
44 | #define CLK_OUT_ENB_SET_H 0x328 | ||
45 | #define CLK_OUT_ENB_CLR_H 0x32c | ||
46 | #define CLK_OUT_ENB_SET_U 0x330 | ||
47 | #define CLK_OUT_ENB_CLR_U 0x334 | ||
48 | #define CLK_OUT_ENB_NUM 3 | ||
49 | |||
50 | #define OSC_CTRL 0x50 | ||
51 | #define OSC_CTRL_OSC_FREQ_MASK (3<<30) | ||
52 | #define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) | ||
53 | #define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) | ||
54 | #define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) | ||
55 | #define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) | ||
56 | #define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) | ||
57 | |||
58 | #define OSC_CTRL_PLL_REF_DIV_MASK (3<<28) | ||
59 | #define OSC_CTRL_PLL_REF_DIV_1 (0<<28) | ||
60 | #define OSC_CTRL_PLL_REF_DIV_2 (1<<28) | ||
61 | #define OSC_CTRL_PLL_REF_DIV_4 (2<<28) | ||
62 | |||
63 | #define OSC_FREQ_DET 0x58 | ||
64 | #define OSC_FREQ_DET_TRIG (1<<31) | ||
65 | |||
66 | #define OSC_FREQ_DET_STATUS 0x5c | ||
67 | #define OSC_FREQ_DET_BUSY (1<<31) | ||
68 | #define OSC_FREQ_DET_CNT_MASK 0xFFFF | ||
69 | |||
70 | #define PLLS_BASE 0xf0 | ||
71 | #define PLLS_MISC 0xf4 | ||
72 | #define PLLC_BASE 0x80 | ||
73 | #define PLLC_MISC 0x8c | ||
74 | #define PLLM_BASE 0x90 | ||
75 | #define PLLM_MISC 0x9c | ||
76 | #define PLLP_BASE 0xa0 | ||
77 | #define PLLP_MISC 0xac | ||
78 | #define PLLA_BASE 0xb0 | ||
79 | #define PLLA_MISC 0xbc | ||
80 | #define PLLU_BASE 0xc0 | ||
81 | #define PLLU_MISC 0xcc | ||
82 | #define PLLD_BASE 0xd0 | ||
83 | #define PLLD_MISC 0xdc | ||
84 | #define PLLX_BASE 0xe0 | ||
85 | #define PLLX_MISC 0xe4 | ||
86 | #define PLLE_BASE 0xe8 | ||
87 | #define PLLE_MISC 0xec | ||
88 | |||
89 | #define PLL_BASE_LOCK 27 | ||
90 | #define PLLE_MISC_LOCK 11 | ||
91 | |||
92 | #define PLL_MISC_LOCK_ENABLE 18 | ||
93 | #define PLLDU_MISC_LOCK_ENABLE 22 | ||
94 | #define PLLE_MISC_LOCK_ENABLE 9 | ||
95 | |||
96 | #define PLLC_OUT 0x84 | ||
97 | #define PLLM_OUT 0x94 | ||
98 | #define PLLP_OUTA 0xa4 | ||
99 | #define PLLP_OUTB 0xa8 | ||
100 | #define PLLA_OUT 0xb4 | ||
101 | |||
102 | #define CCLK_BURST_POLICY 0x20 | ||
103 | #define SUPER_CCLK_DIVIDER 0x24 | ||
104 | #define SCLK_BURST_POLICY 0x28 | ||
105 | #define SUPER_SCLK_DIVIDER 0x2c | ||
106 | #define CLK_SYSTEM_RATE 0x30 | ||
107 | |||
108 | #define CCLK_BURST_POLICY_SHIFT 28 | ||
109 | #define CCLK_RUN_POLICY_SHIFT 4 | ||
110 | #define CCLK_IDLE_POLICY_SHIFT 0 | ||
111 | #define CCLK_IDLE_POLICY 1 | ||
112 | #define CCLK_RUN_POLICY 2 | ||
113 | #define CCLK_BURST_POLICY_PLLX 8 | ||
114 | |||
115 | #define CLK_SOURCE_I2S1 0x100 | ||
116 | #define CLK_SOURCE_I2S2 0x104 | ||
117 | #define CLK_SOURCE_SPDIF_OUT 0x108 | ||
118 | #define CLK_SOURCE_SPDIF_IN 0x10c | ||
119 | #define CLK_SOURCE_PWM 0x110 | ||
120 | #define CLK_SOURCE_SPI 0x114 | ||
121 | #define CLK_SOURCE_SBC1 0x134 | ||
122 | #define CLK_SOURCE_SBC2 0x118 | ||
123 | #define CLK_SOURCE_SBC3 0x11c | ||
124 | #define CLK_SOURCE_SBC4 0x1b4 | ||
125 | #define CLK_SOURCE_XIO 0x120 | ||
126 | #define CLK_SOURCE_TWC 0x12c | ||
127 | #define CLK_SOURCE_IDE 0x144 | ||
128 | #define CLK_SOURCE_NDFLASH 0x160 | ||
129 | #define CLK_SOURCE_VFIR 0x168 | ||
130 | #define CLK_SOURCE_SDMMC1 0x150 | ||
131 | #define CLK_SOURCE_SDMMC2 0x154 | ||
132 | #define CLK_SOURCE_SDMMC3 0x1bc | ||
133 | #define CLK_SOURCE_SDMMC4 0x164 | ||
134 | #define CLK_SOURCE_CVE 0x140 | ||
135 | #define CLK_SOURCE_TVO 0x188 | ||
136 | #define CLK_SOURCE_TVDAC 0x194 | ||
137 | #define CLK_SOURCE_HDMI 0x18c | ||
138 | #define CLK_SOURCE_DISP1 0x138 | ||
139 | #define CLK_SOURCE_DISP2 0x13c | ||
140 | #define CLK_SOURCE_CSITE 0x1d4 | ||
141 | #define CLK_SOURCE_LA 0x1f8 | ||
142 | #define CLK_SOURCE_OWR 0x1cc | ||
143 | #define CLK_SOURCE_NOR 0x1d0 | ||
144 | #define CLK_SOURCE_MIPI 0x174 | ||
145 | #define CLK_SOURCE_I2C1 0x124 | ||
146 | #define CLK_SOURCE_I2C2 0x198 | ||
147 | #define CLK_SOURCE_I2C3 0x1b8 | ||
148 | #define CLK_SOURCE_DVC 0x128 | ||
149 | #define CLK_SOURCE_UARTA 0x178 | ||
150 | #define CLK_SOURCE_UARTB 0x17c | ||
151 | #define CLK_SOURCE_UARTC 0x1a0 | ||
152 | #define CLK_SOURCE_UARTD 0x1c0 | ||
153 | #define CLK_SOURCE_UARTE 0x1c4 | ||
154 | #define CLK_SOURCE_3D 0x158 | ||
155 | #define CLK_SOURCE_2D 0x15c | ||
156 | #define CLK_SOURCE_MPE 0x170 | ||
157 | #define CLK_SOURCE_EPP 0x16c | ||
158 | #define CLK_SOURCE_HOST1X 0x180 | ||
159 | #define CLK_SOURCE_VDE 0x1c8 | ||
160 | #define CLK_SOURCE_VI 0x148 | ||
161 | #define CLK_SOURCE_VI_SENSOR 0x1a8 | ||
162 | #define CLK_SOURCE_EMC 0x19c | ||
163 | |||
164 | #define AUDIO_SYNC_CLK 0x38 | ||
165 | |||
166 | #define PMC_CTRL 0x0 | ||
167 | #define PMC_CTRL_BLINK_ENB 7 | ||
168 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
169 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 | ||
170 | #define PMC_BLINK_TIMER 0x40 | ||
171 | |||
172 | /* Tegra CPU clock and reset control regs */ | ||
173 | #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c | ||
174 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 | ||
175 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344 | ||
176 | |||
177 | #define CPU_CLOCK(cpu) (0x1 << (8 + cpu)) | ||
178 | #define CPU_RESET(cpu) (0x1111ul << (cpu)) | ||
179 | |||
180 | #ifdef CONFIG_PM_SLEEP | ||
181 | static struct cpu_clk_suspend_context { | ||
182 | u32 pllx_misc; | ||
183 | u32 pllx_base; | ||
184 | |||
185 | u32 cpu_burst; | ||
186 | u32 clk_csite_src; | ||
187 | u32 cclk_divider; | ||
188 | } tegra20_cpu_clk_sctx; | ||
189 | #endif | ||
190 | |||
191 | static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; | ||
192 | |||
193 | static void __iomem *clk_base; | ||
194 | static void __iomem *pmc_base; | ||
195 | |||
196 | static DEFINE_SPINLOCK(pll_div_lock); | ||
197 | |||
198 | #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ | ||
199 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
200 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
201 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ | ||
202 | _regs, _clk_num, periph_clk_enb_refcnt, \ | ||
203 | _gate_flags, _clk_id) | ||
204 | |||
205 | #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ | ||
206 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
207 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
208 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ | ||
209 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
210 | _clk_id) | ||
211 | |||
212 | #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ | ||
213 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
214 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
215 | 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, _regs, \ | ||
216 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
217 | _clk_id) | ||
218 | |||
219 | #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ | ||
220 | _mux_shift, _mux_width, _clk_num, _regs, \ | ||
221 | _gate_flags, _clk_id) \ | ||
222 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
223 | _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ | ||
224 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
225 | _clk_id) | ||
226 | |||
227 | /* IDs assigned here must be in sync with DT bindings definition | ||
228 | * for Tegra20 clocks . | ||
229 | */ | ||
230 | enum tegra20_clk { | ||
231 | cpu, ac97 = 3, rtc, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, | ||
232 | ndflash, sdmmc1, sdmmc4, twc, pwm, i2s2, epp, gr2d = 21, usbd, isp, | ||
233 | gr3d, ide, disp2, disp1, host1x, vcp, cache2 = 31, mem, ahbdma, apbdma, | ||
234 | kbc = 36, stat_mon, pmc, fuse, kfuse, sbc1, nor, spi, sbc2, xio, sbc3, | ||
235 | dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, | ||
236 | usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, | ||
237 | pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb, | ||
238 | iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev1, cdev2, | ||
239 | uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve, | ||
240 | osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0, | ||
241 | pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1, | ||
242 | pll_p, pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_u, | ||
243 | pll_x, audio, pll_ref, twd, clk_max, | ||
244 | }; | ||
245 | |||
246 | static struct clk *clks[clk_max]; | ||
247 | static struct clk_onecell_data clk_data; | ||
248 | |||
249 | static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { | ||
250 | { 12000000, 600000000, 600, 12, 1, 8 }, | ||
251 | { 13000000, 600000000, 600, 13, 1, 8 }, | ||
252 | { 19200000, 600000000, 500, 16, 1, 6 }, | ||
253 | { 26000000, 600000000, 600, 26, 1, 8 }, | ||
254 | { 0, 0, 0, 0, 0, 0 }, | ||
255 | }; | ||
256 | |||
257 | static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { | ||
258 | { 12000000, 666000000, 666, 12, 1, 8}, | ||
259 | { 13000000, 666000000, 666, 13, 1, 8}, | ||
260 | { 19200000, 666000000, 555, 16, 1, 8}, | ||
261 | { 26000000, 666000000, 666, 26, 1, 8}, | ||
262 | { 12000000, 600000000, 600, 12, 1, 8}, | ||
263 | { 13000000, 600000000, 600, 13, 1, 8}, | ||
264 | { 19200000, 600000000, 375, 12, 1, 6}, | ||
265 | { 26000000, 600000000, 600, 26, 1, 8}, | ||
266 | { 0, 0, 0, 0, 0, 0 }, | ||
267 | }; | ||
268 | |||
269 | static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { | ||
270 | { 12000000, 216000000, 432, 12, 2, 8}, | ||
271 | { 13000000, 216000000, 432, 13, 2, 8}, | ||
272 | { 19200000, 216000000, 90, 4, 2, 1}, | ||
273 | { 26000000, 216000000, 432, 26, 2, 8}, | ||
274 | { 12000000, 432000000, 432, 12, 1, 8}, | ||
275 | { 13000000, 432000000, 432, 13, 1, 8}, | ||
276 | { 19200000, 432000000, 90, 4, 1, 1}, | ||
277 | { 26000000, 432000000, 432, 26, 1, 8}, | ||
278 | { 0, 0, 0, 0, 0, 0 }, | ||
279 | }; | ||
280 | |||
281 | static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { | ||
282 | { 28800000, 56448000, 49, 25, 1, 1}, | ||
283 | { 28800000, 73728000, 64, 25, 1, 1}, | ||
284 | { 28800000, 24000000, 5, 6, 1, 1}, | ||
285 | { 0, 0, 0, 0, 0, 0 }, | ||
286 | }; | ||
287 | |||
288 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { | ||
289 | { 12000000, 216000000, 216, 12, 1, 4}, | ||
290 | { 13000000, 216000000, 216, 13, 1, 4}, | ||
291 | { 19200000, 216000000, 135, 12, 1, 3}, | ||
292 | { 26000000, 216000000, 216, 26, 1, 4}, | ||
293 | |||
294 | { 12000000, 594000000, 594, 12, 1, 8}, | ||
295 | { 13000000, 594000000, 594, 13, 1, 8}, | ||
296 | { 19200000, 594000000, 495, 16, 1, 8}, | ||
297 | { 26000000, 594000000, 594, 26, 1, 8}, | ||
298 | |||
299 | { 12000000, 1000000000, 1000, 12, 1, 12}, | ||
300 | { 13000000, 1000000000, 1000, 13, 1, 12}, | ||
301 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
302 | { 26000000, 1000000000, 1000, 26, 1, 12}, | ||
303 | |||
304 | { 0, 0, 0, 0, 0, 0 }, | ||
305 | }; | ||
306 | |||
307 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { | ||
308 | { 12000000, 480000000, 960, 12, 2, 0}, | ||
309 | { 13000000, 480000000, 960, 13, 2, 0}, | ||
310 | { 19200000, 480000000, 200, 4, 2, 0}, | ||
311 | { 26000000, 480000000, 960, 26, 2, 0}, | ||
312 | { 0, 0, 0, 0, 0, 0 }, | ||
313 | }; | ||
314 | |||
315 | static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { | ||
316 | /* 1 GHz */ | ||
317 | { 12000000, 1000000000, 1000, 12, 1, 12}, | ||
318 | { 13000000, 1000000000, 1000, 13, 1, 12}, | ||
319 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
320 | { 26000000, 1000000000, 1000, 26, 1, 12}, | ||
321 | |||
322 | /* 912 MHz */ | ||
323 | { 12000000, 912000000, 912, 12, 1, 12}, | ||
324 | { 13000000, 912000000, 912, 13, 1, 12}, | ||
325 | { 19200000, 912000000, 760, 16, 1, 8}, | ||
326 | { 26000000, 912000000, 912, 26, 1, 12}, | ||
327 | |||
328 | /* 816 MHz */ | ||
329 | { 12000000, 816000000, 816, 12, 1, 12}, | ||
330 | { 13000000, 816000000, 816, 13, 1, 12}, | ||
331 | { 19200000, 816000000, 680, 16, 1, 8}, | ||
332 | { 26000000, 816000000, 816, 26, 1, 12}, | ||
333 | |||
334 | /* 760 MHz */ | ||
335 | { 12000000, 760000000, 760, 12, 1, 12}, | ||
336 | { 13000000, 760000000, 760, 13, 1, 12}, | ||
337 | { 19200000, 760000000, 950, 24, 1, 8}, | ||
338 | { 26000000, 760000000, 760, 26, 1, 12}, | ||
339 | |||
340 | /* 750 MHz */ | ||
341 | { 12000000, 750000000, 750, 12, 1, 12}, | ||
342 | { 13000000, 750000000, 750, 13, 1, 12}, | ||
343 | { 19200000, 750000000, 625, 16, 1, 8}, | ||
344 | { 26000000, 750000000, 750, 26, 1, 12}, | ||
345 | |||
346 | /* 608 MHz */ | ||
347 | { 12000000, 608000000, 608, 12, 1, 12}, | ||
348 | { 13000000, 608000000, 608, 13, 1, 12}, | ||
349 | { 19200000, 608000000, 380, 12, 1, 8}, | ||
350 | { 26000000, 608000000, 608, 26, 1, 12}, | ||
351 | |||
352 | /* 456 MHz */ | ||
353 | { 12000000, 456000000, 456, 12, 1, 12}, | ||
354 | { 13000000, 456000000, 456, 13, 1, 12}, | ||
355 | { 19200000, 456000000, 380, 16, 1, 8}, | ||
356 | { 26000000, 456000000, 456, 26, 1, 12}, | ||
357 | |||
358 | /* 312 MHz */ | ||
359 | { 12000000, 312000000, 312, 12, 1, 12}, | ||
360 | { 13000000, 312000000, 312, 13, 1, 12}, | ||
361 | { 19200000, 312000000, 260, 16, 1, 8}, | ||
362 | { 26000000, 312000000, 312, 26, 1, 12}, | ||
363 | |||
364 | { 0, 0, 0, 0, 0, 0 }, | ||
365 | }; | ||
366 | |||
367 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { | ||
368 | { 12000000, 100000000, 200, 24, 1, 0 }, | ||
369 | { 0, 0, 0, 0, 0, 0 }, | ||
370 | }; | ||
371 | |||
372 | /* PLL parameters */ | ||
373 | static struct tegra_clk_pll_params pll_c_params = { | ||
374 | .input_min = 2000000, | ||
375 | .input_max = 31000000, | ||
376 | .cf_min = 1000000, | ||
377 | .cf_max = 6000000, | ||
378 | .vco_min = 20000000, | ||
379 | .vco_max = 1400000000, | ||
380 | .base_reg = PLLC_BASE, | ||
381 | .misc_reg = PLLC_MISC, | ||
382 | .lock_bit_idx = PLL_BASE_LOCK, | ||
383 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
384 | .lock_delay = 300, | ||
385 | }; | ||
386 | |||
387 | static struct tegra_clk_pll_params pll_m_params = { | ||
388 | .input_min = 2000000, | ||
389 | .input_max = 31000000, | ||
390 | .cf_min = 1000000, | ||
391 | .cf_max = 6000000, | ||
392 | .vco_min = 20000000, | ||
393 | .vco_max = 1200000000, | ||
394 | .base_reg = PLLM_BASE, | ||
395 | .misc_reg = PLLM_MISC, | ||
396 | .lock_bit_idx = PLL_BASE_LOCK, | ||
397 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
398 | .lock_delay = 300, | ||
399 | }; | ||
400 | |||
401 | static struct tegra_clk_pll_params pll_p_params = { | ||
402 | .input_min = 2000000, | ||
403 | .input_max = 31000000, | ||
404 | .cf_min = 1000000, | ||
405 | .cf_max = 6000000, | ||
406 | .vco_min = 20000000, | ||
407 | .vco_max = 1400000000, | ||
408 | .base_reg = PLLP_BASE, | ||
409 | .misc_reg = PLLP_MISC, | ||
410 | .lock_bit_idx = PLL_BASE_LOCK, | ||
411 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
412 | .lock_delay = 300, | ||
413 | }; | ||
414 | |||
415 | static struct tegra_clk_pll_params pll_a_params = { | ||
416 | .input_min = 2000000, | ||
417 | .input_max = 31000000, | ||
418 | .cf_min = 1000000, | ||
419 | .cf_max = 6000000, | ||
420 | .vco_min = 20000000, | ||
421 | .vco_max = 1400000000, | ||
422 | .base_reg = PLLA_BASE, | ||
423 | .misc_reg = PLLA_MISC, | ||
424 | .lock_bit_idx = PLL_BASE_LOCK, | ||
425 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
426 | .lock_delay = 300, | ||
427 | }; | ||
428 | |||
429 | static struct tegra_clk_pll_params pll_d_params = { | ||
430 | .input_min = 2000000, | ||
431 | .input_max = 40000000, | ||
432 | .cf_min = 1000000, | ||
433 | .cf_max = 6000000, | ||
434 | .vco_min = 40000000, | ||
435 | .vco_max = 1000000000, | ||
436 | .base_reg = PLLD_BASE, | ||
437 | .misc_reg = PLLD_MISC, | ||
438 | .lock_bit_idx = PLL_BASE_LOCK, | ||
439 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | ||
440 | .lock_delay = 1000, | ||
441 | }; | ||
442 | |||
443 | static struct tegra_clk_pll_params pll_u_params = { | ||
444 | .input_min = 2000000, | ||
445 | .input_max = 40000000, | ||
446 | .cf_min = 1000000, | ||
447 | .cf_max = 6000000, | ||
448 | .vco_min = 48000000, | ||
449 | .vco_max = 960000000, | ||
450 | .base_reg = PLLU_BASE, | ||
451 | .misc_reg = PLLU_MISC, | ||
452 | .lock_bit_idx = PLL_BASE_LOCK, | ||
453 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | ||
454 | .lock_delay = 1000, | ||
455 | }; | ||
456 | |||
457 | static struct tegra_clk_pll_params pll_x_params = { | ||
458 | .input_min = 2000000, | ||
459 | .input_max = 31000000, | ||
460 | .cf_min = 1000000, | ||
461 | .cf_max = 6000000, | ||
462 | .vco_min = 20000000, | ||
463 | .vco_max = 1200000000, | ||
464 | .base_reg = PLLX_BASE, | ||
465 | .misc_reg = PLLX_MISC, | ||
466 | .lock_bit_idx = PLL_BASE_LOCK, | ||
467 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
468 | .lock_delay = 300, | ||
469 | }; | ||
470 | |||
471 | static struct tegra_clk_pll_params pll_e_params = { | ||
472 | .input_min = 12000000, | ||
473 | .input_max = 12000000, | ||
474 | .cf_min = 0, | ||
475 | .cf_max = 0, | ||
476 | .vco_min = 0, | ||
477 | .vco_max = 0, | ||
478 | .base_reg = PLLE_BASE, | ||
479 | .misc_reg = PLLE_MISC, | ||
480 | .lock_bit_idx = PLLE_MISC_LOCK, | ||
481 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, | ||
482 | .lock_delay = 0, | ||
483 | }; | ||
484 | |||
485 | /* Peripheral clock registers */ | ||
486 | static struct tegra_clk_periph_regs periph_l_regs = { | ||
487 | .enb_reg = CLK_OUT_ENB_L, | ||
488 | .enb_set_reg = CLK_OUT_ENB_SET_L, | ||
489 | .enb_clr_reg = CLK_OUT_ENB_CLR_L, | ||
490 | .rst_reg = RST_DEVICES_L, | ||
491 | .rst_set_reg = RST_DEVICES_SET_L, | ||
492 | .rst_clr_reg = RST_DEVICES_CLR_L, | ||
493 | }; | ||
494 | |||
495 | static struct tegra_clk_periph_regs periph_h_regs = { | ||
496 | .enb_reg = CLK_OUT_ENB_H, | ||
497 | .enb_set_reg = CLK_OUT_ENB_SET_H, | ||
498 | .enb_clr_reg = CLK_OUT_ENB_CLR_H, | ||
499 | .rst_reg = RST_DEVICES_H, | ||
500 | .rst_set_reg = RST_DEVICES_SET_H, | ||
501 | .rst_clr_reg = RST_DEVICES_CLR_H, | ||
502 | }; | ||
503 | |||
504 | static struct tegra_clk_periph_regs periph_u_regs = { | ||
505 | .enb_reg = CLK_OUT_ENB_U, | ||
506 | .enb_set_reg = CLK_OUT_ENB_SET_U, | ||
507 | .enb_clr_reg = CLK_OUT_ENB_CLR_U, | ||
508 | .rst_reg = RST_DEVICES_U, | ||
509 | .rst_set_reg = RST_DEVICES_SET_U, | ||
510 | .rst_clr_reg = RST_DEVICES_CLR_U, | ||
511 | }; | ||
512 | |||
513 | static unsigned long tegra20_clk_measure_input_freq(void) | ||
514 | { | ||
515 | u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); | ||
516 | u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK; | ||
517 | u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; | ||
518 | unsigned long input_freq; | ||
519 | |||
520 | switch (auto_clk_control) { | ||
521 | case OSC_CTRL_OSC_FREQ_12MHZ: | ||
522 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
523 | input_freq = 12000000; | ||
524 | break; | ||
525 | case OSC_CTRL_OSC_FREQ_13MHZ: | ||
526 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
527 | input_freq = 13000000; | ||
528 | break; | ||
529 | case OSC_CTRL_OSC_FREQ_19_2MHZ: | ||
530 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
531 | input_freq = 19200000; | ||
532 | break; | ||
533 | case OSC_CTRL_OSC_FREQ_26MHZ: | ||
534 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
535 | input_freq = 26000000; | ||
536 | break; | ||
537 | default: | ||
538 | pr_err("Unexpected clock autodetect value %d", | ||
539 | auto_clk_control); | ||
540 | BUG(); | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | return input_freq; | ||
545 | } | ||
546 | |||
547 | static unsigned int tegra20_get_pll_ref_div(void) | ||
548 | { | ||
549 | u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) & | ||
550 | OSC_CTRL_PLL_REF_DIV_MASK; | ||
551 | |||
552 | switch (pll_ref_div) { | ||
553 | case OSC_CTRL_PLL_REF_DIV_1: | ||
554 | return 1; | ||
555 | case OSC_CTRL_PLL_REF_DIV_2: | ||
556 | return 2; | ||
557 | case OSC_CTRL_PLL_REF_DIV_4: | ||
558 | return 4; | ||
559 | default: | ||
560 | pr_err("Invalied pll ref divider %d\n", pll_ref_div); | ||
561 | BUG(); | ||
562 | } | ||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static void tegra20_pll_init(void) | ||
567 | { | ||
568 | struct clk *clk; | ||
569 | |||
570 | /* PLLC */ | ||
571 | clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0, | ||
572 | 0, &pll_c_params, TEGRA_PLL_HAS_CPCON, | ||
573 | pll_c_freq_table, NULL); | ||
574 | clk_register_clkdev(clk, "pll_c", NULL); | ||
575 | clks[pll_c] = clk; | ||
576 | |||
577 | /* PLLC_OUT1 */ | ||
578 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", | ||
579 | clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
580 | 8, 8, 1, NULL); | ||
581 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", | ||
582 | clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, | ||
583 | 0, NULL); | ||
584 | clk_register_clkdev(clk, "pll_c_out1", NULL); | ||
585 | clks[pll_c_out1] = clk; | ||
586 | |||
587 | /* PLLP */ | ||
588 | clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, NULL, 0, | ||
589 | 216000000, &pll_p_params, TEGRA_PLL_FIXED | | ||
590 | TEGRA_PLL_HAS_CPCON, pll_p_freq_table, NULL); | ||
591 | clk_register_clkdev(clk, "pll_p", NULL); | ||
592 | clks[pll_p] = clk; | ||
593 | |||
594 | /* PLLP_OUT1 */ | ||
595 | clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", | ||
596 | clk_base + PLLP_OUTA, 0, | ||
597 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
598 | 8, 8, 1, &pll_div_lock); | ||
599 | clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", | ||
600 | clk_base + PLLP_OUTA, 1, 0, | ||
601 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
602 | &pll_div_lock); | ||
603 | clk_register_clkdev(clk, "pll_p_out1", NULL); | ||
604 | clks[pll_p_out1] = clk; | ||
605 | |||
606 | /* PLLP_OUT2 */ | ||
607 | clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", | ||
608 | clk_base + PLLP_OUTA, 0, | ||
609 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
610 | 24, 8, 1, &pll_div_lock); | ||
611 | clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", | ||
612 | clk_base + PLLP_OUTA, 17, 16, | ||
613 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
614 | &pll_div_lock); | ||
615 | clk_register_clkdev(clk, "pll_p_out2", NULL); | ||
616 | clks[pll_p_out2] = clk; | ||
617 | |||
618 | /* PLLP_OUT3 */ | ||
619 | clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", | ||
620 | clk_base + PLLP_OUTB, 0, | ||
621 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
622 | 8, 8, 1, &pll_div_lock); | ||
623 | clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", | ||
624 | clk_base + PLLP_OUTB, 1, 0, | ||
625 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
626 | &pll_div_lock); | ||
627 | clk_register_clkdev(clk, "pll_p_out3", NULL); | ||
628 | clks[pll_p_out3] = clk; | ||
629 | |||
630 | /* PLLP_OUT4 */ | ||
631 | clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", | ||
632 | clk_base + PLLP_OUTB, 0, | ||
633 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
634 | 24, 8, 1, &pll_div_lock); | ||
635 | clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", | ||
636 | clk_base + PLLP_OUTB, 17, 16, | ||
637 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
638 | &pll_div_lock); | ||
639 | clk_register_clkdev(clk, "pll_p_out4", NULL); | ||
640 | clks[pll_p_out4] = clk; | ||
641 | |||
642 | /* PLLM */ | ||
643 | clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, | ||
644 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, | ||
645 | &pll_m_params, TEGRA_PLL_HAS_CPCON, | ||
646 | pll_m_freq_table, NULL); | ||
647 | clk_register_clkdev(clk, "pll_m", NULL); | ||
648 | clks[pll_m] = clk; | ||
649 | |||
650 | /* PLLM_OUT1 */ | ||
651 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", | ||
652 | clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
653 | 8, 8, 1, NULL); | ||
654 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", | ||
655 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
656 | CLK_SET_RATE_PARENT, 0, NULL); | ||
657 | clk_register_clkdev(clk, "pll_m_out1", NULL); | ||
658 | clks[pll_m_out1] = clk; | ||
659 | |||
660 | /* PLLX */ | ||
661 | clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0, | ||
662 | 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, | ||
663 | pll_x_freq_table, NULL); | ||
664 | clk_register_clkdev(clk, "pll_x", NULL); | ||
665 | clks[pll_x] = clk; | ||
666 | |||
667 | /* PLLU */ | ||
668 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0, | ||
669 | 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, | ||
670 | pll_u_freq_table, NULL); | ||
671 | clk_register_clkdev(clk, "pll_u", NULL); | ||
672 | clks[pll_u] = clk; | ||
673 | |||
674 | /* PLLD */ | ||
675 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0, | ||
676 | 0, &pll_d_params, TEGRA_PLL_HAS_CPCON, | ||
677 | pll_d_freq_table, NULL); | ||
678 | clk_register_clkdev(clk, "pll_d", NULL); | ||
679 | clks[pll_d] = clk; | ||
680 | |||
681 | /* PLLD_OUT0 */ | ||
682 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", | ||
683 | CLK_SET_RATE_PARENT, 1, 2); | ||
684 | clk_register_clkdev(clk, "pll_d_out0", NULL); | ||
685 | clks[pll_d_out0] = clk; | ||
686 | |||
687 | /* PLLA */ | ||
688 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0, | ||
689 | 0, &pll_a_params, TEGRA_PLL_HAS_CPCON, | ||
690 | pll_a_freq_table, NULL); | ||
691 | clk_register_clkdev(clk, "pll_a", NULL); | ||
692 | clks[pll_a] = clk; | ||
693 | |||
694 | /* PLLA_OUT0 */ | ||
695 | clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", | ||
696 | clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
697 | 8, 8, 1, NULL); | ||
698 | clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", | ||
699 | clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
700 | CLK_SET_RATE_PARENT, 0, NULL); | ||
701 | clk_register_clkdev(clk, "pll_a_out0", NULL); | ||
702 | clks[pll_a_out0] = clk; | ||
703 | |||
704 | /* PLLE */ | ||
705 | clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, NULL, | ||
706 | 0, 100000000, &pll_e_params, | ||
707 | 0, pll_e_freq_table, NULL); | ||
708 | clk_register_clkdev(clk, "pll_e", NULL); | ||
709 | clks[pll_e] = clk; | ||
710 | } | ||
711 | |||
712 | static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | ||
713 | "pll_p_cclk", "pll_p_out4_cclk", | ||
714 | "pll_p_out3_cclk", "clk_d", "pll_x" }; | ||
715 | static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", | ||
716 | "pll_p_out3", "pll_p_out2", "clk_d", | ||
717 | "clk_32k", "pll_m_out1" }; | ||
718 | |||
719 | static void tegra20_super_clk_init(void) | ||
720 | { | ||
721 | struct clk *clk; | ||
722 | |||
723 | /* | ||
724 | * DIV_U71 dividers for CCLK, these dividers are used only | ||
725 | * if parent clock is fixed rate. | ||
726 | */ | ||
727 | |||
728 | /* | ||
729 | * Clock input to cclk divided from pll_p using | ||
730 | * U71 divider of cclk. | ||
731 | */ | ||
732 | clk = tegra_clk_register_divider("pll_p_cclk", "pll_p", | ||
733 | clk_base + SUPER_CCLK_DIVIDER, 0, | ||
734 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
735 | clk_register_clkdev(clk, "pll_p_cclk", NULL); | ||
736 | |||
737 | /* | ||
738 | * Clock input to cclk divided from pll_p_out3 using | ||
739 | * U71 divider of cclk. | ||
740 | */ | ||
741 | clk = tegra_clk_register_divider("pll_p_out3_cclk", "pll_p_out3", | ||
742 | clk_base + SUPER_CCLK_DIVIDER, 0, | ||
743 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
744 | clk_register_clkdev(clk, "pll_p_out3_cclk", NULL); | ||
745 | |||
746 | /* | ||
747 | * Clock input to cclk divided from pll_p_out4 using | ||
748 | * U71 divider of cclk. | ||
749 | */ | ||
750 | clk = tegra_clk_register_divider("pll_p_out4_cclk", "pll_p_out4", | ||
751 | clk_base + SUPER_CCLK_DIVIDER, 0, | ||
752 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
753 | clk_register_clkdev(clk, "pll_p_out4_cclk", NULL); | ||
754 | |||
755 | /* CCLK */ | ||
756 | clk = tegra_clk_register_super_mux("cclk", cclk_parents, | ||
757 | ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT, | ||
758 | clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL); | ||
759 | clk_register_clkdev(clk, "cclk", NULL); | ||
760 | clks[cclk] = clk; | ||
761 | |||
762 | /* SCLK */ | ||
763 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, | ||
764 | ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, | ||
765 | clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); | ||
766 | clk_register_clkdev(clk, "sclk", NULL); | ||
767 | clks[sclk] = clk; | ||
768 | |||
769 | /* HCLK */ | ||
770 | clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, | ||
771 | clk_base + CLK_SYSTEM_RATE, 4, 2, 0, NULL); | ||
772 | clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, | ||
773 | clk_base + CLK_SYSTEM_RATE, 7, | ||
774 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
775 | clk_register_clkdev(clk, "hclk", NULL); | ||
776 | clks[hclk] = clk; | ||
777 | |||
778 | /* PCLK */ | ||
779 | clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, | ||
780 | clk_base + CLK_SYSTEM_RATE, 0, 2, 0, NULL); | ||
781 | clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, | ||
782 | clk_base + CLK_SYSTEM_RATE, 3, | ||
783 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
784 | clk_register_clkdev(clk, "pclk", NULL); | ||
785 | clks[pclk] = clk; | ||
786 | |||
787 | /* twd */ | ||
788 | clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4); | ||
789 | clk_register_clkdev(clk, "twd", NULL); | ||
790 | clks[twd] = clk; | ||
791 | } | ||
792 | |||
793 | static const char *audio_parents[] = {"spdif_in", "i2s1", "i2s2", "unused", | ||
794 | "pll_a_out0", "unused", "unused", | ||
795 | "unused"}; | ||
796 | |||
797 | static void __init tegra20_audio_clk_init(void) | ||
798 | { | ||
799 | struct clk *clk; | ||
800 | |||
801 | /* audio */ | ||
802 | clk = clk_register_mux(NULL, "audio_mux", audio_parents, | ||
803 | ARRAY_SIZE(audio_parents), 0, | ||
804 | clk_base + AUDIO_SYNC_CLK, 0, 3, 0, NULL); | ||
805 | clk = clk_register_gate(NULL, "audio", "audio_mux", 0, | ||
806 | clk_base + AUDIO_SYNC_CLK, 4, | ||
807 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
808 | clk_register_clkdev(clk, "audio", NULL); | ||
809 | clks[audio] = clk; | ||
810 | |||
811 | /* audio_2x */ | ||
812 | clk = clk_register_fixed_factor(NULL, "audio_doubler", "audio", | ||
813 | CLK_SET_RATE_PARENT, 2, 1); | ||
814 | clk = tegra_clk_register_periph_gate("audio_2x", "audio_doubler", | ||
815 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
816 | CLK_SET_RATE_PARENT, 89, &periph_u_regs, | ||
817 | periph_clk_enb_refcnt); | ||
818 | clk_register_clkdev(clk, "audio_2x", NULL); | ||
819 | clks[audio_2x] = clk; | ||
820 | |||
821 | } | ||
822 | |||
823 | static const char *i2s1_parents[] = {"pll_a_out0", "audio_2x", "pll_p", | ||
824 | "clk_m"}; | ||
825 | static const char *i2s2_parents[] = {"pll_a_out0", "audio_2x", "pll_p", | ||
826 | "clk_m"}; | ||
827 | static const char *spdif_out_parents[] = {"pll_a_out0", "audio_2x", "pll_p", | ||
828 | "clk_m"}; | ||
829 | static const char *spdif_in_parents[] = {"pll_p", "pll_c", "pll_m"}; | ||
830 | static const char *pwm_parents[] = {"pll_p", "pll_c", "audio", "clk_m", | ||
831 | "clk_32k"}; | ||
832 | static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; | ||
833 | static const char *mux_pllmcpa[] = {"pll_m", "pll_c", "pll_c", "pll_a"}; | ||
834 | static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c", | ||
835 | "clk_m"}; | ||
836 | static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"}; | ||
837 | |||
838 | static struct tegra_periph_init_data tegra_periph_clk_list[] = { | ||
839 | TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra20-i2s.0", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), | ||
840 | TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra20-i2s.1", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), | ||
841 | TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra20-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), | ||
842 | TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra20-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), | ||
843 | TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), | ||
844 | TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), | ||
845 | TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), | ||
846 | TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), | ||
847 | TEGRA_INIT_DATA_MUX("spi", NULL, "spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, &periph_h_regs, TEGRA_PERIPH_ON_APB, spi), | ||
848 | TEGRA_INIT_DATA_MUX("xio", NULL, "xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, &periph_h_regs, 0, xio), | ||
849 | TEGRA_INIT_DATA_MUX("twc", NULL, "twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, &periph_l_regs, TEGRA_PERIPH_ON_APB, twc), | ||
850 | TEGRA_INIT_DATA_MUX("ide", NULL, "ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, &periph_l_regs, 0, ide), | ||
851 | TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, 0, ndflash), | ||
852 | TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), | ||
853 | TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, 0, csite), | ||
854 | TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, 0, la), | ||
855 | TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), | ||
856 | TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), | ||
857 | TEGRA_INIT_DATA_MUX("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), | ||
858 | TEGRA_INIT_DATA_MUX("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), | ||
859 | TEGRA_INIT_DATA_MUX("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), | ||
860 | TEGRA_INIT_DATA_MUX("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), | ||
861 | TEGRA_INIT_DATA_MUX("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), | ||
862 | TEGRA_INIT_DATA_MUX("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), | ||
863 | TEGRA_INIT_DATA_MUX("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), | ||
864 | TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), | ||
865 | TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), | ||
866 | TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), | ||
867 | TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), | ||
868 | TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), | ||
869 | TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), | ||
870 | TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), | ||
871 | TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), | ||
872 | TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), | ||
873 | TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), | ||
874 | TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), | ||
875 | TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), | ||
876 | TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, dvc), | ||
877 | TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), | ||
878 | TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm), | ||
879 | }; | ||
880 | |||
881 | static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { | ||
882 | TEGRA_INIT_DATA_NODIV("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, &periph_l_regs, TEGRA_PERIPH_ON_APB, uarta), | ||
883 | TEGRA_INIT_DATA_NODIV("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, uartb), | ||
884 | TEGRA_INIT_DATA_NODIV("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, &periph_h_regs, TEGRA_PERIPH_ON_APB, uartc), | ||
885 | TEGRA_INIT_DATA_NODIV("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, &periph_u_regs, TEGRA_PERIPH_ON_APB, uartd), | ||
886 | TEGRA_INIT_DATA_NODIV("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, &periph_u_regs, TEGRA_PERIPH_ON_APB, uarte), | ||
887 | TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, &periph_l_regs, 0, disp1), | ||
888 | TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, &periph_l_regs, 0, disp2), | ||
889 | }; | ||
890 | |||
891 | static void __init tegra20_periph_clk_init(void) | ||
892 | { | ||
893 | struct tegra_periph_init_data *data; | ||
894 | struct clk *clk; | ||
895 | int i; | ||
896 | |||
897 | /* apbdma */ | ||
898 | clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, | ||
899 | 0, 34, &periph_h_regs, | ||
900 | periph_clk_enb_refcnt); | ||
901 | clk_register_clkdev(clk, NULL, "tegra-apbdma"); | ||
902 | clks[apbdma] = clk; | ||
903 | |||
904 | /* rtc */ | ||
905 | clk = tegra_clk_register_periph_gate("rtc", "clk_32k", | ||
906 | TEGRA_PERIPH_NO_RESET, | ||
907 | clk_base, 0, 4, &periph_l_regs, | ||
908 | periph_clk_enb_refcnt); | ||
909 | clk_register_clkdev(clk, NULL, "rtc-tegra"); | ||
910 | clks[rtc] = clk; | ||
911 | |||
912 | /* timer */ | ||
913 | clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, | ||
914 | 0, 5, &periph_l_regs, | ||
915 | periph_clk_enb_refcnt); | ||
916 | clk_register_clkdev(clk, NULL, "timer"); | ||
917 | clks[timer] = clk; | ||
918 | |||
919 | /* kbc */ | ||
920 | clk = tegra_clk_register_periph_gate("kbc", "clk_32k", | ||
921 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
922 | clk_base, 0, 36, &periph_h_regs, | ||
923 | periph_clk_enb_refcnt); | ||
924 | clk_register_clkdev(clk, NULL, "tegra-kbc"); | ||
925 | clks[kbc] = clk; | ||
926 | |||
927 | /* csus */ | ||
928 | clk = tegra_clk_register_periph_gate("csus", "clk_m", | ||
929 | TEGRA_PERIPH_NO_RESET, | ||
930 | clk_base, 0, 92, &periph_u_regs, | ||
931 | periph_clk_enb_refcnt); | ||
932 | clk_register_clkdev(clk, "csus", "tengra_camera"); | ||
933 | clks[csus] = clk; | ||
934 | |||
935 | /* vcp */ | ||
936 | clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, | ||
937 | clk_base, 0, 29, &periph_l_regs, | ||
938 | periph_clk_enb_refcnt); | ||
939 | clk_register_clkdev(clk, "vcp", "tegra-avp"); | ||
940 | clks[vcp] = clk; | ||
941 | |||
942 | /* bsea */ | ||
943 | clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, | ||
944 | clk_base, 0, 62, &periph_h_regs, | ||
945 | periph_clk_enb_refcnt); | ||
946 | clk_register_clkdev(clk, "bsea", "tegra-avp"); | ||
947 | clks[bsea] = clk; | ||
948 | |||
949 | /* bsev */ | ||
950 | clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, | ||
951 | clk_base, 0, 63, &periph_h_regs, | ||
952 | periph_clk_enb_refcnt); | ||
953 | clk_register_clkdev(clk, "bsev", "tegra-aes"); | ||
954 | clks[bsev] = clk; | ||
955 | |||
956 | /* emc */ | ||
957 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, | ||
958 | ARRAY_SIZE(mux_pllmcp_clkm), 0, | ||
959 | clk_base + CLK_SOURCE_EMC, | ||
960 | 30, 2, 0, NULL); | ||
961 | clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, | ||
962 | 57, &periph_h_regs, periph_clk_enb_refcnt); | ||
963 | clk_register_clkdev(clk, "emc", NULL); | ||
964 | clks[emc] = clk; | ||
965 | |||
966 | /* usbd */ | ||
967 | clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, | ||
968 | 22, &periph_l_regs, periph_clk_enb_refcnt); | ||
969 | clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); | ||
970 | clks[usbd] = clk; | ||
971 | |||
972 | /* usb2 */ | ||
973 | clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, | ||
974 | 58, &periph_h_regs, periph_clk_enb_refcnt); | ||
975 | clk_register_clkdev(clk, NULL, "tegra-ehci.1"); | ||
976 | clks[usb2] = clk; | ||
977 | |||
978 | /* usb3 */ | ||
979 | clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, | ||
980 | 59, &periph_h_regs, periph_clk_enb_refcnt); | ||
981 | clk_register_clkdev(clk, NULL, "tegra-ehci.2"); | ||
982 | clks[usb3] = clk; | ||
983 | |||
984 | /* dsi */ | ||
985 | clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, | ||
986 | 48, &periph_h_regs, periph_clk_enb_refcnt); | ||
987 | clk_register_clkdev(clk, NULL, "dsi"); | ||
988 | clks[dsi] = clk; | ||
989 | |||
990 | /* csi */ | ||
991 | clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, | ||
992 | 0, 52, &periph_h_regs, | ||
993 | periph_clk_enb_refcnt); | ||
994 | clk_register_clkdev(clk, "csi", "tegra_camera"); | ||
995 | clks[csi] = clk; | ||
996 | |||
997 | /* isp */ | ||
998 | clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, | ||
999 | &periph_l_regs, periph_clk_enb_refcnt); | ||
1000 | clk_register_clkdev(clk, "isp", "tegra_camera"); | ||
1001 | clks[isp] = clk; | ||
1002 | |||
1003 | /* pex */ | ||
1004 | clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70, | ||
1005 | &periph_u_regs, periph_clk_enb_refcnt); | ||
1006 | clk_register_clkdev(clk, "pex", NULL); | ||
1007 | clks[pex] = clk; | ||
1008 | |||
1009 | /* afi */ | ||
1010 | clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, | ||
1011 | &periph_u_regs, periph_clk_enb_refcnt); | ||
1012 | clk_register_clkdev(clk, "afi", NULL); | ||
1013 | clks[afi] = clk; | ||
1014 | |||
1015 | /* pcie_xclk */ | ||
1016 | clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base, | ||
1017 | 0, 74, &periph_u_regs, | ||
1018 | periph_clk_enb_refcnt); | ||
1019 | clk_register_clkdev(clk, "pcie_xclk", NULL); | ||
1020 | clks[pcie_xclk] = clk; | ||
1021 | |||
1022 | /* cdev1 */ | ||
1023 | clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, | ||
1024 | 26000000); | ||
1025 | clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, | ||
1026 | clk_base, 0, 94, &periph_u_regs, | ||
1027 | periph_clk_enb_refcnt); | ||
1028 | clk_register_clkdev(clk, "cdev1", NULL); | ||
1029 | clks[cdev1] = clk; | ||
1030 | |||
1031 | /* cdev2 */ | ||
1032 | clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, | ||
1033 | 26000000); | ||
1034 | clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, | ||
1035 | clk_base, 0, 93, &periph_u_regs, | ||
1036 | periph_clk_enb_refcnt); | ||
1037 | clk_register_clkdev(clk, "cdev2", NULL); | ||
1038 | clks[cdev2] = clk; | ||
1039 | |||
1040 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { | ||
1041 | data = &tegra_periph_clk_list[i]; | ||
1042 | clk = tegra_clk_register_periph(data->name, data->parent_names, | ||
1043 | data->num_parents, &data->periph, | ||
1044 | clk_base, data->offset); | ||
1045 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1046 | clks[data->clk_id] = clk; | ||
1047 | } | ||
1048 | |||
1049 | for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { | ||
1050 | data = &tegra_periph_nodiv_clk_list[i]; | ||
1051 | clk = tegra_clk_register_periph_nodiv(data->name, | ||
1052 | data->parent_names, | ||
1053 | data->num_parents, &data->periph, | ||
1054 | clk_base, data->offset); | ||
1055 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1056 | clks[data->clk_id] = clk; | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | |||
1061 | static void __init tegra20_fixed_clk_init(void) | ||
1062 | { | ||
1063 | struct clk *clk; | ||
1064 | |||
1065 | /* clk_32k */ | ||
1066 | clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, | ||
1067 | 32768); | ||
1068 | clk_register_clkdev(clk, "clk_32k", NULL); | ||
1069 | clks[clk_32k] = clk; | ||
1070 | } | ||
1071 | |||
1072 | static void __init tegra20_pmc_clk_init(void) | ||
1073 | { | ||
1074 | struct clk *clk; | ||
1075 | |||
1076 | /* blink */ | ||
1077 | writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); | ||
1078 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, | ||
1079 | pmc_base + PMC_DPD_PADS_ORIDE, | ||
1080 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); | ||
1081 | clk = clk_register_gate(NULL, "blink", "blink_override", 0, | ||
1082 | pmc_base + PMC_CTRL, | ||
1083 | PMC_CTRL_BLINK_ENB, 0, NULL); | ||
1084 | clk_register_clkdev(clk, "blink", NULL); | ||
1085 | clks[blink] = clk; | ||
1086 | } | ||
1087 | |||
1088 | static void __init tegra20_osc_clk_init(void) | ||
1089 | { | ||
1090 | struct clk *clk; | ||
1091 | unsigned long input_freq; | ||
1092 | unsigned int pll_ref_div; | ||
1093 | |||
1094 | input_freq = tegra20_clk_measure_input_freq(); | ||
1095 | |||
1096 | /* clk_m */ | ||
1097 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT | | ||
1098 | CLK_IGNORE_UNUSED, input_freq); | ||
1099 | clk_register_clkdev(clk, "clk_m", NULL); | ||
1100 | clks[clk_m] = clk; | ||
1101 | |||
1102 | /* pll_ref */ | ||
1103 | pll_ref_div = tegra20_get_pll_ref_div(); | ||
1104 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", | ||
1105 | CLK_SET_RATE_PARENT, 1, pll_ref_div); | ||
1106 | clk_register_clkdev(clk, "pll_ref", NULL); | ||
1107 | clks[pll_ref] = clk; | ||
1108 | } | ||
1109 | |||
1110 | /* Tegra20 CPU clock and reset control functions */ | ||
1111 | static void tegra20_wait_cpu_in_reset(u32 cpu) | ||
1112 | { | ||
1113 | unsigned int reg; | ||
1114 | |||
1115 | do { | ||
1116 | reg = readl(clk_base + | ||
1117 | TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
1118 | cpu_relax(); | ||
1119 | } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ | ||
1120 | |||
1121 | return; | ||
1122 | } | ||
1123 | |||
1124 | static void tegra20_put_cpu_in_reset(u32 cpu) | ||
1125 | { | ||
1126 | writel(CPU_RESET(cpu), | ||
1127 | clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
1128 | dmb(); | ||
1129 | } | ||
1130 | |||
1131 | static void tegra20_cpu_out_of_reset(u32 cpu) | ||
1132 | { | ||
1133 | writel(CPU_RESET(cpu), | ||
1134 | clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); | ||
1135 | wmb(); | ||
1136 | } | ||
1137 | |||
1138 | static void tegra20_enable_cpu_clock(u32 cpu) | ||
1139 | { | ||
1140 | unsigned int reg; | ||
1141 | |||
1142 | reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1143 | writel(reg & ~CPU_CLOCK(cpu), | ||
1144 | clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1145 | barrier(); | ||
1146 | reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1147 | } | ||
1148 | |||
1149 | static void tegra20_disable_cpu_clock(u32 cpu) | ||
1150 | { | ||
1151 | unsigned int reg; | ||
1152 | |||
1153 | reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1154 | writel(reg | CPU_CLOCK(cpu), | ||
1155 | clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1156 | } | ||
1157 | |||
1158 | #ifdef CONFIG_PM_SLEEP | ||
1159 | static bool tegra20_cpu_rail_off_ready(void) | ||
1160 | { | ||
1161 | unsigned int cpu_rst_status; | ||
1162 | |||
1163 | cpu_rst_status = readl(clk_base + | ||
1164 | TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
1165 | |||
1166 | return !!(cpu_rst_status & 0x2); | ||
1167 | } | ||
1168 | |||
1169 | static void tegra20_cpu_clock_suspend(void) | ||
1170 | { | ||
1171 | /* switch coresite to clk_m, save off original source */ | ||
1172 | tegra20_cpu_clk_sctx.clk_csite_src = | ||
1173 | readl(clk_base + CLK_SOURCE_CSITE); | ||
1174 | writel(3<<30, clk_base + CLK_SOURCE_CSITE); | ||
1175 | |||
1176 | tegra20_cpu_clk_sctx.cpu_burst = | ||
1177 | readl(clk_base + CCLK_BURST_POLICY); | ||
1178 | tegra20_cpu_clk_sctx.pllx_base = | ||
1179 | readl(clk_base + PLLX_BASE); | ||
1180 | tegra20_cpu_clk_sctx.pllx_misc = | ||
1181 | readl(clk_base + PLLX_MISC); | ||
1182 | tegra20_cpu_clk_sctx.cclk_divider = | ||
1183 | readl(clk_base + SUPER_CCLK_DIVIDER); | ||
1184 | } | ||
1185 | |||
1186 | static void tegra20_cpu_clock_resume(void) | ||
1187 | { | ||
1188 | unsigned int reg, policy; | ||
1189 | |||
1190 | /* Is CPU complex already running on PLLX? */ | ||
1191 | reg = readl(clk_base + CCLK_BURST_POLICY); | ||
1192 | policy = (reg >> CCLK_BURST_POLICY_SHIFT) & 0xF; | ||
1193 | |||
1194 | if (policy == CCLK_IDLE_POLICY) | ||
1195 | reg = (reg >> CCLK_IDLE_POLICY_SHIFT) & 0xF; | ||
1196 | else if (policy == CCLK_RUN_POLICY) | ||
1197 | reg = (reg >> CCLK_RUN_POLICY_SHIFT) & 0xF; | ||
1198 | else | ||
1199 | BUG(); | ||
1200 | |||
1201 | if (reg != CCLK_BURST_POLICY_PLLX) { | ||
1202 | /* restore PLLX settings if CPU is on different PLL */ | ||
1203 | writel(tegra20_cpu_clk_sctx.pllx_misc, | ||
1204 | clk_base + PLLX_MISC); | ||
1205 | writel(tegra20_cpu_clk_sctx.pllx_base, | ||
1206 | clk_base + PLLX_BASE); | ||
1207 | |||
1208 | /* wait for PLL stabilization if PLLX was enabled */ | ||
1209 | if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30)) | ||
1210 | udelay(300); | ||
1211 | } | ||
1212 | |||
1213 | /* | ||
1214 | * Restore original burst policy setting for calls resulting from CPU | ||
1215 | * LP2 in idle or system suspend. | ||
1216 | */ | ||
1217 | writel(tegra20_cpu_clk_sctx.cclk_divider, | ||
1218 | clk_base + SUPER_CCLK_DIVIDER); | ||
1219 | writel(tegra20_cpu_clk_sctx.cpu_burst, | ||
1220 | clk_base + CCLK_BURST_POLICY); | ||
1221 | |||
1222 | writel(tegra20_cpu_clk_sctx.clk_csite_src, | ||
1223 | clk_base + CLK_SOURCE_CSITE); | ||
1224 | } | ||
1225 | #endif | ||
1226 | |||
1227 | static struct tegra_cpu_car_ops tegra20_cpu_car_ops = { | ||
1228 | .wait_for_reset = tegra20_wait_cpu_in_reset, | ||
1229 | .put_in_reset = tegra20_put_cpu_in_reset, | ||
1230 | .out_of_reset = tegra20_cpu_out_of_reset, | ||
1231 | .enable_clock = tegra20_enable_cpu_clock, | ||
1232 | .disable_clock = tegra20_disable_cpu_clock, | ||
1233 | #ifdef CONFIG_PM_SLEEP | ||
1234 | .rail_off_ready = tegra20_cpu_rail_off_ready, | ||
1235 | .suspend = tegra20_cpu_clock_suspend, | ||
1236 | .resume = tegra20_cpu_clock_resume, | ||
1237 | #endif | ||
1238 | }; | ||
1239 | |||
1240 | static __initdata struct tegra_clk_init_table init_table[] = { | ||
1241 | {pll_p, clk_max, 216000000, 1}, | ||
1242 | {pll_p_out1, clk_max, 28800000, 1}, | ||
1243 | {pll_p_out2, clk_max, 48000000, 1}, | ||
1244 | {pll_p_out3, clk_max, 72000000, 1}, | ||
1245 | {pll_p_out4, clk_max, 24000000, 1}, | ||
1246 | {pll_c, clk_max, 600000000, 1}, | ||
1247 | {pll_c_out1, clk_max, 120000000, 1}, | ||
1248 | {sclk, pll_c_out1, 0, 1}, | ||
1249 | {hclk, clk_max, 0, 1}, | ||
1250 | {pclk, clk_max, 60000000, 1}, | ||
1251 | {csite, clk_max, 0, 1}, | ||
1252 | {emc, clk_max, 0, 1}, | ||
1253 | {cclk, clk_max, 0, 1}, | ||
1254 | {uarta, pll_p, 0, 1}, | ||
1255 | {uartd, pll_p, 0, 1}, | ||
1256 | {usbd, clk_max, 12000000, 0}, | ||
1257 | {usb2, clk_max, 12000000, 0}, | ||
1258 | {usb3, clk_max, 12000000, 0}, | ||
1259 | {pll_a, clk_max, 56448000, 1}, | ||
1260 | {pll_a_out0, clk_max, 11289600, 1}, | ||
1261 | {cdev1, clk_max, 0, 1}, | ||
1262 | {blink, clk_max, 32768, 1}, | ||
1263 | {i2s1, pll_a_out0, 11289600, 0}, | ||
1264 | {i2s2, pll_a_out0, 11289600, 0}, | ||
1265 | {sdmmc1, pll_p, 48000000, 0}, | ||
1266 | {sdmmc3, pll_p, 48000000, 0}, | ||
1267 | {sdmmc4, pll_p, 48000000, 0}, | ||
1268 | {spi, pll_p, 20000000, 0}, | ||
1269 | {sbc1, pll_p, 100000000, 0}, | ||
1270 | {sbc2, pll_p, 100000000, 0}, | ||
1271 | {sbc3, pll_p, 100000000, 0}, | ||
1272 | {sbc4, pll_p, 100000000, 0}, | ||
1273 | {host1x, pll_c, 150000000, 0}, | ||
1274 | {disp1, pll_p, 600000000, 0}, | ||
1275 | {disp2, pll_p, 600000000, 0}, | ||
1276 | {clk_max, clk_max, 0, 0}, /* This MUST be the last entry */ | ||
1277 | }; | ||
1278 | |||
1279 | /* | ||
1280 | * Some clocks may be used by different drivers depending on the board | ||
1281 | * configuration. List those here to register them twice in the clock lookup | ||
1282 | * table under two names. | ||
1283 | */ | ||
1284 | static struct tegra_clk_duplicate tegra_clk_duplicates[] = { | ||
1285 | TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), | ||
1286 | TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), | ||
1287 | TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), | ||
1288 | TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"), | ||
1289 | TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL), | ||
1290 | TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */ | ||
1291 | }; | ||
1292 | |||
1293 | static const struct of_device_id pmc_match[] __initconst = { | ||
1294 | { .compatible = "nvidia,tegra20-pmc" }, | ||
1295 | {}, | ||
1296 | }; | ||
1297 | |||
1298 | void __init tegra20_clock_init(struct device_node *np) | ||
1299 | { | ||
1300 | int i; | ||
1301 | struct device_node *node; | ||
1302 | |||
1303 | clk_base = of_iomap(np, 0); | ||
1304 | if (!clk_base) { | ||
1305 | pr_err("Can't map CAR registers\n"); | ||
1306 | BUG(); | ||
1307 | } | ||
1308 | |||
1309 | node = of_find_matching_node(NULL, pmc_match); | ||
1310 | if (!node) { | ||
1311 | pr_err("Failed to find pmc node\n"); | ||
1312 | BUG(); | ||
1313 | } | ||
1314 | |||
1315 | pmc_base = of_iomap(node, 0); | ||
1316 | if (!pmc_base) { | ||
1317 | pr_err("Can't map pmc registers\n"); | ||
1318 | BUG(); | ||
1319 | } | ||
1320 | |||
1321 | tegra20_osc_clk_init(); | ||
1322 | tegra20_pmc_clk_init(); | ||
1323 | tegra20_fixed_clk_init(); | ||
1324 | tegra20_pll_init(); | ||
1325 | tegra20_super_clk_init(); | ||
1326 | tegra20_periph_clk_init(); | ||
1327 | tegra20_audio_clk_init(); | ||
1328 | |||
1329 | |||
1330 | for (i = 0; i < ARRAY_SIZE(clks); i++) { | ||
1331 | if (IS_ERR(clks[i])) { | ||
1332 | pr_err("Tegra20 clk %d: register failed with %ld\n", | ||
1333 | i, PTR_ERR(clks[i])); | ||
1334 | BUG(); | ||
1335 | } | ||
1336 | if (!clks[i]) | ||
1337 | clks[i] = ERR_PTR(-EINVAL); | ||
1338 | } | ||
1339 | |||
1340 | tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); | ||
1341 | |||
1342 | clk_data.clks = clks; | ||
1343 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
1344 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
1345 | |||
1346 | tegra_init_from_table(init_table, clks, clk_max); | ||
1347 | |||
1348 | tegra_cpu_car_ops = &tegra20_cpu_car_ops; | ||
1349 | } | ||
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c new file mode 100644 index 000000000000..a1638129eba4 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra30.c | |||
@@ -0,0 +1,1987 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/clk-provider.h> | ||
21 | #include <linux/clkdev.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_address.h> | ||
24 | #include <linux/clk/tegra.h> | ||
25 | |||
26 | #include <mach/powergate.h> | ||
27 | |||
28 | #include "clk.h" | ||
29 | |||
30 | #define RST_DEVICES_L 0x004 | ||
31 | #define RST_DEVICES_H 0x008 | ||
32 | #define RST_DEVICES_U 0x00c | ||
33 | #define RST_DEVICES_V 0x358 | ||
34 | #define RST_DEVICES_W 0x35c | ||
35 | #define RST_DEVICES_SET_L 0x300 | ||
36 | #define RST_DEVICES_CLR_L 0x304 | ||
37 | #define RST_DEVICES_SET_H 0x308 | ||
38 | #define RST_DEVICES_CLR_H 0x30c | ||
39 | #define RST_DEVICES_SET_U 0x310 | ||
40 | #define RST_DEVICES_CLR_U 0x314 | ||
41 | #define RST_DEVICES_SET_V 0x430 | ||
42 | #define RST_DEVICES_CLR_V 0x434 | ||
43 | #define RST_DEVICES_SET_W 0x438 | ||
44 | #define RST_DEVICES_CLR_W 0x43c | ||
45 | #define RST_DEVICES_NUM 5 | ||
46 | |||
47 | #define CLK_OUT_ENB_L 0x010 | ||
48 | #define CLK_OUT_ENB_H 0x014 | ||
49 | #define CLK_OUT_ENB_U 0x018 | ||
50 | #define CLK_OUT_ENB_V 0x360 | ||
51 | #define CLK_OUT_ENB_W 0x364 | ||
52 | #define CLK_OUT_ENB_SET_L 0x320 | ||
53 | #define CLK_OUT_ENB_CLR_L 0x324 | ||
54 | #define CLK_OUT_ENB_SET_H 0x328 | ||
55 | #define CLK_OUT_ENB_CLR_H 0x32c | ||
56 | #define CLK_OUT_ENB_SET_U 0x330 | ||
57 | #define CLK_OUT_ENB_CLR_U 0x334 | ||
58 | #define CLK_OUT_ENB_SET_V 0x440 | ||
59 | #define CLK_OUT_ENB_CLR_V 0x444 | ||
60 | #define CLK_OUT_ENB_SET_W 0x448 | ||
61 | #define CLK_OUT_ENB_CLR_W 0x44c | ||
62 | #define CLK_OUT_ENB_NUM 5 | ||
63 | |||
64 | #define OSC_CTRL 0x50 | ||
65 | #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) | ||
66 | #define OSC_CTRL_OSC_FREQ_13MHZ (0X0<<28) | ||
67 | #define OSC_CTRL_OSC_FREQ_19_2MHZ (0X4<<28) | ||
68 | #define OSC_CTRL_OSC_FREQ_12MHZ (0X8<<28) | ||
69 | #define OSC_CTRL_OSC_FREQ_26MHZ (0XC<<28) | ||
70 | #define OSC_CTRL_OSC_FREQ_16_8MHZ (0X1<<28) | ||
71 | #define OSC_CTRL_OSC_FREQ_38_4MHZ (0X5<<28) | ||
72 | #define OSC_CTRL_OSC_FREQ_48MHZ (0X9<<28) | ||
73 | #define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) | ||
74 | |||
75 | #define OSC_CTRL_PLL_REF_DIV_MASK (3<<26) | ||
76 | #define OSC_CTRL_PLL_REF_DIV_1 (0<<26) | ||
77 | #define OSC_CTRL_PLL_REF_DIV_2 (1<<26) | ||
78 | #define OSC_CTRL_PLL_REF_DIV_4 (2<<26) | ||
79 | |||
80 | #define OSC_FREQ_DET 0x58 | ||
81 | #define OSC_FREQ_DET_TRIG BIT(31) | ||
82 | |||
83 | #define OSC_FREQ_DET_STATUS 0x5c | ||
84 | #define OSC_FREQ_DET_BUSY BIT(31) | ||
85 | #define OSC_FREQ_DET_CNT_MASK 0xffff | ||
86 | |||
87 | #define CCLKG_BURST_POLICY 0x368 | ||
88 | #define SUPER_CCLKG_DIVIDER 0x36c | ||
89 | #define CCLKLP_BURST_POLICY 0x370 | ||
90 | #define SUPER_CCLKLP_DIVIDER 0x374 | ||
91 | #define SCLK_BURST_POLICY 0x028 | ||
92 | #define SUPER_SCLK_DIVIDER 0x02c | ||
93 | |||
94 | #define SYSTEM_CLK_RATE 0x030 | ||
95 | |||
96 | #define PLLC_BASE 0x80 | ||
97 | #define PLLC_MISC 0x8c | ||
98 | #define PLLM_BASE 0x90 | ||
99 | #define PLLM_MISC 0x9c | ||
100 | #define PLLP_BASE 0xa0 | ||
101 | #define PLLP_MISC 0xac | ||
102 | #define PLLX_BASE 0xe0 | ||
103 | #define PLLX_MISC 0xe4 | ||
104 | #define PLLD_BASE 0xd0 | ||
105 | #define PLLD_MISC 0xdc | ||
106 | #define PLLD2_BASE 0x4b8 | ||
107 | #define PLLD2_MISC 0x4bc | ||
108 | #define PLLE_BASE 0xe8 | ||
109 | #define PLLE_MISC 0xec | ||
110 | #define PLLA_BASE 0xb0 | ||
111 | #define PLLA_MISC 0xbc | ||
112 | #define PLLU_BASE 0xc0 | ||
113 | #define PLLU_MISC 0xcc | ||
114 | |||
115 | #define PLL_MISC_LOCK_ENABLE 18 | ||
116 | #define PLLDU_MISC_LOCK_ENABLE 22 | ||
117 | #define PLLE_MISC_LOCK_ENABLE 9 | ||
118 | |||
119 | #define PLL_BASE_LOCK 27 | ||
120 | #define PLLE_MISC_LOCK 11 | ||
121 | |||
122 | #define PLLE_AUX 0x48c | ||
123 | #define PLLC_OUT 0x84 | ||
124 | #define PLLM_OUT 0x94 | ||
125 | #define PLLP_OUTA 0xa4 | ||
126 | #define PLLP_OUTB 0xa8 | ||
127 | #define PLLA_OUT 0xb4 | ||
128 | |||
129 | #define AUDIO_SYNC_CLK_I2S0 0x4a0 | ||
130 | #define AUDIO_SYNC_CLK_I2S1 0x4a4 | ||
131 | #define AUDIO_SYNC_CLK_I2S2 0x4a8 | ||
132 | #define AUDIO_SYNC_CLK_I2S3 0x4ac | ||
133 | #define AUDIO_SYNC_CLK_I2S4 0x4b0 | ||
134 | #define AUDIO_SYNC_CLK_SPDIF 0x4b4 | ||
135 | |||
136 | #define PMC_CLK_OUT_CNTRL 0x1a8 | ||
137 | |||
138 | #define CLK_SOURCE_I2S0 0x1d8 | ||
139 | #define CLK_SOURCE_I2S1 0x100 | ||
140 | #define CLK_SOURCE_I2S2 0x104 | ||
141 | #define CLK_SOURCE_I2S3 0x3bc | ||
142 | #define CLK_SOURCE_I2S4 0x3c0 | ||
143 | #define CLK_SOURCE_SPDIF_OUT 0x108 | ||
144 | #define CLK_SOURCE_SPDIF_IN 0x10c | ||
145 | #define CLK_SOURCE_PWM 0x110 | ||
146 | #define CLK_SOURCE_D_AUDIO 0x3d0 | ||
147 | #define CLK_SOURCE_DAM0 0x3d8 | ||
148 | #define CLK_SOURCE_DAM1 0x3dc | ||
149 | #define CLK_SOURCE_DAM2 0x3e0 | ||
150 | #define CLK_SOURCE_HDA 0x428 | ||
151 | #define CLK_SOURCE_HDA2CODEC_2X 0x3e4 | ||
152 | #define CLK_SOURCE_SBC1 0x134 | ||
153 | #define CLK_SOURCE_SBC2 0x118 | ||
154 | #define CLK_SOURCE_SBC3 0x11c | ||
155 | #define CLK_SOURCE_SBC4 0x1b4 | ||
156 | #define CLK_SOURCE_SBC5 0x3c8 | ||
157 | #define CLK_SOURCE_SBC6 0x3cc | ||
158 | #define CLK_SOURCE_SATA_OOB 0x420 | ||
159 | #define CLK_SOURCE_SATA 0x424 | ||
160 | #define CLK_SOURCE_NDFLASH 0x160 | ||
161 | #define CLK_SOURCE_NDSPEED 0x3f8 | ||
162 | #define CLK_SOURCE_VFIR 0x168 | ||
163 | #define CLK_SOURCE_SDMMC1 0x150 | ||
164 | #define CLK_SOURCE_SDMMC2 0x154 | ||
165 | #define CLK_SOURCE_SDMMC3 0x1bc | ||
166 | #define CLK_SOURCE_SDMMC4 0x164 | ||
167 | #define CLK_SOURCE_VDE 0x1c8 | ||
168 | #define CLK_SOURCE_CSITE 0x1d4 | ||
169 | #define CLK_SOURCE_LA 0x1f8 | ||
170 | #define CLK_SOURCE_OWR 0x1cc | ||
171 | #define CLK_SOURCE_NOR 0x1d0 | ||
172 | #define CLK_SOURCE_MIPI 0x174 | ||
173 | #define CLK_SOURCE_I2C1 0x124 | ||
174 | #define CLK_SOURCE_I2C2 0x198 | ||
175 | #define CLK_SOURCE_I2C3 0x1b8 | ||
176 | #define CLK_SOURCE_I2C4 0x3c4 | ||
177 | #define CLK_SOURCE_I2C5 0x128 | ||
178 | #define CLK_SOURCE_UARTA 0x178 | ||
179 | #define CLK_SOURCE_UARTB 0x17c | ||
180 | #define CLK_SOURCE_UARTC 0x1a0 | ||
181 | #define CLK_SOURCE_UARTD 0x1c0 | ||
182 | #define CLK_SOURCE_UARTE 0x1c4 | ||
183 | #define CLK_SOURCE_VI 0x148 | ||
184 | #define CLK_SOURCE_VI_SENSOR 0x1a8 | ||
185 | #define CLK_SOURCE_3D 0x158 | ||
186 | #define CLK_SOURCE_3D2 0x3b0 | ||
187 | #define CLK_SOURCE_2D 0x15c | ||
188 | #define CLK_SOURCE_EPP 0x16c | ||
189 | #define CLK_SOURCE_MPE 0x170 | ||
190 | #define CLK_SOURCE_HOST1X 0x180 | ||
191 | #define CLK_SOURCE_CVE 0x140 | ||
192 | #define CLK_SOURCE_TVO 0x188 | ||
193 | #define CLK_SOURCE_DTV 0x1dc | ||
194 | #define CLK_SOURCE_HDMI 0x18c | ||
195 | #define CLK_SOURCE_TVDAC 0x194 | ||
196 | #define CLK_SOURCE_DISP1 0x138 | ||
197 | #define CLK_SOURCE_DISP2 0x13c | ||
198 | #define CLK_SOURCE_DSIB 0xd0 | ||
199 | #define CLK_SOURCE_TSENSOR 0x3b8 | ||
200 | #define CLK_SOURCE_ACTMON 0x3e8 | ||
201 | #define CLK_SOURCE_EXTERN1 0x3ec | ||
202 | #define CLK_SOURCE_EXTERN2 0x3f0 | ||
203 | #define CLK_SOURCE_EXTERN3 0x3f4 | ||
204 | #define CLK_SOURCE_I2CSLOW 0x3fc | ||
205 | #define CLK_SOURCE_SE 0x42c | ||
206 | #define CLK_SOURCE_MSELECT 0x3b4 | ||
207 | #define CLK_SOURCE_EMC 0x19c | ||
208 | |||
209 | #define AUDIO_SYNC_DOUBLER 0x49c | ||
210 | |||
211 | #define PMC_CTRL 0 | ||
212 | #define PMC_CTRL_BLINK_ENB 7 | ||
213 | |||
214 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
215 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 | ||
216 | #define PMC_BLINK_TIMER 0x40 | ||
217 | |||
218 | #define UTMIP_PLL_CFG2 0x488 | ||
219 | #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) | ||
220 | #define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) | ||
221 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0) | ||
222 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2) | ||
223 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4) | ||
224 | |||
225 | #define UTMIP_PLL_CFG1 0x484 | ||
226 | #define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6) | ||
227 | #define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) | ||
228 | #define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) | ||
229 | #define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) | ||
230 | #define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16) | ||
231 | |||
232 | /* Tegra CPU clock and reset control regs */ | ||
233 | #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c | ||
234 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 | ||
235 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344 | ||
236 | #define TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR 0x34c | ||
237 | #define TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 | ||
238 | |||
239 | #define CPU_CLOCK(cpu) (0x1 << (8 + cpu)) | ||
240 | #define CPU_RESET(cpu) (0x1111ul << (cpu)) | ||
241 | |||
242 | #define CLK_RESET_CCLK_BURST 0x20 | ||
243 | #define CLK_RESET_CCLK_DIVIDER 0x24 | ||
244 | #define CLK_RESET_PLLX_BASE 0xe0 | ||
245 | #define CLK_RESET_PLLX_MISC 0xe4 | ||
246 | |||
247 | #define CLK_RESET_SOURCE_CSITE 0x1d4 | ||
248 | |||
249 | #define CLK_RESET_CCLK_BURST_POLICY_SHIFT 28 | ||
250 | #define CLK_RESET_CCLK_RUN_POLICY_SHIFT 4 | ||
251 | #define CLK_RESET_CCLK_IDLE_POLICY_SHIFT 0 | ||
252 | #define CLK_RESET_CCLK_IDLE_POLICY 1 | ||
253 | #define CLK_RESET_CCLK_RUN_POLICY 2 | ||
254 | #define CLK_RESET_CCLK_BURST_POLICY_PLLX 8 | ||
255 | |||
256 | #ifdef CONFIG_PM_SLEEP | ||
257 | static struct cpu_clk_suspend_context { | ||
258 | u32 pllx_misc; | ||
259 | u32 pllx_base; | ||
260 | |||
261 | u32 cpu_burst; | ||
262 | u32 clk_csite_src; | ||
263 | u32 cclk_divider; | ||
264 | } tegra30_cpu_clk_sctx; | ||
265 | #endif | ||
266 | |||
267 | static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; | ||
268 | |||
269 | static void __iomem *clk_base; | ||
270 | static void __iomem *pmc_base; | ||
271 | static unsigned long input_freq; | ||
272 | |||
273 | static DEFINE_SPINLOCK(clk_doubler_lock); | ||
274 | static DEFINE_SPINLOCK(clk_out_lock); | ||
275 | static DEFINE_SPINLOCK(pll_div_lock); | ||
276 | static DEFINE_SPINLOCK(cml_lock); | ||
277 | static DEFINE_SPINLOCK(pll_d_lock); | ||
278 | |||
279 | #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ | ||
280 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
281 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
282 | 30, 2, 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
283 | periph_clk_enb_refcnt, _gate_flags, _clk_id) | ||
284 | |||
285 | #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ | ||
286 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
287 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
288 | 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ | ||
289 | _regs, _clk_num, periph_clk_enb_refcnt, \ | ||
290 | _gate_flags, _clk_id) | ||
291 | |||
292 | #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ | ||
293 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
294 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
295 | 29, 3, 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
296 | periph_clk_enb_refcnt, _gate_flags, _clk_id) | ||
297 | |||
298 | #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ | ||
299 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
300 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
301 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ | ||
302 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
303 | _clk_id) | ||
304 | |||
305 | #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ | ||
306 | _clk_num, _regs, _clk_id) \ | ||
307 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
308 | 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs, \ | ||
309 | _clk_num, periph_clk_enb_refcnt, 0, _clk_id) | ||
310 | |||
311 | #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ | ||
312 | _mux_shift, _mux_width, _clk_num, _regs, \ | ||
313 | _gate_flags, _clk_id) \ | ||
314 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
315 | _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ | ||
316 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
317 | _clk_id) | ||
318 | |||
319 | /* | ||
320 | * IDs assigned here must be in sync with DT bindings definition | ||
321 | * for Tegra30 clocks. | ||
322 | */ | ||
323 | enum tegra30_clk { | ||
324 | cpu, rtc = 4, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, ndflash, | ||
325 | sdmmc1, sdmmc4, pwm = 17, i2s2, epp, gr2d = 21, usbd, isp, gr3d, | ||
326 | disp2 = 26, disp1, host1x, vcp, i2s0, cop_cache, mc, ahbdma, apbdma, | ||
327 | kbc = 36, statmon, pmc, kfuse = 40, sbc1, nor, sbc2 = 44, sbc3 = 46, | ||
328 | i2c5, dsia, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, | ||
329 | usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, | ||
330 | pcie, owr, afi, csite, pciex, avpucq, la, dtv = 79, ndspeed, i2c_slow, | ||
331 | dsib, irama = 84, iramb, iramc, iramd, cram2, audio_2x = 90, csus = 92, | ||
332 | cdev1, cdev2, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4, | ||
333 | i2c4, sbc5, sbc6, d_audio, apbif, dam0, dam1, dam2, hda2codec_2x, | ||
334 | atomics, audio0_2x, audio1_2x, audio2_2x, audio3_2x, audio4_2x, | ||
335 | spdif_2x, actmon, extern1, extern2, extern3, sata_oob, sata, hda, se, | ||
336 | hda2hdmi, sata_cold, uartb = 160, vfir, spdif_out, spdif_in, vi, | ||
337 | vi_sensor, fuse, fuse_burn, cve, tvo, clk_32k, clk_m, clk_m_div2, | ||
338 | clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_m, pll_m_out1, pll_p, | ||
339 | pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_a, pll_a_out0, | ||
340 | pll_d, pll_d_out0, pll_d2, pll_d2_out0, pll_u, pll_x, pll_x_out0, pll_e, | ||
341 | spdif_in_sync, i2s0_sync, i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, | ||
342 | vimclk_sync, audio0, audio1, audio2, audio3, audio4, spdif, clk_out_1, | ||
343 | clk_out_2, clk_out_3, sclk, blink, cclk_g, cclk_lp, twd, cml0, cml1, | ||
344 | i2cslow, hclk, pclk, clk_out_1_mux = 300, clk_max | ||
345 | }; | ||
346 | |||
347 | static struct clk *clks[clk_max]; | ||
348 | static struct clk_onecell_data clk_data; | ||
349 | |||
350 | /* | ||
351 | * Structure defining the fields for USB UTMI clocks Parameters. | ||
352 | */ | ||
353 | struct utmi_clk_param { | ||
354 | /* Oscillator Frequency in KHz */ | ||
355 | u32 osc_frequency; | ||
356 | /* UTMIP PLL Enable Delay Count */ | ||
357 | u8 enable_delay_count; | ||
358 | /* UTMIP PLL Stable count */ | ||
359 | u8 stable_count; | ||
360 | /* UTMIP PLL Active delay count */ | ||
361 | u8 active_delay_count; | ||
362 | /* UTMIP PLL Xtal frequency count */ | ||
363 | u8 xtal_freq_count; | ||
364 | }; | ||
365 | |||
366 | static const struct utmi_clk_param utmi_parameters[] = { | ||
367 | /* OSC_FREQUENCY, ENABLE_DLY, STABLE_CNT, ACTIVE_DLY, XTAL_FREQ_CNT */ | ||
368 | {13000000, 0x02, 0x33, 0x05, 0x7F}, | ||
369 | {19200000, 0x03, 0x4B, 0x06, 0xBB}, | ||
370 | {12000000, 0x02, 0x2F, 0x04, 0x76}, | ||
371 | {26000000, 0x04, 0x66, 0x09, 0xFE}, | ||
372 | {16800000, 0x03, 0x41, 0x0A, 0xA4}, | ||
373 | }; | ||
374 | |||
375 | static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { | ||
376 | { 12000000, 1040000000, 520, 6, 1, 8}, | ||
377 | { 13000000, 1040000000, 480, 6, 1, 8}, | ||
378 | { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */ | ||
379 | { 19200000, 1040000000, 325, 6, 1, 6}, | ||
380 | { 26000000, 1040000000, 520, 13, 1, 8}, | ||
381 | |||
382 | { 12000000, 832000000, 416, 6, 1, 8}, | ||
383 | { 13000000, 832000000, 832, 13, 1, 8}, | ||
384 | { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */ | ||
385 | { 19200000, 832000000, 260, 6, 1, 8}, | ||
386 | { 26000000, 832000000, 416, 13, 1, 8}, | ||
387 | |||
388 | { 12000000, 624000000, 624, 12, 1, 8}, | ||
389 | { 13000000, 624000000, 624, 13, 1, 8}, | ||
390 | { 16800000, 600000000, 520, 14, 1, 8}, | ||
391 | { 19200000, 624000000, 520, 16, 1, 8}, | ||
392 | { 26000000, 624000000, 624, 26, 1, 8}, | ||
393 | |||
394 | { 12000000, 600000000, 600, 12, 1, 8}, | ||
395 | { 13000000, 600000000, 600, 13, 1, 8}, | ||
396 | { 16800000, 600000000, 500, 14, 1, 8}, | ||
397 | { 19200000, 600000000, 375, 12, 1, 6}, | ||
398 | { 26000000, 600000000, 600, 26, 1, 8}, | ||
399 | |||
400 | { 12000000, 520000000, 520, 12, 1, 8}, | ||
401 | { 13000000, 520000000, 520, 13, 1, 8}, | ||
402 | { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */ | ||
403 | { 19200000, 520000000, 325, 12, 1, 6}, | ||
404 | { 26000000, 520000000, 520, 26, 1, 8}, | ||
405 | |||
406 | { 12000000, 416000000, 416, 12, 1, 8}, | ||
407 | { 13000000, 416000000, 416, 13, 1, 8}, | ||
408 | { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */ | ||
409 | { 19200000, 416000000, 260, 12, 1, 6}, | ||
410 | { 26000000, 416000000, 416, 26, 1, 8}, | ||
411 | { 0, 0, 0, 0, 0, 0 }, | ||
412 | }; | ||
413 | |||
414 | static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { | ||
415 | { 12000000, 666000000, 666, 12, 1, 8}, | ||
416 | { 13000000, 666000000, 666, 13, 1, 8}, | ||
417 | { 16800000, 666000000, 555, 14, 1, 8}, | ||
418 | { 19200000, 666000000, 555, 16, 1, 8}, | ||
419 | { 26000000, 666000000, 666, 26, 1, 8}, | ||
420 | { 12000000, 600000000, 600, 12, 1, 8}, | ||
421 | { 13000000, 600000000, 600, 13, 1, 8}, | ||
422 | { 16800000, 600000000, 500, 14, 1, 8}, | ||
423 | { 19200000, 600000000, 375, 12, 1, 6}, | ||
424 | { 26000000, 600000000, 600, 26, 1, 8}, | ||
425 | { 0, 0, 0, 0, 0, 0 }, | ||
426 | }; | ||
427 | |||
428 | static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { | ||
429 | { 12000000, 216000000, 432, 12, 2, 8}, | ||
430 | { 13000000, 216000000, 432, 13, 2, 8}, | ||
431 | { 16800000, 216000000, 360, 14, 2, 8}, | ||
432 | { 19200000, 216000000, 360, 16, 2, 8}, | ||
433 | { 26000000, 216000000, 432, 26, 2, 8}, | ||
434 | { 0, 0, 0, 0, 0, 0 }, | ||
435 | }; | ||
436 | |||
437 | static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { | ||
438 | { 9600000, 564480000, 294, 5, 1, 4}, | ||
439 | { 9600000, 552960000, 288, 5, 1, 4}, | ||
440 | { 9600000, 24000000, 5, 2, 1, 1}, | ||
441 | |||
442 | { 28800000, 56448000, 49, 25, 1, 1}, | ||
443 | { 28800000, 73728000, 64, 25, 1, 1}, | ||
444 | { 28800000, 24000000, 5, 6, 1, 1}, | ||
445 | { 0, 0, 0, 0, 0, 0 }, | ||
446 | }; | ||
447 | |||
448 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { | ||
449 | { 12000000, 216000000, 216, 12, 1, 4}, | ||
450 | { 13000000, 216000000, 216, 13, 1, 4}, | ||
451 | { 16800000, 216000000, 180, 14, 1, 4}, | ||
452 | { 19200000, 216000000, 180, 16, 1, 4}, | ||
453 | { 26000000, 216000000, 216, 26, 1, 4}, | ||
454 | |||
455 | { 12000000, 594000000, 594, 12, 1, 8}, | ||
456 | { 13000000, 594000000, 594, 13, 1, 8}, | ||
457 | { 16800000, 594000000, 495, 14, 1, 8}, | ||
458 | { 19200000, 594000000, 495, 16, 1, 8}, | ||
459 | { 26000000, 594000000, 594, 26, 1, 8}, | ||
460 | |||
461 | { 12000000, 1000000000, 1000, 12, 1, 12}, | ||
462 | { 13000000, 1000000000, 1000, 13, 1, 12}, | ||
463 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
464 | { 26000000, 1000000000, 1000, 26, 1, 12}, | ||
465 | |||
466 | { 0, 0, 0, 0, 0, 0 }, | ||
467 | }; | ||
468 | |||
469 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { | ||
470 | { 12000000, 480000000, 960, 12, 2, 12}, | ||
471 | { 13000000, 480000000, 960, 13, 2, 12}, | ||
472 | { 16800000, 480000000, 400, 7, 2, 5}, | ||
473 | { 19200000, 480000000, 200, 4, 2, 3}, | ||
474 | { 26000000, 480000000, 960, 26, 2, 12}, | ||
475 | { 0, 0, 0, 0, 0, 0 }, | ||
476 | }; | ||
477 | |||
478 | static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { | ||
479 | /* 1.7 GHz */ | ||
480 | { 12000000, 1700000000, 850, 6, 1, 8}, | ||
481 | { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */ | ||
482 | { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */ | ||
483 | { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */ | ||
484 | { 26000000, 1700000000, 850, 13, 1, 8}, | ||
485 | |||
486 | /* 1.6 GHz */ | ||
487 | { 12000000, 1600000000, 800, 6, 1, 8}, | ||
488 | { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */ | ||
489 | { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */ | ||
490 | { 19200000, 1600000000, 500, 6, 1, 8}, | ||
491 | { 26000000, 1600000000, 800, 13, 1, 8}, | ||
492 | |||
493 | /* 1.5 GHz */ | ||
494 | { 12000000, 1500000000, 750, 6, 1, 8}, | ||
495 | { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */ | ||
496 | { 16800000, 1500000000, 625, 7, 1, 8}, | ||
497 | { 19200000, 1500000000, 625, 8, 1, 8}, | ||
498 | { 26000000, 1500000000, 750, 13, 1, 8}, | ||
499 | |||
500 | /* 1.4 GHz */ | ||
501 | { 12000000, 1400000000, 700, 6, 1, 8}, | ||
502 | { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */ | ||
503 | { 16800000, 1400000000, 1000, 12, 1, 8}, | ||
504 | { 19200000, 1400000000, 875, 12, 1, 8}, | ||
505 | { 26000000, 1400000000, 700, 13, 1, 8}, | ||
506 | |||
507 | /* 1.3 GHz */ | ||
508 | { 12000000, 1300000000, 975, 9, 1, 8}, | ||
509 | { 13000000, 1300000000, 1000, 10, 1, 8}, | ||
510 | { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */ | ||
511 | { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */ | ||
512 | { 26000000, 1300000000, 650, 13, 1, 8}, | ||
513 | |||
514 | /* 1.2 GHz */ | ||
515 | { 12000000, 1200000000, 1000, 10, 1, 8}, | ||
516 | { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */ | ||
517 | { 16800000, 1200000000, 1000, 14, 1, 8}, | ||
518 | { 19200000, 1200000000, 1000, 16, 1, 8}, | ||
519 | { 26000000, 1200000000, 600, 13, 1, 8}, | ||
520 | |||
521 | /* 1.1 GHz */ | ||
522 | { 12000000, 1100000000, 825, 9, 1, 8}, | ||
523 | { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */ | ||
524 | { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */ | ||
525 | { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */ | ||
526 | { 26000000, 1100000000, 550, 13, 1, 8}, | ||
527 | |||
528 | /* 1 GHz */ | ||
529 | { 12000000, 1000000000, 1000, 12, 1, 8}, | ||
530 | { 13000000, 1000000000, 1000, 13, 1, 8}, | ||
531 | { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */ | ||
532 | { 19200000, 1000000000, 625, 12, 1, 8}, | ||
533 | { 26000000, 1000000000, 1000, 26, 1, 8}, | ||
534 | |||
535 | { 0, 0, 0, 0, 0, 0 }, | ||
536 | }; | ||
537 | |||
538 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { | ||
539 | /* PLLE special case: use cpcon field to store cml divider value */ | ||
540 | { 12000000, 100000000, 150, 1, 18, 11}, | ||
541 | { 216000000, 100000000, 200, 18, 24, 13}, | ||
542 | { 0, 0, 0, 0, 0, 0 }, | ||
543 | }; | ||
544 | |||
545 | /* PLL parameters */ | ||
546 | static struct tegra_clk_pll_params pll_c_params = { | ||
547 | .input_min = 2000000, | ||
548 | .input_max = 31000000, | ||
549 | .cf_min = 1000000, | ||
550 | .cf_max = 6000000, | ||
551 | .vco_min = 20000000, | ||
552 | .vco_max = 1400000000, | ||
553 | .base_reg = PLLC_BASE, | ||
554 | .misc_reg = PLLC_MISC, | ||
555 | .lock_bit_idx = PLL_BASE_LOCK, | ||
556 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
557 | .lock_delay = 300, | ||
558 | }; | ||
559 | |||
560 | static struct tegra_clk_pll_params pll_m_params = { | ||
561 | .input_min = 2000000, | ||
562 | .input_max = 31000000, | ||
563 | .cf_min = 1000000, | ||
564 | .cf_max = 6000000, | ||
565 | .vco_min = 20000000, | ||
566 | .vco_max = 1200000000, | ||
567 | .base_reg = PLLM_BASE, | ||
568 | .misc_reg = PLLM_MISC, | ||
569 | .lock_bit_idx = PLL_BASE_LOCK, | ||
570 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
571 | .lock_delay = 300, | ||
572 | }; | ||
573 | |||
574 | static struct tegra_clk_pll_params pll_p_params = { | ||
575 | .input_min = 2000000, | ||
576 | .input_max = 31000000, | ||
577 | .cf_min = 1000000, | ||
578 | .cf_max = 6000000, | ||
579 | .vco_min = 20000000, | ||
580 | .vco_max = 1400000000, | ||
581 | .base_reg = PLLP_BASE, | ||
582 | .misc_reg = PLLP_MISC, | ||
583 | .lock_bit_idx = PLL_BASE_LOCK, | ||
584 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
585 | .lock_delay = 300, | ||
586 | }; | ||
587 | |||
588 | static struct tegra_clk_pll_params pll_a_params = { | ||
589 | .input_min = 2000000, | ||
590 | .input_max = 31000000, | ||
591 | .cf_min = 1000000, | ||
592 | .cf_max = 6000000, | ||
593 | .vco_min = 20000000, | ||
594 | .vco_max = 1400000000, | ||
595 | .base_reg = PLLA_BASE, | ||
596 | .misc_reg = PLLA_MISC, | ||
597 | .lock_bit_idx = PLL_BASE_LOCK, | ||
598 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
599 | .lock_delay = 300, | ||
600 | }; | ||
601 | |||
602 | static struct tegra_clk_pll_params pll_d_params = { | ||
603 | .input_min = 2000000, | ||
604 | .input_max = 40000000, | ||
605 | .cf_min = 1000000, | ||
606 | .cf_max = 6000000, | ||
607 | .vco_min = 40000000, | ||
608 | .vco_max = 1000000000, | ||
609 | .base_reg = PLLD_BASE, | ||
610 | .misc_reg = PLLD_MISC, | ||
611 | .lock_bit_idx = PLL_BASE_LOCK, | ||
612 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | ||
613 | .lock_delay = 1000, | ||
614 | }; | ||
615 | |||
616 | static struct tegra_clk_pll_params pll_d2_params = { | ||
617 | .input_min = 2000000, | ||
618 | .input_max = 40000000, | ||
619 | .cf_min = 1000000, | ||
620 | .cf_max = 6000000, | ||
621 | .vco_min = 40000000, | ||
622 | .vco_max = 1000000000, | ||
623 | .base_reg = PLLD2_BASE, | ||
624 | .misc_reg = PLLD2_MISC, | ||
625 | .lock_bit_idx = PLL_BASE_LOCK, | ||
626 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | ||
627 | .lock_delay = 1000, | ||
628 | }; | ||
629 | |||
630 | static struct tegra_clk_pll_params pll_u_params = { | ||
631 | .input_min = 2000000, | ||
632 | .input_max = 40000000, | ||
633 | .cf_min = 1000000, | ||
634 | .cf_max = 6000000, | ||
635 | .vco_min = 48000000, | ||
636 | .vco_max = 960000000, | ||
637 | .base_reg = PLLU_BASE, | ||
638 | .misc_reg = PLLU_MISC, | ||
639 | .lock_bit_idx = PLL_BASE_LOCK, | ||
640 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | ||
641 | .lock_delay = 1000, | ||
642 | }; | ||
643 | |||
644 | static struct tegra_clk_pll_params pll_x_params = { | ||
645 | .input_min = 2000000, | ||
646 | .input_max = 31000000, | ||
647 | .cf_min = 1000000, | ||
648 | .cf_max = 6000000, | ||
649 | .vco_min = 20000000, | ||
650 | .vco_max = 1700000000, | ||
651 | .base_reg = PLLX_BASE, | ||
652 | .misc_reg = PLLX_MISC, | ||
653 | .lock_bit_idx = PLL_BASE_LOCK, | ||
654 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
655 | .lock_delay = 300, | ||
656 | }; | ||
657 | |||
658 | static struct tegra_clk_pll_params pll_e_params = { | ||
659 | .input_min = 12000000, | ||
660 | .input_max = 216000000, | ||
661 | .cf_min = 12000000, | ||
662 | .cf_max = 12000000, | ||
663 | .vco_min = 1200000000, | ||
664 | .vco_max = 2400000000U, | ||
665 | .base_reg = PLLE_BASE, | ||
666 | .misc_reg = PLLE_MISC, | ||
667 | .lock_bit_idx = PLLE_MISC_LOCK, | ||
668 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, | ||
669 | .lock_delay = 300, | ||
670 | }; | ||
671 | |||
672 | /* Peripheral clock registers */ | ||
673 | static struct tegra_clk_periph_regs periph_l_regs = { | ||
674 | .enb_reg = CLK_OUT_ENB_L, | ||
675 | .enb_set_reg = CLK_OUT_ENB_SET_L, | ||
676 | .enb_clr_reg = CLK_OUT_ENB_CLR_L, | ||
677 | .rst_reg = RST_DEVICES_L, | ||
678 | .rst_set_reg = RST_DEVICES_SET_L, | ||
679 | .rst_clr_reg = RST_DEVICES_CLR_L, | ||
680 | }; | ||
681 | |||
682 | static struct tegra_clk_periph_regs periph_h_regs = { | ||
683 | .enb_reg = CLK_OUT_ENB_H, | ||
684 | .enb_set_reg = CLK_OUT_ENB_SET_H, | ||
685 | .enb_clr_reg = CLK_OUT_ENB_CLR_H, | ||
686 | .rst_reg = RST_DEVICES_H, | ||
687 | .rst_set_reg = RST_DEVICES_SET_H, | ||
688 | .rst_clr_reg = RST_DEVICES_CLR_H, | ||
689 | }; | ||
690 | |||
691 | static struct tegra_clk_periph_regs periph_u_regs = { | ||
692 | .enb_reg = CLK_OUT_ENB_U, | ||
693 | .enb_set_reg = CLK_OUT_ENB_SET_U, | ||
694 | .enb_clr_reg = CLK_OUT_ENB_CLR_U, | ||
695 | .rst_reg = RST_DEVICES_U, | ||
696 | .rst_set_reg = RST_DEVICES_SET_U, | ||
697 | .rst_clr_reg = RST_DEVICES_CLR_U, | ||
698 | }; | ||
699 | |||
700 | static struct tegra_clk_periph_regs periph_v_regs = { | ||
701 | .enb_reg = CLK_OUT_ENB_V, | ||
702 | .enb_set_reg = CLK_OUT_ENB_SET_V, | ||
703 | .enb_clr_reg = CLK_OUT_ENB_CLR_V, | ||
704 | .rst_reg = RST_DEVICES_V, | ||
705 | .rst_set_reg = RST_DEVICES_SET_V, | ||
706 | .rst_clr_reg = RST_DEVICES_CLR_V, | ||
707 | }; | ||
708 | |||
709 | static struct tegra_clk_periph_regs periph_w_regs = { | ||
710 | .enb_reg = CLK_OUT_ENB_W, | ||
711 | .enb_set_reg = CLK_OUT_ENB_SET_W, | ||
712 | .enb_clr_reg = CLK_OUT_ENB_CLR_W, | ||
713 | .rst_reg = RST_DEVICES_W, | ||
714 | .rst_set_reg = RST_DEVICES_SET_W, | ||
715 | .rst_clr_reg = RST_DEVICES_CLR_W, | ||
716 | }; | ||
717 | |||
718 | static void tegra30_clk_measure_input_freq(void) | ||
719 | { | ||
720 | u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); | ||
721 | u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK; | ||
722 | u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; | ||
723 | |||
724 | switch (auto_clk_control) { | ||
725 | case OSC_CTRL_OSC_FREQ_12MHZ: | ||
726 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
727 | input_freq = 12000000; | ||
728 | break; | ||
729 | case OSC_CTRL_OSC_FREQ_13MHZ: | ||
730 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
731 | input_freq = 13000000; | ||
732 | break; | ||
733 | case OSC_CTRL_OSC_FREQ_19_2MHZ: | ||
734 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
735 | input_freq = 19200000; | ||
736 | break; | ||
737 | case OSC_CTRL_OSC_FREQ_26MHZ: | ||
738 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
739 | input_freq = 26000000; | ||
740 | break; | ||
741 | case OSC_CTRL_OSC_FREQ_16_8MHZ: | ||
742 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
743 | input_freq = 16800000; | ||
744 | break; | ||
745 | case OSC_CTRL_OSC_FREQ_38_4MHZ: | ||
746 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2); | ||
747 | input_freq = 38400000; | ||
748 | break; | ||
749 | case OSC_CTRL_OSC_FREQ_48MHZ: | ||
750 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); | ||
751 | input_freq = 48000000; | ||
752 | break; | ||
753 | default: | ||
754 | pr_err("Unexpected auto clock control value %d", | ||
755 | auto_clk_control); | ||
756 | BUG(); | ||
757 | return; | ||
758 | } | ||
759 | } | ||
760 | |||
761 | static unsigned int tegra30_get_pll_ref_div(void) | ||
762 | { | ||
763 | u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) & | ||
764 | OSC_CTRL_PLL_REF_DIV_MASK; | ||
765 | |||
766 | switch (pll_ref_div) { | ||
767 | case OSC_CTRL_PLL_REF_DIV_1: | ||
768 | return 1; | ||
769 | case OSC_CTRL_PLL_REF_DIV_2: | ||
770 | return 2; | ||
771 | case OSC_CTRL_PLL_REF_DIV_4: | ||
772 | return 4; | ||
773 | default: | ||
774 | pr_err("Invalid pll ref divider %d", pll_ref_div); | ||
775 | BUG(); | ||
776 | } | ||
777 | return 0; | ||
778 | } | ||
779 | |||
780 | static void tegra30_utmi_param_configure(void) | ||
781 | { | ||
782 | u32 reg; | ||
783 | int i; | ||
784 | |||
785 | for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { | ||
786 | if (input_freq == utmi_parameters[i].osc_frequency) | ||
787 | break; | ||
788 | } | ||
789 | |||
790 | if (i >= ARRAY_SIZE(utmi_parameters)) { | ||
791 | pr_err("%s: Unexpected input rate %lu\n", __func__, input_freq); | ||
792 | return; | ||
793 | } | ||
794 | |||
795 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); | ||
796 | |||
797 | /* Program UTMIP PLL stable and active counts */ | ||
798 | reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); | ||
799 | reg |= UTMIP_PLL_CFG2_STABLE_COUNT( | ||
800 | utmi_parameters[i].stable_count); | ||
801 | |||
802 | reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); | ||
803 | |||
804 | reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT( | ||
805 | utmi_parameters[i].active_delay_count); | ||
806 | |||
807 | /* Remove power downs from UTMIP PLL control bits */ | ||
808 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; | ||
809 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; | ||
810 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN; | ||
811 | |||
812 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); | ||
813 | |||
814 | /* Program UTMIP PLL delay and oscillator frequency counts */ | ||
815 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); | ||
816 | reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); | ||
817 | |||
818 | reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT( | ||
819 | utmi_parameters[i].enable_delay_count); | ||
820 | |||
821 | reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); | ||
822 | reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT( | ||
823 | utmi_parameters[i].xtal_freq_count); | ||
824 | |||
825 | /* Remove power downs from UTMIP PLL control bits */ | ||
826 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; | ||
827 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN; | ||
828 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; | ||
829 | |||
830 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); | ||
831 | } | ||
832 | |||
833 | static const char *pll_e_parents[] = {"pll_ref", "pll_p"}; | ||
834 | |||
835 | static void __init tegra30_pll_init(void) | ||
836 | { | ||
837 | struct clk *clk; | ||
838 | |||
839 | /* PLLC */ | ||
840 | clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, | ||
841 | 0, &pll_c_params, | ||
842 | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | ||
843 | pll_c_freq_table, NULL); | ||
844 | clk_register_clkdev(clk, "pll_c", NULL); | ||
845 | clks[pll_c] = clk; | ||
846 | |||
847 | /* PLLC_OUT1 */ | ||
848 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", | ||
849 | clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
850 | 8, 8, 1, NULL); | ||
851 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", | ||
852 | clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, | ||
853 | 0, NULL); | ||
854 | clk_register_clkdev(clk, "pll_c_out1", NULL); | ||
855 | clks[pll_c_out1] = clk; | ||
856 | |||
857 | /* PLLP */ | ||
858 | clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc_base, 0, | ||
859 | 408000000, &pll_p_params, | ||
860 | TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | | ||
861 | TEGRA_PLL_USE_LOCK, pll_p_freq_table, NULL); | ||
862 | clk_register_clkdev(clk, "pll_p", NULL); | ||
863 | clks[pll_p] = clk; | ||
864 | |||
865 | /* PLLP_OUT1 */ | ||
866 | clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", | ||
867 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | | ||
868 | TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, | ||
869 | &pll_div_lock); | ||
870 | clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", | ||
871 | clk_base + PLLP_OUTA, 1, 0, | ||
872 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
873 | &pll_div_lock); | ||
874 | clk_register_clkdev(clk, "pll_p_out1", NULL); | ||
875 | clks[pll_p_out1] = clk; | ||
876 | |||
877 | /* PLLP_OUT2 */ | ||
878 | clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", | ||
879 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | | ||
880 | TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, | ||
881 | &pll_div_lock); | ||
882 | clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", | ||
883 | clk_base + PLLP_OUTA, 17, 16, | ||
884 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
885 | &pll_div_lock); | ||
886 | clk_register_clkdev(clk, "pll_p_out2", NULL); | ||
887 | clks[pll_p_out2] = clk; | ||
888 | |||
889 | /* PLLP_OUT3 */ | ||
890 | clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", | ||
891 | clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | | ||
892 | TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, | ||
893 | &pll_div_lock); | ||
894 | clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", | ||
895 | clk_base + PLLP_OUTB, 1, 0, | ||
896 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
897 | &pll_div_lock); | ||
898 | clk_register_clkdev(clk, "pll_p_out3", NULL); | ||
899 | clks[pll_p_out3] = clk; | ||
900 | |||
901 | /* PLLP_OUT4 */ | ||
902 | clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", | ||
903 | clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | | ||
904 | TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, | ||
905 | &pll_div_lock); | ||
906 | clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", | ||
907 | clk_base + PLLP_OUTB, 17, 16, | ||
908 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
909 | &pll_div_lock); | ||
910 | clk_register_clkdev(clk, "pll_p_out4", NULL); | ||
911 | clks[pll_p_out4] = clk; | ||
912 | |||
913 | /* PLLM */ | ||
914 | clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, | ||
915 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, | ||
916 | &pll_m_params, TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | | ||
917 | TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, | ||
918 | pll_m_freq_table, NULL); | ||
919 | clk_register_clkdev(clk, "pll_m", NULL); | ||
920 | clks[pll_m] = clk; | ||
921 | |||
922 | /* PLLM_OUT1 */ | ||
923 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", | ||
924 | clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
925 | 8, 8, 1, NULL); | ||
926 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", | ||
927 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
928 | CLK_SET_RATE_PARENT, 0, NULL); | ||
929 | clk_register_clkdev(clk, "pll_m_out1", NULL); | ||
930 | clks[pll_m_out1] = clk; | ||
931 | |||
932 | /* PLLX */ | ||
933 | clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0, | ||
934 | 0, &pll_x_params, TEGRA_PLL_HAS_CPCON | | ||
935 | TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, | ||
936 | pll_x_freq_table, NULL); | ||
937 | clk_register_clkdev(clk, "pll_x", NULL); | ||
938 | clks[pll_x] = clk; | ||
939 | |||
940 | /* PLLX_OUT0 */ | ||
941 | clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", | ||
942 | CLK_SET_RATE_PARENT, 1, 2); | ||
943 | clk_register_clkdev(clk, "pll_x_out0", NULL); | ||
944 | clks[pll_x_out0] = clk; | ||
945 | |||
946 | /* PLLU */ | ||
947 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0, | ||
948 | 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | | ||
949 | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, | ||
950 | pll_u_freq_table, | ||
951 | NULL); | ||
952 | clk_register_clkdev(clk, "pll_u", NULL); | ||
953 | clks[pll_u] = clk; | ||
954 | |||
955 | tegra30_utmi_param_configure(); | ||
956 | |||
957 | /* PLLD */ | ||
958 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0, | ||
959 | 0, &pll_d_params, TEGRA_PLL_HAS_CPCON | | ||
960 | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, | ||
961 | pll_d_freq_table, &pll_d_lock); | ||
962 | clk_register_clkdev(clk, "pll_d", NULL); | ||
963 | clks[pll_d] = clk; | ||
964 | |||
965 | /* PLLD_OUT0 */ | ||
966 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", | ||
967 | CLK_SET_RATE_PARENT, 1, 2); | ||
968 | clk_register_clkdev(clk, "pll_d_out0", NULL); | ||
969 | clks[pll_d_out0] = clk; | ||
970 | |||
971 | /* PLLD2 */ | ||
972 | clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, | ||
973 | 0, &pll_d2_params, TEGRA_PLL_HAS_CPCON | | ||
974 | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, | ||
975 | pll_d_freq_table, NULL); | ||
976 | clk_register_clkdev(clk, "pll_d2", NULL); | ||
977 | clks[pll_d2] = clk; | ||
978 | |||
979 | /* PLLD2_OUT0 */ | ||
980 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", | ||
981 | CLK_SET_RATE_PARENT, 1, 2); | ||
982 | clk_register_clkdev(clk, "pll_d2_out0", NULL); | ||
983 | clks[pll_d2_out0] = clk; | ||
984 | |||
985 | /* PLLA */ | ||
986 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc_base, | ||
987 | 0, 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | | ||
988 | TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); | ||
989 | clk_register_clkdev(clk, "pll_a", NULL); | ||
990 | clks[pll_a] = clk; | ||
991 | |||
992 | /* PLLA_OUT0 */ | ||
993 | clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", | ||
994 | clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
995 | 8, 8, 1, NULL); | ||
996 | clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", | ||
997 | clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
998 | CLK_SET_RATE_PARENT, 0, NULL); | ||
999 | clk_register_clkdev(clk, "pll_a_out0", NULL); | ||
1000 | clks[pll_a_out0] = clk; | ||
1001 | |||
1002 | /* PLLE */ | ||
1003 | clk = clk_register_mux(NULL, "pll_e_mux", pll_e_parents, | ||
1004 | ARRAY_SIZE(pll_e_parents), 0, | ||
1005 | clk_base + PLLE_AUX, 2, 1, 0, NULL); | ||
1006 | clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, | ||
1007 | CLK_GET_RATE_NOCACHE, 100000000, &pll_e_params, | ||
1008 | TEGRA_PLLE_CONFIGURE, pll_e_freq_table, NULL); | ||
1009 | clk_register_clkdev(clk, "pll_e", NULL); | ||
1010 | clks[pll_e] = clk; | ||
1011 | } | ||
1012 | |||
1013 | static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", | ||
1014 | "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",}; | ||
1015 | static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", | ||
1016 | "clk_m_div4", "extern1", }; | ||
1017 | static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", | ||
1018 | "clk_m_div4", "extern2", }; | ||
1019 | static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", | ||
1020 | "clk_m_div4", "extern3", }; | ||
1021 | |||
1022 | static void __init tegra30_audio_clk_init(void) | ||
1023 | { | ||
1024 | struct clk *clk; | ||
1025 | |||
1026 | /* spdif_in_sync */ | ||
1027 | clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, | ||
1028 | 24000000); | ||
1029 | clk_register_clkdev(clk, "spdif_in_sync", NULL); | ||
1030 | clks[spdif_in_sync] = clk; | ||
1031 | |||
1032 | /* i2s0_sync */ | ||
1033 | clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); | ||
1034 | clk_register_clkdev(clk, "i2s0_sync", NULL); | ||
1035 | clks[i2s0_sync] = clk; | ||
1036 | |||
1037 | /* i2s1_sync */ | ||
1038 | clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); | ||
1039 | clk_register_clkdev(clk, "i2s1_sync", NULL); | ||
1040 | clks[i2s1_sync] = clk; | ||
1041 | |||
1042 | /* i2s2_sync */ | ||
1043 | clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); | ||
1044 | clk_register_clkdev(clk, "i2s2_sync", NULL); | ||
1045 | clks[i2s2_sync] = clk; | ||
1046 | |||
1047 | /* i2s3_sync */ | ||
1048 | clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); | ||
1049 | clk_register_clkdev(clk, "i2s3_sync", NULL); | ||
1050 | clks[i2s3_sync] = clk; | ||
1051 | |||
1052 | /* i2s4_sync */ | ||
1053 | clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); | ||
1054 | clk_register_clkdev(clk, "i2s4_sync", NULL); | ||
1055 | clks[i2s4_sync] = clk; | ||
1056 | |||
1057 | /* vimclk_sync */ | ||
1058 | clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); | ||
1059 | clk_register_clkdev(clk, "vimclk_sync", NULL); | ||
1060 | clks[vimclk_sync] = clk; | ||
1061 | |||
1062 | /* audio0 */ | ||
1063 | clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, | ||
1064 | ARRAY_SIZE(mux_audio_sync_clk), 0, | ||
1065 | clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, NULL); | ||
1066 | clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, | ||
1067 | clk_base + AUDIO_SYNC_CLK_I2S0, 4, | ||
1068 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1069 | clk_register_clkdev(clk, "audio0", NULL); | ||
1070 | clks[audio0] = clk; | ||
1071 | |||
1072 | /* audio1 */ | ||
1073 | clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, | ||
1074 | ARRAY_SIZE(mux_audio_sync_clk), 0, | ||
1075 | clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, NULL); | ||
1076 | clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, | ||
1077 | clk_base + AUDIO_SYNC_CLK_I2S1, 4, | ||
1078 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1079 | clk_register_clkdev(clk, "audio1", NULL); | ||
1080 | clks[audio1] = clk; | ||
1081 | |||
1082 | /* audio2 */ | ||
1083 | clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, | ||
1084 | ARRAY_SIZE(mux_audio_sync_clk), 0, | ||
1085 | clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, NULL); | ||
1086 | clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, | ||
1087 | clk_base + AUDIO_SYNC_CLK_I2S2, 4, | ||
1088 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1089 | clk_register_clkdev(clk, "audio2", NULL); | ||
1090 | clks[audio2] = clk; | ||
1091 | |||
1092 | /* audio3 */ | ||
1093 | clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, | ||
1094 | ARRAY_SIZE(mux_audio_sync_clk), 0, | ||
1095 | clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, NULL); | ||
1096 | clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, | ||
1097 | clk_base + AUDIO_SYNC_CLK_I2S3, 4, | ||
1098 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1099 | clk_register_clkdev(clk, "audio3", NULL); | ||
1100 | clks[audio3] = clk; | ||
1101 | |||
1102 | /* audio4 */ | ||
1103 | clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, | ||
1104 | ARRAY_SIZE(mux_audio_sync_clk), 0, | ||
1105 | clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, NULL); | ||
1106 | clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, | ||
1107 | clk_base + AUDIO_SYNC_CLK_I2S4, 4, | ||
1108 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1109 | clk_register_clkdev(clk, "audio4", NULL); | ||
1110 | clks[audio4] = clk; | ||
1111 | |||
1112 | /* spdif */ | ||
1113 | clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, | ||
1114 | ARRAY_SIZE(mux_audio_sync_clk), 0, | ||
1115 | clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, NULL); | ||
1116 | clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, | ||
1117 | clk_base + AUDIO_SYNC_CLK_SPDIF, 4, | ||
1118 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1119 | clk_register_clkdev(clk, "spdif", NULL); | ||
1120 | clks[spdif] = clk; | ||
1121 | |||
1122 | /* audio0_2x */ | ||
1123 | clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", | ||
1124 | CLK_SET_RATE_PARENT, 2, 1); | ||
1125 | clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", | ||
1126 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, 0, | ||
1127 | &clk_doubler_lock); | ||
1128 | clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", | ||
1129 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1130 | CLK_SET_RATE_PARENT, 113, &periph_v_regs, | ||
1131 | periph_clk_enb_refcnt); | ||
1132 | clk_register_clkdev(clk, "audio0_2x", NULL); | ||
1133 | clks[audio0_2x] = clk; | ||
1134 | |||
1135 | /* audio1_2x */ | ||
1136 | clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", | ||
1137 | CLK_SET_RATE_PARENT, 2, 1); | ||
1138 | clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", | ||
1139 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, 0, | ||
1140 | &clk_doubler_lock); | ||
1141 | clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", | ||
1142 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1143 | CLK_SET_RATE_PARENT, 114, &periph_v_regs, | ||
1144 | periph_clk_enb_refcnt); | ||
1145 | clk_register_clkdev(clk, "audio1_2x", NULL); | ||
1146 | clks[audio1_2x] = clk; | ||
1147 | |||
1148 | /* audio2_2x */ | ||
1149 | clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", | ||
1150 | CLK_SET_RATE_PARENT, 2, 1); | ||
1151 | clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", | ||
1152 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, 0, | ||
1153 | &clk_doubler_lock); | ||
1154 | clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", | ||
1155 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1156 | CLK_SET_RATE_PARENT, 115, &periph_v_regs, | ||
1157 | periph_clk_enb_refcnt); | ||
1158 | clk_register_clkdev(clk, "audio2_2x", NULL); | ||
1159 | clks[audio2_2x] = clk; | ||
1160 | |||
1161 | /* audio3_2x */ | ||
1162 | clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", | ||
1163 | CLK_SET_RATE_PARENT, 2, 1); | ||
1164 | clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", | ||
1165 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, 0, | ||
1166 | &clk_doubler_lock); | ||
1167 | clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", | ||
1168 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1169 | CLK_SET_RATE_PARENT, 116, &periph_v_regs, | ||
1170 | periph_clk_enb_refcnt); | ||
1171 | clk_register_clkdev(clk, "audio3_2x", NULL); | ||
1172 | clks[audio3_2x] = clk; | ||
1173 | |||
1174 | /* audio4_2x */ | ||
1175 | clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", | ||
1176 | CLK_SET_RATE_PARENT, 2, 1); | ||
1177 | clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", | ||
1178 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, 0, | ||
1179 | &clk_doubler_lock); | ||
1180 | clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", | ||
1181 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1182 | CLK_SET_RATE_PARENT, 117, &periph_v_regs, | ||
1183 | periph_clk_enb_refcnt); | ||
1184 | clk_register_clkdev(clk, "audio4_2x", NULL); | ||
1185 | clks[audio4_2x] = clk; | ||
1186 | |||
1187 | /* spdif_2x */ | ||
1188 | clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", | ||
1189 | CLK_SET_RATE_PARENT, 2, 1); | ||
1190 | clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", | ||
1191 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, 0, | ||
1192 | &clk_doubler_lock); | ||
1193 | clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", | ||
1194 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1195 | CLK_SET_RATE_PARENT, 118, &periph_v_regs, | ||
1196 | periph_clk_enb_refcnt); | ||
1197 | clk_register_clkdev(clk, "spdif_2x", NULL); | ||
1198 | clks[spdif_2x] = clk; | ||
1199 | } | ||
1200 | |||
1201 | static void __init tegra30_pmc_clk_init(void) | ||
1202 | { | ||
1203 | struct clk *clk; | ||
1204 | |||
1205 | /* clk_out_1 */ | ||
1206 | clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, | ||
1207 | ARRAY_SIZE(clk_out1_parents), 0, | ||
1208 | pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, | ||
1209 | &clk_out_lock); | ||
1210 | clks[clk_out_1_mux] = clk; | ||
1211 | clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, | ||
1212 | pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, | ||
1213 | &clk_out_lock); | ||
1214 | clk_register_clkdev(clk, "extern1", "clk_out_1"); | ||
1215 | clks[clk_out_1] = clk; | ||
1216 | |||
1217 | /* clk_out_2 */ | ||
1218 | clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, | ||
1219 | ARRAY_SIZE(clk_out1_parents), 0, | ||
1220 | pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, | ||
1221 | &clk_out_lock); | ||
1222 | clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, | ||
1223 | pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, | ||
1224 | &clk_out_lock); | ||
1225 | clk_register_clkdev(clk, "extern2", "clk_out_2"); | ||
1226 | clks[clk_out_2] = clk; | ||
1227 | |||
1228 | /* clk_out_3 */ | ||
1229 | clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, | ||
1230 | ARRAY_SIZE(clk_out1_parents), 0, | ||
1231 | pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, | ||
1232 | &clk_out_lock); | ||
1233 | clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, | ||
1234 | pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, | ||
1235 | &clk_out_lock); | ||
1236 | clk_register_clkdev(clk, "extern3", "clk_out_3"); | ||
1237 | clks[clk_out_3] = clk; | ||
1238 | |||
1239 | /* blink */ | ||
1240 | writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); | ||
1241 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, | ||
1242 | pmc_base + PMC_DPD_PADS_ORIDE, | ||
1243 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); | ||
1244 | clk = clk_register_gate(NULL, "blink", "blink_override", 0, | ||
1245 | pmc_base + PMC_CTRL, | ||
1246 | PMC_CTRL_BLINK_ENB, 0, NULL); | ||
1247 | clk_register_clkdev(clk, "blink", NULL); | ||
1248 | clks[blink] = clk; | ||
1249 | |||
1250 | } | ||
1251 | |||
1252 | const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | ||
1253 | "pll_p_cclkg", "pll_p_out4_cclkg", | ||
1254 | "pll_p_out3_cclkg", "unused", "pll_x" }; | ||
1255 | const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | ||
1256 | "pll_p_cclklp", "pll_p_out4_cclklp", | ||
1257 | "pll_p_out3_cclklp", "unused", "pll_x", | ||
1258 | "pll_x_out0" }; | ||
1259 | const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", | ||
1260 | "pll_p_out3", "pll_p_out2", "unused", | ||
1261 | "clk_32k", "pll_m_out1" }; | ||
1262 | |||
1263 | static void __init tegra30_super_clk_init(void) | ||
1264 | { | ||
1265 | struct clk *clk; | ||
1266 | |||
1267 | /* | ||
1268 | * Clock input to cclk_g divided from pll_p using | ||
1269 | * U71 divider of cclk_g. | ||
1270 | */ | ||
1271 | clk = tegra_clk_register_divider("pll_p_cclkg", "pll_p", | ||
1272 | clk_base + SUPER_CCLKG_DIVIDER, 0, | ||
1273 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
1274 | clk_register_clkdev(clk, "pll_p_cclkg", NULL); | ||
1275 | |||
1276 | /* | ||
1277 | * Clock input to cclk_g divided from pll_p_out3 using | ||
1278 | * U71 divider of cclk_g. | ||
1279 | */ | ||
1280 | clk = tegra_clk_register_divider("pll_p_out3_cclkg", "pll_p_out3", | ||
1281 | clk_base + SUPER_CCLKG_DIVIDER, 0, | ||
1282 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
1283 | clk_register_clkdev(clk, "pll_p_out3_cclkg", NULL); | ||
1284 | |||
1285 | /* | ||
1286 | * Clock input to cclk_g divided from pll_p_out4 using | ||
1287 | * U71 divider of cclk_g. | ||
1288 | */ | ||
1289 | clk = tegra_clk_register_divider("pll_p_out4_cclkg", "pll_p_out4", | ||
1290 | clk_base + SUPER_CCLKG_DIVIDER, 0, | ||
1291 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
1292 | clk_register_clkdev(clk, "pll_p_out4_cclkg", NULL); | ||
1293 | |||
1294 | /* CCLKG */ | ||
1295 | clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, | ||
1296 | ARRAY_SIZE(cclk_g_parents), | ||
1297 | CLK_SET_RATE_PARENT, | ||
1298 | clk_base + CCLKG_BURST_POLICY, | ||
1299 | 0, 4, 0, 0, NULL); | ||
1300 | clk_register_clkdev(clk, "cclk_g", NULL); | ||
1301 | clks[cclk_g] = clk; | ||
1302 | |||
1303 | /* | ||
1304 | * Clock input to cclk_lp divided from pll_p using | ||
1305 | * U71 divider of cclk_lp. | ||
1306 | */ | ||
1307 | clk = tegra_clk_register_divider("pll_p_cclklp", "pll_p", | ||
1308 | clk_base + SUPER_CCLKLP_DIVIDER, 0, | ||
1309 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
1310 | clk_register_clkdev(clk, "pll_p_cclklp", NULL); | ||
1311 | |||
1312 | /* | ||
1313 | * Clock input to cclk_lp divided from pll_p_out3 using | ||
1314 | * U71 divider of cclk_lp. | ||
1315 | */ | ||
1316 | clk = tegra_clk_register_divider("pll_p_out3_cclklp", "pll_p_out3", | ||
1317 | clk_base + SUPER_CCLKG_DIVIDER, 0, | ||
1318 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
1319 | clk_register_clkdev(clk, "pll_p_out3_cclklp", NULL); | ||
1320 | |||
1321 | /* | ||
1322 | * Clock input to cclk_lp divided from pll_p_out4 using | ||
1323 | * U71 divider of cclk_lp. | ||
1324 | */ | ||
1325 | clk = tegra_clk_register_divider("pll_p_out4_cclklp", "pll_p_out4", | ||
1326 | clk_base + SUPER_CCLKLP_DIVIDER, 0, | ||
1327 | TEGRA_DIVIDER_INT, 16, 8, 1, NULL); | ||
1328 | clk_register_clkdev(clk, "pll_p_out4_cclklp", NULL); | ||
1329 | |||
1330 | /* CCLKLP */ | ||
1331 | clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, | ||
1332 | ARRAY_SIZE(cclk_lp_parents), | ||
1333 | CLK_SET_RATE_PARENT, | ||
1334 | clk_base + CCLKLP_BURST_POLICY, | ||
1335 | TEGRA_DIVIDER_2, 4, 8, 9, | ||
1336 | NULL); | ||
1337 | clk_register_clkdev(clk, "cclk_lp", NULL); | ||
1338 | clks[cclk_lp] = clk; | ||
1339 | |||
1340 | /* SCLK */ | ||
1341 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, | ||
1342 | ARRAY_SIZE(sclk_parents), | ||
1343 | CLK_SET_RATE_PARENT, | ||
1344 | clk_base + SCLK_BURST_POLICY, | ||
1345 | 0, 4, 0, 0, NULL); | ||
1346 | clk_register_clkdev(clk, "sclk", NULL); | ||
1347 | clks[sclk] = clk; | ||
1348 | |||
1349 | /* HCLK */ | ||
1350 | clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, | ||
1351 | clk_base + SYSTEM_CLK_RATE, 4, 2, 0, NULL); | ||
1352 | clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, | ||
1353 | clk_base + SYSTEM_CLK_RATE, 7, | ||
1354 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1355 | clk_register_clkdev(clk, "hclk", NULL); | ||
1356 | clks[hclk] = clk; | ||
1357 | |||
1358 | /* PCLK */ | ||
1359 | clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, | ||
1360 | clk_base + SYSTEM_CLK_RATE, 0, 2, 0, NULL); | ||
1361 | clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, | ||
1362 | clk_base + SYSTEM_CLK_RATE, 3, | ||
1363 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1364 | clk_register_clkdev(clk, "pclk", NULL); | ||
1365 | clks[pclk] = clk; | ||
1366 | |||
1367 | /* twd */ | ||
1368 | clk = clk_register_fixed_factor(NULL, "twd", "cclk_g", | ||
1369 | CLK_SET_RATE_PARENT, 1, 2); | ||
1370 | clk_register_clkdev(clk, "twd", NULL); | ||
1371 | clks[twd] = clk; | ||
1372 | } | ||
1373 | |||
1374 | static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", | ||
1375 | "clk_m" }; | ||
1376 | static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; | ||
1377 | static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; | ||
1378 | static const char *i2s0_parents[] = { "pll_a_out0", "audio0_2x", "pll_p", | ||
1379 | "clk_m" }; | ||
1380 | static const char *i2s1_parents[] = { "pll_a_out0", "audio1_2x", "pll_p", | ||
1381 | "clk_m" }; | ||
1382 | static const char *i2s2_parents[] = { "pll_a_out0", "audio2_2x", "pll_p", | ||
1383 | "clk_m" }; | ||
1384 | static const char *i2s3_parents[] = { "pll_a_out0", "audio3_2x", "pll_p", | ||
1385 | "clk_m" }; | ||
1386 | static const char *i2s4_parents[] = { "pll_a_out0", "audio4_2x", "pll_p", | ||
1387 | "clk_m" }; | ||
1388 | static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", | ||
1389 | "clk_m" }; | ||
1390 | static const char *spdif_in_parents[] = { "pll_p", "pll_c", "pll_m" }; | ||
1391 | static const char *mux_pllpc_clk32k_clkm[] = { "pll_p", "pll_c", "clk_32k", | ||
1392 | "clk_m" }; | ||
1393 | static const char *mux_pllpc_clkm_clk32k[] = { "pll_p", "pll_c", "clk_m", | ||
1394 | "clk_32k" }; | ||
1395 | static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; | ||
1396 | static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", | ||
1397 | "clk_m" }; | ||
1398 | static const char *mux_pllp_clkm[] = { "pll_p", "unused", "unused", "clk_m" }; | ||
1399 | static const char *mux_pllpmdacd2_clkm[] = { "pll_p", "pll_m", "pll_d_out0", | ||
1400 | "pll_a_out0", "pll_c", | ||
1401 | "pll_d2_out0", "clk_m" }; | ||
1402 | static const char *mux_plla_clk32k_pllp_clkm_plle[] = { "pll_a_out0", | ||
1403 | "clk_32k", "pll_p", | ||
1404 | "clk_m", "pll_e" }; | ||
1405 | static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", | ||
1406 | "pll_d2_out0" }; | ||
1407 | |||
1408 | static struct tegra_periph_init_data tegra_periph_clk_list[] = { | ||
1409 | TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", i2s0_parents, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), | ||
1410 | TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), | ||
1411 | TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), | ||
1412 | TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", i2s3_parents, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), | ||
1413 | TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", i2s4_parents, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), | ||
1414 | TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), | ||
1415 | TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), | ||
1416 | TEGRA_INIT_DATA_MUX("d_audio", "d_audio", "tegra30-ahub", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, 0, d_audio), | ||
1417 | TEGRA_INIT_DATA_MUX("dam0", NULL, "tegra30-dam.0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, &periph_v_regs, 0, dam0), | ||
1418 | TEGRA_INIT_DATA_MUX("dam1", NULL, "tegra30-dam.1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, &periph_v_regs, 0, dam1), | ||
1419 | TEGRA_INIT_DATA_MUX("dam2", NULL, "tegra30-dam.2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, &periph_v_regs, 0, dam2), | ||
1420 | TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, 0, hda), | ||
1421 | TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, 0, hda2codec_2x), | ||
1422 | TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), | ||
1423 | TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), | ||
1424 | TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), | ||
1425 | TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), | ||
1426 | TEGRA_INIT_DATA_MUX("sbc5", NULL, "spi_tegra.4", mux_pllpcm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), | ||
1427 | TEGRA_INIT_DATA_MUX("sbc6", NULL, "spi_tegra.5", mux_pllpcm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), | ||
1428 | TEGRA_INIT_DATA_MUX("sata_oob", NULL, "tegra_sata_oob", mux_pllpcm_clkm, CLK_SOURCE_SATA_OOB, 123, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata_oob), | ||
1429 | TEGRA_INIT_DATA_MUX("sata", NULL, "tegra_sata", mux_pllpcm_clkm, CLK_SOURCE_SATA, 124, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata), | ||
1430 | TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, TEGRA_PERIPH_ON_APB, ndflash), | ||
1431 | TEGRA_INIT_DATA_MUX("ndspeed", NULL, "tegra_nand_speed", mux_pllpcm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), | ||
1432 | TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), | ||
1433 | TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite), | ||
1434 | TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), | ||
1435 | TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), | ||
1436 | TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), | ||
1437 | TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllpc_clkm_clk32k, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), | ||
1438 | TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllpc_clk32k_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), | ||
1439 | TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), | ||
1440 | TEGRA_INIT_DATA_INT("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), | ||
1441 | TEGRA_INIT_DATA_INT("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), | ||
1442 | TEGRA_INIT_DATA_INT("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), | ||
1443 | TEGRA_INIT_DATA_INT("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), | ||
1444 | TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), | ||
1445 | TEGRA_INIT_DATA_INT("3d2", NULL, "3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, &periph_v_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d2), | ||
1446 | TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), | ||
1447 | TEGRA_INIT_DATA_INT("se", NULL, "se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, 0, se), | ||
1448 | TEGRA_INIT_DATA_MUX("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect), | ||
1449 | TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), | ||
1450 | TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), | ||
1451 | TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), | ||
1452 | TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), | ||
1453 | TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), | ||
1454 | TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), | ||
1455 | TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), | ||
1456 | TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), | ||
1457 | TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllpc_clk32k_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), | ||
1458 | TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), | ||
1459 | TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), | ||
1460 | TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), | ||
1461 | TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), | ||
1462 | TEGRA_INIT_DATA_DIV16("i2c4", "div-clk", "tegra-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2c4), | ||
1463 | TEGRA_INIT_DATA_DIV16("i2c5", "div-clk", "tegra-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c5), | ||
1464 | TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), | ||
1465 | TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), | ||
1466 | TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), | ||
1467 | TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), | ||
1468 | TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 66, &periph_u_regs, uarte), | ||
1469 | TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), | ||
1470 | TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), | ||
1471 | TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), | ||
1472 | TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), | ||
1473 | TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, 0, pwm), | ||
1474 | }; | ||
1475 | |||
1476 | static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { | ||
1477 | TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, &periph_l_regs, 0, disp1), | ||
1478 | TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, &periph_l_regs, 0, disp2), | ||
1479 | TEGRA_INIT_DATA_NODIV("dsib", NULL, "tegradc.1", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, &periph_u_regs, 0, dsib), | ||
1480 | }; | ||
1481 | |||
1482 | static void __init tegra30_periph_clk_init(void) | ||
1483 | { | ||
1484 | struct tegra_periph_init_data *data; | ||
1485 | struct clk *clk; | ||
1486 | int i; | ||
1487 | |||
1488 | /* apbdma */ | ||
1489 | clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, 0, 34, | ||
1490 | &periph_h_regs, periph_clk_enb_refcnt); | ||
1491 | clk_register_clkdev(clk, NULL, "tegra-apbdma"); | ||
1492 | clks[apbdma] = clk; | ||
1493 | |||
1494 | /* rtc */ | ||
1495 | clk = tegra_clk_register_periph_gate("rtc", "clk_32k", | ||
1496 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
1497 | clk_base, 0, 4, &periph_l_regs, | ||
1498 | periph_clk_enb_refcnt); | ||
1499 | clk_register_clkdev(clk, NULL, "rtc-tegra"); | ||
1500 | clks[rtc] = clk; | ||
1501 | |||
1502 | /* timer */ | ||
1503 | clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0, | ||
1504 | 5, &periph_l_regs, periph_clk_enb_refcnt); | ||
1505 | clk_register_clkdev(clk, NULL, "timer"); | ||
1506 | clks[timer] = clk; | ||
1507 | |||
1508 | /* kbc */ | ||
1509 | clk = tegra_clk_register_periph_gate("kbc", "clk_32k", | ||
1510 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
1511 | clk_base, 0, 36, &periph_h_regs, | ||
1512 | periph_clk_enb_refcnt); | ||
1513 | clk_register_clkdev(clk, NULL, "tegra-kbc"); | ||
1514 | clks[kbc] = clk; | ||
1515 | |||
1516 | /* csus */ | ||
1517 | clk = tegra_clk_register_periph_gate("csus", "clk_m", | ||
1518 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
1519 | clk_base, 0, 92, &periph_u_regs, | ||
1520 | periph_clk_enb_refcnt); | ||
1521 | clk_register_clkdev(clk, "csus", "tengra_camera"); | ||
1522 | clks[csus] = clk; | ||
1523 | |||
1524 | /* vcp */ | ||
1525 | clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, 29, | ||
1526 | &periph_l_regs, periph_clk_enb_refcnt); | ||
1527 | clk_register_clkdev(clk, "vcp", "tegra-avp"); | ||
1528 | clks[vcp] = clk; | ||
1529 | |||
1530 | /* bsea */ | ||
1531 | clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, 0, | ||
1532 | 62, &periph_h_regs, periph_clk_enb_refcnt); | ||
1533 | clk_register_clkdev(clk, "bsea", "tegra-avp"); | ||
1534 | clks[bsea] = clk; | ||
1535 | |||
1536 | /* bsev */ | ||
1537 | clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, 0, | ||
1538 | 63, &periph_h_regs, periph_clk_enb_refcnt); | ||
1539 | clk_register_clkdev(clk, "bsev", "tegra-aes"); | ||
1540 | clks[bsev] = clk; | ||
1541 | |||
1542 | /* usbd */ | ||
1543 | clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, | ||
1544 | 22, &periph_l_regs, periph_clk_enb_refcnt); | ||
1545 | clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); | ||
1546 | clks[usbd] = clk; | ||
1547 | |||
1548 | /* usb2 */ | ||
1549 | clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, | ||
1550 | 58, &periph_h_regs, periph_clk_enb_refcnt); | ||
1551 | clk_register_clkdev(clk, NULL, "tegra-ehci.1"); | ||
1552 | clks[usb2] = clk; | ||
1553 | |||
1554 | /* usb3 */ | ||
1555 | clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, | ||
1556 | 59, &periph_h_regs, periph_clk_enb_refcnt); | ||
1557 | clk_register_clkdev(clk, NULL, "tegra-ehci.2"); | ||
1558 | clks[usb3] = clk; | ||
1559 | |||
1560 | /* dsia */ | ||
1561 | clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base, | ||
1562 | 0, 48, &periph_h_regs, | ||
1563 | periph_clk_enb_refcnt); | ||
1564 | clk_register_clkdev(clk, "dsia", "tegradc.0"); | ||
1565 | clks[dsia] = clk; | ||
1566 | |||
1567 | /* csi */ | ||
1568 | clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, | ||
1569 | 0, 52, &periph_h_regs, | ||
1570 | periph_clk_enb_refcnt); | ||
1571 | clk_register_clkdev(clk, "csi", "tegra_camera"); | ||
1572 | clks[csi] = clk; | ||
1573 | |||
1574 | /* isp */ | ||
1575 | clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, | ||
1576 | &periph_l_regs, periph_clk_enb_refcnt); | ||
1577 | clk_register_clkdev(clk, "isp", "tegra_camera"); | ||
1578 | clks[isp] = clk; | ||
1579 | |||
1580 | /* pcie */ | ||
1581 | clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, | ||
1582 | 70, &periph_u_regs, periph_clk_enb_refcnt); | ||
1583 | clk_register_clkdev(clk, "pcie", "tegra-pcie"); | ||
1584 | clks[pcie] = clk; | ||
1585 | |||
1586 | /* afi */ | ||
1587 | clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, | ||
1588 | &periph_u_regs, periph_clk_enb_refcnt); | ||
1589 | clk_register_clkdev(clk, "afi", "tegra-pcie"); | ||
1590 | clks[afi] = clk; | ||
1591 | |||
1592 | /* kfuse */ | ||
1593 | clk = tegra_clk_register_periph_gate("kfuse", "clk_m", | ||
1594 | TEGRA_PERIPH_ON_APB, | ||
1595 | clk_base, 0, 40, &periph_h_regs, | ||
1596 | periph_clk_enb_refcnt); | ||
1597 | clk_register_clkdev(clk, NULL, "kfuse-tegra"); | ||
1598 | clks[kfuse] = clk; | ||
1599 | |||
1600 | /* fuse */ | ||
1601 | clk = tegra_clk_register_periph_gate("fuse", "clk_m", | ||
1602 | TEGRA_PERIPH_ON_APB, | ||
1603 | clk_base, 0, 39, &periph_h_regs, | ||
1604 | periph_clk_enb_refcnt); | ||
1605 | clk_register_clkdev(clk, "fuse", "fuse-tegra"); | ||
1606 | clks[fuse] = clk; | ||
1607 | |||
1608 | /* fuse_burn */ | ||
1609 | clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", | ||
1610 | TEGRA_PERIPH_ON_APB, | ||
1611 | clk_base, 0, 39, &periph_h_regs, | ||
1612 | periph_clk_enb_refcnt); | ||
1613 | clk_register_clkdev(clk, "fuse_burn", "fuse-tegra"); | ||
1614 | clks[fuse_burn] = clk; | ||
1615 | |||
1616 | /* apbif */ | ||
1617 | clk = tegra_clk_register_periph_gate("apbif", "clk_m", 0, | ||
1618 | clk_base, 0, 107, &periph_v_regs, | ||
1619 | periph_clk_enb_refcnt); | ||
1620 | clk_register_clkdev(clk, "apbif", "tegra30-ahub"); | ||
1621 | clks[apbif] = clk; | ||
1622 | |||
1623 | /* hda2hdmi */ | ||
1624 | clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", | ||
1625 | TEGRA_PERIPH_ON_APB, | ||
1626 | clk_base, 0, 128, &periph_w_regs, | ||
1627 | periph_clk_enb_refcnt); | ||
1628 | clk_register_clkdev(clk, "hda2hdmi", "tegra30-hda"); | ||
1629 | clks[hda2hdmi] = clk; | ||
1630 | |||
1631 | /* sata_cold */ | ||
1632 | clk = tegra_clk_register_periph_gate("sata_cold", "clk_m", | ||
1633 | TEGRA_PERIPH_ON_APB, | ||
1634 | clk_base, 0, 129, &periph_w_regs, | ||
1635 | periph_clk_enb_refcnt); | ||
1636 | clk_register_clkdev(clk, NULL, "tegra_sata_cold"); | ||
1637 | clks[sata_cold] = clk; | ||
1638 | |||
1639 | /* dtv */ | ||
1640 | clk = tegra_clk_register_periph_gate("dtv", "clk_m", | ||
1641 | TEGRA_PERIPH_ON_APB, | ||
1642 | clk_base, 0, 79, &periph_u_regs, | ||
1643 | periph_clk_enb_refcnt); | ||
1644 | clk_register_clkdev(clk, NULL, "dtv"); | ||
1645 | clks[dtv] = clk; | ||
1646 | |||
1647 | /* emc */ | ||
1648 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, | ||
1649 | ARRAY_SIZE(mux_pllmcp_clkm), 0, | ||
1650 | clk_base + CLK_SOURCE_EMC, | ||
1651 | 30, 2, 0, NULL); | ||
1652 | clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, | ||
1653 | 57, &periph_h_regs, periph_clk_enb_refcnt); | ||
1654 | clk_register_clkdev(clk, "emc", NULL); | ||
1655 | clks[emc] = clk; | ||
1656 | |||
1657 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { | ||
1658 | data = &tegra_periph_clk_list[i]; | ||
1659 | clk = tegra_clk_register_periph(data->name, data->parent_names, | ||
1660 | data->num_parents, &data->periph, | ||
1661 | clk_base, data->offset); | ||
1662 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1663 | clks[data->clk_id] = clk; | ||
1664 | } | ||
1665 | |||
1666 | for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { | ||
1667 | data = &tegra_periph_nodiv_clk_list[i]; | ||
1668 | clk = tegra_clk_register_periph_nodiv(data->name, | ||
1669 | data->parent_names, | ||
1670 | data->num_parents, &data->periph, | ||
1671 | clk_base, data->offset); | ||
1672 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1673 | clks[data->clk_id] = clk; | ||
1674 | } | ||
1675 | } | ||
1676 | |||
1677 | static void __init tegra30_fixed_clk_init(void) | ||
1678 | { | ||
1679 | struct clk *clk; | ||
1680 | |||
1681 | /* clk_32k */ | ||
1682 | clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, | ||
1683 | 32768); | ||
1684 | clk_register_clkdev(clk, "clk_32k", NULL); | ||
1685 | clks[clk_32k] = clk; | ||
1686 | |||
1687 | /* clk_m_div2 */ | ||
1688 | clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", | ||
1689 | CLK_SET_RATE_PARENT, 1, 2); | ||
1690 | clk_register_clkdev(clk, "clk_m_div2", NULL); | ||
1691 | clks[clk_m_div2] = clk; | ||
1692 | |||
1693 | /* clk_m_div4 */ | ||
1694 | clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", | ||
1695 | CLK_SET_RATE_PARENT, 1, 4); | ||
1696 | clk_register_clkdev(clk, "clk_m_div4", NULL); | ||
1697 | clks[clk_m_div4] = clk; | ||
1698 | |||
1699 | /* cml0 */ | ||
1700 | clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, | ||
1701 | 0, 0, &cml_lock); | ||
1702 | clk_register_clkdev(clk, "cml0", NULL); | ||
1703 | clks[cml0] = clk; | ||
1704 | |||
1705 | /* cml1 */ | ||
1706 | clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, | ||
1707 | 1, 0, &cml_lock); | ||
1708 | clk_register_clkdev(clk, "cml1", NULL); | ||
1709 | clks[cml1] = clk; | ||
1710 | |||
1711 | /* pciex */ | ||
1712 | clk = clk_register_fixed_rate(NULL, "pciex", "pll_e", 0, 100000000); | ||
1713 | clk_register_clkdev(clk, "pciex", NULL); | ||
1714 | clks[pciex] = clk; | ||
1715 | } | ||
1716 | |||
1717 | static void __init tegra30_osc_clk_init(void) | ||
1718 | { | ||
1719 | struct clk *clk; | ||
1720 | unsigned int pll_ref_div; | ||
1721 | |||
1722 | tegra30_clk_measure_input_freq(); | ||
1723 | |||
1724 | /* clk_m */ | ||
1725 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, | ||
1726 | input_freq); | ||
1727 | clk_register_clkdev(clk, "clk_m", NULL); | ||
1728 | clks[clk_m] = clk; | ||
1729 | |||
1730 | /* pll_ref */ | ||
1731 | pll_ref_div = tegra30_get_pll_ref_div(); | ||
1732 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", | ||
1733 | CLK_SET_RATE_PARENT, 1, pll_ref_div); | ||
1734 | clk_register_clkdev(clk, "pll_ref", NULL); | ||
1735 | clks[pll_ref] = clk; | ||
1736 | } | ||
1737 | |||
1738 | /* Tegra30 CPU clock and reset control functions */ | ||
1739 | static void tegra30_wait_cpu_in_reset(u32 cpu) | ||
1740 | { | ||
1741 | unsigned int reg; | ||
1742 | |||
1743 | do { | ||
1744 | reg = readl(clk_base + | ||
1745 | TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); | ||
1746 | cpu_relax(); | ||
1747 | } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ | ||
1748 | |||
1749 | return; | ||
1750 | } | ||
1751 | |||
1752 | static void tegra30_put_cpu_in_reset(u32 cpu) | ||
1753 | { | ||
1754 | writel(CPU_RESET(cpu), | ||
1755 | clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
1756 | dmb(); | ||
1757 | } | ||
1758 | |||
1759 | static void tegra30_cpu_out_of_reset(u32 cpu) | ||
1760 | { | ||
1761 | writel(CPU_RESET(cpu), | ||
1762 | clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); | ||
1763 | wmb(); | ||
1764 | } | ||
1765 | |||
1766 | |||
1767 | static void tegra30_enable_cpu_clock(u32 cpu) | ||
1768 | { | ||
1769 | unsigned int reg; | ||
1770 | |||
1771 | writel(CPU_CLOCK(cpu), | ||
1772 | clk_base + TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); | ||
1773 | reg = readl(clk_base + | ||
1774 | TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); | ||
1775 | } | ||
1776 | |||
1777 | static void tegra30_disable_cpu_clock(u32 cpu) | ||
1778 | { | ||
1779 | |||
1780 | unsigned int reg; | ||
1781 | |||
1782 | reg = readl(clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1783 | writel(reg | CPU_CLOCK(cpu), | ||
1784 | clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
1785 | } | ||
1786 | |||
1787 | #ifdef CONFIG_PM_SLEEP | ||
1788 | static bool tegra30_cpu_rail_off_ready(void) | ||
1789 | { | ||
1790 | unsigned int cpu_rst_status; | ||
1791 | int cpu_pwr_status; | ||
1792 | |||
1793 | cpu_rst_status = readl(clk_base + | ||
1794 | TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); | ||
1795 | cpu_pwr_status = tegra_powergate_is_powered(TEGRA_POWERGATE_CPU1) || | ||
1796 | tegra_powergate_is_powered(TEGRA_POWERGATE_CPU2) || | ||
1797 | tegra_powergate_is_powered(TEGRA_POWERGATE_CPU3); | ||
1798 | |||
1799 | if (((cpu_rst_status & 0xE) != 0xE) || cpu_pwr_status) | ||
1800 | return false; | ||
1801 | |||
1802 | return true; | ||
1803 | } | ||
1804 | |||
1805 | static void tegra30_cpu_clock_suspend(void) | ||
1806 | { | ||
1807 | /* switch coresite to clk_m, save off original source */ | ||
1808 | tegra30_cpu_clk_sctx.clk_csite_src = | ||
1809 | readl(clk_base + CLK_RESET_SOURCE_CSITE); | ||
1810 | writel(3<<30, clk_base + CLK_RESET_SOURCE_CSITE); | ||
1811 | |||
1812 | tegra30_cpu_clk_sctx.cpu_burst = | ||
1813 | readl(clk_base + CLK_RESET_CCLK_BURST); | ||
1814 | tegra30_cpu_clk_sctx.pllx_base = | ||
1815 | readl(clk_base + CLK_RESET_PLLX_BASE); | ||
1816 | tegra30_cpu_clk_sctx.pllx_misc = | ||
1817 | readl(clk_base + CLK_RESET_PLLX_MISC); | ||
1818 | tegra30_cpu_clk_sctx.cclk_divider = | ||
1819 | readl(clk_base + CLK_RESET_CCLK_DIVIDER); | ||
1820 | } | ||
1821 | |||
1822 | static void tegra30_cpu_clock_resume(void) | ||
1823 | { | ||
1824 | unsigned int reg, policy; | ||
1825 | |||
1826 | /* Is CPU complex already running on PLLX? */ | ||
1827 | reg = readl(clk_base + CLK_RESET_CCLK_BURST); | ||
1828 | policy = (reg >> CLK_RESET_CCLK_BURST_POLICY_SHIFT) & 0xF; | ||
1829 | |||
1830 | if (policy == CLK_RESET_CCLK_IDLE_POLICY) | ||
1831 | reg = (reg >> CLK_RESET_CCLK_IDLE_POLICY_SHIFT) & 0xF; | ||
1832 | else if (policy == CLK_RESET_CCLK_RUN_POLICY) | ||
1833 | reg = (reg >> CLK_RESET_CCLK_RUN_POLICY_SHIFT) & 0xF; | ||
1834 | else | ||
1835 | BUG(); | ||
1836 | |||
1837 | if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) { | ||
1838 | /* restore PLLX settings if CPU is on different PLL */ | ||
1839 | writel(tegra30_cpu_clk_sctx.pllx_misc, | ||
1840 | clk_base + CLK_RESET_PLLX_MISC); | ||
1841 | writel(tegra30_cpu_clk_sctx.pllx_base, | ||
1842 | clk_base + CLK_RESET_PLLX_BASE); | ||
1843 | |||
1844 | /* wait for PLL stabilization if PLLX was enabled */ | ||
1845 | if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) | ||
1846 | udelay(300); | ||
1847 | } | ||
1848 | |||
1849 | /* | ||
1850 | * Restore original burst policy setting for calls resulting from CPU | ||
1851 | * LP2 in idle or system suspend. | ||
1852 | */ | ||
1853 | writel(tegra30_cpu_clk_sctx.cclk_divider, | ||
1854 | clk_base + CLK_RESET_CCLK_DIVIDER); | ||
1855 | writel(tegra30_cpu_clk_sctx.cpu_burst, | ||
1856 | clk_base + CLK_RESET_CCLK_BURST); | ||
1857 | |||
1858 | writel(tegra30_cpu_clk_sctx.clk_csite_src, | ||
1859 | clk_base + CLK_RESET_SOURCE_CSITE); | ||
1860 | } | ||
1861 | #endif | ||
1862 | |||
1863 | static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { | ||
1864 | .wait_for_reset = tegra30_wait_cpu_in_reset, | ||
1865 | .put_in_reset = tegra30_put_cpu_in_reset, | ||
1866 | .out_of_reset = tegra30_cpu_out_of_reset, | ||
1867 | .enable_clock = tegra30_enable_cpu_clock, | ||
1868 | .disable_clock = tegra30_disable_cpu_clock, | ||
1869 | #ifdef CONFIG_PM_SLEEP | ||
1870 | .rail_off_ready = tegra30_cpu_rail_off_ready, | ||
1871 | .suspend = tegra30_cpu_clock_suspend, | ||
1872 | .resume = tegra30_cpu_clock_resume, | ||
1873 | #endif | ||
1874 | }; | ||
1875 | |||
1876 | static __initdata struct tegra_clk_init_table init_table[] = { | ||
1877 | {uarta, pll_p, 408000000, 1}, | ||
1878 | {pll_a, clk_max, 564480000, 1}, | ||
1879 | {pll_a_out0, clk_max, 11289600, 1}, | ||
1880 | {extern1, pll_a_out0, 0, 1}, | ||
1881 | {clk_out_1_mux, extern1, 0, 0}, | ||
1882 | {clk_out_1, clk_max, 0, 1}, | ||
1883 | {blink, clk_max, 0, 1}, | ||
1884 | {i2s0, pll_a_out0, 11289600, 0}, | ||
1885 | {i2s1, pll_a_out0, 11289600, 0}, | ||
1886 | {i2s2, pll_a_out0, 11289600, 0}, | ||
1887 | {i2s3, pll_a_out0, 11289600, 0}, | ||
1888 | {i2s4, pll_a_out0, 11289600, 0}, | ||
1889 | {sdmmc1, pll_p, 48000000, 0}, | ||
1890 | {sdmmc2, pll_p, 48000000, 0}, | ||
1891 | {sdmmc3, pll_p, 48000000, 0}, | ||
1892 | {pll_m, clk_max, 0, 1}, | ||
1893 | {pclk, clk_max, 0, 1}, | ||
1894 | {csite, clk_max, 0, 1}, | ||
1895 | {emc, clk_max, 0, 1}, | ||
1896 | {mselect, clk_max, 0, 1}, | ||
1897 | {sbc1, pll_p, 100000000, 0}, | ||
1898 | {sbc2, pll_p, 100000000, 0}, | ||
1899 | {sbc3, pll_p, 100000000, 0}, | ||
1900 | {sbc4, pll_p, 100000000, 0}, | ||
1901 | {sbc5, pll_p, 100000000, 0}, | ||
1902 | {sbc6, pll_p, 100000000, 0}, | ||
1903 | {host1x, pll_c, 150000000, 0}, | ||
1904 | {disp1, pll_p, 600000000, 0}, | ||
1905 | {disp2, pll_p, 600000000, 0}, | ||
1906 | {twd, clk_max, 0, 1}, | ||
1907 | {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ | ||
1908 | }; | ||
1909 | |||
1910 | /* | ||
1911 | * Some clocks may be used by different drivers depending on the board | ||
1912 | * configuration. List those here to register them twice in the clock lookup | ||
1913 | * table under two names. | ||
1914 | */ | ||
1915 | static struct tegra_clk_duplicate tegra_clk_duplicates[] = { | ||
1916 | TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), | ||
1917 | TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), | ||
1918 | TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), | ||
1919 | TEGRA_CLK_DUPLICATE(bsev, "tegra-avp", "bsev"), | ||
1920 | TEGRA_CLK_DUPLICATE(bsev, "nvavp", "bsev"), | ||
1921 | TEGRA_CLK_DUPLICATE(vde, "tegra-aes", "vde"), | ||
1922 | TEGRA_CLK_DUPLICATE(bsea, "tegra-aes", "bsea"), | ||
1923 | TEGRA_CLK_DUPLICATE(bsea, "nvavp", "bsea"), | ||
1924 | TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL), | ||
1925 | TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"), | ||
1926 | TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"), | ||
1927 | TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL), | ||
1928 | TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"), | ||
1929 | TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */ | ||
1930 | }; | ||
1931 | |||
1932 | static const struct of_device_id pmc_match[] __initconst = { | ||
1933 | { .compatible = "nvidia,tegra30-pmc" }, | ||
1934 | {}, | ||
1935 | }; | ||
1936 | |||
1937 | void __init tegra30_clock_init(struct device_node *np) | ||
1938 | { | ||
1939 | struct device_node *node; | ||
1940 | int i; | ||
1941 | |||
1942 | clk_base = of_iomap(np, 0); | ||
1943 | if (!clk_base) { | ||
1944 | pr_err("ioremap tegra30 CAR failed\n"); | ||
1945 | return; | ||
1946 | } | ||
1947 | |||
1948 | node = of_find_matching_node(NULL, pmc_match); | ||
1949 | if (!node) { | ||
1950 | pr_err("Failed to find pmc node\n"); | ||
1951 | BUG(); | ||
1952 | } | ||
1953 | |||
1954 | pmc_base = of_iomap(node, 0); | ||
1955 | if (!pmc_base) { | ||
1956 | pr_err("Can't map pmc registers\n"); | ||
1957 | BUG(); | ||
1958 | } | ||
1959 | |||
1960 | tegra30_osc_clk_init(); | ||
1961 | tegra30_fixed_clk_init(); | ||
1962 | tegra30_pll_init(); | ||
1963 | tegra30_super_clk_init(); | ||
1964 | tegra30_periph_clk_init(); | ||
1965 | tegra30_audio_clk_init(); | ||
1966 | tegra30_pmc_clk_init(); | ||
1967 | |||
1968 | for (i = 0; i < ARRAY_SIZE(clks); i++) { | ||
1969 | if (IS_ERR(clks[i])) { | ||
1970 | pr_err("Tegra30 clk %d: register failed with %ld\n", | ||
1971 | i, PTR_ERR(clks[i])); | ||
1972 | BUG(); | ||
1973 | } | ||
1974 | if (!clks[i]) | ||
1975 | clks[i] = ERR_PTR(-EINVAL); | ||
1976 | } | ||
1977 | |||
1978 | tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); | ||
1979 | |||
1980 | clk_data.clks = clks; | ||
1981 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
1982 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
1983 | |||
1984 | tegra_init_from_table(init_table, clks, clk_max); | ||
1985 | |||
1986 | tegra_cpu_car_ops = &tegra30_cpu_car_ops; | ||
1987 | } | ||
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c new file mode 100644 index 000000000000..a603b9af0ad3 --- /dev/null +++ b/drivers/clk/tegra/clk.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/clk-provider.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/clk/tegra.h> | ||
21 | |||
22 | #include "clk.h" | ||
23 | |||
24 | /* Global data of Tegra CPU CAR ops */ | ||
25 | struct tegra_cpu_car_ops *tegra_cpu_car_ops; | ||
26 | |||
27 | void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, | ||
28 | struct clk *clks[], int clk_max) | ||
29 | { | ||
30 | struct clk *clk; | ||
31 | |||
32 | for (; dup_list->clk_id < clk_max; dup_list++) { | ||
33 | clk = clks[dup_list->clk_id]; | ||
34 | dup_list->lookup.clk = clk; | ||
35 | clkdev_add(&dup_list->lookup); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, | ||
40 | struct clk *clks[], int clk_max) | ||
41 | { | ||
42 | struct clk *clk; | ||
43 | |||
44 | for (; tbl->clk_id < clk_max; tbl++) { | ||
45 | clk = clks[tbl->clk_id]; | ||
46 | if (IS_ERR_OR_NULL(clk)) | ||
47 | return; | ||
48 | |||
49 | if (tbl->parent_id < clk_max) { | ||
50 | struct clk *parent = clks[tbl->parent_id]; | ||
51 | if (clk_set_parent(clk, parent)) { | ||
52 | pr_err("%s: Failed to set parent %s of %s\n", | ||
53 | __func__, __clk_get_name(parent), | ||
54 | __clk_get_name(clk)); | ||
55 | WARN_ON(1); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (tbl->rate) | ||
60 | if (clk_set_rate(clk, tbl->rate)) { | ||
61 | pr_err("%s: Failed to set rate %lu of %s\n", | ||
62 | __func__, tbl->rate, | ||
63 | __clk_get_name(clk)); | ||
64 | WARN_ON(1); | ||
65 | } | ||
66 | |||
67 | if (tbl->state) | ||
68 | if (clk_prepare_enable(clk)) { | ||
69 | pr_err("%s: Failed to enable %s\n", __func__, | ||
70 | __clk_get_name(clk)); | ||
71 | WARN_ON(1); | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | |||
76 | static const struct of_device_id tegra_dt_clk_match[] = { | ||
77 | { .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init }, | ||
78 | { .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init }, | ||
79 | { } | ||
80 | }; | ||
81 | |||
82 | void __init tegra_clocks_init(void) | ||
83 | { | ||
84 | of_clk_init(tegra_dt_clk_match); | ||
85 | } | ||
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h new file mode 100644 index 000000000000..0744731c6229 --- /dev/null +++ b/drivers/clk/tegra/clk.h | |||
@@ -0,0 +1,502 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __TEGRA_CLK_H | ||
18 | #define __TEGRA_CLK_H | ||
19 | |||
20 | #include <linux/clk-provider.h> | ||
21 | #include <linux/clkdev.h> | ||
22 | |||
23 | /** | ||
24 | * struct tegra_clk_sync_source - external clock source from codec | ||
25 | * | ||
26 | * @hw: handle between common and hardware-specific interfaces | ||
27 | * @rate: input frequency from source | ||
28 | * @max_rate: max rate allowed | ||
29 | */ | ||
30 | struct tegra_clk_sync_source { | ||
31 | struct clk_hw hw; | ||
32 | unsigned long rate; | ||
33 | unsigned long max_rate; | ||
34 | }; | ||
35 | |||
36 | #define to_clk_sync_source(_hw) \ | ||
37 | container_of(_hw, struct tegra_clk_sync_source, hw) | ||
38 | |||
39 | extern const struct clk_ops tegra_clk_sync_source_ops; | ||
40 | struct clk *tegra_clk_register_sync_source(const char *name, | ||
41 | unsigned long fixed_rate, unsigned long max_rate); | ||
42 | |||
43 | /** | ||
44 | * struct tegra_clk_frac_div - fractional divider clock | ||
45 | * | ||
46 | * @hw: handle between common and hardware-specific interfaces | ||
47 | * @reg: register containing divider | ||
48 | * @flags: hardware-specific flags | ||
49 | * @shift: shift to the divider bit field | ||
50 | * @width: width of the divider bit field | ||
51 | * @frac_width: width of the fractional bit field | ||
52 | * @lock: register lock | ||
53 | * | ||
54 | * Flags: | ||
55 | * TEGRA_DIVIDER_ROUND_UP - This flags indicates to round up the divider value. | ||
56 | * TEGRA_DIVIDER_FIXED - Fixed rate PLL dividers has addition override bit, this | ||
57 | * flag indicates that this divider is for fixed rate PLL. | ||
58 | * TEGRA_DIVIDER_INT - Some modules can not cope with the duty cycle when | ||
59 | * fraction bit is set. This flags indicates to calculate divider for which | ||
60 | * fracton bit will be zero. | ||
61 | * TEGRA_DIVIDER_UART - UART module divider has additional enable bit which is | ||
62 | * set when divider value is not 0. This flags indicates that the divider | ||
63 | * is for UART module. | ||
64 | */ | ||
65 | struct tegra_clk_frac_div { | ||
66 | struct clk_hw hw; | ||
67 | void __iomem *reg; | ||
68 | u8 flags; | ||
69 | u8 shift; | ||
70 | u8 width; | ||
71 | u8 frac_width; | ||
72 | spinlock_t *lock; | ||
73 | }; | ||
74 | |||
75 | #define to_clk_frac_div(_hw) container_of(_hw, struct tegra_clk_frac_div, hw) | ||
76 | |||
77 | #define TEGRA_DIVIDER_ROUND_UP BIT(0) | ||
78 | #define TEGRA_DIVIDER_FIXED BIT(1) | ||
79 | #define TEGRA_DIVIDER_INT BIT(2) | ||
80 | #define TEGRA_DIVIDER_UART BIT(3) | ||
81 | |||
82 | extern const struct clk_ops tegra_clk_frac_div_ops; | ||
83 | struct clk *tegra_clk_register_divider(const char *name, | ||
84 | const char *parent_name, void __iomem *reg, | ||
85 | unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width, | ||
86 | u8 frac_width, spinlock_t *lock); | ||
87 | |||
88 | /* | ||
89 | * Tegra PLL: | ||
90 | * | ||
91 | * In general, there are 3 requirements for each PLL | ||
92 | * that SW needs to be comply with. | ||
93 | * (1) Input frequency range (REF). | ||
94 | * (2) Comparison frequency range (CF). CF = REF/DIVM. | ||
95 | * (3) VCO frequency range (VCO). VCO = CF * DIVN. | ||
96 | * | ||
97 | * The final PLL output frequency (FO) = VCO >> DIVP. | ||
98 | */ | ||
99 | |||
100 | /** | ||
101 | * struct tegra_clk_pll_freq_table - PLL frequecy table | ||
102 | * | ||
103 | * @input_rate: input rate from source | ||
104 | * @output_rate: output rate from PLL for the input rate | ||
105 | * @n: feedback divider | ||
106 | * @m: input divider | ||
107 | * @p: post divider | ||
108 | * @cpcon: charge pump current | ||
109 | */ | ||
110 | struct tegra_clk_pll_freq_table { | ||
111 | unsigned long input_rate; | ||
112 | unsigned long output_rate; | ||
113 | u16 n; | ||
114 | u16 m; | ||
115 | u8 p; | ||
116 | u8 cpcon; | ||
117 | }; | ||
118 | |||
119 | /** | ||
120 | * struct clk_pll_params - PLL parameters | ||
121 | * | ||
122 | * @input_min: Minimum input frequency | ||
123 | * @input_max: Maximum input frequency | ||
124 | * @cf_min: Minimum comparison frequency | ||
125 | * @cf_max: Maximum comparison frequency | ||
126 | * @vco_min: Minimum VCO frequency | ||
127 | * @vco_max: Maximum VCO frequency | ||
128 | * @base_reg: PLL base reg offset | ||
129 | * @misc_reg: PLL misc reg offset | ||
130 | * @lock_reg: PLL lock reg offset | ||
131 | * @lock_bit_idx: Bit index for PLL lock status | ||
132 | * @lock_enable_bit_idx: Bit index to enable PLL lock | ||
133 | * @lock_delay: Delay in us if PLL lock is not used | ||
134 | */ | ||
135 | struct tegra_clk_pll_params { | ||
136 | unsigned long input_min; | ||
137 | unsigned long input_max; | ||
138 | unsigned long cf_min; | ||
139 | unsigned long cf_max; | ||
140 | unsigned long vco_min; | ||
141 | unsigned long vco_max; | ||
142 | |||
143 | u32 base_reg; | ||
144 | u32 misc_reg; | ||
145 | u32 lock_reg; | ||
146 | u32 lock_bit_idx; | ||
147 | u32 lock_enable_bit_idx; | ||
148 | int lock_delay; | ||
149 | }; | ||
150 | |||
151 | /** | ||
152 | * struct tegra_clk_pll - Tegra PLL clock | ||
153 | * | ||
154 | * @hw: handle between common and hardware-specifix interfaces | ||
155 | * @clk_base: address of CAR controller | ||
156 | * @pmc: address of PMC, required to read override bits | ||
157 | * @freq_table: array of frequencies supported by PLL | ||
158 | * @params: PLL parameters | ||
159 | * @flags: PLL flags | ||
160 | * @fixed_rate: PLL rate if it is fixed | ||
161 | * @lock: register lock | ||
162 | * @divn_shift: shift to the feedback divider bit field | ||
163 | * @divn_width: width of the feedback divider bit field | ||
164 | * @divm_shift: shift to the input divider bit field | ||
165 | * @divm_width: width of the input divider bit field | ||
166 | * @divp_shift: shift to the post divider bit field | ||
167 | * @divp_width: width of the post divider bit field | ||
168 | * | ||
169 | * Flags: | ||
170 | * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for | ||
171 | * PLL locking. If not set it will use lock_delay value to wait. | ||
172 | * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs | ||
173 | * to be programmed to change output frequency of the PLL. | ||
174 | * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs | ||
175 | * to be programmed to change output frequency of the PLL. | ||
176 | * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs | ||
177 | * to be programmed to change output frequency of the PLL. | ||
178 | * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated | ||
179 | * that it is PLLU and invert post divider value. | ||
180 | * TEGRA_PLLM - PLLM has additional override settings in PMC. This | ||
181 | * flag indicates that it is PLLM and use override settings. | ||
182 | * TEGRA_PLL_FIXED - We are not supposed to change output frequency | ||
183 | * of some plls. | ||
184 | * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling. | ||
185 | */ | ||
186 | struct tegra_clk_pll { | ||
187 | struct clk_hw hw; | ||
188 | void __iomem *clk_base; | ||
189 | void __iomem *pmc; | ||
190 | u8 flags; | ||
191 | unsigned long fixed_rate; | ||
192 | spinlock_t *lock; | ||
193 | u8 divn_shift; | ||
194 | u8 divn_width; | ||
195 | u8 divm_shift; | ||
196 | u8 divm_width; | ||
197 | u8 divp_shift; | ||
198 | u8 divp_width; | ||
199 | struct tegra_clk_pll_freq_table *freq_table; | ||
200 | struct tegra_clk_pll_params *params; | ||
201 | }; | ||
202 | |||
203 | #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw) | ||
204 | |||
205 | #define TEGRA_PLL_USE_LOCK BIT(0) | ||
206 | #define TEGRA_PLL_HAS_CPCON BIT(1) | ||
207 | #define TEGRA_PLL_SET_LFCON BIT(2) | ||
208 | #define TEGRA_PLL_SET_DCCON BIT(3) | ||
209 | #define TEGRA_PLLU BIT(4) | ||
210 | #define TEGRA_PLLM BIT(5) | ||
211 | #define TEGRA_PLL_FIXED BIT(6) | ||
212 | #define TEGRA_PLLE_CONFIGURE BIT(7) | ||
213 | |||
214 | extern const struct clk_ops tegra_clk_pll_ops; | ||
215 | extern const struct clk_ops tegra_clk_plle_ops; | ||
216 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | ||
217 | void __iomem *clk_base, void __iomem *pmc, | ||
218 | unsigned long flags, unsigned long fixed_rate, | ||
219 | struct tegra_clk_pll_params *pll_params, u8 pll_flags, | ||
220 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); | ||
221 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | ||
222 | void __iomem *clk_base, void __iomem *pmc, | ||
223 | unsigned long flags, unsigned long fixed_rate, | ||
224 | struct tegra_clk_pll_params *pll_params, u8 pll_flags, | ||
225 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); | ||
226 | |||
227 | /** | ||
228 | * struct tegra_clk_pll_out - PLL divider down clock | ||
229 | * | ||
230 | * @hw: handle between common and hardware-specific interfaces | ||
231 | * @reg: register containing the PLL divider | ||
232 | * @enb_bit_idx: bit to enable/disable PLL divider | ||
233 | * @rst_bit_idx: bit to reset PLL divider | ||
234 | * @lock: register lock | ||
235 | * @flags: hardware-specific flags | ||
236 | */ | ||
237 | struct tegra_clk_pll_out { | ||
238 | struct clk_hw hw; | ||
239 | void __iomem *reg; | ||
240 | u8 enb_bit_idx; | ||
241 | u8 rst_bit_idx; | ||
242 | spinlock_t *lock; | ||
243 | u8 flags; | ||
244 | }; | ||
245 | |||
246 | #define to_clk_pll_out(_hw) container_of(_hw, struct tegra_clk_pll_out, hw) | ||
247 | |||
248 | extern const struct clk_ops tegra_clk_pll_out_ops; | ||
249 | struct clk *tegra_clk_register_pll_out(const char *name, | ||
250 | const char *parent_name, void __iomem *reg, u8 enb_bit_idx, | ||
251 | u8 rst_bit_idx, unsigned long flags, u8 pll_div_flags, | ||
252 | spinlock_t *lock); | ||
253 | |||
254 | /** | ||
255 | * struct tegra_clk_periph_regs - Registers controlling peripheral clock | ||
256 | * | ||
257 | * @enb_reg: read the enable status | ||
258 | * @enb_set_reg: write 1 to enable clock | ||
259 | * @enb_clr_reg: write 1 to disable clock | ||
260 | * @rst_reg: read the reset status | ||
261 | * @rst_set_reg: write 1 to assert the reset of peripheral | ||
262 | * @rst_clr_reg: write 1 to deassert the reset of peripheral | ||
263 | */ | ||
264 | struct tegra_clk_periph_regs { | ||
265 | u32 enb_reg; | ||
266 | u32 enb_set_reg; | ||
267 | u32 enb_clr_reg; | ||
268 | u32 rst_reg; | ||
269 | u32 rst_set_reg; | ||
270 | u32 rst_clr_reg; | ||
271 | }; | ||
272 | |||
273 | /** | ||
274 | * struct tegra_clk_periph_gate - peripheral gate clock | ||
275 | * | ||
276 | * @magic: magic number to validate type | ||
277 | * @hw: handle between common and hardware-specific interfaces | ||
278 | * @clk_base: address of CAR controller | ||
279 | * @regs: Registers to control the peripheral | ||
280 | * @flags: hardware-specific flags | ||
281 | * @clk_num: Clock number | ||
282 | * @enable_refcnt: array to maintain reference count of the clock | ||
283 | * | ||
284 | * Flags: | ||
285 | * TEGRA_PERIPH_NO_RESET - This flag indicates that reset is not allowed | ||
286 | * for this module. | ||
287 | * TEGRA_PERIPH_MANUAL_RESET - This flag indicates not to reset module | ||
288 | * after clock enable and driver for the module is responsible for | ||
289 | * doing reset. | ||
290 | * TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the | ||
291 | * bus to flush the write operation in apb bus. This flag indicates | ||
292 | * that this peripheral is in apb bus. | ||
293 | */ | ||
294 | struct tegra_clk_periph_gate { | ||
295 | u32 magic; | ||
296 | struct clk_hw hw; | ||
297 | void __iomem *clk_base; | ||
298 | u8 flags; | ||
299 | int clk_num; | ||
300 | int *enable_refcnt; | ||
301 | struct tegra_clk_periph_regs *regs; | ||
302 | }; | ||
303 | |||
304 | #define to_clk_periph_gate(_hw) \ | ||
305 | container_of(_hw, struct tegra_clk_periph_gate, hw) | ||
306 | |||
307 | #define TEGRA_CLK_PERIPH_GATE_MAGIC 0x17760309 | ||
308 | |||
309 | #define TEGRA_PERIPH_NO_RESET BIT(0) | ||
310 | #define TEGRA_PERIPH_MANUAL_RESET BIT(1) | ||
311 | #define TEGRA_PERIPH_ON_APB BIT(2) | ||
312 | |||
313 | void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); | ||
314 | extern const struct clk_ops tegra_clk_periph_gate_ops; | ||
315 | struct clk *tegra_clk_register_periph_gate(const char *name, | ||
316 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, | ||
317 | unsigned long flags, int clk_num, | ||
318 | struct tegra_clk_periph_regs *pregs, int *enable_refcnt); | ||
319 | |||
320 | /** | ||
321 | * struct clk-periph - peripheral clock | ||
322 | * | ||
323 | * @magic: magic number to validate type | ||
324 | * @hw: handle between common and hardware-specific interfaces | ||
325 | * @mux: mux clock | ||
326 | * @divider: divider clock | ||
327 | * @gate: gate clock | ||
328 | * @mux_ops: mux clock ops | ||
329 | * @div_ops: divider clock ops | ||
330 | * @gate_ops: gate clock ops | ||
331 | */ | ||
332 | struct tegra_clk_periph { | ||
333 | u32 magic; | ||
334 | struct clk_hw hw; | ||
335 | struct clk_mux mux; | ||
336 | struct tegra_clk_frac_div divider; | ||
337 | struct tegra_clk_periph_gate gate; | ||
338 | |||
339 | const struct clk_ops *mux_ops; | ||
340 | const struct clk_ops *div_ops; | ||
341 | const struct clk_ops *gate_ops; | ||
342 | }; | ||
343 | |||
344 | #define to_clk_periph(_hw) container_of(_hw, struct tegra_clk_periph, hw) | ||
345 | |||
346 | #define TEGRA_CLK_PERIPH_MAGIC 0x18221223 | ||
347 | |||
348 | extern const struct clk_ops tegra_clk_periph_ops; | ||
349 | struct clk *tegra_clk_register_periph(const char *name, | ||
350 | const char **parent_names, int num_parents, | ||
351 | struct tegra_clk_periph *periph, void __iomem *clk_base, | ||
352 | u32 offset); | ||
353 | struct clk *tegra_clk_register_periph_nodiv(const char *name, | ||
354 | const char **parent_names, int num_parents, | ||
355 | struct tegra_clk_periph *periph, void __iomem *clk_base, | ||
356 | u32 offset); | ||
357 | |||
358 | #define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags, \ | ||
359 | _div_shift, _div_width, _div_frac_width, \ | ||
360 | _div_flags, _clk_num, _enb_refcnt, _regs, \ | ||
361 | _gate_flags) \ | ||
362 | { \ | ||
363 | .mux = { \ | ||
364 | .flags = _mux_flags, \ | ||
365 | .shift = _mux_shift, \ | ||
366 | .width = _mux_width, \ | ||
367 | }, \ | ||
368 | .divider = { \ | ||
369 | .flags = _div_flags, \ | ||
370 | .shift = _div_shift, \ | ||
371 | .width = _div_width, \ | ||
372 | .frac_width = _div_frac_width, \ | ||
373 | }, \ | ||
374 | .gate = { \ | ||
375 | .flags = _gate_flags, \ | ||
376 | .clk_num = _clk_num, \ | ||
377 | .enable_refcnt = _enb_refcnt, \ | ||
378 | .regs = _regs, \ | ||
379 | }, \ | ||
380 | .mux_ops = &clk_mux_ops, \ | ||
381 | .div_ops = &tegra_clk_frac_div_ops, \ | ||
382 | .gate_ops = &tegra_clk_periph_gate_ops, \ | ||
383 | } | ||
384 | |||
385 | struct tegra_periph_init_data { | ||
386 | const char *name; | ||
387 | int clk_id; | ||
388 | const char **parent_names; | ||
389 | int num_parents; | ||
390 | struct tegra_clk_periph periph; | ||
391 | u32 offset; | ||
392 | const char *con_id; | ||
393 | const char *dev_id; | ||
394 | }; | ||
395 | |||
396 | #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \ | ||
397 | _mux_shift, _mux_width, _mux_flags, _div_shift, \ | ||
398 | _div_width, _div_frac_width, _div_flags, _regs, \ | ||
399 | _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ | ||
400 | { \ | ||
401 | .name = _name, \ | ||
402 | .clk_id = _clk_id, \ | ||
403 | .parent_names = _parent_names, \ | ||
404 | .num_parents = ARRAY_SIZE(_parent_names), \ | ||
405 | .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width, \ | ||
406 | _mux_flags, _div_shift, \ | ||
407 | _div_width, _div_frac_width, \ | ||
408 | _div_flags, _clk_num, \ | ||
409 | _enb_refcnt, _regs, \ | ||
410 | _gate_flags), \ | ||
411 | .offset = _offset, \ | ||
412 | .con_id = _con_id, \ | ||
413 | .dev_id = _dev_id, \ | ||
414 | } | ||
415 | |||
416 | /** | ||
417 | * struct clk_super_mux - super clock | ||
418 | * | ||
419 | * @hw: handle between common and hardware-specific interfaces | ||
420 | * @reg: register controlling multiplexer | ||
421 | * @width: width of the multiplexer bit field | ||
422 | * @flags: hardware-specific flags | ||
423 | * @div2_index: bit controlling divide-by-2 | ||
424 | * @pllx_index: PLLX index in the parent list | ||
425 | * @lock: register lock | ||
426 | * | ||
427 | * Flags: | ||
428 | * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates | ||
429 | * that this is LP cluster clock. | ||
430 | */ | ||
431 | struct tegra_clk_super_mux { | ||
432 | struct clk_hw hw; | ||
433 | void __iomem *reg; | ||
434 | u8 width; | ||
435 | u8 flags; | ||
436 | u8 div2_index; | ||
437 | u8 pllx_index; | ||
438 | spinlock_t *lock; | ||
439 | }; | ||
440 | |||
441 | #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw) | ||
442 | |||
443 | #define TEGRA_DIVIDER_2 BIT(0) | ||
444 | |||
445 | extern const struct clk_ops tegra_clk_super_ops; | ||
446 | struct clk *tegra_clk_register_super_mux(const char *name, | ||
447 | const char **parent_names, u8 num_parents, | ||
448 | unsigned long flags, void __iomem *reg, u8 clk_super_flags, | ||
449 | u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock); | ||
450 | |||
451 | /** | ||
452 | * struct clk_init_tabel - clock initialization table | ||
453 | * @clk_id: clock id as mentioned in device tree bindings | ||
454 | * @parent_id: parent clock id as mentioned in device tree bindings | ||
455 | * @rate: rate to set | ||
456 | * @state: enable/disable | ||
457 | */ | ||
458 | struct tegra_clk_init_table { | ||
459 | unsigned int clk_id; | ||
460 | unsigned int parent_id; | ||
461 | unsigned long rate; | ||
462 | int state; | ||
463 | }; | ||
464 | |||
465 | /** | ||
466 | * struct clk_duplicate - duplicate clocks | ||
467 | * @clk_id: clock id as mentioned in device tree bindings | ||
468 | * @lookup: duplicate lookup entry for the clock | ||
469 | */ | ||
470 | struct tegra_clk_duplicate { | ||
471 | int clk_id; | ||
472 | struct clk_lookup lookup; | ||
473 | }; | ||
474 | |||
475 | #define TEGRA_CLK_DUPLICATE(_clk_id, _dev, _con) \ | ||
476 | { \ | ||
477 | .clk_id = _clk_id, \ | ||
478 | .lookup = { \ | ||
479 | .dev_id = _dev, \ | ||
480 | .con_id = _con, \ | ||
481 | }, \ | ||
482 | } | ||
483 | |||
484 | void tegra_init_from_table(struct tegra_clk_init_table *tbl, | ||
485 | struct clk *clks[], int clk_max); | ||
486 | |||
487 | void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, | ||
488 | struct clk *clks[], int clk_max); | ||
489 | |||
490 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
491 | void tegra20_clock_init(struct device_node *np); | ||
492 | #else | ||
493 | static inline void tegra20_clock_init(struct device_node *np) {} | ||
494 | #endif /* CONFIG_ARCH_TEGRA_2x_SOC */ | ||
495 | |||
496 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
497 | void tegra30_clock_init(struct device_node *np); | ||
498 | #else | ||
499 | static inline void tegra30_clock_init(struct device_node *np) {} | ||
500 | #endif /* CONFIG_ARCH_TEGRA_3x_SOC */ | ||
501 | |||
502 | #endif /* TEGRA_CLK_H */ | ||
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index c4cc27e5c8a5..071e2c3eec4f 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig | |||
@@ -39,4 +39,10 @@ config CPU_IDLE_CALXEDA | |||
39 | help | 39 | help |
40 | Select this to enable cpuidle on Calxeda processors. | 40 | Select this to enable cpuidle on Calxeda processors. |
41 | 41 | ||
42 | config CPU_IDLE_KIRKWOOD | ||
43 | bool "CPU Idle Driver for Kirkwood processors" | ||
44 | depends on ARCH_KIRKWOOD | ||
45 | help | ||
46 | Select this to enable cpuidle on Kirkwood processors. | ||
47 | |||
42 | endif | 48 | endif |
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index 03ee87482c71..24c6e7d945ed 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile | |||
@@ -6,3 +6,4 @@ obj-y += cpuidle.o driver.o governor.o sysfs.o governors/ | |||
6 | obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o | 6 | obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o |
7 | 7 | ||
8 | obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o | 8 | obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o |
9 | obj-$(CONFIG_CPU_IDLE_KIRKWOOD) += cpuidle-kirkwood.o | ||
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/drivers/cpuidle/cpuidle-kirkwood.c index f7304670f2f8..670aa1e55cd6 100644 --- a/arch/arm/mach-kirkwood/cpuidle.c +++ b/drivers/cpuidle/cpuidle-kirkwood.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/cpuidle.h> | 20 | #include <linux/cpuidle.h> |
@@ -21,16 +22,17 @@ | |||
21 | #include <linux/export.h> | 22 | #include <linux/export.h> |
22 | #include <asm/proc-fns.h> | 23 | #include <asm/proc-fns.h> |
23 | #include <asm/cpuidle.h> | 24 | #include <asm/cpuidle.h> |
24 | #include <mach/kirkwood.h> | ||
25 | 25 | ||
26 | #define KIRKWOOD_MAX_STATES 2 | 26 | #define KIRKWOOD_MAX_STATES 2 |
27 | 27 | ||
28 | static void __iomem *ddr_operation_base; | ||
29 | |||
28 | /* Actual code that puts the SoC in different idle states */ | 30 | /* Actual code that puts the SoC in different idle states */ |
29 | static int kirkwood_enter_idle(struct cpuidle_device *dev, | 31 | static int kirkwood_enter_idle(struct cpuidle_device *dev, |
30 | struct cpuidle_driver *drv, | 32 | struct cpuidle_driver *drv, |
31 | int index) | 33 | int index) |
32 | { | 34 | { |
33 | writel(0x7, DDR_OPERATION_BASE); | 35 | writel(0x7, ddr_operation_base); |
34 | cpu_do_idle(); | 36 | cpu_do_idle(); |
35 | 37 | ||
36 | return index; | 38 | return index; |
@@ -51,13 +53,22 @@ static struct cpuidle_driver kirkwood_idle_driver = { | |||
51 | }, | 53 | }, |
52 | .state_count = KIRKWOOD_MAX_STATES, | 54 | .state_count = KIRKWOOD_MAX_STATES, |
53 | }; | 55 | }; |
56 | static struct cpuidle_device *device; | ||
54 | 57 | ||
55 | static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); | 58 | static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); |
56 | 59 | ||
57 | /* Initialize CPU idle by registering the idle states */ | 60 | /* Initialize CPU idle by registering the idle states */ |
58 | static int kirkwood_init_cpuidle(void) | 61 | static int kirkwood_cpuidle_probe(struct platform_device *pdev) |
59 | { | 62 | { |
60 | struct cpuidle_device *device; | 63 | struct resource *res; |
64 | |||
65 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
66 | if (res == NULL) | ||
67 | return -EINVAL; | ||
68 | |||
69 | ddr_operation_base = devm_request_and_ioremap(&pdev->dev, res); | ||
70 | if (!ddr_operation_base) | ||
71 | return -EADDRNOTAVAIL; | ||
61 | 72 | ||
62 | device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); | 73 | device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); |
63 | device->state_count = KIRKWOOD_MAX_STATES; | 74 | device->state_count = KIRKWOOD_MAX_STATES; |
@@ -70,4 +81,26 @@ static int kirkwood_init_cpuidle(void) | |||
70 | return 0; | 81 | return 0; |
71 | } | 82 | } |
72 | 83 | ||
73 | device_initcall(kirkwood_init_cpuidle); | 84 | int kirkwood_cpuidle_remove(struct platform_device *pdev) |
85 | { | ||
86 | cpuidle_unregister_device(device); | ||
87 | cpuidle_unregister_driver(&kirkwood_idle_driver); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static struct platform_driver kirkwood_cpuidle_driver = { | ||
93 | .probe = kirkwood_cpuidle_probe, | ||
94 | .remove = kirkwood_cpuidle_remove, | ||
95 | .driver = { | ||
96 | .name = "kirkwood_cpuidle", | ||
97 | .owner = THIS_MODULE, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | module_platform_driver(kirkwood_cpuidle_driver); | ||
102 | |||
103 | MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>"); | ||
104 | MODULE_DESCRIPTION("Kirkwood cpu idle driver"); | ||
105 | MODULE_LICENSE("GPL v2"); | ||
106 | MODULE_ALIAS("platform:kirkwood-cpuidle"); | ||
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 58c1896271e1..f6c018f1b453 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c | |||
@@ -32,8 +32,8 @@ | |||
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/clk/tegra.h> | ||
35 | 36 | ||
36 | #include <mach/clk.h> | ||
37 | #include "dmaengine.h" | 37 | #include "dmaengine.h" |
38 | 38 | ||
39 | #define TEGRA_APBDMA_GENERAL 0x0 | 39 | #define TEGRA_APBDMA_GENERAL 0x0 |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index d365c6dff0fb..b6679b36700f 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
@@ -12,8 +12,7 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/of.h> | 13 | #include <linux/of.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | 15 | #include <linux/clk/tegra.h> | |
16 | #include <mach/clk.h> | ||
17 | 16 | ||
18 | #include "drm.h" | 17 | #include "drm.h" |
19 | #include "dc.h" | 18 | #include "dc.h" |
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 3a503c9e4686..d980dc75788c 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/of_address.h> | 11 | #include <linux/of_address.h> |
12 | #include <linux/of_platform.h> | 12 | #include <linux/of_platform.h> |
13 | 13 | ||
14 | #include <mach/clk.h> | ||
15 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
16 | #include <asm/dma-iommu.h> | 15 | #include <asm/dma-iommu.h> |
17 | 16 | ||
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 266af7879240..d4f3fb9f0c29 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c | |||
@@ -14,8 +14,7 @@ | |||
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/regulator/consumer.h> | 16 | #include <linux/regulator/consumer.h> |
17 | 17 | #include <linux/clk/tegra.h> | |
18 | #include <mach/clk.h> | ||
19 | 18 | ||
20 | #include "hdmi.h" | 19 | #include "hdmi.h" |
21 | #include "drm.h" | 20 | #include "drm.h" |
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 1fb30099dac4..f0d9923323ea 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -29,11 +29,10 @@ | |||
29 | #include <linux/of_i2c.h> | 29 | #include <linux/of_i2c.h> |
30 | #include <linux/of_device.h> | 30 | #include <linux/of_device.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/clk/tegra.h> | ||
32 | 33 | ||
33 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
34 | 35 | ||
35 | #include <mach/clk.h> | ||
36 | |||
37 | #define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000)) | 36 | #define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000)) |
38 | #define BYTES_PER_FIFO_WORD 4 | 37 | #define BYTES_PER_FIFO_WORD 4 |
39 | 38 | ||
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index d89e7d392d1e..0e138ebcc768 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/input/matrix_keypad.h> | 32 | #include <linux/input/matrix_keypad.h> |
33 | #include <mach/clk.h> | 33 | #include <linux/clk/tegra.h> |
34 | 34 | ||
35 | #define KBC_MAX_GPIO 24 | 35 | #define KBC_MAX_GPIO 24 |
36 | #define KBC_MAX_KPENT 8 | 36 | #define KBC_MAX_KPENT 8 |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index aa64d5d3fb20..476d06452af8 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -1033,7 +1033,7 @@ config RTC_DRV_TX4939 | |||
1033 | 1033 | ||
1034 | config RTC_DRV_MV | 1034 | config RTC_DRV_MV |
1035 | tristate "Marvell SoC RTC" | 1035 | tristate "Marvell SoC RTC" |
1036 | depends on ARCH_KIRKWOOD || ARCH_DOVE | 1036 | depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU |
1037 | help | 1037 | help |
1038 | If you say yes here you will get support for the in-chip RTC | 1038 | If you say yes here you will get support for the in-chip RTC |
1039 | that can be found in some of Marvell's SoC devices, such as | 1039 | that can be found in some of Marvell's SoC devices, such as |
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 8a61b27a9f2d..3d6a12b2af04 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/of_device.h> | 34 | #include <linux/of_device.h> |
35 | #include <linux/spi/spi.h> | 35 | #include <linux/spi/spi.h> |
36 | #include <linux/spi/spi-tegra.h> | 36 | #include <linux/spi/spi-tegra.h> |
37 | #include <mach/clk.h> | 37 | #include <linux/clk/tegra.h> |
38 | 38 | ||
39 | #define SPI_COMMAND 0x000 | 39 | #define SPI_COMMAND 0x000 |
40 | #define SPI_GO BIT(30) | 40 | #define SPI_GO BIT(30) |
@@ -531,7 +531,7 @@ static int tegra_sflash_probe(struct platform_device *pdev) | |||
531 | goto exit_free_master; | 531 | goto exit_free_master; |
532 | } | 532 | } |
533 | 533 | ||
534 | tsd->clk = devm_clk_get(&pdev->dev, "spi"); | 534 | tsd->clk = devm_clk_get(&pdev->dev, NULL); |
535 | if (IS_ERR(tsd->clk)) { | 535 | if (IS_ERR(tsd->clk)) { |
536 | dev_err(&pdev->dev, "can not get clock\n"); | 536 | dev_err(&pdev->dev, "can not get clock\n"); |
537 | ret = PTR_ERR(tsd->clk); | 537 | ret = PTR_ERR(tsd->clk); |
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 8458c4bf7172..b8698b389ef3 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/of_device.h> | 35 | #include <linux/of_device.h> |
36 | #include <linux/spi/spi.h> | 36 | #include <linux/spi/spi.h> |
37 | #include <linux/spi/spi-tegra.h> | 37 | #include <linux/spi/spi-tegra.h> |
38 | #include <mach/clk.h> | 38 | #include <linux/clk/tegra.h> |
39 | 39 | ||
40 | #define SLINK_COMMAND 0x000 | 40 | #define SLINK_COMMAND 0x000 |
41 | #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) | 41 | #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) |
@@ -1186,7 +1186,7 @@ static int tegra_slink_probe(struct platform_device *pdev) | |||
1186 | goto exit_free_master; | 1186 | goto exit_free_master; |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | tspi->clk = devm_clk_get(&pdev->dev, "slink"); | 1189 | tspi->clk = devm_clk_get(&pdev->dev, NULL); |
1190 | if (IS_ERR(tspi->clk)) { | 1190 | if (IS_ERR(tspi->clk)) { |
1191 | dev_err(&pdev->dev, "can not get clock\n"); | 1191 | dev_err(&pdev->dev, "can not get clock\n"); |
1192 | ret = PTR_ERR(tspi->clk); | 1192 | ret = PTR_ERR(tspi->clk); |
diff --git a/drivers/staging/nvec/TODO b/drivers/staging/nvec/TODO index f950ab890e2e..e5ae42a0b44a 100644 --- a/drivers/staging/nvec/TODO +++ b/drivers/staging/nvec/TODO | |||
@@ -1,9 +1,5 @@ | |||
1 | ToDo list (incomplete, unordered) | 1 | ToDo list (incomplete, unordered) |
2 | - add compile as module support | 2 | - add compile as module support |
3 | - fix clk usage | ||
4 | should not be using clk_get_sys(), but clk_get(&pdev->dev, conn) | ||
5 | where conn is either NULL if the device only has one clock, or | ||
6 | the device specific name if it has multiple clocks. | ||
7 | - move half of the nvec init stuff to i2c-tegra.c | 3 | - move half of the nvec init stuff to i2c-tegra.c |
8 | - move event handling to nvec_events | 4 | - move event handling to nvec_events |
9 | - finish suspend/resume support | 5 | - finish suspend/resume support |
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 6a0b6eccf1e6..cf159365b0ee 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c | |||
@@ -37,8 +37,7 @@ | |||
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
40 | 40 | #include <linux/clk/tegra.h> | |
41 | #include <mach/clk.h> | ||
42 | 41 | ||
43 | #include "nvec.h" | 42 | #include "nvec.h" |
44 | 43 | ||
@@ -816,7 +815,7 @@ static int tegra_nvec_probe(struct platform_device *pdev) | |||
816 | return -ENODEV; | 815 | return -ENODEV; |
817 | } | 816 | } |
818 | 817 | ||
819 | i2c_clk = clk_get_sys("tegra-i2c.2", "div-clk"); | 818 | i2c_clk = clk_get(&pdev->dev, "div-clk"); |
820 | if (IS_ERR(i2c_clk)) { | 819 | if (IS_ERR(i2c_clk)) { |
821 | dev_err(nvec->dev, "failed to get controller clock\n"); | 820 | dev_err(nvec->dev, "failed to get controller clock\n"); |
822 | return -ENODEV; | 821 | return -ENODEV; |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index acf17556bd87..568aecc7075b 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs | 2 | * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Google, Inc. | 4 | * Copyright (C) 2010 Google, Inc. |
5 | * Copyright (C) 2009 NVIDIA Corporation | 5 | * Copyright (C) 2009 - 2013 NVIDIA Corporation |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
@@ -26,23 +26,28 @@ | |||
26 | #include <linux/of.h> | 26 | #include <linux/of.h> |
27 | #include <linux/of_gpio.h> | 27 | #include <linux/of_gpio.h> |
28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
29 | 29 | #include <linux/usb/ehci_def.h> | |
30 | #include <linux/usb/tegra_usb_phy.h> | 30 | #include <linux/usb/tegra_usb_phy.h> |
31 | 31 | ||
32 | #define TEGRA_USB_BASE 0xC5000000 | 32 | #define TEGRA_USB_BASE 0xC5000000 |
33 | #define TEGRA_USB2_BASE 0xC5004000 | 33 | #define TEGRA_USB2_BASE 0xC5004000 |
34 | #define TEGRA_USB3_BASE 0xC5008000 | 34 | #define TEGRA_USB3_BASE 0xC5008000 |
35 | 35 | ||
36 | /* PORTSC registers */ | ||
37 | #define TEGRA_USB_PORTSC1 0x184 | ||
38 | #define TEGRA_USB_PORTSC1_PTS(x) (((x) & 0x3) << 30) | ||
39 | #define TEGRA_USB_PORTSC1_PHCD (1 << 23) | ||
40 | |||
36 | #define TEGRA_USB_DMA_ALIGN 32 | 41 | #define TEGRA_USB_DMA_ALIGN 32 |
37 | 42 | ||
38 | struct tegra_ehci_hcd { | 43 | struct tegra_ehci_hcd { |
39 | struct ehci_hcd *ehci; | 44 | struct ehci_hcd *ehci; |
40 | struct tegra_usb_phy *phy; | 45 | struct tegra_usb_phy *phy; |
41 | struct clk *clk; | 46 | struct clk *clk; |
42 | struct clk *emc_clk; | ||
43 | struct usb_phy *transceiver; | 47 | struct usb_phy *transceiver; |
44 | int host_resumed; | 48 | int host_resumed; |
45 | int port_resuming; | 49 | int port_resuming; |
50 | bool needs_double_reset; | ||
46 | enum tegra_usb_phy_port_speed port_speed; | 51 | enum tegra_usb_phy_port_speed port_speed; |
47 | }; | 52 | }; |
48 | 53 | ||
@@ -50,9 +55,8 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd) | |||
50 | { | 55 | { |
51 | struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); | 56 | struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); |
52 | 57 | ||
53 | clk_prepare_enable(tegra->emc_clk); | ||
54 | clk_prepare_enable(tegra->clk); | 58 | clk_prepare_enable(tegra->clk); |
55 | usb_phy_set_suspend(&tegra->phy->u_phy, 0); | 59 | usb_phy_set_suspend(hcd->phy, 0); |
56 | tegra->host_resumed = 1; | 60 | tegra->host_resumed = 1; |
57 | } | 61 | } |
58 | 62 | ||
@@ -61,9 +65,8 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd) | |||
61 | struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); | 65 | struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); |
62 | 66 | ||
63 | tegra->host_resumed = 0; | 67 | tegra->host_resumed = 0; |
64 | usb_phy_set_suspend(&tegra->phy->u_phy, 1); | 68 | usb_phy_set_suspend(hcd->phy, 1); |
65 | clk_disable_unprepare(tegra->clk); | 69 | clk_disable_unprepare(tegra->clk); |
66 | clk_disable_unprepare(tegra->emc_clk); | ||
67 | } | 70 | } |
68 | 71 | ||
69 | static int tegra_ehci_internal_port_reset( | 72 | static int tegra_ehci_internal_port_reset( |
@@ -156,7 +159,7 @@ static int tegra_ehci_hub_control( | |||
156 | if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { | 159 | if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { |
157 | /* Resume completed, re-enable disconnect detection */ | 160 | /* Resume completed, re-enable disconnect detection */ |
158 | tegra->port_resuming = 0; | 161 | tegra->port_resuming = 0; |
159 | tegra_usb_phy_postresume(tegra->phy); | 162 | tegra_usb_phy_postresume(hcd->phy); |
160 | } | 163 | } |
161 | } | 164 | } |
162 | 165 | ||
@@ -184,7 +187,7 @@ static int tegra_ehci_hub_control( | |||
184 | } | 187 | } |
185 | 188 | ||
186 | /* For USB1 port we need to issue Port Reset twice internally */ | 189 | /* For USB1 port we need to issue Port Reset twice internally */ |
187 | if (tegra->phy->instance == 0 && | 190 | if (tegra->needs_double_reset && |
188 | (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) { | 191 | (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) { |
189 | spin_unlock_irqrestore(&ehci->lock, flags); | 192 | spin_unlock_irqrestore(&ehci->lock, flags); |
190 | return tegra_ehci_internal_port_reset(ehci, status_reg); | 193 | return tegra_ehci_internal_port_reset(ehci, status_reg); |
@@ -209,7 +212,7 @@ static int tegra_ehci_hub_control( | |||
209 | goto done; | 212 | goto done; |
210 | 213 | ||
211 | /* Disable disconnect detection during port resume */ | 214 | /* Disable disconnect detection during port resume */ |
212 | tegra_usb_phy_preresume(tegra->phy); | 215 | tegra_usb_phy_preresume(hcd->phy); |
213 | 216 | ||
214 | ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); | 217 | ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); |
215 | 218 | ||
@@ -473,7 +476,7 @@ static int controller_resume(struct device *dev) | |||
473 | } | 476 | } |
474 | 477 | ||
475 | /* Force the phy to keep data lines in suspend state */ | 478 | /* Force the phy to keep data lines in suspend state */ |
476 | tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); | 479 | tegra_ehci_phy_restore_start(hcd->phy, tegra->port_speed); |
477 | 480 | ||
478 | /* Enable host mode */ | 481 | /* Enable host mode */ |
479 | tdi_reset(ehci); | 482 | tdi_reset(ehci); |
@@ -540,17 +543,17 @@ static int controller_resume(struct device *dev) | |||
540 | } | 543 | } |
541 | } | 544 | } |
542 | 545 | ||
543 | tegra_ehci_phy_restore_end(tegra->phy); | 546 | tegra_ehci_phy_restore_end(hcd->phy); |
544 | goto done; | 547 | goto done; |
545 | 548 | ||
546 | restart: | 549 | restart: |
547 | if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) | 550 | if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) |
548 | tegra_ehci_phy_restore_end(tegra->phy); | 551 | tegra_ehci_phy_restore_end(hcd->phy); |
549 | 552 | ||
550 | tegra_ehci_restart(hcd); | 553 | tegra_ehci_restart(hcd); |
551 | 554 | ||
552 | done: | 555 | done: |
553 | tegra_usb_phy_preresume(tegra->phy); | 556 | tegra_usb_phy_preresume(hcd->phy); |
554 | tegra->port_resuming = 1; | 557 | tegra->port_resuming = 1; |
555 | return 0; | 558 | return 0; |
556 | } | 559 | } |
@@ -604,6 +607,37 @@ static const struct dev_pm_ops tegra_ehci_pm_ops = { | |||
604 | 607 | ||
605 | #endif | 608 | #endif |
606 | 609 | ||
610 | /* Bits of PORTSC1, which will get cleared by writing 1 into them */ | ||
611 | #define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) | ||
612 | |||
613 | void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val) | ||
614 | { | ||
615 | unsigned long val; | ||
616 | struct usb_hcd *hcd = bus_to_hcd(x->otg->host); | ||
617 | void __iomem *base = hcd->regs; | ||
618 | |||
619 | val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS; | ||
620 | val &= ~TEGRA_USB_PORTSC1_PTS(3); | ||
621 | val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3); | ||
622 | writel(val, base + TEGRA_USB_PORTSC1); | ||
623 | } | ||
624 | EXPORT_SYMBOL_GPL(tegra_ehci_set_pts); | ||
625 | |||
626 | void tegra_ehci_set_phcd(struct usb_phy *x, bool enable) | ||
627 | { | ||
628 | unsigned long val; | ||
629 | struct usb_hcd *hcd = bus_to_hcd(x->otg->host); | ||
630 | void __iomem *base = hcd->regs; | ||
631 | |||
632 | val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS; | ||
633 | if (enable) | ||
634 | val |= TEGRA_USB_PORTSC1_PHCD; | ||
635 | else | ||
636 | val &= ~TEGRA_USB_PORTSC1_PHCD; | ||
637 | writel(val, base + TEGRA_USB_PORTSC1); | ||
638 | } | ||
639 | EXPORT_SYMBOL_GPL(tegra_ehci_set_phcd); | ||
640 | |||
607 | static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); | 641 | static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); |
608 | 642 | ||
609 | static int tegra_ehci_probe(struct platform_device *pdev) | 643 | static int tegra_ehci_probe(struct platform_device *pdev) |
@@ -615,6 +649,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) | |||
615 | int err = 0; | 649 | int err = 0; |
616 | int irq; | 650 | int irq; |
617 | int instance = pdev->id; | 651 | int instance = pdev->id; |
652 | struct usb_phy *u_phy; | ||
618 | 653 | ||
619 | pdata = pdev->dev.platform_data; | 654 | pdata = pdev->dev.platform_data; |
620 | if (!pdata) { | 655 | if (!pdata) { |
@@ -656,15 +691,8 @@ static int tegra_ehci_probe(struct platform_device *pdev) | |||
656 | if (err) | 691 | if (err) |
657 | goto fail_clk; | 692 | goto fail_clk; |
658 | 693 | ||
659 | tegra->emc_clk = devm_clk_get(&pdev->dev, "emc"); | 694 | tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node, |
660 | if (IS_ERR(tegra->emc_clk)) { | 695 | "nvidia,needs-double-reset"); |
661 | dev_err(&pdev->dev, "Can't get emc clock\n"); | ||
662 | err = PTR_ERR(tegra->emc_clk); | ||
663 | goto fail_emc_clk; | ||
664 | } | ||
665 | |||
666 | clk_prepare_enable(tegra->emc_clk); | ||
667 | clk_set_rate(tegra->emc_clk, 400000000); | ||
668 | 696 | ||
669 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 697 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
670 | if (!res) { | 698 | if (!res) { |
@@ -712,9 +740,19 @@ static int tegra_ehci_probe(struct platform_device *pdev) | |||
712 | goto fail_io; | 740 | goto fail_io; |
713 | } | 741 | } |
714 | 742 | ||
715 | usb_phy_init(&tegra->phy->u_phy); | 743 | hcd->phy = u_phy = &tegra->phy->u_phy; |
744 | usb_phy_init(hcd->phy); | ||
745 | |||
746 | u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), | ||
747 | GFP_KERNEL); | ||
748 | if (!u_phy->otg) { | ||
749 | dev_err(&pdev->dev, "Failed to alloc memory for otg\n"); | ||
750 | err = -ENOMEM; | ||
751 | goto fail_io; | ||
752 | } | ||
753 | u_phy->otg->host = hcd_to_bus(hcd); | ||
716 | 754 | ||
717 | err = usb_phy_set_suspend(&tegra->phy->u_phy, 0); | 755 | err = usb_phy_set_suspend(hcd->phy, 0); |
718 | if (err) { | 756 | if (err) { |
719 | dev_err(&pdev->dev, "Failed to power on the phy\n"); | 757 | dev_err(&pdev->dev, "Failed to power on the phy\n"); |
720 | goto fail; | 758 | goto fail; |
@@ -760,10 +798,8 @@ fail: | |||
760 | if (!IS_ERR_OR_NULL(tegra->transceiver)) | 798 | if (!IS_ERR_OR_NULL(tegra->transceiver)) |
761 | otg_set_host(tegra->transceiver->otg, NULL); | 799 | otg_set_host(tegra->transceiver->otg, NULL); |
762 | #endif | 800 | #endif |
763 | usb_phy_shutdown(&tegra->phy->u_phy); | 801 | usb_phy_shutdown(hcd->phy); |
764 | fail_io: | 802 | fail_io: |
765 | clk_disable_unprepare(tegra->emc_clk); | ||
766 | fail_emc_clk: | ||
767 | clk_disable_unprepare(tegra->clk); | 803 | clk_disable_unprepare(tegra->clk); |
768 | fail_clk: | 804 | fail_clk: |
769 | usb_put_hcd(hcd); | 805 | usb_put_hcd(hcd); |
@@ -784,15 +820,12 @@ static int tegra_ehci_remove(struct platform_device *pdev) | |||
784 | otg_set_host(tegra->transceiver->otg, NULL); | 820 | otg_set_host(tegra->transceiver->otg, NULL); |
785 | #endif | 821 | #endif |
786 | 822 | ||
823 | usb_phy_shutdown(hcd->phy); | ||
787 | usb_remove_hcd(hcd); | 824 | usb_remove_hcd(hcd); |
788 | usb_put_hcd(hcd); | 825 | usb_put_hcd(hcd); |
789 | 826 | ||
790 | usb_phy_shutdown(&tegra->phy->u_phy); | ||
791 | |||
792 | clk_disable_unprepare(tegra->clk); | 827 | clk_disable_unprepare(tegra->clk); |
793 | 828 | ||
794 | clk_disable_unprepare(tegra->emc_clk); | ||
795 | |||
796 | return 0; | 829 | return 0; |
797 | } | 830 | } |
798 | 831 | ||
diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c index 9d13c81754e0..5487d38481af 100644 --- a/drivers/usb/phy/tegra_usb_phy.c +++ b/drivers/usb/phy/tegra_usb_phy.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
27 | #include <linux/of.h> | ||
27 | #include <linux/of_gpio.h> | 28 | #include <linux/of_gpio.h> |
28 | #include <linux/usb/otg.h> | 29 | #include <linux/usb/otg.h> |
29 | #include <linux/usb/ulpi.h> | 30 | #include <linux/usb/ulpi.h> |
@@ -35,19 +36,6 @@ | |||
35 | 36 | ||
36 | #define ULPI_VIEWPORT 0x170 | 37 | #define ULPI_VIEWPORT 0x170 |
37 | 38 | ||
38 | #define USB_PORTSC1 0x184 | ||
39 | #define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30) | ||
40 | #define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26) | ||
41 | #define USB_PORTSC1_PHCD (1 << 23) | ||
42 | #define USB_PORTSC1_WKOC (1 << 22) | ||
43 | #define USB_PORTSC1_WKDS (1 << 21) | ||
44 | #define USB_PORTSC1_WKCN (1 << 20) | ||
45 | #define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16) | ||
46 | #define USB_PORTSC1_PP (1 << 12) | ||
47 | #define USB_PORTSC1_SUSP (1 << 7) | ||
48 | #define USB_PORTSC1_PE (1 << 2) | ||
49 | #define USB_PORTSC1_CCS (1 << 0) | ||
50 | |||
51 | #define USB_SUSP_CTRL 0x400 | 39 | #define USB_SUSP_CTRL 0x400 |
52 | #define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) | 40 | #define USB_WAKE_ON_CNNT_EN_DEV (1 << 3) |
53 | #define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) | 41 | #define USB_WAKE_ON_DISCON_EN_DEV (1 << 4) |
@@ -208,11 +196,6 @@ static struct tegra_utmip_config utmip_default[] = { | |||
208 | }, | 196 | }, |
209 | }; | 197 | }; |
210 | 198 | ||
211 | static inline bool phy_is_ulpi(struct tegra_usb_phy *phy) | ||
212 | { | ||
213 | return (phy->instance == 1); | ||
214 | } | ||
215 | |||
216 | static int utmip_pad_open(struct tegra_usb_phy *phy) | 199 | static int utmip_pad_open(struct tegra_usb_phy *phy) |
217 | { | 200 | { |
218 | phy->pad_clk = clk_get_sys("utmip-pad", NULL); | 201 | phy->pad_clk = clk_get_sys("utmip-pad", NULL); |
@@ -221,7 +204,7 @@ static int utmip_pad_open(struct tegra_usb_phy *phy) | |||
221 | return PTR_ERR(phy->pad_clk); | 204 | return PTR_ERR(phy->pad_clk); |
222 | } | 205 | } |
223 | 206 | ||
224 | if (phy->instance == 0) { | 207 | if (phy->is_legacy_phy) { |
225 | phy->pad_regs = phy->regs; | 208 | phy->pad_regs = phy->regs; |
226 | } else { | 209 | } else { |
227 | phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); | 210 | phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE); |
@@ -236,7 +219,7 @@ static int utmip_pad_open(struct tegra_usb_phy *phy) | |||
236 | 219 | ||
237 | static void utmip_pad_close(struct tegra_usb_phy *phy) | 220 | static void utmip_pad_close(struct tegra_usb_phy *phy) |
238 | { | 221 | { |
239 | if (phy->instance != 0) | 222 | if (!phy->is_legacy_phy) |
240 | iounmap(phy->pad_regs); | 223 | iounmap(phy->pad_regs); |
241 | clk_put(phy->pad_clk); | 224 | clk_put(phy->pad_clk); |
242 | } | 225 | } |
@@ -305,7 +288,7 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) | |||
305 | unsigned long val; | 288 | unsigned long val; |
306 | void __iomem *base = phy->regs; | 289 | void __iomem *base = phy->regs; |
307 | 290 | ||
308 | if (phy->instance == 0) { | 291 | if (phy->is_legacy_phy) { |
309 | val = readl(base + USB_SUSP_CTRL); | 292 | val = readl(base + USB_SUSP_CTRL); |
310 | val |= USB_SUSP_SET; | 293 | val |= USB_SUSP_SET; |
311 | writel(val, base + USB_SUSP_CTRL); | 294 | writel(val, base + USB_SUSP_CTRL); |
@@ -315,13 +298,8 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) | |||
315 | val = readl(base + USB_SUSP_CTRL); | 298 | val = readl(base + USB_SUSP_CTRL); |
316 | val &= ~USB_SUSP_SET; | 299 | val &= ~USB_SUSP_SET; |
317 | writel(val, base + USB_SUSP_CTRL); | 300 | writel(val, base + USB_SUSP_CTRL); |
318 | } | 301 | } else |
319 | 302 | tegra_ehci_set_phcd(&phy->u_phy, true); | |
320 | if (phy->instance == 2) { | ||
321 | val = readl(base + USB_PORTSC1); | ||
322 | val |= USB_PORTSC1_PHCD; | ||
323 | writel(val, base + USB_PORTSC1); | ||
324 | } | ||
325 | 303 | ||
326 | if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) | 304 | if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) |
327 | pr_err("%s: timeout waiting for phy to stabilize\n", __func__); | 305 | pr_err("%s: timeout waiting for phy to stabilize\n", __func__); |
@@ -332,7 +310,7 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) | |||
332 | unsigned long val; | 310 | unsigned long val; |
333 | void __iomem *base = phy->regs; | 311 | void __iomem *base = phy->regs; |
334 | 312 | ||
335 | if (phy->instance == 0) { | 313 | if (phy->is_legacy_phy) { |
336 | val = readl(base + USB_SUSP_CTRL); | 314 | val = readl(base + USB_SUSP_CTRL); |
337 | val |= USB_SUSP_CLR; | 315 | val |= USB_SUSP_CLR; |
338 | writel(val, base + USB_SUSP_CTRL); | 316 | writel(val, base + USB_SUSP_CTRL); |
@@ -342,13 +320,8 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) | |||
342 | val = readl(base + USB_SUSP_CTRL); | 320 | val = readl(base + USB_SUSP_CTRL); |
343 | val &= ~USB_SUSP_CLR; | 321 | val &= ~USB_SUSP_CLR; |
344 | writel(val, base + USB_SUSP_CTRL); | 322 | writel(val, base + USB_SUSP_CTRL); |
345 | } | 323 | } else |
346 | 324 | tegra_ehci_set_phcd(&phy->u_phy, false); | |
347 | if (phy->instance == 2) { | ||
348 | val = readl(base + USB_PORTSC1); | ||
349 | val &= ~USB_PORTSC1_PHCD; | ||
350 | writel(val, base + USB_PORTSC1); | ||
351 | } | ||
352 | 325 | ||
353 | if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, | 326 | if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, |
354 | USB_PHY_CLK_VALID)) | 327 | USB_PHY_CLK_VALID)) |
@@ -365,7 +338,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) | |||
365 | val |= UTMIP_RESET; | 338 | val |= UTMIP_RESET; |
366 | writel(val, base + USB_SUSP_CTRL); | 339 | writel(val, base + USB_SUSP_CTRL); |
367 | 340 | ||
368 | if (phy->instance == 0) { | 341 | if (phy->is_legacy_phy) { |
369 | val = readl(base + USB1_LEGACY_CTRL); | 342 | val = readl(base + USB1_LEGACY_CTRL); |
370 | val |= USB1_NO_LEGACY_MODE; | 343 | val |= USB1_NO_LEGACY_MODE; |
371 | writel(val, base + USB1_LEGACY_CTRL); | 344 | writel(val, base + USB1_LEGACY_CTRL); |
@@ -440,16 +413,14 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) | |||
440 | val |= UTMIP_BIAS_PDTRK_COUNT(0x5); | 413 | val |= UTMIP_BIAS_PDTRK_COUNT(0x5); |
441 | writel(val, base + UTMIP_BIAS_CFG1); | 414 | writel(val, base + UTMIP_BIAS_CFG1); |
442 | 415 | ||
443 | if (phy->instance == 0) { | 416 | if (phy->is_legacy_phy) { |
444 | val = readl(base + UTMIP_SPARE_CFG0); | 417 | val = readl(base + UTMIP_SPARE_CFG0); |
445 | if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) | 418 | if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) |
446 | val &= ~FUSE_SETUP_SEL; | 419 | val &= ~FUSE_SETUP_SEL; |
447 | else | 420 | else |
448 | val |= FUSE_SETUP_SEL; | 421 | val |= FUSE_SETUP_SEL; |
449 | writel(val, base + UTMIP_SPARE_CFG0); | 422 | writel(val, base + UTMIP_SPARE_CFG0); |
450 | } | 423 | } else { |
451 | |||
452 | if (phy->instance == 2) { | ||
453 | val = readl(base + USB_SUSP_CTRL); | 424 | val = readl(base + USB_SUSP_CTRL); |
454 | val |= UTMIP_PHY_ENABLE; | 425 | val |= UTMIP_PHY_ENABLE; |
455 | writel(val, base + USB_SUSP_CTRL); | 426 | writel(val, base + USB_SUSP_CTRL); |
@@ -459,7 +430,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) | |||
459 | val &= ~UTMIP_RESET; | 430 | val &= ~UTMIP_RESET; |
460 | writel(val, base + USB_SUSP_CTRL); | 431 | writel(val, base + USB_SUSP_CTRL); |
461 | 432 | ||
462 | if (phy->instance == 0) { | 433 | if (phy->is_legacy_phy) { |
463 | val = readl(base + USB1_LEGACY_CTRL); | 434 | val = readl(base + USB1_LEGACY_CTRL); |
464 | val &= ~USB1_VBUS_SENSE_CTL_MASK; | 435 | val &= ~USB1_VBUS_SENSE_CTL_MASK; |
465 | val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; | 436 | val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD; |
@@ -472,11 +443,8 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) | |||
472 | 443 | ||
473 | utmi_phy_clk_enable(phy); | 444 | utmi_phy_clk_enable(phy); |
474 | 445 | ||
475 | if (phy->instance == 2) { | 446 | if (!phy->is_legacy_phy) |
476 | val = readl(base + USB_PORTSC1); | 447 | tegra_ehci_set_pts(&phy->u_phy, 0); |
477 | val &= ~USB_PORTSC1_PTS(~0); | ||
478 | writel(val, base + USB_PORTSC1); | ||
479 | } | ||
480 | 448 | ||
481 | return 0; | 449 | return 0; |
482 | } | 450 | } |
@@ -621,10 +589,6 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy) | |||
621 | return ret; | 589 | return ret; |
622 | } | 590 | } |
623 | 591 | ||
624 | val = readl(base + USB_PORTSC1); | ||
625 | val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN; | ||
626 | writel(val, base + USB_PORTSC1); | ||
627 | |||
628 | val = readl(base + USB_SUSP_CTRL); | 592 | val = readl(base + USB_SUSP_CTRL); |
629 | val |= USB_SUSP_CLR; | 593 | val |= USB_SUSP_CLR; |
630 | writel(val, base + USB_SUSP_CTRL); | 594 | writel(val, base + USB_SUSP_CTRL); |
@@ -639,17 +603,8 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy) | |||
639 | 603 | ||
640 | static int ulpi_phy_power_off(struct tegra_usb_phy *phy) | 604 | static int ulpi_phy_power_off(struct tegra_usb_phy *phy) |
641 | { | 605 | { |
642 | unsigned long val; | ||
643 | void __iomem *base = phy->regs; | ||
644 | struct tegra_ulpi_config *config = phy->config; | 606 | struct tegra_ulpi_config *config = phy->config; |
645 | 607 | ||
646 | /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB | ||
647 | * Controller to immediately bring the ULPI PHY out of low power | ||
648 | */ | ||
649 | val = readl(base + USB_PORTSC1); | ||
650 | val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN); | ||
651 | writel(val, base + USB_PORTSC1); | ||
652 | |||
653 | clk_disable(phy->clk); | 608 | clk_disable(phy->clk); |
654 | return gpio_direction_output(config->reset_gpio, 0); | 609 | return gpio_direction_output(config->reset_gpio, 0); |
655 | } | 610 | } |
@@ -660,7 +615,7 @@ static int tegra_phy_init(struct usb_phy *x) | |||
660 | struct tegra_ulpi_config *ulpi_config; | 615 | struct tegra_ulpi_config *ulpi_config; |
661 | int err; | 616 | int err; |
662 | 617 | ||
663 | if (phy_is_ulpi(phy)) { | 618 | if (phy->is_ulpi_phy) { |
664 | ulpi_config = phy->config; | 619 | ulpi_config = phy->config; |
665 | phy->clk = clk_get_sys(NULL, ulpi_config->clk); | 620 | phy->clk = clk_get_sys(NULL, ulpi_config->clk); |
666 | if (IS_ERR(phy->clk)) { | 621 | if (IS_ERR(phy->clk)) { |
@@ -698,7 +653,7 @@ static void tegra_usb_phy_close(struct usb_phy *x) | |||
698 | { | 653 | { |
699 | struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); | 654 | struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); |
700 | 655 | ||
701 | if (phy_is_ulpi(phy)) | 656 | if (phy->is_ulpi_phy) |
702 | clk_put(phy->clk); | 657 | clk_put(phy->clk); |
703 | else | 658 | else |
704 | utmip_pad_close(phy); | 659 | utmip_pad_close(phy); |
@@ -709,7 +664,7 @@ static void tegra_usb_phy_close(struct usb_phy *x) | |||
709 | 664 | ||
710 | static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) | 665 | static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) |
711 | { | 666 | { |
712 | if (phy_is_ulpi(phy)) | 667 | if (phy->is_ulpi_phy) |
713 | return ulpi_phy_power_on(phy); | 668 | return ulpi_phy_power_on(phy); |
714 | else | 669 | else |
715 | return utmi_phy_power_on(phy); | 670 | return utmi_phy_power_on(phy); |
@@ -717,7 +672,7 @@ static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) | |||
717 | 672 | ||
718 | static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) | 673 | static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) |
719 | { | 674 | { |
720 | if (phy_is_ulpi(phy)) | 675 | if (phy->is_ulpi_phy) |
721 | return ulpi_phy_power_off(phy); | 676 | return ulpi_phy_power_off(phy); |
722 | else | 677 | else |
723 | return utmi_phy_power_off(phy); | 678 | return utmi_phy_power_off(phy); |
@@ -739,8 +694,9 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, | |||
739 | unsigned long parent_rate; | 694 | unsigned long parent_rate; |
740 | int i; | 695 | int i; |
741 | int err; | 696 | int err; |
697 | struct device_node *np = dev->of_node; | ||
742 | 698 | ||
743 | phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); | 699 | phy = kzalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL); |
744 | if (!phy) | 700 | if (!phy) |
745 | return ERR_PTR(-ENOMEM); | 701 | return ERR_PTR(-ENOMEM); |
746 | 702 | ||
@@ -749,9 +705,16 @@ struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, | |||
749 | phy->config = config; | 705 | phy->config = config; |
750 | phy->mode = phy_mode; | 706 | phy->mode = phy_mode; |
751 | phy->dev = dev; | 707 | phy->dev = dev; |
708 | phy->is_legacy_phy = | ||
709 | of_property_read_bool(np, "nvidia,has-legacy-mode"); | ||
710 | err = of_property_match_string(np, "phy_type", "ulpi"); | ||
711 | if (err < 0) | ||
712 | phy->is_ulpi_phy = false; | ||
713 | else | ||
714 | phy->is_ulpi_phy = true; | ||
752 | 715 | ||
753 | if (!phy->config) { | 716 | if (!phy->config) { |
754 | if (phy_is_ulpi(phy)) { | 717 | if (phy->is_ulpi_phy) { |
755 | pr_err("%s: ulpi phy configuration missing", __func__); | 718 | pr_err("%s: ulpi phy configuration missing", __func__); |
756 | err = -EINVAL; | 719 | err = -EINVAL; |
757 | goto err0; | 720 | goto err0; |
@@ -796,45 +759,40 @@ err0: | |||
796 | } | 759 | } |
797 | EXPORT_SYMBOL_GPL(tegra_usb_phy_open); | 760 | EXPORT_SYMBOL_GPL(tegra_usb_phy_open); |
798 | 761 | ||
799 | void tegra_usb_phy_preresume(struct tegra_usb_phy *phy) | 762 | void tegra_usb_phy_preresume(struct usb_phy *x) |
800 | { | 763 | { |
801 | if (!phy_is_ulpi(phy)) | 764 | struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); |
765 | |||
766 | if (!phy->is_ulpi_phy) | ||
802 | utmi_phy_preresume(phy); | 767 | utmi_phy_preresume(phy); |
803 | } | 768 | } |
804 | EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume); | 769 | EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume); |
805 | 770 | ||
806 | void tegra_usb_phy_postresume(struct tegra_usb_phy *phy) | 771 | void tegra_usb_phy_postresume(struct usb_phy *x) |
807 | { | 772 | { |
808 | if (!phy_is_ulpi(phy)) | 773 | struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); |
774 | |||
775 | if (!phy->is_ulpi_phy) | ||
809 | utmi_phy_postresume(phy); | 776 | utmi_phy_postresume(phy); |
810 | } | 777 | } |
811 | EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume); | 778 | EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume); |
812 | 779 | ||
813 | void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, | 780 | void tegra_ehci_phy_restore_start(struct usb_phy *x, |
814 | enum tegra_usb_phy_port_speed port_speed) | 781 | enum tegra_usb_phy_port_speed port_speed) |
815 | { | 782 | { |
816 | if (!phy_is_ulpi(phy)) | 783 | struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); |
784 | |||
785 | if (!phy->is_ulpi_phy) | ||
817 | utmi_phy_restore_start(phy, port_speed); | 786 | utmi_phy_restore_start(phy, port_speed); |
818 | } | 787 | } |
819 | EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start); | 788 | EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start); |
820 | 789 | ||
821 | void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) | 790 | void tegra_ehci_phy_restore_end(struct usb_phy *x) |
822 | { | 791 | { |
823 | if (!phy_is_ulpi(phy)) | 792 | struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy); |
793 | |||
794 | if (!phy->is_ulpi_phy) | ||
824 | utmi_phy_restore_end(phy); | 795 | utmi_phy_restore_end(phy); |
825 | } | 796 | } |
826 | EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); | 797 | EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); |
827 | 798 | ||
828 | void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy) | ||
829 | { | ||
830 | if (!phy_is_ulpi(phy)) | ||
831 | utmi_phy_clk_disable(phy); | ||
832 | } | ||
833 | EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_disable); | ||
834 | |||
835 | void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy) | ||
836 | { | ||
837 | if (!phy_is_ulpi(phy)) | ||
838 | utmi_phy_clk_enable(phy); | ||
839 | } | ||
840 | EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable); | ||
diff --git a/arch/arm/mach-tegra/tegra_cpu_car.h b/include/linux/clk/tegra.h index 9764d31032b7..404d6f940872 100644 --- a/arch/arm/mach-tegra/tegra_cpu_car.h +++ b/include/linux/clk/tegra.h | |||
@@ -14,8 +14,10 @@ | |||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #ifndef __MACH_TEGRA_CPU_CAR_H | 17 | #ifndef __LINUX_CLK_TEGRA_H_ |
18 | #define __MACH_TEGRA_CPU_CAR_H | 18 | #define __LINUX_CLK_TEGRA_H_ |
19 | |||
20 | #include <linux/clk.h> | ||
19 | 21 | ||
20 | /* | 22 | /* |
21 | * Tegra CPU clock and reset control ops | 23 | * Tegra CPU clock and reset control ops |
@@ -118,7 +120,8 @@ static inline void tegra_cpu_clock_resume(void) | |||
118 | } | 120 | } |
119 | #endif | 121 | #endif |
120 | 122 | ||
121 | void tegra20_cpu_car_ops_init(void); | 123 | void tegra_periph_reset_deassert(struct clk *c); |
122 | void tegra30_cpu_car_ops_init(void); | 124 | void tegra_periph_reset_assert(struct clk *c); |
125 | void tegra_clocks_init(void); | ||
123 | 126 | ||
124 | #endif /* __MACH_TEGRA_CPU_CAR_H */ | 127 | #endif /* __LINUX_CLK_TEGRA_H_ */ |
diff --git a/include/linux/platform_data/usb-omap.h b/include/linux/platform_data/usb-omap.h index ef65b67c56c3..e697c85ad3bc 100644 --- a/include/linux/platform_data/usb-omap.h +++ b/include/linux/platform_data/usb-omap.h | |||
@@ -55,13 +55,17 @@ struct ohci_hcd_omap_platform_data { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | struct usbhs_omap_platform_data { | 57 | struct usbhs_omap_platform_data { |
58 | enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; | 58 | enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; |
59 | int reset_gpio_port[OMAP3_HS_USB_PORTS]; | ||
60 | struct regulator *regulator[OMAP3_HS_USB_PORTS]; | ||
59 | 61 | ||
60 | struct ehci_hcd_omap_platform_data *ehci_data; | 62 | struct ehci_hcd_omap_platform_data *ehci_data; |
61 | struct ohci_hcd_omap_platform_data *ohci_data; | 63 | struct ohci_hcd_omap_platform_data *ohci_data; |
62 | 64 | ||
63 | /* OMAP3 <= ES2.1 have a single ulpi bypass control bit */ | 65 | /* OMAP3 <= ES2.1 have a single ulpi bypass control bit */ |
64 | unsigned single_ulpi_bypass:1; | 66 | unsigned single_ulpi_bypass:1; |
67 | unsigned es2_compatibility:1; | ||
68 | unsigned phy_reset:1; | ||
65 | }; | 69 | }; |
66 | 70 | ||
67 | /*-------------------------------------------------------------------------*/ | 71 | /*-------------------------------------------------------------------------*/ |
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h new file mode 100644 index 000000000000..95f611d78f3a --- /dev/null +++ b/include/linux/tegra-soc.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __LINUX_TEGRA_SOC_H_ | ||
18 | #define __LINUX_TEGRA_SOC_H_ | ||
19 | |||
20 | u32 tegra_read_chipid(void); | ||
21 | |||
22 | #endif /* __LINUX_TEGRA_SOC_H_ */ | ||
diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h index 176b1ca06ae4..9ebebe906925 100644 --- a/include/linux/usb/tegra_usb_phy.h +++ b/include/linux/usb/tegra_usb_phy.h | |||
@@ -59,22 +59,24 @@ struct tegra_usb_phy { | |||
59 | struct usb_phy *ulpi; | 59 | struct usb_phy *ulpi; |
60 | struct usb_phy u_phy; | 60 | struct usb_phy u_phy; |
61 | struct device *dev; | 61 | struct device *dev; |
62 | bool is_legacy_phy; | ||
63 | bool is_ulpi_phy; | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, | 66 | struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, |
65 | void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode); | 67 | void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode); |
66 | 68 | ||
67 | void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy); | 69 | void tegra_usb_phy_preresume(struct usb_phy *phy); |
68 | 70 | ||
69 | void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy); | 71 | void tegra_usb_phy_postresume(struct usb_phy *phy); |
70 | 72 | ||
71 | void tegra_usb_phy_preresume(struct tegra_usb_phy *phy); | 73 | void tegra_ehci_phy_restore_start(struct usb_phy *phy, |
74 | enum tegra_usb_phy_port_speed port_speed); | ||
72 | 75 | ||
73 | void tegra_usb_phy_postresume(struct tegra_usb_phy *phy); | 76 | void tegra_ehci_phy_restore_end(struct usb_phy *phy); |
74 | 77 | ||
75 | void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, | 78 | void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val); |
76 | enum tegra_usb_phy_port_speed port_speed); | ||
77 | 79 | ||
78 | void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy); | 80 | void tegra_ehci_set_phcd(struct usb_phy *x, bool enable); |
79 | 81 | ||
80 | #endif /* __TEGRA_USB_PHY_H */ | 82 | #endif /* __TEGRA_USB_PHY_H */ |
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index dd146f10fef2..e5cfb4ac41ba 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/pm_runtime.h> | 25 | #include <linux/pm_runtime.h> |
26 | #include <linux/regmap.h> | 26 | #include <linux/regmap.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <mach/clk.h> | 28 | #include <linux/clk/tegra.h> |
29 | #include <sound/soc.h> | 29 | #include <sound/soc.h> |
30 | #include "tegra30_ahub.h" | 30 | #include "tegra30_ahub.h" |
31 | 31 | ||
@@ -299,15 +299,6 @@ static const char * const configlink_clocks[] = { | |||
299 | "spdif_in", | 299 | "spdif_in", |
300 | }; | 300 | }; |
301 | 301 | ||
302 | struct of_dev_auxdata ahub_auxdata[] = { | ||
303 | OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080300, "tegra30-i2s.0", NULL), | ||
304 | OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080400, "tegra30-i2s.1", NULL), | ||
305 | OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL), | ||
306 | OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080600, "tegra30-i2s.3", NULL), | ||
307 | OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080700, "tegra30-i2s.4", NULL), | ||
308 | {} | ||
309 | }; | ||
310 | |||
311 | #define LAST_REG(name) \ | 302 | #define LAST_REG(name) \ |
312 | (TEGRA30_AHUB_##name + \ | 303 | (TEGRA30_AHUB_##name + \ |
313 | (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4) | 304 | (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4) |
@@ -451,7 +442,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev) | |||
451 | * Ensure that here. | 442 | * Ensure that here. |
452 | */ | 443 | */ |
453 | for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { | 444 | for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { |
454 | clk = clk_get_sys(NULL, configlink_clocks[i]); | 445 | clk = clk_get(&pdev->dev, configlink_clocks[i]); |
455 | if (IS_ERR(clk)) { | 446 | if (IS_ERR(clk)) { |
456 | dev_err(&pdev->dev, "Can't get clock %s\n", | 447 | dev_err(&pdev->dev, "Can't get clock %s\n", |
457 | configlink_clocks[i]); | 448 | configlink_clocks[i]); |
@@ -569,8 +560,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev) | |||
569 | goto err_pm_disable; | 560 | goto err_pm_disable; |
570 | } | 561 | } |
571 | 562 | ||
572 | of_platform_populate(pdev->dev.of_node, NULL, ahub_auxdata, | 563 | of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); |
573 | &pdev->dev); | ||
574 | 564 | ||
575 | return 0; | 565 | return 0; |
576 | 566 | ||