diff mbox

SATA_SIL: Add a work-around for IXP4xx CPU.

Message ID m3fx8m0vwh.fsf@intrepid.localdomain
State Not Applicable
Delegated to: David Miller
Headers show

Commit Message

Krzysztof Halasa Nov. 11, 2009, 12:04 a.m. UTC
IXP4xx CPUs can't read from 8 and 16-bit PCI MMIO registers, we have to read
from normal IO regions instead.

Tested on SIL3512, and specifically not tested on 4-port SIL3114.

Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>

Comments

Tejun Heo Dec. 15, 2009, 8:19 a.m. UTC | #1
Hello,

On 11/11/2009 09:04 AM, Krzysztof Halasa wrote:
> IXP4xx CPUs can't read from 8 and 16-bit PCI MMIO registers, we have to read
> from normal IO regions instead.
> 
> Tested on SIL3512, and specifically not tested on 4-port SIL3114.
> 
> Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>

Hmmm... Given that there are some platforms which have problem with
mmio and sil3112/4 can do everything via io accesses, it would be nice
to generalize this so that there's CONFIG_SATA_SIL_NO_MMIO which is
selected by affected platforms.  Are you interested in doing it?

Thanks.
Krzysztof Halasa Dec. 15, 2009, 11:03 p.m. UTC | #2
Tejun Heo <tj@kernel.org> writes:

> Hmmm... Given that there are some platforms which have problem with
> mmio and sil3112/4 can do everything via io accesses, it would be nice
> to generalize this so that there's CONFIG_SATA_SIL_NO_MMIO which is
> selected by affected platforms.  Are you interested in doing it?

Unfortunately I no longer have access to that SIL3512 miniPCI card so
I wouln't be able to test on IXP425. Perhaps it's not a problem, testing
on i386 (probably with disabled MMIO BAR) should be enough.

OTOH IIRC SIL3x12 needs to use the MMIO write to start BM DMA, otherwise
the AT-style 64 KB limits apply. I think IXP4xx would benefit from only
ioread8() going through normal IO.

Do you know what platforms have the MMIO problems? What kind of problems
are there, inability to use MMIO at all? (IXP4xx can't do 8/16-bit MMIO
reads).
Jeff Garzik Dec. 15, 2009, 11:09 p.m. UTC | #3
On 12/15/2009 06:03 PM, Krzysztof Halasa wrote:
> Tejun Heo<tj@kernel.org>  writes:
>
>> Hmmm... Given that there are some platforms which have problem with
>> mmio and sil3112/4 can do everything via io accesses, it would be nice
>> to generalize this so that there's CONFIG_SATA_SIL_NO_MMIO which is
>> selected by affected platforms.  Are you interested in doing it?
>
> Unfortunately I no longer have access to that SIL3512 miniPCI card so
> I wouln't be able to test on IXP425. Perhaps it's not a problem, testing
> on i386 (probably with disabled MMIO BAR) should be enough.
>
> OTOH IIRC SIL3x12 needs to use the MMIO write to start BM DMA, otherwise
> the AT-style 64 KB limits apply. I think IXP4xx would benefit from only
> ioread8() going through normal IO.
>
> Do you know what platforms have the MMIO problems? What kind of problems
> are there, inability to use MMIO at all? (IXP4xx can't do 8/16-bit MMIO
> reads).

The inability to do 8/16-bit MMIO reads are a repeated sticking point 
with embedded scenarios.  That's it.

I keep meaning to give the docs a hard look, and see if we can combine 
multiple taskfile register reads/writes into a single 32-bit one.  That 
would solve all these problems, without having to resort to the use of 
standard BARs.

	Jeff



--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tejun Heo Dec. 16, 2009, 12:39 a.m. UTC | #4
Hello,

On 12/16/2009 08:03 AM, Krzysztof Halasa wrote:
> Tejun Heo <tj@kernel.org> writes:
> 
>> Hmmm... Given that there are some platforms which have problem with
>> mmio and sil3112/4 can do everything via io accesses, it would be nice
>> to generalize this so that there's CONFIG_SATA_SIL_NO_MMIO which is
>> selected by affected platforms.  Are you interested in doing it?
> 
> Unfortunately I no longer have access to that SIL3512 miniPCI card so
> I wouln't be able to test on IXP425. Perhaps it's not a problem, testing
> on i386 (probably with disabled MMIO BAR) should be enough.
> 
> OTOH IIRC SIL3x12 needs to use the MMIO write to start BM DMA, otherwise
> the AT-style 64 KB limits apply. I think IXP4xx would benefit from only
> ioread8() going through normal IO.
> 
> Do you know what platforms have the MMIO problems? What kind of problems
> are there, inability to use MMIO at all? (IXP4xx can't do 8/16-bit MMIO
> reads).

I don't remember exactly but similar subjects have come up multiple
times on the mailing list and elsewhere.  ISTR a case where MMIO was
completely unavailable but I could be mistaken.  At any rate, the most
common problem seems to be smaller MMIO accesses, so generalizing your
previous patch just a bit would help a lot.
ie. CONFIG_SATA_SIL_ONLY_32BIT_MMIO which is selected by platform.

Thanks.
diff mbox

Patch

--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -757,7 +757,22 @@  static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (rc)
 		return rc;
 
+#ifdef CONFIG_ARCH_IXP4XX
+	/* IXP4xx CPUs can't perform 8 and 16-bit MMIO reads,
+	   use normal IO from/to regions 0-5 instead.
+	   region 0: channel 0 (and 2) task file regs
+	   region 1: channel 0 (and 2) auxiliary status
+	   region 2: channel 1 (and 3) task file regs
+	   region 3: channel 1 (and 3) auxiliary status
+	   region 4: bus master DMA command and status for all channels
+	   region 5: the normal MMIO
+
+	   Channels 2 and 3 are present only on SIL3114, device selection
+	   is done with ATA_DEV1 bit in ATA_REG_DEVICE. FIXME - untested */
+	rc = pcim_iomap_regions(pdev, 0x3F, DRV_NAME);
+#else
 	rc = pcim_iomap_regions(pdev, 1 << SIL_MMIO_BAR, DRV_NAME);
+#endif
 	if (rc == -EBUSY)
 		pcim_pin_device(pdev);
 	if (rc)
@@ -777,10 +792,16 @@  static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		struct ata_port *ap = host->ports[i];
 		struct ata_ioports *ioaddr = &ap->ioaddr;
 
+#ifdef CONFIG_ARCH_IXP4XX
+		ioaddr->cmd_addr = host->iomap[(i % 2) * 2];
+		ioaddr->altstatus_addr = host->iomap[1 + (i % 2) * 2] + 2;
+		ioaddr->bmdma_addr = host->iomap[4] + sil_port[i % 2].bmdma;
+#else
 		ioaddr->cmd_addr = mmio_base + sil_port[i].tf;
-		ioaddr->altstatus_addr =
-		ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
+		ioaddr->altstatus_addr = mmio_base + sil_port[i].ctl;
 		ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
+#endif
+		ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
 		ioaddr->scr_addr = mmio_base + sil_port[i].scr;
 		ata_sff_std_ports(ioaddr);