[PATCH v3 2/2] ahci_platform: add support for CNS3xxx SoC devices
From: <hidden>
Date: 2011-01-06 17:53:13
Also in:
linux-arm-kernel
Subsystem:
arm port, libata sata ahci platform devices support, libata subsystem (serial and parallel ata drivers), the rest · Maintainers:
Russell King, Hans de Goede, Damien Le Moal, Niklas Cassel, Linus Torvalds
From: Mac Lin <redacted>
CNS3xxx override the softreset function of ahci_platform ahci_softreset by
cns3xxx_ahci_softreset, which would retry ahci_do_softreset again with pmp=0 if
pmp=15 failed, for the controller has problem receiving D2H Reg FIS of the
different PMP setting of the previous sent H2D Reg FIS.
Following describe the isssue with original ahci_platform driver on
linux-2.6.37-rc3, arm/cns3xxx.
If CONFIG_SATA_PMP is enabled, while not using multiplier and connect the disks
directly to the board, the disk cannot be found due to software reset always
failed.
ahci ahci.0: forcing PORTS_IMPL to 0x3
ahci ahci.0: AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl platform mode
ahci ahci.0: flags: ncq sntf pm led clo only pmp pio slum part ccc
scsi0 : ahci_platform
scsi1 : ahci_platform
ata1: SATA max UDMA/133 irq_stat 0x00400040, connection status changed irq 65
ata2: SATA max UDMA/133 mmio [mem 0x83000000-0x83ffffff] port 0x180 irq 65
ata2: SATA link down (SStatus 0 SControl 300)
ata1: link is slow to respond, please be patient (ready=0)
ata1: softreset failed (device not ready)
ata1: link is slow to respond, please be patient (ready=0)
ata1: softreset failed (device not ready)
ata1: link is slow to respond, please be patient (ready=0)
ata1: softreset failed (device not ready)
ata1: limiting SATA link speed to 1.5 Gbps
ata1: SATA link down (SStatus 1 SControl 310)
While using multiplier with CONFIG_SATA_PMP enabled, or using disks directly
without CONFIG_SATA_PMP have no issue. It seems the device is sending D2H Reg
FIS, but controller is not reflecting it on any known means.
Signed-off-by: Mac Lin <redacted>
---
arch/arm/mach-cns3xxx/devices.c | 2 +-
drivers/ata/Kconfig | 11 +++++++++++
drivers/ata/ahci_platform.c | 39 +++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c
index 50b4d31..b496f02 100644
--- a/arch/arm/mach-cns3xxx/devices.c
+++ b/arch/arm/mach-cns3xxx/devices.c@@ -40,7 +40,7 @@ static struct resource cns3xxx_ahci_resource[] = { static u64 cns3xxx_ahci_dmamask = DMA_BIT_MASK(32); static struct platform_device cns3xxx_ahci_pdev = { - .name = "ahci", + .name = "ahci-cns3xxx", .id = 0, .resource = cns3xxx_ahci_resource, .num_resources = ARRAY_SIZE(cns3xxx_ahci_resource),
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 36e2319..5d8b1a3 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig@@ -75,6 +75,17 @@ config SATA_AHCI_PLATFORM If unsure, say N. +config SATA_AHCI_CNS3XXX + bool "AHCI Support on the Cavium Networks CNS3xxx SOC" + depends on ARCH_CNS3XXX + depends on SATA_AHCI_PLATFORM + help + This option enables AHCI platform driver to support CNS3xxx + System-on-Chip devices. This is only needed when using CNS3xxx AHCI + controller. + + If unsure, say N. + config SATA_FSL tristate "Freescale 3.0Gbps SATA support" depends on FSL_SOC
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 25d98c8..7d6957f 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c@@ -176,8 +176,47 @@ static int __devexit ahci_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_SATA_AHCI_CNS3XXX +/* + * TODO: move cns3xxx_ahci_init to here after cns3xxx_pwr*() calls are + * thread-safe + */ + +static int cns3xxx_ahci_softreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + int pmp = sata_srst_pmp(link); + int ret; + + ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); + if (pmp && ret) + return ahci_do_softreset(link, class, 0, deadline, + ahci_check_ready); + return ret; +} + +static struct ata_port_operations cns3xxx_ahci_ops = { + .inherits = &ahci_ops, + .softreset = cns3xxx_ahci_softreset, +}; + +static const struct ata_port_info cns3xxx_ata_port_info = { + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &cns3xxx_ahci_ops, +}; + +struct ahci_platform_data cns3xxx_ahci_platform_data = { + .ata_port_info = &cns3xxx_ata_port_info, +}; +#endif + static const struct platform_device_id ahci_pltfm_ids[] = { { "ahci", }, +#ifdef CONFIG_SATA_AHCI_CNS3XXX + { "ahci-cns3xxx", (kernel_ulong_t)&cns3xxx_ahci_platform_data}, +#endif { }, }; MODULE_DEVICE_TABLE(platform, ahci_pltfm_ids);
--
1.7.3