ata: ahci_brcm: Add support for Broadcom NSP SoC
authorYendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
Thu, 16 Jun 2016 13:53:33 +0000 (09:53 -0400)
committerTejun Heo <tj@kernel.org>
Thu, 16 Jun 2016 20:24:55 +0000 (16:24 -0400)
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>
drivers/ata/Kconfig
drivers/ata/ahci_brcm.c

index 8fe06e6a9a0b9a72c7e67b6e47bb3237931f6072..2c8be74f401de1bcfc698deec75287bc56f5efbf 100644 (file)
@@ -100,7 +100,7 @@ config SATA_AHCI_PLATFORM
 
 config AHCI_BRCM
        tristate "Broadcom AHCI SATA support"
 
 config AHCI_BRCM
        tristate "Broadcom AHCI SATA support"
-       depends on ARCH_BRCMSTB || BMIPS_GENERIC
+       depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP
        help
          This option enables support for the AHCI SATA3 controller found on
          Broadcom SoC's.
        help
          This option enables support for the AHCI SATA3 controller found on
          Broadcom SoC's.
index e87bcec0fd7c31d9623e54cf84fa6c62b41f2f39..6f8a7341fa08a701af61226fab156206b506be20 100644 (file)
        (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) |         \
        (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
 
        (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) |         \
        (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
 
+enum brcm_ahci_version {
+       BRCM_SATA_BCM7425 = 1,
+       BRCM_SATA_BCM7445,
+       BRCM_SATA_NSP,
+};
+
 enum brcm_ahci_quirks {
        BRCM_AHCI_QUIRK_NO_NCQ          = BIT(0),
        BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1),
 enum brcm_ahci_quirks {
        BRCM_AHCI_QUIRK_NO_NCQ          = BIT(0),
        BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1),
@@ -81,6 +87,7 @@ struct brcm_ahci_priv {
        void __iomem *top_ctrl;
        u32 port_mask;
        u32 quirks;
        void __iomem *top_ctrl;
        u32 port_mask;
        u32 quirks;
+       enum brcm_ahci_version version;
 };
 
 static const struct ata_port_info ahci_brcm_port_info = {
 };
 
 static const struct ata_port_info ahci_brcm_port_info = {
@@ -247,9 +254,19 @@ static u32 brcm_ahci_get_portmask(struct platform_device *pdev,
 
 static void brcm_sata_init(struct brcm_ahci_priv *priv)
 {
 
 static void brcm_sata_init(struct brcm_ahci_priv *priv)
 {
+       void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
+
        /* Configure endianness */
        /* Configure endianness */
-       brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF,
-                          priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL);
+       if (priv->version ==  BRCM_SATA_NSP) {
+               u32 data = brcm_sata_readreg(ctrl);
+
+               data &= ~((0x03 << DMADATA_ENDIAN_SHIFT) |
+                       (0x03 << DMADESC_ENDIAN_SHIFT));
+               data |= (0x02 << DMADATA_ENDIAN_SHIFT) |
+                       (0x02 << DMADESC_ENDIAN_SHIFT);
+               brcm_sata_writereg(data, ctrl);
+       } else
+               brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, ctrl);
 }
 
 #ifdef CONFIG_PM_SLEEP
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -282,8 +299,17 @@ static struct scsi_host_template ahci_platform_sht = {
        AHCI_SHT(DRV_NAME),
 };
 
        AHCI_SHT(DRV_NAME),
 };
 
+static const struct of_device_id ahci_of_match[] = {
+       {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
+       {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
+       {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
+       {},
+};
+MODULE_DEVICE_TABLE(of, ahci_of_match);
+
 static int brcm_ahci_probe(struct platform_device *pdev)
 {
 static int brcm_ahci_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *of_id;
        struct device *dev = &pdev->dev;
        struct brcm_ahci_priv *priv;
        struct ahci_host_priv *hpriv;
        struct device *dev = &pdev->dev;
        struct brcm_ahci_priv *priv;
        struct ahci_host_priv *hpriv;
@@ -293,6 +319,12 @@ static int brcm_ahci_probe(struct platform_device *pdev)
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
+
+       of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
+       if (!of_id)
+               return -ENODEV;
+
+       priv->version = (enum brcm_ahci_version)of_id->data;
        priv->dev = dev;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
        priv->dev = dev;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
@@ -300,7 +332,8 @@ static int brcm_ahci_probe(struct platform_device *pdev)
        if (IS_ERR(priv->top_ctrl))
                return PTR_ERR(priv->top_ctrl);
 
        if (IS_ERR(priv->top_ctrl))
                return PTR_ERR(priv->top_ctrl);
 
-       if (of_device_is_compatible(dev->of_node, "brcm,bcm7425-ahci")) {
+       if ((priv->version == BRCM_SATA_BCM7425) ||
+               (priv->version == BRCM_SATA_NSP)) {
                priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ;
                priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
        }
                priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ;
                priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
        }
@@ -354,13 +387,6 @@ static int brcm_ahci_remove(struct platform_device *pdev)
        return 0;
 }
 
        return 0;
 }
 
-static const struct of_device_id ahci_of_match[] = {
-       {.compatible = "brcm,bcm7425-ahci"},
-       {.compatible = "brcm,bcm7445-ahci"},
-       {},
-};
-MODULE_DEVICE_TABLE(of, ahci_of_match);
-
 static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
 
 static struct platform_driver brcm_ahci_driver = {
 static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
 
 static struct platform_driver brcm_ahci_driver = {