diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2007-07-06 19:21:22 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-15 14:58:51 -0400 |
commit | 2b9e68f728d6b2cf38b252650f017576e8dae2ad (patch) | |
tree | 9a5d5947879a192666307cc90dbfcc23d64fb83c | |
parent | f4921aff5b174349bc36551f142a5dbac782ea3f (diff) |
[libata] pata_sil680: Add MMIO support
This patch adds MMIO support to the pata_sil680 for taskfile IOs,
based on what the old siimage does.
I haven't bothered changing the chip setup stuff from PCI config
cycles to MMIO though (siimage does it), I don't think it matters,
I've only adapted it to use MMIO for taskfile accesses.
I've tested it on a Cell blade and it seems to work fine.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/ata/pata_sil680.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 2eb75cd74a96..4dc2e73298fd 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c | |||
@@ -279,7 +279,7 @@ static struct ata_port_operations sil680_port_ops = { | |||
279 | * Returns the final clock settings. | 279 | * Returns the final clock settings. |
280 | */ | 280 | */ |
281 | 281 | ||
282 | static u8 sil680_init_chip(struct pci_dev *pdev) | 282 | static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio) |
283 | { | 283 | { |
284 | u32 class_rev = 0; | 284 | u32 class_rev = 0; |
285 | u8 tmpbyte = 0; | 285 | u8 tmpbyte = 0; |
@@ -297,6 +297,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev) | |||
297 | dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n", | 297 | dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n", |
298 | tmpbyte & 1, tmpbyte & 0x30); | 298 | tmpbyte & 1, tmpbyte & 0x30); |
299 | 299 | ||
300 | *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5); | ||
301 | |||
300 | switch(tmpbyte & 0x30) { | 302 | switch(tmpbyte & 0x30) { |
301 | case 0x00: | 303 | case 0x00: |
302 | /* 133 clock attempt to force it on */ | 304 | /* 133 clock attempt to force it on */ |
@@ -361,25 +363,76 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, | |||
361 | }; | 363 | }; |
362 | const struct ata_port_info *ppi[] = { &info, NULL }; | 364 | const struct ata_port_info *ppi[] = { &info, NULL }; |
363 | static int printed_version; | 365 | static int printed_version; |
366 | struct ata_host *host; | ||
367 | void __iomem *mmio_base; | ||
368 | int rc, try_mmio; | ||
364 | 369 | ||
365 | if (!printed_version++) | 370 | if (!printed_version++) |
366 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 371 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
367 | 372 | ||
368 | switch(sil680_init_chip(pdev)) | 373 | switch (sil680_init_chip(pdev, &try_mmio)) { |
369 | { | ||
370 | case 0: | 374 | case 0: |
371 | ppi[0] = &info_slow; | 375 | ppi[0] = &info_slow; |
372 | break; | 376 | break; |
373 | case 0x30: | 377 | case 0x30: |
374 | return -ENODEV; | 378 | return -ENODEV; |
375 | } | 379 | } |
380 | |||
381 | if (!try_mmio) | ||
382 | goto use_ioports; | ||
383 | |||
384 | /* Try to acquire MMIO resources and fallback to PIO if | ||
385 | * that fails | ||
386 | */ | ||
387 | rc = pcim_enable_device(pdev); | ||
388 | if (rc) | ||
389 | return rc; | ||
390 | rc = pcim_iomap_regions(pdev, 1 << SIL680_MMIO_BAR, DRV_NAME); | ||
391 | if (rc) | ||
392 | goto use_ioports; | ||
393 | |||
394 | /* Allocate host and set it up */ | ||
395 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2); | ||
396 | if (!host) | ||
397 | return -ENOMEM; | ||
398 | host->iomap = pcim_iomap_table(pdev); | ||
399 | |||
400 | /* Setup DMA masks */ | ||
401 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | ||
402 | if (rc) | ||
403 | return rc; | ||
404 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | ||
405 | if (rc) | ||
406 | return rc; | ||
407 | pci_set_master(pdev); | ||
408 | |||
409 | /* Get MMIO base and initialize port addresses */ | ||
410 | mmio_base = host->iomap[SIL680_MMIO_BAR]; | ||
411 | host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x00; | ||
412 | host->ports[0]->ioaddr.cmd_addr = mmio_base + 0x80; | ||
413 | host->ports[0]->ioaddr.ctl_addr = mmio_base + 0x8a; | ||
414 | host->ports[0]->ioaddr.altstatus_addr = mmio_base + 0x8a; | ||
415 | ata_std_ports(&host->ports[0]->ioaddr); | ||
416 | host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x08; | ||
417 | host->ports[1]->ioaddr.cmd_addr = mmio_base + 0xc0; | ||
418 | host->ports[1]->ioaddr.ctl_addr = mmio_base + 0xca; | ||
419 | host->ports[1]->ioaddr.altstatus_addr = mmio_base + 0xca; | ||
420 | ata_std_ports(&host->ports[1]->ioaddr); | ||
421 | |||
422 | /* Register & activate */ | ||
423 | return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, | ||
424 | &sil680_sht); | ||
425 | |||
426 | use_ioports: | ||
376 | return ata_pci_init_one(pdev, ppi); | 427 | return ata_pci_init_one(pdev, ppi); |
377 | } | 428 | } |
378 | 429 | ||
379 | #ifdef CONFIG_PM | 430 | #ifdef CONFIG_PM |
380 | static int sil680_reinit_one(struct pci_dev *pdev) | 431 | static int sil680_reinit_one(struct pci_dev *pdev) |
381 | { | 432 | { |
382 | sil680_init_chip(pdev); | 433 | int try_mmio; |
434 | |||
435 | sil680_init_chip(pdev, &try_mmio); | ||
383 | return ata_pci_device_resume(pdev); | 436 | return ata_pci_device_resume(pdev); |
384 | } | 437 | } |
385 | #endif | 438 | #endif |