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