Skip to contentSkip to conversation

ahci: add support for hisilicon sata

PATCH Applied Kefeng Wang 3 participants 14 messages Apr 25, 2014 – Jun 24, 2014

Subsystems (6)

v6 of 7 Applied Latest is v7 →

lore
Share & tools
lore
#0 lore raw

v6 cover ahci: add support for hisilicon sata

change in v6:
1) type of host_flags changed from unsigned int to unsigned long, fix the building warning and error.

channge in v5:
1) drop AHCI_HFLAGS(...) from ahci_xgene.c and do use host_flags in ahci_platform_init_host, it's my carelessness.

changes in v4:
1) add a dynamic host_flags parameter in ahci_platform_init_host to make it more flexible, modify some driver to use new way to pass host flags, suggested by Hans

changes in v3:
1) move NO_FBS chunk after YES_FBS, Tejun's suggestion
2) use ata_port_info pointer to avoid struct ata_port_info on the stack twice

changes in v2:
1) make code more concise according to Hans's advice

Kefeng Wang (3):
ata: ahci: append new hflag AHCI_HFLAG_NO_FBS
libahci_platform: add host_flags parameter in
ahci_platform_init_host()
ahci: add support for Hisilicon sata

 .../devicetree/bindings/ata/ahci-platform.txt      |    3 ++-
 drivers/ata/ahci.h                                 |    1 +
 drivers/ata/ahci_da850.c                           |    3 ++-
 drivers/ata/ahci_imx.c                             |    3 ++-
 drivers/ata/ahci_platform.c                        |    9 ++++++++-
 drivers/ata/ahci_st.c                              |    2 +-
 drivers/ata/ahci_sunxi.c                           |    9 ++++++---
 drivers/ata/ahci_xgene.c                           |    7 +++++--
 drivers/ata/libahci.c                              |    5 +++++
 drivers/ata/libahci_platform.c                     |    5 ++++-
 include/linux/ahci_platform.h                      |    1 +
 11 files changed, 37 insertions(+), 11 deletions(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v6 1/3 ata: ahci: append new hflag AHCI_HFLAG_NO_FBS

Append AHCI_HFLAG_NO_FBS to force turning off FBS flag.

---
 drivers/ata/ahci.h    |    1 +
 drivers/ata/libahci.c |    5 +++++
 2 files changed, 6 insertions(+)
drivers/ata/ahci.h +1 -0
index b5eb886..48073ef 100644
@@ -236,6 +236,7 @@ enum {
 						        port start (wait until
 						        error-handling stage) */
 	AHCI_HFLAG_MULTI_MSI		= (1 << 16), /* multiple PCI MSIs */
+	AHCI_HFLAG_NO_FBS		= (1 << 17), /* no FBS */
 
 	/* ap->flags bits */
 
drivers/ata/libahci.c +5 -0
index 6bd4f66..e1cf859 100644
@@ -457,6 +457,11 @@ void ahci_save_initial_config(struct device *dev,
 		cap |= HOST_CAP_FBS;
 	}
 
+	if ((cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_NO_FBS)) {
+		dev_info(dev, "controller can't do FBS, turning off CAP_FBS\n");
+		cap &= ~HOST_CAP_FBS;
+	}
+
 	if (force_port_map && port_map != force_port_map) {
 		dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
 			 port_map, force_port_map);
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v6 2/3 libahci_platform: add host_flags parameter in ahci_platform_init_host()

In reply to Kefeng Wang

Add a dynamic host_flags argument to make ahci_platform_init_host more flexible, then remove the AHCI_HFLAGS(...) argument from some driver's ata_port_info, and pass that in as the new argument.

---
 drivers/ata/ahci_da850.c       |    3 ++-
 drivers/ata/ahci_imx.c         |    3 ++-
 drivers/ata/ahci_platform.c    |    2 +-
 drivers/ata/ahci_st.c          |    2 +-
 drivers/ata/ahci_sunxi.c       |    9 ++++++---
 drivers/ata/ahci_xgene.c       |    7 +++++--
 drivers/ata/libahci_platform.c |    5 ++++-
 include/linux/ahci_platform.h  |    1 +
 8 files changed, 22 insertions(+), 10 deletions(-)
drivers/ata/ahci_da850.c +2 -1
index 2c83613..2b77d53 100644
@@ -85,7 +85,8 @@ static int ahci_da850_probe(struct platform_device *pdev)
 
 	da850_sata_init(dev, pwrdn_reg, hpriv->mmio);
 
-	rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info, 0, 0);
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
+				     0, 0, 0);
 	if (rc)
 		goto disable_resources;
 
