diff options
author | Olof Johansson <olof@lixom.net> | 2013-02-05 16:19:03 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-02-05 16:19:03 -0500 |
commit | 0b6ad80abb1ad1584347e5ec5c5739ebc540a1a7 (patch) | |
tree | a91d4934ac4ffda651804b30554bb6da5af572d4 | |
parent | f015941f6b4a7d4d90c46a65bca17f2c2c41fb89 (diff) | |
parent | f7c66dc0bf0f4ecd349c79315c87841c67e27aef (diff) |
Merge branch 'next/soc' into next/dt
210 files changed, 10629 insertions, 10093 deletions
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 42ee64e68c43..b70ee954f69f 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 |
@@ -642,6 +643,7 @@ config ARCH_TEGRA | |||
642 | select ARCH_HAS_CPUFREQ | 643 | select ARCH_HAS_CPUFREQ |
643 | select CLKDEV_LOOKUP | 644 | select CLKDEV_LOOKUP |
644 | select CLKSRC_MMIO | 645 | select CLKSRC_MMIO |
646 | select CLKSRC_OF | ||
645 | select COMMON_CLK | 647 | select COMMON_CLK |
646 | select GENERIC_CLOCKEVENTS | 648 | select GENERIC_CLOCKEVENTS |
647 | select GENERIC_GPIO | 649 | select GENERIC_GPIO |
@@ -951,22 +953,6 @@ config ARCH_OMAP | |||
951 | help | 953 | help |
952 | Support for TI's OMAP platform (OMAP1/2/3/4). | 954 | Support for TI's OMAP platform (OMAP1/2/3/4). |
953 | 955 | ||
954 | config ARCH_VT8500_SINGLE | ||
955 | bool "VIA/WonderMedia 85xx" | ||
956 | select ARCH_HAS_CPUFREQ | ||
957 | select ARCH_REQUIRE_GPIOLIB | ||
958 | select CLKDEV_LOOKUP | ||
959 | select COMMON_CLK | ||
960 | select CPU_ARM926T | ||
961 | select GENERIC_CLOCKEVENTS | ||
962 | select GENERIC_GPIO | ||
963 | select HAVE_CLK | ||
964 | select MULTI_IRQ_HANDLER | ||
965 | select SPARSE_IRQ | ||
966 | select USE_OF | ||
967 | help | ||
968 | Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. | ||
969 | |||
970 | endchoice | 956 | endchoice |
971 | 957 | ||
972 | menu "Multiple platform selection" | 958 | menu "Multiple platform selection" |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 661030d6bc6c..0cc8e3652b0e 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -219,12 +219,12 @@ choice | |||
219 | Say Y here if you want kernel low-level debugging support | 219 | Say Y here if you want kernel low-level debugging support |
220 | on i.MX51. | 220 | on i.MX51. |
221 | 221 | ||
222 | config DEBUG_IMX50_IMX53_UART | 222 | config DEBUG_IMX53_UART |
223 | bool "i.MX50 and i.MX53 Debug UART" | 223 | bool "i.MX53 Debug UART" |
224 | depends on SOC_IMX50 || SOC_IMX53 | 224 | depends on SOC_IMX53 |
225 | help | 225 | help |
226 | Say Y here if you want kernel low-level debugging support | 226 | Say Y here if you want kernel low-level debugging support |
227 | on i.MX50 or i.MX53. | 227 | on i.MX53. |
228 | 228 | ||
229 | config DEBUG_IMX6Q_UART | 229 | config DEBUG_IMX6Q_UART |
230 | bool "i.MX6Q Debug UART" | 230 | bool "i.MX6Q Debug UART" |
@@ -386,6 +386,20 @@ choice | |||
386 | Say Y here if you want kernel low-level debugging support | 386 | Say Y here if you want kernel low-level debugging support |
387 | on Tegra based platforms. | 387 | on Tegra based platforms. |
388 | 388 | ||
389 | config DEBUG_SIRFPRIMA2_UART1 | ||
390 | bool "Kernel low-level debugging messages via SiRFprimaII UART1" | ||
391 | depends on ARCH_PRIMA2 | ||
392 | help | ||
393 | Say Y here if you want the debug print routines to direct | ||
394 | their output to the uart1 port on SiRFprimaII devices. | ||
395 | |||
396 | config DEBUG_SIRFMARCO_UART1 | ||
397 | bool "Kernel low-level debugging messages via SiRFmarco UART1" | ||
398 | depends on ARCH_MARCO | ||
399 | help | ||
400 | Say Y here if you want the debug print routines to direct | ||
401 | their output to the uart1 port on SiRFmarco devices. | ||
402 | |||
389 | config DEBUG_VEXPRESS_UART0_DETECT | 403 | config DEBUG_VEXPRESS_UART0_DETECT |
390 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" | 404 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" |
391 | depends on ARCH_VEXPRESS && CPU_CP15_MMU | 405 | depends on ARCH_VEXPRESS && CPU_CP15_MMU |
@@ -412,6 +426,13 @@ choice | |||
412 | of the tiles using the RS1 memory map, including all new A-class | 426 | of the tiles using the RS1 memory map, including all new A-class |
413 | core tiles, FPGA-based SMMs and software models. | 427 | core tiles, FPGA-based SMMs and software models. |
414 | 428 | ||
429 | config DEBUG_VT8500_UART0 | ||
430 | bool "Use UART0 on VIA/Wondermedia SoCs" | ||
431 | depends on ARCH_VT8500 | ||
432 | help | ||
433 | This option selects UART0 on VIA/Wondermedia System-on-a-chip | ||
434 | devices, including VT8500, WM8505, WM8650 and WM8850. | ||
435 | |||
415 | config DEBUG_LL_UART_NONE | 436 | config DEBUG_LL_UART_NONE |
416 | bool "No low-level debugging UART" | 437 | bool "No low-level debugging UART" |
417 | depends on !ARCH_MULTIPLATFORM | 438 | depends on !ARCH_MULTIPLATFORM |
@@ -497,7 +518,7 @@ config DEBUG_LL_INCLUDE | |||
497 | DEBUG_IMX21_IMX27_UART || \ | 518 | DEBUG_IMX21_IMX27_UART || \ |
498 | DEBUG_IMX31_IMX35_UART || \ | 519 | DEBUG_IMX31_IMX35_UART || \ |
499 | DEBUG_IMX51_UART || \ | 520 | DEBUG_IMX51_UART || \ |
500 | DEBUG_IMX50_IMX53_UART ||\ | 521 | DEBUG_IMX53_UART ||\ |
501 | DEBUG_IMX6Q_UART | 522 | DEBUG_IMX6Q_UART |
502 | default "debug/highbank.S" if DEBUG_HIGHBANK_UART | 523 | default "debug/highbank.S" if DEBUG_HIGHBANK_UART |
503 | default "debug/mvebu.S" if DEBUG_MVEBU_UART | 524 | default "debug/mvebu.S" if DEBUG_MVEBU_UART |
@@ -506,6 +527,7 @@ config DEBUG_LL_INCLUDE | |||
506 | default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1 | 527 | default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1 |
507 | default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ | 528 | default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ |
508 | DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 | 529 | DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 |
530 | default "debug/vt8500.S" if DEBUG_VT8500_UART0 | ||
509 | default "debug/tegra.S" if DEBUG_TEGRA_UART | 531 | default "debug/tegra.S" if DEBUG_TEGRA_UART |
510 | default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 | 532 | default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 |
511 | default "mach/debug-macro.S" | 533 | default "mach/debug-macro.S" |
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 3d115dcb3461..ca683a66b498 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 \ |
@@ -144,7 +145,9 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ | |||
144 | tegra20-ventana.dtb \ | 145 | tegra20-ventana.dtb \ |
145 | tegra20-whistler.dtb \ | 146 | tegra20-whistler.dtb \ |
146 | tegra30-cardhu-a02.dtb \ | 147 | tegra30-cardhu-a02.dtb \ |
147 | tegra30-cardhu-a04.dtb | 148 | tegra30-cardhu-a04.dtb \ |
149 | tegra114-dalmore.dtb \ | ||
150 | tegra114-pluto.dtb | ||
148 | dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ | 151 | dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ |
149 | vexpress-v2p-ca9.dtb \ | 152 | vexpress-v2p-ca9.dtb \ |
150 | vexpress-v2p-ca15-tc1.dtb \ | 153 | vexpress-v2p-ca15-tc1.dtb \ |
@@ -152,7 +155,8 @@ dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ | |||
152 | xenvm-4.2.dtb | 155 | xenvm-4.2.dtb |
153 | dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ | 156 | dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ |
154 | wm8505-ref.dtb \ | 157 | wm8505-ref.dtb \ |
155 | wm8650-mid.dtb | 158 | wm8650-mid.dtb \ |
159 | wm8850-w70v2.dtb | ||
156 | dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb | 160 | dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb |
157 | 161 | ||
158 | targets += dtbs | 162 | targets += dtbs |
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index 42eac1ff3cc8..740630f9cd65 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi | |||
@@ -93,6 +93,7 @@ | |||
93 | reg = <0xd0400 0x20>; | 93 | reg = <0xd0400 0x20>; |
94 | ngpios = <32>; | 94 | ngpios = <32>; |
95 | interrupt-controller; | 95 | interrupt-controller; |
96 | #interrupt-cells = <2>; | ||
96 | interrupts = <12>, <13>, <14>, <60>; | 97 | interrupts = <12>, <13>, <14>, <60>; |
97 | }; | 98 | }; |
98 | 99 | ||
@@ -103,6 +104,7 @@ | |||
103 | reg = <0xd0420 0x20>; | 104 | reg = <0xd0420 0x20>; |
104 | ngpios = <32>; | 105 | ngpios = <32>; |
105 | interrupt-controller; | 106 | interrupt-controller; |
107 | #interrupt-cells = <2>; | ||
106 | interrupts = <61>; | 108 | interrupts = <61>; |
107 | }; | 109 | }; |
108 | 110 | ||
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/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 69667133321f..d946372c4300 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 |
@@ -32,7 +33,6 @@ CONFIG_MACH_PCM043=y | |||
32 | CONFIG_MACH_MX35_3DS=y | 33 | CONFIG_MACH_MX35_3DS=y |
33 | CONFIG_MACH_VPR200=y | 34 | CONFIG_MACH_VPR200=y |
34 | CONFIG_MACH_IMX51_DT=y | 35 | CONFIG_MACH_IMX51_DT=y |
35 | CONFIG_MACH_MX51_3DS=y | ||
36 | CONFIG_MACH_EUKREA_CPUIMX51SD=y | 36 | CONFIG_MACH_EUKREA_CPUIMX51SD=y |
37 | CONFIG_SOC_IMX53=y | 37 | CONFIG_SOC_IMX53=y |
38 | CONFIG_SOC_IMX6Q=y | 38 | CONFIG_SOC_IMX6Q=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/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index b5bc96cb65a7..cbd91bce1ca9 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig | |||
@@ -33,6 +33,8 @@ CONFIG_MVNETA=y | |||
33 | CONFIG_MARVELL_PHY=y | 33 | CONFIG_MARVELL_PHY=y |
34 | CONFIG_SERIAL_8250=y | 34 | CONFIG_SERIAL_8250=y |
35 | CONFIG_SERIAL_8250_CONSOLE=y | 35 | CONFIG_SERIAL_8250_CONSOLE=y |
36 | CONFIG_I2C=y | ||
37 | CONFIG_I2C_MV64XXX=y | ||
36 | CONFIG_SERIAL_8250_DW=y | 38 | CONFIG_SERIAL_8250_DW=y |
37 | CONFIG_GPIOLIB=y | 39 | CONFIG_GPIOLIB=y |
38 | CONFIG_GPIO_SYSFS=y | 40 | CONFIG_GPIO_SYSFS=y |
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/cputype.h b/arch/arm/include/asm/cputype.h index a59dcb5ab5fc..ad41ec2471e8 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h | |||
@@ -64,6 +64,24 @@ extern unsigned int processor_id; | |||
64 | #define read_cpuid_ext(reg) 0 | 64 | #define read_cpuid_ext(reg) 0 |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #define ARM_CPU_IMP_ARM 0x41 | ||
68 | #define ARM_CPU_IMP_INTEL 0x69 | ||
69 | |||
70 | #define ARM_CPU_PART_ARM1136 0xB360 | ||
71 | #define ARM_CPU_PART_ARM1156 0xB560 | ||
72 | #define ARM_CPU_PART_ARM1176 0xB760 | ||
73 | #define ARM_CPU_PART_ARM11MPCORE 0xB020 | ||
74 | #define ARM_CPU_PART_CORTEX_A8 0xC080 | ||
75 | #define ARM_CPU_PART_CORTEX_A9 0xC090 | ||
76 | #define ARM_CPU_PART_CORTEX_A5 0xC050 | ||
77 | #define ARM_CPU_PART_CORTEX_A15 0xC0F0 | ||
78 | #define ARM_CPU_PART_CORTEX_A7 0xC070 | ||
79 | |||
80 | #define ARM_CPU_XSCALE_ARCH_MASK 0xe000 | ||
81 | #define ARM_CPU_XSCALE_ARCH_V1 0x2000 | ||
82 | #define ARM_CPU_XSCALE_ARCH_V2 0x4000 | ||
83 | #define ARM_CPU_XSCALE_ARCH_V3 0x6000 | ||
84 | |||
67 | /* | 85 | /* |
68 | * The CPU ID never changes at run time, so we might as well tell the | 86 | * The CPU ID never changes at run time, so we might as well tell the |
69 | * compiler that it's constant. Use this function to read the CPU ID | 87 | * compiler that it's constant. Use this function to read the CPU ID |
@@ -74,6 +92,21 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void) | |||
74 | return read_cpuid(CPUID_ID); | 92 | return read_cpuid(CPUID_ID); |
75 | } | 93 | } |
76 | 94 | ||
95 | static inline unsigned int __attribute_const__ read_cpuid_implementor(void) | ||
96 | { | ||
97 | return (read_cpuid_id() & 0xFF000000) >> 24; | ||
98 | } | ||
99 | |||
100 | static inline unsigned int __attribute_const__ read_cpuid_part_number(void) | ||
101 | { | ||
102 | return read_cpuid_id() & 0xFFF0; | ||
103 | } | ||
104 | |||
105 | static inline unsigned int __attribute_const__ xscale_cpu_arch_version(void) | ||
106 | { | ||
107 | return read_cpuid_part_number() & ARM_CPU_XSCALE_ARCH_MASK; | ||
108 | } | ||
109 | |||
77 | static inline unsigned int __attribute_const__ read_cpuid_cachetype(void) | 110 | static inline unsigned int __attribute_const__ read_cpuid_cachetype(void) |
78 | { | 111 | { |
79 | return read_cpuid(CPUID_CACHETYPE); | 112 | return read_cpuid(CPUID_CACHETYPE); |
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h index 4eb6d005ffaa..006f02681cd8 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 | void scu_enable(void __iomem *); | 27 | void scu_enable(void __iomem *); |
11 | int scu_power_mode(void __iomem *, unsigned int); | 28 | int scu_power_mode(void __iomem *, unsigned int); |
diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index 0c4e17d4d359..c6f294cf18f0 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S | |||
@@ -34,7 +34,7 @@ | |||
34 | #define UART_PADDR 0x43f90000 | 34 | #define UART_PADDR 0x43f90000 |
35 | #elif defined (CONFIG_DEBUG_IMX51_UART) | 35 | #elif defined (CONFIG_DEBUG_IMX51_UART) |
36 | #define UART_PADDR 0x73fbc000 | 36 | #define UART_PADDR 0x73fbc000 |
37 | #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART) | 37 | #elif defined (CONFIG_DEBUG_IMX53_UART) |
38 | #define UART_PADDR 0x53fbc000 | 38 | #define UART_PADDR 0x53fbc000 |
39 | #elif defined (CONFIG_DEBUG_IMX6Q_UART) | 39 | #elif defined (CONFIG_DEBUG_IMX6Q_UART) |
40 | #define UART_PADDR IMX6Q_DEBUG_UART_BASE | 40 | #define UART_PADDR IMX6Q_DEBUG_UART_BASE |
diff --git a/arch/arm/mach-vt8500/include/mach/debug-macro.S b/arch/arm/include/debug/vt8500.S index ca292f29d4a3..0e0ca0869da7 100644 --- a/arch/arm/mach-vt8500/include/mach/debug-macro.S +++ b/arch/arm/include/debug/vt8500.S | |||
@@ -1,20 +1,24 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-vt8500/include/mach/debug-macro.S | 2 | * Debugging macro include header |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | 4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> |
5 | * | 5 | * Moved from arch/arm/mach-vt8500/include/mach/debug-macro.S |
6 | * Debugging macro include header | 6 | * Minor changes for readability. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | */ |
12 | */ | 12 | |
13 | #define DEBUG_LL_PHYS_BASE 0xD8000000 | ||
14 | #define DEBUG_LL_VIRT_BASE 0xF8000000 | ||
15 | #define DEBUG_LL_UART_OFFSET 0x00200000 | ||
13 | 16 | ||
17 | #if defined(CONFIG_DEBUG_VT8500_UART0) | ||
14 | .macro addruart, rp, rv, tmp | 18 | .macro addruart, rp, rv, tmp |
15 | mov \rp, #0x00200000 | 19 | mov \rp, #DEBUG_LL_UART_OFFSET |
16 | orr \rv, \rp, #0xf8000000 | 20 | orr \rv, \rp, #DEBUG_LL_VIRT_BASE |
17 | orr \rp, \rp, #0xd8000000 | 21 | orr \rp, \rp, #DEBUG_LL_PHYS_BASE |
18 | .endm | 22 | .endm |
19 | 23 | ||
20 | .macro senduart,rd,rx | 24 | .macro senduart,rd,rx |
@@ -29,3 +33,5 @@ | |||
29 | 33 | ||
30 | .macro waituart,rd,rx | 34 | .macro waituart,rd,rx |
31 | .endm | 35 | .endm |
36 | |||
37 | #endif | ||
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index f9e8657dd241..31e0eb353cd8 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -149,12 +149,6 @@ again: | |||
149 | static void | 149 | static void |
150 | armpmu_read(struct perf_event *event) | 150 | armpmu_read(struct perf_event *event) |
151 | { | 151 | { |
152 | struct hw_perf_event *hwc = &event->hw; | ||
153 | |||
154 | /* Don't read disabled counters! */ | ||
155 | if (hwc->idx < 0) | ||
156 | return; | ||
157 | |||
158 | armpmu_event_update(event); | 152 | armpmu_event_update(event); |
159 | } | 153 | } |
160 | 154 | ||
@@ -207,8 +201,6 @@ armpmu_del(struct perf_event *event, int flags) | |||
207 | struct hw_perf_event *hwc = &event->hw; | 201 | struct hw_perf_event *hwc = &event->hw; |
208 | int idx = hwc->idx; | 202 | int idx = hwc->idx; |
209 | 203 | ||
210 | WARN_ON(idx < 0); | ||
211 | |||
212 | armpmu_stop(event, PERF_EF_UPDATE); | 204 | armpmu_stop(event, PERF_EF_UPDATE); |
213 | hw_events->events[idx] = NULL; | 205 | hw_events->events[idx] = NULL; |
214 | clear_bit(idx, hw_events->used_mask); | 206 | clear_bit(idx, hw_events->used_mask); |
@@ -358,7 +350,7 @@ __hw_perf_event_init(struct perf_event *event) | |||
358 | { | 350 | { |
359 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | 351 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); |
360 | struct hw_perf_event *hwc = &event->hw; | 352 | struct hw_perf_event *hwc = &event->hw; |
361 | int mapping, err; | 353 | int mapping; |
362 | 354 | ||
363 | mapping = armpmu->map_event(event); | 355 | mapping = armpmu->map_event(event); |
364 | 356 | ||
@@ -407,14 +399,12 @@ __hw_perf_event_init(struct perf_event *event) | |||
407 | local64_set(&hwc->period_left, hwc->sample_period); | 399 | local64_set(&hwc->period_left, hwc->sample_period); |
408 | } | 400 | } |
409 | 401 | ||
410 | err = 0; | ||
411 | if (event->group_leader != event) { | 402 | if (event->group_leader != event) { |
412 | err = validate_group(event); | 403 | if (validate_group(event) != 0); |
413 | if (err) | ||
414 | return -EINVAL; | 404 | return -EINVAL; |
415 | } | 405 | } |
416 | 406 | ||
417 | return err; | 407 | return 0; |
418 | } | 408 | } |
419 | 409 | ||
420 | static int armpmu_event_init(struct perf_event *event) | 410 | static int armpmu_event_init(struct perf_event *event) |
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index 5f6620684e25..1f2740e3dbc0 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c | |||
@@ -147,7 +147,7 @@ static void cpu_pmu_init(struct arm_pmu *cpu_pmu) | |||
147 | cpu_pmu->free_irq = cpu_pmu_free_irq; | 147 | cpu_pmu->free_irq = cpu_pmu_free_irq; |
148 | 148 | ||
149 | /* Ensure the PMU has sane values out of reset. */ | 149 | /* Ensure the PMU has sane values out of reset. */ |
150 | if (cpu_pmu && cpu_pmu->reset) | 150 | if (cpu_pmu->reset) |
151 | on_each_cpu(cpu_pmu->reset, cpu_pmu, 1); | 151 | on_each_cpu(cpu_pmu->reset, cpu_pmu, 1); |
152 | } | 152 | } |
153 | 153 | ||
@@ -201,48 +201,46 @@ static struct platform_device_id cpu_pmu_plat_device_ids[] = { | |||
201 | static int probe_current_pmu(struct arm_pmu *pmu) | 201 | static int probe_current_pmu(struct arm_pmu *pmu) |
202 | { | 202 | { |
203 | int cpu = get_cpu(); | 203 | int cpu = get_cpu(); |
204 | unsigned long cpuid = read_cpuid_id(); | 204 | unsigned long implementor = read_cpuid_implementor(); |
205 | unsigned long implementor = (cpuid & 0xFF000000) >> 24; | 205 | unsigned long part_number = read_cpuid_part_number(); |
206 | unsigned long part_number = (cpuid & 0xFFF0); | ||
207 | int ret = -ENODEV; | 206 | int ret = -ENODEV; |
208 | 207 | ||
209 | pr_info("probing PMU on CPU %d\n", cpu); | 208 | pr_info("probing PMU on CPU %d\n", cpu); |
210 | 209 | ||
211 | /* ARM Ltd CPUs. */ | 210 | /* ARM Ltd CPUs. */ |
212 | if (0x41 == implementor) { | 211 | if (implementor == ARM_CPU_IMP_ARM) { |
213 | switch (part_number) { | 212 | switch (part_number) { |
214 | case 0xB360: /* ARM1136 */ | 213 | case ARM_CPU_PART_ARM1136: |
215 | case 0xB560: /* ARM1156 */ | 214 | case ARM_CPU_PART_ARM1156: |
216 | case 0xB760: /* ARM1176 */ | 215 | case ARM_CPU_PART_ARM1176: |
217 | ret = armv6pmu_init(pmu); | 216 | ret = armv6pmu_init(pmu); |
218 | break; | 217 | break; |
219 | case 0xB020: /* ARM11mpcore */ | 218 | case ARM_CPU_PART_ARM11MPCORE: |
220 | ret = armv6mpcore_pmu_init(pmu); | 219 | ret = armv6mpcore_pmu_init(pmu); |
221 | break; | 220 | break; |
222 | case 0xC080: /* Cortex-A8 */ | 221 | case ARM_CPU_PART_CORTEX_A8: |
223 | ret = armv7_a8_pmu_init(pmu); | 222 | ret = armv7_a8_pmu_init(pmu); |
224 | break; | 223 | break; |
225 | case 0xC090: /* Cortex-A9 */ | 224 | case ARM_CPU_PART_CORTEX_A9: |
226 | ret = armv7_a9_pmu_init(pmu); | 225 | ret = armv7_a9_pmu_init(pmu); |
227 | break; | 226 | break; |
228 | case 0xC050: /* Cortex-A5 */ | 227 | case ARM_CPU_PART_CORTEX_A5: |
229 | ret = armv7_a5_pmu_init(pmu); | 228 | ret = armv7_a5_pmu_init(pmu); |
230 | break; | 229 | break; |
231 | case 0xC0F0: /* Cortex-A15 */ | 230 | case ARM_CPU_PART_CORTEX_A15: |
232 | ret = armv7_a15_pmu_init(pmu); | 231 | ret = armv7_a15_pmu_init(pmu); |
233 | break; | 232 | break; |
234 | case 0xC070: /* Cortex-A7 */ | 233 | case ARM_CPU_PART_CORTEX_A7: |
235 | ret = armv7_a7_pmu_init(pmu); | 234 | ret = armv7_a7_pmu_init(pmu); |
236 | break; | 235 | break; |
237 | } | 236 | } |
238 | /* Intel CPUs [xscale]. */ | 237 | /* Intel CPUs [xscale]. */ |
239 | } else if (0x69 == implementor) { | 238 | } else if (implementor == ARM_CPU_IMP_INTEL) { |
240 | part_number = (cpuid >> 13) & 0x7; | 239 | switch (xscale_cpu_arch_version()) { |
241 | switch (part_number) { | 240 | case ARM_CPU_XSCALE_ARCH_V1: |
242 | case 1: | ||
243 | ret = xscale1pmu_init(pmu); | 241 | ret = xscale1pmu_init(pmu); |
244 | break; | 242 | break; |
245 | case 2: | 243 | case ARM_CPU_XSCALE_ARCH_V2: |
246 | ret = xscale2pmu_init(pmu); | 244 | ret = xscale2pmu_init(pmu); |
247 | break; | 245 | break; |
248 | } | 246 | } |
@@ -279,17 +277,22 @@ static int cpu_pmu_device_probe(struct platform_device *pdev) | |||
279 | } | 277 | } |
280 | 278 | ||
281 | if (ret) { | 279 | if (ret) { |
282 | pr_info("failed to register PMU devices!"); | 280 | pr_info("failed to probe PMU!"); |
283 | kfree(pmu); | 281 | goto out_free; |
284 | return ret; | ||
285 | } | 282 | } |
286 | 283 | ||
287 | cpu_pmu = pmu; | 284 | cpu_pmu = pmu; |
288 | cpu_pmu->plat_device = pdev; | 285 | cpu_pmu->plat_device = pdev; |
289 | cpu_pmu_init(cpu_pmu); | 286 | cpu_pmu_init(cpu_pmu); |
290 | armpmu_register(cpu_pmu, PERF_TYPE_RAW); | 287 | ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW); |
291 | 288 | ||
292 | return 0; | 289 | if (!ret) |
290 | return 0; | ||
291 | |||
292 | out_free: | ||
293 | pr_info("failed to register PMU devices!"); | ||
294 | kfree(pmu); | ||
295 | return ret; | ||
293 | } | 296 | } |
294 | 297 | ||
295 | static struct platform_driver cpu_pmu_driver = { | 298 | static struct platform_driver cpu_pmu_driver = { |
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index 041d0526a288..03664b0e8fa4 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c | |||
@@ -106,7 +106,7 @@ static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
106 | }, | 106 | }, |
107 | [C(OP_WRITE)] = { | 107 | [C(OP_WRITE)] = { |
108 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 108 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
109 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS, | 109 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
110 | }, | 110 | }, |
111 | [C(OP_PREFETCH)] = { | 111 | [C(OP_PREFETCH)] = { |
112 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 112 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
@@ -259,7 +259,7 @@ static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
259 | }, | 259 | }, |
260 | [C(OP_WRITE)] = { | 260 | [C(OP_WRITE)] = { |
261 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 261 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
262 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS, | 262 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
263 | }, | 263 | }, |
264 | [C(OP_PREFETCH)] = { | 264 | [C(OP_PREFETCH)] = { |
265 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 265 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 4fbc757d9cff..8c79a9e70b83 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c | |||
@@ -157,8 +157,8 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
157 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 157 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, |
158 | }, | 158 | }, |
159 | [C(OP_WRITE)] = { | 159 | [C(OP_WRITE)] = { |
160 | [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS, | 160 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
161 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 161 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
162 | }, | 162 | }, |
163 | [C(OP_PREFETCH)] = { | 163 | [C(OP_PREFETCH)] = { |
164 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 164 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
@@ -282,7 +282,7 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
282 | }, | 282 | }, |
283 | [C(OP_WRITE)] = { | 283 | [C(OP_WRITE)] = { |
284 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 284 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
285 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 285 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
286 | }, | 286 | }, |
287 | [C(OP_PREFETCH)] = { | 287 | [C(OP_PREFETCH)] = { |
288 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 288 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
@@ -399,8 +399,8 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
399 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 399 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, |
400 | }, | 400 | }, |
401 | [C(OP_WRITE)] = { | 401 | [C(OP_WRITE)] = { |
402 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, | 402 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
403 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 403 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
404 | }, | 404 | }, |
405 | /* | 405 | /* |
406 | * The prefetch counters don't differentiate between the I | 406 | * The prefetch counters don't differentiate between the I |
@@ -527,8 +527,8 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
527 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 527 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, |
528 | }, | 528 | }, |
529 | [C(OP_WRITE)] = { | 529 | [C(OP_WRITE)] = { |
530 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, | 530 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
531 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 531 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
532 | }, | 532 | }, |
533 | [C(OP_PREFETCH)] = { | 533 | [C(OP_PREFETCH)] = { |
534 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 534 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
@@ -651,8 +651,8 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
651 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 651 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, |
652 | }, | 652 | }, |
653 | [C(OP_WRITE)] = { | 653 | [C(OP_WRITE)] = { |
654 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, | 654 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
655 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, | 655 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
656 | }, | 656 | }, |
657 | [C(OP_PREFETCH)] = { | 657 | [C(OP_PREFETCH)] = { |
658 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 658 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c index 2b0fe30ec12e..63990c42fac9 100644 --- a/arch/arm/kernel/perf_event_xscale.c +++ b/arch/arm/kernel/perf_event_xscale.c | |||
@@ -83,7 +83,7 @@ static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
83 | }, | 83 | }, |
84 | [C(OP_WRITE)] = { | 84 | [C(OP_WRITE)] = { |
85 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 85 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
86 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, | 86 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, |
87 | }, | 87 | }, |
88 | [C(OP_PREFETCH)] = { | 88 | [C(OP_PREFETCH)] = { |
89 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | 89 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, |
diff --git a/arch/arm/mach-bcm2835/bcm2835.c b/arch/arm/mach-bcm2835/bcm2835.c index 176d2d24782d..1a446a164c8c 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/Kconfig b/arch/arm/mach-imx/Kconfig index 0a2349dc7018..7b11d3329e81 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -95,9 +95,6 @@ config MACH_MX27 | |||
95 | config ARCH_MX5 | 95 | config ARCH_MX5 |
96 | bool | 96 | bool |
97 | 97 | ||
98 | config ARCH_MX50 | ||
99 | bool | ||
100 | |||
101 | config ARCH_MX51 | 98 | config ARCH_MX51 |
102 | bool | 99 | bool |
103 | 100 | ||
@@ -164,11 +161,6 @@ config SOC_IMX5 | |||
164 | select CPU_V7 | 161 | select CPU_V7 |
165 | select MXC_TZIC | 162 | select MXC_TZIC |
166 | 163 | ||
167 | config SOC_IMX50 | ||
168 | bool | ||
169 | select ARCH_MX50 | ||
170 | select SOC_IMX5 | ||
171 | |||
172 | config SOC_IMX51 | 164 | config SOC_IMX51 |
173 | bool | 165 | bool |
174 | select ARCH_MX5 | 166 | select ARCH_MX5 |
@@ -738,25 +730,10 @@ endif | |||
738 | 730 | ||
739 | if ARCH_MULTI_V7 | 731 | if ARCH_MULTI_V7 |
740 | 732 | ||
741 | comment "i.MX5 platforms:" | ||
742 | |||
743 | config MACH_MX50_RDP | ||
744 | bool "Support MX50 reference design platform" | ||
745 | depends on BROKEN | ||
746 | select IMX_HAVE_PLATFORM_IMX_I2C | ||
747 | select IMX_HAVE_PLATFORM_IMX_UART | ||
748 | select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX | ||
749 | select IMX_HAVE_PLATFORM_SPI_IMX | ||
750 | select SOC_IMX50 | ||
751 | help | ||
752 | Include support for MX50 reference design platform (RDP) board. This | ||
753 | includes specific configurations for the board and its peripherals. | ||
754 | |||
755 | comment "i.MX51 machines:" | 733 | comment "i.MX51 machines:" |
756 | 734 | ||
757 | config MACH_IMX51_DT | 735 | config MACH_IMX51_DT |
758 | bool "Support i.MX51 platforms from device tree" | 736 | bool "Support i.MX51 platforms from device tree" |
759 | select MACH_MX51_BABBAGE | ||
760 | select SOC_IMX51 | 737 | select SOC_IMX51 |
761 | help | 738 | help |
762 | Include support for Freescale i.MX51 based platforms | 739 | Include support for Freescale i.MX51 based platforms |
@@ -777,19 +754,6 @@ config MACH_MX51_BABBAGE | |||
777 | u-boot. This includes specific configurations for the board and its | 754 | u-boot. This includes specific configurations for the board and its |
778 | peripherals. | 755 | peripherals. |
779 | 756 | ||
780 | config MACH_MX51_3DS | ||
781 | bool "Support MX51PDK (3DS)" | ||
782 | select IMX_HAVE_PLATFORM_IMX2_WDT | ||
783 | select IMX_HAVE_PLATFORM_IMX_KEYPAD | ||
784 | select IMX_HAVE_PLATFORM_IMX_UART | ||
785 | select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX | ||
786 | select IMX_HAVE_PLATFORM_SPI_IMX | ||
787 | select MXC_DEBUG_BOARD | ||
788 | select SOC_IMX51 | ||
789 | help | ||
790 | Include support for MX51PDK (3DS) platform. This includes specific | ||
791 | configurations for the board and its peripherals. | ||
792 | |||
793 | config MACH_EUKREA_CPUIMX51SD | 757 | config MACH_EUKREA_CPUIMX51SD |
794 | bool "Support Eukrea CPUIMX51SD module" | 758 | bool "Support Eukrea CPUIMX51SD module" |
795 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC | 759 | select IMX_HAVE_PLATFORM_FSL_USB2_UDC |
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 0634b3152c24..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 |
@@ -88,7 +92,6 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o | |||
88 | obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o | 92 | obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o |
89 | obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o | 93 | obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o |
90 | 94 | ||
91 | obj-$(CONFIG_DEBUG_LL) += lluart.o | ||
92 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o | 95 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o |
93 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o | 96 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o |
94 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o | 97 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o |
@@ -103,10 +106,8 @@ endif | |||
103 | 106 | ||
104 | # i.MX5 based machines | 107 | # i.MX5 based machines |
105 | obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o | 108 | obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o |
106 | obj-$(CONFIG_MACH_MX51_3DS) += mach-mx51_3ds.o | ||
107 | obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += mach-cpuimx51sd.o | 109 | obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += mach-cpuimx51sd.o |
108 | obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd51-baseboard.o | 110 | obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd51-baseboard.o |
109 | obj-$(CONFIG_MACH_MX50_RDP) += mach-mx50_rdp.o | ||
110 | 111 | ||
111 | obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o | 112 | obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o |
112 | obj-$(CONFIG_SOC_IMX53) += mach-imx53.o | 113 | obj-$(CONFIG_SOC_IMX53) += mach-imx53.o |
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot index b27815de8473..41ba1bb0437b 100644 --- a/arch/arm/mach-imx/Makefile.boot +++ b/arch/arm/mach-imx/Makefile.boot | |||
@@ -22,10 +22,6 @@ zreladdr-$(CONFIG_SOC_IMX35) += 0x80008000 | |||
22 | params_phys-$(CONFIG_SOC_IMX35) := 0x80000100 | 22 | params_phys-$(CONFIG_SOC_IMX35) := 0x80000100 |
23 | initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000 | 23 | initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000 |
24 | 24 | ||
25 | zreladdr-$(CONFIG_SOC_IMX50) += 0x70008000 | ||
26 | params_phys-$(CONFIG_SOC_IMX50) := 0x70000100 | ||
27 | initrd_phys-$(CONFIG_SOC_IMX50) := 0x70800000 | ||
28 | |||
29 | zreladdr-$(CONFIG_SOC_IMX51) += 0x90008000 | 25 | zreladdr-$(CONFIG_SOC_IMX51) += 0x90008000 |
30 | params_phys-$(CONFIG_SOC_IMX51) := 0x90000100 | 26 | params_phys-$(CONFIG_SOC_IMX51) := 0x90000100 |
31 | initrd_phys-$(CONFIG_SOC_IMX51) := 0x90800000 | 27 | initrd_phys-$(CONFIG_SOC_IMX51) := 0x90800000 |
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 1ffe3b534e51..d24b0d68e83f 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 c0c4e723b7f5..540138c4606c 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c | |||
@@ -54,9 +54,18 @@ | |||
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 | ||
59 | void __init imx6q_clock_map_io(void) { } | 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 | } | ||
60 | 69 | ||
61 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | 70 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) |
62 | { | 71 | { |
@@ -68,6 +77,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | |||
68 | break; | 77 | break; |
69 | case WAIT_UNCLOCKED: | 78 | case WAIT_UNCLOCKED: |
70 | val |= 0x1 << BP_CLPCR_LPM; | 79 | val |= 0x1 << BP_CLPCR_LPM; |
80 | val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; | ||
71 | break; | 81 | break; |
72 | case STOP_POWER_ON: | 82 | case STOP_POWER_ON: |
73 | 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 e17dbc50c85f..5a800bfcec5b 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h | |||
@@ -21,7 +21,6 @@ extern void mx25_map_io(void); | |||
21 | extern void mx27_map_io(void); | 21 | extern void mx27_map_io(void); |
22 | extern void mx31_map_io(void); | 22 | extern void mx31_map_io(void); |
23 | extern void mx35_map_io(void); | 23 | extern void mx35_map_io(void); |
24 | extern void mx50_map_io(void); | ||
25 | extern void mx51_map_io(void); | 24 | extern void mx51_map_io(void); |
26 | extern void mx53_map_io(void); | 25 | extern void mx53_map_io(void); |
27 | extern void imx1_init_early(void); | 26 | extern void imx1_init_early(void); |
@@ -30,7 +29,6 @@ extern void imx25_init_early(void); | |||
30 | extern void imx27_init_early(void); | 29 | extern void imx27_init_early(void); |
31 | extern void imx31_init_early(void); | 30 | extern void imx31_init_early(void); |
32 | extern void imx35_init_early(void); | 31 | extern void imx35_init_early(void); |
33 | extern void imx50_init_early(void); | ||
34 | extern void imx51_init_early(void); | 32 | extern void imx51_init_early(void); |
35 | extern void imx53_init_early(void); | 33 | extern void imx53_init_early(void); |
36 | extern void mxc_init_irq(void __iomem *); | 34 | extern void mxc_init_irq(void __iomem *); |
@@ -41,7 +39,6 @@ extern void mx25_init_irq(void); | |||
41 | extern void mx27_init_irq(void); | 39 | extern void mx27_init_irq(void); |
42 | extern void mx31_init_irq(void); | 40 | extern void mx31_init_irq(void); |
43 | extern void mx35_init_irq(void); | 41 | extern void mx35_init_irq(void); |
44 | extern void mx50_init_irq(void); | ||
45 | extern void mx51_init_irq(void); | 42 | extern void mx51_init_irq(void); |
46 | extern void mx53_init_irq(void); | 43 | extern void mx53_init_irq(void); |
47 | extern void imx1_soc_init(void); | 44 | extern void imx1_soc_init(void); |
@@ -50,7 +47,6 @@ extern void imx25_soc_init(void); | |||
50 | extern void imx27_soc_init(void); | 47 | extern void imx27_soc_init(void); |
51 | extern void imx31_soc_init(void); | 48 | extern void imx31_soc_init(void); |
52 | extern void imx35_soc_init(void); | 49 | extern void imx35_soc_init(void); |
53 | extern void imx50_soc_init(void); | ||
54 | extern void imx51_soc_init(void); | 50 | extern void imx51_soc_init(void); |
55 | extern void imx51_init_late(void); | 51 | extern void imx51_init_late(void); |
56 | extern void imx53_init_late(void); | 52 | extern void imx53_init_late(void); |
@@ -109,26 +105,22 @@ void tzic_handle_irq(struct pt_regs *); | |||
109 | #define imx27_handle_irq avic_handle_irq | 105 | #define imx27_handle_irq avic_handle_irq |
110 | #define imx31_handle_irq avic_handle_irq | 106 | #define imx31_handle_irq avic_handle_irq |
111 | #define imx35_handle_irq avic_handle_irq | 107 | #define imx35_handle_irq avic_handle_irq |
112 | #define imx50_handle_irq tzic_handle_irq | ||
113 | #define imx51_handle_irq tzic_handle_irq | 108 | #define imx51_handle_irq tzic_handle_irq |
114 | #define imx53_handle_irq tzic_handle_irq | 109 | #define imx53_handle_irq tzic_handle_irq |
115 | 110 | ||
116 | extern void imx_enable_cpu(int cpu, bool enable); | 111 | extern void imx_enable_cpu(int cpu, bool enable); |
117 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); | 112 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); |
118 | #ifdef CONFIG_DEBUG_LL | ||
119 | extern void imx_lluart_map_io(void); | ||
120 | #else | ||
121 | static inline void imx_lluart_map_io(void) {} | ||
122 | #endif | ||
123 | extern void v7_cpu_resume(void); | 113 | extern void v7_cpu_resume(void); |
124 | extern u32 *pl310_get_save_ptr(void); | 114 | extern u32 *pl310_get_save_ptr(void); |
125 | #ifdef CONFIG_SMP | 115 | #ifdef CONFIG_SMP |
126 | extern void v7_secondary_startup(void); | 116 | extern void v7_secondary_startup(void); |
127 | extern void imx_scu_map_io(void); | 117 | extern void imx_scu_map_io(void); |
128 | extern void imx_smp_prepare(void); | 118 | extern void imx_smp_prepare(void); |
119 | extern void imx_scu_standby_enable(void); | ||
129 | #else | 120 | #else |
130 | static inline void imx_scu_map_io(void) {} | 121 | static inline void imx_scu_map_io(void) {} |
131 | static inline void imx_smp_prepare(void) {} | 122 | static inline void imx_smp_prepare(void) {} |
123 | static inline void imx_scu_standby_enable(void) {} | ||
132 | #endif | 124 | #endif |
133 | extern void imx_enable_cpu(int cpu, bool enable); | 125 | extern void imx_enable_cpu(int cpu, bool enable); |
134 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); | 126 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); |
@@ -138,7 +130,7 @@ extern void imx_gpc_init(void); | |||
138 | extern void imx_gpc_pre_suspend(void); | 130 | extern void imx_gpc_pre_suspend(void); |
139 | extern void imx_gpc_post_resume(void); | 131 | extern void imx_gpc_post_resume(void); |
140 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | 132 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); |
141 | extern void imx6q_clock_map_io(void); | 133 | extern void imx6q_set_chicken_bit(void); |
142 | 134 | ||
143 | extern void imx_cpu_die(unsigned int cpu); | 135 | extern void imx_cpu_die(unsigned int cpu); |
144 | extern int imx_cpu_kill(unsigned int cpu); | 136 | extern int imx_cpu_kill(unsigned int cpu); |
diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c index d88760014ff9..d7ce72252a4e 100644 --- a/arch/arm/mach-imx/cpu-imx5.c +++ b/arch/arm/mach-imx/cpu-imx5.c | |||
@@ -22,7 +22,6 @@ | |||
22 | static int mx5_cpu_rev = -1; | 22 | static int mx5_cpu_rev = -1; |
23 | 23 | ||
24 | #define IIM_SREV 0x24 | 24 | #define IIM_SREV 0x24 |
25 | #define MX50_HW_ADADIG_DIGPROG 0xB0 | ||
26 | 25 | ||
27 | static int get_mx51_srev(void) | 26 | static int get_mx51_srev(void) |
28 | { | 27 | { |
@@ -108,41 +107,3 @@ int mx53_revision(void) | |||
108 | return mx5_cpu_rev; | 107 | return mx5_cpu_rev; |
109 | } | 108 | } |
110 | EXPORT_SYMBOL(mx53_revision); | 109 | EXPORT_SYMBOL(mx53_revision); |
111 | |||
112 | static int get_mx50_srev(void) | ||
113 | { | ||
114 | void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K); | ||
115 | u32 rev; | ||
116 | |||
117 | if (!anatop) { | ||
118 | mx5_cpu_rev = -EINVAL; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | rev = readl(anatop + MX50_HW_ADADIG_DIGPROG); | ||
123 | rev &= 0xff; | ||
124 | |||
125 | iounmap(anatop); | ||
126 | if (rev == 0x0) | ||
127 | return IMX_CHIP_REVISION_1_0; | ||
128 | else if (rev == 0x1) | ||
129 | return IMX_CHIP_REVISION_1_1; | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Returns: | ||
135 | * the silicon revision of the cpu | ||
136 | * -EINVAL - not a mx50 | ||
137 | */ | ||
138 | int mx50_revision(void) | ||
139 | { | ||
140 | if (!cpu_is_mx50()) | ||
141 | return -EINVAL; | ||
142 | |||
143 | if (mx5_cpu_rev == -1) | ||
144 | mx5_cpu_rev = get_mx50_srev(); | ||
145 | |||
146 | return mx5_cpu_rev; | ||
147 | } | ||
148 | EXPORT_SYMBOL(mx50_revision); | ||
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/devices-imx50.h b/arch/arm/mach-imx/devices-imx50.h deleted file mode 100644 index 2c290391f298..000000000000 --- a/arch/arm/mach-imx/devices-imx50.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | |||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include "devices/devices-common.h" | ||
22 | |||
23 | extern const struct imx_imx_uart_1irq_data imx50_imx_uart_data[]; | ||
24 | #define imx50_add_imx_uart(id, pdata) \ | ||
25 | imx_add_imx_uart_1irq(&imx50_imx_uart_data[id], pdata) | ||
26 | |||
27 | extern const struct imx_fec_data imx50_fec_data; | ||
28 | #define imx50_add_fec(pdata) \ | ||
29 | imx_add_fec(&imx50_fec_data, pdata) | ||
30 | |||
31 | extern const struct imx_imx_i2c_data imx50_imx_i2c_data[]; | ||
32 | #define imx50_add_imx_i2c(id, pdata) \ | ||
33 | imx_add_imx_i2c(&imx50_imx_i2c_data[id], pdata) | ||
diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig index 9a8f1ca7bcb1..9b9ba1f4ffe1 100644 --- a/arch/arm/mach-imx/devices/Kconfig +++ b/arch/arm/mach-imx/devices/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config IMX_HAVE_PLATFORM_FEC | 1 | config IMX_HAVE_PLATFORM_FEC |
2 | bool | 2 | bool |
3 | default y if ARCH_MX25 || SOC_IMX27 || SOC_IMX35 || SOC_IMX50 || SOC_IMX51 || SOC_IMX53 | 3 | default y if ARCH_MX25 || SOC_IMX27 || SOC_IMX35 || SOC_IMX51 || SOC_IMX53 |
4 | 4 | ||
5 | config IMX_HAVE_PLATFORM_FLEXCAN | 5 | config IMX_HAVE_PLATFORM_FLEXCAN |
6 | bool | 6 | bool |
diff --git a/arch/arm/mach-imx/devices/platform-fec.c b/arch/arm/mach-imx/devices/platform-fec.c index 2cb188ad9a0a..63eba08f87b1 100644 --- a/arch/arm/mach-imx/devices/platform-fec.c +++ b/arch/arm/mach-imx/devices/platform-fec.c | |||
@@ -35,12 +35,6 @@ const struct imx_fec_data imx35_fec_data __initconst = | |||
35 | imx_fec_data_entry_single(MX35, "imx27-fec"); | 35 | imx_fec_data_entry_single(MX35, "imx27-fec"); |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #ifdef CONFIG_SOC_IMX50 | ||
39 | /* i.mx50 has the i.mx25 type fec */ | ||
40 | const struct imx_fec_data imx50_fec_data __initconst = | ||
41 | imx_fec_data_entry_single(MX50, "imx25-fec"); | ||
42 | #endif | ||
43 | |||
44 | #ifdef CONFIG_SOC_IMX51 | 38 | #ifdef CONFIG_SOC_IMX51 |
45 | /* i.mx51 has the i.mx27 type fec */ | 39 | /* i.mx51 has the i.mx27 type fec */ |
46 | const struct imx_fec_data imx51_fec_data __initconst = | 40 | const struct imx_fec_data imx51_fec_data __initconst = |
diff --git a/arch/arm/mach-imx/devices/platform-imx-i2c.c b/arch/arm/mach-imx/devices/platform-imx-i2c.c index 8e30e5703cd2..57d342e85c2f 100644 --- a/arch/arm/mach-imx/devices/platform-imx-i2c.c +++ b/arch/arm/mach-imx/devices/platform-imx-i2c.c | |||
@@ -70,16 +70,6 @@ const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = { | |||
70 | }; | 70 | }; |
71 | #endif /* ifdef CONFIG_SOC_IMX35 */ | 71 | #endif /* ifdef CONFIG_SOC_IMX35 */ |
72 | 72 | ||
73 | #ifdef CONFIG_SOC_IMX50 | ||
74 | const struct imx_imx_i2c_data imx50_imx_i2c_data[] __initconst = { | ||
75 | #define imx50_imx_i2c_data_entry(_id, _hwid) \ | ||
76 | imx_imx_i2c_data_entry(MX50, "imx21-i2c", _id, _hwid, SZ_4K) | ||
77 | imx50_imx_i2c_data_entry(0, 1), | ||
78 | imx50_imx_i2c_data_entry(1, 2), | ||
79 | imx50_imx_i2c_data_entry(2, 3), | ||
80 | }; | ||
81 | #endif /* ifdef CONFIG_SOC_IMX51 */ | ||
82 | |||
83 | #ifdef CONFIG_SOC_IMX51 | 73 | #ifdef CONFIG_SOC_IMX51 |
84 | const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = { | 74 | const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = { |
85 | #define imx51_imx_i2c_data_entry(_id, _hwid) \ | 75 | #define imx51_imx_i2c_data_entry(_id, _hwid) \ |
diff --git a/arch/arm/mach-imx/devices/platform-imx-uart.c b/arch/arm/mach-imx/devices/platform-imx-uart.c index 67bf866a2cb6..faac4aa6ca6d 100644 --- a/arch/arm/mach-imx/devices/platform-imx-uart.c +++ b/arch/arm/mach-imx/devices/platform-imx-uart.c | |||
@@ -94,18 +94,6 @@ const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = { | |||
94 | }; | 94 | }; |
95 | #endif /* ifdef CONFIG_SOC_IMX35 */ | 95 | #endif /* ifdef CONFIG_SOC_IMX35 */ |
96 | 96 | ||
97 | #ifdef CONFIG_SOC_IMX50 | ||
98 | const struct imx_imx_uart_1irq_data imx50_imx_uart_data[] __initconst = { | ||
99 | #define imx50_imx_uart_data_entry(_id, _hwid) \ | ||
100 | imx_imx_uart_1irq_data_entry(MX50, _id, _hwid, SZ_4K) | ||
101 | imx50_imx_uart_data_entry(0, 1), | ||
102 | imx50_imx_uart_data_entry(1, 2), | ||
103 | imx50_imx_uart_data_entry(2, 3), | ||
104 | imx50_imx_uart_data_entry(3, 4), | ||
105 | imx50_imx_uart_data_entry(4, 5), | ||
106 | }; | ||
107 | #endif /* ifdef CONFIG_SOC_IMX50 */ | ||
108 | |||
109 | #ifdef CONFIG_SOC_IMX51 | 97 | #ifdef CONFIG_SOC_IMX51 |
110 | const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = { | 98 | const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = { |
111 | #define imx51_imx_uart_data_entry(_id, _hwid) \ | 99 | #define imx51_imx_uart_data_entry(_id, _hwid) \ |
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/hardware.h b/arch/arm/mach-imx/hardware.h index 3ce7fa3bd43f..911e9b31b03f 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h | |||
@@ -72,11 +72,6 @@ | |||
72 | * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 | 72 | * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 |
73 | * X_MEMC 0xb8000000+0x010000 -> 0xf5c00000+0x010000 | 73 | * X_MEMC 0xb8000000+0x010000 -> 0xf5c00000+0x010000 |
74 | * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 | 74 | * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 |
75 | * mx50: | ||
76 | * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 | ||
77 | * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000 | ||
78 | * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 | ||
79 | * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000 | ||
80 | * mx51: | 75 | * mx51: |
81 | * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 | 76 | * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 |
82 | * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000 | 77 | * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000 |
@@ -108,7 +103,6 @@ | |||
108 | #include "mxc.h" | 103 | #include "mxc.h" |
109 | 104 | ||
110 | #include "mx6q.h" | 105 | #include "mx6q.h" |
111 | #include "mx50.h" | ||
112 | #include "mx51.h" | 106 | #include "mx51.h" |
113 | #include "mx53.h" | 107 | #include "mx53.h" |
114 | #include "mx3x.h" | 108 | #include "mx3x.h" |
diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/imx31-dt.c index f9a690960097..00737eb4e00d 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/iomux-mx50.h b/arch/arm/mach-imx/iomux-mx50.h deleted file mode 100644 index 00f56e0e8009..000000000000 --- a/arch/arm/mach-imx/iomux-mx50.h +++ /dev/null | |||
@@ -1,977 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
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 along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef __MACH_IOMUX_MX50_H__ | ||
20 | #define __MACH_IOMUX_MX50_H__ | ||
21 | |||
22 | #include "iomux-v3.h" | ||
23 | |||
24 | #define MX50_ELCDIF_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH) | ||
25 | |||
26 | #define MX50_SD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \ | ||
27 | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH) | ||
28 | |||
29 | #define MX50_UART_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE) | ||
30 | |||
31 | #define MX50_I2C_PAD_CTRL (PAD_CTL_ODE | PAD_CTL_DSE_HIGH | \ | ||
32 | PAD_CTL_PUS_100K_UP | PAD_CTL_HYS) | ||
33 | |||
34 | #define MX50_USB_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ | ||
35 | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP) | ||
36 | |||
37 | #define MX50_FEC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \ | ||
38 | PAD_CTL_PUS_22K_UP | PAD_CTL_ODE | \ | ||
39 | PAD_CTL_DSE_HIGH) | ||
40 | |||
41 | #define MX50_OWIRE_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \ | ||
42 | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE | \ | ||
43 | PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST) | ||
44 | |||
45 | #define MX50_KEYPAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \ | ||
46 | PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH) | ||
47 | |||
48 | #define MX50_CSPI_SS_PAD (PAD_CTL_PKE | PAD_CTL_PUE | \ | ||
49 | PAD_CTL_PUS_22K_UP | PAD_CTL_DSE_HIGH) | ||
50 | |||
51 | #define MX50_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x2CC, 0x20, 0, 0x0, 0, NO_PAD_CTRL) | ||
52 | #define MX50_PAD_KEY_COL0__GPIO_4_0 IOMUX_PAD(0x2CC, 0x20, 1, 0x0, 0, NO_PAD_CTRL) | ||
53 | #define MX50_PAD_KEY_COL0__NANDF_CLE IOMUX_PAD(0x2CC, 0x20, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
54 | |||
55 | #define MX50_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x2D0, 0x24, 0, 0x0, 0, MX50_KEYPAD_CTRL) | ||
56 | #define MX50_PAD_KEY_ROW0__GPIO_4_1 IOMUX_PAD(0x2D0, 0x24, 1, 0x0, 0, NO_PAD_CTRL) | ||
57 | #define MX50_PAD_KEY_ROW0__NANDF_ALE IOMUX_PAD(0x2D0, 0x24, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
58 | |||
59 | #define MX50_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x2D4, 0x28, 0, 0x0, 0, NO_PAD_CTRL) | ||
60 | #define MX50_PAD_KEY_COL1__GPIO_4_2 IOMUX_PAD(0x2D4, 0x28, 1, 0x0, 0, NO_PAD_CTRL) | ||
61 | #define MX50_PAD_KEY_COL1__NANDF_CE0 IOMUX_PAD(0x2D4, 0x28, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
62 | |||
63 | #define MX50_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x2D8, 0x2C, 0, 0x0, 0, MX50_KEYPAD_CTRL) | ||
64 | #define MX50_PAD_KEY_ROW1__GPIO_4_3 IOMUX_PAD(0x2D8, 0x2C, 1, 0x0, 0, NO_PAD_CTRL) | ||
65 | #define MX50_PAD_KEY_ROW1__NANDF_CE1 IOMUX_PAD(0x2D8, 0x2C, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
66 | |||
67 | #define MX50_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x2DC, 0x30, 0, 0x0, 0, MX50_KEYPAD_CTRL) | ||
68 | #define MX50_PAD_KEY_COL2__GPIO_4_4 IOMUX_PAD(0x2DC, 0x30, 1, 0x0, 0, NO_PAD_CTRL) | ||
69 | #define MX50_PAD_KEY_COL2__NANDF_CE2 IOMUX_PAD(0x2DC, 0x30, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
70 | |||
71 | #define MX50_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x2E0, 0x34, 0, 0x0, 0, MX50_KEYPAD_CTRL) | ||
72 | #define MX50_PAD_KEY_ROW2__GPIO_4_5 IOMUX_PAD(0x2E0, 0x34, 1, 0x0, 0, NO_PAD_CTRL) | ||
73 | #define MX50_PAD_KEY_ROW2__NANDF_CE3 IOMUX_PAD(0x2E0, 0x34, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
74 | |||
75 | #define MX50_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x2E4, 0x38, 0, 0x0, 0, NO_PAD_CTRL) | ||
76 | #define MX50_PAD_KEY_COL3__GPIO_4_6 IOMUX_PAD(0x2E4, 0x38, 1, 0x0, 0, NO_PAD_CTRL) | ||
77 | #define MX50_PAD_KEY_COL3__NANDF_READY IOMUX_PAD(0x2E4, 0x38, 2, 0x7b4, 0, PAD_CTL_PKE | \ | ||
78 | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP) | ||
79 | #define MX50_PAD_KEY_COL3__SDMA_EXT0 IOMUX_PAD(0x2E4, 0x38, 6, 0x7b8, 0, NO_PAD_CTRL) | ||
80 | |||
81 | #define MX50_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x2E8, 0x3C, 0, 0x0, 0, MX50_KEYPAD_CTRL) | ||
82 | #define MX50_PAD_KEY_ROW3__GPIO_4_7 IOMUX_PAD(0x2E8, 0x3C, 1, 0x0, 0, NO_PAD_CTRL) | ||
83 | #define MX50_PAD_KEY_ROW3__NANDF_DQS IOMUX_PAD(0x2E8, 0x3C, 2, 0x7b0, 0, PAD_CTL_DSE_HIGH) | ||
84 | #define MX50_PAD_KEY_ROW3__SDMA_EXT1 IOMUX_PAD(0x2E8, 0x3C, 6, 0x7bc, 0, NO_PAD_CTRL) | ||
85 | |||
86 | #define MX50_PAD_I2C1_SCL__I2C1_SCL IOMUX_PAD(0x2EC, 0x40, IOMUX_CONFIG_SION, 0x0, 0, \ | ||
87 | MX50_I2C_PAD_CTRL) | ||
88 | #define MX50_PAD_I2C1_SCL__GPIO_6_18 IOMUX_PAD(0x2EC, 0x40, 1, 0x0, 0, NO_PAD_CTRL) | ||
89 | #define MX50_PAD_I2C1_SCL__UART2_TXD IOMUX_PAD(0x2EC, 0x40, 2, 0x0, 0, MX50_UART_PAD_CTRL) | ||
90 | |||
91 | #define MX50_PAD_I2C1_SDA__I2C1_SDA IOMUX_PAD(0x2F0, 0x44, IOMUX_CONFIG_SION, 0x0, 0, \ | ||
92 | MX50_I2C_PAD_CTRL) | ||
93 | #define MX50_PAD_I2C1_SDA__GPIO_6_19 IOMUX_PAD(0x2F0, 0x44, 1, 0x0, 0, NO_PAD_CTRL) | ||
94 | #define MX50_PAD_I2C1_SDA__UART2_RXD IOMUX_PAD(0x2F0, 0x44, 2, 0x7cc, 1, MX50_UART_PAD_CTRL) | ||
95 | |||
96 | #define MX50_PAD_I2C2_SCL__I2C2_SCL IOMUX_PAD(0x2F4, 0x48, IOMUX_CONFIG_SION, 0x0, 0, \ | ||
97 | MX50_I2C_PAD_CTRL) | ||
98 | #define MX50_PAD_I2C2_SCL__GPIO_6_20 IOMUX_PAD(0x2F4, 0x48, 1, 0x0, 0, NO_PAD_CTRL) | ||
99 | #define MX50_PAD_I2C2_SCL__UART2_CTS IOMUX_PAD(0x2F4, 0x48, 2, 0x0, 0, MX50_UART_PAD_CTRL) | ||
100 | #define MX50_PAD_I2C2_SCL__DCDC_OK IOMUX_PAD(0x2F4, 0x48, 7, 0x0, 0, NO_PAD_CTRL) | ||
101 | |||
102 | #define MX50_PAD_I2C2_SDA__I2C2_SDA IOMUX_PAD(0x2F8, 0x4C, IOMUX_CONFIG_SION, 0x0, 0, \ | ||
103 | MX50_I2C_PAD_CTRL) | ||
104 | #define MX50_PAD_I2C2_SDA__GPIO_6_21 IOMUX_PAD(0x2F8, 0x4C, 1, 0x0, 0, NO_PAD_CTRL) | ||
105 | #define MX50_PAD_I2C2_SDA__UART2_RTS IOMUX_PAD(0x2F8, 0x4C, 2, 0x7c8, 1, MX50_UART_PAD_CTRL) | ||
106 | #define MX50_PAD_I2C2_SDA__PWRSTABLE IOMUX_PAD(0x2F8, 0x4C, 7, 0x0, 0, NO_PAD_CTRL) | ||
107 | |||
108 | #define MX50_PAD_I2C3_SCL__I2C3_SCL IOMUX_PAD(0x2FC, 0x50, IOMUX_CONFIG_SION, 0x0, 0, \ | ||
109 | MX50_I2C_PAD_CTRL) | ||
110 | #define MX50_PAD_I2C3_SCL__GPIO_6_22 IOMUX_PAD(0x2FC, 0x50, 1, 0x0, 0, NO_PAD_CTRL) | ||
111 | #define MX50_PAD_I2C3_SCL__FEC_MDC IOMUX_PAD(0x2FC, 0x50, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
112 | #define MX50_PAD_I2C3_SCL__PMIC_RDY IOMUX_PAD(0x2FC, 0x50, 3, 0x0, 0, NO_PAD_CTRL) | ||
113 | #define MX50_PAD_I2C3_SCL__GPT_CAPIN1 IOMUX_PAD(0x2FC, 0x50, 5, 0x0, 0, NO_PAD_CTRL) | ||
114 | #define MX50_PAD_I2C3_SCL__USBOTG_OC IOMUX_PAD(0x2FC, 0x50, 7, 0x7E8, 0, MX50_USB_PAD_CTRL) | ||
115 | |||
116 | #define MX50_PAD_I2C3_SDA__I2C3_SDA IOMUX_PAD(0x300, 0x54, IOMUX_CONFIG_SION, 0x0, 0, \ | ||
117 | MX50_I2C_PAD_CTRL) | ||
118 | #define MX50_PAD_I2C3_SDA__GPIO_6_23 IOMUX_PAD(0x300, 0x54, 1, 0x0, 0, NO_PAD_CTRL) | ||
119 | #define MX50_PAD_I2C3_SDA__FEC_MDIO IOMUX_PAD(0x300, 0x54, 2, 0x774, 0, MX50_FEC_PAD_CTRL) | ||
120 | #define MX50_PAD_I2C3_SDA__PWRFAIL_INT IOMUX_PAD(0x300, 0x54, 3, 0x0, 0, NO_PAD_CTRL) | ||
121 | #define MX50_PAD_I2C3_SDA__ALARM_DEB IOMUX_PAD(0x300, 0x54, 4, 0x0, 0, NO_PAD_CTRL) | ||
122 | #define MX50_PAD_I2C3_SDA__GPT_CAPIN1 IOMUX_PAD(0x300, 0x54, 5, 0x0, 0, NO_PAD_CTRL) | ||
123 | #define MX50_PAD_I2C3_SDA__USBOTG_PWR IOMUX_PAD(0x300, 0x54, 7, 0x0, 0, \ | ||
124 | PAD_CTL_PKE | PAD_CTL_DSE_HIGH) | ||
125 | |||
126 | #define MX50_PAD_PWM1__PWM1_PWMO IOMUX_PAD(0x304, 0x58, 0, 0x0, 0, NO_PAD_CTRL) | ||
127 | #define MX50_PAD_PWM1__GPIO_6_24 IOMUX_PAD(0x304, 0x58, 1, 0x0, 0, NO_PAD_CTRL) | ||
128 | #define MX50_PAD_PWM1__USBOTG_OC IOMUX_PAD(0x304, 0x58, 2, 0x7E8, 1, MX50_USB_PAD_CTRL) | ||
129 | #define MX50_PAD_PWM1__GPT_CMPOUT1 IOMUX_PAD(0x304, 0x58, 5, 0x0, 0, NO_PAD_CTRL) | ||
130 | |||
131 | #define MX50_PAD_PWM2__PWM2_PWMO IOMUX_PAD(0x308, 0x5C, 0, 0x0, 0, NO_PAD_CTRL) | ||
132 | #define MX50_PAD_PWM2__GPIO_6_25 IOMUX_PAD(0x308, 0x5C, 1, 0x0, 0, NO_PAD_CTRL) | ||
133 | #define MX50_PAD_PWM2__USBOTG_PWR IOMUX_PAD(0x308, 0x5C, 2, 0x0, 0, \ | ||
134 | PAD_CTL_PKE | PAD_CTL_DSE_HIGH) | ||
135 | #define MX50_PAD_PWM2__DCDC_PWM IOMUX_PAD(0x308, 0x5C, 4, 0x0, 0, NO_PAD_CTRL) | ||
136 | #define MX50_PAD_PWM2__GPT_CMPOUT2 IOMUX_PAD(0x308, 0x5C, 5, 0x0, 0, NO_PAD_CTRL) | ||
137 | #define MX50_PAD_PWM2__ANY_PU_RST IOMUX_PAD(0x308, 0x5C, 7, 0x0, 0, NO_PAD_CTRL) | ||
138 | |||
139 | #define MX50_PAD_OWIRE__OWIRE IOMUX_PAD(0x30C, 0x60, 0, 0x0, 0, MX50_OWIRE_PAD_CTRL) | ||
140 | #define MX50_PAD_OWIRE__GPIO_6_26 IOMUX_PAD(0x30C, 0x60, 1, 0x0, 0, NO_PAD_CTRL) | ||
141 | #define MX50_PAD_OWIRE__USBH1_OC IOMUX_PAD(0x30C, 0x60, 2, 0x0, 0, MX50_USB_PAD_CTRL) | ||
142 | #define MX50_PAD_OWIRE__SSI_EXT1_CLK IOMUX_PAD(0x30C, 0x60, 3, 0x0, 0, NO_PAD_CTRL) | ||
143 | #define MX50_PAD_OWIRE__EPDC_PWRIRQ IOMUX_PAD(0x30C, 0x60, 4, 0x0, 0, NO_PAD_CTRL) | ||
144 | #define MX50_PAD_OWIRE__GPT_CMPOUT3 IOMUX_PAD(0x30C, 0x60, 5, 0x0, 0, NO_PAD_CTRL) | ||
145 | |||
146 | #define MX50_PAD_EPITO__EPITO IOMUX_PAD(0x310, 0x64, 0, 0x0, 0, NO_PAD_CTRL) | ||
147 | #define MX50_PAD_EPITO__GPIO_6_27 IOMUX_PAD(0x310, 0x64, 1, 0x0, 0, NO_PAD_CTRL) | ||
148 | #define MX50_PAD_EPITO__USBH1_PWR IOMUX_PAD(0x310, 0x64, 2, 0x0, 0, \ | ||
149 | PAD_CTL_PKE | PAD_CTL_DSE_HIGH) | ||
150 | #define MX50_PAD_EPITO__SSI_EXT2_CLK IOMUX_PAD(0x310, 0x64, 3, 0x0, 0, NO_PAD_CTRL) | ||
151 | #define MX50_PAD_EPITO__TOG_EN IOMUX_PAD(0x310, 0x64, 4, 0x0, 0, NO_PAD_CTRL) | ||
152 | #define MX50_PAD_EPITO__GPT_CLKIN IOMUX_PAD(0x310, 0x64, 5, 0x0, 0, NO_PAD_CTRL) | ||
153 | |||
154 | #define MX50_PAD_WDOG__WDOG IOMUX_PAD(0x314, 0x68, 0, 0x0, 0, NO_PAD_CTRL) | ||
155 | #define MX50_PAD_WDOG__GPIO_6_28 IOMUX_PAD(0x314, 0x68, 1, 0x0, 0, NO_PAD_CTRL) | ||
156 | #define MX50_PAD_WDOG__WDOG_RST IOMUX_PAD(0x314, 0x68, 2, 0x0, 0, NO_PAD_CTRL) | ||
157 | #define MX50_PAD_WDOG__XTAL32K IOMUX_PAD(0x314, 0x68, 6, 0x0, 0, NO_PAD_CTRL) | ||
158 | |||
159 | #define MX50_PAD_SSI_TXFS__SSI_TXFS IOMUX_PAD(0x318, 0x6C, 0, 0x0, 0, NO_PAD_CTRL) | ||
160 | #define MX50_PAD_SSI_TXFS__GPIO_6_0 IOMUX_PAD(0x318, 0x6C, 1, 0x0, 0, NO_PAD_CTRL) | ||
161 | |||
162 | #define MX50_PAD_SSI_TXC__SSI_TXC IOMUX_PAD(0x31C, 0x70, 0, 0x0, 0, NO_PAD_CTRL) | ||
163 | #define MX50_PAD_SSI_TXC__GPIO_6_1 IOMUX_PAD(0x31C, 0x70, 1, 0x0, 0, NO_PAD_CTRL) | ||
164 | |||
165 | #define MX50_PAD_SSI_TXD__SSI_TXD IOMUX_PAD(0x320, 0x74, 0, 0x0, 0, NO_PAD_CTRL) | ||
166 | #define MX50_PAD_SSI_TXD__GPIO_6_2 IOMUX_PAD(0x320, 0x74, 1, 0x0, 0, NO_PAD_CTRL) | ||
167 | #define MX50_PAD_SSI_TXD__CSPI_RDY IOMUX_PAD(0x320, 0x74, 4, 0x6e8, 0, NO_PAD_CTRL) | ||
168 | |||
169 | #define MX50_PAD_SSI_RXD__SSI_RXD IOMUX_PAD(0x324, 0x78, 0, 0x0, 0, NO_PAD_CTRL) | ||
170 | #define MX50_PAD_SSI_RXD__GPIO_6_3 IOMUX_PAD(0x324, 0x78, 1, 0x0, 0, NO_PAD_CTRL) | ||
171 | #define MX50_PAD_SSI_RXD__CSPI_SS3 IOMUX_PAD(0x324, 0x78, 4, 0x6f4, 0, MX50_CSPI_SS_PAD) | ||
172 | |||
173 | #define MX50_PAD_SSI_RXFS__AUD3_RXFS IOMUX_PAD(0x328, 0x7C, 0, 0x0, 0, NO_PAD_CTRL) | ||
174 | #define MX50_PAD_SSI_RXFS__GPIO_6_4 IOMUX_PAD(0x328, 0x7C, 1, 0x0, 0, NO_PAD_CTRL) | ||
175 | #define MX50_PAD_SSI_RXFS__UART5_TXD IOMUX_PAD(0x328, 0x7C, 2, 0x0, 0, MX50_UART_PAD_CTRL) | ||
176 | #define MX50_PAD_SSI_RXFS__WEIM_D6 IOMUX_PAD(0x328, 0x7C, 3, 0x804, 0, NO_PAD_CTRL) | ||
177 | #define MX50_PAD_SSI_RXFS__CSPI_SS2 IOMUX_PAD(0x328, 0x7C, 4, 0x6f0, 0, MX50_CSPI_SS_PAD) | ||
178 | #define MX50_PAD_SSI_RXFS__FEC_COL IOMUX_PAD(0x328, 0x7C, 5, 0x770, 0, PAD_CTL_DSE_HIGH) | ||
179 | #define MX50_PAD_SSI_RXFS__FEC_MDC IOMUX_PAD(0x328, 0x7C, 6, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
180 | |||
181 | #define MX50_PAD_SSI_RXC__AUD3_RXC IOMUX_PAD(0x32C, 0x80, 0, 0x0, 0, NO_PAD_CTRL) | ||
182 | #define MX50_PAD_SSI_RXC__GPIO_6_5 IOMUX_PAD(0x32C, 0x80, 1, 0x0, 0, NO_PAD_CTRL) | ||
183 | #define MX50_PAD_SSI_RXC__UART5_RXD IOMUX_PAD(0x32C, 0x80, 2, 0x7e4, 1, MX50_UART_PAD_CTRL) | ||
184 | #define MX50_PAD_SSI_RXC__WEIM_D7 IOMUX_PAD(0x32C, 0x80, 3, 0x808, 0, NO_PAD_CTRL) | ||
185 | #define MX50_PAD_SSI_RXC__CSPI_SS1 IOMUX_PAD(0x32C, 0x80, 4, 0x6ec, 0, MX50_CSPI_SS_PAD) | ||
186 | #define MX50_PAD_SSI_RXC__FEC_RX_CLK IOMUX_PAD(0x32C, 0x80, 5, 0x780, 0, NO_PAD_CTRL) | ||
187 | #define MX50_PAD_SSI_RXC__FEC_MDIO IOMUX_PAD(0x32C, 0x80, 6, 0x774, 1, MX50_FEC_PAD_CTRL) | ||
188 | |||
189 | #define MX50_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x330, 0x84, 0, 0x0, 0, MX50_UART_PAD_CTRL) | ||
190 | #define MX50_PAD_UART1_TXD__GPIO_6_6 IOMUX_PAD(0x330, 0x84, 1, 0x0, 0, NO_PAD_CTRL) | ||
191 | |||
192 | #define MX50_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x334, 0x88, 0, 0x7c4, 1, MX50_UART_PAD_CTRL) | ||
193 | #define MX50_PAD_UART1_RXD__GPIO_6_7 IOMUX_PAD(0x334, 0x88, 1, 0x0, 0, NO_PAD_CTRL) | ||
194 | |||
195 | #define MX50_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x338, 0x8C, 0, 0x0, 0, MX50_UART_PAD_CTRL) | ||
196 | #define MX50_PAD_UART1_CTS__GPIO_6_8 IOMUX_PAD(0x338, 0x8C, 1, 0x0, 0, NO_PAD_CTRL) | ||
197 | #define MX50_PAD_UART1_CTS__UART5_TXD IOMUX_PAD(0x338, 0x8C, 2, 0x0, 0, MX50_UART_PAD_CTRL) | ||
198 | #define MX50_PAD_UART1_CTS__SD4_D4 IOMUX_PAD(0x338, 0x8C, 4, 0x760, 0, MX50_SD_PAD_CTRL) | ||
199 | #define MX50_PAD_UART1_CTS__SD4_CMD IOMUX_PAD(0x338, 0x8C, 5, 0x74c, 0, MX50_SD_PAD_CTRL) | ||
200 | |||
201 | #define MX50_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x33C, 0x90, 0, 0x7c0, 1, MX50_UART_PAD_CTRL) | ||
202 | #define MX50_PAD_UART1_RTS__GPIO_6_9 IOMUX_PAD(0x33C, 0x90, 1, 0x0, 0, NO_PAD_CTRL) | ||
203 | #define MX50_PAD_UART1_RTS__UART5_RXD IOMUX_PAD(0x33C, 0x90, 2, 0x7e4, 3, MX50_UART_PAD_CTRL) | ||
204 | #define MX50_PAD_UART1_RTS__SD4_D5 IOMUX_PAD(0x33C, 0x90, 4, 0x764, 0, MX50_SD_PAD_CTRL) | ||
205 | #define MX50_PAD_UART1_RTS__SD4_CLK IOMUX_PAD(0x33C, 0x90, 5, 0x748, 0, MX50_SD_PAD_CTRL) | ||
206 | |||
207 | #define MX50_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x340, 0x94, 0, 0x0, 0, MX50_UART_PAD_CTRL) | ||
208 | #define MX50_PAD_UART2_TXD__GPIO_6_10 IOMUX_PAD(0x340, 0x94, 1, 0x0, 0, NO_PAD_CTRL) | ||
209 | #define MX50_PAD_UART2_TXD__SD4_D6 IOMUX_PAD(0x340, 0x94, 4, 0x768, 0, MX50_SD_PAD_CTRL) | ||
210 | #define MX50_PAD_UART2_TXD__SD4_D4 IOMUX_PAD(0x340, 0x94, 5, 0x760, 1, MX50_SD_PAD_CTRL) | ||
211 | |||
212 | #define MX50_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x344, 0x98, 0, 0x7cc, 3, MX50_UART_PAD_CTRL) | ||
213 | #define MX50_PAD_UART2_RXD__GPIO_6_11 IOMUX_PAD(0x344, 0x98, 1, 0x0, 0, NO_PAD_CTRL) | ||
214 | #define MX50_PAD_UART2_RXD__SD4_D7 IOMUX_PAD(0x344, 0x98, 4, 0x76c, 0, MX50_SD_PAD_CTRL) | ||
215 | #define MX50_PAD_UART2_RXD__SD4_D5 IOMUX_PAD(0x344, 0x98, 5, 0x764, 1, MX50_SD_PAD_CTRL) | ||
216 | |||
217 | #define MX50_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x348, 0x9C, 0, 0x0, 0, MX50_UART_PAD_CTRL) | ||
218 | #define MX50_PAD_UART2_CTS__GPIO_6_12 IOMUX_PAD(0x348, 0x9C, 1, 0x0, 0, NO_PAD_CTRL) | ||
219 | #define MX50_PAD_UART2_CTS__SD4_CMD IOMUX_PAD(0x348, 0x9C, 4, 0x74c, 1, MX50_SD_PAD_CTRL) | ||
220 | #define MX50_PAD_UART2_CTS__SD4_D6 IOMUX_PAD(0x348, 0x9C, 5, 0x768, 1, MX50_SD_PAD_CTRL) | ||
221 | |||
222 | #define MX50_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x34C, 0xA0, 0, 0x7c8, 3, MX50_UART_PAD_CTRL) | ||
223 | #define MX50_PAD_UART2_RTS__GPIO_6_13 IOMUX_PAD(0x34C, 0xA0, 1, 0x0, 0, NO_PAD_CTRL) | ||
224 | #define MX50_PAD_UART2_RTS__SD4_CLK IOMUX_PAD(0x34C, 0xA0, 4, 0x748, 1, MX50_SD_PAD_CTRL) | ||
225 | #define MX50_PAD_UART2_RTS__SD4_D7 IOMUX_PAD(0x34C, 0xA0, 5, 0x76c, 1, MX50_SD_PAD_CTRL) | ||
226 | |||
227 | #define MX50_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x350, 0xA4, 0, 0x0, 0, MX50_UART_PAD_CTRL) | ||
228 | #define MX50_PAD_UART3_TXD__GPIO_6_14 IOMUX_PAD(0x350, 0xA4, 1, 0x0, 0, NO_PAD_CTRL) | ||
229 | #define MX50_PAD_UART3_TXD__SD1_D4 IOMUX_PAD(0x350, 0xA4, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
230 | #define MX50_PAD_UART3_TXD__SD4_D0 IOMUX_PAD(0x350, 0xA4, 4, 0x750, 0, MX50_SD_PAD_CTRL) | ||
231 | #define MX50_PAD_UART3_TXD__SD2_WP IOMUX_PAD(0x350, 0xA4, 5, 0x744, 0, MX50_SD_PAD_CTRL) | ||
232 | #define MX50_PAD_UART3_TXD__WEIM_D12 IOMUX_PAD(0x350, 0xA4, 6, 0x81c, 0, NO_PAD_CTRL) | ||
233 | |||
234 | #define MX50_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x354, 0xA8, 0, 0x7d4, 1, MX50_UART_PAD_CTRL) | ||
235 | #define MX50_PAD_UART3_RXD__GPIO_6_15 IOMUX_PAD(0x354, 0xA8, 1, 0x0, 0, NO_PAD_CTRL) | ||
236 | #define MX50_PAD_UART3_RXD__SD1_D5 IOMUX_PAD(0x354, 0xA8, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
237 | #define MX50_PAD_UART3_RXD__SD4_D1 IOMUX_PAD(0x354, 0xA8, 4, 0x754, 0, MX50_SD_PAD_CTRL) | ||
238 | #define MX50_PAD_UART3_RXD__SD2_CD IOMUX_PAD(0x354, 0xA8, 5, 0x740, 0, MX50_SD_PAD_CTRL) | ||
239 | #define MX50_PAD_UART3_RXD__WEIM_D13 IOMUX_PAD(0x354, 0xA8, 6, 0x820, 0, NO_PAD_CTRL) | ||
240 | |||
241 | #define MX50_PAD_UART4_TXD__UART4_TXD IOMUX_PAD(0x358, 0xAC, 0, 0x0, 0, MX50_UART_PAD_CTRL) | ||
242 | #define MX50_PAD_UART4_TXD__GPIO_6_16 IOMUX_PAD(0x358, 0xAC, 1, 0x0, 0, NO_PAD_CTRL) | ||
243 | #define MX50_PAD_UART4_TXD__UART3_CTS IOMUX_PAD(0x358, 0xAC, 2, 0x0, 0, MX50_UART_PAD_CTRL) | ||
244 | #define MX50_PAD_UART4_TXD__SD1_D6 IOMUX_PAD(0x358, 0xAC, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
245 | #define MX50_PAD_UART4_TXD__SD4_D2 IOMUX_PAD(0x358, 0xAC, 4, 0x758, 0, MX50_SD_PAD_CTRL) | ||
246 | #define MX50_PAD_UART4_TXD__SD2_LCTL IOMUX_PAD(0x358, 0xAC, 5, 0x0, 0, MX50_SD_PAD_CTRL) | ||
247 | #define MX50_PAD_UART4_TXD__WEIM_D14 IOMUX_PAD(0x358, 0xAC, 6, 0x824, 0, NO_PAD_CTRL) | ||
248 | |||
249 | #define MX50_PAD_UART4_RXD__UART4_RXD IOMUX_PAD(0x35C, 0xB0, 0, 0x7dc, 1, MX50_UART_PAD_CTRL) | ||
250 | #define MX50_PAD_UART4_RXD__GPIO_6_17 IOMUX_PAD(0x35C, 0xB0, 1, 0x0, 0, NO_PAD_CTRL) | ||
251 | #define MX50_PAD_UART4_RXD__UART3_RTS IOMUX_PAD(0x35C, 0xB0, 2, 0x7d0, 1, MX50_UART_PAD_CTRL) | ||
252 | #define MX50_PAD_UART4_RXD__SD1_D7 IOMUX_PAD(0x35C, 0xB0, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
253 | #define MX50_PAD_UART4_RXD__SD4_D3 IOMUX_PAD(0x35C, 0xB0, 4, 0x75c, 0, MX50_SD_PAD_CTRL) | ||
254 | #define MX50_PAD_UART4_RXD__SD1_LCTL IOMUX_PAD(0x35C, 0xB0, 5, 0x0, 0, MX50_SD_PAD_CTRL) | ||
255 | #define MX50_PAD_UART4_RXD__WEIM_D15 IOMUX_PAD(0x35C, 0xB0, 6, 0x828, 0, NO_PAD_CTRL) | ||
256 | |||
257 | #define MX50_PAD_CSPI_SCLK__CSPI_SCLK IOMUX_PAD(0x360, 0xB4, 0, 0x0, 0, NO_PAD_CTRL) | ||
258 | #define MX50_PAD_CSPI_SCLK__GPIO_4_8 IOMUX_PAD(0x360, 0xB4, 1, 0x0, 0, NO_PAD_CTRL) | ||
259 | |||
260 | #define MX50_PAD_CSPI_MOSI__CSPI_MOSI IOMUX_PAD(0x364, 0xB8, 0, 0x0, 0, NO_PAD_CTRL) | ||
261 | #define MX50_PAD_CSPI_MOSI__GPIO_4_9 IOMUX_PAD(0x364, 0xB8, 1, 0x0, 0, NO_PAD_CTRL) | ||
262 | |||
263 | #define MX50_PAD_CSPI_MISO__CSPI_MISO IOMUX_PAD(0x368, 0xBC, 0, 0x0, 0, NO_PAD_CTRL) | ||
264 | #define MX50_PAD_CSPI_MISO__GPIO_4_10 IOMUX_PAD(0x368, 0xBC, 1, 0x0, 0, NO_PAD_CTRL) | ||
265 | |||
266 | #define MX50_PAD_CSPI_SS0__CSPI_SS0 IOMUX_PAD(0x36C, 0xC0, 0, 0x0, 0, MX50_CSPI_SS_PAD) | ||
267 | #define MX50_PAD_CSPI_SS0__GPIO_4_11 IOMUX_PAD(0x36C, 0xC0, 1, 0x0, 0, NO_PAD_CTRL) | ||
268 | |||
269 | #define MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x370, 0xC4, 0, 0x0, 0, NO_PAD_CTRL) | ||
270 | #define MX50_PAD_ECSPI1_SCLK__GPIO_4_12 IOMUX_PAD(0x370, 0xC4, 1, 0x0, 0, NO_PAD_CTRL) | ||
271 | #define MX50_PAD_ECSPI1_SCLK__CSPI_RDY IOMUX_PAD(0x370, 0xC4, 2, 0x6e8, 1, NO_PAD_CTRL) | ||
272 | #define MX50_PAD_ECSPI1_SCLK__ECSPI2_RDY IOMUX_PAD(0x370, 0xC4, 3, 0x0, 0, NO_PAD_CTRL) | ||
273 | #define MX50_PAD_ECSPI1_SCLK__UART3_RTS IOMUX_PAD(0x370, 0xC4, 4, 0x7d0, 2, MX50_UART_PAD_CTRL) | ||
274 | #define MX50_PAD_ECSPI1_SCLK__EPDC_SDCE6 IOMUX_PAD(0x370, 0xC4, 5, 0x0, 0, NO_PAD_CTRL) | ||
275 | #define MX50_PAD_ECSPI1_SCLK__WEIM_D8 IOMUX_PAD(0x370, 0xC4, 7, 0x80c, 0, NO_PAD_CTRL) | ||
276 | |||
277 | #define MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x374, 0xC8, 0, 0x0, 0, NO_PAD_CTRL) | ||
278 | #define MX50_PAD_ECSPI1_MOSI__GPIO_4_13 IOMUX_PAD(0x374, 0xC8, 1, 0x0, 0, NO_PAD_CTRL) | ||
279 | #define MX50_PAD_ECSPI1_MOSI__CSPI_SS1 IOMUX_PAD(0x374, 0xC8, 2, 0x6ec, 1, MX50_CSPI_SS_PAD) | ||
280 | #define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1 IOMUX_PAD(0x374, 0xC8, 3, 0x0, 0, MX50_CSPI_SS_PAD) | ||
281 | #define MX50_PAD_ECSPI1_MOSI__UART3_CTS IOMUX_PAD(0x374, 0xC8, 4, 0x0, 0, MX50_UART_PAD_CTRL) | ||
282 | #define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE7 IOMUX_PAD(0x374, 0xC8, 5, 0x0, 0, NO_PAD_CTRL) | ||
283 | #define MX50_PAD_ECSPI1_MOSI__WEIM_D9 IOMUX_PAD(0x374, 0xC8, 7, 0x810, 0, NO_PAD_CTRL) | ||
284 | |||
285 | #define MX50_PAD_ECSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x378, 0xCC, 0, 0x0, 0, NO_PAD_CTRL) | ||
286 | #define MX50_PAD_ECSPI1_MISO__GPIO_4_14 IOMUX_PAD(0x378, 0xCC, 1, 0x0, 0, NO_PAD_CTRL) | ||
287 | #define MX50_PAD_ECSPI1_MISO__CSPI_SS2 IOMUX_PAD(0x378, 0xCC, 2, 0x6f0, 1, MX50_CSPI_SS_PAD) | ||
288 | #define MX50_PAD_ECSPI1_MISO__ECSPI2_SS2 IOMUX_PAD(0x378, 0xCC, 3, 0x0, 0, MX50_CSPI_SS_PAD) | ||
289 | #define MX50_PAD_ECSPI1_MISO__UART4_RTS IOMUX_PAD(0x378, 0xCC, 4, 0x7d8, 0, MX50_UART_PAD_CTRL) | ||
290 | #define MX50_PAD_ECSPI1_MISO__EPDC_SDCE8 IOMUX_PAD(0x378, 0xCC, 5, 0x0, 0, NO_PAD_CTRL) | ||
291 | #define MX50_PAD_ECSPI1_MISO__WEIM_D10 IOMUX_PAD(0x378, 0xCC, 7, 0x814, 0, NO_PAD_CTRL) | ||
292 | |||
293 | #define MX50_PAD_ECSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x37C, 0xD0, 0, 0x0, 0, MX50_CSPI_SS_PAD) | ||
294 | #define MX50_PAD_ECSPI1_SS0__GPIO_4_15 IOMUX_PAD(0x37C, 0xD0, 1, 0x0, 0, PAD_CTL_PUS_100K_UP) | ||
295 | #define MX50_PAD_ECSPI1_SS0__CSPI_SS3 IOMUX_PAD(0x37C, 0xD0, 2, 0x6f4, 1, MX50_CSPI_SS_PAD) | ||
296 | #define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3 IOMUX_PAD(0x37C, 0xD0, 3, 0x0, 0, MX50_CSPI_SS_PAD) | ||
297 | #define MX50_PAD_ECSPI1_SS0__UART4_CTS IOMUX_PAD(0x37C, 0xD0, 4, 0x0, 0, MX50_UART_PAD_CTRL) | ||
298 | #define MX50_PAD_ECSPI1_SS0__EPDC_SDCE9 IOMUX_PAD(0x37C, 0xD0, 5, 0x0, 0, NO_PAD_CTRL) | ||
299 | #define MX50_PAD_ECSPI1_SS0__WEIM_D11 IOMUX_PAD(0x37C, 0xD0, 7, 0x818, 0, NO_PAD_CTRL) | ||
300 | |||
301 | #define MX50_PAD_ECSPI2_SCLK__ECSPI2_SCLK IOMUX_PAD(0x380, 0xD4, 0, 0x0, 0, NO_PAD_CTRL) | ||
302 | #define MX50_PAD_ECSPI2_SCLK__GPIO_4_16 IOMUX_PAD(0x380, 0xD4, 1, 0x0, 0, NO_PAD_CTRL) | ||
303 | #define MX50_PAD_ECSPI2_SCLK__ELCDIF_WR IOMUX_PAD(0x380, 0xD4, 2, 0x0, 0, NO_PAD_CTRL) | ||
304 | #define MX50_PAD_ECSPI2_SCLK__ECSPI1_RDY IOMUX_PAD(0x380, 0xD4, 3, 0x0, 0, NO_PAD_CTRL) | ||
305 | #define MX50_PAD_ECSPI2_SCLK__UART5_RTS IOMUX_PAD(0x380, 0xD4, 4, 0x7e0, 0, MX50_UART_PAD_CTRL) | ||
306 | #define MX50_PAD_ECSPI2_SCLK__ELCDIF_DOTCLK IOMUX_PAD(0x380, 0xD4, 5, 0x0, 0, NO_PAD_CTRL) | ||
307 | #define MX50_PAD_ECSPI2_SCLK__NANDF_CEN4 IOMUX_PAD(0x380, 0xD4, 6, 0x0, 0, NO_PAD_CTRL) | ||
308 | #define MX50_PAD_ECSPI2_SCLK__WEIM_D8 IOMUX_PAD(0x380, 0xD4, 7, 0x80c, 1, NO_PAD_CTRL) | ||
309 | |||
310 | #define MX50_PAD_ECSPI2_MOSI__ECSPI2_MOSI IOMUX_PAD(0x384, 0xD8, 0, 0x0, 0, NO_PAD_CTRL) | ||
311 | #define MX50_PAD_ECSPI2_MOSI__GPIO_4_17 IOMUX_PAD(0x384, 0xD8, 1, 0x0, 0, NO_PAD_CTRL) | ||
312 | #define MX50_PAD_ECSPI2_MOSI__ELCDIF_RD IOMUX_PAD(0x384, 0xD8, 2, 0x0, 0, NO_PAD_CTRL) | ||
313 | #define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1 IOMUX_PAD(0x384, 0xD8, 3, 0x0, 0, MX50_CSPI_SS_PAD) | ||
314 | #define MX50_PAD_ECSPI2_MOSI__UART5_CTS IOMUX_PAD(0x384, 0xD8, 4, 0x0, 0, MX50_UART_PAD_CTRL) | ||
315 | #define MX50_PAD_ECSPI2_MOSI__ELCDIF_EN IOMUX_PAD(0x384, 0xD8, 5, 0x0, 0, NO_PAD_CTRL) | ||
316 | #define MX50_PAD_ECSPI2_MOSI__NANDF_CEN5 IOMUX_PAD(0x384, 0xD8, 6, 0x0, 0, NO_PAD_CTRL) | ||
317 | #define MX50_PAD_ECSPI2_MOSI__WEIM_D9 IOMUX_PAD(0x384, 0xD8, 7, 0x810, 1, NO_PAD_CTRL) | ||
318 | |||
319 | #define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO IOMUX_PAD(0x388, 0xDC, 0, 0x0, 0, NO_PAD_CTRL) | ||
320 | #define MX50_PAD_ECSPI2_MISO__GPIO_4_18 IOMUX_PAD(0x388, 0xDC, 1, 0x0, 0, PAD_CTL_PUS_100K_UP) | ||
321 | #define MX50_PAD_ECSPI2_MISO__ELCDIF_RS IOMUX_PAD(0x388, 0xDC, 2, 0x0, 0, NO_PAD_CTRL) | ||
322 | #define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2 IOMUX_PAD(0x388, 0xDC, 3, 0x0, 0, MX50_CSPI_SS_PAD) | ||
323 | #define MX50_PAD_ECSPI2_MISO__UART5_TXD IOMUX_PAD(0x388, 0xDC, 4, 0x0, 0, MX50_UART_PAD_CTRL) | ||
324 | #define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC IOMUX_PAD(0x388, 0xDC, 5, 0x73c, 0, NO_PAD_CTRL) | ||
325 | #define MX50_PAD_ECSPI2_MISO__NANDF_CEN6 IOMUX_PAD(0x388, 0xDC, 6, 0x0, 0, NO_PAD_CTRL) | ||
326 | #define MX50_PAD_ECSPI2_MISO__WEIM_D10 IOMUX_PAD(0x388, 0xDC, 7, 0x814, 1, NO_PAD_CTRL) | ||
327 | |||
328 | #define MX50_PAD_ECSPI2_SS0__ECSPI2_SS0 IOMUX_PAD(0x38C, 0xE0, 0, 0x0, 0, MX50_CSPI_SS_PAD) | ||
329 | #define MX50_PAD_ECSPI2_SS0__GPIO_4_19 IOMUX_PAD(0x38C, 0xE0, 1, 0x0, 0, NO_PAD_CTRL) | ||
330 | #define MX50_PAD_ECSPI2_SS0__ELCDIF_CS IOMUX_PAD(0x38C, 0xE0, 2, 0x0, 0, NO_PAD_CTRL) | ||
331 | #define MX50_PAD_ECSPI2_SS0__ECSPI1_SS3 IOMUX_PAD(0x38C, 0xE0, 3, 0x0, 0, MX50_CSPI_SS_PAD) | ||
332 | #define MX50_PAD_ECSPI2_SS0__UART5_RXD IOMUX_PAD(0x38C, 0xE0, 4, 0x7e4, 5, MX50_UART_PAD_CTRL) | ||
333 | #define MX50_PAD_ECSPI2_SS0__ELCDIF_HSYNC IOMUX_PAD(0x38C, 0xE0, 5, 0x6f8, 0, NO_PAD_CTRL) | ||
334 | #define MX50_PAD_ECSPI2_SS0__NANDF_CEN7 IOMUX_PAD(0x38C, 0xE0, 6, 0x0, 0, NO_PAD_CTRL) | ||
335 | #define MX50_PAD_ECSPI2_SS0__WEIM_D11 IOMUX_PAD(0x38C, 0xE0, 7, 0x818, 1, NO_PAD_CTRL) | ||
336 | |||
337 | #define MX50_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x390, 0xE4, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL) | ||
338 | #define MX50_PAD_SD1_CLK__GPIO_5_0 IOMUX_PAD(0x390, 0xE4, 1, 0x0, 0, NO_PAD_CTRL) | ||
339 | #define MX50_PAD_SD1_CLK__CLKO IOMUX_PAD(0x390, 0xE4, 7, 0x0, 0, NO_PAD_CTRL) | ||
340 | |||
341 | #define MX50_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x394, 0xE8, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL) | ||
342 | #define MX50_PAD_SD1_CMD__GPIO_5_1 IOMUX_PAD(0x394, 0xE8, 1, 0x0, 0, NO_PAD_CTRL) | ||
343 | #define MX50_PAD_SD1_CMD__CLKO2 IOMUX_PAD(0x394, 0xE8, 7, 0x0, 0, NO_PAD_CTRL) | ||
344 | |||
345 | #define MX50_PAD_SD1_D0__SD1_D0 IOMUX_PAD(0x398, 0xEC, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
346 | #define MX50_PAD_SD1_D0__GPIO_5_2 IOMUX_PAD(0x398, 0xEC, 1, 0x0, 0, NO_PAD_CTRL) | ||
347 | #define MX50_PAD_SD1_D0__PLL1_BYP IOMUX_PAD(0x398, 0xEC, 7, 0x6dc, 0, NO_PAD_CTRL) | ||
348 | |||
349 | #define MX50_PAD_SD1_D1__SD1_D1 IOMUX_PAD(0x39C, 0xF0, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
350 | #define MX50_PAD_SD1_D1__GPIO_5_3 IOMUX_PAD(0x39C, 0xF0, 1, 0x0, 0, NO_PAD_CTRL) | ||
351 | #define MX50_PAD_SD1_D1__PLL2_BYP IOMUX_PAD(0x39C, 0xF0, 7, 0x6e0, 0, NO_PAD_CTRL) | ||
352 | |||
353 | #define MX50_PAD_SD1_D2__SD1_D2 IOMUX_PAD(0x3A0, 0xF4, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
354 | #define MX50_PAD_SD1_D2__GPIO_5_4 IOMUX_PAD(0x3A0, 0xF4, 1, 0x0, 0, NO_PAD_CTRL) | ||
355 | #define MX50_PAD_SD1_D2__PLL3_BYP IOMUX_PAD(0x3A0, 0xF4, 7, 0x6e4, 0, NO_PAD_CTRL) | ||
356 | |||
357 | #define MX50_PAD_SD1_D3__SD1_D3 IOMUX_PAD(0x3A4, 0xF8, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
358 | #define MX50_PAD_SD1_D3__GPIO_5_5 IOMUX_PAD(0x3A4, 0xF8, 1, 0x0, 0, NO_PAD_CTRL) | ||
359 | |||
360 | #define MX50_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x3A8, 0xFC, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL) | ||
361 | #define MX50_PAD_SD2_CLK__GPIO_5_6 IOMUX_PAD(0x3A8, 0xFC, 1, 0x0, 0, NO_PAD_CTRL) | ||
362 | #define MX50_PAD_SD2_CLK__MSHC_SCLK IOMUX_PAD(0x3A8, 0xFC, 2, 0x0, 0, MX50_SD_PAD_CTRL) | ||
363 | |||
364 | #define MX50_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x3AC, 0x100, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL) | ||
365 | #define MX50_PAD_SD2_CMD__GPIO_5_7 IOMUX_PAD(0x3AC, 0x100, 1, 0x0, 0, NO_PAD_CTRL) | ||
366 | #define MX50_PAD_SD2_CMD__MSHC_BS IOMUX_PAD(0x3AC, 0x100, 2, 0x0, 0, MX50_SD_PAD_CTRL) | ||
367 | |||
368 | #define MX50_PAD_SD2_D0__SD2_D0 IOMUX_PAD(0x3B0, 0x104, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
369 | #define MX50_PAD_SD2_D0__GPIO_5_8 IOMUX_PAD(0x3B0, 0x104, 1, 0x0, 0, NO_PAD_CTRL) | ||
370 | #define MX50_PAD_SD2_D0__MSHC_D0 IOMUX_PAD(0x3B0, 0x104, 2, 0x0, 0, MX50_SD_PAD_CTRL) | ||
371 | #define MX50_PAD_SD2_D0__KEY_COL4 IOMUX_PAD(0x3B0, 0x104, 3, 0x790, 0, NO_PAD_CTRL) | ||
372 | |||
373 | #define MX50_PAD_SD2_D1__SD2_D1 IOMUX_PAD(0x3B4, 0x108, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
374 | #define MX50_PAD_SD2_D1__GPIO_5_9 IOMUX_PAD(0x3B4, 0x108, 1, 0x0, 0, NO_PAD_CTRL) | ||
375 | #define MX50_PAD_SD2_D1__MSHC_D1 IOMUX_PAD(0x3B4, 0x108, 2, 0x0, 0, MX50_SD_PAD_CTRL) | ||
376 | #define MX50_PAD_SD2_D1__KEY_ROW4 IOMUX_PAD(0x3B4, 0x108, 3, 0x7a0, 0, NO_PAD_CTRL) | ||
377 | |||
378 | #define MX50_PAD_SD2_D2__SD2_D2 IOMUX_PAD(0x3B8, 0x10C, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
379 | #define MX50_PAD_SD2_D2__GPIO_5_10 IOMUX_PAD(0x3B8, 0x10C, 1, 0x0, 0, NO_PAD_CTRL) | ||
380 | #define MX50_PAD_SD2_D2__MSHC_D2 IOMUX_PAD(0x3B8, 0x10C, 2, 0x0, 0, MX50_SD_PAD_CTRL) | ||
381 | #define MX50_PAD_SD2_D2__KEY_COL5 IOMUX_PAD(0x3B8, 0x10C, 3, 0x794, 0, NO_PAD_CTRL) | ||
382 | |||
383 | #define MX50_PAD_SD2_D3__SD2_D3 IOMUX_PAD(0x3BC, 0x110, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
384 | #define MX50_PAD_SD2_D3__GPIO_5_11 IOMUX_PAD(0x3BC, 0x110, 1, 0x0, 0, NO_PAD_CTRL) | ||
385 | #define MX50_PAD_SD2_D3__MSHC_D3 IOMUX_PAD(0x3BC, 0x110, 2, 0x0, 0, MX50_SD_PAD_CTRL) | ||
386 | #define MX50_PAD_SD2_D3__KEY_ROW5 IOMUX_PAD(0x3BC, 0x110, 3, 0x7a4, 0, NO_PAD_CTRL) | ||
387 | |||
388 | #define MX50_PAD_SD2_D4__SD2_D4 IOMUX_PAD(0x3C0, 0x114, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
389 | #define MX50_PAD_SD2_D4__GPIO_5_12 IOMUX_PAD(0x3C0, 0x114, 1, 0x0, 0, NO_PAD_CTRL) | ||
390 | #define MX50_PAD_SD2_D4__AUD4_RXFS IOMUX_PAD(0x3C0, 0x114, 2, 0x6d0, 0, NO_PAD_CTRL) | ||
391 | #define MX50_PAD_SD2_D4__KEY_COL6 IOMUX_PAD(0x3C0, 0x114, 3, 0x798, 0, NO_PAD_CTRL) | ||
392 | #define MX50_PAD_SD2_D4__WEIM_D0 IOMUX_PAD(0x3C0, 0x114, 4, 0x7ec, 0, NO_PAD_CTRL) | ||
393 | #define MX50_PAD_SD2_D4__CCM_OUT0 IOMUX_PAD(0x3C0, 0x114, 7, 0x0, 0, NO_PAD_CTRL) | ||
394 | |||
395 | #define MX50_PAD_SD2_D5__SD2_D5 IOMUX_PAD(0x3C4, 0x118, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
396 | #define MX50_PAD_SD2_D5__GPIO_5_13 IOMUX_PAD(0x3C4, 0x118, 1, 0x0, 0, NO_PAD_CTRL) | ||
397 | #define MX50_PAD_SD2_D5__AUD4_RXC IOMUX_PAD(0x3C4, 0x118, 2, 0x6cc, 0, NO_PAD_CTRL) | ||
398 | #define MX50_PAD_SD2_D5__KEY_ROW6 IOMUX_PAD(0x3C4, 0x118, 3, 0x7a8, 0, NO_PAD_CTRL) | ||
399 | #define MX50_PAD_SD2_D5__WEIM_D1 IOMUX_PAD(0x3C4, 0x118, 4, 0x7f0, 0, NO_PAD_CTRL) | ||
400 | #define MX50_PAD_SD2_D5__CCM_OUT1 IOMUX_PAD(0x3C4, 0x118, 7, 0x0, 0, NO_PAD_CTRL) | ||
401 | |||
402 | #define MX50_PAD_SD2_D6__SD2_D6 IOMUX_PAD(0x3C8, 0x11C, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
403 | #define MX50_PAD_SD2_D6__GPIO_5_14 IOMUX_PAD(0x3C8, 0x11C, 1, 0x0, 0, NO_PAD_CTRL) | ||
404 | #define MX50_PAD_SD2_D6__AUD4_RXD IOMUX_PAD(0x3C8, 0x11C, 2, 0x6c4, 0, NO_PAD_CTRL) | ||
405 | #define MX50_PAD_SD2_D6__KEY_COL7 IOMUX_PAD(0x3C8, 0x11C, 3, 0x79c, 0, NO_PAD_CTRL) | ||
406 | #define MX50_PAD_SD2_D6__WEIM_D2 IOMUX_PAD(0x3C8, 0x11C, 4, 0x7f4, 0, NO_PAD_CTRL) | ||
407 | #define MX50_PAD_SD2_D6__CCM_OUT2 IOMUX_PAD(0x3C8, 0x11C, 7, 0x0, 0, NO_PAD_CTRL) | ||
408 | |||
409 | #define MX50_PAD_SD2_D7__SD2_D7 IOMUX_PAD(0x3CC, 0x120, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
410 | #define MX50_PAD_SD2_D7__GPIO_5_15 IOMUX_PAD(0x3CC, 0x120, 1, 0x0, 0, NO_PAD_CTRL) | ||
411 | #define MX50_PAD_SD2_D7__AUD4_TXFS IOMUX_PAD(0x3CC, 0x120, 2, 0x6d8, 0, NO_PAD_CTRL) | ||
412 | #define MX50_PAD_SD2_D7__KEY_ROW7 IOMUX_PAD(0x3CC, 0x120, 3, 0x7ac, 0, NO_PAD_CTRL) | ||
413 | #define MX50_PAD_SD2_D7__WEIM_D3 IOMUX_PAD(0x3CC, 0x120, 4, 0x7f8, 0, NO_PAD_CTRL) | ||
414 | #define MX50_PAD_SD2_D7__CCM_STOP IOMUX_PAD(0x3CC, 0x120, 7, 0x0, 0, NO_PAD_CTRL) | ||
415 | |||
416 | #define MX50_PAD_SD2_WP__SD2_WP IOMUX_PAD(0x3D0, 0x124, 0, 0x744, 1, MX50_SD_PAD_CTRL) | ||
417 | #define MX50_PAD_SD2_WP__GPIO_5_16 IOMUX_PAD(0x3D0, 0x124, 1, 0x0, 0, NO_PAD_CTRL) | ||
418 | #define MX50_PAD_SD2_WP__AUD4_TXD IOMUX_PAD(0x3D0, 0x124, 2, 0x6c8, 0, NO_PAD_CTRL) | ||
419 | #define MX50_PAD_SD2_WP__WEIM_D4 IOMUX_PAD(0x3D0, 0x124, 4, 0x7fc, 0, NO_PAD_CTRL) | ||
420 | #define MX50_PAD_SD2_WP__CCM_WAIT IOMUX_PAD(0x3D0, 0x124, 7, 0x0, 0, NO_PAD_CTRL) | ||
421 | |||
422 | #define MX50_PAD_SD2_CD__SD2_CD IOMUX_PAD(0x3D4, 0x128, 0, 0x740, 1, MX50_SD_PAD_CTRL) | ||
423 | #define MX50_PAD_SD2_CD__GPIO_5_17 IOMUX_PAD(0x3D4, 0x128, 1, 0x0, 0, NO_PAD_CTRL) | ||
424 | #define MX50_PAD_SD2_CD__AUD4_TXC IOMUX_PAD(0x3D4, 0x128, 2, 0x6d4, 0, NO_PAD_CTRL) | ||
425 | #define MX50_PAD_SD2_CD__WEIM_D5 IOMUX_PAD(0x3D4, 0x128, 4, 0x800, 0, NO_PAD_CTRL) | ||
426 | #define MX50_PAD_SD2_CD__CCM_REF_EN IOMUX_PAD(0x3D4, 0x128, 7, 0x0, 0, NO_PAD_CTRL) | ||
427 | |||
428 | #define MX50_PAD_PMIC_ON_REQ__PMIC_ON_REQ IOMUX_PAD(0x3D8, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
429 | |||
430 | #define MX50_PAD_PMIC_STBY_REQ__PMIC_STBY_REQ IOMUX_PAD(0x3DC, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
431 | |||
432 | #define MX50_PAD_PMIC_PORT_B__PMIC_PORT_B IOMUX_PAD(0x3E0, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
433 | |||
434 | #define MX50_PAD_PMIC_BOOT_MODE1__PMIC_BOOT_MODE1 IOMUX_PAD(0x3E4, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
435 | |||
436 | #define MX50_PAD_PMIC_RESET_IN_B__PMIC_RESET_IN_B IOMUX_PAD(0x3E8, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
437 | |||
438 | #define MX50_PAD_PMIC_BOOT_MODE0__PMIC_BOOT_MODE0 IOMUX_PAD(0x3EC, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
439 | |||
440 | #define MX50_PAD_PMIC_TEST_MODE__PMIC_TEST_MODE IOMUX_PAD(0x3F0, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
441 | |||
442 | #define MX50_PAD_PMIC_JTAG_TMS__PMIC_JTAG_TMS IOMUX_PAD(0x3F4, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
443 | |||
444 | #define MX50_PAD_PMIC_JTAG_MOD__PMIC_JTAG_MOD IOMUX_PAD(0x3F8, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
445 | |||
446 | #define MX50_PAD_PMIC_JTAG_TRSTB__PMIC_JTAG_TRSTB IOMUX_PAD(0x3FC, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
447 | |||
448 | #define MX50_PAD_PMIC_JTAG_TDI__PMIC_JTAG_TDI IOMUX_PAD(0x400, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
449 | |||
450 | #define MX50_PAD_PMIC_JTAG_TCK__PMIC_JTAG_TCK IOMUX_PAD(0x404, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
451 | |||
452 | #define MX50_PAD_PMIC_JTAG_TDO__PMIC_JTAG_TDO IOMUX_PAD(0x408, 0, 0, 0x0, 0, NO_PAD_CTRL) | ||
453 | |||
454 | #define MX50_PAD_DISP_D0__DISP_D0 IOMUX_PAD(0x40C, 0x12C, 0, 0x6fc, 0, MX50_ELCDIF_PAD_CTRL) | ||
455 | #define MX50_PAD_DISP_D0__GPIO_2_0 IOMUX_PAD(0x40C, 0x12C, 1, 0x0, 0, NO_PAD_CTRL) | ||
456 | #define MX50_PAD_DISP_D0__FEC_TXCLK IOMUX_PAD(0x40C, 0x12C, 2, 0x78c, 0, PAD_CTL_HYS | PAD_CTL_PKE) | ||
457 | |||
458 | #define MX50_PAD_DISP_D1__DISP_D1 IOMUX_PAD(0x410, 0x130, 0, 0x700, 0, MX50_ELCDIF_PAD_CTRL) | ||
459 | #define MX50_PAD_DISP_D1__GPIO_2_1 IOMUX_PAD(0x410, 0x130, 1, 0x0, 0, NO_PAD_CTRL) | ||
460 | #define MX50_PAD_DISP_D1__FEC_RX_ER IOMUX_PAD(0x410, 0x130, 2, 0x788, 0, PAD_CTL_HYS | PAD_CTL_PKE) | ||
461 | #define MX50_PAD_DISP_D1__WEIM_A17 IOMUX_PAD(0x410, 0x130, 3, 0x0, 0, NO_PAD_CTRL) | ||
462 | |||
463 | #define MX50_PAD_DISP_D2__DISP_D2 IOMUX_PAD(0x414, 0x134, 0, 0x704, 0, MX50_ELCDIF_PAD_CTRL) | ||
464 | #define MX50_PAD_DISP_D2__GPIO_2_2 IOMUX_PAD(0x414, 0x134, 1, 0x0, 0, NO_PAD_CTRL) | ||
465 | #define MX50_PAD_DISP_D2__FEC_RX_DV IOMUX_PAD(0x414, 0x134, 2, 0x784, 0, PAD_CTL_HYS | PAD_CTL_PKE) | ||
466 | #define MX50_PAD_DISP_D2__WEIM_A18 IOMUX_PAD(0x414, 0x134, 3, 0x0, 0, NO_PAD_CTRL) | ||
467 | |||
468 | #define MX50_PAD_DISP_D3__DISP_D3 IOMUX_PAD(0x418, 0x138, 0, 0x708, 0, MX50_ELCDIF_PAD_CTRL) | ||
469 | #define MX50_PAD_DISP_D3__GPIO_2_3 IOMUX_PAD(0x418, 0x138, 1, 0x0, 0, NO_PAD_CTRL) | ||
470 | #define MX50_PAD_DISP_D3__FEC_RXD1 IOMUX_PAD(0x418, 0x138, 2, 0x77C, 0, PAD_CTL_HYS | PAD_CTL_PKE) | ||
471 | #define MX50_PAD_DISP_D3__WEIM_A19 IOMUX_PAD(0x418, 0x138, 3, 0x0, 0, NO_PAD_CTRL) | ||
472 | #define MX50_PAD_DISP_D3__FEC_COL IOMUX_PAD(0x418, 0x138, 4, 0x770, 1, NO_PAD_CTRL) | ||
473 | |||
474 | #define MX50_PAD_DISP_D4__DISP_D4 IOMUX_PAD(0x41C, 0x13C, 0, 0x70c, 0, MX50_ELCDIF_PAD_CTRL) | ||
475 | #define MX50_PAD_DISP_D4__GPIO_2_4 IOMUX_PAD(0x41C, 0x13C, 1, 0x0, 0, NO_PAD_CTRL) | ||
476 | #define MX50_PAD_DISP_D4__FEC_RXD0 IOMUX_PAD(0x41C, 0x13C, 2, 0x778, 0, PAD_CTL_HYS | PAD_CTL_PKE) | ||
477 | #define MX50_PAD_DISP_D4__WEIM_A20 IOMUX_PAD(0x41C, 0x13C, 3, 0x0, 0, NO_PAD_CTRL) | ||
478 | |||
479 | #define MX50_PAD_DISP_D5__DISP_D5 IOMUX_PAD(0x420, 0x140, 0, 0x710, 0, MX50_ELCDIF_PAD_CTRL) | ||
480 | #define MX50_PAD_DISP_D5__GPIO_2_5 IOMUX_PAD(0x420, 0x140, 1, 0x0, 0, NO_PAD_CTRL) | ||
481 | #define MX50_PAD_DISP_D5__FEC_TX_EN IOMUX_PAD(0x420, 0x140, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
482 | #define MX50_PAD_DISP_D5__WEIM_A21 IOMUX_PAD(0x420, 0x140, 3, 0x0, 0, NO_PAD_CTRL) | ||
483 | |||
484 | #define MX50_PAD_DISP_D6__DISP_D6 IOMUX_PAD(0x424, 0x144, 0, 0x714, 0, MX50_ELCDIF_PAD_CTRL) | ||
485 | #define MX50_PAD_DISP_D6__GPIO_2_6 IOMUX_PAD(0x424, 0x144, 1, 0x0, 0, NO_PAD_CTRL) | ||
486 | #define MX50_PAD_DISP_D6__FEC_TXD1 IOMUX_PAD(0x424, 0x144, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
487 | #define MX50_PAD_DISP_D6__WEIM_A22 IOMUX_PAD(0x424, 0x144, 3, 0x0, 0, NO_PAD_CTRL) | ||
488 | #define MX50_PAD_DISP_D6__FEC_RX_CLK IOMUX_PAD(0x424, 0x144, 4, 0x780, 1, NO_PAD_CTRL) | ||
489 | |||
490 | #define MX50_PAD_DISP_D7__DISP_D7 IOMUX_PAD(0x428, 0x148, 0, 0x718, 0, MX50_ELCDIF_PAD_CTRL) | ||
491 | #define MX50_PAD_DISP_D7__GPIO_2_7 IOMUX_PAD(0x428, 0x148, 1, 0x0, 0, NO_PAD_CTRL) | ||
492 | #define MX50_PAD_DISP_D7__FEC_TXD0 IOMUX_PAD(0x428, 0x148, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
493 | #define MX50_PAD_DISP_D7__WEIM_A23 IOMUX_PAD(0x428, 0x148, 3, 0x0, 0, NO_PAD_CTRL) | ||
494 | |||
495 | |||
496 | #define MX50_PAD_DISP_WR__ELCDIF_WR IOMUX_PAD(0x42C, 0x14C, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
497 | #define MX50_PAD_DISP_WR__GPIO_2_16 IOMUX_PAD(0x42C, 0x14C, 1, 0x0, 0, NO_PAD_CTRL) | ||
498 | #define MX50_PAD_DISP_WR__ELCDIF_PIXCLK IOMUX_PAD(0x42C, 0x14C, 2, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
499 | #define MX50_PAD_DISP_WR__WEIM_A24 IOMUX_PAD(0x42C, 0x14C, 3, 0x0, 0, NO_PAD_CTRL) | ||
500 | |||
501 | #define MX50_PAD_DISP_RD__ELCDIF_RD IOMUX_PAD(0x430, 0x150, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
502 | #define MX50_PAD_DISP_RD__GPIO_2_19 IOMUX_PAD(0x430, 0x150, 1, 0x0, 0, NO_PAD_CTRL) | ||
503 | #define MX50_PAD_DISP_RD__ELCDIF_EN IOMUX_PAD(0x430, 0x150, 2, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
504 | #define MX50_PAD_DISP_RD__WEIM_A25 IOMUX_PAD(0x430, 0x150, 3, 0x0, 0, NO_PAD_CTRL) | ||
505 | |||
506 | #define MX50_PAD_DISP_RS__ELCDIF_RS IOMUX_PAD(0x434, 0x154, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
507 | #define MX50_PAD_DISP_RS__GPIO_2_17 IOMUX_PAD(0x434, 0x154, 1, 0x0, 0, NO_PAD_CTRL) | ||
508 | #define MX50_PAD_DISP_RS__ELCDIF_VSYNC IOMUX_PAD(0x434, 0x154, 2, 0x73c, 1, MX50_ELCDIF_PAD_CTRL) | ||
509 | #define MX50_PAD_DISP_RS__WEIM_A26 IOMUX_PAD(0x434, 0x154, 3, 0x0, 0, NO_PAD_CTRL) | ||
510 | |||
511 | #define MX50_PAD_DISP_CS__ELCDIF_CS IOMUX_PAD(0x438, 0x158, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
512 | #define MX50_PAD_DISP_CS__GPIO_2_21 IOMUX_PAD(0x438, 0x158, 1, 0x0, 0, NO_PAD_CTRL) | ||
513 | #define MX50_PAD_DISP_CS__ELCDIF_HSYNC IOMUX_PAD(0x438, 0x158, 2, 0x6f8, 1, MX50_ELCDIF_PAD_CTRL) | ||
514 | #define MX50_PAD_DISP_CS__WEIM_A27 IOMUX_PAD(0x438, 0x158, 3, 0x0, 0, NO_PAD_CTRL) | ||
515 | #define MX50_PAD_DISP_CS__WEIM_CS3 IOMUX_PAD(0x438, 0x158, 4, 0x0, 0, NO_PAD_CTRL) | ||
516 | |||
517 | #define MX50_PAD_DISP_BUSY__ELCDIF_HSYNC IOMUX_PAD(0x43C, 0x15C, 0, 0x6f8, 2, MX50_ELCDIF_PAD_CTRL) | ||
518 | #define MX50_PAD_DISP_BUSY__GPIO_2_18 IOMUX_PAD(0x43C, 0x15C, 1, 0x0, 0, NO_PAD_CTRL) | ||
519 | #define MX50_PAD_DISP_BUSY__WEIM_CS3 IOMUX_PAD(0x43C, 0x15C, 3, 0x0, 0, NO_PAD_CTRL) | ||
520 | |||
521 | #define MX50_PAD_DISP_RESET__ELCDIF_RST IOMUX_PAD(0x440, 0x160, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
522 | #define MX50_PAD_DISP_RESET__GPIO_2_20 IOMUX_PAD(0x440, 0x160, 1, 0x0, 0, NO_PAD_CTRL) | ||
523 | #define MX50_PAD_DISP_RESET__WEIM_CS3 IOMUX_PAD(0x440, 0x160, 4, 0x0, 0, NO_PAD_CTRL) | ||
524 | |||
525 | #define MX50_PAD_SD3_CMD__SD3_CMD IOMUX_PAD(0x444, 0x164, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
526 | #define MX50_PAD_SD3_CMD__GPIO_5_18 IOMUX_PAD(0x444, 0x164, 1, 0x0, 0, NO_PAD_CTRL) | ||
527 | #define MX50_PIN_SD3_CMD__NANDF_WRN IOMUX_PAD(0x444, 0x164, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
528 | #define MX50_PAD_SD3_CMD__SSP_CMD IOMUX_PAD(0x444, 0x164, 3, 0x0, 0, NO_PAD_CTRL) | ||
529 | |||
530 | #define MX50_PAD_SD3_CLK__SD3_CLK IOMUX_PAD(0x448, 0x168, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
531 | #define MX50_PAD_SD3_CLK__GPIO_5_19 IOMUX_PAD(0x448, 0x168, 1, 0x0, 0, NO_PAD_CTRL) | ||
532 | #define MX50_PIN_SD3_CLK__NANDF_RDN IOMUX_PAD(0x448, 0x168, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
533 | #define MX50_PAD_SD3_CLK__SSP_CLK IOMUX_PAD(0x448, 0x168, 3, 0x0, 0, NO_PAD_CTRL) | ||
534 | |||
535 | #define MX50_PAD_SD3_D0__SD3_D0 IOMUX_PAD(0x44C, 0x16C, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
536 | #define MX50_PAD_SD3_D0__GPIO_5_20 IOMUX_PAD(0x44C, 0x16C, 1, 0x0, 0, NO_PAD_CTRL) | ||
537 | #define MX50_PIN_SD3_D0__NANDF_D4 IOMUX_PAD(0x44C, 0x16C, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
538 | #define MX50_PAD_SD3_D0__SSP_D0 IOMUX_PAD(0x44C, 0x16C, 3, 0x0, 0, NO_PAD_CTRL) | ||
539 | #define MX50_PAD_SD3_D0__PLL1_BYP IOMUX_PAD(0x44C, 0x16C, 7, 0x6dc, 1, NO_PAD_CTRL) | ||
540 | |||
541 | #define MX50_PAD_SD3_D1__SD3_D1 IOMUX_PAD(0x450, 0x170, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
542 | #define MX50_PAD_SD3_D1__GPIO_5_21 IOMUX_PAD(0x450, 0x170, 1, 0x0, 0, NO_PAD_CTRL) | ||
543 | #define MX50_PIN_SD3_D1__NANDF_D5 IOMUX_PAD(0x450, 0x170, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
544 | #define MX50_PAD_SD3_D1__PLL2_BYP IOMUX_PAD(0x450, 0x170, 7, 0x6e0, 1, NO_PAD_CTRL) | ||
545 | |||
546 | #define MX50_PAD_SD3_D2__SD3_D2 IOMUX_PAD(0x454, 0x174, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
547 | #define MX50_PAD_SD3_D2__GPIO_5_22 IOMUX_PAD(0x454, 0x174, 1, 0x0, 0, NO_PAD_CTRL) | ||
548 | #define MX50_PIN_SD3_D2__NANDF_D6 IOMUX_PAD(0x454, 0x174, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
549 | #define MX50_PAD_SD3_D2__SSP_D2 IOMUX_PAD(0x454, 0x174, 3, 0x0, 0, NO_PAD_CTRL) | ||
550 | #define MX50_PAD_SD3_D2__PLL3_BYP IOMUX_PAD(0x454, 0x174, 7, 0x6e4, 1, NO_PAD_CTRL) | ||
551 | |||
552 | #define MX50_PAD_SD3_D3__SD3_D3 IOMUX_PAD(0x458, 0x178, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
553 | #define MX50_PAD_SD3_D3__GPIO_5_23 IOMUX_PAD(0x458, 0x178, 1, 0x0, 0, NO_PAD_CTRL) | ||
554 | #define MX50_PIN_SD3_D3__NANDF_D7 IOMUX_PAD(0x458, 0x178, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
555 | #define MX50_PAD_SD3_D3__SSP_D3 IOMUX_PAD(0x458, 0x178, 3, 0x0, 0, NO_PAD_CTRL) | ||
556 | |||
557 | #define MX50_PAD_SD3_D4__SD3_D4 IOMUX_PAD(0x45C, 0x17C, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
558 | #define MX50_PAD_SD3_D4__GPIO_5_24 IOMUX_PAD(0x45C, 0x17C, 1, 0x0, 0, NO_PAD_CTRL) | ||
559 | #define MX50_PIN_SD3_D4__NANDF_D0 IOMUX_PAD(0x45C, 0x17C, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
560 | #define MX50_PAD_SD3_D4__SSP_D4 IOMUX_PAD(0x45C, 0x17C, 1, 0x0, 0, NO_PAD_CTRL) | ||
561 | |||
562 | #define MX50_PAD_SD3_D5__SD3_D5 IOMUX_PAD(0x460, 0x180, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
563 | #define MX50_PAD_SD3_D5__GPIO_5_25 IOMUX_PAD(0x460, 0x180, 1, 0x0, 0, NO_PAD_CTRL) | ||
564 | #define MX50_PIN_SD3_D5__NANDF_D1 IOMUX_PAD(0x460, 0x180, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
565 | #define MX50_PAD_SD3_D5__SSP_D5 IOMUX_PAD(0x460, 0x180, 3, 0x0, 0, NO_PAD_CTRL) | ||
566 | |||
567 | #define MX50_PAD_SD3_D6__SD3_D6 IOMUX_PAD(0x464, 0x184, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
568 | #define MX50_PAD_SD3_D6__GPIO_5_26 IOMUX_PAD(0x464, 0x184, 1, 0x0, 0, NO_PAD_CTRL) | ||
569 | #define MX50_PIN_SD3_D6__NANDF_D2 IOMUX_PAD(0x464, 0x184, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
570 | #define MX50_PAD_SD3_D6__SSP_D6 IOMUX_PAD(0x464, 0x184, 3, 0x0, 0, NO_PAD_CTRL) | ||
571 | |||
572 | #define MX50_PAD_SD3_D7__SD3_D7 IOMUX_PAD(0x468, 0x188, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
573 | #define MX50_PAD_SD3_D7__GPIO_5_27 IOMUX_PAD(0x468, 0x188, 1, 0x0, 0, NO_PAD_CTRL) | ||
574 | #define MX50_PIN_SD3_D7__NANDF_D3 IOMUX_PAD(0x468, 0x188, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
575 | #define MX50_PAD_SD3_D7__SSP_D7 IOMUX_PAD(0x468, 0x188, 3, 0x0, 0, NO_PAD_CTRL) | ||
576 | |||
577 | #define MX50_PAD_SD3_WP__SD3_WP IOMUX_PAD(0x46C, 0x18C, 0, 0x0, 0, MX50_SD_PAD_CTRL) | ||
578 | #define MX50_PAD_SD3_WP__GPIO_5_28 IOMUX_PAD(0x46C, 0x18C, 1, 0x0, 0, NO_PAD_CTRL) | ||
579 | #define MX50_PIN_SD3_WP__NANDF_RESETN IOMUX_PAD(0x46C, 0x18C, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
580 | #define MX50_PAD_SD3_WP__SSP_CD IOMUX_PAD(0x46C, 0x18C, 3, 0x0, 0, NO_PAD_CTRL) | ||
581 | #define MX50_PAD_SD3_WP__SD4_LCTL IOMUX_PAD(0x46C, 0x18C, 4, 0x0, 0, MX50_SD_PAD_CTRL) | ||
582 | #define MX50_PAD_SD3_WP__WEIM_CS3 IOMUX_PAD(0x46C, 0x18C, 5, 0x0, 0, NO_PAD_CTRL) | ||
583 | |||
584 | #define MX50_PAD_DISP_D8__DISP_D8 IOMUX_PAD(0x470, 0x190, 0, 0x71c, 0, MX50_ELCDIF_PAD_CTRL) | ||
585 | #define MX50_PAD_DISP_D8__GPIO_2_8 IOMUX_PAD(0x470, 0x190, 1, 0x0, 0, NO_PAD_CTRL) | ||
586 | #define MX50_PAD_DISP_D8__NANDF_CLE IOMUX_PAD(0x470, 0x190, 2, 0x0, 0, NO_PAD_CTRL) | ||
587 | #define MX50_PAD_DISP_D8__SD1_LCTL IOMUX_PAD(0x470, 0x190, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
588 | #define MX50_PAD_DISP_D8__SD4_CMD IOMUX_PAD(0x470, 0x190, 4, 0x74c, 2, MX50_SD_PAD_CTRL) | ||
589 | #define MX50_PAD_DISP_D8__KEY_COL4 IOMUX_PAD(0x470, 0x190, 5, 0x790, 1, NO_PAD_CTRL) | ||
590 | #define MX50_PAD_DISP_D8__FEC_TX_CLK IOMUX_PAD(0x470, 0x190, 6, 0x78c, 1, NO_PAD_CTRL) | ||
591 | |||
592 | #define MX50_PAD_DISP_D9__DISP_D9 IOMUX_PAD(0x474, 0x194, 0, 0x720, 0, MX50_ELCDIF_PAD_CTRL) | ||
593 | #define MX50_PAD_DISP_D9__GPIO_2_9 IOMUX_PAD(0x474, 0x194, 1, 0x0, 0, NO_PAD_CTRL) | ||
594 | #define MX50_PAD_DISP_D9__NANDF_ALE IOMUX_PAD(0x474, 0x194, 2, 0x0, 0, NO_PAD_CTRL) | ||
595 | #define MX50_PAD_DISP_D9__SD2_LCTL IOMUX_PAD(0x474, 0x194, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
596 | #define MX50_PAD_DISP_D9__SD4_CLK IOMUX_PAD(0x474, 0x194, 4, 0x748, 2, MX50_SD_PAD_CTRL) | ||
597 | #define MX50_PAD_DISP_D9__KEY_ROW4 IOMUX_PAD(0x474, 0x194, 5, 0x7a0, 1, NO_PAD_CTRL) | ||
598 | #define MX50_PAD_DISP_D9__FEC_RX_ER IOMUX_PAD(0x474, 0x194, 6, 0x788, 1, NO_PAD_CTRL) | ||
599 | |||
600 | #define MX50_PAD_DISP_D10__DISP_D10 IOMUX_PAD(0x478, 0x198, 0, 0x724, 0, MX50_ELCDIF_PAD_CTRL) | ||
601 | #define MX50_PAD_DISP_D10__GPIO_2_10 IOMUX_PAD(0x478, 0x198, 1, 0x0, 0, NO_PAD_CTRL) | ||
602 | #define MX50_PAD_DISP_D10__NANDF_CEN0 IOMUX_PAD(0x478, 0x198, 2, 0x0, 0, NO_PAD_CTRL) | ||
603 | #define MX50_PAD_DISP_D10__SD3_LCTL IOMUX_PAD(0x478, 0x198, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
604 | #define MX50_PAD_DISP_D10__SD4_D0 IOMUX_PAD(0x478, 0x198, 4, 0x750, 1, MX50_SD_PAD_CTRL) | ||
605 | #define MX50_PAD_DISP_D10__KEY_COL5 IOMUX_PAD(0x478, 0x198, 5, 0x794, 1, NO_PAD_CTRL) | ||
606 | #define MX50_PAD_DISP_D10__FEC_RX_DV IOMUX_PAD(0x478, 0x198, 6, 0x784, 1, NO_PAD_CTRL) | ||
607 | |||
608 | #define MX50_PAD_DISP_D11__DISP_D11 IOMUX_PAD(0x47C, 0x19C, 0, 0x728, 0, MX50_ELCDIF_PAD_CTRL) | ||
609 | #define MX50_PAD_DISP_D11__GPIO_2_11 IOMUX_PAD(0x47C, 0x19C, 1, 0x0, 0, NO_PAD_CTRL) | ||
610 | #define MX50_PAD_DISP_D11__NANDF_CEN1 IOMUX_PAD(0x47C, 0x19C, 2, 0x0, 0, NO_PAD_CTRL) | ||
611 | #define MX50_PAD_DISP_D11__SD4_D1 IOMUX_PAD(0x47C, 0x19C, 4, 0x754, 1, MX50_SD_PAD_CTRL) | ||
612 | #define MX50_PAD_DISP_D11__KEY_ROW5 IOMUX_PAD(0x47C, 0x19C, 5, 0x7a4, 1, NO_PAD_CTRL) | ||
613 | #define MX50_PAD_DISP_D11__FEC_RDAT1 IOMUX_PAD(0x47C, 0x19C, 6, 0x77c, 1, NO_PAD_CTRL) | ||
614 | |||
615 | #define MX50_PAD_DISP_D12__DISP_D12 IOMUX_PAD(0x480, 0x1A0, 0, 0x72c, 0, MX50_ELCDIF_PAD_CTRL) | ||
616 | #define MX50_PAD_DISP_D12__GPIO_2_12 IOMUX_PAD(0x480, 0x1A0, 1, 0x0, 0, NO_PAD_CTRL) | ||
617 | #define MX50_PAD_DISP_D12__NANDF_CEN2 IOMUX_PAD(0x480, 0x1A0, 2, 0x0, 0, NO_PAD_CTRL) | ||
618 | #define MX50_PAD_DISP_D12__SD1_CD IOMUX_PAD(0x480, 0x1A0, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
619 | #define MX50_PAD_DISP_D12__SD4_D2 IOMUX_PAD(0x480, 0x1A0, 4, 0x758, 1, MX50_SD_PAD_CTRL) | ||
620 | #define MX50_PAD_DISP_D12__KEY_COL6 IOMUX_PAD(0x480, 0x1A0, 5, 0x798, 1, NO_PAD_CTRL) | ||
621 | #define MX50_PAD_DISP_D12__FEC_RDAT0 IOMUX_PAD(0x480, 0x1A0, 6, 0x778, 1, NO_PAD_CTRL) | ||
622 | |||
623 | #define MX50_PAD_DISP_D13__DISP_D13 IOMUX_PAD(0x484, 0x1A4, 0, 0x730, 0, MX50_ELCDIF_PAD_CTRL) | ||
624 | #define MX50_PAD_DISP_D13__GPIO_2_13 IOMUX_PAD(0x484, 0x1A4, 1, 0x0, 0, NO_PAD_CTRL) | ||
625 | #define MX50_PAD_DISP_D13__NANDF_CEN3 IOMUX_PAD(0x484, 0x1A4, 2, 0x0, 0, NO_PAD_CTRL) | ||
626 | #define MX50_PAD_DISP_D13__SD3_CD IOMUX_PAD(0x484, 0x1A4, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
627 | #define MX50_PAD_DISP_D13__SD4_D3 IOMUX_PAD(0x484, 0x1A4, 4, 0x75c, 1, MX50_SD_PAD_CTRL) | ||
628 | #define MX50_PAD_DISP_D13__KEY_ROW6 IOMUX_PAD(0x484, 0x1A4, 5, 0x7a8, 1, NO_PAD_CTRL) | ||
629 | #define MX50_PAD_DISP_D13__FEC_TX_EN IOMUX_PAD(0x484, 0x1A4, 6, 0x0, 0, NO_PAD_CTRL) | ||
630 | |||
631 | #define MX50_PAD_DISP_D14__DISP_D14 IOMUX_PAD(0x488, 0x1A8, 0, 0x734, 0, MX50_ELCDIF_PAD_CTRL) | ||
632 | #define MX50_PAD_DISP_D14__GPIO_2_14 IOMUX_PAD(0x488, 0x1A8, 1, 0x0, 0, NO_PAD_CTRL) | ||
633 | #define MX50_PAD_DISP_D14__NANDF_RDY0 IOMUX_PAD(0x488, 0x1A8, 2, 0x7b4, 1, NO_PAD_CTRL) | ||
634 | #define MX50_PAD_DISP_D14__SD1_WP IOMUX_PAD(0x488, 0x1A8, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
635 | #define MX50_PAD_DISP_D14__SD4_WP IOMUX_PAD(0x488, 0x1A8, 4, 0x0, 0, MX50_SD_PAD_CTRL) | ||
636 | #define MX50_PAD_DISP_D14__KEY_COL7 IOMUX_PAD(0x488, 0x1A8, 5, 0x79c, 1, NO_PAD_CTRL) | ||
637 | #define MX50_PAD_DISP_D14__FEC_TDAT1 IOMUX_PAD(0x488, 0x1A8, 6, 0x0, 0, NO_PAD_CTRL) | ||
638 | |||
639 | #define MX50_PAD_DISP_D15__DISP_D15 IOMUX_PAD(0x48C, 0x1AC, 0, 0x738, 0, MX50_ELCDIF_PAD_CTRL) | ||
640 | #define MX50_PAD_DISP_D15__GPIO_2_15 IOMUX_PAD(0x48C, 0x1AC, 1, 0x0, 0, NO_PAD_CTRL) | ||
641 | #define MX50_PAD_DISP_D15__NANDF_DQS IOMUX_PAD(0x48C, 0x1AC, 2, 0x7b0, 1, NO_PAD_CTRL) | ||
642 | #define MX50_PAD_DISP_D15__SD3_RST IOMUX_PAD(0x48C, 0x1AC, 3, 0x0, 0, MX50_SD_PAD_CTRL) | ||
643 | #define MX50_PAD_DISP_D15__SD4_CD IOMUX_PAD(0x48C, 0x1AC, 4, 0x0, 0, MX50_SD_PAD_CTRL) | ||
644 | #define MX50_PAD_DISP_D15__KEY_ROW7 IOMUX_PAD(0x48C, 0x1AC, 5, 0x7ac, 1, NO_PAD_CTRL) | ||
645 | #define MX50_PAD_DISP_D15__FEC_TDAT0 IOMUX_PAD(0x48C, 0x1AC, 6, 0x0, 0, NO_PAD_CTRL) | ||
646 | |||
647 | #define MX50_PAD_EPDC_D0__EPDC_D0 IOMUX_PAD(0x54C, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL) | ||
648 | #define MX50_PAD_EPDC_D0__GPIO_3_0 IOMUX_PAD(0x54C, 0x1B0, 1, 0x0, 0, NO_PAD_CTRL) | ||
649 | #define MX50_PAD_EPDC_D0__WEIM_D0 IOMUX_PAD(0x54C, 0x1B0, 2, 0x7ec, 1, NO_PAD_CTRL) | ||
650 | #define MX50_PAD_EPDC_D0__ELCDIF_RS IOMUX_PAD(0x54C, 0x1B0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
651 | #define MX50_PAD_EPDC_D0__ELCDIF_PIXCLK IOMUX_PAD(0x54C, 0x1B0, 4, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
652 | |||
653 | #define MX50_PAD_EPDC_D1__EPDC_D1 IOMUX_PAD(0x550, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL) | ||
654 | #define MX50_PAD_EPDC_D1__GPIO_3_1 IOMUX_PAD(0x550, 0x1B4, 1, 0x0, 0, NO_PAD_CTRL) | ||
655 | #define MX50_PAD_EPDC_D1__WEIM_D1 IOMUX_PAD(0x550, 0x1B4, 2, 0x7f0, 1, NO_PAD_CTRL) | ||
656 | #define MX50_PAD_EPDC_D1__ELCDIF_CS IOMUX_PAD(0x550, 0x1B4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
657 | #define MX50_PAD_EPDC_D1__ELCDIF_EN IOMUX_PAD(0x550, 0x1B4, 4, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
658 | |||
659 | #define MX50_PAD_EPDC_D2__EPDC_D2 IOMUX_PAD(0x554, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL) | ||
660 | #define MX50_PAD_EPDC_D2__GPIO_3_2 IOMUX_PAD(0x554, 0x1B8, 1, 0x0, 0, NO_PAD_CTRL) | ||
661 | #define MX50_PAD_EPDC_D2__WEIM_D2 IOMUX_PAD(0x554, 0x1B8, 2, 0x7f4, 1, NO_PAD_CTRL) | ||
662 | #define MX50_PAD_EPDC_D2__ELCDIF_WR IOMUX_PAD(0x554, 0x1B8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
663 | #define MX50_PAD_EPDC_D2__ELCDIF_VSYNC IOMUX_PAD(0x554, 0x1B8, 4, 0x73c, 2, MX50_ELCDIF_PAD_CTRL) | ||
664 | |||
665 | #define MX50_PAD_EPDC_D3__EPDC_D3 IOMUX_PAD(0x558, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL) | ||
666 | #define MX50_PAD_EPDC_D3__GPIO_3_3 IOMUX_PAD(0x558, 0x1BC, 1, 0x0, 0, NO_PAD_CTRL) | ||
667 | #define MX50_PAD_EPDC_D3__WEIM_D3 IOMUX_PAD(0x558, 0x1BC, 2, 0x7f8, 1, NO_PAD_CTRL) | ||
668 | #define MX50_PAD_EPDC_D3__ELCDIF_RD IOMUX_PAD(0x558, 0x1BC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
669 | #define MX50_PAD_EPDC_D3__ELCDIF_HSYNC IOMUX_PAD(0x558, 0x1BC, 4, 0x6f8, 3, MX50_ELCDIF_PAD_CTRL) | ||
670 | |||
671 | #define MX50_PAD_EPDC_D4__EPDC_D4 IOMUX_PAD(0x55C, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL) | ||
672 | #define MX50_PAD_EPDC_D4__GPIO_3_4 IOMUX_PAD(0x55C, 0x1C0, 1, 0x0, 0, NO_PAD_CTRL) | ||
673 | #define MX50_PAD_EPDC_D4__WEIM_D4 IOMUX_PAD(0x55C, 0x1C0, 2, 0x7fc, 1, NO_PAD_CTRL) | ||
674 | |||
675 | #define MX50_PAD_EPDC_D5__EPDC_D5 IOMUX_PAD(0x560, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL) | ||
676 | #define MX50_PAD_EPDC_D5__GPIO_3_5 IOMUX_PAD(0x560, 0x1C4, 1, 0x0, 0, NO_PAD_CTRL) | ||
677 | #define MX50_PAD_EPDC_D5__WEIM_D5 IOMUX_PAD(0x560, 0x1C4, 2, 0x800, 1, NO_PAD_CTRL) | ||
678 | |||
679 | #define MX50_PAD_EPDC_D6__EPDC_D6 IOMUX_PAD(0x564, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL) | ||
680 | #define MX50_PAD_EPDC_D6__GPIO_3_6 IOMUX_PAD(0x564, 0x1C8, 1, 0x0, 0, NO_PAD_CTRL) | ||
681 | #define MX50_PAD_EPDC_D6__WEIM_D6 IOMUX_PAD(0x564, 0x1C8, 2, 0x804, 1, NO_PAD_CTRL) | ||
682 | |||
683 | #define MX50_PAD_EPDC_D7__EPDC_D7 IOMUX_PAD(0x568, 0x1CC, 0, 0x0, 0, NO_PAD_CTRL) | ||
684 | #define MX50_PAD_EPDC_D7__GPIO_3_7 IOMUX_PAD(0x568, 0x1CC, 1, 0x0, 0, NO_PAD_CTRL) | ||
685 | #define MX50_PAD_EPDC_D7__WEIM_D7 IOMUX_PAD(0x568, 0x1CC, 2, 0x808, 1, NO_PAD_CTRL) | ||
686 | |||
687 | #define MX50_PAD_EPDC_D8__EPDC_D8 IOMUX_PAD(0x56C, 0x1D0, 0, 0x0, 0, NO_PAD_CTRL) | ||
688 | #define MX50_PAD_EPDC_D8__GPIO_3_8 IOMUX_PAD(0x56C, 0x1D0, 1, 0x0, 0, NO_PAD_CTRL) | ||
689 | #define MX50_PAD_EPDC_D8__WEIM_D8 IOMUX_PAD(0x56C, 0x1D0, 2, 0x80c, 2, NO_PAD_CTRL) | ||
690 | #define MX50_PAD_EPDC_D8__ELCDIF_D24 IOMUX_PAD(0x56C, 0x1D0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
691 | |||
692 | #define MX50_PAD_EPDC_D9__EPDC_D9 IOMUX_PAD(0x570, 0x1D4, 0, 0x0, 0, NO_PAD_CTRL) | ||
693 | #define MX50_PAD_EPDC_D9__GPIO_3_9 IOMUX_PAD(0x570, 0x1D4, 1, 0x0, 0, NO_PAD_CTRL) | ||
694 | #define MX50_PAD_EPDC_D9__WEIM_D9 IOMUX_PAD(0x570, 0x1D4, 2, 0x810, 2, NO_PAD_CTRL) | ||
695 | #define MX50_PAD_EPDC_D9__ELCDIF_D25 IOMUX_PAD(0x570, 0x1D4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
696 | |||
697 | #define MX50_PAD_EPDC_D10__EPDC_D10 IOMUX_PAD(0x574, 0x1D8, 0, 0x0, 0, NO_PAD_CTRL) | ||
698 | #define MX50_PAD_EPDC_D10__GPIO_3_10 IOMUX_PAD(0x574, 0x1D8, 1, 0x0, 0, NO_PAD_CTRL) | ||
699 | #define MX50_PAD_EPDC_D10__WEIM_D10 IOMUX_PAD(0x574, 0x1D8, 2, 0x814, 2, NO_PAD_CTRL) | ||
700 | #define MX50_PAD_EPDC_D10__ELCDIF_D26 IOMUX_PAD(0x574, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL) | ||
701 | |||
702 | #define MX50_PAD_EPDC_D11__EPDC_D11 IOMUX_PAD(0x578, 0x1DC, 0, 0x0, 0, NO_PAD_CTRL) | ||
703 | #define MX50_PAD_EPDC_D11__GPIO_3_11 IOMUX_PAD(0x578, 0x1DC, 1, 0x0, 0, NO_PAD_CTRL) | ||
704 | #define MX50_PAD_EPDC_D11__WEIM_D11 IOMUX_PAD(0x578, 0x1DC, 2, 0x818, 2, NO_PAD_CTRL) | ||
705 | #define MX50_PAD_EPDC_D11__ELCDIF_D27 IOMUX_PAD(0x578, 0x1DC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
706 | |||
707 | #define MX50_PAD_EPDC_D12__EPDC_D12 IOMUX_PAD(0x57C, 0x1E0, 0, 0x0, 0, NO_PAD_CTRL) | ||
708 | #define MX50_PAD_EPDC_D12__GPIO_3_12 IOMUX_PAD(0x57C, 0x1E0, 1, 0x0, 0, NO_PAD_CTRL) | ||
709 | #define MX50_PAD_EPDC_D12__WEIM_D12 IOMUX_PAD(0x57C, 0x1E0, 2, 0x81c, 1, NO_PAD_CTRL) | ||
710 | #define MX50_PAD_EPDC_D12__ELCDIF_D28 IOMUX_PAD(0x57C, 0x1E0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
711 | |||
712 | #define MX50_PAD_EPDC_D13__EPDC_D13 IOMUX_PAD(0x580, 0x1E4, 0, 0x0, 0, NO_PAD_CTRL) | ||
713 | #define MX50_PAD_EPDC_D13__GPIO_3_13 IOMUX_PAD(0x580, 0x1E4, 1, 0x0, 0, NO_PAD_CTRL) | ||
714 | #define MX50_PAD_EPDC_D13__WEIM_D13 IOMUX_PAD(0x580, 0x1E4, 2, 0x820, 1, NO_PAD_CTRL) | ||
715 | #define MX50_PAD_EPDC_D13__ELCDIF_D29 IOMUX_PAD(0x580, 0x1E4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
716 | |||
717 | #define MX50_PAD_EPDC_D14__EPDC_D14 IOMUX_PAD(0x584, 0x1E8, 0, 0x0, 0, NO_PAD_CTRL) | ||
718 | #define MX50_PAD_EPDC_D14__GPIO_3_14 IOMUX_PAD(0x584, 0x1E8, 1, 0x0, 0, NO_PAD_CTRL) | ||
719 | #define MX50_PAD_EPDC_D14__WEIM_D14 IOMUX_PAD(0x584, 0x1E8, 2, 0x824, 1, NO_PAD_CTRL) | ||
720 | #define MX50_PAD_EPDC_D14__ELCDIF_D30 IOMUX_PAD(0x584, 0x1E8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
721 | #define MX50_PAD_EPDC_D14__AUD6_TXD IOMUX_PAD(0x584, 0x1E8, 4, 0x0, 0, NO_PAD_CTRL) | ||
722 | |||
723 | #define MX50_PAD_EPDC_D15__EPDC_D15 IOMUX_PAD(0x588, 0x1EC, 0, 0x0, 0, NO_PAD_CTRL) | ||
724 | #define MX50_PAD_EPDC_D15__GPIO_3_15 IOMUX_PAD(0x588, 0x1EC, 1, 0x0, 0, NO_PAD_CTRL) | ||
725 | #define MX50_PAD_EPDC_D15__WEIM_D15 IOMUX_PAD(0x588, 0x1EC, 2, 0x828, 1, NO_PAD_CTRL) | ||
726 | #define MX50_PAD_EPDC_D15__ELCDIF_D31 IOMUX_PAD(0x588, 0x1EC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
727 | #define MX50_PAD_EPDC_D15__AUD6_TXC IOMUX_PAD(0x588, 0x1EC, 4, 0x0, 0, NO_PAD_CTRL) | ||
728 | |||
729 | #define MX50_PAD_EPDC_GDCLK__EPDC_GDCLK IOMUX_PAD(0x58C, 0x1F0, 0, 0x0, 0, NO_PAD_CTRL) | ||
730 | #define MX50_PAD_EPDC_GDCLK__GPIO_3_16 IOMUX_PAD(0x58C, 0x1F0, 1, 0x0, 0, NO_PAD_CTRL) | ||
731 | #define MX50_PAD_EPDC_GDCLK__WEIM_D16 IOMUX_PAD(0x58C, 0x1F0, 2, 0x0, 0, NO_PAD_CTRL) | ||
732 | #define MX50_PAD_EPDC_GDCLK__ELCDIF_D16 IOMUX_PAD(0x58C, 0x1F0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
733 | #define MX50_PAD_EPDC_GDCLK__AUD6_TXFS IOMUX_PAD(0x58C, 0x1F0, 4, 0x0, 0, NO_PAD_CTRL) | ||
734 | |||
735 | #define MX50_PAD_EPDC_GDSP__EPDC_GDSP IOMUX_PAD(0x590, 0x1F4, 0, 0x0, 0, NO_PAD_CTRL) | ||
736 | #define MX50_PAD_EPDC_GDSP__GPIO_3_17 IOMUX_PAD(0x590, 0x1F4, 1, 0x0, 0, NO_PAD_CTRL) | ||
737 | #define MX50_PAD_EPDC_GDSP__WEIM_D17 IOMUX_PAD(0x590, 0x1F4, 2, 0x0, 0, NO_PAD_CTRL) | ||
738 | #define MX50_PAD_EPDC_GDSP__ELCDIF_D17 IOMUX_PAD(0x590, 0x1F4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
739 | #define MX50_PAD_EPDC_GDSP__AUD6_RXD IOMUX_PAD(0x590, 0x1F4, 4, 0x0, 0, NO_PAD_CTRL) | ||
740 | |||
741 | #define MX50_PAD_EPDC_GDOE__EPDC_GDOE IOMUX_PAD(0x594, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL) | ||
742 | #define MX50_PAD_EPDC_GDOE__GPIO_3_18 IOMUX_PAD(0x594, 0x1F8, 1, 0x0, 0, NO_PAD_CTRL) | ||
743 | #define MX50_PAD_EPDC_GDOE__WEIM_D18 IOMUX_PAD(0x594, 0x1F8, 2, 0x0, 0, NO_PAD_CTRL) | ||
744 | #define MX50_PAD_EPDC_GDOE__ELCDIF_D18 IOMUX_PAD(0x594, 0x1F8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
745 | #define MX50_PAD_EPDC_GDOE__AUD6_RXC IOMUX_PAD(0x594, 0x1F8, 4, 0x0, 0, NO_PAD_CTRL) | ||
746 | |||
747 | #define MX50_PAD_EPDC_GDRL__EPDC_GDRL IOMUX_PAD(0x598, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL) | ||
748 | #define MX50_PAD_EPDC_GDRL__GPIO_3_19 IOMUX_PAD(0x598, 0x1FC, 1, 0x0, 0, NO_PAD_CTRL) | ||
749 | #define MX50_PAD_EPDC_GDRL__WEIM_D19 IOMUX_PAD(0x598, 0x1FC, 2, 0x0, 0, NO_PAD_CTRL) | ||
750 | #define MX50_PAD_EPDC_GDRL__ELCDIF_D19 IOMUX_PAD(0x598, 0x1FC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
751 | #define MX50_PAD_EPDC_GDRL__AUD6_RXFS IOMUX_PAD(0x598, 0x1FC, 4, 0x0, 0, NO_PAD_CTRL) | ||
752 | |||
753 | #define MX50_PAD_EPDC_SDCLK__EPDC_SDCLK IOMUX_PAD(0x59C, 0x200, 0, 0x0, 0, NO_PAD_CTRL) | ||
754 | #define MX50_PAD_EPDC_SDCLK__GPIO_3_20 IOMUX_PAD(0x59C, 0x200, 1, 0x0, 0, NO_PAD_CTRL) | ||
755 | #define MX50_PAD_EPDC_SDCLK__WEIM_D20 IOMUX_PAD(0x59C, 0x200, 2, 0x0, 0, NO_PAD_CTRL) | ||
756 | #define MX50_PAD_EPDC_SDCLK__ELCDIF_D20 IOMUX_PAD(0x59C, 0x200, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
757 | #define MX50_PAD_EPDC_SDCLK__AUD5_TXD IOMUX_PAD(0x59C, 0x200, 4, 0x0, 0, NO_PAD_CTRL) | ||
758 | |||
759 | #define MX50_PAD_EPDC_SDOEZ__EPDC_SDOEZ IOMUX_PAD(0x5A0, 0x204, 0, 0x0, 0, NO_PAD_CTRL) | ||
760 | #define MX50_PAD_EPDC_SDOEZ__GPIO_3_21 IOMUX_PAD(0x5A0, 0x204, 1, 0x0, 0, NO_PAD_CTRL) | ||
761 | #define MX50_PAD_EPDC_SDOEZ__WEIM_D21 IOMUX_PAD(0x5A0, 0x204, 2, 0x0, 0, NO_PAD_CTRL) | ||
762 | #define MX50_PAD_EPDC_SDOEZ__ELCDIF_D21 IOMUX_PAD(0x5A0, 0x204, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
763 | #define MX50_PAD_EPDC_SDOEZ__AUD5_TXC IOMUX_PAD(0x5A0, 0x204, 4, 0x0, 0, NO_PAD_CTRL) | ||
764 | |||
765 | #define MX50_PAD_EPDC_SDOED__EPDC_SDOED IOMUX_PAD(0x5A4, 0x208, 0, 0x0, 0, NO_PAD_CTRL) | ||
766 | #define MX50_PAD_EPDC_SDOED__GPIO_3_22 IOMUX_PAD(0x5A4, 0x208, 1, 0x0, 0, NO_PAD_CTRL) | ||
767 | #define MX50_PAD_EPDC_SDOED__WEIM_D22 IOMUX_PAD(0x5A4, 0x208, 2, 0x0, 0, NO_PAD_CTRL) | ||
768 | #define MX50_PAD_EPDC_SDOED__ELCDIF_D22 IOMUX_PAD(0x5A4, 0x208, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
769 | #define MX50_PAD_EPDC_SDOED__AUD5_TXFS IOMUX_PAD(0x5A4, 0x208, 4, 0x0, 0, NO_PAD_CTRL) | ||
770 | |||
771 | #define MX50_PAD_EPDC_SDOE__EPDC_SDOE IOMUX_PAD(0x5A8, 0x20C, 0, 0x0, 0, NO_PAD_CTRL) | ||
772 | #define MX50_PAD_EPDC_SDOE__GPIO_3_23 IOMUX_PAD(0x5A8, 0x20C, 1, 0x0, 0, NO_PAD_CTRL) | ||
773 | #define MX50_PAD_EPDC_SDOE__WEIM_D23 IOMUX_PAD(0x5A8, 0x20C, 2, 0x0, 0, NO_PAD_CTRL) | ||
774 | #define MX50_PAD_EPDC_SDOE__ELCDIF_D23 IOMUX_PAD(0x5A8, 0x20C, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL) | ||
775 | #define MX50_PAD_EPDC_SDOE__AUD5_RXD IOMUX_PAD(0x5A8, 0x20C, 4, 0x0, 0, NO_PAD_CTRL) | ||
776 | |||
777 | #define MX50_PAD_EPDC_SDLE__EPDC_SDLE IOMUX_PAD(0x5AC, 0x210, 0, 0x0, 0, NO_PAD_CTRL) | ||
778 | #define MX50_PAD_EPDC_SDLE__GPIO_3_24 IOMUX_PAD(0x5AC, 0x210, 1, 0x0, 0, NO_PAD_CTRL) | ||
779 | #define MX50_PAD_EPDC_SDLE__WEIM_D24 IOMUX_PAD(0x5AC, 0x210, 2, 0x0, 0, NO_PAD_CTRL) | ||
780 | #define MX50_PAD_EPDC_SDLE__ELCDIF_D8 IOMUX_PAD(0x5AC, 0x210, 3, 0x71c, 1, MX50_ELCDIF_PAD_CTRL) | ||
781 | #define MX50_PAD_EPDC_SDLE__AUD5_RXC IOMUX_PAD(0x5AC, 0x210, 4, 0x0, 0, NO_PAD_CTRL) | ||
782 | |||
783 | #define MX50_PAD_EPDC_SDCLKN__EPDC_SDCLKN IOMUX_PAD(0x5B0, 0x214, 0, 0x0, 0, NO_PAD_CTRL) | ||
784 | #define MX50_PAD_EPDC_SDCLKN__GPIO_3_25 IOMUX_PAD(0x5B0, 0x214, 1, 0x0, 0, NO_PAD_CTRL) | ||
785 | #define MX50_PAD_EPDC_SDCLKN__WEIM_D25 IOMUX_PAD(0x5B0, 0x214, 2, 0x0, 0, NO_PAD_CTRL) | ||
786 | #define MX50_PAD_EPDC_SDCLKN__ELCDIF_D9 IOMUX_PAD(0x5B0, 0x214, 3, 0x720, 1, MX50_ELCDIF_PAD_CTRL) | ||
787 | #define MX50_PAD_EPDC_SDCLKN__AUD5_RXFS IOMUX_PAD(0x5B0, 0x214, 4, 0x0, 0, NO_PAD_CTRL) | ||
788 | |||
789 | #define MX50_PAD_EPDC_SDSHR__EPDC_SDSHR IOMUX_PAD(0x5B4, 0x218, 0, 0x0, 0, NO_PAD_CTRL) | ||
790 | #define MX50_PAD_EPDC_SDSHR__GPIO_3_26 IOMUX_PAD(0x5B4, 0x218, 1, 0x0, 0, NO_PAD_CTRL) | ||
791 | #define MX50_PAD_EPDC_SDSHR__WEIM_D26 IOMUX_PAD(0x5B4, 0x218, 2, 0x0, 0, NO_PAD_CTRL) | ||
792 | #define MX50_PAD_EPDC_SDSHR__ELCDIF_D10 IOMUX_PAD(0x5B4, 0x218, 3, 0x724, 1, MX50_ELCDIF_PAD_CTRL) | ||
793 | #define MX50_PAD_EPDC_SDSHR__AUD4_TXD IOMUX_PAD(0x5B4, 0x218, 4, 0x6c8, 1, NO_PAD_CTRL) | ||
794 | |||
795 | #define MX50_PAD_EPDC_PWRCOM__EPDC_PWRCOM IOMUX_PAD(0x5B8, 0x21C, 0, 0x0, 0, NO_PAD_CTRL) | ||
796 | #define MX50_PAD_EPDC_PWRCOM__GPIO_3_27 IOMUX_PAD(0x5B8, 0x21C, 1, 0x0, 0, NO_PAD_CTRL) | ||
797 | #define MX50_PAD_EPDC_PWRCOM__WEIM_D27 IOMUX_PAD(0x5B8, 0x21C, 2, 0x0, 0, NO_PAD_CTRL) | ||
798 | #define MX50_PAD_EPDC_PWRCOM__ELCDIF_D11 IOMUX_PAD(0x5B8, 0x21C, 3, 0x728, 1, MX50_ELCDIF_PAD_CTRL) | ||
799 | #define MX50_PAD_EPDC_PWRCOM__AUD4_TXC IOMUX_PAD(0x5B8, 0x21C, 4, 0x6d4, 1, NO_PAD_CTRL) | ||
800 | |||
801 | #define MX50_PAD_EPDC_PWRSTAT__EPDC_PWRSTAT IOMUX_PAD(0x5BC, 0x220, 0, 0x0, 0, NO_PAD_CTRL) | ||
802 | #define MX50_PAD_EPDC_PWRSTAT__GPIO_3_28 IOMUX_PAD(0x5BC, 0x220, 1, 0x0, 0, NO_PAD_CTRL) | ||
803 | #define MX50_PAD_EPDC_PWRSTAT__WEIM_D28 IOMUX_PAD(0x5BC, 0x220, 2, 0x0, 0, NO_PAD_CTRL) | ||
804 | #define MX50_PAD_EPDC_PWRSTAT__ELCDIF_D12 IOMUX_PAD(0x5BC, 0x220, 3, 0x72c, 1, MX50_ELCDIF_PAD_CTRL) | ||
805 | #define MX50_PAD_EPDC_PWRSTAT__AUD4_TXFS IOMUX_PAD(0x5BC, 0x220, 4, 0x6d8, 1, NO_PAD_CTRL) | ||
806 | |||
807 | #define MX50_PAD_EPDC_PWRCTRL0__EPDC_PWRCTRL0 IOMUX_PAD(0x5C0, 0x224, 0, 0x0, 0, NO_PAD_CTRL) | ||
808 | #define MX50_PAD_EPDC_PWRCTRL0__GPIO_3_29 IOMUX_PAD(0x5C0, 0x224, 1, 0x0, 0, NO_PAD_CTRL) | ||
809 | #define MX50_PAD_EPDC_PWRCTRL0__WEIM_D29 IOMUX_PAD(0x5C0, 0x224, 2, 0x0, 0, NO_PAD_CTRL) | ||
810 | #define MX50_PAD_EPDC_PWRCTRL0__ELCDIF_D13 IOMUX_PAD(0x5C0, 0x224, 3, 0x730, 1, MX50_ELCDIF_PAD_CTRL) | ||
811 | #define MX50_PAD_EPDC_PWRCTRL0__AUD4_RXD IOMUX_PAD(0x5C0, 0x224, 4, 0x6c4, 1, NO_PAD_CTRL) | ||
812 | |||
813 | #define MX50_PAD_EPDC_PWRCTRL1__EPDC_PWRCTRL1 IOMUX_PAD(0x5C4, 0x228, 0, 0x0, 0, NO_PAD_CTRL) | ||
814 | #define MX50_PAD_EPDC_PWRCTRL1__GPIO_3_30 IOMUX_PAD(0x5C4, 0x228, 1, 0x0, 0, NO_PAD_CTRL) | ||
815 | #define MX50_PAD_EPDC_PWRCTRL1__WEIM_D30 IOMUX_PAD(0x5C4, 0x228, 2, 0x0, 0, NO_PAD_CTRL) | ||
816 | #define MX50_PAD_EPDC_PWRCTRL1__ELCDIF_D14 IOMUX_PAD(0x5C4, 0x228, 3, 0x734, 1, MX50_ELCDIF_PAD_CTRL) | ||
817 | #define MX50_PAD_EPDC_PWRCTRL1__AUD4_RXC IOMUX_PAD(0x5C4, 0x228, 4, 0x6cc, 1, NO_PAD_CTRL) | ||
818 | |||
819 | #define MX50_PAD_EPDC_PWRCTRL2__EPDC_PWRCTRL2 IOMUX_PAD(0x5C8, 0x22C, 0, 0x0, 0, NO_PAD_CTRL) | ||
820 | #define MX50_PAD_EPDC_PWRCTRL2__GPIO_3_31 IOMUX_PAD(0x5C8, 0x22C, 1, 0x0, 0, NO_PAD_CTRL) | ||
821 | #define MX50_PAD_EPDC_PWRCTRL2__WEIM_D31 IOMUX_PAD(0x5C8, 0x22C, 2, 0x0, 0, NO_PAD_CTRL) | ||
822 | #define MX50_PAD_EPDC_PWRCTRL2__ELCDIF_D15 IOMUX_PAD(0x5C8, 0x22C, 3, 0x738, 1, MX50_ELCDIF_PAD_CTRL) | ||
823 | #define MX50_PAD_EPDC_PWRCTRL2__AUD4_RXFS IOMUX_PAD(0x5C8, 0x22C, 4, 0x6d0, 1, NO_PAD_CTRL) | ||
824 | #define MX50_PAD_EPDC_PWRCTRL2__SDMA_EXT0 IOMUX_PAD(0x5C8, 0x22C, 6, 0x7b8, 1, NO_PAD_CTRL) | ||
825 | |||
826 | #define MX50_PAD_EPDC_PWRCTRL3__PWRCTRL3 IOMUX_PAD(0x5CC, 0x230, 0, 0x0, 0, NO_PAD_CTRL) | ||
827 | #define MX50_PAD_EPDC_PWRCTRL3__GPIO_4_20 IOMUX_PAD(0x5CC, 0x230, 1, 0x0, 0, NO_PAD_CTRL) | ||
828 | #define MX50_PAD_EPDC_PWRCTRL3__WEIM_EB2 IOMUX_PAD(0x5CC, 0x230, 2, 0x0, 0, NO_PAD_CTRL) | ||
829 | #define MX50_PAD_EPDC_PWRCTRL3__SDMA_EXT1 IOMUX_PAD(0x5CC, 0x230, 6, 0x7bc, 1, NO_PAD_CTRL) | ||
830 | |||
831 | #define MX50_PAD_EPDC_VCOM0__EPDC_VCOM0 IOMUX_PAD(0x5D0, 0x234, 0, 0x0, 0, NO_PAD_CTRL) | ||
832 | #define MX50_PAD_EPDC_VCOM0__GPIO_4_21 IOMUX_PAD(0x5D0, 0x234, 1, 0x0, 0, NO_PAD_CTRL) | ||
833 | #define MX50_PAD_EPDC_VCOM0__WEIM_EB3 IOMUX_PAD(0x5D0, 0x234, 2, 0x0, 0, NO_PAD_CTRL) | ||
834 | |||
835 | #define MX50_PAD_EPDC_VCOM1__EPDC_VCOM1 IOMUX_PAD(0x5D4, 0x238, 0, 0x0, 0, NO_PAD_CTRL) | ||
836 | #define MX50_PAD_EPDC_VCOM1__GPIO_4_22 IOMUX_PAD(0x5D4, 0x238, 1, 0x0, 0, NO_PAD_CTRL) | ||
837 | #define MX50_PAD_EPDC_VCOM1__WEIM_CS3 IOMUX_PAD(0x5D4, 0x238, 2, 0x0, 0, NO_PAD_CTRL) | ||
838 | |||
839 | #define MX50_PAD_EPDC_BDR0__EPDC_BDR0 IOMUX_PAD(0x5D8, 0x23C, 0, 0x0, 0, NO_PAD_CTRL) | ||
840 | #define MX50_PAD_EPDC_BDR0__GPIO_4_23 IOMUX_PAD(0x5D8, 0x23C, 1, 0x0, 0, NO_PAD_CTRL) | ||
841 | #define MX50_PAD_EPDC_BDR0__ELCDIF_D7 IOMUX_PAD(0x5D8, 0x23C, 3, 0x718, 1, MX50_ELCDIF_PAD_CTRL) | ||
842 | |||
843 | #define MX50_PAD_EPDC_BDR1__EPDC_BDR1 IOMUX_PAD(0x5DC, 0x240, 0, 0x0, 0, NO_PAD_CTRL) | ||
844 | #define MX50_PAD_EPDC_BDR1__GPIO_4_24 IOMUX_PAD(0x5DC, 0x240, 1, 0x0, 0, NO_PAD_CTRL) | ||
845 | #define MX50_PAD_EPDC_BDR1__ELCDIF_D6 IOMUX_PAD(0x5DC, 0x240, 3, 0x714, 1, MX50_ELCDIF_PAD_CTRL) | ||
846 | |||
847 | #define MX50_PAD_EPDC_SDCE0__EPDC_SDCE0 IOMUX_PAD(0x5E0, 0x244, 0, 0x0, 0, NO_PAD_CTRL) | ||
848 | #define MX50_PAD_EPDC_SDCE0__GPIO_4_25 IOMUX_PAD(0x5E0, 0x244, 1, 0x0, 0, NO_PAD_CTRL) | ||
849 | #define MX50_PAD_EPDC_SDCE0__ELCDIF_D5 IOMUX_PAD(0x5E0, 0x244, 3, 0x710, 1, MX50_ELCDIF_PAD_CTRL) | ||
850 | |||
851 | #define MX50_PAD_EPDC_SDCE1__EPDC_SDCE1 IOMUX_PAD(0x5E4, 0x248, 0, 0x0, 0, NO_PAD_CTRL) | ||
852 | #define MX50_PAD_EPDC_SDCE1__GPIO_4_26 IOMUX_PAD(0x5E4, 0x248, 1, 0x0, 0, NO_PAD_CTRL) | ||
853 | #define MX50_PAD_EPDC_SDCE1__ELCDIF_D4 IOMUX_PAD(0x5E4, 0x248, 2, 0x70c, 1, MX50_ELCDIF_PAD_CTRL) | ||
854 | |||
855 | #define MX50_PAD_EPDC_SDCE2__EPDC_SDCE2 IOMUX_PAD(0x5E8, 0x24C, 0, 0x0, 0, NO_PAD_CTRL) | ||
856 | #define MX50_PAD_EPDC_SDCE2__GPIO_4_27 IOMUX_PAD(0x5E8, 0x24C, 1, 0x0, 0, NO_PAD_CTRL) | ||
857 | #define MX50_PAD_EPDC_SDCE2__ELCDIF_DAT3 IOMUX_PAD(0x5E8, 0x24C, 3, 0x708, 1, MX50_ELCDIF_PAD_CTRL) | ||
858 | |||
859 | #define MX50_PAD_EPDC_SDCE3__EPDC_SDCE3 IOMUX_PAD(0x5EC, 0x250, 0, 0x0, 0, NO_PAD_CTRL) | ||
860 | #define MX50_PAD_EPDC_SDCE3__GPIO_4_28 IOMUX_PAD(0x5EC, 0x250, 1, 0x0, 0, NO_PAD_CTRL) | ||
861 | #define MX50_PAD_EPDC_SDCE3__ELCDIF_D2 IOMUX_PAD(0x5EC, 0x250, 3, 0x704, 1, MX50_ELCDIF_PAD_CTRL) | ||
862 | |||
863 | #define MX50_PAD_EPDC_SDCE4__EPDC_SDCE4 IOMUX_PAD(0x5F0, 0x254, 0, 0x0, 0, NO_PAD_CTRL) | ||
864 | #define MX50_PAD_EPDC_SDCE4__GPIO_4_29 IOMUX_PAD(0x5F0, 0x254, 1, 0x0, 0, NO_PAD_CTRL) | ||
865 | #define MX50_PAD_EPDC_SDCE4__ELCDIF_D1 IOMUX_PAD(0x5F0, 0x254, 3, 0x700, 1, MX50_ELCDIF_PAD_CTRL) | ||
866 | |||
867 | #define MX50_PAD_EPDC_SDCE5__EPDC_SDCE5 IOMUX_PAD(0x5F4, 0x258, 0, 0x0, 0, NO_PAD_CTRL) | ||
868 | #define MX50_PAD_EPDC_SDCE5__GPIO_4_30 IOMUX_PAD(0x5F4, 0x258, 1, 0x0, 0, NO_PAD_CTRL) | ||
869 | #define MX50_PAD_EPDC_SDCE5__ELCDIF_D0 IOMUX_PAD(0x5F4, 0x258, 3, 0x6fc, 1, MX50_ELCDIF_PAD_CTRL) | ||
870 | |||
871 | #define MX50_PAD_EIM_DA0__WEIM_A0 IOMUX_PAD(0x5F8, 0x25C, 0, 0x0, 0, NO_PAD_CTRL) | ||
872 | #define MX50_PAD_EIM_DA0__GPIO_1_0 IOMUX_PAD(0x5F8, 0x25C, 1, 0x0, 0, NO_PAD_CTRL) | ||
873 | #define MX50_PAD_EIM_DA0__KEY_COL4 IOMUX_PAD(0x5f8, 0x25C, 3, 0x790, 2, NO_PAD_CTRL) | ||
874 | |||
875 | #define MX50_PAD_EIM_DA1__WEIM_A1 IOMUX_PAD(0x5FC, 0x260, 0, 0x0, 0, NO_PAD_CTRL) | ||
876 | #define MX50_PAD_EIM_DA1__GPIO_1_1 IOMUX_PAD(0x5FC, 0x260, 1, 0x0, 0, NO_PAD_CTRL) | ||
877 | #define MX50_PAD_EIM_DA1__KEY_ROW4 IOMUX_PAD(0x5fc, 0x260, 3, 0x7a0, 2, MX50_KEYPAD_CTRL) | ||
878 | |||
879 | #define MX50_PAD_EIM_DA2__WEIM_A2 IOMUX_PAD(0x600, 0x264, 0, 0x0, 0, NO_PAD_CTRL) | ||
880 | #define MX50_PAD_EIM_DA2__GPIO_1_2 IOMUX_PAD(0x600, 0x264, 1, 0x0, 0, NO_PAD_CTRL) | ||
881 | #define MX50_PAD_EIM_DA2__KEY_COL5 IOMUX_PAD(0x600, 0x264, 3, 0x794, 2, NO_PAD_CTRL) | ||
882 | |||
883 | #define MX50_PAD_EIM_DA3__WEIM_A3 IOMUX_PAD(0x604, 0x268, 0, 0x0, 0, NO_PAD_CTRL) | ||
884 | #define MX50_PAD_EIM_DA3__GPIO_1_3 IOMUX_PAD(0x604, 0x268, 1, 0x0, 0, NO_PAD_CTRL) | ||
885 | #define MX50_PAD_EIM_DA3__KEY_ROW5 IOMUX_PAD(0x604, 0x268, 3, 0x7a4, 2, MX50_KEYPAD_CTRL) | ||
886 | |||
887 | #define MX50_PAD_EIM_DA4__WEIM_A4 IOMUX_PAD(0x608, 0x26C, 0, 0x0, 0, NO_PAD_CTRL) | ||
888 | #define MX50_PAD_EIM_DA4__GPIO_1_4 IOMUX_PAD(0x608, 0x26C, 1, 0x0, 0, NO_PAD_CTRL) | ||
889 | #define MX50_PAD_EIM_DA4__KEY_COL6 IOMUX_PAD(0x608, 0x26C, 3, 0x798, 2, NO_PAD_CTRL) | ||
890 | |||
891 | #define MX50_PAD_EIM_DA5__WEIM_A5 IOMUX_PAD(0x60C, 0x270, 0, 0x0, 0, NO_PAD_CTRL) | ||
892 | #define MX50_PAD_EIM_DA5__GPIO_1_5 IOMUX_PAD(0x60C, 0x270, 1, 0x0, 0, NO_PAD_CTRL) | ||
893 | #define MX50_PAD_EIM_DA5__KEY_ROW6 IOMUX_PAD(0x60C, 0x270, 3, 0x7a8, 2, MX50_KEYPAD_CTRL) | ||
894 | |||
895 | #define MX50_PAD_EIM_DA6__WEIM_A6 IOMUX_PAD(0x610, 0x274, 0, 0x0, 0, NO_PAD_CTRL) | ||
896 | #define MX50_PAD_EIM_DA6__GPIO_1_6 IOMUX_PAD(0x610, 0x274, 1, 0x0, 0, NO_PAD_CTRL) | ||
897 | #define MX50_PAD_EIM_DA6__KEY_COL7 IOMUX_PAD(0x610, 0x274, 3, 0x79c, 2, NO_PAD_CTRL) | ||
898 | |||
899 | #define MX50_PAD_EIM_DA7__WEIM_A7 IOMUX_PAD(0x614, 0x278, 0, 0x0, 0, NO_PAD_CTRL) | ||
900 | #define MX50_PAD_EIM_DA7__GPIO_1_7 IOMUX_PAD(0x614, 0x278, 1, 0x0, 0, NO_PAD_CTRL) | ||
901 | #define MX50_PAD_EIM_DA7__KEY_ROW7 IOMUX_PAD(0x614, 0x278, 3, 0x7ac, 2, MX50_KEYPAD_CTRL) | ||
902 | |||
903 | #define MX50_PAD_EIM_DA8__WEIM_A8 IOMUX_PAD(0x618, 0x27C, 0, 0x0, 0, NO_PAD_CTRL) | ||
904 | #define MX50_PAD_EIM_DA8__GPIO_1_8 IOMUX_PAD(0x618, 0x27C, 1, 0x0, 0, NO_PAD_CTRL) | ||
905 | #define MX50_PIN_EIM_DA8__NANDF_CLE IOMUX_PAD(0x618, 0x27C, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
906 | |||
907 | #define MX50_PAD_EIM_DA9__WEIM_A9 IOMUX_PAD(0x61C, 0x280, 0, 0x0, 0, NO_PAD_CTRL) | ||
908 | #define MX50_PAD_EIM_DA9__GPIO_1_9 IOMUX_PAD(0x61C, 0x280, 1, 0x0, 0, NO_PAD_CTRL) | ||
909 | #define MX50_PIN_EIM_DA9__NANDF_ALE IOMUX_PAD(0x61C, 0x280, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
910 | |||
911 | #define MX50_PAD_EIM_DA10__WEIM_A10 IOMUX_PAD(0x620, 0x284, 0, 0x0, 0, NO_PAD_CTRL) | ||
912 | #define MX50_PAD_EIM_DA10__GPIO_1_10 IOMUX_PAD(0x620, 0x284, 1, 0x0, 0, NO_PAD_CTRL) | ||
913 | #define MX50_PIN_EIM_DA10__NANDF_CE0 IOMUX_PAD(0x620, 0x284, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
914 | |||
915 | #define MX50_PAD_EIM_DA11__WEIM_A11 IOMUX_PAD(0x624, 0x288, 0, 0x0, 0, NO_PAD_CTRL) | ||
916 | #define MX50_PAD_EIM_DA11__GPIO_1_11 IOMUX_PAD(0x624, 0x288, 1, 0x0, 0, NO_PAD_CTRL) | ||
917 | #define MX50_PIN_EIM_DA11__NANDF_CE1 IOMUX_PAD(0x624, 0x288, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
918 | |||
919 | #define MX50_PAD_EIM_DA12__WEIM_A12 IOMUX_PAD(0x628, 0x28C, 0, 0x0, 0, NO_PAD_CTRL) | ||
920 | #define MX50_PAD_EIM_DA12__GPIO_1_12 IOMUX_PAD(0x628, 0x28C, 1, 0x0, 0, NO_PAD_CTRL) | ||
921 | #define MX50_PIN_EIM_DA12__NANDF_CE2 IOMUX_PAD(0x628, 0x28C, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
922 | #define MX50_PAD_EIM_DA12__EPDC_SDCE6 IOMUX_PAD(0x628, 0x28C, 3, 0x0, 0, NO_PAD_CTRL) | ||
923 | |||
924 | #define MX50_PAD_EIM_DA13__WEIM_A13 IOMUX_PAD(0x62C, 0x290, 0, 0x0, 0, NO_PAD_CTRL) | ||
925 | #define MX50_PAD_EIM_DA13__GPIO_1_13 IOMUX_PAD(0x62C, 0x290, 1, 0x0, 0, NO_PAD_CTRL) | ||
926 | #define MX50_PIN_EIM_DA13__NANDF_CE3 IOMUX_PAD(0x62C, 0x290, 2, 0x0, 0, PAD_CTL_DSE_HIGH) | ||
927 | #define MX50_PIN_EIM_DA13__EPDC_SDCE7 IOMUX_PAD(0x62C, 0x290, 3, 0x0, 0, NO_PAD_CTRL) | ||
928 | |||
929 | #define MX50_PAD_EIM_DA14__WEIM_A14 IOMUX_PAD(0x630, 0x294, 0, 0x0, 0, NO_PAD_CTRL) | ||
930 | #define MX50_PAD_EIM_DA14__GPIO_1_14 IOMUX_PAD(0x630, 0x294, 1, 0x0, 0, NO_PAD_CTRL) | ||
931 | #define MX50_PAD_EIM_DA14__NANDF_READY IOMUX_PAD(0x630, 0x294, 2, 0x7B4, 2, PAD_CTL_PKE | \ | ||
932 | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP) | ||
933 | #define MX50_PAD_EIM_DA14__EPDC_SDCE8 IOMUX_PAD(0x630, 0x294, 3, 0x0, 0, NO_PAD_CTRL) | ||
934 | |||
935 | #define MX50_PAD_EIM_DA15__WEIM_A15 IOMUX_PAD(0x634, 0x298, 0, 0x0, 0, NO_PAD_CTRL) | ||
936 | #define MX50_PAD_EIM_DA15__GPIO_1_15 IOMUX_PAD(0x634, 0x298, 1, 0x0, 0, NO_PAD_CTRL) | ||
937 | #define MX50_PIN_EIM_DA15__NANDF_DQS IOMUX_PAD(0x634, 0x298, 2, 0x7B0, 2, PAD_CTL_DSE_HIGH) | ||
938 | #define MX50_PAD_EIM_DA15__EPDC_SDCE9 IOMUX_PAD(0x634, 0x298, 3, 0x0, 0, NO_PAD_CTRL) | ||
939 | |||
940 | #define MX50_PAD_EIM_CS2__WEIM_CS2 IOMUX_PAD(0x638, 0x29C, 0, 0x0, 0, NO_PAD_CTRL) | ||
941 | #define MX50_PAD_EIM_CS2__GPIO_1_16 IOMUX_PAD(0x638, 0x29C, 1, 0x0, 0, NO_PAD_CTRL) | ||
942 | #define MX50_PAD_EIM_CS2__WEIM_A27 IOMUX_PAD(0x638, 0x29C, 2, 0x0, 0, NO_PAD_CTRL) | ||
943 | |||
944 | #define MX50_PAD_EIM_CS1__WEIM_CS1 IOMUX_PAD(0x63C, 0x2A0, 0, 0x0, 0, NO_PAD_CTRL) | ||
945 | #define MX50_PAD_EIM_CS1__GPIO_1_17 IOMUX_PAD(0x63C, 0x2A0, 1, 0x0, 0, NO_PAD_CTRL) | ||
946 | |||
947 | #define MX50_PAD_EIM_CS0__WEIM_CS0 IOMUX_PAD(0x640, 0x2A4, 0, 0x0, 0, NO_PAD_CTRL) | ||
948 | #define MX50_PAD_EIM_CS0__GPIO_1_18 IOMUX_PAD(0x640, 0x2A4, 1, 0x0, 0, NO_PAD_CTRL) | ||
949 | |||
950 | #define MX50_PAD_EIM_EB0__WEIM_EB0 IOMUX_PAD(0x644, 0x2A8, 0, 0x0, 0, NO_PAD_CTRL) | ||
951 | #define MX50_PAD_EIM_EB0__GPIO_1_19 IOMUX_PAD(0x644, 0x2A8, 1, 0x0, 0, NO_PAD_CTRL) | ||
952 | |||
953 | #define MX50_PAD_EIM_EB1__WEIM_EB1 IOMUX_PAD(0x648, 0x2AC, 0, 0x0, 0, NO_PAD_CTRL) | ||
954 | #define MX50_PAD_EIM_EB1__GPIO_1_20 IOMUX_PAD(0x648, 0x2AC, 1, 0x0, 0, NO_PAD_CTRL) | ||
955 | |||
956 | #define MX50_PAD_EIM_WAIT__WEIM_WAIT IOMUX_PAD(0x64C, 0x2B0, 0, 0x0, 0, NO_PAD_CTRL) | ||
957 | #define MX50_PAD_EIM_WAIT__GPIO_1_21 IOMUX_PAD(0x64C, 0x2B0, 1, 0x0, 0, NO_PAD_CTRL) | ||
958 | |||
959 | #define MX50_PAD_EIM_BCLK__WEIM_BCLK IOMUX_PAD(0x650, 0x2B4, 0, 0x0, 0, NO_PAD_CTRL) | ||
960 | #define MX50_PAD_EIM_BCLK__GPIO_1_22 IOMUX_PAD(0x650, 0x2B4, 1, 0x0, 0, NO_PAD_CTRL) | ||
961 | |||
962 | #define MX50_PAD_EIM_RDY__WEIM_RDY IOMUX_PAD(0x654, 0x2B8, 0, 0x0, 0, NO_PAD_CTRL) | ||
963 | #define MX50_PAD_EIM_RDY__GPIO_1_23 IOMUX_PAD(0x654, 0x2B8, 1, 0x0, 0, NO_PAD_CTRL) | ||
964 | |||
965 | #define MX50_PAD_EIM_OE__WEIM_OE IOMUX_PAD(0x658, 0x2BC, 0, 0x0, 0, NO_PAD_CTRL) | ||
966 | #define MX50_PAD_EIM_OE__GPIO_1_24 IOMUX_PAD(0x658, 0x2BC, 1, 0x0, 0, NO_PAD_CTRL) | ||
967 | |||
968 | #define MX50_PAD_EIM_RW__WEIM_RW IOMUX_PAD(0x65C, 0x2C0, 0, 0x0, 0, NO_PAD_CTRL) | ||
969 | #define MX50_PAD_EIM_RW__GPIO_1_25 IOMUX_PAD(0x65C, 0x2C0, 1, 0x0, 0, NO_PAD_CTRL) | ||
970 | |||
971 | #define MX50_PAD_EIM_LBA__WEIM_LBA IOMUX_PAD(0x660, 0x2C4, 0, 0x0, 0, NO_PAD_CTRL) | ||
972 | #define MX50_PAD_EIM_LBA__GPIO_1_26 IOMUX_PAD(0x660, 0x2C4, 1, 0x0, 0, NO_PAD_CTRL) | ||
973 | |||
974 | #define MX50_PAD_EIM_CRE__WEIM_CRE IOMUX_PAD(0x664, 0x2C8, 0, 0x0, 0, NO_PAD_CTRL) | ||
975 | #define MX50_PAD_EIM_CRE__GPIO_1_27 IOMUX_PAD(0x664, 0x2C8, 1, 0x0, 0, NO_PAD_CTRL) | ||
976 | |||
977 | #endif /* __MACH_IOMUX_MX50_H__ */ | ||
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c deleted file mode 100644 index 2fdc9bf2fb5e..000000000000 --- a/arch/arm/mach-imx/lluart.c +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Freescale Semiconductor, Inc. | ||
3 | * Copyright 2011 Linaro Ltd. | ||
4 | * | ||
5 | * The code contained herein is licensed under the GNU General Public | ||
6 | * License. You may obtain a copy of the GNU General Public License | ||
7 | * Version 2 or later at the following locations: | ||
8 | * | ||
9 | * http://www.opensource.org/licenses/gpl-license.html | ||
10 | * http://www.gnu.org/copyleft/gpl.html | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/sizes.h> | ||
16 | #include <asm/mach/map.h> | ||
17 | |||
18 | #include "hardware.h" | ||
19 | |||
20 | #define IMX6Q_UART1_BASE_ADDR 0x02020000 | ||
21 | #define IMX6Q_UART2_BASE_ADDR 0x021e8000 | ||
22 | #define IMX6Q_UART3_BASE_ADDR 0x021ec000 | ||
23 | #define IMX6Q_UART4_BASE_ADDR 0x021f0000 | ||
24 | #define IMX6Q_UART5_BASE_ADDR 0x021f4000 | ||
25 | |||
26 | /* | ||
27 | * IMX6Q_UART_BASE_ADDR is put in the middle to force the expansion | ||
28 | * of IMX6Q_UART##n##_BASE_ADDR. | ||
29 | */ | ||
30 | #define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR | ||
31 | #define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n) | ||
32 | #define IMX6Q_DEBUG_UART_BASE IMX6Q_UART_BASE(CONFIG_DEBUG_IMX6Q_UART_PORT) | ||
33 | |||
34 | static struct map_desc imx_lluart_desc = { | ||
35 | #ifdef CONFIG_DEBUG_IMX6Q_UART | ||
36 | .virtual = IMX_IO_P2V(IMX6Q_DEBUG_UART_BASE), | ||
37 | .pfn = __phys_to_pfn(IMX6Q_DEBUG_UART_BASE), | ||
38 | .length = 0x4000, | ||
39 | .type = MT_DEVICE, | ||
40 | #endif | ||
41 | }; | ||
42 | |||
43 | void __init imx_lluart_map_io(void) | ||
44 | { | ||
45 | if (imx_lluart_desc.virtual) | ||
46 | iotable_init(&imx_lluart_desc, 1); | ||
47 | } | ||
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 8d3d06e0e8a1..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,10 +26,10 @@ | |||
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> |
32 | #include <asm/mach/map.h> | ||
34 | #include <asm/mach/time.h> | 33 | #include <asm/mach/time.h> |
35 | #include <asm/system_misc.h> | 34 | #include <asm/system_misc.h> |
36 | 35 | ||
@@ -201,24 +200,20 @@ static void __init imx6q_init_machine(void) | |||
201 | imx6q_1588_init(); | 200 | imx6q_1588_init(); |
202 | } | 201 | } |
203 | 202 | ||
204 | static struct cpuidle_driver imx6q_cpuidle_driver = { | ||
205 | .name = "imx6q_cpuidle", | ||
206 | .owner = THIS_MODULE, | ||
207 | .en_core_tk_irqen = 1, | ||
208 | .states[0] = ARM_CPUIDLE_WFI_STATE, | ||
209 | .state_count = 1, | ||
210 | }; | ||
211 | |||
212 | static void __init imx6q_init_late(void) | 203 | static void __init imx6q_init_late(void) |
213 | { | 204 | { |
214 | 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(); | ||
215 | } | 211 | } |
216 | 212 | ||
217 | static void __init imx6q_map_io(void) | 213 | static void __init imx6q_map_io(void) |
218 | { | 214 | { |
219 | imx_lluart_map_io(); | 215 | debug_ll_io_init(); |
220 | imx_scu_map_io(); | 216 | imx_scu_map_io(); |
221 | imx6q_clock_map_io(); | ||
222 | } | 217 | } |
223 | 218 | ||
224 | static void __init imx6q_init_irq(void) | 219 | static void __init imx6q_init_irq(void) |
diff --git a/arch/arm/mach-imx/mach-mx50_rdp.c b/arch/arm/mach-imx/mach-mx50_rdp.c deleted file mode 100644 index 8937902bda5f..000000000000 --- a/arch/arm/mach-imx/mach-mx50_rdp.c +++ /dev/null | |||
@@ -1,221 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | |||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/init.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/io.h> | ||
26 | |||
27 | #include <asm/irq.h> | ||
28 | #include <asm/setup.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/mach/arch.h> | ||
31 | #include <asm/mach/time.h> | ||
32 | |||
33 | #include "common.h" | ||
34 | #include "devices-imx50.h" | ||
35 | #include "hardware.h" | ||
36 | #include "iomux-mx50.h" | ||
37 | |||
38 | #define FEC_EN IMX_GPIO_NR(6, 23) | ||
39 | #define FEC_RESET_B IMX_GPIO_NR(4, 12) | ||
40 | |||
41 | static iomux_v3_cfg_t mx50_rdp_pads[] __initdata = { | ||
42 | /* SD1 */ | ||
43 | MX50_PAD_ECSPI2_SS0__GPIO_4_19, | ||
44 | MX50_PAD_EIM_CRE__GPIO_1_27, | ||
45 | MX50_PAD_SD1_CMD__SD1_CMD, | ||
46 | |||
47 | MX50_PAD_SD1_CLK__SD1_CLK, | ||
48 | MX50_PAD_SD1_D0__SD1_D0, | ||
49 | MX50_PAD_SD1_D1__SD1_D1, | ||
50 | MX50_PAD_SD1_D2__SD1_D2, | ||
51 | MX50_PAD_SD1_D3__SD1_D3, | ||
52 | |||
53 | /* SD2 */ | ||
54 | MX50_PAD_SD2_CD__GPIO_5_17, | ||
55 | MX50_PAD_SD2_WP__GPIO_5_16, | ||
56 | MX50_PAD_SD2_CMD__SD2_CMD, | ||
57 | MX50_PAD_SD2_CLK__SD2_CLK, | ||
58 | MX50_PAD_SD2_D0__SD2_D0, | ||
59 | MX50_PAD_SD2_D1__SD2_D1, | ||
60 | MX50_PAD_SD2_D2__SD2_D2, | ||
61 | MX50_PAD_SD2_D3__SD2_D3, | ||
62 | MX50_PAD_SD2_D4__SD2_D4, | ||
63 | MX50_PAD_SD2_D5__SD2_D5, | ||
64 | MX50_PAD_SD2_D6__SD2_D6, | ||
65 | MX50_PAD_SD2_D7__SD2_D7, | ||
66 | |||
67 | /* SD3 */ | ||
68 | MX50_PAD_SD3_CMD__SD3_CMD, | ||
69 | MX50_PAD_SD3_CLK__SD3_CLK, | ||
70 | MX50_PAD_SD3_D0__SD3_D0, | ||
71 | MX50_PAD_SD3_D1__SD3_D1, | ||
72 | MX50_PAD_SD3_D2__SD3_D2, | ||
73 | MX50_PAD_SD3_D3__SD3_D3, | ||
74 | MX50_PAD_SD3_D4__SD3_D4, | ||
75 | MX50_PAD_SD3_D5__SD3_D5, | ||
76 | MX50_PAD_SD3_D6__SD3_D6, | ||
77 | MX50_PAD_SD3_D7__SD3_D7, | ||
78 | |||
79 | /* PWR_INT */ | ||
80 | MX50_PAD_ECSPI2_MISO__GPIO_4_18, | ||
81 | |||
82 | /* UART pad setting */ | ||
83 | MX50_PAD_UART1_TXD__UART1_TXD, | ||
84 | MX50_PAD_UART1_RXD__UART1_RXD, | ||
85 | MX50_PAD_UART1_RTS__UART1_RTS, | ||
86 | MX50_PAD_UART2_TXD__UART2_TXD, | ||
87 | MX50_PAD_UART2_RXD__UART2_RXD, | ||
88 | MX50_PAD_UART2_CTS__UART2_CTS, | ||
89 | MX50_PAD_UART2_RTS__UART2_RTS, | ||
90 | |||
91 | MX50_PAD_I2C1_SCL__I2C1_SCL, | ||
92 | MX50_PAD_I2C1_SDA__I2C1_SDA, | ||
93 | MX50_PAD_I2C2_SCL__I2C2_SCL, | ||
94 | MX50_PAD_I2C2_SDA__I2C2_SDA, | ||
95 | |||
96 | MX50_PAD_EPITO__USBH1_PWR, | ||
97 | /* Need to comment below line if | ||
98 | * one needs to debug owire. | ||
99 | */ | ||
100 | MX50_PAD_OWIRE__USBH1_OC, | ||
101 | /* using gpio to control otg pwr */ | ||
102 | MX50_PAD_PWM2__GPIO_6_25, | ||
103 | MX50_PAD_I2C3_SCL__USBOTG_OC, | ||
104 | |||
105 | MX50_PAD_SSI_RXC__FEC_MDIO, | ||
106 | MX50_PAD_SSI_RXFS__FEC_MDC, | ||
107 | MX50_PAD_DISP_D0__FEC_TXCLK, | ||
108 | MX50_PAD_DISP_D1__FEC_RX_ER, | ||
109 | MX50_PAD_DISP_D2__FEC_RX_DV, | ||
110 | MX50_PAD_DISP_D3__FEC_RXD1, | ||
111 | MX50_PAD_DISP_D4__FEC_RXD0, | ||
112 | MX50_PAD_DISP_D5__FEC_TX_EN, | ||
113 | MX50_PAD_DISP_D6__FEC_TXD1, | ||
114 | MX50_PAD_DISP_D7__FEC_TXD0, | ||
115 | MX50_PAD_I2C3_SDA__GPIO_6_23, | ||
116 | MX50_PAD_ECSPI1_SCLK__GPIO_4_12, | ||
117 | |||
118 | MX50_PAD_CSPI_SS0__CSPI_SS0, | ||
119 | MX50_PAD_ECSPI1_MOSI__CSPI_SS1, | ||
120 | MX50_PAD_CSPI_MOSI__CSPI_MOSI, | ||
121 | MX50_PAD_CSPI_MISO__CSPI_MISO, | ||
122 | |||
123 | /* SGTL500_OSC_EN */ | ||
124 | MX50_PAD_UART1_CTS__GPIO_6_8, | ||
125 | |||
126 | /* SGTL_AMP_SHDN */ | ||
127 | MX50_PAD_UART3_RXD__GPIO_6_15, | ||
128 | |||
129 | /* Keypad */ | ||
130 | MX50_PAD_KEY_COL0__KEY_COL0, | ||
131 | MX50_PAD_KEY_ROW0__KEY_ROW0, | ||
132 | MX50_PAD_KEY_COL1__KEY_COL1, | ||
133 | MX50_PAD_KEY_ROW1__KEY_ROW1, | ||
134 | MX50_PAD_KEY_COL2__KEY_COL2, | ||
135 | MX50_PAD_KEY_ROW2__KEY_ROW2, | ||
136 | MX50_PAD_KEY_COL3__KEY_COL3, | ||
137 | MX50_PAD_KEY_ROW3__KEY_ROW3, | ||
138 | MX50_PAD_EIM_DA0__KEY_COL4, | ||
139 | MX50_PAD_EIM_DA1__KEY_ROW4, | ||
140 | MX50_PAD_EIM_DA2__KEY_COL5, | ||
141 | MX50_PAD_EIM_DA3__KEY_ROW5, | ||
142 | MX50_PAD_EIM_DA4__KEY_COL6, | ||
143 | MX50_PAD_EIM_DA5__KEY_ROW6, | ||
144 | MX50_PAD_EIM_DA6__KEY_COL7, | ||
145 | MX50_PAD_EIM_DA7__KEY_ROW7, | ||
146 | /*EIM pads */ | ||
147 | MX50_PAD_EIM_DA8__GPIO_1_8, | ||
148 | MX50_PAD_EIM_DA9__GPIO_1_9, | ||
149 | MX50_PAD_EIM_DA10__GPIO_1_10, | ||
150 | MX50_PAD_EIM_DA11__GPIO_1_11, | ||
151 | MX50_PAD_EIM_DA12__GPIO_1_12, | ||
152 | MX50_PAD_EIM_DA13__GPIO_1_13, | ||
153 | MX50_PAD_EIM_DA14__GPIO_1_14, | ||
154 | MX50_PAD_EIM_DA15__GPIO_1_15, | ||
155 | MX50_PAD_EIM_CS2__GPIO_1_16, | ||
156 | MX50_PAD_EIM_CS1__GPIO_1_17, | ||
157 | MX50_PAD_EIM_CS0__GPIO_1_18, | ||
158 | MX50_PAD_EIM_EB0__GPIO_1_19, | ||
159 | MX50_PAD_EIM_EB1__GPIO_1_20, | ||
160 | MX50_PAD_EIM_WAIT__GPIO_1_21, | ||
161 | MX50_PAD_EIM_BCLK__GPIO_1_22, | ||
162 | MX50_PAD_EIM_RDY__GPIO_1_23, | ||
163 | MX50_PAD_EIM_OE__GPIO_1_24, | ||
164 | }; | ||
165 | |||
166 | /* Serial ports */ | ||
167 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
168 | .flags = IMXUART_HAVE_RTSCTS, | ||
169 | }; | ||
170 | |||
171 | static const struct fec_platform_data fec_data __initconst = { | ||
172 | .phy = PHY_INTERFACE_MODE_RMII, | ||
173 | }; | ||
174 | |||
175 | static inline void mx50_rdp_fec_reset(void) | ||
176 | { | ||
177 | gpio_request(FEC_EN, "fec-en"); | ||
178 | gpio_direction_output(FEC_EN, 0); | ||
179 | gpio_request(FEC_RESET_B, "fec-reset_b"); | ||
180 | gpio_direction_output(FEC_RESET_B, 0); | ||
181 | msleep(1); | ||
182 | gpio_set_value(FEC_RESET_B, 1); | ||
183 | } | ||
184 | |||
185 | static const struct imxi2c_platform_data i2c_data __initconst = { | ||
186 | .bitrate = 100000, | ||
187 | }; | ||
188 | |||
189 | /* | ||
190 | * Board specific initialization. | ||
191 | */ | ||
192 | static void __init mx50_rdp_board_init(void) | ||
193 | { | ||
194 | imx50_soc_init(); | ||
195 | |||
196 | mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads, | ||
197 | ARRAY_SIZE(mx50_rdp_pads)); | ||
198 | |||
199 | imx50_add_imx_uart(0, &uart_pdata); | ||
200 | imx50_add_imx_uart(1, &uart_pdata); | ||
201 | mx50_rdp_fec_reset(); | ||
202 | imx50_add_fec(&fec_data); | ||
203 | imx50_add_imx_i2c(0, &i2c_data); | ||
204 | imx50_add_imx_i2c(1, &i2c_data); | ||
205 | imx50_add_imx_i2c(2, &i2c_data); | ||
206 | } | ||
207 | |||
208 | static void __init mx50_rdp_timer_init(void) | ||
209 | { | ||
210 | mx50_clocks_init(32768, 24000000, 22579200); | ||
211 | } | ||
212 | |||
213 | MACHINE_START(MX50_RDP, "Freescale MX50 Reference Design Platform") | ||
214 | .map_io = mx50_map_io, | ||
215 | .init_early = imx50_init_early, | ||
216 | .init_irq = mx50_init_irq, | ||
217 | .handle_irq = imx50_handle_irq, | ||
218 | .init_time = mx50_rdp_timer_init, | ||
219 | .init_machine = mx50_rdp_board_init, | ||
220 | .restart = mxc_restart, | ||
221 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mach-mx51_3ds.c b/arch/arm/mach-imx/mach-mx51_3ds.c deleted file mode 100644 index 2d2365111532..000000000000 --- a/arch/arm/mach-imx/mach-mx51_3ds.c +++ /dev/null | |||
@@ -1,174 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com> | ||
4 | * | ||
5 | * The code contained herein is licensed under the GNU General Public | ||
6 | * License. You may obtain a copy of the GNU General Public License | ||
7 | * Version 2 or later at the following locations: | ||
8 | * | ||
9 | * http://www.opensource.org/licenses/gpl-license.html | ||
10 | * http://www.gnu.org/copyleft/gpl.html | ||
11 | */ | ||
12 | |||
13 | #include <linux/irq.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | #include <linux/gpio.h> | ||
17 | |||
18 | #include <asm/mach-types.h> | ||
19 | #include <asm/mach/arch.h> | ||
20 | #include <asm/mach/time.h> | ||
21 | |||
22 | #include "3ds_debugboard.h" | ||
23 | #include "common.h" | ||
24 | #include "devices-imx51.h" | ||
25 | #include "hardware.h" | ||
26 | #include "iomux-mx51.h" | ||
27 | |||
28 | #define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28) | ||
29 | |||
30 | static iomux_v3_cfg_t mx51_3ds_pads[] = { | ||
31 | /* UART1 */ | ||
32 | MX51_PAD_UART1_RXD__UART1_RXD, | ||
33 | MX51_PAD_UART1_TXD__UART1_TXD, | ||
34 | MX51_PAD_UART1_RTS__UART1_RTS, | ||
35 | MX51_PAD_UART1_CTS__UART1_CTS, | ||
36 | |||
37 | /* UART2 */ | ||
38 | MX51_PAD_UART2_RXD__UART2_RXD, | ||
39 | MX51_PAD_UART2_TXD__UART2_TXD, | ||
40 | MX51_PAD_EIM_D25__UART2_CTS, | ||
41 | MX51_PAD_EIM_D26__UART2_RTS, | ||
42 | |||
43 | /* UART3 */ | ||
44 | MX51_PAD_UART3_RXD__UART3_RXD, | ||
45 | MX51_PAD_UART3_TXD__UART3_TXD, | ||
46 | MX51_PAD_EIM_D24__UART3_CTS, | ||
47 | MX51_PAD_EIM_D27__UART3_RTS, | ||
48 | |||
49 | /* CPLD PARENT IRQ PIN */ | ||
50 | MX51_PAD_GPIO1_6__GPIO1_6, | ||
51 | |||
52 | /* KPP */ | ||
53 | MX51_PAD_KEY_ROW0__KEY_ROW0, | ||
54 | MX51_PAD_KEY_ROW1__KEY_ROW1, | ||
55 | MX51_PAD_KEY_ROW2__KEY_ROW2, | ||
56 | MX51_PAD_KEY_ROW3__KEY_ROW3, | ||
57 | MX51_PAD_KEY_COL0__KEY_COL0, | ||
58 | MX51_PAD_KEY_COL1__KEY_COL1, | ||
59 | MX51_PAD_KEY_COL2__KEY_COL2, | ||
60 | MX51_PAD_KEY_COL3__KEY_COL3, | ||
61 | MX51_PAD_KEY_COL4__KEY_COL4, | ||
62 | MX51_PAD_KEY_COL5__KEY_COL5, | ||
63 | |||
64 | /* eCSPI2 */ | ||
65 | MX51_PAD_NANDF_RB2__ECSPI2_SCLK, | ||
66 | MX51_PAD_NANDF_RB3__ECSPI2_MISO, | ||
67 | MX51_PAD_NANDF_D15__ECSPI2_MOSI, | ||
68 | MX51_PAD_NANDF_D12__GPIO3_28, | ||
69 | }; | ||
70 | |||
71 | /* Serial ports */ | ||
72 | static const struct imxuart_platform_data uart_pdata __initconst = { | ||
73 | .flags = IMXUART_HAVE_RTSCTS, | ||
74 | }; | ||
75 | |||
76 | static int mx51_3ds_board_keymap[] = { | ||
77 | KEY(0, 0, KEY_1), | ||
78 | KEY(0, 1, KEY_2), | ||
79 | KEY(0, 2, KEY_3), | ||
80 | KEY(0, 3, KEY_F1), | ||
81 | KEY(0, 4, KEY_UP), | ||
82 | KEY(0, 5, KEY_F2), | ||
83 | |||
84 | KEY(1, 0, KEY_4), | ||
85 | KEY(1, 1, KEY_5), | ||
86 | KEY(1, 2, KEY_6), | ||
87 | KEY(1, 3, KEY_LEFT), | ||
88 | KEY(1, 4, KEY_SELECT), | ||
89 | KEY(1, 5, KEY_RIGHT), | ||
90 | |||
91 | KEY(2, 0, KEY_7), | ||
92 | KEY(2, 1, KEY_8), | ||
93 | KEY(2, 2, KEY_9), | ||
94 | KEY(2, 3, KEY_F3), | ||
95 | KEY(2, 4, KEY_DOWN), | ||
96 | KEY(2, 5, KEY_F4), | ||
97 | |||
98 | KEY(3, 0, KEY_0), | ||
99 | KEY(3, 1, KEY_OK), | ||
100 | KEY(3, 2, KEY_ESC), | ||
101 | KEY(3, 3, KEY_ENTER), | ||
102 | KEY(3, 4, KEY_MENU), | ||
103 | KEY(3, 5, KEY_BACK) | ||
104 | }; | ||
105 | |||
106 | static const struct matrix_keymap_data mx51_3ds_map_data __initconst = { | ||
107 | .keymap = mx51_3ds_board_keymap, | ||
108 | .keymap_size = ARRAY_SIZE(mx51_3ds_board_keymap), | ||
109 | }; | ||
110 | |||
111 | static int mx51_3ds_spi2_cs[] = { | ||
112 | MXC_SPI_CS(0), | ||
113 | MX51_3DS_ECSPI2_CS, | ||
114 | }; | ||
115 | |||
116 | static const struct spi_imx_master mx51_3ds_ecspi2_pdata __initconst = { | ||
117 | .chipselect = mx51_3ds_spi2_cs, | ||
118 | .num_chipselect = ARRAY_SIZE(mx51_3ds_spi2_cs), | ||
119 | }; | ||
120 | |||
121 | static struct spi_board_info mx51_3ds_spi_nor_device[] = { | ||
122 | { | ||
123 | .modalias = "m25p80", | ||
124 | .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ | ||
125 | .bus_num = 1, | ||
126 | .chip_select = 1, | ||
127 | .mode = SPI_MODE_0, | ||
128 | .platform_data = NULL,}, | ||
129 | }; | ||
130 | |||
131 | /* | ||
132 | * Board specific initialization. | ||
133 | */ | ||
134 | static void __init mx51_3ds_init(void) | ||
135 | { | ||
136 | imx51_soc_init(); | ||
137 | |||
138 | mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads, | ||
139 | ARRAY_SIZE(mx51_3ds_pads)); | ||
140 | |||
141 | imx51_add_imx_uart(0, &uart_pdata); | ||
142 | imx51_add_imx_uart(1, &uart_pdata); | ||
143 | imx51_add_imx_uart(2, &uart_pdata); | ||
144 | |||
145 | imx51_add_ecspi(1, &mx51_3ds_ecspi2_pdata); | ||
146 | spi_register_board_info(mx51_3ds_spi_nor_device, | ||
147 | ARRAY_SIZE(mx51_3ds_spi_nor_device)); | ||
148 | |||
149 | if (mxc_expio_init(MX51_CS5_BASE_ADDR, IMX_GPIO_NR(1, 6))) | ||
150 | printk(KERN_WARNING "Init of the debugboard failed, all " | ||
151 | "devices on the board are unusable.\n"); | ||
152 | |||
153 | imx51_add_sdhci_esdhc_imx(0, NULL); | ||
154 | imx51_add_imx_keypad(&mx51_3ds_map_data); | ||
155 | imx51_add_imx2_wdt(0); | ||
156 | } | ||
157 | |||
158 | static void __init mx51_3ds_timer_init(void) | ||
159 | { | ||
160 | mx51_clocks_init(32768, 24000000, 22579200, 0); | ||
161 | } | ||
162 | |||
163 | MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board") | ||
164 | /* Maintainer: Freescale Semiconductor, Inc. */ | ||
165 | .atag_offset = 0x100, | ||
166 | .map_io = mx51_map_io, | ||
167 | .init_early = imx51_init_early, | ||
168 | .init_irq = mx51_init_irq, | ||
169 | .handle_irq = imx51_handle_irq, | ||
170 | .init_time = mx51_3ds_timer_init, | ||
171 | .init_machine = mx51_3ds_init, | ||
172 | .init_late = imx51_init_late, | ||
173 | .restart = mxc_restart, | ||
174 | MACHINE_END | ||
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index 79d71cf23a1d..cf34994cfe28 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c | |||
@@ -24,16 +24,6 @@ | |||
24 | #include "iomux-v3.h" | 24 | #include "iomux-v3.h" |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Define the MX50 memory map. | ||
28 | */ | ||
29 | static struct map_desc mx50_io_desc[] __initdata = { | ||
30 | imx_map_entry(MX50, TZIC, MT_DEVICE), | ||
31 | imx_map_entry(MX50, SPBA0, MT_DEVICE), | ||
32 | imx_map_entry(MX50, AIPS1, MT_DEVICE), | ||
33 | imx_map_entry(MX50, AIPS2, MT_DEVICE), | ||
34 | }; | ||
35 | |||
36 | /* | ||
37 | * Define the MX51 memory map. | 27 | * Define the MX51 memory map. |
38 | */ | 28 | */ |
39 | static struct map_desc mx51_io_desc[] __initdata = { | 29 | static struct map_desc mx51_io_desc[] __initdata = { |
@@ -59,11 +49,6 @@ static struct map_desc mx53_io_desc[] __initdata = { | |||
59 | * system startup to create static physical to virtual memory mappings | 49 | * system startup to create static physical to virtual memory mappings |
60 | * for the IO modules. | 50 | * for the IO modules. |
61 | */ | 51 | */ |
62 | void __init mx50_map_io(void) | ||
63 | { | ||
64 | iotable_init(mx50_io_desc, ARRAY_SIZE(mx50_io_desc)); | ||
65 | } | ||
66 | |||
67 | void __init mx51_map_io(void) | 52 | void __init mx51_map_io(void) |
68 | { | 53 | { |
69 | iotable_init(mx51_io_desc, ARRAY_SIZE(mx51_io_desc)); | 54 | iotable_init(mx51_io_desc, ARRAY_SIZE(mx51_io_desc)); |
@@ -74,13 +59,6 @@ void __init mx53_map_io(void) | |||
74 | iotable_init(mx53_io_desc, ARRAY_SIZE(mx53_io_desc)); | 59 | iotable_init(mx53_io_desc, ARRAY_SIZE(mx53_io_desc)); |
75 | } | 60 | } |
76 | 61 | ||
77 | void __init imx50_init_early(void) | ||
78 | { | ||
79 | mxc_set_cpu_type(MXC_CPU_MX50); | ||
80 | mxc_iomux_v3_init(MX50_IO_ADDRESS(MX50_IOMUXC_BASE_ADDR)); | ||
81 | mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR)); | ||
82 | } | ||
83 | |||
84 | /* | 62 | /* |
85 | * The MIPI HSC unit has been removed from the i.MX51 Reference Manual by | 63 | * The MIPI HSC unit has been removed from the i.MX51 Reference Manual by |
86 | * the Freescale marketing division. However this did not remove the | 64 | * the Freescale marketing division. However this did not remove the |
@@ -115,11 +93,6 @@ void __init imx53_init_early(void) | |||
115 | mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR)); | 93 | mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR)); |
116 | } | 94 | } |
117 | 95 | ||
118 | void __init mx50_init_irq(void) | ||
119 | { | ||
120 | tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR)); | ||
121 | } | ||
122 | |||
123 | void __init mx51_init_irq(void) | 96 | void __init mx51_init_irq(void) |
124 | { | 97 | { |
125 | tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR)); | 98 | tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR)); |
@@ -148,31 +121,10 @@ static struct sdma_platform_data imx51_sdma_pdata __initdata = { | |||
148 | .script_addrs = &imx51_sdma_script, | 121 | .script_addrs = &imx51_sdma_script, |
149 | }; | 122 | }; |
150 | 123 | ||
151 | static const struct resource imx50_audmux_res[] __initconst = { | ||
152 | DEFINE_RES_MEM(MX50_AUDMUX_BASE_ADDR, SZ_16K), | ||
153 | }; | ||
154 | |||
155 | static const struct resource imx51_audmux_res[] __initconst = { | 124 | static const struct resource imx51_audmux_res[] __initconst = { |
156 | DEFINE_RES_MEM(MX51_AUDMUX_BASE_ADDR, SZ_16K), | 125 | DEFINE_RES_MEM(MX51_AUDMUX_BASE_ADDR, SZ_16K), |
157 | }; | 126 | }; |
158 | 127 | ||
159 | void __init imx50_soc_init(void) | ||
160 | { | ||
161 | mxc_device_init(); | ||
162 | |||
163 | /* i.mx50 has the i.mx35 type gpio */ | ||
164 | mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH); | ||
165 | mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH); | ||
166 | mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH); | ||
167 | mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH); | ||
168 | mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH); | ||
169 | mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH); | ||
170 | |||
171 | /* i.mx50 has the i.mx31 type audmux */ | ||
172 | platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res, | ||
173 | ARRAY_SIZE(imx50_audmux_res)); | ||
174 | } | ||
175 | |||
176 | void __init imx51_soc_init(void) | 128 | void __init imx51_soc_init(void) |
177 | { | 129 | { |
178 | mxc_device_init(); | 130 | mxc_device_init(); |
diff --git a/arch/arm/mach-imx/mx50.h b/arch/arm/mach-imx/mx50.h deleted file mode 100644 index 09ac19c1570c..000000000000 --- a/arch/arm/mach-imx/mx50.h +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | #ifndef __MACH_MX50_H__ | ||
2 | #define __MACH_MX50_H__ | ||
3 | |||
4 | /* | ||
5 | * IROM | ||
6 | */ | ||
7 | #define MX50_IROM_BASE_ADDR 0x0 | ||
8 | #define MX50_IROM_SIZE SZ_64K | ||
9 | |||
10 | /* TZIC */ | ||
11 | #define MX50_TZIC_BASE_ADDR 0x0fffc000 | ||
12 | #define MX50_TZIC_SIZE SZ_16K | ||
13 | |||
14 | /* | ||
15 | * IRAM | ||
16 | */ | ||
17 | #define MX50_IRAM_BASE_ADDR 0xf8000000 /* internal ram */ | ||
18 | #define MX50_IRAM_PARTITIONS 16 | ||
19 | #define MX50_IRAM_SIZE (MX50_IRAM_PARTITIONS * SZ_8K) /* 128KB */ | ||
20 | |||
21 | /* | ||
22 | * Databahn | ||
23 | */ | ||
24 | #define MX50_DATABAHN_BASE_ADDR 0x14000000 | ||
25 | |||
26 | /* | ||
27 | * Graphics Memory of GPU | ||
28 | */ | ||
29 | #define MX50_GPU2D_BASE_ADDR 0x20000000 | ||
30 | |||
31 | #define MX50_DEBUG_BASE_ADDR 0x40000000 | ||
32 | #define MX50_DEBUG_SIZE SZ_1M | ||
33 | #define MX50_ETB_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00001000) | ||
34 | #define MX50_ETM_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00002000) | ||
35 | #define MX50_TPIU_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00003000) | ||
36 | #define MX50_CTI0_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00004000) | ||
37 | #define MX50_CTI1_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00005000) | ||
38 | #define MX50_CTI2_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00006000) | ||
39 | #define MX50_CTI3_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00007000) | ||
40 | #define MX50_CORTEX_DBG_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00008000) | ||
41 | |||
42 | #define MX50_APBHDMA_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01000000) | ||
43 | #define MX50_OCOTP_CTRL_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01002000) | ||
44 | #define MX50_DIGCTL_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01004000) | ||
45 | #define MX50_GPMI_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01006000) | ||
46 | #define MX50_BCH_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01008000) | ||
47 | #define MX50_ELCDIF_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100a000) | ||
48 | #define MX50_EPXP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100c000) | ||
49 | #define MX50_DCP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100e000) | ||
50 | #define MX50_EPDC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01010000) | ||
51 | #define MX50_QOSC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01012000) | ||
52 | #define MX50_PERFMON_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01014000) | ||
53 | #define MX50_SSP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01016000) | ||
54 | #define MX50_ANATOP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01018000) | ||
55 | #define MX50_NIC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x08000000) | ||
56 | |||
57 | /* | ||
58 | * SPBA global module enabled #0 | ||
59 | */ | ||
60 | #define MX50_SPBA0_BASE_ADDR 0x50000000 | ||
61 | #define MX50_SPBA0_SIZE SZ_1M | ||
62 | |||
63 | #define MX50_MMC_SDHC1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00004000) | ||
64 | #define MX50_MMC_SDHC2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00008000) | ||
65 | #define MX50_UART3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x0000c000) | ||
66 | #define MX50_CSPI1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00010000) | ||
67 | #define MX50_SSI2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00014000) | ||
68 | #define MX50_MMC_SDHC3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00020000) | ||
69 | #define MX50_MMC_SDHC4_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00024000) | ||
70 | |||
71 | /* | ||
72 | * AIPS 1 | ||
73 | */ | ||
74 | #define MX50_AIPS1_BASE_ADDR 0x53f00000 | ||
75 | #define MX50_AIPS1_SIZE SZ_1M | ||
76 | |||
77 | #define MX50_OTG_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00080000) | ||
78 | #define MX50_GPIO1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00084000) | ||
79 | #define MX50_GPIO2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00088000) | ||
80 | #define MX50_GPIO3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x0008c000) | ||
81 | #define MX50_GPIO4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00090000) | ||
82 | #define MX50_KPP_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00094000) | ||
83 | #define MX50_WDOG_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00098000) | ||
84 | #define MX50_GPT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a0000) | ||
85 | #define MX50_SRTC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a4000) | ||
86 | #define MX50_IOMUXC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a8000) | ||
87 | #define MX50_EPIT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000ac000) | ||
88 | #define MX50_PWM1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000b4000) | ||
89 | #define MX50_PWM2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000b8000) | ||
90 | #define MX50_UART1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000bc000) | ||
91 | #define MX50_UART2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000c0000) | ||
92 | #define MX50_SRC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d0000) | ||
93 | #define MX50_CCM_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d4000) | ||
94 | #define MX50_GPC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d8000) | ||
95 | #define MX50_GPIO5_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000dc000) | ||
96 | #define MX50_GPIO6_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000e0000) | ||
97 | #define MX50_I2C3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000ec000) | ||
98 | #define MX50_UART4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f0000) | ||
99 | |||
100 | #define MX50_MSHC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f4000) | ||
101 | #define MX50_RNGB_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f8000) | ||
102 | |||
103 | /* | ||
104 | * AIPS 2 | ||
105 | */ | ||
106 | #define MX50_AIPS2_BASE_ADDR 0x63f00000 | ||
107 | #define MX50_AIPS2_SIZE SZ_1M | ||
108 | |||
109 | #define MX50_PLL1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00080000) | ||
110 | #define MX50_PLL2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00084000) | ||
111 | #define MX50_PLL3_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00088000) | ||
112 | #define MX50_UART5_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00090000) | ||
113 | #define MX50_AHBMAX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00094000) | ||
114 | #define MX50_ARM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000a0000) | ||
115 | #define MX50_OWIRE_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000a4000) | ||
116 | #define MX50_CSPI2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000ac000) | ||
117 | #define MX50_SDMA_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000b0000) | ||
118 | #define MX50_ROMCP_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000b8000) | ||
119 | #define MX50_CSPI3_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c0000) | ||
120 | #define MX50_I2C2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c4000) | ||
121 | #define MX50_I2C1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c8000) | ||
122 | #define MX50_SSI1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000cc000) | ||
123 | #define MX50_AUDMUX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000d0000) | ||
124 | #define MX50_WEIM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000d8000) | ||
125 | #define MX50_FEC_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000ec000) | ||
126 | |||
127 | /* | ||
128 | * Memory regions and CS | ||
129 | */ | ||
130 | #define MX50_CSD0_BASE_ADDR 0x70000000 | ||
131 | #define MX50_CSD1_BASE_ADDR 0xb0000000 | ||
132 | #define MX50_CS0_BASE_ADDR 0xf0000000 | ||
133 | |||
134 | #define MX50_IO_P2V(x) IMX_IO_P2V(x) | ||
135 | #define MX50_IO_ADDRESS(x) IOMEM(MX50_IO_P2V(x)) | ||
136 | |||
137 | /* | ||
138 | * defines for SPBA modules | ||
139 | */ | ||
140 | #define MX50_SPBA_SDHC1 0x04 | ||
141 | #define MX50_SPBA_SDHC2 0x08 | ||
142 | #define MX50_SPBA_UART3 0x0c | ||
143 | #define MX50_SPBA_CSPI1 0x10 | ||
144 | #define MX50_SPBA_SSI2 0x14 | ||
145 | #define MX50_SPBA_SDHC3 0x20 | ||
146 | #define MX50_SPBA_SDHC4 0x24 | ||
147 | #define MX50_SPBA_SPDIF 0x28 | ||
148 | #define MX50_SPBA_ATA 0x30 | ||
149 | #define MX50_SPBA_SLIM 0x34 | ||
150 | #define MX50_SPBA_HSI2C 0x38 | ||
151 | #define MX50_SPBA_CTRL 0x3c | ||
152 | |||
153 | /* | ||
154 | * DMA request assignments | ||
155 | */ | ||
156 | #define MX50_DMA_REQ_GPC 1 | ||
157 | #define MX50_DMA_REQ_ATA_UART4_RX 2 | ||
158 | #define MX50_DMA_REQ_ATA_UART4_TX 3 | ||
159 | #define MX50_DMA_REQ_CSPI1_RX 6 | ||
160 | #define MX50_DMA_REQ_CSPI1_TX 7 | ||
161 | #define MX50_DMA_REQ_CSPI2_RX 8 | ||
162 | #define MX50_DMA_REQ_CSPI2_TX 9 | ||
163 | #define MX50_DMA_REQ_I2C3_SDHC3 10 | ||
164 | #define MX50_DMA_REQ_SDHC4 11 | ||
165 | #define MX50_DMA_REQ_UART2_FIRI_RX 12 | ||
166 | #define MX50_DMA_REQ_UART2_FIRI_TX 13 | ||
167 | #define MX50_DMA_REQ_EXT0 14 | ||
168 | #define MX50_DMA_REQ_EXT1 15 | ||
169 | #define MX50_DMA_REQ_UART5_RX 16 | ||
170 | #define MX50_DMA_REQ_UART5_TX 17 | ||
171 | #define MX50_DMA_REQ_UART1_RX 18 | ||
172 | #define MX50_DMA_REQ_UART1_TX 19 | ||
173 | #define MX50_DMA_REQ_I2C1_SDHC1 20 | ||
174 | #define MX50_DMA_REQ_I2C2_SDHC2 21 | ||
175 | #define MX50_DMA_REQ_SSI2_RX2 22 | ||
176 | #define MX50_DMA_REQ_SSI2_TX2 23 | ||
177 | #define MX50_DMA_REQ_SSI2_RX1 24 | ||
178 | #define MX50_DMA_REQ_SSI2_TX1 25 | ||
179 | #define MX50_DMA_REQ_SSI1_RX2 26 | ||
180 | #define MX50_DMA_REQ_SSI1_TX2 27 | ||
181 | #define MX50_DMA_REQ_SSI1_RX1 28 | ||
182 | #define MX50_DMA_REQ_SSI1_TX1 29 | ||
183 | #define MX50_DMA_REQ_CSPI_RX 38 | ||
184 | #define MX50_DMA_REQ_CSPI_TX 39 | ||
185 | #define MX50_DMA_REQ_UART3_RX 42 | ||
186 | #define MX50_DMA_REQ_UART3_TX 43 | ||
187 | |||
188 | /* | ||
189 | * Interrupt numbers | ||
190 | */ | ||
191 | #include <asm/irq.h> | ||
192 | #define MX50_INT_MMC_SDHC1 (NR_IRQS_LEGACY + 1) | ||
193 | #define MX50_INT_MMC_SDHC2 (NR_IRQS_LEGACY + 2) | ||
194 | #define MX50_INT_MMC_SDHC3 (NR_IRQS_LEGACY + 3) | ||
195 | #define MX50_INT_MMC_SDHC4 (NR_IRQS_LEGACY + 4) | ||
196 | #define MX50_INT_DAP (NR_IRQS_LEGACY + 5) | ||
197 | #define MX50_INT_SDMA (NR_IRQS_LEGACY + 6) | ||
198 | #define MX50_INT_IOMUX (NR_IRQS_LEGACY + 7) | ||
199 | #define MX50_INT_UART4 (NR_IRQS_LEGACY + 13) | ||
200 | #define MX50_INT_USB_H1 (NR_IRQS_LEGACY + 14) | ||
201 | #define MX50_INT_USB_OTG (NR_IRQS_LEGACY + 18) | ||
202 | #define MX50_INT_DATABAHN (NR_IRQS_LEGACY + 19) | ||
203 | #define MX50_INT_ELCDIF (NR_IRQS_LEGACY + 20) | ||
204 | #define MX50_INT_EPXP (NR_IRQS_LEGACY + 21) | ||
205 | #define MX50_INT_SRTC_NTZ (NR_IRQS_LEGACY + 24) | ||
206 | #define MX50_INT_SRTC_TZ (NR_IRQS_LEGACY + 25) | ||
207 | #define MX50_INT_EPDC (NR_IRQS_LEGACY + 27) | ||
208 | #define MX50_INT_NIC (NR_IRQS_LEGACY + 28) | ||
209 | #define MX50_INT_SSI1 (NR_IRQS_LEGACY + 29) | ||
210 | #define MX50_INT_SSI2 (NR_IRQS_LEGACY + 30) | ||
211 | #define MX50_INT_UART1 (NR_IRQS_LEGACY + 31) | ||
212 | #define MX50_INT_UART2 (NR_IRQS_LEGACY + 32) | ||
213 | #define MX50_INT_UART3 (NR_IRQS_LEGACY + 33) | ||
214 | #define MX50_INT_RESV34 (NR_IRQS_LEGACY + 34) | ||
215 | #define MX50_INT_RESV35 (NR_IRQS_LEGACY + 35) | ||
216 | #define MX50_INT_CSPI1 (NR_IRQS_LEGACY + 36) | ||
217 | #define MX50_INT_CSPI2 (NR_IRQS_LEGACY + 37) | ||
218 | #define MX50_INT_CSPI (NR_IRQS_LEGACY + 38) | ||
219 | #define MX50_INT_GPT (NR_IRQS_LEGACY + 39) | ||
220 | #define MX50_INT_EPIT1 (NR_IRQS_LEGACY + 40) | ||
221 | #define MX50_INT_GPIO1_INT7 (NR_IRQS_LEGACY + 42) | ||
222 | #define MX50_INT_GPIO1_INT6 (NR_IRQS_LEGACY + 43) | ||
223 | #define MX50_INT_GPIO1_INT5 (NR_IRQS_LEGACY + 44) | ||
224 | #define MX50_INT_GPIO1_INT4 (NR_IRQS_LEGACY + 45) | ||
225 | #define MX50_INT_GPIO1_INT3 (NR_IRQS_LEGACY + 46) | ||
226 | #define MX50_INT_GPIO1_INT2 (NR_IRQS_LEGACY + 47) | ||
227 | #define MX50_INT_GPIO1_INT1 (NR_IRQS_LEGACY + 48) | ||
228 | #define MX50_INT_GPIO1_INT0 (NR_IRQS_LEGACY + 49) | ||
229 | #define MX50_INT_GPIO1_LOW (NR_IRQS_LEGACY + 50) | ||
230 | #define MX50_INT_GPIO1_HIGH (NR_IRQS_LEGACY + 51) | ||
231 | #define MX50_INT_GPIO2_LOW (NR_IRQS_LEGACY + 52) | ||
232 | #define MX50_INT_GPIO2_HIGH (NR_IRQS_LEGACY + 53) | ||
233 | #define MX50_INT_GPIO3_LOW (NR_IRQS_LEGACY + 54) | ||
234 | #define MX50_INT_GPIO3_HIGH (NR_IRQS_LEGACY + 55) | ||
235 | #define MX50_INT_GPIO4_LOW (NR_IRQS_LEGACY + 56) | ||
236 | #define MX50_INT_GPIO4_HIGH (NR_IRQS_LEGACY + 57) | ||
237 | #define MX50_INT_WDOG1 (NR_IRQS_LEGACY + 58) | ||
238 | #define MX50_INT_KPP (NR_IRQS_LEGACY + 60) | ||
239 | #define MX50_INT_PWM1 (NR_IRQS_LEGACY + 61) | ||
240 | #define MX50_INT_I2C1 (NR_IRQS_LEGACY + 62) | ||
241 | #define MX50_INT_I2C2 (NR_IRQS_LEGACY + 63) | ||
242 | #define MX50_INT_I2C3 (NR_IRQS_LEGACY + 64) | ||
243 | #define MX50_INT_RESV65 (NR_IRQS_LEGACY + 65) | ||
244 | #define MX50_INT_DCDC (NR_IRQS_LEGACY + 66) | ||
245 | #define MX50_INT_THERMAL_ALARM (NR_IRQS_LEGACY + 67) | ||
246 | #define MX50_INT_ANA3 (NR_IRQS_LEGACY + 68) | ||
247 | #define MX50_INT_ANA4 (NR_IRQS_LEGACY + 69) | ||
248 | #define MX50_INT_CCM1 (NR_IRQS_LEGACY + 71) | ||
249 | #define MX50_INT_CCM2 (NR_IRQS_LEGACY + 72) | ||
250 | #define MX50_INT_GPC1 (NR_IRQS_LEGACY + 73) | ||
251 | #define MX50_INT_GPC2 (NR_IRQS_LEGACY + 74) | ||
252 | #define MX50_INT_SRC (NR_IRQS_LEGACY + 75) | ||
253 | #define MX50_INT_NM (NR_IRQS_LEGACY + 76) | ||
254 | #define MX50_INT_PMU (NR_IRQS_LEGACY + 77) | ||
255 | #define MX50_INT_CTI_IRQ (NR_IRQS_LEGACY + 78) | ||
256 | #define MX50_INT_CTI1_TG0 (NR_IRQS_LEGACY + 79) | ||
257 | #define MX50_INT_CTI1_TG1 (NR_IRQS_LEGACY + 80) | ||
258 | #define MX50_INT_GPU2_IRQ (NR_IRQS_LEGACY + 84) | ||
259 | #define MX50_INT_GPU2_BUSY (NR_IRQS_LEGACY + 85) | ||
260 | #define MX50_INT_UART5 (NR_IRQS_LEGACY + 86) | ||
261 | #define MX50_INT_FEC (NR_IRQS_LEGACY + 87) | ||
262 | #define MX50_INT_OWIRE (NR_IRQS_LEGACY + 88) | ||
263 | #define MX50_INT_CTI1_TG2 (NR_IRQS_LEGACY + 89) | ||
264 | #define MX50_INT_SJC (NR_IRQS_LEGACY + 90) | ||
265 | #define MX50_INT_DCP_CHAN1_3 (NR_IRQS_LEGACY + 91) | ||
266 | #define MX50_INT_DCP_CHAN0 (NR_IRQS_LEGACY + 92) | ||
267 | #define MX50_INT_PWM2 (NR_IRQS_LEGACY + 94) | ||
268 | #define MX50_INT_RNGB (NR_IRQS_LEGACY + 97) | ||
269 | #define MX50_INT_CTI1_TG3 (NR_IRQS_LEGACY + 98) | ||
270 | #define MX50_INT_RAWNAND_BCH (NR_IRQS_LEGACY + 100) | ||
271 | #define MX50_INT_RAWNAND_GPMI (NR_IRQS_LEGACY + 102) | ||
272 | #define MX50_INT_GPIO5_LOW (NR_IRQS_LEGACY + 103) | ||
273 | #define MX50_INT_GPIO5_HIGH (NR_IRQS_LEGACY + 104) | ||
274 | #define MX50_INT_GPIO6_LOW (NR_IRQS_LEGACY + 105) | ||
275 | #define MX50_INT_GPIO6_HIGH (NR_IRQS_LEGACY + 106) | ||
276 | #define MX50_INT_MSHC (NR_IRQS_LEGACY + 109) | ||
277 | #define MX50_INT_APBHDMA_CHAN0 (NR_IRQS_LEGACY + 110) | ||
278 | #define MX50_INT_APBHDMA_CHAN1 (NR_IRQS_LEGACY + 111) | ||
279 | #define MX50_INT_APBHDMA_CHAN2 (NR_IRQS_LEGACY + 112) | ||
280 | #define MX50_INT_APBHDMA_CHAN3 (NR_IRQS_LEGACY + 113) | ||
281 | #define MX50_INT_APBHDMA_CHAN4 (NR_IRQS_LEGACY + 114) | ||
282 | #define MX50_INT_APBHDMA_CHAN5 (NR_IRQS_LEGACY + 115) | ||
283 | #define MX50_INT_APBHDMA_CHAN6 (NR_IRQS_LEGACY + 116) | ||
284 | #define MX50_INT_APBHDMA_CHAN7 (NR_IRQS_LEGACY + 117) | ||
285 | |||
286 | #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) | ||
287 | extern int mx50_revision(void); | ||
288 | #endif | ||
289 | |||
290 | #endif /* ifndef __MACH_MX50_H__ */ | ||
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index d78298366a91..7dce17a9fe6c 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h | |||
@@ -32,7 +32,6 @@ | |||
32 | #define MXC_CPU_MX27 27 | 32 | #define MXC_CPU_MX27 27 |
33 | #define MXC_CPU_MX31 31 | 33 | #define MXC_CPU_MX31 31 |
34 | #define MXC_CPU_MX35 35 | 34 | #define MXC_CPU_MX35 35 |
35 | #define MXC_CPU_MX50 50 | ||
36 | #define MXC_CPU_MX51 51 | 35 | #define MXC_CPU_MX51 51 |
37 | #define MXC_CPU_MX53 53 | 36 | #define MXC_CPU_MX53 53 |
38 | 37 | ||
@@ -126,18 +125,6 @@ extern unsigned int __mxc_cpu_type; | |||
126 | # define cpu_is_mx35() (0) | 125 | # define cpu_is_mx35() (0) |
127 | #endif | 126 | #endif |
128 | 127 | ||
129 | #ifdef CONFIG_SOC_IMX50 | ||
130 | # ifdef mxc_cpu_type | ||
131 | # undef mxc_cpu_type | ||
132 | # define mxc_cpu_type __mxc_cpu_type | ||
133 | # else | ||
134 | # define mxc_cpu_type MXC_CPU_MX50 | ||
135 | # endif | ||
136 | # define cpu_is_mx50() (mxc_cpu_type == MXC_CPU_MX50) | ||
137 | #else | ||
138 | # define cpu_is_mx50() (0) | ||
139 | #endif | ||
140 | |||
141 | #ifdef CONFIG_SOC_IMX51 | 128 | #ifdef CONFIG_SOC_IMX51 |
142 | # ifdef mxc_cpu_type | 129 | # ifdef mxc_cpu_type |
143 | # undef mxc_cpu_type | 130 | # undef mxc_cpu_type |
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/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 2e063c2deb9e..f67fd7ee8127 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | /* | 35 | /* |
36 | * set cpu low power mode before WFI instruction. This function is called | 36 | * set cpu low power mode before WFI instruction. This function is called |
37 | * mx5 because it can be used for mx50, mx51, and mx53. | 37 | * mx5 because it can be used for mx51, and mx53. |
38 | */ | 38 | */ |
39 | static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) | 39 | static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) |
40 | { | 40 | { |
@@ -85,10 +85,7 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) | |||
85 | __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC); | 85 | __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC); |
86 | __raw_writel(ccm_clpcr, MXC_CCM_CLPCR); | 86 | __raw_writel(ccm_clpcr, MXC_CCM_CLPCR); |
87 | __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); | 87 | __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); |
88 | 88 | __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); | |
89 | /* Enable NEON SRPG for all but MX50TO1.0. */ | ||
90 | if (mx50_revision() != IMX_CHIP_REVISION_1_0) | ||
91 | __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); | ||
92 | 89 | ||
93 | if (stop_mode) { | 90 | if (stop_mode) { |
94 | empgc0 |= MXC_SRPGCR_PCR; | 91 | empgc0 |= MXC_SRPGCR_PCR; |
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-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-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..6ec19d51a271 --- /dev/null +++ b/arch/arm/mach-prima2/headsmp.S | |||
@@ -0,0 +1,79 @@ | |||
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 | __INIT | ||
13 | /* | ||
14 | * Cold boot and hardware reset show different behaviour, | ||
15 | * system will be always panic if we warm-reset the board | ||
16 | * Here we invalidate L1 of CPU1 to make sure there isn't | ||
17 | * uninitialized data written into memory later | ||
18 | */ | ||
19 | ENTRY(v7_invalidate_l1) | ||
20 | mov r0, #0 | ||
21 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
22 | mcr p15, 2, r0, c0, c0, 0 | ||
23 | mrc p15, 1, r0, c0, c0, 0 | ||
24 | |||
25 | ldr r1, =0x7fff | ||
26 | and r2, r1, r0, lsr #13 | ||
27 | |||
28 | ldr r1, =0x3ff | ||
29 | |||
30 | and r3, r1, r0, lsr #3 @ NumWays - 1 | ||
31 | add r2, r2, #1 @ NumSets | ||
32 | |||
33 | and r0, r0, #0x7 | ||
34 | add r0, r0, #4 @ SetShift | ||
35 | |||
36 | clz r1, r3 @ WayShift | ||
37 | add r4, r3, #1 @ NumWays | ||
38 | 1: sub r2, r2, #1 @ NumSets-- | ||
39 | mov r3, r4 @ Temp = NumWays | ||
40 | 2: subs r3, r3, #1 @ Temp-- | ||
41 | mov r5, r3, lsl r1 | ||
42 | mov r6, r2, lsl r0 | ||
43 | orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) | ||
44 | mcr p15, 0, r5, c7, c6, 2 | ||
45 | bgt 2b | ||
46 | cmp r2, #0 | ||
47 | bgt 1b | ||
48 | dsb | ||
49 | isb | ||
50 | mov pc, lr | ||
51 | ENDPROC(v7_invalidate_l1) | ||
52 | |||
53 | /* | ||
54 | * SIRFSOC specific entry point for secondary CPUs. This provides | ||
55 | * a "holding pen" into which all secondary cores are held until we're | ||
56 | * ready for them to initialise. | ||
57 | */ | ||
58 | ENTRY(sirfsoc_secondary_startup) | ||
59 | bl v7_invalidate_l1 | ||
60 | mrc p15, 0, r0, c0, c0, 5 | ||
61 | and r0, r0, #15 | ||
62 | adr r4, 1f | ||
63 | ldmia r4, {r5, r6} | ||
64 | sub r4, r4, r5 | ||
65 | add r6, r6, r4 | ||
66 | pen: ldr r7, [r6] | ||
67 | cmp r7, r0 | ||
68 | bne pen | ||
69 | |||
70 | /* | ||
71 | * we've been released from the holding pen: secondary_stack | ||
72 | * should now contain the SVC stack for this core | ||
73 | */ | ||
74 | b secondary_startup | ||
75 | ENDPROC(sirfsoc_secondary_startup) | ||
76 | |||
77 | .align | ||
78 | 1: .long . | ||
79 | .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..97c1ee586442 --- /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 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 0c898fcf909c..15f3edcfbb47 100644 --- a/arch/arm/mach-prima2/include/mach/uncompress.h +++ b/arch/arm/mach-prima2/include/mach/uncompress.h | |||
@@ -25,6 +25,9 @@ static __inline__ void putc(char c) | |||
25 | * during kernel decompression, all mappings are flat: | 25 | * during kernel decompression, all mappings are flat: |
26 | * virt_addr == phys_addr | 26 | * virt_addr == phys_addr |
27 | */ | 27 | */ |
28 | if (!SIRFSOC_UART1_PA_BASE) | ||
29 | return; | ||
30 | |||
28 | while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) | 31 | while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) |
29 | & SIRFSOC_UART1_TXFIFO_FULL) | 32 | & SIRFSOC_UART1_TXFIFO_FULL) |
30 | barrier(); | 33 | 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 0b7147928aa3..700e6623aa86 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 | ||
@@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o | |||
37 | obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o | 37 | obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o |
38 | obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o | 38 | obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o |
39 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o | 39 | obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o |
40 | obj-$(CONFIG_ARCH_SH73A0) += pm-sh73a0.o | ||
40 | 41 | ||
41 | # Board objects | 42 | # Board objects |
42 | obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o | 43 | 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 e7912447ad50..65731370da81 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 ac9428530d7b..363c6edfa3cd 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..202370de32f0 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c | |||
@@ -161,7 +161,8 @@ static struct clk_lookup lookups[] = { | |||
161 | CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ | 161 | CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ |
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[MSTP015]), /* TMU01 */ |
165 | CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP014]), /* 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/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 03c69f9979aa..847567d55487 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> |
@@ -262,6 +261,97 @@ static struct platform_device cmt10_device = { | |||
262 | .num_resources = ARRAY_SIZE(cmt10_resources), | 261 | .num_resources = ARRAY_SIZE(cmt10_resources), |
263 | }; | 262 | }; |
264 | 263 | ||
264 | /* TMU */ | ||
265 | static struct sh_timer_config tmu00_platform_data = { | ||
266 | .name = "TMU00", | ||
267 | .channel_offset = 0x4, | ||
268 | .timer_bit = 0, | ||
269 | .clockevent_rating = 200, | ||
270 | }; | ||
271 | |||
272 | static struct resource tmu00_resources[] = { | ||
273 | [0] = { | ||
274 | .name = "TMU00", | ||
275 | .start = 0xfff80008, | ||
276 | .end = 0xfff80014 - 1, | ||
277 | .flags = IORESOURCE_MEM, | ||
278 | }, | ||
279 | [1] = { | ||
280 | .start = intcs_evt2irq(0xe80), | ||
281 | .flags = IORESOURCE_IRQ, | ||
282 | }, | ||
283 | }; | ||
284 | |||
285 | static struct platform_device tmu00_device = { | ||
286 | .name = "sh_tmu", | ||
287 | .id = 0, | ||
288 | .dev = { | ||
289 | .platform_data = &tmu00_platform_data, | ||
290 | }, | ||
291 | .resource = tmu00_resources, | ||
292 | .num_resources = ARRAY_SIZE(tmu00_resources), | ||
293 | }; | ||
294 | |||
295 | static struct sh_timer_config tmu01_platform_data = { | ||
296 | .name = "TMU01", | ||
297 | .channel_offset = 0x10, | ||
298 | .timer_bit = 1, | ||
299 | .clocksource_rating = 200, | ||
300 | }; | ||
301 | |||
302 | static struct resource tmu01_resources[] = { | ||
303 | [0] = { | ||
304 | .name = "TMU01", | ||
305 | .start = 0xfff80014, | ||
306 | .end = 0xfff80020 - 1, | ||
307 | .flags = IORESOURCE_MEM, | ||
308 | }, | ||
309 | [1] = { | ||
310 | .start = intcs_evt2irq(0xea0), | ||
311 | .flags = IORESOURCE_IRQ, | ||
312 | }, | ||
313 | }; | ||
314 | |||
315 | static struct platform_device tmu01_device = { | ||
316 | .name = "sh_tmu", | ||
317 | .id = 1, | ||
318 | .dev = { | ||
319 | .platform_data = &tmu01_platform_data, | ||
320 | }, | ||
321 | .resource = tmu01_resources, | ||
322 | .num_resources = ARRAY_SIZE(tmu01_resources), | ||
323 | }; | ||
324 | |||
325 | static struct sh_timer_config tmu02_platform_data = { | ||
326 | .name = "TMU02", | ||
327 | .channel_offset = 0x1C, | ||
328 | .timer_bit = 2, | ||
329 | .clocksource_rating = 200, | ||
330 | }; | ||
331 | |||
332 | static struct resource tmu02_resources[] = { | ||
333 | [0] = { | ||
334 | .name = "TMU02", | ||
335 | .start = 0xfff80020, | ||
336 | .end = 0xfff8002C - 1, | ||
337 | .flags = IORESOURCE_MEM, | ||
338 | }, | ||
339 | [1] = { | ||
340 | .start = intcs_evt2irq(0xec0), | ||
341 | .flags = IORESOURCE_IRQ, | ||
342 | }, | ||
343 | }; | ||
344 | |||
345 | static struct platform_device tmu02_device = { | ||
346 | .name = "sh_tmu", | ||
347 | .id = 2, | ||
348 | .dev = { | ||
349 | .platform_data = &tmu02_platform_data, | ||
350 | }, | ||
351 | .resource = tmu02_resources, | ||
352 | .num_resources = ARRAY_SIZE(tmu02_resources), | ||
353 | }; | ||
354 | |||
265 | static struct platform_device *r8a7740_early_devices[] __initdata = { | 355 | static struct platform_device *r8a7740_early_devices[] __initdata = { |
266 | &scif0_device, | 356 | &scif0_device, |
267 | &scif1_device, | 357 | &scif1_device, |
@@ -273,6 +363,9 @@ static struct platform_device *r8a7740_early_devices[] __initdata = { | |||
273 | &scif7_device, | 363 | &scif7_device, |
274 | &scifb_device, | 364 | &scifb_device, |
275 | &cmt10_device, | 365 | &cmt10_device, |
366 | &tmu00_device, | ||
367 | &tmu01_device, | ||
368 | &tmu02_device, | ||
276 | }; | 369 | }; |
277 | 370 | ||
278 | /* DMA */ | 371 | /* DMA */ |
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index a181ced09e45..7e87ab3eb8d3 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c | |||
@@ -66,8 +66,7 @@ static struct plat_sci_port scif0_platform_data = { | |||
66 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 66 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
67 | .scbrr_algo_id = SCBRR_ALGO_2, | 67 | .scbrr_algo_id = SCBRR_ALGO_2, |
68 | .type = PORT_SCIF, | 68 | .type = PORT_SCIF, |
69 | .irqs = { gic_spi(88), gic_spi(88), | 69 | .irqs = SCIx_IRQ_MUXED(gic_spi(88)), |
70 | gic_spi(88), gic_spi(88) }, | ||
71 | }; | 70 | }; |
72 | 71 | ||
73 | static struct platform_device scif0_device = { | 72 | static struct platform_device scif0_device = { |
@@ -84,8 +83,7 @@ static struct plat_sci_port scif1_platform_data = { | |||
84 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 83 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
85 | .scbrr_algo_id = SCBRR_ALGO_2, | 84 | .scbrr_algo_id = SCBRR_ALGO_2, |
86 | .type = PORT_SCIF, | 85 | .type = PORT_SCIF, |
87 | .irqs = { gic_spi(89), gic_spi(89), | 86 | .irqs = SCIx_IRQ_MUXED(gic_spi(89)), |
88 | gic_spi(89), gic_spi(89) }, | ||
89 | }; | 87 | }; |
90 | 88 | ||
91 | static struct platform_device scif1_device = { | 89 | static struct platform_device scif1_device = { |
@@ -102,8 +100,7 @@ static struct plat_sci_port scif2_platform_data = { | |||
102 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 100 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
103 | .scbrr_algo_id = SCBRR_ALGO_2, | 101 | .scbrr_algo_id = SCBRR_ALGO_2, |
104 | .type = PORT_SCIF, | 102 | .type = PORT_SCIF, |
105 | .irqs = { gic_spi(90), gic_spi(90), | 103 | .irqs = SCIx_IRQ_MUXED(gic_spi(90)), |
106 | gic_spi(90), gic_spi(90) }, | ||
107 | }; | 104 | }; |
108 | 105 | ||
109 | static struct platform_device scif2_device = { | 106 | static struct platform_device scif2_device = { |
@@ -120,8 +117,7 @@ static struct plat_sci_port scif3_platform_data = { | |||
120 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 117 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
121 | .scbrr_algo_id = SCBRR_ALGO_2, | 118 | .scbrr_algo_id = SCBRR_ALGO_2, |
122 | .type = PORT_SCIF, | 119 | .type = PORT_SCIF, |
123 | .irqs = { gic_spi(91), gic_spi(91), | 120 | .irqs = SCIx_IRQ_MUXED(gic_spi(91)), |
124 | gic_spi(91), gic_spi(91) }, | ||
125 | }; | 121 | }; |
126 | 122 | ||
127 | static struct platform_device scif3_device = { | 123 | static struct platform_device scif3_device = { |
@@ -138,8 +134,7 @@ static struct plat_sci_port scif4_platform_data = { | |||
138 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 134 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
139 | .scbrr_algo_id = SCBRR_ALGO_2, | 135 | .scbrr_algo_id = SCBRR_ALGO_2, |
140 | .type = PORT_SCIF, | 136 | .type = PORT_SCIF, |
141 | .irqs = { gic_spi(92), gic_spi(92), | 137 | .irqs = SCIx_IRQ_MUXED(gic_spi(92)), |
142 | gic_spi(92), gic_spi(92) }, | ||
143 | }; | 138 | }; |
144 | 139 | ||
145 | static struct platform_device scif4_device = { | 140 | static struct platform_device scif4_device = { |
@@ -156,8 +151,7 @@ static struct plat_sci_port scif5_platform_data = { | |||
156 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | 151 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, |
157 | .scbrr_algo_id = SCBRR_ALGO_2, | 152 | .scbrr_algo_id = SCBRR_ALGO_2, |
158 | .type = PORT_SCIF, | 153 | .type = PORT_SCIF, |
159 | .irqs = { gic_spi(93), gic_spi(93), | 154 | .irqs = SCIx_IRQ_MUXED(gic_spi(93)), |
160 | gic_spi(93), gic_spi(93) }, | ||
161 | }; | 155 | }; |
162 | 156 | ||
163 | static struct platform_device scif5_device = { | 157 | 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 8c2d6424f470..f7ecb0bc1bec 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> |
@@ -754,7 +755,7 @@ static struct platform_device pmu_device = { | |||
754 | .resource = pmu_resources, | 755 | .resource = pmu_resources, |
755 | }; | 756 | }; |
756 | 757 | ||
757 | static struct platform_device *sh73a0_early_devices[] __initdata = { | 758 | static struct platform_device *sh73a0_early_devices_dt[] __initdata = { |
758 | &scif0_device, | 759 | &scif0_device, |
759 | &scif1_device, | 760 | &scif1_device, |
760 | &scif2_device, | 761 | &scif2_device, |
@@ -765,6 +766,9 @@ static struct platform_device *sh73a0_early_devices[] __initdata = { | |||
765 | &scif7_device, | 766 | &scif7_device, |
766 | &scif8_device, | 767 | &scif8_device, |
767 | &cmt10_device, | 768 | &cmt10_device, |
769 | }; | ||
770 | |||
771 | static struct platform_device *sh73a0_early_devices[] __initdata = { | ||
768 | &tmu00_device, | 772 | &tmu00_device, |
769 | &tmu01_device, | 773 | &tmu01_device, |
770 | }; | 774 | }; |
@@ -787,6 +791,8 @@ void __init sh73a0_add_standard_devices(void) | |||
787 | /* Clear software reset bit on SY-DMAC module */ | 791 | /* Clear software reset bit on SY-DMAC module */ |
788 | __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); | 792 | __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); |
789 | 793 | ||
794 | platform_add_devices(sh73a0_early_devices_dt, | ||
795 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
790 | platform_add_devices(sh73a0_early_devices, | 796 | platform_add_devices(sh73a0_early_devices, |
791 | ARRAY_SIZE(sh73a0_early_devices)); | 797 | ARRAY_SIZE(sh73a0_early_devices)); |
792 | platform_add_devices(sh73a0_late_devices, | 798 | platform_add_devices(sh73a0_late_devices, |
@@ -805,9 +811,63 @@ void __init sh73a0_earlytimer_init(void) | |||
805 | 811 | ||
806 | void __init sh73a0_add_early_devices(void) | 812 | void __init sh73a0_add_early_devices(void) |
807 | { | 813 | { |
814 | early_platform_add_devices(sh73a0_early_devices_dt, | ||
815 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
808 | early_platform_add_devices(sh73a0_early_devices, | 816 | early_platform_add_devices(sh73a0_early_devices, |
809 | ARRAY_SIZE(sh73a0_early_devices)); | 817 | ARRAY_SIZE(sh73a0_early_devices)); |
810 | 818 | ||
811 | /* setup early console here as well */ | 819 | /* setup early console here as well */ |
812 | shmobile_setup_console(); | 820 | shmobile_setup_console(); |
813 | } | 821 | } |
822 | |||
823 | #ifdef CONFIG_USE_OF | ||
824 | |||
825 | /* Please note that the clock initialisation shcheme used in | ||
826 | * sh73a0_add_early_devices_dt() and sh73a0_add_standard_devices_dt() | ||
827 | * does not work with SMP as there is a yet to be resolved lock-up in | ||
828 | * workqueue initialisation. | ||
829 | * | ||
830 | * CONFIG_SMP should be disabled when using this code. | ||
831 | */ | ||
832 | |||
833 | void __init sh73a0_add_early_devices_dt(void) | ||
834 | { | ||
835 | shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */ | ||
836 | |||
837 | early_platform_add_devices(sh73a0_early_devices_dt, | ||
838 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
839 | |||
840 | /* setup early console here as well */ | ||
841 | shmobile_setup_console(); | ||
842 | } | ||
843 | |||
844 | static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = { | ||
845 | {}, | ||
846 | }; | ||
847 | |||
848 | void __init sh73a0_add_standard_devices_dt(void) | ||
849 | { | ||
850 | /* clocks are setup late during boot in the case of DT */ | ||
851 | sh73a0_clock_init(); | ||
852 | |||
853 | platform_add_devices(sh73a0_early_devices_dt, | ||
854 | ARRAY_SIZE(sh73a0_early_devices_dt)); | ||
855 | of_platform_populate(NULL, of_default_bus_match_table, | ||
856 | sh73a0_auxdata_lookup, NULL); | ||
857 | } | ||
858 | |||
859 | static const char *sh73a0_boards_compat_dt[] __initdata = { | ||
860 | "renesas,sh73a0", | ||
861 | NULL, | ||
862 | }; | ||
863 | |||
864 | DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") | ||
865 | .map_io = sh73a0_map_io, | ||
866 | .init_early = sh73a0_add_early_devices_dt, | ||
867 | .nr_irqs = NR_IRQS_LEGACY, | ||
868 | .init_irq = sh73a0_init_irq_dt, | ||
869 | .init_machine = sh73a0_add_standard_devices_dt, | ||
870 | .init_time = shmobile_timer_init, | ||
871 | .dt_compat = sh73a0_boards_compat_dt, | ||
872 | MACHINE_END | ||
873 | #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-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index b442f15fd01a..bde8197c8db8 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
@@ -4,11 +4,12 @@ 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_NEEDS_CPU_IDLE_COUPLED if SMP | ||
7 | select ARCH_REQUIRE_GPIOLIB | 8 | select ARCH_REQUIRE_GPIOLIB |
8 | select ARM_ERRATA_720789 | 9 | select ARM_ERRATA_720789 |
9 | select ARM_ERRATA_742230 | 10 | select ARM_ERRATA_742230 if SMP |
10 | select ARM_ERRATA_751472 | 11 | select ARM_ERRATA_751472 |
11 | select ARM_ERRATA_754327 | 12 | select ARM_ERRATA_754327 if SMP |
12 | select ARM_ERRATA_764369 if SMP | 13 | select ARM_ERRATA_764369 if SMP |
13 | select ARM_GIC | 14 | select ARM_GIC |
14 | select CPU_FREQ_TABLE if CPU_FREQ | 15 | select CPU_FREQ_TABLE if CPU_FREQ |
@@ -44,6 +45,18 @@ config ARCH_TEGRA_3x_SOC | |||
44 | Support for NVIDIA Tegra T30 processor family, based on the | 45 | Support for NVIDIA Tegra T30 processor family, based on the |
45 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller | 46 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller |
46 | 47 | ||
48 | config ARCH_TEGRA_114_SOC | ||
49 | bool "Enable support for Tegra114 family" | ||
50 | select ARM_GIC | ||
51 | select CPU_V7 | ||
52 | select ARM_L1_CACHE_SHIFT_6 | ||
53 | select ARM_ARCH_TIMER | ||
54 | select PINCTRL | ||
55 | select PINCTRL_TEGRA114 | ||
56 | help | ||
57 | Support for NVIDIA Tegra T114 processor family, based on the | ||
58 | ARM CortexA15MP CPU | ||
59 | |||
47 | config TEGRA_PCI | 60 | config TEGRA_PCI |
48 | bool "PCI Express support" | 61 | bool "PCI Express support" |
49 | depends on ARCH_TEGRA_2x_SOC | 62 | depends on ARCH_TEGRA_2x_SOC |
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 0979e8bba78a..f6b46ae2b7f8 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
@@ -1,39 +1,38 @@ | |||
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 += timer.o | ||
6 | obj-y += fuse.o | 4 | obj-y += fuse.o |
7 | obj-y += pmc.o | 5 | obj-y += pmc.o |
8 | obj-y += flowctrl.o | 6 | obj-y += flowctrl.o |
9 | obj-y += powergate.o | 7 | obj-y += powergate.o |
10 | obj-y += apbio.o | 8 | obj-y += apbio.o |
11 | obj-y += pm.o | 9 | obj-y += pm.o |
10 | obj-y += reset.o | ||
11 | obj-y += reset-handler.o | ||
12 | obj-y += sleep.o | ||
12 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | 13 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o |
13 | obj-$(CONFIG_CPU_IDLE) += sleep.o | ||
14 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o | ||
15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o | ||
16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o | 14 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o |
17 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o | 15 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o |
18 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o | 16 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o |
19 | ifeq ($(CONFIG_CPU_IDLE),y) | 17 | ifeq ($(CONFIG_CPU_IDLE),y) |
20 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o | 18 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += cpuidle-tegra20.o |
21 | endif | 19 | endif |
22 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o | ||
23 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o | ||
24 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o | 20 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_speedo.o |
25 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o | 21 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o |
26 | ifeq ($(CONFIG_CPU_IDLE),y) | 22 | ifeq ($(CONFIG_CPU_IDLE),y) |
27 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o | 23 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o |
28 | endif | 24 | endif |
29 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 25 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
30 | obj-$(CONFIG_SMP) += reset.o | ||
31 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 26 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
32 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o | 27 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o |
33 | obj-$(CONFIG_TEGRA_PCI) += pcie.o | 28 | 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/apbio.c b/arch/arm/mach-tegra/apbio.c index d091675ba376..d7aa52ea6cfc 100644 --- a/arch/arm/mach-tegra/apbio.c +++ b/arch/arm/mach-tegra/apbio.c | |||
@@ -38,7 +38,7 @@ static void tegra_apb_writel_direct(u32 value, unsigned long offset); | |||
38 | static struct dma_chan *tegra_apb_dma_chan; | 38 | static struct dma_chan *tegra_apb_dma_chan; |
39 | static struct dma_slave_config dma_sconfig; | 39 | static struct dma_slave_config dma_sconfig; |
40 | 40 | ||
41 | bool tegra_apb_dma_init(void) | 41 | static bool tegra_apb_dma_init(void) |
42 | { | 42 | { |
43 | dma_cap_mask_t mask; | 43 | dma_cap_mask_t mask; |
44 | 44 | ||
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..3ed17ce884df --- /dev/null +++ b/arch/arm/mach-tegra/board-dt-tegra114.c | |||
@@ -0,0 +1,48 @@ | |||
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 | #include <asm/hardware/gic.h> | ||
23 | |||
24 | #include "board.h" | ||
25 | #include "common.h" | ||
26 | |||
27 | static void __init tegra114_dt_init(void) | ||
28 | { | ||
29 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | ||
30 | } | ||
31 | |||
32 | static const char * const tegra114_dt_board_compat[] = { | ||
33 | "nvidia,tegra114", | ||
34 | NULL, | ||
35 | }; | ||
36 | |||
37 | DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)") | ||
38 | .smp = smp_ops(tegra_smp_ops), | ||
39 | .map_io = tegra_map_common_io, | ||
40 | .init_early = tegra30_init_early, | ||
41 | .init_irq = tegra_dt_init_irq, | ||
42 | .handle_irq = gic_handle_irq, | ||
43 | .init_time = clocksource_of_init, | ||
44 | .init_machine = tegra114_dt_init, | ||
45 | .init_late = tegra_init_late, | ||
46 | .restart = tegra_assert_system_reset, | ||
47 | .dt_compat = tegra114_dt_board_compat, | ||
48 | MACHINE_END | ||
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 5ed81bab2d4b..a0edf2510280 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/clocksource.h> | ||
18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
@@ -39,99 +40,45 @@ | |||
39 | #include <asm/setup.h> | 40 | #include <asm/setup.h> |
40 | 41 | ||
41 | #include "board.h" | 42 | #include "board.h" |
42 | #include "clock.h" | ||
43 | #include "common.h" | 43 | #include "common.h" |
44 | #include "iomap.h" | 44 | #include "iomap.h" |
45 | 45 | ||
46 | struct tegra_ehci_platform_data tegra_ehci1_pdata = { | 46 | static struct tegra_ehci_platform_data tegra_ehci1_pdata = { |
47 | .operating_mode = TEGRA_USB_OTG, | 47 | .operating_mode = TEGRA_USB_OTG, |
48 | .power_down_on_bus_suspend = 1, | 48 | .power_down_on_bus_suspend = 1, |
49 | .vbus_gpio = -1, | 49 | .vbus_gpio = -1, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { | 52 | static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { |
53 | .reset_gpio = -1, | 53 | .reset_gpio = -1, |
54 | .clk = "cdev2", | 54 | .clk = "cdev2", |
55 | }; | 55 | }; |
56 | 56 | ||
57 | struct tegra_ehci_platform_data tegra_ehci2_pdata = { | 57 | static struct tegra_ehci_platform_data tegra_ehci2_pdata = { |
58 | .phy_config = &tegra_ehci2_ulpi_phy_config, | 58 | .phy_config = &tegra_ehci2_ulpi_phy_config, |
59 | .operating_mode = TEGRA_USB_HOST, | 59 | .operating_mode = TEGRA_USB_HOST, |
60 | .power_down_on_bus_suspend = 1, | 60 | .power_down_on_bus_suspend = 1, |
61 | .vbus_gpio = -1, | 61 | .vbus_gpio = -1, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | struct tegra_ehci_platform_data tegra_ehci3_pdata = { | 64 | static struct tegra_ehci_platform_data tegra_ehci3_pdata = { |
65 | .operating_mode = TEGRA_USB_HOST, | 65 | .operating_mode = TEGRA_USB_HOST, |
66 | .power_down_on_bus_suspend = 1, | 66 | .power_down_on_bus_suspend = 1, |
67 | .vbus_gpio = -1, | 67 | .vbus_gpio = -1, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { | 70 | static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { |
71 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), | 71 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0", |
72 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), | ||
73 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), | ||
74 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL), | ||
75 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL), | ||
76 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL), | ||
77 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL), | ||
78 | OF_DEV_AUXDATA("nvidia,tegra20-i2c-dvc", TEGRA_DVC_BASE, "tegra-i2c.3", NULL), | ||
79 | OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra20-i2s.0", NULL), | ||
80 | OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra20-i2s.1", NULL), | ||
81 | OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra20-das", NULL), | ||
82 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0", | ||
83 | &tegra_ehci1_pdata), | 72 | &tegra_ehci1_pdata), |
84 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1", | 73 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1", |
85 | &tegra_ehci2_pdata), | 74 | &tegra_ehci2_pdata), |
86 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", | 75 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2", |
87 | &tegra_ehci3_pdata), | 76 | &tegra_ehci3_pdata), |
88 | OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL), | ||
89 | OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL), | ||
90 | OF_DEV_AUXDATA("nvidia,tegra20-sflash", 0x7000c380, "spi", NULL), | ||
91 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D400, "spi_tegra.0", NULL), | ||
92 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D600, "spi_tegra.1", NULL), | ||
93 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D800, "spi_tegra.2", NULL), | ||
94 | OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000DA00, "spi_tegra.3", NULL), | ||
95 | OF_DEV_AUXDATA("nvidia,tegra20-host1x", 0x50000000, "host1x", NULL), | ||
96 | OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54200000, "tegradc.0", NULL), | ||
97 | OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54240000, "tegradc.1", NULL), | ||
98 | OF_DEV_AUXDATA("nvidia,tegra20-hdmi", 0x54280000, "hdmi", NULL), | ||
99 | OF_DEV_AUXDATA("nvidia,tegra20-dsi", 0x54300000, "dsi", NULL), | ||
100 | OF_DEV_AUXDATA("nvidia,tegra20-tvo", 0x542c0000, "tvo", NULL), | ||
101 | {} | 77 | {} |
102 | }; | 78 | }; |
103 | 79 | ||
104 | static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { | ||
105 | /* name parent rate enabled */ | ||
106 | { "uarta", "pll_p", 216000000, true }, | ||
107 | { "uartd", "pll_p", 216000000, true }, | ||
108 | { "usbd", "clk_m", 12000000, false }, | ||
109 | { "usb2", "clk_m", 12000000, false }, | ||
110 | { "usb3", "clk_m", 12000000, false }, | ||
111 | { "pll_a", "pll_p_out1", 56448000, true }, | ||
112 | { "pll_a_out0", "pll_a", 11289600, true }, | ||
113 | { "cdev1", NULL, 0, true }, | ||
114 | { "blink", "clk_32k", 32768, true }, | ||
115 | { "i2s1", "pll_a_out0", 11289600, false}, | ||
116 | { "i2s2", "pll_a_out0", 11289600, false}, | ||
117 | { "sdmmc1", "pll_p", 48000000, false}, | ||
118 | { "sdmmc3", "pll_p", 48000000, false}, | ||
119 | { "sdmmc4", "pll_p", 48000000, false}, | ||
120 | { "spi", "pll_p", 20000000, false }, | ||
121 | { "sbc1", "pll_p", 100000000, false }, | ||
122 | { "sbc2", "pll_p", 100000000, false }, | ||
123 | { "sbc3", "pll_p", 100000000, false }, | ||
124 | { "sbc4", "pll_p", 100000000, false }, | ||
125 | { "host1x", "pll_c", 150000000, false }, | ||
126 | { "disp1", "pll_p", 600000000, false }, | ||
127 | { "disp2", "pll_p", 600000000, false }, | ||
128 | { NULL, NULL, 0, 0}, | ||
129 | }; | ||
130 | |||
131 | static void __init tegra_dt_init(void) | 80 | static void __init tegra_dt_init(void) |
132 | { | 81 | { |
133 | tegra_clk_init_from_table(tegra_dt_clk_init_table); | ||
134 | |||
135 | /* | 82 | /* |
136 | * Finished with the static registrations now; fill in the missing | 83 | * Finished with the static registrations now; fill in the missing |
137 | * devices | 84 | * devices |
@@ -200,7 +147,7 @@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") | |||
200 | .smp = smp_ops(tegra_smp_ops), | 147 | .smp = smp_ops(tegra_smp_ops), |
201 | .init_early = tegra20_init_early, | 148 | .init_early = tegra20_init_early, |
202 | .init_irq = tegra_dt_init_irq, | 149 | .init_irq = tegra_dt_init_irq, |
203 | .init_time = tegra_init_timer, | 150 | .init_time = clocksource_of_init, |
204 | .init_machine = tegra_dt_init, | 151 | .init_machine = tegra_dt_init, |
205 | .init_late = tegra_dt_init_late, | 152 | .init_late = tegra_dt_init_late, |
206 | .restart = tegra_assert_system_reset, | 153 | .restart = tegra_assert_system_reset, |
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 12dc2ddeca64..bf68567e549d 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c | |||
@@ -23,6 +23,7 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/clocksource.h> | ||
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
27 | #include <linux/of.h> | 28 | #include <linux/of.h> |
28 | #include <linux/of_address.h> | 29 | #include <linux/of_address.h> |
@@ -33,72 +34,12 @@ | |||
33 | #include <asm/mach/arch.h> | 34 | #include <asm/mach/arch.h> |
34 | 35 | ||
35 | #include "board.h" | 36 | #include "board.h" |
36 | #include "clock.h" | ||
37 | #include "common.h" | 37 | #include "common.h" |
38 | #include "iomap.h" | 38 | #include "iomap.h" |
39 | 39 | ||
40 | struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { | ||
41 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), | ||
42 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL), | ||
43 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL), | ||
44 | OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL), | ||
45 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL), | ||
46 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL), | ||
47 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL), | ||
48 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL), | ||
49 | OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), | ||
50 | OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL), | ||
51 | OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL), | ||
52 | OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL), | ||
53 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D400, "spi_tegra.0", NULL), | ||
54 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D600, "spi_tegra.1", NULL), | ||
55 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D800, "spi_tegra.2", NULL), | ||
56 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DA00, "spi_tegra.3", NULL), | ||
57 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DC00, "spi_tegra.4", NULL), | ||
58 | OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DE00, "spi_tegra.5", NULL), | ||
59 | OF_DEV_AUXDATA("nvidia,tegra30-host1x", 0x50000000, "host1x", NULL), | ||
60 | OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54200000, "tegradc.0", NULL), | ||
61 | OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54240000, "tegradc.1", NULL), | ||
62 | OF_DEV_AUXDATA("nvidia,tegra30-hdmi", 0x54280000, "hdmi", NULL), | ||
63 | OF_DEV_AUXDATA("nvidia,tegra30-dsi", 0x54300000, "dsi", NULL), | ||
64 | OF_DEV_AUXDATA("nvidia,tegra30-tvo", 0x542c0000, "tvo", NULL), | ||
65 | {} | ||
66 | }; | ||
67 | |||
68 | static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { | ||
69 | /* name parent rate enabled */ | ||
70 | { "uarta", "pll_p", 408000000, true }, | ||
71 | { "pll_a", "pll_p_out1", 564480000, true }, | ||
72 | { "pll_a_out0", "pll_a", 11289600, true }, | ||
73 | { "extern1", "pll_a_out0", 0, true }, | ||
74 | { "clk_out_1", "extern1", 0, true }, | ||
75 | { "blink", "clk_32k", 32768, true }, | ||
76 | { "i2s0", "pll_a_out0", 11289600, false}, | ||
77 | { "i2s1", "pll_a_out0", 11289600, false}, | ||
78 | { "i2s2", "pll_a_out0", 11289600, false}, | ||
79 | { "i2s3", "pll_a_out0", 11289600, false}, | ||
80 | { "i2s4", "pll_a_out0", 11289600, false}, | ||
81 | { "sdmmc1", "pll_p", 48000000, false}, | ||
82 | { "sdmmc3", "pll_p", 48000000, false}, | ||
83 | { "sdmmc4", "pll_p", 48000000, false}, | ||
84 | { "sbc1", "pll_p", 100000000, false}, | ||
85 | { "sbc2", "pll_p", 100000000, false}, | ||
86 | { "sbc3", "pll_p", 100000000, false}, | ||
87 | { "sbc4", "pll_p", 100000000, false}, | ||
88 | { "sbc5", "pll_p", 100000000, false}, | ||
89 | { "sbc6", "pll_p", 100000000, false}, | ||
90 | { "host1x", "pll_c", 150000000, false}, | ||
91 | { "disp1", "pll_p", 600000000, false}, | ||
92 | { "disp2", "pll_p", 600000000, false}, | ||
93 | { NULL, NULL, 0, 0}, | ||
94 | }; | ||
95 | |||
96 | static void __init tegra30_dt_init(void) | 40 | static void __init tegra30_dt_init(void) |
97 | { | 41 | { |
98 | tegra_clk_init_from_table(tegra_dt_clk_init_table); | 42 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
99 | |||
100 | of_platform_populate(NULL, of_default_bus_match_table, | ||
101 | tegra30_auxdata_lookup, NULL); | ||
102 | } | 43 | } |
103 | 44 | ||
104 | static const char *tegra30_dt_board_compat[] = { | 45 | static const char *tegra30_dt_board_compat[] = { |
@@ -111,7 +52,7 @@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)") | |||
111 | .map_io = tegra_map_common_io, | 52 | .map_io = tegra_map_common_io, |
112 | .init_early = tegra30_init_early, | 53 | .init_early = tegra30_init_early, |
113 | .init_irq = tegra_dt_init_irq, | 54 | .init_irq = tegra_dt_init_irq, |
114 | .init_time = tegra_init_timer, | 55 | .init_time = clocksource_of_init, |
115 | .init_machine = tegra30_dt_init, | 56 | .init_machine = tegra30_dt_init, |
116 | .init_late = tegra_init_late, | 57 | .init_late = tegra_init_late, |
117 | .restart = tegra_assert_system_reset, | 58 | .restart = tegra_assert_system_reset, |
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index 744cdd246f6a..da8f5a3c4240 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h | |||
@@ -55,5 +55,4 @@ static inline int harmony_pcie_init(void) { return 0; } | |||
55 | 55 | ||
56 | void __init tegra_paz00_wifikill_init(void); | 56 | void __init tegra_paz00_wifikill_init(void); |
57 | 57 | ||
58 | extern void tegra_init_timer(void); | ||
59 | #endif | 58 | #endif |
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 3599959517b3..46c071861c4e 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c | |||
@@ -22,13 +22,13 @@ | |||
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/irqchip.h> | 24 | #include <linux/irqchip.h> |
25 | #include <linux/clk/tegra.h> | ||
25 | 26 | ||
26 | #include <asm/hardware/cache-l2x0.h> | 27 | #include <asm/hardware/cache-l2x0.h> |
27 | 28 | ||
28 | #include <mach/powergate.h> | 29 | #include <mach/powergate.h> |
29 | 30 | ||
30 | #include "board.h" | 31 | #include "board.h" |
31 | #include "clock.h" | ||
32 | #include "common.h" | 32 | #include "common.h" |
33 | #include "fuse.h" | 33 | #include "fuse.h" |
34 | #include "iomap.h" | 34 | #include "iomap.h" |
@@ -36,6 +36,7 @@ | |||
36 | #include "apbio.h" | 36 | #include "apbio.h" |
37 | #include "sleep.h" | 37 | #include "sleep.h" |
38 | #include "pm.h" | 38 | #include "pm.h" |
39 | #include "reset.h" | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * Storage for debug-macro.S's state. | 42 | * Storage for debug-macro.S's state. |
@@ -58,6 +59,7 @@ u32 tegra_uart_config[4] = { | |||
58 | #ifdef CONFIG_OF | 59 | #ifdef CONFIG_OF |
59 | void __init tegra_dt_init_irq(void) | 60 | void __init tegra_dt_init_irq(void) |
60 | { | 61 | { |
62 | tegra_clocks_init(); | ||
61 | tegra_init_irq(); | 63 | tegra_init_irq(); |
62 | irqchip_init(); | 64 | irqchip_init(); |
63 | } | 65 | } |
@@ -73,43 +75,6 @@ void tegra_assert_system_reset(char mode, const char *cmd) | |||
73 | writel_relaxed(reg, reset); | 75 | writel_relaxed(reg, reset); |
74 | } | 76 | } |
75 | 77 | ||
76 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
77 | static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = { | ||
78 | /* name parent rate enabled */ | ||
79 | { "clk_m", NULL, 0, true }, | ||
80 | { "pll_p", "clk_m", 216000000, true }, | ||
81 | { "pll_p_out1", "pll_p", 28800000, true }, | ||
82 | { "pll_p_out2", "pll_p", 48000000, true }, | ||
83 | { "pll_p_out3", "pll_p", 72000000, true }, | ||
84 | { "pll_p_out4", "pll_p", 24000000, true }, | ||
85 | { "pll_c", "clk_m", 600000000, true }, | ||
86 | { "pll_c_out1", "pll_c", 120000000, true }, | ||
87 | { "sclk", "pll_c_out1", 120000000, true }, | ||
88 | { "hclk", "sclk", 120000000, true }, | ||
89 | { "pclk", "hclk", 60000000, true }, | ||
90 | { "csite", NULL, 0, true }, | ||
91 | { "emc", NULL, 0, true }, | ||
92 | { "cpu", NULL, 0, true }, | ||
93 | { NULL, NULL, 0, 0}, | ||
94 | }; | ||
95 | #endif | ||
96 | |||
97 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
98 | static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = { | ||
99 | /* name parent rate enabled */ | ||
100 | { "clk_m", NULL, 0, true }, | ||
101 | { "pll_p", "pll_ref", 408000000, true }, | ||
102 | { "pll_p_out1", "pll_p", 9600000, true }, | ||
103 | { "pll_p_out4", "pll_p", 102000000, true }, | ||
104 | { "sclk", "pll_p_out4", 102000000, true }, | ||
105 | { "hclk", "sclk", 102000000, true }, | ||
106 | { "pclk", "hclk", 51000000, true }, | ||
107 | { "csite", NULL, 0, true }, | ||
108 | { NULL, NULL, 0, 0}, | ||
109 | }; | ||
110 | #endif | ||
111 | |||
112 | |||
113 | static void __init tegra_init_cache(void) | 78 | static void __init tegra_init_cache(void) |
114 | { | 79 | { |
115 | #ifdef CONFIG_CACHE_L2X0 | 80 | #ifdef CONFIG_CACHE_L2X0 |
@@ -131,10 +96,9 @@ static void __init tegra_init_cache(void) | |||
131 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 96 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC |
132 | void __init tegra20_init_early(void) | 97 | void __init tegra20_init_early(void) |
133 | { | 98 | { |
99 | tegra_cpu_reset_handler_init(); | ||
134 | tegra_apb_io_init(); | 100 | tegra_apb_io_init(); |
135 | tegra_init_fuse(); | 101 | tegra_init_fuse(); |
136 | tegra2_init_clocks(); | ||
137 | tegra_clk_init_from_table(tegra20_clk_init_table); | ||
138 | tegra_init_cache(); | 102 | tegra_init_cache(); |
139 | tegra_pmc_init(); | 103 | tegra_pmc_init(); |
140 | tegra_powergate_init(); | 104 | tegra_powergate_init(); |
@@ -144,10 +108,9 @@ void __init tegra20_init_early(void) | |||
144 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | 108 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC |
145 | void __init tegra30_init_early(void) | 109 | void __init tegra30_init_early(void) |
146 | { | 110 | { |
111 | tegra_cpu_reset_handler_init(); | ||
147 | tegra_apb_io_init(); | 112 | tegra_apb_io_init(); |
148 | tegra_init_fuse(); | 113 | tegra_init_fuse(); |
149 | tegra30_init_clocks(); | ||
150 | tegra_clk_init_from_table(tegra30_clk_init_table); | ||
151 | tegra_init_cache(); | 114 | tegra_init_cache(); |
152 | tegra_pmc_init(); | 115 | tegra_pmc_init(); |
153 | tegra_powergate_init(); | 116 | tegra_powergate_init(); |
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h index 02f71b4f1e51..32f8eb3fe344 100644 --- a/arch/arm/mach-tegra/common.h +++ b/arch/arm/mach-tegra/common.h | |||
@@ -1,4 +1,5 @@ | |||
1 | extern struct smp_operations tegra_smp_ops; | 1 | extern struct smp_operations tegra_smp_ops; |
2 | 2 | ||
3 | extern int tegra_cpu_kill(unsigned int cpu); | ||
3 | extern void tegra_cpu_die(unsigned int cpu); | 4 | extern void tegra_cpu_die(unsigned int cpu); |
4 | extern int tegra_cpu_disable(unsigned int cpu); | 5 | extern int tegra_cpu_disable(unsigned int cpu); |
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index a74d3c7d2e26..ebffed67e2f5 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c | |||
@@ -214,24 +214,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) | |||
214 | if (policy->cpu >= NUM_CPUS) | 214 | if (policy->cpu >= NUM_CPUS) |
215 | return -EINVAL; | 215 | return -EINVAL; |
216 | 216 | ||
217 | cpu_clk = clk_get_sys(NULL, "cpu"); | ||
218 | if (IS_ERR(cpu_clk)) | ||
219 | return PTR_ERR(cpu_clk); | ||
220 | |||
221 | pll_x_clk = clk_get_sys(NULL, "pll_x"); | ||
222 | if (IS_ERR(pll_x_clk)) | ||
223 | return PTR_ERR(pll_x_clk); | ||
224 | |||
225 | pll_p_clk = clk_get_sys(NULL, "pll_p"); | ||
226 | if (IS_ERR(pll_p_clk)) | ||
227 | return PTR_ERR(pll_p_clk); | ||
228 | |||
229 | emc_clk = clk_get_sys("cpu", "emc"); | ||
230 | if (IS_ERR(emc_clk)) { | ||
231 | clk_put(cpu_clk); | ||
232 | return PTR_ERR(emc_clk); | ||
233 | } | ||
234 | |||
235 | clk_prepare_enable(emc_clk); | 217 | clk_prepare_enable(emc_clk); |
236 | clk_prepare_enable(cpu_clk); | 218 | clk_prepare_enable(cpu_clk); |
237 | 219 | ||
@@ -256,8 +238,6 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy) | |||
256 | { | 238 | { |
257 | cpufreq_frequency_table_cpuinfo(policy, freq_table); | 239 | cpufreq_frequency_table_cpuinfo(policy, freq_table); |
258 | clk_disable_unprepare(emc_clk); | 240 | clk_disable_unprepare(emc_clk); |
259 | clk_put(emc_clk); | ||
260 | clk_put(cpu_clk); | ||
261 | return 0; | 241 | return 0; |
262 | } | 242 | } |
263 | 243 | ||
@@ -278,12 +258,32 @@ static struct cpufreq_driver tegra_cpufreq_driver = { | |||
278 | 258 | ||
279 | static int __init tegra_cpufreq_init(void) | 259 | static int __init tegra_cpufreq_init(void) |
280 | { | 260 | { |
261 | cpu_clk = clk_get_sys(NULL, "cpu"); | ||
262 | if (IS_ERR(cpu_clk)) | ||
263 | return PTR_ERR(cpu_clk); | ||
264 | |||
265 | pll_x_clk = clk_get_sys(NULL, "pll_x"); | ||
266 | if (IS_ERR(pll_x_clk)) | ||
267 | return PTR_ERR(pll_x_clk); | ||
268 | |||
269 | pll_p_clk = clk_get_sys(NULL, "pll_p_cclk"); | ||
270 | if (IS_ERR(pll_p_clk)) | ||
271 | return PTR_ERR(pll_p_clk); | ||
272 | |||
273 | emc_clk = clk_get_sys("cpu", "emc"); | ||
274 | if (IS_ERR(emc_clk)) { | ||
275 | clk_put(cpu_clk); | ||
276 | return PTR_ERR(emc_clk); | ||
277 | } | ||
278 | |||
281 | return cpufreq_register_driver(&tegra_cpufreq_driver); | 279 | return cpufreq_register_driver(&tegra_cpufreq_driver); |
282 | } | 280 | } |
283 | 281 | ||
284 | static void __exit tegra_cpufreq_exit(void) | 282 | static void __exit tegra_cpufreq_exit(void) |
285 | { | 283 | { |
286 | cpufreq_unregister_driver(&tegra_cpufreq_driver); | 284 | cpufreq_unregister_driver(&tegra_cpufreq_driver); |
285 | clk_put(emc_clk); | ||
286 | clk_put(cpu_clk); | ||
287 | } | 287 | } |
288 | 288 | ||
289 | 289 | ||
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 5e8cbf5b799f..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, |
@@ -121,9 +121,9 @@ static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev, | |||
121 | } | 121 | } |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | static int __cpuinit tegra30_idle_lp2(struct cpuidle_device *dev, | 124 | static int tegra30_idle_lp2(struct cpuidle_device *dev, |
125 | struct cpuidle_driver *drv, | 125 | struct cpuidle_driver *drv, |
126 | int index) | 126 | int index) |
127 | { | 127 | { |
128 | u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; | 128 | u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu; |
129 | bool entered_lp2 = false; | 129 | bool entered_lp2 = false; |
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 a2250ddae797..b477ef310dcd 100644 --- a/arch/arm/mach-tegra/flowctrl.c +++ b/arch/arm/mach-tegra/flowctrl.c | |||
@@ -25,15 +25,16 @@ | |||
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 | u8 flowctrl_offset_halt_cpu[] = { | 30 | static u8 flowctrl_offset_halt_cpu[] = { |
30 | FLOW_CTRL_HALT_CPU0_EVENTS, | 31 | FLOW_CTRL_HALT_CPU0_EVENTS, |
31 | FLOW_CTRL_HALT_CPU1_EVENTS, | 32 | FLOW_CTRL_HALT_CPU1_EVENTS, |
32 | FLOW_CTRL_HALT_CPU1_EVENTS + 8, | 33 | FLOW_CTRL_HALT_CPU1_EVENTS + 8, |
33 | FLOW_CTRL_HALT_CPU1_EVENTS + 16, | 34 | FLOW_CTRL_HALT_CPU1_EVENTS + 16, |
34 | }; | 35 | }; |
35 | 36 | ||
36 | u8 flowctrl_offset_cpu_csr[] = { | 37 | static u8 flowctrl_offset_cpu_csr[] = { |
37 | FLOW_CTRL_CPU0_CSR, | 38 | FLOW_CTRL_CPU0_CSR, |
38 | FLOW_CTRL_CPU1_CSR, | 39 | FLOW_CTRL_CPU1_CSR, |
39 | FLOW_CTRL_CPU1_CSR + 8, | 40 | FLOW_CTRL_CPU1_CSR + 8, |
@@ -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 4a317fae6860..b2834810b02b 100644 --- a/arch/arm/mach-tegra/headsmp.S +++ b/arch/arm/mach-tegra/headsmp.S | |||
@@ -1,22 +1,9 @@ | |||
1 | #include <linux/linkage.h> | 1 | #include <linux/linkage.h> |
2 | #include <linux/init.h> | 2 | #include <linux/init.h> |
3 | 3 | ||
4 | #include <asm/cache.h> | ||
5 | #include <asm/asm-offsets.h> | ||
6 | #include <asm/hardware/cache-l2x0.h> | ||
7 | |||
8 | #include "flowctrl.h" | ||
9 | #include "iomap.h" | ||
10 | #include "reset.h" | ||
11 | #include "sleep.h" | 4 | #include "sleep.h" |
12 | 5 | ||
13 | #define APB_MISC_GP_HIDREV 0x804 | ||
14 | #define PMC_SCRATCH41 0x140 | ||
15 | |||
16 | #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) | ||
17 | |||
18 | .section ".text.head", "ax" | 6 | .section ".text.head", "ax" |
19 | __CPUINIT | ||
20 | 7 | ||
21 | /* | 8 | /* |
22 | * Tegra specific entry point for secondary CPUs. | 9 | * Tegra specific entry point for secondary CPUs. |
@@ -61,7 +48,6 @@ ENTRY(v7_invalidate_l1) | |||
61 | mov pc, lr | 48 | mov pc, lr |
62 | ENDPROC(v7_invalidate_l1) | 49 | ENDPROC(v7_invalidate_l1) |
63 | 50 | ||
64 | |||
65 | ENTRY(tegra_secondary_startup) | 51 | ENTRY(tegra_secondary_startup) |
66 | bl v7_invalidate_l1 | 52 | bl v7_invalidate_l1 |
67 | /* Enable coresight */ | 53 | /* Enable coresight */ |
@@ -69,210 +55,3 @@ ENTRY(tegra_secondary_startup) | |||
69 | mcr p14, 0, r0, c7, c12, 6 | 55 | mcr p14, 0, r0, c7, c12, 6 |
70 | b secondary_startup | 56 | b secondary_startup |
71 | ENDPROC(tegra_secondary_startup) | 57 | ENDPROC(tegra_secondary_startup) |
72 | |||
73 | #ifdef CONFIG_PM_SLEEP | ||
74 | /* | ||
75 | * tegra_resume | ||
76 | * | ||
77 | * CPU boot vector when restarting the a CPU following | ||
78 | * an LP2 transition. Also branched to by LP0 and LP1 resume after | ||
79 | * re-enabling sdram. | ||
80 | */ | ||
81 | ENTRY(tegra_resume) | ||
82 | bl v7_invalidate_l1 | ||
83 | /* Enable coresight */ | ||
84 | mov32 r0, 0xC5ACCE55 | ||
85 | mcr p14, 0, r0, c7, c12, 6 | ||
86 | |||
87 | cpu_id r0 | ||
88 | cmp r0, #0 @ CPU0? | ||
89 | bne cpu_resume @ no | ||
90 | |||
91 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
92 | /* Are we on Tegra20? */ | ||
93 | mov32 r6, TEGRA_APB_MISC_BASE | ||
94 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
95 | and r0, r0, #0xff00 | ||
96 | cmp r0, #(0x20 << 8) | ||
97 | beq 1f @ Yes | ||
98 | /* Clear the flow controller flags for this CPU. */ | ||
99 | mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR | ||
100 | ldr r1, [r2] | ||
101 | /* Clear event & intr flag */ | ||
102 | orr r1, r1, \ | ||
103 | #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
104 | movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps | ||
105 | bic r1, r1, r0 | ||
106 | str r1, [r2] | ||
107 | 1: | ||
108 | #endif | ||
109 | |||
110 | #ifdef CONFIG_HAVE_ARM_SCU | ||
111 | /* enable SCU */ | ||
112 | mov32 r0, TEGRA_ARM_PERIF_BASE | ||
113 | ldr r1, [r0] | ||
114 | orr r1, r1, #1 | ||
115 | str r1, [r0] | ||
116 | #endif | ||
117 | |||
118 | /* L2 cache resume & re-enable */ | ||
119 | l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr | ||
120 | |||
121 | b cpu_resume | ||
122 | ENDPROC(tegra_resume) | ||
123 | #endif | ||
124 | |||
125 | #ifdef CONFIG_CACHE_L2X0 | ||
126 | .globl l2x0_saved_regs_addr | ||
127 | l2x0_saved_regs_addr: | ||
128 | .long 0 | ||
129 | #endif | ||
130 | |||
131 | .align L1_CACHE_SHIFT | ||
132 | ENTRY(__tegra_cpu_reset_handler_start) | ||
133 | |||
134 | /* | ||
135 | * __tegra_cpu_reset_handler: | ||
136 | * | ||
137 | * Common handler for all CPU reset events. | ||
138 | * | ||
139 | * Register usage within the reset handler: | ||
140 | * | ||
141 | * R7 = CPU present (to the OS) mask | ||
142 | * R8 = CPU in LP1 state mask | ||
143 | * R9 = CPU in LP2 state mask | ||
144 | * R10 = CPU number | ||
145 | * R11 = CPU mask | ||
146 | * R12 = pointer to reset handler data | ||
147 | * | ||
148 | * NOTE: This code is copied to IRAM. All code and data accesses | ||
149 | * must be position-independent. | ||
150 | */ | ||
151 | |||
152 | .align L1_CACHE_SHIFT | ||
153 | ENTRY(__tegra_cpu_reset_handler) | ||
154 | |||
155 | cpsid aif, 0x13 @ SVC mode, interrupts disabled | ||
156 | mrc p15, 0, r10, c0, c0, 5 @ MPIDR | ||
157 | and r10, r10, #0x3 @ R10 = CPU number | ||
158 | mov r11, #1 | ||
159 | mov r11, r11, lsl r10 @ R11 = CPU mask | ||
160 | adr r12, __tegra_cpu_reset_handler_data | ||
161 | |||
162 | #ifdef CONFIG_SMP | ||
163 | /* Does the OS know about this CPU? */ | ||
164 | ldr r7, [r12, #RESET_DATA(MASK_PRESENT)] | ||
165 | tst r7, r11 @ if !present | ||
166 | bleq __die @ CPU not present (to OS) | ||
167 | #endif | ||
168 | |||
169 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
170 | /* Are we on Tegra20? */ | ||
171 | mov32 r6, TEGRA_APB_MISC_BASE | ||
172 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
173 | and r0, r0, #0xff00 | ||
174 | cmp r0, #(0x20 << 8) | ||
175 | bne 1f | ||
176 | /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ | ||
177 | mov32 r6, TEGRA_PMC_BASE | ||
178 | mov r0, #0 | ||
179 | cmp r10, #0 | ||
180 | strne r0, [r6, #PMC_SCRATCH41] | ||
181 | 1: | ||
182 | #endif | ||
183 | |||
184 | /* Waking up from LP2? */ | ||
185 | ldr r9, [r12, #RESET_DATA(MASK_LP2)] | ||
186 | tst r9, r11 @ if in_lp2 | ||
187 | beq __is_not_lp2 | ||
188 | ldr lr, [r12, #RESET_DATA(STARTUP_LP2)] | ||
189 | cmp lr, #0 | ||
190 | bleq __die @ no LP2 startup handler | ||
191 | bx lr | ||
192 | |||
193 | __is_not_lp2: | ||
194 | |||
195 | #ifdef CONFIG_SMP | ||
196 | /* | ||
197 | * Can only be secondary boot (initial or hotplug) but CPU 0 | ||
198 | * cannot be here. | ||
199 | */ | ||
200 | cmp r10, #0 | ||
201 | bleq __die @ CPU0 cannot be here | ||
202 | ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] | ||
203 | cmp lr, #0 | ||
204 | bleq __die @ no secondary startup handler | ||
205 | bx lr | ||
206 | #endif | ||
207 | |||
208 | /* | ||
209 | * We don't know why the CPU reset. Just kill it. | ||
210 | * The LR register will contain the address we died at + 4. | ||
211 | */ | ||
212 | |||
213 | __die: | ||
214 | sub lr, lr, #4 | ||
215 | mov32 r7, TEGRA_PMC_BASE | ||
216 | str lr, [r7, #PMC_SCRATCH41] | ||
217 | |||
218 | mov32 r7, TEGRA_CLK_RESET_BASE | ||
219 | |||
220 | /* Are we on Tegra20? */ | ||
221 | mov32 r6, TEGRA_APB_MISC_BASE | ||
222 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
223 | and r0, r0, #0xff00 | ||
224 | cmp r0, #(0x20 << 8) | ||
225 | bne 1f | ||
226 | |||
227 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
228 | mov32 r0, 0x1111 | ||
229 | mov r1, r0, lsl r10 | ||
230 | str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET | ||
231 | #endif | ||
232 | 1: | ||
233 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
234 | mov32 r6, TEGRA_FLOW_CTRL_BASE | ||
235 | |||
236 | cmp r10, #0 | ||
237 | moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS | ||
238 | moveq r2, #FLOW_CTRL_CPU0_CSR | ||
239 | movne r1, r10, lsl #3 | ||
240 | addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8) | ||
241 | addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8) | ||
242 | |||
243 | /* Clear CPU "event" and "interrupt" flags and power gate | ||
244 | it when halting but not before it is in the "WFI" state. */ | ||
245 | ldr r0, [r6, +r2] | ||
246 | orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
247 | orr r0, r0, #FLOW_CTRL_CSR_ENABLE | ||
248 | str r0, [r6, +r2] | ||
249 | |||
250 | /* Unconditionally halt this CPU */ | ||
251 | mov r0, #FLOW_CTRL_WAITEVENT | ||
252 | str r0, [r6, +r1] | ||
253 | ldr r0, [r6, +r1] @ memory barrier | ||
254 | |||
255 | dsb | ||
256 | isb | ||
257 | wfi @ CPU should be power gated here | ||
258 | |||
259 | /* If the CPU didn't power gate above just kill it's clock. */ | ||
260 | |||
261 | mov r0, r11, lsl #8 | ||
262 | str r0, [r7, #348] @ CLK_CPU_CMPLX_SET | ||
263 | #endif | ||
264 | |||
265 | /* If the CPU still isn't dead, just spin here. */ | ||
266 | b . | ||
267 | ENDPROC(__tegra_cpu_reset_handler) | ||
268 | |||
269 | .align L1_CACHE_SHIFT | ||
270 | .type __tegra_cpu_reset_handler_data, %object | ||
271 | .globl __tegra_cpu_reset_handler_data | ||
272 | __tegra_cpu_reset_handler_data: | ||
273 | .rept TEGRA_RESET_DATA_SIZE | ||
274 | .long 0 | ||
275 | .endr | ||
276 | .align L1_CACHE_SHIFT | ||
277 | |||
278 | ENTRY(__tegra_cpu_reset_handler_end) | ||
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index dca5141a2c31..a599f6e36dea 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c | |||
@@ -10,15 +10,26 @@ | |||
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 | ||
22 | int tegra_cpu_kill(unsigned cpu) | ||
23 | { | ||
24 | cpu = cpu_logical_map(cpu); | ||
25 | |||
26 | /* Clock gate the CPU */ | ||
27 | tegra_wait_cpu_in_reset(cpu); | ||
28 | tegra_disable_cpu_clock(cpu); | ||
29 | |||
30 | return 1; | ||
31 | } | ||
32 | |||
22 | /* | 33 | /* |
23 | * platform-specific code to shutdown a CPU | 34 | * platform-specific code to shutdown a CPU |
24 | * | 35 | * |
@@ -26,18 +37,12 @@ static void (*tegra_hotplug_shutdown)(void); | |||
26 | */ | 37 | */ |
27 | void __ref tegra_cpu_die(unsigned int cpu) | 38 | void __ref tegra_cpu_die(unsigned int cpu) |
28 | { | 39 | { |
29 | cpu = cpu_logical_map(cpu); | 40 | /* Clean L1 data cache */ |
30 | 41 | tegra_disable_clean_inv_dcache(); | |
31 | /* Flush the L1 data cache. */ | ||
32 | flush_cache_all(); | ||
33 | 42 | ||
34 | /* Shut down the current CPU. */ | 43 | /* Shut down the current CPU. */ |
35 | tegra_hotplug_shutdown(); | 44 | tegra_hotplug_shutdown(); |
36 | 45 | ||
37 | /* Clock gate the CPU */ | ||
38 | tegra_wait_cpu_in_reset(cpu); | ||
39 | tegra_disable_cpu_clock(cpu); | ||
40 | |||
41 | /* Should never return here. */ | 46 | /* Should never return here. */ |
42 | BUG(); | 47 | BUG(); |
43 | } | 48 | } |
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 18d7290cf93b..2c6b3d55213b 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c | |||
@@ -19,24 +19,25 @@ | |||
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> |
25 | #include <asm/smp_scu.h> | 26 | #include <asm/smp_scu.h> |
27 | #include <asm/smp_plat.h> | ||
26 | 28 | ||
27 | #include <mach/powergate.h> | 29 | #include <mach/powergate.h> |
28 | 30 | ||
29 | #include "fuse.h" | 31 | #include "fuse.h" |
30 | #include "flowctrl.h" | 32 | #include "flowctrl.h" |
31 | #include "reset.h" | 33 | #include "reset.h" |
32 | #include "tegra_cpu_car.h" | ||
33 | 34 | ||
34 | #include "common.h" | 35 | #include "common.h" |
35 | #include "iomap.h" | 36 | #include "iomap.h" |
36 | 37 | ||
37 | extern void tegra_secondary_startup(void); | 38 | extern void tegra_secondary_startup(void); |
38 | 39 | ||
39 | static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); | 40 | static cpumask_t tegra_cpu_init_mask; |
40 | 41 | ||
41 | #define EVP_CPU_RESET_VECTOR \ | 42 | #define EVP_CPU_RESET_VECTOR \ |
42 | (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) | 43 | (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) |
@@ -50,6 +51,7 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu) | |||
50 | */ | 51 | */ |
51 | gic_secondary_init(0); | 52 | gic_secondary_init(0); |
52 | 53 | ||
54 | cpumask_set_cpu(cpu, &tegra_cpu_init_mask); | ||
53 | } | 55 | } |
54 | 56 | ||
55 | static int tegra20_power_up_cpu(unsigned int cpu) | 57 | static int tegra20_power_up_cpu(unsigned int cpu) |
@@ -72,14 +74,42 @@ static int tegra30_power_up_cpu(unsigned int cpu) | |||
72 | if (pwrgateid < 0) | 74 | if (pwrgateid < 0) |
73 | return pwrgateid; | 75 | return pwrgateid; |
74 | 76 | ||
75 | /* If this is the first boot, toggle powergates directly. */ | 77 | /* |
78 | * The power up sequence of cold boot CPU and warm boot CPU | ||
79 | * was different. | ||
80 | * | ||
81 | * For warm boot CPU that was resumed from CPU hotplug, the | ||
82 | * power will be resumed automatically after un-halting the | ||
83 | * flow controller of the warm boot CPU. We need to wait for | ||
84 | * the confirmaiton that the CPU is powered then removing | ||
85 | * the IO clamps. | ||
86 | * For cold boot CPU, do not wait. After the cold boot CPU be | ||
87 | * booted, it will run to tegra_secondary_init() and set | ||
88 | * tegra_cpu_init_mask which influences what tegra30_power_up_cpu() | ||
89 | * next time around. | ||
90 | */ | ||
91 | if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { | ||
92 | timeout = jiffies + msecs_to_jiffies(50); | ||
93 | do { | ||
94 | if (!tegra_powergate_is_powered(pwrgateid)) | ||
95 | goto remove_clamps; | ||
96 | udelay(10); | ||
97 | } while (time_before(jiffies, timeout)); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * The power status of the cold boot CPU is power gated as | ||
102 | * default. To power up the cold boot CPU, the power should | ||
103 | * be un-gated by un-toggling the power gate register | ||
104 | * manually. | ||
105 | */ | ||
76 | if (!tegra_powergate_is_powered(pwrgateid)) { | 106 | if (!tegra_powergate_is_powered(pwrgateid)) { |
77 | ret = tegra_powergate_power_on(pwrgateid); | 107 | ret = tegra_powergate_power_on(pwrgateid); |
78 | if (ret) | 108 | if (ret) |
79 | return ret; | 109 | return ret; |
80 | 110 | ||
81 | /* Wait for the power to come up. */ | 111 | /* Wait for the power to come up. */ |
82 | timeout = jiffies + 10*HZ; | 112 | timeout = jiffies + msecs_to_jiffies(100); |
83 | while (tegra_powergate_is_powered(pwrgateid)) { | 113 | while (tegra_powergate_is_powered(pwrgateid)) { |
84 | if (time_after(jiffies, timeout)) | 114 | if (time_after(jiffies, timeout)) |
85 | return -ETIMEDOUT; | 115 | return -ETIMEDOUT; |
@@ -87,6 +117,7 @@ static int tegra30_power_up_cpu(unsigned int cpu) | |||
87 | } | 117 | } |
88 | } | 118 | } |
89 | 119 | ||
120 | remove_clamps: | ||
90 | /* CPU partition is powered. Enable the CPU clock. */ | 121 | /* CPU partition is powered. Enable the CPU clock. */ |
91 | tegra_enable_cpu_clock(cpu); | 122 | tegra_enable_cpu_clock(cpu); |
92 | udelay(10); | 123 | udelay(10); |
@@ -105,6 +136,8 @@ static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct * | |||
105 | { | 136 | { |
106 | int status; | 137 | int status; |
107 | 138 | ||
139 | cpu = cpu_logical_map(cpu); | ||
140 | |||
108 | /* | 141 | /* |
109 | * Force the CPU into reset. The CPU must remain in reset when the | 142 | * Force the CPU into reset. The CPU must remain in reset when the |
110 | * flow controller state is cleared (which will cause the flow | 143 | * flow controller state is cleared (which will cause the flow |
@@ -143,36 +176,21 @@ done: | |||
143 | return status; | 176 | return status; |
144 | } | 177 | } |
145 | 178 | ||
146 | /* | ||
147 | * Initialise the CPU possible map early - this describes the CPUs | ||
148 | * which may be present or become present in the system. | ||
149 | */ | ||
150 | static void __init tegra_smp_init_cpus(void) | ||
151 | { | ||
152 | unsigned int i, ncores = scu_get_core_count(scu_base); | ||
153 | |||
154 | if (ncores > nr_cpu_ids) { | ||
155 | pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", | ||
156 | ncores, nr_cpu_ids); | ||
157 | ncores = nr_cpu_ids; | ||
158 | } | ||
159 | |||
160 | for (i = 0; i < ncores; i++) | ||
161 | set_cpu_possible(i, true); | ||
162 | } | ||
163 | |||
164 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) | 179 | static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) |
165 | { | 180 | { |
166 | tegra_cpu_reset_handler_init(); | 181 | /* Always mark the boot CPU (CPU0) as initialized. */ |
167 | scu_enable(scu_base); | 182 | cpumask_set_cpu(0, &tegra_cpu_init_mask); |
183 | |||
184 | if (scu_a9_has_base()) | ||
185 | scu_enable(IO_ADDRESS(scu_a9_get_base())); | ||
168 | } | 186 | } |
169 | 187 | ||
170 | struct smp_operations tegra_smp_ops __initdata = { | 188 | struct smp_operations tegra_smp_ops __initdata = { |
171 | .smp_init_cpus = tegra_smp_init_cpus, | ||
172 | .smp_prepare_cpus = tegra_smp_prepare_cpus, | 189 | .smp_prepare_cpus = tegra_smp_prepare_cpus, |
173 | .smp_secondary_init = tegra_secondary_init, | 190 | .smp_secondary_init = tegra_secondary_init, |
174 | .smp_boot_secondary = tegra_boot_secondary, | 191 | .smp_boot_secondary = tegra_boot_secondary, |
175 | #ifdef CONFIG_HOTPLUG_CPU | 192 | #ifdef CONFIG_HOTPLUG_CPU |
193 | .cpu_kill = tegra_cpu_kill, | ||
176 | .cpu_die = tegra_cpu_die, | 194 | .cpu_die = tegra_cpu_die, |
177 | .cpu_disable = tegra_cpu_disable, | 195 | .cpu_disable = tegra_cpu_disable, |
178 | #endif | 196 | #endif |
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 1b11707eaca0..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 | ||
@@ -148,7 +149,7 @@ static void suspend_cpu_complex(void) | |||
148 | save_cpu_arch_register(); | 149 | save_cpu_arch_register(); |
149 | } | 150 | } |
150 | 151 | ||
151 | void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id) | 152 | void tegra_clear_cpu_in_lp2(int phy_cpu_id) |
152 | { | 153 | { |
153 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; | 154 | u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; |
154 | 155 | ||
@@ -160,7 +161,7 @@ void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id) | |||
160 | spin_unlock(&tegra_lp2_lock); | 161 | spin_unlock(&tegra_lp2_lock); |
161 | } | 162 | } |
162 | 163 | ||
163 | bool __cpuinit tegra_set_cpu_in_lp2(int phy_cpu_id) | 164 | bool tegra_set_cpu_in_lp2(int phy_cpu_id) |
164 | { | 165 | { |
165 | bool last_cpu = false; | 166 | bool last_cpu = false; |
166 | cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; | 167 | cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; |
@@ -173,6 +174,8 @@ bool __cpuinit 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/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S new file mode 100644 index 000000000000..54382ceade4a --- /dev/null +++ b/arch/arm/mach-tegra/reset-handler.S | |||
@@ -0,0 +1,239 @@ | |||
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/linkage.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <asm/cache.h> | ||
21 | #include <asm/asm-offsets.h> | ||
22 | #include <asm/hardware/cache-l2x0.h> | ||
23 | |||
24 | #include "flowctrl.h" | ||
25 | #include "iomap.h" | ||
26 | #include "reset.h" | ||
27 | #include "sleep.h" | ||
28 | |||
29 | #define APB_MISC_GP_HIDREV 0x804 | ||
30 | #define PMC_SCRATCH41 0x140 | ||
31 | |||
32 | #define RESET_DATA(x) ((TEGRA_RESET_##x)*4) | ||
33 | |||
34 | #ifdef CONFIG_PM_SLEEP | ||
35 | /* | ||
36 | * tegra_resume | ||
37 | * | ||
38 | * CPU boot vector when restarting the a CPU following | ||
39 | * an LP2 transition. Also branched to by LP0 and LP1 resume after | ||
40 | * re-enabling sdram. | ||
41 | */ | ||
42 | ENTRY(tegra_resume) | ||
43 | bl v7_invalidate_l1 | ||
44 | /* Enable coresight */ | ||
45 | mov32 r0, 0xC5ACCE55 | ||
46 | mcr p14, 0, r0, c7, c12, 6 | ||
47 | |||
48 | cpu_id r0 | ||
49 | cmp r0, #0 @ CPU0? | ||
50 | bne cpu_resume @ no | ||
51 | |||
52 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
53 | /* Are we on Tegra20? */ | ||
54 | mov32 r6, TEGRA_APB_MISC_BASE | ||
55 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
56 | and r0, r0, #0xff00 | ||
57 | cmp r0, #(0x20 << 8) | ||
58 | beq 1f @ Yes | ||
59 | /* Clear the flow controller flags for this CPU. */ | ||
60 | mov32 r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR @ CPU0 CSR | ||
61 | ldr r1, [r2] | ||
62 | /* Clear event & intr flag */ | ||
63 | orr r1, r1, \ | ||
64 | #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
65 | movw r0, #0x0FFD @ enable, cluster_switch, immed, & bitmaps | ||
66 | bic r1, r1, r0 | ||
67 | str r1, [r2] | ||
68 | 1: | ||
69 | #endif | ||
70 | |||
71 | #ifdef CONFIG_HAVE_ARM_SCU | ||
72 | /* enable SCU */ | ||
73 | mov32 r0, TEGRA_ARM_PERIF_BASE | ||
74 | ldr r1, [r0] | ||
75 | orr r1, r1, #1 | ||
76 | str r1, [r0] | ||
77 | #endif | ||
78 | |||
79 | /* L2 cache resume & re-enable */ | ||
80 | l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr | ||
81 | |||
82 | b cpu_resume | ||
83 | ENDPROC(tegra_resume) | ||
84 | #endif | ||
85 | |||
86 | #ifdef CONFIG_CACHE_L2X0 | ||
87 | .globl l2x0_saved_regs_addr | ||
88 | l2x0_saved_regs_addr: | ||
89 | .long 0 | ||
90 | #endif | ||
91 | |||
92 | .align L1_CACHE_SHIFT | ||
93 | ENTRY(__tegra_cpu_reset_handler_start) | ||
94 | |||
95 | /* | ||
96 | * __tegra_cpu_reset_handler: | ||
97 | * | ||
98 | * Common handler for all CPU reset events. | ||
99 | * | ||
100 | * Register usage within the reset handler: | ||
101 | * | ||
102 | * R7 = CPU present (to the OS) mask | ||
103 | * R8 = CPU in LP1 state mask | ||
104 | * R9 = CPU in LP2 state mask | ||
105 | * R10 = CPU number | ||
106 | * R11 = CPU mask | ||
107 | * R12 = pointer to reset handler data | ||
108 | * | ||
109 | * NOTE: This code is copied to IRAM. All code and data accesses | ||
110 | * must be position-independent. | ||
111 | */ | ||
112 | |||
113 | .align L1_CACHE_SHIFT | ||
114 | ENTRY(__tegra_cpu_reset_handler) | ||
115 | |||
116 | cpsid aif, 0x13 @ SVC mode, interrupts disabled | ||
117 | mrc p15, 0, r10, c0, c0, 5 @ MPIDR | ||
118 | and r10, r10, #0x3 @ R10 = CPU number | ||
119 | mov r11, #1 | ||
120 | mov r11, r11, lsl r10 @ R11 = CPU mask | ||
121 | adr r12, __tegra_cpu_reset_handler_data | ||
122 | |||
123 | #ifdef CONFIG_SMP | ||
124 | /* Does the OS know about this CPU? */ | ||
125 | ldr r7, [r12, #RESET_DATA(MASK_PRESENT)] | ||
126 | tst r7, r11 @ if !present | ||
127 | bleq __die @ CPU not present (to OS) | ||
128 | #endif | ||
129 | |||
130 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
131 | /* Are we on Tegra20? */ | ||
132 | mov32 r6, TEGRA_APB_MISC_BASE | ||
133 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
134 | and r0, r0, #0xff00 | ||
135 | cmp r0, #(0x20 << 8) | ||
136 | bne 1f | ||
137 | /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ | ||
138 | mov32 r6, TEGRA_PMC_BASE | ||
139 | mov r0, #0 | ||
140 | cmp r10, #0 | ||
141 | strne r0, [r6, #PMC_SCRATCH41] | ||
142 | 1: | ||
143 | #endif | ||
144 | |||
145 | /* Waking up from LP2? */ | ||
146 | ldr r9, [r12, #RESET_DATA(MASK_LP2)] | ||
147 | tst r9, r11 @ if in_lp2 | ||
148 | beq __is_not_lp2 | ||
149 | ldr lr, [r12, #RESET_DATA(STARTUP_LP2)] | ||
150 | cmp lr, #0 | ||
151 | bleq __die @ no LP2 startup handler | ||
152 | bx lr | ||
153 | |||
154 | __is_not_lp2: | ||
155 | |||
156 | #ifdef CONFIG_SMP | ||
157 | /* | ||
158 | * Can only be secondary boot (initial or hotplug) but CPU 0 | ||
159 | * cannot be here. | ||
160 | */ | ||
161 | cmp r10, #0 | ||
162 | bleq __die @ CPU0 cannot be here | ||
163 | ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] | ||
164 | cmp lr, #0 | ||
165 | bleq __die @ no secondary startup handler | ||
166 | bx lr | ||
167 | #endif | ||
168 | |||
169 | /* | ||
170 | * We don't know why the CPU reset. Just kill it. | ||
171 | * The LR register will contain the address we died at + 4. | ||
172 | */ | ||
173 | |||
174 | __die: | ||
175 | sub lr, lr, #4 | ||
176 | mov32 r7, TEGRA_PMC_BASE | ||
177 | str lr, [r7, #PMC_SCRATCH41] | ||
178 | |||
179 | mov32 r7, TEGRA_CLK_RESET_BASE | ||
180 | |||
181 | /* Are we on Tegra20? */ | ||
182 | mov32 r6, TEGRA_APB_MISC_BASE | ||
183 | ldr r0, [r6, #APB_MISC_GP_HIDREV] | ||
184 | and r0, r0, #0xff00 | ||
185 | cmp r0, #(0x20 << 8) | ||
186 | bne 1f | ||
187 | |||
188 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
189 | mov32 r0, 0x1111 | ||
190 | mov r1, r0, lsl r10 | ||
191 | str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET | ||
192 | #endif | ||
193 | 1: | ||
194 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
195 | mov32 r6, TEGRA_FLOW_CTRL_BASE | ||
196 | |||
197 | cmp r10, #0 | ||
198 | moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS | ||
199 | moveq r2, #FLOW_CTRL_CPU0_CSR | ||
200 | movne r1, r10, lsl #3 | ||
201 | addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8) | ||
202 | addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8) | ||
203 | |||
204 | /* Clear CPU "event" and "interrupt" flags and power gate | ||
205 | it when halting but not before it is in the "WFI" state. */ | ||
206 | ldr r0, [r6, +r2] | ||
207 | orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | ||
208 | orr r0, r0, #FLOW_CTRL_CSR_ENABLE | ||
209 | str r0, [r6, +r2] | ||
210 | |||
211 | /* Unconditionally halt this CPU */ | ||
212 | mov r0, #FLOW_CTRL_WAITEVENT | ||
213 | str r0, [r6, +r1] | ||
214 | ldr r0, [r6, +r1] @ memory barrier | ||
215 | |||
216 | dsb | ||
217 | isb | ||
218 | wfi @ CPU should be power gated here | ||
219 | |||
220 | /* If the CPU didn't power gate above just kill it's clock. */ | ||
221 | |||
222 | mov r0, r11, lsl #8 | ||
223 | str r0, [r7, #348] @ CLK_CPU_CMPLX_SET | ||
224 | #endif | ||
225 | |||
226 | /* If the CPU still isn't dead, just spin here. */ | ||
227 | b . | ||
228 | ENDPROC(__tegra_cpu_reset_handler) | ||
229 | |||
230 | .align L1_CACHE_SHIFT | ||
231 | .type __tegra_cpu_reset_handler_data, %object | ||
232 | .globl __tegra_cpu_reset_handler_data | ||
233 | __tegra_cpu_reset_handler_data: | ||
234 | .rept TEGRA_RESET_DATA_SIZE | ||
235 | .long 0 | ||
236 | .endr | ||
237 | .align L1_CACHE_SHIFT | ||
238 | |||
239 | ENTRY(__tegra_cpu_reset_handler_end) | ||
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c index 3fd89ecd158e..1ac434e0068f 100644 --- a/arch/arm/mach-tegra/reset.c +++ b/arch/arm/mach-tegra/reset.c | |||
@@ -75,7 +75,7 @@ void __init tegra_cpu_reset_handler_init(void) | |||
75 | 75 | ||
76 | #ifdef CONFIG_SMP | 76 | #ifdef CONFIG_SMP |
77 | __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] = | 77 | __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] = |
78 | *((u32 *)cpu_present_mask); | 78 | *((u32 *)cpu_possible_mask); |
79 | __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] = | 79 | __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] = |
80 | virt_to_phys((void *)tegra_secondary_startup); | 80 | virt_to_phys((void *)tegra_secondary_startup); |
81 | #endif | 81 | #endif |
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S index 72ce709799da..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" |
@@ -33,9 +35,6 @@ | |||
33 | * should never return | 35 | * should never return |
34 | */ | 36 | */ |
35 | ENTRY(tegra20_hotplug_shutdown) | 37 | ENTRY(tegra20_hotplug_shutdown) |
36 | /* Turn off SMP coherency */ | ||
37 | exit_smp r4, r5 | ||
38 | |||
39 | /* Put this CPU down */ | 38 | /* Put this CPU down */ |
40 | cpu_id r0 | 39 | cpu_id r0 |
41 | bl tegra20_cpu_shutdown | 40 | bl tegra20_cpu_shutdown |
@@ -58,6 +57,9 @@ ENDPROC(tegra20_hotplug_shutdown) | |||
58 | ENTRY(tegra20_cpu_shutdown) | 57 | ENTRY(tegra20_cpu_shutdown) |
59 | cmp r0, #0 | 58 | cmp r0, #0 |
60 | 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] | ||
61 | 63 | ||
62 | cpu_to_halt_reg r1, r0 | 64 | cpu_to_halt_reg r1, r0 |
63 | ldr r3, =TEGRA_FLOW_CTRL_VIRT | 65 | ldr r3, =TEGRA_FLOW_CTRL_VIRT |
@@ -78,3 +80,198 @@ ENTRY(tegra20_cpu_shutdown) | |||
78 | mov pc, lr | 80 | mov pc, lr |
79 | ENDPROC(tegra20_cpu_shutdown) | 81 | ENDPROC(tegra20_cpu_shutdown) |
80 | #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-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S index 562a8e7e413d..63a15bd9b653 100644 --- a/arch/arm/mach-tegra/sleep-tegra30.S +++ b/arch/arm/mach-tegra/sleep-tegra30.S | |||
@@ -32,9 +32,6 @@ | |||
32 | * Should never return. | 32 | * Should never return. |
33 | */ | 33 | */ |
34 | ENTRY(tegra30_hotplug_shutdown) | 34 | ENTRY(tegra30_hotplug_shutdown) |
35 | /* Turn off SMP coherency */ | ||
36 | exit_smp r4, r5 | ||
37 | |||
38 | /* Powergate this CPU */ | 35 | /* Powergate this CPU */ |
39 | mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN | 36 | mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN |
40 | bl tegra30_cpu_shutdown | 37 | bl tegra30_cpu_shutdown |
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S index 26afa7cbed11..364d84523fba 100644 --- a/arch/arm/mach-tegra/sleep.S +++ b/arch/arm/mach-tegra/sleep.S | |||
@@ -34,7 +34,10 @@ | |||
34 | #include "flowctrl.h" | 34 | #include "flowctrl.h" |
35 | #include "sleep.h" | 35 | #include "sleep.h" |
36 | 36 | ||
37 | #ifdef CONFIG_PM_SLEEP | 37 | #define CLK_RESET_CCLK_BURST 0x20 |
38 | #define CLK_RESET_CCLK_DIVIDER 0x24 | ||
39 | |||
40 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) | ||
38 | /* | 41 | /* |
39 | * tegra_disable_clean_inv_dcache | 42 | * tegra_disable_clean_inv_dcache |
40 | * | 43 | * |
@@ -60,7 +63,9 @@ ENTRY(tegra_disable_clean_inv_dcache) | |||
60 | 63 | ||
61 | ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc} | 64 | ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc} |
62 | ENDPROC(tegra_disable_clean_inv_dcache) | 65 | ENDPROC(tegra_disable_clean_inv_dcache) |
66 | #endif | ||
63 | 67 | ||
68 | #ifdef CONFIG_PM_SLEEP | ||
64 | /* | 69 | /* |
65 | * tegra_sleep_cpu_finish(unsigned long v2p) | 70 | * tegra_sleep_cpu_finish(unsigned long v2p) |
66 | * | 71 | * |
@@ -108,4 +113,20 @@ ENTRY(tegra_shut_off_mmu) | |||
108 | mov pc, r0 | 113 | mov pc, r0 |
109 | ENDPROC(tegra_shut_off_mmu) | 114 | ENDPROC(tegra_shut_off_mmu) |
110 | .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) | ||
111 | #endif | 132 | #endif |
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index 9821ee725420..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,8 +117,11 @@ 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); |
124 | void tegra_disable_clean_inv_dcache(void); | ||
109 | 125 | ||
110 | #ifdef CONFIG_HOTPLUG_CPU | 126 | #ifdef CONFIG_HOTPLUG_CPU |
111 | void tegra20_hotplug_init(void); | 127 | void tegra20_hotplug_init(void); |
@@ -115,6 +131,17 @@ static inline void tegra20_hotplug_init(void) {} | |||
115 | static inline void tegra30_hotplug_init(void) {} | 131 | static inline void tegra30_hotplug_init(void) {} |
116 | #endif | 132 | #endif |
117 | 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); | ||
118 | int tegra30_sleep_cpu_secondary_finish(unsigned long); | 145 | int tegra30_sleep_cpu_secondary_finish(unsigned long); |
119 | void tegra30_tear_down_cpu(void); | 146 | void tegra30_tear_down_cpu(void); |
120 | 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 6942c7add3bb..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 | 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 | 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 | 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 570a801fb862..c0b1c604ccf8 100644 --- a/arch/arm/mach-vt8500/Kconfig +++ b/arch/arm/mach-vt8500/Kconfig | |||
@@ -1,13 +1,34 @@ | |||
1 | config ARCH_VT8500 | 1 | config ARCH_VT8500 |
2 | bool "VIA/WonderMedia 85xx" if ARCH_MULTI_V5 | 2 | bool |
3 | default ARCH_VT8500_SINGLE | ||
4 | select ARCH_HAS_CPUFREQ | 3 | select ARCH_HAS_CPUFREQ |
5 | select ARCH_REQUIRE_GPIOLIB | 4 | select ARCH_REQUIRE_GPIOLIB |
6 | select CLKDEV_LOOKUP | 5 | select CLKDEV_LOOKUP |
7 | select CPU_ARM926T | ||
8 | select GENERIC_CLOCKEVENTS | 6 | select GENERIC_CLOCKEVENTS |
9 | select GENERIC_GPIO | 7 | select GENERIC_GPIO |
10 | select HAVE_CLK | 8 | select HAVE_CLK |
11 | select VT8500_TIMER | 9 | select VT8500_TIMER |
12 | help | 10 | help |
13 | Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. | 11 | Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. |
12 | |||
13 | config ARCH_WM8505 | ||
14 | bool "VIA/Wondermedia 85xx and WM8650" | ||
15 | depends on ARCH_MULTI_V5 | ||
16 | select ARCH_VT8500 | ||
17 | select CPU_ARM926T | ||
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/include/mach/timex.h b/arch/arm/mach-vt8500/include/mach/timex.h deleted file mode 100644 index 8487e4c690b7..000000000000 --- a/arch/arm/mach-vt8500/include/mach/timex.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-vt8500/include/mach/timex.h | ||
3 | * | ||
4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * 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, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef MACH_TIMEX_H | ||
22 | #define MACH_TIMEX_H | ||
23 | |||
24 | #define CLOCK_TICK_RATE (3000000) | ||
25 | |||
26 | #endif /* MACH_TIMEX_H */ | ||
diff --git a/arch/arm/mach-vt8500/include/mach/uncompress.h b/arch/arm/mach-vt8500/include/mach/uncompress.h deleted file mode 100644 index e6e81fdaf109..000000000000 --- a/arch/arm/mach-vt8500/include/mach/uncompress.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* arch/arm/mach-vt8500/include/mach/uncompress.h | ||
2 | * | ||
3 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
4 | * | ||
5 | * Based on arch/arm/mach-dove/include/mach/uncompress.h | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #define UART0_PHYS 0xd8200000 | ||
19 | #define UART0_ADDR(x) *(volatile unsigned char *)(UART0_PHYS + x) | ||
20 | |||
21 | static void putc(const char c) | ||
22 | { | ||
23 | while (UART0_ADDR(0x1c) & 0x2) | ||
24 | /* Tx busy, wait and poll */; | ||
25 | |||
26 | UART0_ADDR(0) = c; | ||
27 | } | ||
28 | |||
29 | static void flush(void) | ||
30 | { | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * nothing to do | ||
35 | */ | ||
36 | #define arch_decomp_setup() | ||
37 | #define arch_decomp_wdog() | ||
diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c index b9fd9d3cbfb3..6141868b9a3c 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/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c index e686fe76a96b..7310bcfb299f 100644 --- a/arch/arm/plat-orion/mpp.c +++ b/arch/arm/plat-orion/mpp.c | |||
@@ -49,7 +49,7 @@ void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask, | |||
49 | "number (%u)\n", num); | 49 | "number (%u)\n", num); |
50 | continue; | 50 | continue; |
51 | } | 51 | } |
52 | if (variant_mask & !(*mpp_list & variant_mask)) { | 52 | if (variant_mask && !(*mpp_list & variant_mask)) { |
53 | printk(KERN_WARNING | 53 | printk(KERN_WARNING |
54 | "orion_mpp_conf: requested MPP%u config " | 54 | "orion_mpp_conf: requested MPP%u config " |
55 | "unavailable on this hardware\n", num); | 55 | "unavailable on this hardware\n", num); |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index ee90e87e7675..f0b269a2058d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_ARCH_U8500) += ux500/ | |||
22 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o | 22 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o |
23 | obj-$(CONFIG_ARCH_SUNXI) += clk-sunxi.o | 23 | obj-$(CONFIG_ARCH_SUNXI) += clk-sunxi.o |
24 | obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o | 24 | obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o |
25 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ | ||
25 | 26 | ||
26 | # Chip specific | 27 | # Chip specific |
27 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | 28 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o |
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/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/clocksource/Makefile b/drivers/clocksource/Makefile index 440449c1ca21..596c45c2f192 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o | |||
17 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | 17 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o |
18 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o | 18 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o |
19 | obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o | 19 | obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o |
20 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o | ||
20 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o | 21 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o |
21 | 22 | ||
22 | obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o | 23 | obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o |
diff --git a/arch/arm/mach-tegra/timer.c b/drivers/clocksource/tegra20_timer.c index eba0969ded19..0bde03feb095 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/drivers/clocksource/tegra20_timer.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arch/mach-tegra/timer.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | 2 | * Copyright (C) 2010 Google, Inc. |
5 | * | 3 | * |
6 | * Author: | 4 | * Author: |
@@ -33,8 +31,6 @@ | |||
33 | #include <asm/smp_twd.h> | 31 | #include <asm/smp_twd.h> |
34 | #include <asm/sched_clock.h> | 32 | #include <asm/sched_clock.h> |
35 | 33 | ||
36 | #include "board.h" | ||
37 | |||
38 | #define RTC_SECONDS 0x08 | 34 | #define RTC_SECONDS 0x08 |
39 | #define RTC_SHADOW_SECONDS 0x0c | 35 | #define RTC_SHADOW_SECONDS 0x0c |
40 | #define RTC_MILLISECONDS 0x10 | 36 | #define RTC_MILLISECONDS 0x10 |
@@ -168,7 +164,7 @@ static const struct of_device_id rtc_match[] __initconst = { | |||
168 | {} | 164 | {} |
169 | }; | 165 | }; |
170 | 166 | ||
171 | void __init tegra_init_timer(void) | 167 | static void __init tegra20_init_timer(void) |
172 | { | 168 | { |
173 | struct device_node *np; | 169 | struct device_node *np; |
174 | struct clk *clk; | 170 | struct clk *clk; |
@@ -183,7 +179,7 @@ void __init tegra_init_timer(void) | |||
183 | 179 | ||
184 | timer_reg_base = of_iomap(np, 0); | 180 | timer_reg_base = of_iomap(np, 0); |
185 | if (!timer_reg_base) { | 181 | if (!timer_reg_base) { |
186 | pr_err("Can't map timer registers"); | 182 | pr_err("Can't map timer registers\n"); |
187 | BUG(); | 183 | BUG(); |
188 | } | 184 | } |
189 | 185 | ||
@@ -268,6 +264,7 @@ void __init tegra_init_timer(void) | |||
268 | #endif | 264 | #endif |
269 | register_persistent_clock(NULL, tegra_read_persistent_clock); | 265 | register_persistent_clock(NULL, tegra_read_persistent_clock); |
270 | } | 266 | } |
267 | CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer); | ||
271 | 268 | ||
272 | #ifdef CONFIG_PM | 269 | #ifdef CONFIG_PM |
273 | static u32 usec_config; | 270 | static u32 usec_config; |
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 3cad856fe67f..2a02c11890ec 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c | |||
@@ -31,8 +31,8 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/clk/tegra.h> | ||
34 | 35 | ||
35 | #include <mach/clk.h> | ||
36 | #include "dmaengine.h" | 36 | #include "dmaengine.h" |
37 | 37 | ||
38 | #define TEGRA_APBDMA_GENERAL 0x0 | 38 | #define TEGRA_APBDMA_GENERAL 0x0 |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 656b2e3334a6..56813f967c8f 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 e060c7e6434d..92ad276cc5e0 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 7b38877ffec1..c7aca35e38fd 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 c76f96872d31..54ac1dc7d477 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/tegra_kbc.h> | 32 | #include <linux/input/tegra_kbc.h> |
33 | #include <mach/clk.h> | 33 | #include <linux/clk/tegra.h> |
34 | 34 | ||
35 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu | 35 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu |
36 | 36 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 923a9da9c829..20354b43932e 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -1023,7 +1023,7 @@ config RTC_DRV_TX4939 | |||
1023 | 1023 | ||
1024 | config RTC_DRV_MV | 1024 | config RTC_DRV_MV |
1025 | tristate "Marvell SoC RTC" | 1025 | tristate "Marvell SoC RTC" |
1026 | depends on ARCH_KIRKWOOD || ARCH_DOVE | 1026 | depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU |
1027 | help | 1027 | help |
1028 | If you say yes here you will get support for the in-chip RTC | 1028 | If you say yes here you will get support for the in-chip RTC |
1029 | that can be found in some of Marvell's SoC devices, such as | 1029 | 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 448a8cc71df3..e5dce91b74ca 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) |
@@ -525,7 +525,7 @@ static int tegra_sflash_probe(struct platform_device *pdev) | |||
525 | goto exit_free_master; | 525 | goto exit_free_master; |
526 | } | 526 | } |
527 | 527 | ||
528 | tsd->clk = devm_clk_get(&pdev->dev, "spi"); | 528 | tsd->clk = devm_clk_get(&pdev->dev, NULL); |
529 | if (IS_ERR(tsd->clk)) { | 529 | if (IS_ERR(tsd->clk)) { |
530 | dev_err(&pdev->dev, "can not get clock\n"); | 530 | dev_err(&pdev->dev, "can not get clock\n"); |
531 | ret = PTR_ERR(tsd->clk); | 531 | ret = PTR_ERR(tsd->clk); |
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 651167f2e0af..e255e7a35678 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) |
@@ -1191,7 +1191,7 @@ static int tegra_slink_probe(struct platform_device *pdev) | |||
1191 | goto exit_free_master; | 1191 | goto exit_free_master; |
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | tspi->clk = devm_clk_get(&pdev->dev, "slink"); | 1194 | tspi->clk = devm_clk_get(&pdev->dev, NULL); |
1195 | if (IS_ERR(tspi->clk)) { | 1195 | if (IS_ERR(tspi->clk)) { |
1196 | dev_err(&pdev->dev, "can not get clock\n"); | 1196 | dev_err(&pdev->dev, "can not get clock\n"); |
1197 | ret = PTR_ERR(tspi->clk); | 1197 | 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 2830946860d1..9417941974f7 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 | ||
@@ -771,7 +770,7 @@ static int tegra_nvec_probe(struct platform_device *pdev) | |||
771 | return -ENODEV; | 770 | return -ENODEV; |
772 | } | 771 | } |
773 | 772 | ||
774 | i2c_clk = clk_get_sys("tegra-i2c.2", "div-clk"); | 773 | i2c_clk = clk_get(&pdev->dev, "div-clk"); |
775 | if (IS_ERR(i2c_clk)) { | 774 | if (IS_ERR(i2c_clk)) { |
776 | dev_err(nvec->dev, "failed to get controller clock\n"); | 775 | dev_err(nvec->dev, "failed to get controller clock\n"); |
777 | return -ENODEV; | 776 | 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/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 f354dc390a0b..2355630367f7 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 | ||