aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>2016-06-16 09:53:33 -0400
committerTejun Heo <tj@kernel.org>2016-06-16 16:24:55 -0400
commit3ee2e6dcaa3570df6f7ceeda6d8342bc47cf6b1c (patch)
treed13c69889e54161ddca9252317be0ac71d144088
parenteba68f829794a1c3eb7a78d53c652daa303580ed (diff)
ata: ahci_brcm: Add support for Broadcom NSP SoC
Add SATA3 support for Broadcom NSP SoC Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com> Acked-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/ata/ahci_brcm.c46
2 files changed, 37 insertions, 11 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 8fe06e6a9a0b..2c8be74f401d 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -100,7 +100,7 @@ config SATA_AHCI_PLATFORM
100 100
101config AHCI_BRCM 101config AHCI_BRCM
102 tristate "Broadcom AHCI SATA support" 102 tristate "Broadcom AHCI SATA support"
103 depends on ARCH_BRCMSTB || BMIPS_GENERIC 103 depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP
104 help 104 help
105 This option enables support for the AHCI SATA3 controller found on 105 This option enables support for the AHCI SATA3 controller found on
106 Broadcom SoC's. 106 Broadcom SoC's.
diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c
index e87bcec0fd7c..6f8a7341fa08 100644
--- a/drivers/ata/ahci_brcm.c
+++ b/drivers/ata/ahci_brcm.c
@@ -71,6 +71,12 @@
71 (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \ 71 (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \
72 (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT)) 72 (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
73 73
74enum brcm_ahci_version {
75 BRCM_SATA_BCM7425 = 1,
76 BRCM_SATA_BCM7445,
77 BRCM_SATA_NSP,
78};
79
74enum brcm_ahci_quirks { 80enum brcm_ahci_quirks {
75 BRCM_AHCI_QUIRK_NO_NCQ = BIT(0), 81 BRCM_AHCI_QUIRK_NO_NCQ = BIT(0),
76 BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1), 82 BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1),
@@ -81,6 +87,7 @@ struct brcm_ahci_priv {
81 void __iomem *top_ctrl; 87 void __iomem *top_ctrl;
82 u32 port_mask; 88 u32 port_mask;
83 u32 quirks; 89 u32 quirks;
90 enum brcm_ahci_version version;
84}; 91};
85 92
86static const struct ata_port_info ahci_brcm_port_info = { 93static const struct ata_port_info ahci_brcm_port_info = {
@@ -247,9 +254,19 @@ static u32 brcm_ahci_get_portmask(struct platform_device *pdev,
247 254
248static void brcm_sata_init(struct brcm_ahci_priv *priv) 255static void brcm_sata_init(struct brcm_ahci_priv *priv)
249{ 256{
257 void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
258
250 /* Configure endianness */ 259 /* Configure endianness */
251 brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, 260 if (priv->version == BRCM_SATA_NSP) {
252 priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL); 261 u32 data = brcm_sata_readreg(ctrl);
262
263 data &= ~((0x03 << DMADATA_ENDIAN_SHIFT) |
264 (0x03 << DMADESC_ENDIAN_SHIFT));
265 data |= (0x02 << DMADATA_ENDIAN_SHIFT) |
266 (0x02 << DMADESC_ENDIAN_SHIFT);
267 brcm_sata_writereg(data, ctrl);
268 } else
269 brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, ctrl);
253} 270}
254 271
255#ifdef CONFIG_PM_SLEEP 272#ifdef CONFIG_PM_SLEEP
@@ -282,8 +299,17 @@ static struct scsi_host_template ahci_platform_sht = {
282 AHCI_SHT(DRV_NAME), 299 AHCI_SHT(DRV_NAME),
283}; 300};
284 301
302static const struct of_device_id ahci_of_match[] = {
303 {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
304 {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
305 {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
306 {},
307};
308MODULE_DEVICE_TABLE(of, ahci_of_match);
309
285static int brcm_ahci_probe(struct platform_device *pdev) 310static int brcm_ahci_probe(struct platform_device *pdev)
286{ 311{
312 const struct of_device_id *of_id;
287 struct device *dev = &pdev->dev; 313 struct device *dev = &pdev->dev;
288 struct brcm_ahci_priv *priv; 314 struct brcm_ahci_priv *priv;
289 struct ahci_host_priv *hpriv; 315 struct ahci_host_priv *hpriv;
@@ -293,6 +319,12 @@ static int brcm_ahci_probe(struct platform_device *pdev)
293 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 319 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
294 if (!priv) 320 if (!priv)
295 return -ENOMEM; 321 return -ENOMEM;
322
323 of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
324 if (!of_id)
325 return -ENODEV;
326
327 priv->version = (enum brcm_ahci_version)of_id->data;
296 priv->dev = dev; 328 priv->dev = dev;
297 329
298 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl"); 330 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
@@ -300,7 +332,8 @@ static int brcm_ahci_probe(struct platform_device *pdev)
300 if (IS_ERR(priv->top_ctrl)) 332 if (IS_ERR(priv->top_ctrl))
301 return PTR_ERR(priv->top_ctrl); 333 return PTR_ERR(priv->top_ctrl);
302 334
303 if (of_device_is_compatible(dev->of_node, "brcm,bcm7425-ahci")) { 335 if ((priv->version == BRCM_SATA_BCM7425) ||
336 (priv->version == BRCM_SATA_NSP)) {
304 priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ; 337 priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ;
305 priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; 338 priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
306 } 339 }
@@ -354,13 +387,6 @@ static int brcm_ahci_remove(struct platform_device *pdev)
354 return 0; 387 return 0;
355} 388}
356 389
357static const struct of_device_id ahci_of_match[] = {
358 {.compatible = "brcm,bcm7425-ahci"},
359 {.compatible = "brcm,bcm7445-ahci"},
360 {},
361};
362MODULE_DEVICE_TABLE(of, ahci_of_match);
363
364static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); 390static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
365 391
366static struct platform_driver brcm_ahci_driver = { 392static struct platform_driver brcm_ahci_driver = {