drivers/ata/ahci_imx.c +2 -1
index 497c7ab..e7e44a7 100644
@@ -267,7 +267,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
 	reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
 	writel(reg_val, hpriv->mmio + HOST_TIMER1MS);
 
-	ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0);
+	ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
+				      0, 0, 0);
 	if (ret)
 		imx_sata_disable(hpriv);
 
drivers/ata/ahci_platform.c +1 -1
index ef67e79..a476a1f 100644
@@ -55,7 +55,7 @@ static int ahci_probe(struct platform_device *pdev)
 			goto disable_resources;
 	}
 
-	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0);
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0, 0);
 	if (rc)
 		goto pdata_exit;
 
drivers/ata/ahci_st.c +1 -1
index 6332222..2595598 100644
@@ -166,7 +166,7 @@ static int st_ahci_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, 0, 0);
+	err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, 0, 0, 0);
 	if (err) {
 		ahci_platform_disable_resources(hpriv);
 		return err;
drivers/ata/ahci_sunxi.c +6 -3
index 42d3f64..02002f1 100644
@@ -157,8 +157,6 @@ static void ahci_sunxi_start_engine(struct ata_port *ap)
 }
 
 static const struct ata_port_info ahci_sunxi_port_info = {
-	AHCI_HFLAGS(AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
-			  AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ),
 	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
 	.pio_mask	= ATA_PIO4,
 	.udma_mask	= ATA_UDMA6,
@@ -169,6 +167,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct ahci_host_priv *hpriv;
+	unsigned long hflags;
 	int rc;
 
 	hpriv = ahci_platform_get_resources(pdev);
@@ -185,7 +184,11 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
 	if (rc)
 		goto disable_resources;
 
-	rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info, 0, 0);
+	hflags = AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
+		 AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
+
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info,
+				     hflags, 0, 0);
 	if (rc)
 		goto disable_resources;
 
drivers/ata/ahci_xgene.c +5 -2
index 77c89bf..042a9bb 100644
@@ -303,7 +303,6 @@ static struct ata_port_operations xgene_ahci_ops = {
 };
 
 static const struct ata_port_info xgene_ahci_port_info = {
-	AHCI_HFLAGS(AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ),
 	.flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
 	.pio_mask = ATA_PIO4,
 	.udma_mask = ATA_UDMA6,
@@ -382,6 +381,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
 	struct ahci_host_priv *hpriv;
 	struct xgene_ahci_context *ctx;
 	struct resource *res;
+	unsigned long hflags;
 	int rc;
 
 	hpriv = ahci_platform_get_resources(pdev);
@@ -450,7 +450,10 @@ static int xgene_ahci_probe(struct platform_device *pdev)
 		goto disable_resources;
 	}
 
-	rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info, 0, 0);
+	hflags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
+
+	rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info,
+				     hflags, 0, 0);
 	if (rc)
 		goto disable_resources;
 
drivers/ata/libahci_platform.c +4 -1
index 7cb3a85..3a5b4ed 100644
@@ -283,6 +283,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
  * @pdev: platform device pointer for the host
  * @hpriv: ahci-host private data for the host
  * @pi_template: template for the ata_port_info to use
+ * @host_flags: ahci host flags used in ahci_host_priv
  * @force_port_map: param passed to ahci_save_initial_config
  * @mask_port_map: param passed to ahci_save_initial_config
  *
