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