FreeBSD/Linux Kernel Cross Reference
sys/arm/mv/mv_sata.c
1 /*-
2 * Copyright (C) 2008-2009 Semihalf
3 * All rights reserved.
4 *
5 * Initial version developed by Ilya Bakulin. Full functionality and bringup
6 * by Piotr Ziecik.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD: releng/8.0/sys/arm/mv/mv_sata.c 194845 2009-06-24 15:41:18Z raj $");
32
33 #include <sys/param.h>
34 #include <sys/bus.h>
35 #include <sys/lock.h>
36 #include <sys/resource.h>
37 #include <sys/systm.h>
38 #include <sys/rman.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/endian.h>
43 #include <sys/sema.h>
44 #include <sys/taskqueue.h>
45 #include <vm/uma.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48
49 #include <sys/ata.h>
50 #include <dev/ata/ata-all.h>
51
52 #include "ata_if.h"
53
54 #include "mvreg.h"
55 #include "mvvar.h"
56
57 /* Useful macros */
58 #define EDMA_TIMEOUT 100000 /* 100 ms */
59 #define SATA_INL(sc, reg) ATA_INL((sc)->sc_mem_res, reg)
60 #define SATA_OUTL(sc, reg, val) ATA_OUTL((sc)->sc_mem_res, reg, val)
61
62 /* HW-related data structures */
63 struct sata_prdentry {
64 uint32_t prd_addrlo;
65 uint32_t prd_count;
66 uint32_t prd_addrhi;
67 uint32_t prd_reserved;
68 };
69
70 struct sata_crqb {
71 uint32_t crqb_prdlo;
72 uint32_t crqb_prdhi;
73 uint32_t crqb_flags;
74 uint16_t crqb_count;
75 uint16_t crqb_reserved1[2];
76 uint8_t crqb_ata_command;
77 uint8_t crqb_ata_feature;
78 uint8_t crqb_ata_lba_low;
79 uint8_t crqb_ata_lba_mid;
80 uint8_t crqb_ata_lba_high;
81 uint8_t crqb_ata_device;
82 uint8_t crqb_ata_lba_low_p;
83 uint8_t crqb_ata_lba_mid_p;
84 uint8_t crqb_ata_lba_high_p;
85 uint8_t crqb_ata_feature_p;
86 uint8_t crqb_ata_count;
87 uint8_t crqb_ata_count_p;
88 uint16_t crqb_reserved2;
89 };
90
91 struct sata_crpb {
92 uint8_t crpb_tag;
93 uint8_t crpb_reserved;
94 uint8_t crpb_edma_status;
95 uint8_t crpb_dev_status;
96 uint32_t crpb_timestamp;
97 };
98
99 /* Identification section. */
100 struct sata_softc {
101 device_t sc_dev;
102 unsigned int sc_version;
103 unsigned int sc_edma_qlen;
104 uint32_t sc_edma_reqis_mask;
105 uint32_t sc_edma_resos_mask;
106 struct resource *sc_mem_res;
107 bus_space_tag_t sc_mem_res_bustag;
108 bus_space_handle_t sc_mem_res_bushdl;
109 struct resource *sc_irq_res;
110 void *sc_irq_cookiep;
111 struct {
112 void (*function)(void *);
113 void *argument;
114 } sc_interrupt[SATA_CHAN_NUM];
115 };
116
117 /* Controller functions */
118 static int sata_probe(device_t dev);
119 static int sata_attach(device_t dev);
120 static int sata_detach(device_t dev);
121 static void sata_intr(void*);
122 static struct resource * sata_alloc_resource(device_t dev, device_t child,
123 int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
124 static int sata_release_resource(device_t dev, device_t child, int type,
125 int rid, struct resource *r);
126 static int sata_setup_intr(device_t dev, device_t child,
127 struct resource *irq, int flags, driver_filter_t *filt,
128 driver_intr_t *function, void *argument, void **cookiep);
129 static int sata_teardown_intr(device_t dev, device_t child,
130 struct resource *irq, void *cookie);
131
132 /* Channel functions */
133 static int sata_channel_probe(device_t dev);
134 static int sata_channel_attach(device_t dev);
135 static int sata_channel_detach(device_t dev);
136 static int sata_channel_begin_transaction(struct ata_request *request);
137 static int sata_channel_end_transaction(struct ata_request *request);
138 static int sata_channel_status(device_t dev);
139 static void sata_channel_setmode(device_t parent, device_t dev);
140 static void sata_channel_reset(device_t dev);
141 static void sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs,
142 int nsegs, int error);
143
144 /* EDMA functions */
145 static int sata_edma_ctrl(device_t dev, int on);
146 static int sata_edma_is_running(device_t);
147
148 static device_method_t sata_methods[] = {
149 /* Device method */
150 DEVMETHOD(device_probe, sata_probe),
151 DEVMETHOD(device_attach, sata_attach),
152 DEVMETHOD(device_detach, sata_detach),
153 DEVMETHOD(device_shutdown, bus_generic_shutdown),
154 DEVMETHOD(device_suspend, bus_generic_suspend),
155 DEVMETHOD(device_resume, bus_generic_resume),
156
157 /* ATA bus methods. */
158 DEVMETHOD(bus_alloc_resource, sata_alloc_resource),
159 DEVMETHOD(bus_release_resource, sata_release_resource),
160 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
161 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
162 DEVMETHOD(bus_setup_intr, sata_setup_intr),
163 DEVMETHOD(bus_teardown_intr, sata_teardown_intr),
164 { 0, 0 },
165 };
166
167 static driver_t sata_driver = {
168 "sata",
169 sata_methods,
170 sizeof(struct sata_softc),
171 };
172
173 devclass_t sata_devclass;
174
175 DRIVER_MODULE(sata, mbus, sata_driver, sata_devclass, 0, 0);
176 MODULE_VERSION(sata, 1);
177 MODULE_DEPEND(sata, ata, 1, 1, 1);
178
179 static int
180 sata_probe(device_t dev)
181 {
182 struct sata_softc *sc;
183 uint32_t d, r;
184
185 soc_id(&d, &r);
186 sc = device_get_softc(dev);
187
188 /* No SATA controller on the 88F5281 SoC */
189 if (d == MV_DEV_88F5281)
190 return (ENXIO);
191
192 switch(d) {
193 case MV_DEV_88F5182:
194 sc->sc_version = 1;
195 sc->sc_edma_qlen = 128;
196 break;
197 case MV_DEV_88F6281:
198 case MV_DEV_MV78100:
199 case MV_DEV_MV78100_Z0:
200 sc->sc_version = 2;
201 sc->sc_edma_qlen = 32;
202 break;
203 default:
204 device_printf(dev, "unsupported SoC (ID: 0x%08X)!\n", d);
205 return (ENXIO);
206 }
207
208 sc->sc_edma_reqis_mask = (sc->sc_edma_qlen - 1) << SATA_EDMA_REQIS_OFS;
209 sc->sc_edma_resos_mask = (sc->sc_edma_qlen - 1) << SATA_EDMA_RESOS_OFS;
210
211 device_set_desc(dev, "Marvell Integrated SATA Controller");
212 return (0);
213 }
214
215 static int
216 sata_attach(device_t dev)
217 {
218 struct sata_softc *sc;
219 int mem_id, irq_id, error, i;
220 device_t ata_chan;
221 uint32_t reg;
222
223 sc = device_get_softc(dev);
224 sc->sc_dev = dev;
225 mem_id = 0;
226 irq_id = 0;
227
228 /* Allocate resources */
229 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
230 &mem_id, RF_ACTIVE);
231 if (sc->sc_mem_res == NULL) {
232 device_printf(dev, "could not allocate memory.\n");
233 return (ENOMEM);
234 }
235
236 sc->sc_mem_res_bustag = rman_get_bustag(sc->sc_mem_res);
237 sc->sc_mem_res_bushdl = rman_get_bushandle(sc->sc_mem_res);
238 KASSERT(sc->sc_mem_res_bustag && sc->sc_mem_res_bushdl,
239 ("cannot get bus handle or tag."));
240
241 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_id,
242 RF_ACTIVE);
243 if (sc->sc_irq_res == NULL) {
244 device_printf(dev, "could not allocate IRQ.\n");
245 error = ENOMEM;
246 goto err;
247 }
248
249 error = bus_setup_intr(dev, sc->sc_irq_res,
250 INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
251 NULL, sata_intr, sc, &sc->sc_irq_cookiep);
252 if (error != 0) {
253 device_printf(dev, "could not setup interrupt.\n");
254 goto err;
255 }
256
257 /* Attach channels */
258 for (i = 0; i < SATA_CHAN_NUM; i++) {
259 ata_chan = device_add_child(dev, "ata",
260 devclass_find_free_unit(ata_devclass, 0));
261
262 if (!ata_chan) {
263 device_printf(dev, "cannot add channel %d.\n", i);
264 error = ENOMEM;
265 goto err;
266 }
267 }
268
269 /* Disable interrupt coalescing */
270 reg = SATA_INL(sc, SATA_CR);
271 for (i = 0; i < SATA_CHAN_NUM; i++)
272 reg |= SATA_CR_COALDIS(i);
273
274 /* Disable DMA byte swapping */
275 if (sc->sc_version == 2)
276 reg |= SATA_CR_NODMABS | SATA_CR_NOEDMABS |
277 SATA_CR_NOPRDPBS;
278
279 SATA_OUTL(sc, SATA_CR, reg);
280
281 /* Clear and mask all interrupts */
282 SATA_OUTL(sc, SATA_ICR, 0);
283 SATA_OUTL(sc, SATA_MIMR, 0);
284
285 return(bus_generic_attach(dev));
286
287 err:
288 sata_detach(dev);
289 return (error);
290 }
291
292 static int
293 sata_detach(device_t dev)
294 {
295 struct sata_softc *sc;
296
297 sc = device_get_softc(dev);
298
299 if (device_is_attached(dev))
300 bus_generic_detach(dev);
301
302 if (sc->sc_mem_res != NULL) {
303 bus_release_resource(dev, SYS_RES_MEMORY,
304 rman_get_rid(sc->sc_mem_res), sc->sc_mem_res);
305 sc->sc_mem_res = NULL;
306 }
307
308 if (sc->sc_irq_res != NULL) {
309 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_cookiep);
310 bus_release_resource(dev, SYS_RES_IRQ,
311 rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
312 sc->sc_irq_res = NULL;
313 }
314
315 return (0);
316 }
317
318 static struct resource *
319 sata_alloc_resource(device_t dev, device_t child, int type, int *rid,
320 u_long start, u_long end, u_long count, u_int flags)
321 {
322 struct sata_softc *sc;
323
324 sc = device_get_softc(dev);
325
326 KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
327 ("illegal resource request (type %u, rid %u).",
328 type, *rid));
329
330 return (sc->sc_irq_res);
331 }
332
333 static int
334 sata_release_resource(device_t dev, device_t child, int type, int rid,
335 struct resource *r)
336 {
337
338 KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
339 ("strange type %u and/or rid %u while releasing resource.", type,
340 rid));
341
342 return (0);
343 }
344
345 static int
346 sata_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
347 driver_filter_t *filt, driver_intr_t *function, void *argument,
348 void **cookiep)
349 {
350 struct sata_softc *sc;
351 struct ata_channel *ch;
352
353 sc = device_get_softc(dev);
354 ch = device_get_softc(child);
355
356 if (filt != NULL) {
357 device_printf(dev, "filter interrupts are not supported.\n");
358 return (EINVAL);
359 }
360
361 sc->sc_interrupt[ch->unit].function = function;
362 sc->sc_interrupt[ch->unit].argument = argument;
363 *cookiep = sc;
364
365 return (0);
366 }
367
368 static int
369 sata_teardown_intr(device_t dev, device_t child, struct resource *irq,
370 void *cookie)
371 {
372 struct sata_softc *sc;
373 struct ata_channel *ch;
374
375 sc = device_get_softc(dev);
376 ch = device_get_softc(child);
377
378 sc->sc_interrupt[ch->unit].function = NULL;
379 sc->sc_interrupt[ch->unit].argument = NULL;
380
381 return (0);
382 }
383
384 static void
385 sata_intr(void *xsc)
386 {
387 struct sata_softc *sc;
388 int unit;
389
390 sc = xsc;
391
392 /*
393 * Behave like ata_generic_intr() for PCI controllers.
394 * Simply invoke ISRs on all channels.
395 */
396 for (unit = 0; unit < SATA_CHAN_NUM; unit++)
397 if (sc->sc_interrupt[unit].function != NULL)
398 sc->sc_interrupt[unit].function(
399 sc->sc_interrupt[unit].argument);
400 }
401
402 static int
403 sata_channel_probe(device_t dev)
404 {
405
406 device_set_desc(dev, "Marvell Integrated SATA Channel");
407 return (ata_probe(dev));
408 }
409
410 static int
411 sata_channel_attach(device_t dev)
412 {
413 struct sata_softc *sc;
414 struct ata_channel *ch;
415 uint64_t work;
416 int error, i;
417
418 sc = device_get_softc(device_get_parent(dev));
419 ch = device_get_softc(dev);
420
421 if (ch->attached)
422 return (0);
423
424 ch->dev = dev;
425 ch->unit = device_get_unit(dev);
426 ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE;
427
428 /* Set legacy ATA resources. */
429 for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
430 ch->r_io[i].res = sc->sc_mem_res;
431 ch->r_io[i].offset = SATA_SHADOWR_BASE(ch->unit) + (i << 2);
432 }
433
434 ch->r_io[ATA_CONTROL].res = sc->sc_mem_res;
435 ch->r_io[ATA_CONTROL].offset = SATA_SHADOWR_CONTROL(ch->unit);
436
437 ch->r_io[ATA_IDX_ADDR].res = sc->sc_mem_res;
438 ata_default_registers(dev);
439
440 /* Set SATA resources. */
441 ch->r_io[ATA_SSTATUS].res = sc->sc_mem_res;
442 ch->r_io[ATA_SSTATUS].offset = SATA_SATA_SSTATUS(ch->unit);
443 ch->r_io[ATA_SERROR].res = sc->sc_mem_res;
444 ch->r_io[ATA_SERROR].offset = SATA_SATA_SERROR(ch->unit);
445 ch->r_io[ATA_SCONTROL].res = sc->sc_mem_res;
446 ch->r_io[ATA_SCONTROL].offset = SATA_SATA_SCONTROL(ch->unit);
447 ata_generic_hw(dev);
448
449 ch->hw.begin_transaction = sata_channel_begin_transaction;
450 ch->hw.end_transaction = sata_channel_end_transaction;
451 ch->hw.status = sata_channel_status;
452
453 /* Set DMA resources */
454 ata_dmainit(dev);
455 ch->dma.setprd = sata_channel_dmasetprd;
456
457 /* Clear work area */
458 KASSERT(sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
459 sizeof(struct sata_crpb)) <= ch->dma.max_iosize,
460 ("insufficient DMA memory for request/response queues.\n"));
461 bzero(ch->dma.work, sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
462 sizeof(struct sata_crpb)));
463 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
464 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
465
466 /* Turn off EDMA engine */
467 error = sata_edma_ctrl(dev, 0);
468 if (error) {
469 ata_dmafini(dev);
470 return (error);
471 }
472
473 /*
474 * Initialize EDMA engine:
475 * - Native Command Queuing off,
476 * - Non-Queued operation,
477 * - Host Queue Cache enabled.
478 */
479 SATA_OUTL(sc, SATA_EDMA_CFG(ch->unit), SATA_EDMA_CFG_HQCACHE |
480 (sc->sc_version == 1) ? SATA_EDMA_CFG_QL128 : 0);
481
482 /* Set request queue pointers */
483 work = ch->dma.work_bus;
484 SATA_OUTL(sc, SATA_EDMA_REQBAHR(ch->unit), work >> 32);
485 SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), work & 0xFFFFFFFF);
486 SATA_OUTL(sc, SATA_EDMA_REQOPR(ch->unit), work & 0xFFFFFFFF);
487
488 /* Set response queue pointers */
489 work += sc->sc_edma_qlen * sizeof(struct sata_crqb);
490 SATA_OUTL(sc, SATA_EDMA_RESBAHR(ch->unit), work >> 32);
491 SATA_OUTL(sc, SATA_EDMA_RESIPR(ch->unit), work & 0xFFFFFFFF);
492 SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), work & 0xFFFFFFFF);
493
494 /* Clear any outstanding interrupts */
495 ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
496 SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
497 SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
498 SATA_OUTL(sc, SATA_ICR,
499 ~(SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit)));
500
501 /* Umask channel interrupts */
502 SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
503 SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) |
504 SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
505 SATA_MICR_ERR(ch->unit));
506
507 ch->attached = 1;
508
509 return (ata_attach(dev));
510 }
511
512 static int
513 sata_channel_detach(device_t dev)
514 {
515 struct sata_softc *sc;
516 struct ata_channel *ch;
517 int error;
518
519 sc = device_get_softc(device_get_parent(dev));
520 ch = device_get_softc(dev);
521
522 if (!ch->attached)
523 return (0);
524
525 /* Turn off EDMA engine */
526 sata_edma_ctrl(dev, 0);
527
528 /* Mask chanel interrupts */
529 SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0);
530 SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) & ~(
531 SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
532 SATA_MICR_ERR(ch->unit)));
533
534 error = ata_detach(dev);
535 ata_dmafini(dev);
536
537 ch->attached = 0;
538
539 return (error);
540 }
541
542 static int
543 sata_channel_begin_transaction(struct ata_request *request)
544 {
545 struct sata_softc *sc;
546 struct ata_channel *ch;
547 struct sata_crqb *crqb;
548 uint32_t req_in;
549 int error, slot;
550
551 sc = device_get_softc(GRANDPARENT(request->dev));
552 ch = device_get_softc(request->parent);
553
554 mtx_assert(&ch->state_mtx, MA_OWNED);
555
556 /* Only DMA R/W goes through the EDMA machine. */
557 if (request->u.ata.command != ATA_READ_DMA &&
558 request->u.ata.command != ATA_WRITE_DMA) {
559
560 /* Disable EDMA before accessing legacy registers */
561 if (sata_edma_is_running(request->parent)) {
562 error = sata_edma_ctrl(request->parent, 0);
563 if (error) {
564 request->result = error;
565 return (ATA_OP_FINISHED);
566 }
567 }
568
569 return (ata_begin_transaction(request));
570 }
571
572 /* Check for 48 bit access and convert if needed */
573 ata_modify_if_48bit(request);
574
575 /* Prepare data for DMA */
576 if ((error = ch->dma.load(request, NULL, NULL))) {
577 device_printf(request->dev, "setting up DMA failed!\n");
578 request->result = error;
579 return ATA_OP_FINISHED;
580 }
581
582 /* Get next free queue slot */
583 req_in = SATA_INL(sc, SATA_EDMA_REQIPR(ch->unit));
584 slot = (req_in & sc->sc_edma_reqis_mask) >> SATA_EDMA_REQIS_OFS;
585 crqb = (struct sata_crqb *)(ch->dma.work +
586 (slot << SATA_EDMA_REQIS_OFS));
587
588 /* Fill in request */
589 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
590 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
591
592 crqb->crqb_prdlo = htole32((uint64_t)request->dma->sg_bus & 0xFFFFFFFF);
593 crqb->crqb_prdhi = htole32((uint64_t)request->dma->sg_bus >> 32);
594 crqb->crqb_flags = htole32((request->flags & ATA_R_READ ? 0x01 : 0x00) |
595 (request->tag << 1));
596
597 crqb->crqb_ata_command = request->u.ata.command;
598 crqb->crqb_ata_feature = request->u.ata.feature;
599 crqb->crqb_ata_lba_low = request->u.ata.lba;
600 crqb->crqb_ata_lba_mid = request->u.ata.lba >> 8;
601 crqb->crqb_ata_lba_high = request->u.ata.lba >> 16;
602 crqb->crqb_ata_device = ((request->u.ata.lba >> 24) & 0x0F) | (1 << 6);
603 crqb->crqb_ata_count = request->u.ata.count;
604
605 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
606 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
607
608 /* Enable EDMA if disabled */
609 if (!sata_edma_is_running(request->parent)) {
610 error = sata_edma_ctrl(request->parent, 1);
611 if (error) {
612 ch->dma.unload(request);
613 request->result = error;
614 return (ATA_OP_FINISHED);
615 }
616 }
617
618 /* Tell EDMA about new request */
619 req_in = (req_in & ~sc->sc_edma_reqis_mask) | (((slot + 1) <<
620 SATA_EDMA_REQIS_OFS) & sc->sc_edma_reqis_mask);
621
622 SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), req_in);
623
624 return (ATA_OP_CONTINUES);
625 }
626
627 static int
628 sata_channel_end_transaction(struct ata_request *request)
629 {
630 struct sata_softc *sc;
631 struct ata_channel *ch;
632 struct sata_crpb *crpb;
633 uint32_t res_in, res_out, icr;
634 int slot;
635
636 sc = device_get_softc(GRANDPARENT(request->dev));
637 ch = device_get_softc(request->parent);
638
639 mtx_assert(&ch->state_mtx, MA_OWNED);
640
641 icr = SATA_INL(sc, SATA_ICR);
642 if (icr & SATA_ICR_DMADONE(ch->unit)) {
643 /* Get current response slot */
644 res_out = SATA_INL(sc, SATA_EDMA_RESOPR(ch->unit));
645 slot = (res_out & sc->sc_edma_resos_mask) >>
646 SATA_EDMA_RESOS_OFS;
647 crpb = (struct sata_crpb *)(ch->dma.work +
648 (sc->sc_edma_qlen * sizeof(struct sata_crqb)) +
649 (slot << SATA_EDMA_RESOS_OFS));
650
651 /* Record this request status */
652 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
653 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
654
655 request->status = crpb->crpb_dev_status;
656 request->error = 0;
657
658 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
659 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
660
661 /* Update response queue pointer */
662 res_out = (res_out & ~sc->sc_edma_resos_mask) | (((slot + 1) <<
663 SATA_EDMA_RESOS_OFS) & sc->sc_edma_resos_mask);
664
665 SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), res_out);
666
667 /* Ack DMA interrupt if there is nothing more to do */
668 res_in = SATA_INL(sc, SATA_EDMA_RESIPR(ch->unit));
669 res_in &= sc->sc_edma_resos_mask;
670 res_out &= sc->sc_edma_resos_mask;
671
672 if (res_in == res_out)
673 SATA_OUTL(sc, SATA_ICR,
674 ~SATA_ICR_DMADONE(ch->unit));
675
676 /* Update progress */
677 if (!(request->status & ATA_S_ERROR) &&
678 !(request->flags & ATA_R_TIMEOUT))
679 request->donecount = request->bytecount;
680
681 /* Unload DMA data */
682 ch->dma.unload(request);
683
684 return(ATA_OP_FINISHED);
685 }
686
687 /* Legacy ATA interrupt */
688 return (ata_end_transaction(request));
689 }
690
691 static int
692 sata_channel_status(device_t dev)
693 {
694 struct sata_softc *sc;
695 struct ata_channel *ch;
696 uint32_t icr, iecr;
697
698 sc = device_get_softc(device_get_parent(dev));
699 ch = device_get_softc(dev);
700
701 icr = SATA_INL(sc, SATA_ICR);
702 iecr = SATA_INL(sc, SATA_EDMA_IECR(ch->unit));
703
704 if ((icr & SATA_ICR_DEV(ch->unit)) || iecr) {
705 /* Disable EDMA before accessing SATA registers */
706 sata_edma_ctrl(dev, 0);
707 ata_sata_phy_check_events(dev);
708
709 /* Ack device and error interrupt */
710 SATA_OUTL(sc, SATA_ICR, ~SATA_ICR_DEV(ch->unit));
711 SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
712 }
713
714 icr &= SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit);
715 return (icr);
716 }
717
718 static void
719 sata_channel_reset(device_t dev)
720 {
721 struct sata_softc *sc;
722 struct ata_channel *ch;
723
724 sc = device_get_softc(device_get_parent(dev));
725 ch = device_get_softc(dev);
726
727 /* Disable EDMA before using legacy registers */
728 sata_edma_ctrl(dev, 0);
729
730 /* Mask all EDMA interrups */
731 SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0);
732
733 /* Reset EDMA */
734 SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), SATA_EDMA_CMD_RESET);
735 DELAY(25);
736 SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), 0);
737
738 /* Reset PHY and device */
739 if (ata_sata_phy_reset(dev, -1, 1))
740 ata_generic_reset(dev);
741 else
742 ch->devices = 0;
743
744 /* Clear EDMA errors */
745 SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
746 SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
747
748 /* Unmask all EDMA interrups */
749 SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
750 }
751
752 static void
753 sata_channel_setmode(device_t parent, device_t dev)
754 {
755 struct ata_device *atadev;
756
757 atadev = device_get_softc(dev);
758
759 /* Disable EDMA before using legacy registers */
760 sata_edma_ctrl(parent, 0);
761
762 ata_sata_setmode(dev, ATA_PIO_MAX);
763 if (atadev->mode >= ATA_DMA)
764 ata_sata_setmode(dev, atadev->mode);
765 }
766
767 static void
768 sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs,
769 int error)
770 {
771 struct ata_dmasetprd_args *args;
772 struct sata_prdentry *prd;
773 int i;
774
775 args = xsc;
776 prd = args->dmatab;
777
778 if ((args->error = error))
779 return;
780
781 for (i = 0; i < nsegs; i++) {
782 prd[i].prd_addrlo = htole32(segs[i].ds_addr);
783 prd[i].prd_addrhi = htole32((uint64_t)segs[i].ds_addr >> 32);
784 prd[i].prd_count = htole32(segs[i].ds_len);
785 }
786
787 prd[i - 1].prd_count |= htole32(ATA_DMA_EOT);
788 KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries.\n"));
789 args->nsegs = nsegs;
790 }
791
792 static int
793 sata_edma_ctrl(device_t dev, int on)
794 {
795 struct sata_softc *sc;
796 struct ata_channel *ch;
797 int bit, timeout;
798 uint32_t reg;
799
800 sc = device_get_softc(device_get_parent(dev));
801 ch = device_get_softc(dev);
802 bit = on ? SATA_EDMA_CMD_ENABLE : SATA_EDMA_CMD_DISABLE;
803 timeout = EDMA_TIMEOUT;
804
805 SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), bit);
806
807 while (1) {
808 DELAY(1);
809
810 reg = SATA_INL(sc, SATA_EDMA_CMD(ch->unit));
811
812 /* Enable bit will be 1 after disable command completion */
813 if (on && (reg & SATA_EDMA_CMD_ENABLE))
814 break;
815
816 /* Disable bit will be 0 after disable command completion */
817 if (!on && !(reg & SATA_EDMA_CMD_DISABLE))
818 break;
819
820 if (timeout-- <= 0) {
821 device_printf(dev, "EDMA command timeout!\n");
822 return (ETIMEDOUT);
823 }
824 }
825
826 return (0);
827 }
828
829 static int
830 sata_edma_is_running(device_t dev)
831 {
832 struct sata_softc *sc;
833 struct ata_channel *ch;
834
835 sc = device_get_softc(device_get_parent(dev));
836 ch = device_get_softc(dev);
837
838 return (SATA_INL(sc, SATA_EDMA_CMD(ch->unit)) & SATA_EDMA_CMD_ENABLE);
839 }
840
841 static device_method_t sata_channel_methods[] = {
842 /* Device interface. */
843 DEVMETHOD(device_probe, sata_channel_probe),
844 DEVMETHOD(device_attach, sata_channel_attach),
845 DEVMETHOD(device_detach, sata_channel_detach),
846 DEVMETHOD(device_shutdown, bus_generic_shutdown),
847 DEVMETHOD(device_suspend, ata_suspend),
848 DEVMETHOD(device_resume, ata_resume),
849
850 /* ATA channel interface */
851 DEVMETHOD(ata_reset, sata_channel_reset),
852 DEVMETHOD(ata_setmode, sata_channel_setmode),
853 { 0, 0 }
854 };
855
856 driver_t sata_channel_driver = {
857 "ata",
858 sata_channel_methods,
859 sizeof(struct ata_channel),
860 };
861
862 DRIVER_MODULE(ata, sata, sata_channel_driver, ata_devclass, 0, 0);
Cache object: 4f817c1e583e5136966f18dbc30eed26
|