@@ -296,6 +297,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
 int ahci_platform_init_host(struct platform_device *pdev,
 			    struct ahci_host_priv *hpriv,
 			    const struct ata_port_info *pi_template,
+			    unsigned long host_flags,
 			    unsigned int force_port_map,
 			    unsigned int mask_port_map)
 {
@@ -312,7 +314,8 @@ int ahci_platform_init_host(struct platform_device *pdev,
 	}
 
 	/* prepare host */
-	hpriv->flags |= (unsigned long)pi.private_data;
+	pi.private_data = (void *)host_flags;
+	hpriv->flags |= host_flags;
 
 	ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
 
include/linux/ahci_platform.h +1 -0
index 1f16d50..6dfd51a 100644
@@ -44,6 +44,7 @@ struct ahci_host_priv *ahci_platform_get_resources(
 int ahci_platform_init_host(struct platform_device *pdev,
 			    struct ahci_host_priv *hpriv,
 			    const struct ata_port_info *pi_template,
+			    unsigned long host_flags,
 			    unsigned int force_port_map,
 			    unsigned int mask_port_map);
 
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH v6 3/3 ahci: add support for Hisilicon sata

In reply to Kefeng Wang

The hip04 SoC of hisilicon has an AHCI compliant SATA controller, and it is compliant with the ahci 1.3 and sata 3.0 specification.

There is a wrong bit in HOST_CAP of hip04 sata controller, which enable unsupported feature of FBS, use AHCI_HFLAG_NO_FBS hflag to disable it.

---
 .../devicetree/bindings/ata/ahci-platform.txt      |    3 ++-
 drivers/ata/ahci_platform.c                        |    9 ++++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/ata/ahci-platform.txt +2 -1
index 48b285f..aab1d70 100644
@@ -7,7 +7,8 @@ Required properties:
 - compatible        : compatible list, one of "snps,spear-ahci",
                       "snps,exynos5440-ahci", "ibm,476gtr-ahci",
                       "allwinner,sun4i-a10-ahci", "fsl,imx53-ahci"
-                      "fsl,imx6q-ahci" or "snps,dwc-ahci"
+                      "fsl,imx6q-ahci", "snps,dwc-ahci" or
+                      "hisilicon,hisi-ahci"
 - interrupts        : <interrupt mapping for SATA IRQ>
 - reg               : <registers mapping>
 
drivers/ata/ahci_platform.c +8 -1
index a476a1f..ebe505c 100644
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/device.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/libata.h>
 #include <linux/ahci_platform.h>
@@ -33,6 +34,7 @@ static int ahci_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
 	struct ahci_host_priv *hpriv;
+	unsigned long hflags = 0;
 	int rc;
 
 	hpriv = ahci_platform_get_resources(pdev);
@@ -55,7 +57,11 @@ static int ahci_probe(struct platform_device *pdev)
 			goto disable_resources;
 	}
 
-	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0, 0);
+	if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
+		hflags |= AHCI_HFLAG_NO_FBS;
+
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
+				     hflags, 0, 0);
 	if (rc)
 		goto pdata_exit;
 
@@ -76,6 +82,7 @@ static const struct of_device_id ahci_of_match[] = {
 	{ .compatible = "snps,exynos5440-ahci", },
 	{ .compatible = "ibm,476gtr-ahci", },
 	{ .compatible = "snps,dwc-ahci", },
+	{ .compatible = "hisilicon,hisi-ahci", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
Signature · 1 line
1.7.9.5
#4 lore raw

Re: [PATCH v6 3/3] ahci: add support for Hisilicon sata

Quoted 8 lines · Kefeng Wang

The hip04 SoC of hisilicon has an AHCI compliant SATA controller, and it is compliant with the ahci 1.3 and sata 3.0 specification.

There is a wrong bit in HOST_CAP of hip04 sata controller, which enable unsupported feature of FBS, use AHCI_HFLAG_NO_FBS hflag to disable it.

Doesn't apply to libata/for-3.16. Please refresh.

Thanks.

Signature · 1 line
tejun
#5 lore raw

Re: [PATCH v6 3/3] ahci: add support for Hisilicon sata

Quoted 11 lines · Tejun Heo
Quoted 8 lines · Kefeng Wang

The hip04 SoC of hisilicon has an AHCI compliant SATA controller, and it is compliant with the ahci 1.3 and sata 3.0 specification.

There is a wrong bit in HOST_CAP of hip04 sata controller, which enable unsupported feature of FBS, use AHCI_HFLAG_NO_FBS hflag to disable it.

Doesn't apply to libata/for-3.16. Please refresh.

Send new patches, rebased onto libata/for-3.16, based on commit: 58eb8cd565af. Is this OK, if not, please let me know, thanks.

Quoted 3 lines

Thanks.

Reviewed-by on the v6 series
#6 lore raw
In reply to Kefeng Wang

Hi,

Quoted 18 lines · Kefeng Wang

change in v6:
1) type of host_flags changed from unsigned int to unsigned long, fix the building warning and error.

channge in v5:
1) drop AHCI_HFLAGS(...) from ahci_xgene.c and do use host_flags in ahci_platform_init_host, it's my carelessness.

