1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/init.h>
4#include <linux/blkdev.h>
5#include <scsi/scsi_host.h>
6#include <linux/ata.h>
7#include <linux/libata.h>
8
9#include <asm/dma.h>
10#include <asm/ecard.h>
11
12#define DRV_NAME "pata_icside"
13
14#define ICS_IDENT_OFFSET 0x2280
15
16#define ICS_ARCIN_V5_INTRSTAT 0x0000
17#define ICS_ARCIN_V5_INTROFFSET 0x0004
18
19#define ICS_ARCIN_V6_INTROFFSET_1 0x2200
20#define ICS_ARCIN_V6_INTRSTAT_1 0x2290
21#define ICS_ARCIN_V6_INTROFFSET_2 0x3200
22#define ICS_ARCIN_V6_INTRSTAT_2 0x3290
23
24struct portinfo {
25 unsigned int dataoffset;
26 unsigned int ctrloffset;
27 unsigned int stepping;
28};
29
30static const struct portinfo pata_icside_portinfo_v5 = {
31 .dataoffset = 0x2800,
32 .ctrloffset = 0x2b80,
33 .stepping = 6,
34};
35
36static const struct portinfo pata_icside_portinfo_v6_1 = {
37 .dataoffset = 0x2000,
38 .ctrloffset = 0x2380,
39 .stepping = 6,
40};
41
42static const struct portinfo pata_icside_portinfo_v6_2 = {
43 .dataoffset = 0x3000,
44 .ctrloffset = 0x3380,
45 .stepping = 6,
46};
47
48#define PATA_ICSIDE_MAX_SG 128
49
50struct pata_icside_state {
51 void __iomem *irq_port;
52 void __iomem *ioc_base;
53 unsigned int type;
54 unsigned int dma;
55 struct {
56 u8 port_sel;
57 u8 disabled;
58 unsigned int speed[ATA_MAX_DEVICES];
59 } port[2];
60 struct scatterlist sg[PATA_ICSIDE_MAX_SG];
61};
62
63struct pata_icside_info {
64 struct pata_icside_state *state;
65 struct expansion_card *ec;
66 void __iomem *base;
67 void __iomem *irqaddr;
68 unsigned int irqmask;
69 const expansioncard_ops_t *irqops;
70 unsigned int mwdma_mask;
71 unsigned int nr_ports;
72 const struct portinfo *port[2];
73 unsigned long raw_base;
74 unsigned long raw_ioc_base;
75};
76
77#define ICS_TYPE_A3IN 0
78#define ICS_TYPE_A3USER 1
79#define ICS_TYPE_V6 3
80#define ICS_TYPE_V5 15
81#define ICS_TYPE_NOTYPE ((unsigned int)-1)
82
83
84
85
86
87static void pata_icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
88{
89 struct pata_icside_state *state = ec->irq_data;
90
91 writeb(0, state->irq_port + ICS_ARCIN_V5_INTROFFSET);
92}
93
94
95
96
97static void pata_icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
98{
99 struct pata_icside_state *state = ec->irq_data;
100
101 readb(state->irq_port + ICS_ARCIN_V5_INTROFFSET);
102}
103
104static const expansioncard_ops_t pata_icside_ops_arcin_v5 = {
105 .irqenable = pata_icside_irqenable_arcin_v5,
106 .irqdisable = pata_icside_irqdisable_arcin_v5,
107};
108
109
110
111
112
113
114static void pata_icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
115{
116 struct pata_icside_state *state = ec->irq_data;
117 void __iomem *base = state->irq_port;
118
119 if (!state->port[0].disabled)
120 writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
121 if (!state->port[1].disabled)
122 writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
123}
124
125
126
127
128static void pata_icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
129{
130 struct pata_icside_state *state = ec->irq_data;
131
132 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
133 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
134}
135
136
137
138
139static int pata_icside_irqpending_arcin_v6(struct expansion_card *ec)
140{
141 struct pata_icside_state *state = ec->irq_data;
142
143 return readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
144 readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
145}
146
147static const expansioncard_ops_t pata_icside_ops_arcin_v6 = {
148 .irqenable = pata_icside_irqenable_arcin_v6,
149 .irqdisable = pata_icside_irqdisable_arcin_v6,
150 .irqpending = pata_icside_irqpending_arcin_v6,
151};
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189static void pata_icside_set_dmamode(struct ata_port *ap, struct ata_device *adev)
190{
191 struct pata_icside_state *state = ap->host->private_data;
192 struct ata_timing t;
193 unsigned int cycle;
194 char iomd_type;
195
196
197
198
199 if (ata_timing_compute(adev, adev->dma_mode, &t, 1000, 1))
200 return;
201
202
203
204
205
206 if (t.active <= 50 && t.recover <= 375 && t.cycle <= 425)
207 iomd_type = 'D', cycle = 187;
208 else if (t.active <= 125 && t.recover <= 375 && t.cycle <= 500)
209 iomd_type = 'C', cycle = 250;
210 else if (t.active <= 200 && t.recover <= 550 && t.cycle <= 750)
211 iomd_type = 'B', cycle = 437;
212 else
213 iomd_type = 'A', cycle = 562;
214
215 ata_dev_printk(adev, KERN_INFO, "timings: act %dns rec %dns cyc %dns (%c)\n",
216 t.active, t.recover, t.cycle, iomd_type);
217
218 state->port[ap->port_no].speed[adev->devno] = cycle;
219}
220
221static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
222{
223 struct ata_port *ap = qc->ap;
224 struct pata_icside_state *state = ap->host->private_data;
225 struct scatterlist *sg, *rsg = state->sg;
226 unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE;
227
228
229
230
231
232 BUG_ON(dma_channel_active(state->dma));
233
234
235
236
237 ata_for_each_sg(sg, qc) {
238 memcpy(rsg, sg, sizeof(*sg));
239 rsg++;
240 }
241
242
243
244
245 writeb(state->port[ap->port_no].port_sel, state->ioc_base);
246
247 set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]);
248 set_dma_sg(state->dma, state->sg, rsg - state->sg);
249 set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ);
250
251
252 ap->ops->exec_command(ap, &qc->tf);
253}
254
255static void pata_icside_bmdma_start(struct ata_queued_cmd *qc)
256{
257 struct ata_port *ap = qc->ap;
258 struct pata_icside_state *state = ap->host->private_data;
259
260 BUG_ON(dma_channel_active(state->dma));
261 enable_dma(state->dma);
262}
263
264static void pata_icside_bmdma_stop(struct ata_queued_cmd *qc)
265{
266 struct ata_port *ap = qc->ap;
267 struct pata_icside_state *state = ap->host->private_data;
268
269 disable_dma(state->dma);
270
271
272 ata_altstatus(ap);
273}
274
275static u8 pata_icside_bmdma_status(struct ata_port *ap)
276{
277 struct pata_icside_state *state = ap->host->private_data;
278 void __iomem *irq_port;
279
280 irq_port = state->irq_port + (ap->port_no ? ICS_ARCIN_V6_INTRSTAT_2 :
281 ICS_ARCIN_V6_INTRSTAT_1);
282
283 return readb(irq_port) & 1 ? ATA_DMA_INTR : 0;
284}
285
286static int icside_dma_init(struct pata_icside_info *info)
287{
288 struct pata_icside_state *state = info->state;
289 struct expansion_card *ec = info->ec;
290 int i;
291
292 for (i = 0; i < ATA_MAX_DEVICES; i++) {
293 state->port[0].speed[i] = 480;
294 state->port[1].speed[i] = 480;
295 }
296
297 if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
298 state->dma = ec->dma;
299 info->mwdma_mask = 0x07;
300 }
301
302 return 0;
303}
304
305
306static int pata_icside_port_start(struct ata_port *ap)
307{
308
309 return ata_pad_alloc(ap, ap->dev);
310}
311
312static struct scsi_host_template pata_icside_sht = {
313 .module = THIS_MODULE,
314 .name = DRV_NAME,
315 .ioctl = ata_scsi_ioctl,
316 .queuecommand = ata_scsi_queuecmd,
317 .can_queue = ATA_DEF_QUEUE,
318 .this_id = ATA_SHT_THIS_ID,
319 .sg_tablesize = PATA_ICSIDE_MAX_SG,
320 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
321 .emulated = ATA_SHT_EMULATED,
322 .use_clustering = ATA_SHT_USE_CLUSTERING,
323 .proc_name = DRV_NAME,
324 .dma_boundary = ~0,
325 .slave_configure = ata_scsi_slave_config,
326 .slave_destroy = ata_scsi_slave_destroy,
327 .bios_param = ata_std_bios_param,
328};
329
330
331static void ata_dummy_noret(struct ata_port *port)
332{
333}
334
335static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
336{
337 struct ata_port *ap = link->ap;
338 struct pata_icside_state *state = ap->host->private_data;
339
340 if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE)
341 return ata_std_postreset(link, classes);
342
343 state->port[ap->port_no].disabled = 1;
344
345 if (state->type == ICS_TYPE_V6) {
346
347
348
349
350
351 void __iomem *irq_port = state->irq_port +
352 (ap->port_no ? ICS_ARCIN_V6_INTROFFSET_2 : ICS_ARCIN_V6_INTROFFSET_1);
353 readb(irq_port);
354 }
355}
356
357static void pata_icside_error_handler(struct ata_port *ap)
358{
359 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
360 pata_icside_postreset);
361}
362
363static struct ata_port_operations pata_icside_port_ops = {
364 .set_dmamode = pata_icside_set_dmamode,
365
366 .tf_load = ata_tf_load,
367 .tf_read = ata_tf_read,
368 .exec_command = ata_exec_command,
369 .check_status = ata_check_status,
370 .dev_select = ata_std_dev_select,
371
372 .cable_detect = ata_cable_40wire,
373
374 .bmdma_setup = pata_icside_bmdma_setup,
375 .bmdma_start = pata_icside_bmdma_start,
376
377 .data_xfer = ata_data_xfer_noirq,
378
379
380 .qc_prep = ata_noop_qc_prep,
381 .qc_issue = ata_qc_issue_prot,
382
383 .freeze = ata_bmdma_freeze,
384 .thaw = ata_bmdma_thaw,
385 .error_handler = pata_icside_error_handler,
386 .post_internal_cmd = pata_icside_bmdma_stop,
387
388 .irq_clear = ata_dummy_noret,
389 .irq_on = ata_irq_on,
390
391 .port_start = pata_icside_port_start,
392
393 .bmdma_stop = pata_icside_bmdma_stop,
394 .bmdma_status = pata_icside_bmdma_status,
395};
396
397static void __devinit
398pata_icside_setup_ioaddr(struct ata_port *ap, void __iomem *base,
399 struct pata_icside_info *info,
400 const struct portinfo *port)
401{
402 struct ata_ioports *ioaddr = &ap->ioaddr;
403 void __iomem *cmd = base + port->dataoffset;
404
405 ioaddr->cmd_addr = cmd;
406 ioaddr->data_addr = cmd + (ATA_REG_DATA << port->stepping);
407 ioaddr->error_addr = cmd + (ATA_REG_ERR << port->stepping);
408 ioaddr->feature_addr = cmd + (ATA_REG_FEATURE << port->stepping);
409 ioaddr->nsect_addr = cmd + (ATA_REG_NSECT << port->stepping);
410 ioaddr->lbal_addr = cmd + (ATA_REG_LBAL << port->stepping);
411 ioaddr->lbam_addr = cmd + (ATA_REG_LBAM << port->stepping);
412 ioaddr->lbah_addr = cmd + (ATA_REG_LBAH << port->stepping);
413 ioaddr->device_addr = cmd + (ATA_REG_DEVICE << port->stepping);
414 ioaddr->status_addr = cmd + (ATA_REG_STATUS << port->stepping);
415 ioaddr->command_addr = cmd + (ATA_REG_CMD << port->stepping);
416
417 ioaddr->ctl_addr = base + port->ctrloffset;
418 ioaddr->altstatus_addr = ioaddr->ctl_addr;
419
420 ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
421 info->raw_base + port->dataoffset,
422 info->raw_base + port->ctrloffset);
423
424 if (info->raw_ioc_base)
425 ata_port_desc(ap, "iocbase 0x%lx", info->raw_ioc_base);
426}
427
428static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
429{
430 struct pata_icside_state *state = info->state;
431 void __iomem *base;
432
433 base = ecardm_iomap(info->ec, ECARD_RES_MEMC, 0, 0);
434 if (!base)
435 return -ENOMEM;
436
437 state->irq_port = base;
438
439 info->base = base;
440 info->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
441 info->irqmask = 1;
442 info->irqops = &pata_icside_ops_arcin_v5;
443 info->nr_ports = 1;
444 info->port[0] = &pata_icside_portinfo_v5;
445
446 info->raw_base = ecard_resource_start(info->ec, ECARD_RES_MEMC);
447
448 return 0;
449}
450
451static int __devinit pata_icside_register_v6(struct pata_icside_info *info)
452{
453 struct pata_icside_state *state = info->state;
454 struct expansion_card *ec = info->ec;
455 void __iomem *ioc_base, *easi_base;
456 unsigned int sel = 0;
457
458 ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
459 if (!ioc_base)
460 return -ENOMEM;
461
462 easi_base = ioc_base;
463
464 if (ecard_resource_flags(ec, ECARD_RES_EASI)) {
465 easi_base = ecardm_iomap(ec, ECARD_RES_EASI, 0, 0);
466 if (!easi_base)
467 return -ENOMEM;
468
469
470
471
472 sel = 1 << 5;
473 }
474
475 writeb(sel, ioc_base);
476
477 state->irq_port = easi_base;
478 state->ioc_base = ioc_base;
479 state->port[0].port_sel = sel;
480 state->port[1].port_sel = sel | 1;
481
482 info->base = easi_base;
483 info->irqops = &pata_icside_ops_arcin_v6;
484 info->nr_ports = 2;
485 info->port[0] = &pata_icside_portinfo_v6_1;
486 info->port[1] = &pata_icside_portinfo_v6_2;
487
488 info->raw_base = ecard_resource_start(ec, ECARD_RES_EASI);
489 info->raw_ioc_base = ecard_resource_start(ec, ECARD_RES_IOCFAST);
490
491 return icside_dma_init(info);
492}
493
494static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
495{
496 struct expansion_card *ec = info->ec;
497 struct ata_host *host;
498 int i;
499
500 if (info->irqaddr) {
501 ec->irqaddr = info->irqaddr;
502 ec->irqmask = info->irqmask;
503 }
504 if (info->irqops)
505 ecard_setirq(ec, info->irqops, info->state);
506
507
508
509
510 ec->ops->irqdisable(ec, ec->irq);
511
512 host = ata_host_alloc(&ec->dev, info->nr_ports);
513 if (!host)
514 return -ENOMEM;
515
516 host->private_data = info->state;
517 host->flags = ATA_HOST_SIMPLEX;
518
519 for (i = 0; i < info->nr_ports; i++) {
520 struct ata_port *ap = host->ports[i];
521
522 ap->pio_mask = 0x1f;
523 ap->mwdma_mask = info->mwdma_mask;
524 ap->flags |= ATA_FLAG_SLAVE_POSS;
525 ap->ops = &pata_icside_port_ops;
526
527 pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]);
528 }
529
530 return ata_host_activate(host, ec->irq, ata_interrupt, 0,
531 &pata_icside_sht);
532}
533
534static int __devinit
535pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id)
536{
537 struct pata_icside_state *state;
538 struct pata_icside_info info;
539 void __iomem *idmem;
540 int ret;
541
542 ret = ecard_request_resources(ec);
543 if (ret)
544 goto out;
545
546 state = devm_kzalloc(&ec->dev, sizeof(*state), GFP_KERNEL);
547 if (!state) {
548 ret = -ENOMEM;
549 goto release;
550 }
551
552 state->type = ICS_TYPE_NOTYPE;
553 state->dma = NO_DMA;
554
555 idmem = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
556 if (idmem) {
557 unsigned int type;
558
559 type = readb(idmem + ICS_IDENT_OFFSET) & 1;
560 type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1;
561 type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2;
562 type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3;
563 ecardm_iounmap(ec, idmem);
564
565 state->type = type;
566 }
567
568 memset(&info, 0, sizeof(info));
569 info.state = state;
570 info.ec = ec;
571
572 switch (state->type) {
573 case ICS_TYPE_A3IN:
574 dev_warn(&ec->dev, "A3IN unsupported\n");
575 ret = -ENODEV;
576 break;
577
578 case ICS_TYPE_A3USER:
579 dev_warn(&ec->dev, "A3USER unsupported\n");
580 ret = -ENODEV;
581 break;
582
583 case ICS_TYPE_V5:
584 ret = pata_icside_register_v5(&info);
585 break;
586
587 case ICS_TYPE_V6:
588 ret = pata_icside_register_v6(&info);
589 break;
590
591 default:
592 dev_warn(&ec->dev, "unknown interface type\n");
593 ret = -ENODEV;
594 break;
595 }
596
597 if (ret == 0)
598 ret = pata_icside_add_ports(&info);
599
600 if (ret == 0)
601 goto out;
602
603 release:
604 ecard_release_resources(ec);
605 out:
606 return ret;
607}
608
609static void pata_icside_shutdown(struct expansion_card *ec)
610{
611 struct ata_host *host = ecard_get_drvdata(ec);
612 unsigned long flags;
613
614
615
616
617
618
619 local_irq_save(flags);
620 ec->ops->irqdisable(ec, ec->irq);
621 local_irq_restore(flags);
622
623
624
625
626
627
628 if (host) {
629 struct pata_icside_state *state = host->private_data;
630 if (state->ioc_base)
631 writeb(0, state->ioc_base);
632 }
633}
634
635static void __devexit pata_icside_remove(struct expansion_card *ec)
636{
637 struct ata_host *host = ecard_get_drvdata(ec);
638 struct pata_icside_state *state = host->private_data;
639
640 ata_host_detach(host);
641
642 pata_icside_shutdown(ec);
643
644
645
646
647
648 if (state->dma != NO_DMA)
649 free_dma(state->dma);
650
651 ecard_release_resources(ec);
652}
653
654static const struct ecard_id pata_icside_ids[] = {
655 { MANU_ICS, PROD_ICS_IDE },
656 { MANU_ICS2, PROD_ICS2_IDE },
657 { 0xffff, 0xffff }
658};
659
660static struct ecard_driver pata_icside_driver = {
661 .probe = pata_icside_probe,
662 .remove = __devexit_p(pata_icside_remove),
663 .shutdown = pata_icside_shutdown,
664 .id_table = pata_icside_ids,
665 .drv = {
666 .name = DRV_NAME,
667 },
668};
669
670static int __init pata_icside_init(void)
671{
672 return ecard_register_driver(&pata_icside_driver);
673}
674
675static void __exit pata_icside_exit(void)
676{
677 ecard_remove_driver(&pata_icside_driver);
678}
679
680MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
681MODULE_LICENSE("GPL");
682MODULE_DESCRIPTION("ICS PATA driver");
683
684module_init(pata_icside_init);
685module_exit(pata_icside_exit);
686