imx_ahcisata.c revision 1.4 1 1.4 andvar /* $NetBSD: imx_ahcisata.c,v 1.4 2022/02/06 20:20:19 andvar Exp $ */
2 1.1 skrll
3 1.1 skrll /*-
4 1.1 skrll * Copyright (c) 2019 Genetec Corporation. All rights reserved.
5 1.1 skrll * Written by Hashimoto Kenichi for Genetec Corporation.
6 1.1 skrll *
7 1.1 skrll * Redistribution and use in source and binary forms, with or without
8 1.1 skrll * modification, are permitted provided that the following conditions
9 1.1 skrll * are met:
10 1.1 skrll * 1. Redistributions of source code must retain the above copyright
11 1.1 skrll * notice, this list of conditions and the following disclaimer.
12 1.1 skrll * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 skrll * notice, this list of conditions and the following disclaimer in the
14 1.1 skrll * documentation and/or other materials provided with the distribution.
15 1.1 skrll *
16 1.1 skrll * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 skrll * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1 skrll * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1 skrll * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1 skrll * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 1.1 skrll * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 1.1 skrll * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 1.1 skrll * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 1.1 skrll * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.1 skrll * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.1 skrll * SUCH DAMAGE.
27 1.1 skrll */
28 1.1 skrll
29 1.1 skrll #include <sys/cdefs.h>
30 1.4 andvar __KERNEL_RCSID(0, "$NetBSD: imx_ahcisata.c,v 1.4 2022/02/06 20:20:19 andvar Exp $");
31 1.1 skrll
32 1.1 skrll #include <sys/param.h>
33 1.1 skrll #include <sys/bus.h>
34 1.1 skrll #include <sys/device.h>
35 1.1 skrll #include <sys/intr.h>
36 1.1 skrll #include <sys/systm.h>
37 1.1 skrll #include <sys/kernel.h>
38 1.1 skrll
39 1.1 skrll #include <dev/ata/atavar.h>
40 1.1 skrll #include <dev/ic/ahcisatavar.h>
41 1.1 skrll
42 1.1 skrll #include <arm/nxp/imx_ahcisatareg.h>
43 1.1 skrll #include <arm/nxp/imx6_iomuxreg.h>
44 1.1 skrll #include <arm/nxp/imx6_ccmreg.h>
45 1.1 skrll #include <arm/nxp/imx6_ccmvar.h>
46 1.1 skrll
47 1.1 skrll #include <dev/fdt/fdtvar.h>
48 1.1 skrll
49 1.1 skrll static int imx_ahcisata_match(device_t, cfdata_t, void *);
50 1.1 skrll static void imx_ahcisata_attach(device_t, device_t, void *);
51 1.1 skrll
52 1.1 skrll struct imx_ahcisata_softc {
53 1.1 skrll struct ahci_softc sc;
54 1.1 skrll
55 1.1 skrll device_t sc_dev;
56 1.1 skrll bus_space_tag_t sc_iot;
57 1.1 skrll bus_space_handle_t sc_ioh;
58 1.1 skrll bus_space_handle_t sc_gpr_ioh;
59 1.1 skrll void *sc_ih;
60 1.1 skrll
61 1.1 skrll u_int sc_tx_level;
62 1.1 skrll u_int sc_tx_boost;
63 1.1 skrll u_int sc_tx_atten;
64 1.1 skrll u_int sc_rx_eq;
65 1.1 skrll u_int sc_ss;
66 1.1 skrll
67 1.1 skrll struct clk *sc_clk_sata;
68 1.1 skrll struct clk *sc_clk_sata_ref;
69 1.1 skrll struct clk *sc_clk_ahb;
70 1.1 skrll };
71 1.1 skrll
72 1.1 skrll static int imx_ahcisata_init(struct imx_ahcisata_softc *);
73 1.1 skrll static int imx_ahcisata_phy_ctrl(struct imx_ahcisata_softc *, uint32_t, int);
74 1.1 skrll static int imx_ahcisata_phy_addr(struct imx_ahcisata_softc *, uint32_t);
75 1.1 skrll static int imx_ahcisata_phy_write(struct imx_ahcisata_softc *, uint32_t, uint16_t);
76 1.1 skrll static int imx_ahcisata_phy_read(struct imx_ahcisata_softc *, uint32_t);
77 1.1 skrll static int imx_ahcisata_init_clocks(struct imx_ahcisata_softc *);
78 1.1 skrll
79 1.1 skrll CFATTACH_DECL_NEW(imx_ahcisata, sizeof(struct imx_ahcisata_softc),
80 1.1 skrll imx_ahcisata_match, imx_ahcisata_attach, NULL, NULL);
81 1.1 skrll
82 1.3 thorpej static const struct device_compatible_entry compat_data[] = {
83 1.3 thorpej { .compat = "fsl,imx6q-ahci" },
84 1.3 thorpej DEVICE_COMPAT_EOL
85 1.3 thorpej };
86 1.3 thorpej
87 1.1 skrll static int
88 1.1 skrll imx_ahcisata_match(device_t parent, cfdata_t cf, void *aux)
89 1.1 skrll {
90 1.1 skrll struct fdt_attach_args * const faa = aux;
91 1.1 skrll
92 1.3 thorpej return of_compatible_match(faa->faa_phandle, compat_data);
93 1.1 skrll }
94 1.1 skrll
95 1.1 skrll static void
96 1.1 skrll imx_ahcisata_attach(device_t parent, device_t self, void *aux)
97 1.1 skrll {
98 1.1 skrll struct imx_ahcisata_softc * const sc = device_private(self);
99 1.1 skrll struct fdt_attach_args * const faa = aux;
100 1.1 skrll const int phandle = faa->faa_phandle;
101 1.1 skrll bus_addr_t ahci_addr;
102 1.1 skrll bus_size_t ahci_size;
103 1.1 skrll bus_addr_t addr;
104 1.1 skrll bus_size_t size;
105 1.1 skrll char intrstr[128];
106 1.1 skrll int error;
107 1.1 skrll
108 1.1 skrll if (fdtbus_get_reg(phandle, 0, &ahci_addr, &ahci_size) != 0) {
109 1.1 skrll aprint_error(": couldn't get ahci registers\n");
110 1.1 skrll return;
111 1.1 skrll }
112 1.1 skrll
113 1.1 skrll if (of_getprop_uint32(phandle, "fsl,transmit-level-mV", &sc->sc_tx_level) != 0)
114 1.1 skrll sc->sc_tx_level = 1104;
115 1.1 skrll if (of_getprop_uint32(phandle, "fsl,transmit-boost-mdB", &sc->sc_tx_boost) != 0)
116 1.1 skrll sc->sc_tx_boost = 3330;
117 1.1 skrll if (of_getprop_uint32(phandle, "fsl,transmit-atten-16ths", &sc->sc_tx_atten) != 0)
118 1.1 skrll sc->sc_tx_atten = 9;
119 1.1 skrll if (of_getprop_uint32(phandle, "fsl,receive-eq-mdB", &sc->sc_rx_eq) != 0)
120 1.1 skrll sc->sc_rx_eq = 3000;
121 1.1 skrll if (of_getprop_bool(phandle, "fsl,no-spread-spectrum") == false)
122 1.1 skrll sc->sc_ss = 1;
123 1.1 skrll else
124 1.1 skrll sc->sc_ss = 0;
125 1.1 skrll
126 1.1 skrll sc->sc_clk_sata = fdtbus_clock_get(phandle, "sata");
127 1.1 skrll if (sc->sc_clk_sata == NULL) {
128 1.1 skrll aprint_error(": couldn't get clock sata\n");
129 1.1 skrll return;
130 1.1 skrll }
131 1.1 skrll sc->sc_clk_sata_ref = fdtbus_clock_get(phandle, "sata_ref");
132 1.1 skrll if (sc->sc_clk_sata_ref == NULL) {
133 1.1 skrll aprint_error(": couldn't get clock sata_ref\n");
134 1.1 skrll return;
135 1.1 skrll }
136 1.1 skrll sc->sc_clk_ahb = fdtbus_clock_get(phandle, "ahb");
137 1.1 skrll if (sc->sc_clk_ahb == NULL) {
138 1.1 skrll aprint_error(": couldn't get clock ahb\n");
139 1.1 skrll return;
140 1.1 skrll }
141 1.1 skrll
142 1.1 skrll aprint_naive("\n");
143 1.1 skrll aprint_normal(": AHCI Controller\n");
144 1.1 skrll
145 1.1 skrll aprint_debug_dev(self, "tx level %d [mV]\n", sc->sc_tx_level);
146 1.1 skrll aprint_debug_dev(self, "tx boost %d [mdB]\n", sc->sc_tx_boost);
147 1.1 skrll aprint_debug_dev(self, "tx atten %d [16ths]\n", sc->sc_tx_atten);
148 1.1 skrll aprint_debug_dev(self, "rx eq %d [mdB]\n", sc->sc_rx_eq);
149 1.1 skrll aprint_debug_dev(self, "ss %d\n", sc->sc_ss);
150 1.1 skrll
151 1.1 skrll sc->sc_dev = self;
152 1.1 skrll
153 1.1 skrll sc->sc.sc_atac.atac_dev = self;
154 1.1 skrll sc->sc.sc_ahci_ports = 1;
155 1.1 skrll sc->sc.sc_dmat = faa->faa_dmat;
156 1.1 skrll sc->sc.sc_ahcit = faa->faa_bst;
157 1.1 skrll sc->sc.sc_ahcis = ahci_size;
158 1.1 skrll error = bus_space_map(sc->sc.sc_ahcit, ahci_addr, ahci_size, 0,
159 1.1 skrll &sc->sc.sc_ahcih);
160 1.1 skrll if (error) {
161 1.1 skrll aprint_error(": couldn't map ahci registers: %d\n", error);
162 1.1 skrll return;
163 1.1 skrll }
164 1.1 skrll
165 1.1 skrll sc->sc_iot = sc->sc.sc_ahcit;
166 1.1 skrll sc->sc_ioh = sc->sc.sc_ahcih;
167 1.1 skrll
168 1.1 skrll const int gpr_phandle = OF_finddevice("/soc/aips-bus/iomuxc-gpr");
169 1.1 skrll fdtbus_get_reg(gpr_phandle, 0, &addr, &size);
170 1.1 skrll if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_gpr_ioh)) {
171 1.1 skrll aprint_error_dev(self, "Cannot map registers\n");
172 1.1 skrll return;
173 1.1 skrll }
174 1.1 skrll
175 1.1 skrll if (imx_ahcisata_init_clocks(sc) != 0) {
176 1.1 skrll aprint_error_dev(self, "couldn't init clocks\n");
177 1.1 skrll return;
178 1.1 skrll }
179 1.1 skrll
180 1.1 skrll if (imx_ahcisata_init(sc) != 0) {
181 1.1 skrll aprint_error_dev(self, "couldn't init ahci\n");
182 1.1 skrll return;
183 1.1 skrll }
184 1.1 skrll
185 1.1 skrll if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
186 1.1 skrll aprint_error_dev(self, "failed to decode interrupt\n");
187 1.1 skrll return;
188 1.1 skrll }
189 1.1 skrll
190 1.2 jmcneill sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 0,
191 1.2 jmcneill ahci_intr, &sc->sc, device_xname(self));
192 1.1 skrll if (sc->sc_ih == NULL) {
193 1.1 skrll aprint_error_dev(self, "failed to establish interrupt on %s\n",
194 1.1 skrll intrstr);
195 1.1 skrll return;
196 1.1 skrll }
197 1.1 skrll aprint_normal_dev(self, "interrupting on %s\n", intrstr);
198 1.1 skrll
199 1.1 skrll ahci_attach(&sc->sc);
200 1.1 skrll }
201 1.1 skrll
202 1.1 skrll static int
203 1.1 skrll imx_ahcisata_phy_ctrl(struct imx_ahcisata_softc *sc, uint32_t bitmask, int on)
204 1.1 skrll {
205 1.1 skrll uint32_t v;
206 1.1 skrll int timeout;
207 1.1 skrll
208 1.1 skrll v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR);
209 1.1 skrll if (on)
210 1.1 skrll v |= bitmask;
211 1.1 skrll else
212 1.1 skrll v &= ~bitmask;
213 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, v);
214 1.1 skrll
215 1.1 skrll for (timeout = 5000; timeout > 0; --timeout) {
216 1.1 skrll v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYSR);
217 1.1 skrll if (!!(v & SATA_P0PHYSR_CR_ACK) == !!on)
218 1.1 skrll break;
219 1.1 skrll delay(100);
220 1.1 skrll }
221 1.1 skrll
222 1.1 skrll if (timeout > 0)
223 1.1 skrll return 0;
224 1.1 skrll
225 1.1 skrll return -1;
226 1.1 skrll }
227 1.1 skrll
228 1.1 skrll static int
229 1.1 skrll imx_ahcisata_phy_addr(struct imx_ahcisata_softc *sc, uint32_t addr)
230 1.1 skrll {
231 1.1 skrll delay(100);
232 1.1 skrll
233 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, addr);
234 1.1 skrll
235 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 1) != 0)
236 1.1 skrll return -1;
237 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 0) != 0)
238 1.1 skrll return -1;
239 1.1 skrll
240 1.1 skrll return 0;
241 1.1 skrll }
242 1.1 skrll
243 1.1 skrll static int
244 1.1 skrll imx_ahcisata_phy_write(struct imx_ahcisata_softc *sc, uint32_t addr,
245 1.1 skrll uint16_t data)
246 1.1 skrll {
247 1.1 skrll if (imx_ahcisata_phy_addr(sc, addr) != 0)
248 1.1 skrll return -1;
249 1.1 skrll
250 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, data);
251 1.1 skrll
252 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 1) != 0)
253 1.1 skrll return -1;
254 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 0) != 0)
255 1.1 skrll return -1;
256 1.1 skrll
257 1.1 skrll if ((addr == SATA_PHY_CLOCK_RESET) && data) {
258 1.1 skrll /* we can't check ACK after RESET */
259 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR,
260 1.1 skrll data | SATA_P0PHYCR_CR_WRITE);
261 1.1 skrll return 0;
262 1.1 skrll }
263 1.1 skrll
264 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 1) != 0)
265 1.1 skrll return -1;
266 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 0) != 0)
267 1.1 skrll return -1;
268 1.1 skrll
269 1.1 skrll return 0;
270 1.1 skrll }
271 1.1 skrll
272 1.1 skrll static int
273 1.1 skrll imx_ahcisata_phy_read(struct imx_ahcisata_softc *sc, uint32_t addr)
274 1.1 skrll {
275 1.1 skrll uint32_t v;
276 1.1 skrll
277 1.1 skrll if (imx_ahcisata_phy_addr(sc, addr) != 0)
278 1.1 skrll return -1;
279 1.1 skrll
280 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 1) != 0)
281 1.1 skrll return -1;
282 1.1 skrll
283 1.1 skrll v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYSR);
284 1.1 skrll
285 1.1 skrll if (imx_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 0) != 0)
286 1.1 skrll return -1;
287 1.1 skrll
288 1.1 skrll return SATA_P0PHYSR_CR_DATA_OUT(v);
289 1.1 skrll }
290 1.1 skrll
291 1.1 skrll const static int tx_level[] = {
292 1.1 skrll 937,
293 1.1 skrll 947,
294 1.1 skrll 957,
295 1.1 skrll 966,
296 1.1 skrll 976,
297 1.1 skrll 986,
298 1.1 skrll 996,
299 1.1 skrll 1005,
300 1.1 skrll 1015,
301 1.1 skrll 1025,
302 1.1 skrll 1035,
303 1.1 skrll 1045,
304 1.1 skrll 1054,
305 1.1 skrll 1064,
306 1.1 skrll 1074,
307 1.1 skrll 1084,
308 1.1 skrll 1094,
309 1.1 skrll 1104,
310 1.1 skrll 1113,
311 1.1 skrll 1123,
312 1.1 skrll 1133,
313 1.1 skrll 1143,
314 1.1 skrll 1152,
315 1.1 skrll 1162,
316 1.1 skrll 1172,
317 1.1 skrll 1182,
318 1.1 skrll 1191,
319 1.1 skrll 1201,
320 1.1 skrll 1211,
321 1.1 skrll 1221,
322 1.1 skrll 1230,
323 1.1 skrll 1240,
324 1.1 skrll };
325 1.1 skrll
326 1.1 skrll const static int tx_boots[] = {
327 1.1 skrll 0,
328 1.1 skrll 370,
329 1.1 skrll 740,
330 1.1 skrll 1110,
331 1.1 skrll 1480,
332 1.1 skrll 1850,
333 1.1 skrll 2220,
334 1.1 skrll 2590,
335 1.1 skrll 2960,
336 1.1 skrll 3330,
337 1.1 skrll 3700,
338 1.1 skrll 4070,
339 1.1 skrll 4440,
340 1.1 skrll 4810,
341 1.1 skrll 5280,
342 1.1 skrll 5750,
343 1.1 skrll };
344 1.1 skrll
345 1.1 skrll const static int tx_atten[] = {
346 1.1 skrll 16,
347 1.1 skrll 14,
348 1.1 skrll 12,
349 1.1 skrll 10,
350 1.1 skrll 9,
351 1.1 skrll 8,
352 1.1 skrll };
353 1.1 skrll
354 1.1 skrll const static int rx_eq[] = {
355 1.1 skrll 500,
356 1.1 skrll 1000,
357 1.1 skrll 1500,
358 1.1 skrll 2000,
359 1.1 skrll 2500,
360 1.1 skrll 3000,
361 1.1 skrll 3500,
362 1.1 skrll 4000,
363 1.1 skrll };
364 1.1 skrll
365 1.1 skrll static int
366 1.1 skrll imx_ahcisata_search_regval(const int *values, int count, int val)
367 1.1 skrll {
368 1.1 skrll for (int i = 0; i < count; i++)
369 1.1 skrll if (values[i] == val)
370 1.1 skrll return i;
371 1.1 skrll
372 1.1 skrll return -1;
373 1.1 skrll }
374 1.1 skrll
375 1.1 skrll static int
376 1.1 skrll imx_ahcisata_init(struct imx_ahcisata_softc *sc)
377 1.1 skrll {
378 1.1 skrll uint32_t v;
379 1.1 skrll int timeout;
380 1.1 skrll int pllstat;
381 1.1 skrll
382 1.1 skrll v = bus_space_read_4(sc->sc_iot, sc->sc_gpr_ioh, IOMUX_GPR13);
383 1.1 skrll /* clear */
384 1.1 skrll v &= ~(IOMUX_GPR13_SATA_PHY_8 |
385 1.1 skrll IOMUX_GPR13_SATA_PHY_7 |
386 1.1 skrll IOMUX_GPR13_SATA_PHY_6 |
387 1.1 skrll IOMUX_GPR13_SATA_SPEED |
388 1.1 skrll IOMUX_GPR13_SATA_PHY_5 |
389 1.1 skrll IOMUX_GPR13_SATA_PHY_4 |
390 1.1 skrll IOMUX_GPR13_SATA_PHY_3 |
391 1.1 skrll IOMUX_GPR13_SATA_PHY_2 |
392 1.1 skrll IOMUX_GPR13_SATA_PHY_1 |
393 1.1 skrll IOMUX_GPR13_SATA_PHY_0);
394 1.1 skrll /* setting */
395 1.1 skrll struct {
396 1.1 skrll const int *array;
397 1.1 skrll int count;
398 1.1 skrll int val;
399 1.1 skrll int def_val;
400 1.1 skrll int mask;
401 1.1 skrll } gpr13_sata_phy_settings[] = {
402 1.1 skrll { tx_level, __arraycount(tx_level), sc->sc_tx_level,
403 1.1 skrll 0x11, IOMUX_GPR13_SATA_PHY_2 },
404 1.1 skrll { tx_boots, __arraycount(tx_boots), sc->sc_tx_boost,
405 1.1 skrll 0x09, IOMUX_GPR13_SATA_PHY_3 },
406 1.1 skrll { tx_atten, __arraycount(tx_atten), sc->sc_tx_atten,
407 1.1 skrll 0x04, IOMUX_GPR13_SATA_PHY_4 },
408 1.1 skrll { rx_eq, __arraycount(rx_eq), sc->sc_rx_eq,
409 1.1 skrll 0x05, IOMUX_GPR13_SATA_PHY_8 }
410 1.1 skrll };
411 1.1 skrll for (int i = 0; i < __arraycount(gpr13_sata_phy_settings); i++) {
412 1.1 skrll int val;
413 1.1 skrll val = imx_ahcisata_search_regval(
414 1.1 skrll gpr13_sata_phy_settings[i].array,
415 1.1 skrll gpr13_sata_phy_settings[i].count,
416 1.1 skrll gpr13_sata_phy_settings[i].val);
417 1.1 skrll if (val == -1)
418 1.1 skrll val = gpr13_sata_phy_settings[i].def_val;
419 1.1 skrll v |= __SHIFTIN(val, gpr13_sata_phy_settings[i].mask);
420 1.1 skrll }
421 1.1 skrll v |= __SHIFTIN(0x12, IOMUX_GPR13_SATA_PHY_7); /* Rx SATA2m */
422 1.1 skrll v |= __SHIFTIN(3, IOMUX_GPR13_SATA_PHY_6); /* Rx DPLL mode */
423 1.1 skrll v |= __SHIFTIN(1, IOMUX_GPR13_SATA_SPEED); /* 3.0GHz */
424 1.1 skrll v |= __SHIFTIN(sc->sc_ss, IOMUX_GPR13_SATA_PHY_5);
425 1.1 skrll v |= __SHIFTIN(1, IOMUX_GPR13_SATA_PHY_1); /* PLL clock enable */
426 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_gpr_ioh, IOMUX_GPR13, v);
427 1.1 skrll
428 1.1 skrll /* phy reset */
429 1.1 skrll if (imx_ahcisata_phy_write(sc, SATA_PHY_CLOCK_RESET,
430 1.1 skrll SATA_PHY_CLOCK_RESET_RST) < 0) {
431 1.1 skrll aprint_error_dev(sc->sc_dev, "cannot reset PHY\n");
432 1.1 skrll return -1;
433 1.1 skrll }
434 1.1 skrll
435 1.1 skrll for (timeout = 50; timeout > 0; --timeout) {
436 1.1 skrll delay(100);
437 1.1 skrll pllstat = imx_ahcisata_phy_read(sc, SATA_PHY_LANE0_OUT_STAT);
438 1.1 skrll if (pllstat < 0) {
439 1.1 skrll aprint_error_dev(sc->sc_dev,
440 1.1 skrll "cannot read LANE0 status\n");
441 1.1 skrll break;
442 1.1 skrll }
443 1.1 skrll if (pllstat & SATA_PHY_LANE0_OUT_STAT_RX_PLL_STATE)
444 1.1 skrll break;
445 1.1 skrll }
446 1.1 skrll if (timeout <= 0)
447 1.1 skrll return -1;
448 1.1 skrll
449 1.1 skrll /* Support Staggered Spin-up */
450 1.1 skrll v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_CAP);
451 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_CAP, v | SATA_CAP_SSS);
452 1.1 skrll
453 1.4 andvar /* Ports Implemented. must set 1 */
454 1.1 skrll v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_PI);
455 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_PI, v | SATA_PI_PI);
456 1.1 skrll
457 1.1 skrll /* set 1ms-timer = AHB clock / 1000 */
458 1.1 skrll bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_TIMER1MS,
459 1.1 skrll clk_get_rate(sc->sc_clk_ahb) / 1000);
460 1.1 skrll
461 1.1 skrll return 0;
462 1.1 skrll }
463 1.1 skrll
464 1.1 skrll static int
465 1.1 skrll imx_ahcisata_init_clocks(struct imx_ahcisata_softc *sc)
466 1.1 skrll {
467 1.1 skrll int error;
468 1.1 skrll
469 1.1 skrll error = clk_enable(sc->sc_clk_sata);
470 1.1 skrll if (error) {
471 1.1 skrll aprint_error_dev(sc->sc_dev, "couldn't enable sata: %d\n", error);
472 1.1 skrll return error;
473 1.1 skrll }
474 1.1 skrll error = clk_enable(sc->sc_clk_sata_ref);
475 1.1 skrll if (error) {
476 1.1 skrll aprint_error_dev(sc->sc_dev, "couldn't enable sata-ref: %d\n", error);
477 1.1 skrll return error;
478 1.1 skrll }
479 1.1 skrll error = clk_enable(sc->sc_clk_ahb);
480 1.1 skrll if (error) {
481 1.1 skrll aprint_error_dev(sc->sc_dev, "couldn't enable anb: %d\n", error);
482 1.1 skrll return error;
483 1.1 skrll }
484 1.1 skrll
485 1.1 skrll return 0;
486 1.1 skrll }
487