changes in v4:
1) add a dynamic host_flags parameter in ahci_platform_init_host to make it more flexible, modify some driver to use new way to pass host flags, suggested by Hans

changes in v3:
1) move NO_FBS chunk after YES_FBS, Tejun's suggestion
2) use ata_port_info pointer to avoid struct ata_port_info on the stack twice

Quoted 8 lines

changes in v2:
1) make code more concise according to Hans's advice

Kefeng Wang (3):
ata: ahci: append new hflag AHCI_HFLAG_NO_FBS
libahci_platform: add host_flags parameter in
ahci_platform_init_host()
ahci: add support for Hisilicon sata

Thanks, looks good:

Regards,

Hans

Quoted 14 lines
 .../devicetree/bindings/ata/ahci-platform.txt      |    3 ++-
 drivers/ata/ahci.h                                 |    1 +
 drivers/ata/ahci_da850.c                           |    3 ++-
 drivers/ata/ahci_imx.c                             |    3 ++-
 drivers/ata/ahci_platform.c                        |    9 ++++++++-
 drivers/ata/ahci_st.c                              |    2 +-
 drivers/ata/ahci_sunxi.c                           |    9 ++++++---
 drivers/ata/ahci_xgene.c                           |    7 +++++--
 drivers/ata/libahci.c                              |    5 +++++
 drivers/ata/libahci_platform.c                     |    5 ++++-
 include/linux/ahci_platform.h                      |    1 +
 11 files changed, 37 insertions(+), 11 deletions(-)
#7 lore raw
In reply to Kefeng Wang

Hi Tejun, ping...

Quoted 40 lines · Kefeng Wang

change in v6:
1) type of host_flags changed from unsigned int to unsigned long, fix the building warning and error.

channge in v5:
1) drop AHCI_HFLAGS(...) from ahci_xgene.c and do use host_flags in ahci_platform_init_host, it's my carelessness.

changes in v4:
1) add a dynamic host_flags parameter in ahci_platform_init_host to make it more flexible, modify some driver to use new way to pass host flags, suggested by Hans

changes in v3:
1) move NO_FBS chunk after YES_FBS, Tejun's suggestion
2) use ata_port_info pointer to avoid struct ata_port_info on the stack twice

changes in v2:
1) make code more concise according to Hans's advice

Kefeng Wang (3):
ata: ahci: append new hflag AHCI_HFLAG_NO_FBS
libahci_platform: add host_flags parameter in
ahci_platform_init_host()
ahci: add support for Hisilicon sata

 .../devicetree/bindings/ata/ahci-platform.txt      |    3 ++-
 drivers/ata/ahci.h                                 |    1 +
 drivers/ata/ahci_da850.c                           |    3 ++-
 drivers/ata/ahci_imx.c                             |    3 ++-
 drivers/ata/ahci_platform.c                        |    9 ++++++++-
 drivers/ata/ahci_st.c                              |    2 +-
 drivers/ata/ahci_sunxi.c                           |    9 ++++++---
 drivers/ata/ahci_xgene.c                           |    7 +++++--
 drivers/ata/libahci.c                              |    5 +++++
 drivers/ata/libahci_platform.c                     |    5 ++++-
 include/linux/ahci_platform.h                      |    1 +
 11 files changed, 37 insertions(+), 11 deletions(-)
#9 lore raw

PATCH 1/1 ahci: disable ncq feature for hisilicon sata

NCQ feature is unsupported on hisilicon sata controller, so disable it. This version of IP is used by hip04 and hix5hd2 soc.

---
 drivers/ata/ahci_platform.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/ahci_platform.c +1 -1
index ebe505c..0cfda8b 100644
@@ -58,7 +58,7 @@ static int ahci_probe(struct platform_device *pdev)
        }
 
        if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
-               hflags |= AHCI_HFLAG_NO_FBS;
+               hflags = AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
 
        rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
                                     hflags, 0, 0);
Signature · 1 line
1.7.9.5
#10 lore raw

Re: [PATCH] ahci: disable ncq feature for hisilicon sata

Hi Tejun,

I have a question, the hip04 and hix5hd2 soc use the old version of IP, but they also have a new version of IP which support FBS and NCQ, and now the new one is used by a new soc. How can I distinguish them, use "hisilicon,hisi-ahci-vX" or just add "generic-ahci" string for the IP which is conformant with spec and has no special customization and issue? Any advices, thanks.

Regards,
Kefeng

Quoted 22 lines · kefeng.wang

NCQ feature is unsupported on hisilicon sata controller, so disable it. This version of IP is used by hip04 and hix5hd2 soc.

---
 drivers/ata/ahci_platform.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/ahci_platform.c +1 -1
index ebe505c..0cfda8b 100644
@@ -58,7 +58,7 @@ static int ahci_probe(struct platform_device *pdev)
        }
 
        if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
-               hflags |= AHCI_HFLAG_NO_FBS;
+               hflags = AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
 
        rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
                                     hflags, 0, 0);
#11 lore raw

Re: [PATCH] ahci: disable ncq feature for hisilicon sata

Hi Kefeng,

Quoted 7 lines · kefeng.wang

Hi Tejun,

I have a question, the hip04 and hix5hd2 soc use the old version of IP, but they also have a new version of IP which support FBS and NCQ, and now the new one is used by a new soc. How can I distinguish them, use "hisilicon,hisi-ahci-vX" or just add "generic-ahci" string for the IP which is conformant with spec and has no special customization and issue? Any advices, thanks.

Please use "hisilicon,hisi-ahci-vX", this way it will be easier to add any special behavior in case this turns out to be necessary later.

Regards,

Hans

#12 lore raw

Re: [PATCH] ahci: disable ncq feature for hisilicon sata

Quoted 5 lines · Hans de Goede

Hi Kefeng,

Quoted 2 lines · kefeng.wang

Hi Tejun,

Quoted 8 lines
Quoted 5 lines

I have a question, the hip04 and hix5hd2 soc use the old version of IP, but they also have a new version of IP which support FBS and NCQ, and now the new one is used by a new soc. How can I distinguish them, use "hisilicon,hisi-ahci-vX" or just add "generic-ahci" string for the IP which is conformant with spec and has no special customization and issue? Any advices, thanks.

Please use "hisilicon,hisi-ahci-vX", this way it will be easier to add any special behavior in case this turns out to be necessary later.

OK, thanks for your guidance. If necessary, we will use hisi-ahci-vX for hisi's IP.

Hi Tejun, could you merger this patch please? thanks.

Regards,
Kefeng

Quoted 5 lines

Regards,

Hans

#13 lore raw

PATCH 1/1 ahci: disable ncq feature for hisilicon sata

In reply to kefeng.wang
Quoted 1 line

From 72cbaa3d2f563d7b48c9f8aef47ec9aa3a31adf2 Mon Sep 17 00:00:00 2001

From: Kefeng Wang <[email protected]>
Date: Tue, 24 Jun 2014 16:54:23 -0400

NCQ feature is unsupported on hisilicon sata controller, so disable it. This version of IP is used by hip04 and hix5hd2 soc.

tj: "|=" was replaced with "=" for no reason. Restored "|=".

---
Patch didn't apply. Applied to libata/for-3.16-fixes manually and dropped "|=" -> "=" conversion. Why was this done?

Thanks.

 drivers/ata/ahci_platform.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/ahci_platform.c +1 -1
index ebe505c..b10d81d 100644
@@ -58,7 +58,7 @@ static int ahci_probe(struct platform_device *pdev)
 	}
 
 	if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
-		hflags |= AHCI_HFLAG_NO_FBS;
+		hflags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
 
 	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
 				     hflags, 0, 0);
Signature · 1 line
1.9.3