devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/23] HiSilicon SAS v2 hw support
@ 2016-01-08 14:15 John Garry
  2016-01-08 14:15 ` [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings John Garry
                   ` (19 more replies)
  0 siblings, 20 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

This patchset introduces support for the HiSi SAS v2 hw.
The major difference between v1 and v2 hw is support
for SATA/STP.

Known limitation:
- We cannot connect a SATA disk through a 12G expander
  without disabling the STP buffer. Direcly connecting
  a SATA disk to the HBA is ok.

John Garry (23):
  devicetree: bindings: hisi_sas: add v2 HW bindings
  hisi_sas: relocate DEV_IS_EXPANDER
  hisi_sas: set max commands as configurable
  hisi_sas: reduce max itct entries
  hisi_sas: add hisi_sas_err_record_v1
  hisi_sas: rename some fields in hisi_sas_itct
  hisi_sas: add bare v2 hw driver
  hisi_sas: add v2 register definitions
  hisi_sas: add v2 hw init
  hisi_sas: add init_id_frame_v2_hw()
  hisi_sas: add v2 phy init code
  hisi_sas: add v2 int init and phy up handler
  hisi_sas: add v2 phy down handler
  hisi_sas: add v2 channel interrupt handler
  hisi_sas: add v2 SATA interrupt handler
  hisi_sas: add v2 cq interrupt handler
  hisi_sas: add v2 path to send ssp frame
  hisi_sas: add v2 code to send smp command
  hisi_sas: add v2 code for itct setup and free
  hisi_sas: add v2 path to send ATA command
  hisi_sas: add v2 slot error handler
  hisi_sas: add v2 tmf functions
  hisi_sas: update driver version to 1.1

 .../devicetree/bindings/scsi/hisilicon-sas.txt     |   20 +-
 drivers/scsi/hisi_sas/Makefile                     |    2 +-
 drivers/scsi/hisi_sas/hisi_sas.h                   |   39 +-
 drivers/scsi/hisi_sas/hisi_sas_main.c              |   36 +-
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c             |   20 +-
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c             | 2206 ++++++++++++++++++++
 6 files changed, 2277 insertions(+), 46 deletions(-)
 create mode 100644 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
@ 2016-01-08 14:15 ` John Garry
       [not found]   ` <1452262542-64589-2-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
  2016-01-08 14:15 ` [PATCH 03/23] hisi_sas: set max commands as configurable John Garry
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Add the dt bindings for HiSi SAS controller v2 HW.

The main difference in the controllers from dt perspective
is interrupts.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 .../devicetree/bindings/scsi/hisilicon-sas.txt       | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
index 0a7a325..2695023 100644
--- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
+++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
@@ -5,6 +5,7 @@ The HiSilicon SAS controller supports SAS/SATA.
 Main node required properties:
   - compatible : value should be as follows:
 	(a) "hisilicon,hip05-sas-v1" for v1 hw in hip05 chipset
+	(b) "hisilicon,hip06-sas-v2" for v2 hw in hip06 chipset
   - sas-addr : array of 8 bytes for host SAS address
   - reg : Address and length of the SAS register
   - hisilicon,sas-syscon: phandle of syscon used for sas control
@@ -13,11 +14,11 @@ Main node required properties:
   - ctrl-clock-ena-reg : offset to controller clock enable register in ctrl reg
   - queue-count : number of delivery and completion queues in the controller
   - phy-count : number of phys accessible by the controller
-  - interrupts : Interrupts for phys, completion queues, and fatal
+  - interrupts : For v1 hw: Interrupts for phys, completion queues, and fatal
 		sources; the interrupts are ordered in 3 groups, as follows:
-			- Phy interrupts
-			- Completion queue interrupts
-			- Fatal interrupts
+		  - Phy interrupts
+		  - Completion queue interrupts
+		  - Fatal interrupts
 		Phy interrupts : Each phy has 3 interrupt sources:
 			- broadcast
 			- phyup
@@ -25,11 +26,28 @@ Main node required properties:
 		The phy interrupts are ordered into groups of 3 per phy
 		(broadcast, phyup, and abnormal) in increasing order.
 		Completion queue interrupts : each completion queue has 1
-			interrupt source.
-			The interrupts are ordered in increasing order.
+			interrupt source. The interrupts are ordered in
+			increasing order.
 		Fatal interrupts : the fatal interrupts are ordered as follows:
 			- ECC
 			- AXI bus
+		For v2 hw: Interrupts for phys, Sata, and completion queues;
+		the interrupts are ordered in 3 groups, as follows:
+		  - Phy interrupts
+		  - Sata interrupts
+		  - Completion queue interrupts
+		Phy interrupts : Each controller has 2 phy interrupts:
+			- phy up/down
+			- channel interrupt
+		Sata interrupts : Each phy on the controller has 1 Sata
+			interrupt. The interrupts are ordered in increasing
+			order.
+		Completion queue interrupts : each completion queue has 1
+			interrupt source. The interrupts are ordered in
+			increasing order.
+
+Optional main node properties:
+ - am-max-trans : limit controller for am max transmissions
 
 Example:
 	sas0: sas@c1000000 {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 02/23] hisi_sas: relocate DEV_IS_EXPANDER
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
@ 2016-01-08 14:15   ` John Garry
  2016-01-08 14:15   ` [PATCH 09/23] hisi_sas: add v2 hw init John Garry
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley-wo1vFcy6AUs, martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ
  Cc: linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA, John Garry

Relocate DEV_IS_EXPANDER to hisi_sas.h as
it will be required for v2 hw support.

Signed-off-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 drivers/scsi/hisi_sas/hisi_sas.h      | 4 ++++
 drivers/scsi/hisi_sas/hisi_sas_main.c | 4 ----
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 5af2e41..21eb2bb 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -37,6 +37,10 @@
 #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024)
 #define HISI_SAS_MAX_SMP_RESP_SZ 1028
 
+#define DEV_IS_EXPANDER(type) \
+	((type == SAS_EDGE_EXPANDER_DEVICE) || \
+	(type == SAS_FANOUT_EXPANDER_DEVICE))
+
 struct hisi_hba;
 
 enum {
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 99b1950..7689939 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -12,10 +12,6 @@
 #include "hisi_sas.h"
 #define DRV_NAME "hisi_sas"
 
-#define DEV_IS_EXPANDER(type) \
-	((type == SAS_EDGE_EXPANDER_DEVICE) || \
-	(type == SAS_FANOUT_EXPANDER_DEVICE))
-
 #define DEV_IS_GONE(dev) \
 	((!dev) || (dev->dev_type == SAS_PHY_UNUSED))
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 03/23] hisi_sas: set max commands as configurable
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
  2016-01-08 14:15 ` [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 04/23] hisi_sas: reduce max itct entries John Garry
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Since v2 hardware permits different numbers of
commands to v1, set this as configurable in
hisi_sas_hw.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h       |  2 +-
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 24 ++++++++++++------------
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c |  3 +++
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 21eb2bb..5ed5cf1 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -27,7 +27,6 @@
 #define HISI_SAS_QUEUE_SLOTS 512
 #define HISI_SAS_MAX_ITCT_ENTRIES 4096
 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
-#define HISI_SAS_COMMAND_ENTRIES 8192
 
 #define HISI_SAS_STATUS_BUF_SZ \
 		(sizeof(struct hisi_sas_err_record) + 1024)
@@ -144,6 +143,7 @@ struct hisi_sas_hw {
 	void (*free_device)(struct hisi_hba *hisi_hba,
 			    struct hisi_sas_device *dev);
 	int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id);
+	int max_command_entries;
 	int complete_hdr_size;
 };
 
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 7689939..c48df6d 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -973,9 +973,9 @@ static struct sas_domain_function_template hisi_sas_transport_ops = {
 
 static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
 {
-	int i, s;
 	struct platform_device *pdev = hisi_hba->pdev;
 	struct device *dev = &pdev->dev;
+	int i, s, max_command_entries = hisi_hba->hw->max_command_entries;
 
 	spin_lock_init(&hisi_hba->lock);
 	for (i = 0; i < hisi_hba->n_phy; i++) {
@@ -1035,13 +1035,13 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
 
 	memset(hisi_hba->itct, 0, s);
 
-	hisi_hba->slot_info = devm_kcalloc(dev, HISI_SAS_COMMAND_ENTRIES,
+	hisi_hba->slot_info = devm_kcalloc(dev, max_command_entries,
 					   sizeof(struct hisi_sas_slot),
 					   GFP_KERNEL);
 	if (!hisi_hba->slot_info)
 		goto err_out;
 
-	s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost);
+	s = max_command_entries * sizeof(struct hisi_sas_iost);
 	hisi_hba->iost = dma_alloc_coherent(dev, s, &hisi_hba->iost_dma,
 					    GFP_KERNEL);
 	if (!hisi_hba->iost)
@@ -1049,7 +1049,7 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
 
 	memset(hisi_hba->iost, 0, s);
 
-	s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint);
+	s = max_command_entries * sizeof(struct hisi_sas_breakpoint);
 	hisi_hba->breakpoint = dma_alloc_coherent(dev, s,
 				&hisi_hba->breakpoint_dma, GFP_KERNEL);
 	if (!hisi_hba->breakpoint)
@@ -1057,7 +1057,7 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
 
 	memset(hisi_hba->breakpoint, 0, s);
 
-	hisi_hba->slot_index_count = HISI_SAS_COMMAND_ENTRIES;
+	hisi_hba->slot_index_count = max_command_entries;
 	s = hisi_hba->slot_index_count / sizeof(unsigned long);
 	hisi_hba->slot_index_tags = devm_kzalloc(dev, s, GFP_KERNEL);
 	if (!hisi_hba->slot_index_tags)
@@ -1075,7 +1075,7 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
 		goto err_out;
 	memset(hisi_hba->initial_fis, 0, s);
 
-	s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2;
+	s = max_command_entries * sizeof(struct hisi_sas_breakpoint) * 2;
 	hisi_hba->sata_breakpoint = dma_alloc_coherent(dev, s,
 				&hisi_hba->sata_breakpoint_dma, GFP_KERNEL);
 	if (!hisi_hba->sata_breakpoint)
@@ -1098,7 +1098,7 @@ err_out:
 static void hisi_sas_free(struct hisi_hba *hisi_hba)
 {
 	struct device *dev = &hisi_hba->pdev->dev;
-	int i, s;
+	int i, s, max_command_entries = hisi_hba->hw->max_command_entries;
 
 	for (i = 0; i < hisi_hba->queue_count; i++) {
 		s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS;
@@ -1123,12 +1123,12 @@ static void hisi_sas_free(struct hisi_hba *hisi_hba)
 		dma_free_coherent(dev, s,
 				  hisi_hba->itct, hisi_hba->itct_dma);
 
-	s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_iost);
+	s = max_command_entries * sizeof(struct hisi_sas_iost);
 	if (hisi_hba->iost)
 		dma_free_coherent(dev, s,
 				  hisi_hba->iost, hisi_hba->iost_dma);
 
-	s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint);
+	s = max_command_entries * sizeof(struct hisi_sas_breakpoint);
 	if (hisi_hba->breakpoint)
 		dma_free_coherent(dev, s,
 				  hisi_hba->breakpoint,
@@ -1141,7 +1141,7 @@ static void hisi_sas_free(struct hisi_hba *hisi_hba)
 				  hisi_hba->initial_fis,
 				  hisi_hba->initial_fis_dma);
 
-	s = HISI_SAS_COMMAND_ENTRIES * sizeof(struct hisi_sas_breakpoint) * 2;
+	s = max_command_entries * sizeof(struct hisi_sas_breakpoint) * 2;
 	if (hisi_hba->sata_breakpoint)
 		dma_free_coherent(dev, s,
 				  hisi_hba->sata_breakpoint,
@@ -1273,8 +1273,8 @@ int hisi_sas_probe(struct platform_device *pdev,
 	shost->max_channel = 1;
 	shost->max_cmd_len = 16;
 	shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
-	shost->can_queue = HISI_SAS_COMMAND_ENTRIES;
-	shost->cmd_per_lun = HISI_SAS_COMMAND_ENTRIES;
+	shost->can_queue = hisi_hba->hw->max_command_entries;
+	shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
 
 	sha->sas_ha_name = DRV_NAME;
 	sha->dev = &hisi_hba->pdev->dev;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 3d562de..9bbcf6d 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -392,6 +392,8 @@ enum {
 	TRANS_RX_SMP_RESP_TIMEOUT_ERR, /* 0x31a */
 };
 
+#define HISI_SAS_COMMAND_ENTRIES_V1_HW 8192
+
 #define HISI_SAS_PHY_MAX_INT_NR (HISI_SAS_PHY_INT_NR * HISI_SAS_MAX_PHYS)
 #define HISI_SAS_CQ_MAX_INT_NR (HISI_SAS_MAX_QUEUES)
 #define HISI_SAS_FATAL_INT_NR (2)
@@ -1799,6 +1801,7 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = {
 	.phy_disable = disable_phy_v1_hw,
 	.phy_hard_reset = phy_hard_reset_v1_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v1_hw,
+	.max_command_entries = HISI_SAS_COMMAND_ENTRIES_V1_HW,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr),
 };
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 04/23] hisi_sas: reduce max itct entries
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
  2016-01-08 14:15 ` [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings John Garry
  2016-01-08 14:15 ` [PATCH 03/23] hisi_sas: set max commands as configurable John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 05/23] hisi_sas: add hisi_sas_err_record_v1 John Garry
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Since v2 hw only supports 2048 itct entries,
as opposed to 4096 for v1 hw, set the max itct
entries to the lower of the two.

It is not anticipated that any device with v1
will ever require to connect > 2048 devices.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 5ed5cf1..7c05eb3 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -25,7 +25,7 @@
 #define HISI_SAS_MAX_PHYS	9
 #define HISI_SAS_MAX_QUEUES	32
 #define HISI_SAS_QUEUE_SLOTS 512
-#define HISI_SAS_MAX_ITCT_ENTRIES 4096
+#define HISI_SAS_MAX_ITCT_ENTRIES 2048
 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
 
 #define HISI_SAS_STATUS_BUF_SZ \
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 05/23] hisi_sas: add hisi_sas_err_record_v1
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (2 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 04/23] hisi_sas: reduce max itct entries John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 06/23] hisi_sas: rename some fields in hisi_sas_itct John Garry
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Since the error record structure is different for
v2 hw, make hisi_sas_err_record opaque and add
hisi_sas_err_record_v1.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h       | 12 +-----------
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 17 +++++++++++++++--
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 7c05eb3..e5a58c5 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -270,17 +270,7 @@ struct hisi_sas_iost {
 };
 
 struct hisi_sas_err_record {
-	/* dw0 */
-	__le32 dma_err_type;
-
-	/* dw1 */
-	__le32 trans_tx_fail_type;
-
-	/* dw2 */
-	__le32 trans_rx_fail_type;
-
-	/* dw3 */
-	u32 rsvd;
+	u32	data[4];
 };
 
 struct hisi_sas_initial_fis {
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 9bbcf6d..87a0622 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -288,6 +288,20 @@ struct hisi_sas_complete_v1_hdr {
 	__le32 data;
 };
 
+struct hisi_sas_err_record_v1 {
+	/* dw0 */
+	__le32 dma_err_type;
+
+	/* dw1 */
+	__le32 trans_tx_fail_type;
+
+	/* dw2 */
+	__le32 trans_rx_fail_type;
+
+	/* dw3 */
+	u32 rsvd;
+};
+
 enum {
 	HISI_SAS_PHY_BCAST_ACK = 0,
 	HISI_SAS_PHY_SL_PHY_ENABLED,
@@ -1098,7 +1112,7 @@ static void slot_err_v1_hw(struct hisi_hba *hisi_hba,
 			   struct hisi_sas_slot *slot)
 {
 	struct task_status_struct *ts = &task->task_status;
-	struct hisi_sas_err_record *err_record = slot->status_buffer;
+	struct hisi_sas_err_record_v1 *err_record = slot->status_buffer;
 	struct device *dev = &hisi_hba->pdev->dev;
 
 	switch (task->task_proto) {
@@ -1222,7 +1236,6 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba,
 	struct domain_device *device;
 	enum exec_status sts;
 	struct hisi_sas_complete_v1_hdr *complete_queue =
-			(struct hisi_sas_complete_v1_hdr *)
 			hisi_hba->complete_hdr[slot->cmplt_queue];
 	struct hisi_sas_complete_v1_hdr *complete_hdr;
 	u32 cmplt_hdr_data;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 06/23] hisi_sas: rename some fields in hisi_sas_itct
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (3 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 05/23] hisi_sas: add hisi_sas_err_record_v1 John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 07/23] hisi_sas: add bare v2 hw driver John Garry
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Since hisi_sas_itct format is different between v1
and v2 hw, give more general names for some fields.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index e5a58c5..b2e4b26 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -248,18 +248,7 @@ struct hisi_sas_itct {
 	__le64 sas_addr;
 	__le64 qw2;
 	__le64 qw3;
-	__le64 qw4;
-	__le64 qw_sata_ncq0_3;
-	__le64 qw_sata_ncq7_4;
-	__le64 qw_sata_ncq11_8;
-	__le64 qw_sata_ncq15_12;
-	__le64 qw_sata_ncq19_16;
-	__le64 qw_sata_ncq23_20;
-	__le64 qw_sata_ncq27_24;
-	__le64 qw_sata_ncq31_28;
-	__le64 qw_non_ncq_iptt;
-	__le64 qw_rsvd0;
-	__le64 qw_rsvd1;
+	__le64 qw4_15[12];
 };
 
 struct hisi_sas_iost {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 07/23] hisi_sas: add bare v2 hw driver
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (4 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 06/23] hisi_sas: rename some fields in hisi_sas_itct John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 08/23] hisi_sas: add v2 register definitions John Garry
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Just add enough to build and init the module.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/Makefile         |  2 +-
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 48 ++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile
index 3e70eae..c6d3a1b 100644
--- a/drivers/scsi/hisi_sas/Makefile
+++ b/drivers/scsi/hisi_sas/Makefile
@@ -1,2 +1,2 @@
 obj-$(CONFIG_SCSI_HISI_SAS)		+= hisi_sas_main.o
-obj-$(CONFIG_SCSI_HISI_SAS)		+= hisi_sas_v1_hw.o
+obj-$(CONFIG_SCSI_HISI_SAS)		+= hisi_sas_v1_hw.o hisi_sas_v2_hw.o
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
new file mode 100644
index 0000000..0f7f2af
--- /dev/null
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Linaro Ltd.
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include "hisi_sas.h"
+#define DRV_NAME "hisi_sas_v2_hw"
+
+static const struct hisi_sas_hw hisi_sas_v2_hw = {
+};
+
+static int hisi_sas_v2_probe(struct platform_device *pdev)
+{
+	return hisi_sas_probe(pdev, &hisi_sas_v2_hw);
+}
+
+static int hisi_sas_v2_remove(struct platform_device *pdev)
+{
+	return hisi_sas_remove(pdev);
+}
+
+static const struct of_device_id sas_v2_of_match[] = {
+	{ .compatible = "hisilicon,hip06-sas-v2",},
+	{},
+};
+MODULE_DEVICE_TABLE(of, sas_v2_of_match);
+
+static struct platform_driver hisi_sas_v2_driver = {
+	.probe = hisi_sas_v2_probe,
+	.remove = hisi_sas_v2_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = sas_v2_of_match,
+	},
+};
+
+module_platform_driver(hisi_sas_v2_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
+MODULE_DESCRIPTION("HISILICON SAS controller v2 hw driver");
+MODULE_ALIAS("platform:" DRV_NAME);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 08/23] hisi_sas: add v2 register definitions
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (5 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 07/23] hisi_sas: add bare v2 hw driver John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 10/23] hisi_sas: add init_id_frame_v2_hw() John Garry
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 237 +++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 0f7f2af..31e4fdc 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -12,6 +12,243 @@
 #include "hisi_sas.h"
 #define DRV_NAME "hisi_sas_v2_hw"
 
+/* global registers need init*/
+#define DLVRY_QUEUE_ENABLE		0x0
+#define IOST_BASE_ADDR_LO		0x8
+#define IOST_BASE_ADDR_HI		0xc
+#define ITCT_BASE_ADDR_LO		0x10
+#define ITCT_BASE_ADDR_HI		0x14
+#define IO_BROKEN_MSG_ADDR_LO		0x18
+#define IO_BROKEN_MSG_ADDR_HI		0x1c
+#define PHY_CONTEXT			0x20
+#define PHY_STATE			0x24
+#define PHY_PORT_NUM_MA			0x28
+#define PORT_STATE			0x2c
+#define PORT_STATE_PHY8_PORT_NUM_OFF	16
+#define PORT_STATE_PHY8_PORT_NUM_MSK	(0xf << PORT_STATE_PHY8_PORT_NUM_OFF)
+#define PORT_STATE_PHY8_CONN_RATE_OFF	20
+#define PORT_STATE_PHY8_CONN_RATE_MSK	(0xf << PORT_STATE_PHY8_CONN_RATE_OFF)
+#define PHY_CONN_RATE			0x30
+#define HGC_TRANS_TASK_CNT_LIMIT	0x38
+#define AXI_AHB_CLK_CFG			0x3c
+#define ITCT_CLR			0x44
+#define ITCT_CLR_EN_OFF			16
+#define ITCT_CLR_EN_MSK			(0x1 << ITCT_CLR_EN_OFF)
+#define ITCT_DEV_OFF			0
+#define ITCT_DEV_MSK			(0x7ff << ITCT_DEV_OFF)
+#define AXI_USER1			0x48
+#define AXI_USER2			0x4c
+#define IO_SATA_BROKEN_MSG_ADDR_LO	0x58
+#define IO_SATA_BROKEN_MSG_ADDR_HI	0x5c
+#define SATA_INITI_D2H_STORE_ADDR_LO	0x60
+#define SATA_INITI_D2H_STORE_ADDR_HI	0x64
+#define HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL	0x84
+#define HGC_SAS_TXFAIL_RETRY_CTRL	0x88
+#define HGC_GET_ITV_TIME		0x90
+#define DEVICE_MSG_WORK_MODE		0x94
+#define OPENA_WT_CONTI_TIME		0x9c
+#define I_T_NEXUS_LOSS_TIME		0xa0
+#define MAX_CON_TIME_LIMIT_TIME		0xa4
+#define BUS_INACTIVE_LIMIT_TIME		0xa8
+#define REJECT_TO_OPEN_LIMIT_TIME	0xac
+#define CFG_AGING_TIME			0xbc
+#define HGC_DFX_CFG2			0xc0
+#define HGC_IOMB_PROC1_STATUS	0x104
+#define CFG_1US_TIMER_TRSH		0xcc
+#define HGC_INVLD_DQE_INFO		0x148
+#define HGC_INVLD_DQE_INFO_FB_CH0_OFF	9
+#define HGC_INVLD_DQE_INFO_FB_CH0_MSK	(0x1 << HGC_INVLD_DQE_INFO_FB_CH0_OFF)
+#define HGC_INVLD_DQE_INFO_FB_CH3_OFF	18
+#define INT_COAL_EN			0x19c
+#define OQ_INT_COAL_TIME		0x1a0
+#define OQ_INT_COAL_CNT			0x1a4
+#define ENT_INT_COAL_TIME		0x1a8
+#define ENT_INT_COAL_CNT		0x1ac
+#define OQ_INT_SRC			0x1b0
+#define OQ_INT_SRC_MSK			0x1b4
+#define ENT_INT_SRC1			0x1b8
+#define ENT_INT_SRC1_D2H_FIS_CH0_OFF	0
+#define ENT_INT_SRC1_D2H_FIS_CH0_MSK	(0x1 << ENT_INT_SRC1_D2H_FIS_CH0_OFF)
+#define ENT_INT_SRC1_D2H_FIS_CH1_OFF	8
+#define ENT_INT_SRC1_D2H_FIS_CH1_MSK	(0x1 << ENT_INT_SRC1_D2H_FIS_CH1_OFF)
+#define ENT_INT_SRC2			0x1bc
+#define ENT_INT_SRC3			0x1c0
+#define ENT_INT_SRC3_ITC_INT_OFF	15
+#define ENT_INT_SRC3_ITC_INT_MSK	(0x1 << ENT_INT_SRC3_ITC_INT_OFF)
+#define ENT_INT_SRC_MSK1		0x1c4
+#define ENT_INT_SRC_MSK2		0x1c8
+#define ENT_INT_SRC_MSK3		0x1cc
+#define ENT_INT_SRC_MSK3_ENT95_MSK_OFF	31
+#define ENT_INT_SRC_MSK3_ENT95_MSK_MSK	(0x1 << ENT_INT_SRC_MSK3_ENT95_MSK_OFF)
+#define SAS_ECC_INTR_MSK		0x1ec
+#define HGC_ERR_STAT_EN			0x238
+#define DLVRY_Q_0_BASE_ADDR_LO		0x260
+#define DLVRY_Q_0_BASE_ADDR_HI		0x264
+#define DLVRY_Q_0_DEPTH			0x268
+#define DLVRY_Q_0_WR_PTR		0x26c
+#define DLVRY_Q_0_RD_PTR		0x270
+#define HYPER_STREAM_ID_EN_CFG		0xc80
+#define OQ0_INT_SRC_MSK			0xc90
+#define COMPL_Q_0_BASE_ADDR_LO		0x4e0
+#define COMPL_Q_0_BASE_ADDR_HI		0x4e4
+#define COMPL_Q_0_DEPTH			0x4e8
+#define COMPL_Q_0_WR_PTR		0x4ec
+#define COMPL_Q_0_RD_PTR		0x4f0
+
+/* phy registers need init */
+#define PORT_BASE			(0x2000)
+
+#define PHY_CFG				(PORT_BASE + 0x0)
+#define HARD_PHY_LINKRATE		(PORT_BASE + 0x4)
+#define PHY_CFG_ENA_OFF			0
+#define PHY_CFG_ENA_MSK			(0x1 << PHY_CFG_ENA_OFF)
+#define PHY_CFG_DC_OPT_OFF		2
+#define PHY_CFG_DC_OPT_MSK		(0x1 << PHY_CFG_DC_OPT_OFF)
+#define PROG_PHY_LINK_RATE		(PORT_BASE + 0x8)
+#define PROG_PHY_LINK_RATE_MAX_OFF	0
+#define PROG_PHY_LINK_RATE_MAX_MSK	(0xff << PROG_PHY_LINK_RATE_MAX_OFF)
+#define PHY_CTRL			(PORT_BASE + 0x14)
+#define PHY_CTRL_RESET_OFF		0
+#define PHY_CTRL_RESET_MSK		(0x1 << PHY_CTRL_RESET_OFF)
+#define SAS_PHY_CTRL			(PORT_BASE + 0x20)
+#define SL_CFG				(PORT_BASE + 0x84)
+#define PHY_PCN				(PORT_BASE + 0x44)
+#define SL_TOUT_CFG			(PORT_BASE + 0x8c)
+#define SL_CONTROL			(PORT_BASE + 0x94)
+#define SL_CONTROL_NOTIFY_EN_OFF	0
+#define SL_CONTROL_NOTIFY_EN_MSK	(0x1 << SL_CONTROL_NOTIFY_EN_OFF)
+#define TX_ID_DWORD0			(PORT_BASE + 0x9c)
+#define TX_ID_DWORD1			(PORT_BASE + 0xa0)
+#define TX_ID_DWORD2			(PORT_BASE + 0xa4)
+#define TX_ID_DWORD3			(PORT_BASE + 0xa8)
+#define TX_ID_DWORD4			(PORT_BASE + 0xaC)
+#define TX_ID_DWORD5			(PORT_BASE + 0xb0)
+#define TX_ID_DWORD6			(PORT_BASE + 0xb4)
+#define RX_IDAF_DWORD0			(PORT_BASE + 0xc4)
+#define RX_IDAF_DWORD1			(PORT_BASE + 0xc8)
+#define RX_IDAF_DWORD2			(PORT_BASE + 0xcc)
+#define RX_IDAF_DWORD3			(PORT_BASE + 0xd0)
+#define RX_IDAF_DWORD4			(PORT_BASE + 0xd4)
+#define RX_IDAF_DWORD5			(PORT_BASE + 0xd8)
+#define RX_IDAF_DWORD6			(PORT_BASE + 0xdc)
+#define RXOP_CHECK_CFG_H		(PORT_BASE + 0xfc)
+#define DONE_RECEIVED_TIME		(PORT_BASE + 0x11c)
+#define CHL_INT0			(PORT_BASE + 0x1b4)
+#define CHL_INT0_HOTPLUG_TOUT_OFF	0
+#define CHL_INT0_HOTPLUG_TOUT_MSK	(0x1 << CHL_INT0_HOTPLUG_TOUT_OFF)
+#define CHL_INT0_SL_RX_BCST_ACK_OFF	1
+#define CHL_INT0_SL_RX_BCST_ACK_MSK	(0x1 << CHL_INT0_SL_RX_BCST_ACK_OFF)
+#define CHL_INT0_SL_PHY_ENABLE_OFF	2
+#define CHL_INT0_SL_PHY_ENABLE_MSK	(0x1 << CHL_INT0_SL_PHY_ENABLE_OFF)
+#define CHL_INT0_NOT_RDY_OFF		4
+#define CHL_INT0_NOT_RDY_MSK		(0x1 << CHL_INT0_NOT_RDY_OFF)
+#define CHL_INT0_PHY_RDY_OFF		5
+#define CHL_INT0_PHY_RDY_MSK		(0x1 << CHL_INT0_PHY_RDY_OFF)
+#define CHL_INT1			(PORT_BASE + 0x1b8)
+#define CHL_INT1_DMAC_TX_ECC_ERR_OFF	15
+#define CHL_INT1_DMAC_TX_ECC_ERR_MSK	(0x1 << CHL_INT1_DMAC_TX_ECC_ERR_OFF)
+#define CHL_INT1_DMAC_RX_ECC_ERR_OFF	17
+#define CHL_INT1_DMAC_RX_ECC_ERR_MSK	(0x1 << CHL_INT1_DMAC_RX_ECC_ERR_OFF)
+#define CHL_INT2			(PORT_BASE + 0x1bc)
+#define CHL_INT0_MSK			(PORT_BASE + 0x1c0)
+#define CHL_INT1_MSK			(PORT_BASE + 0x1c4)
+#define CHL_INT2_MSK			(PORT_BASE + 0x1c8)
+#define CHL_INT_COAL_EN			(PORT_BASE + 0x1d0)
+#define PHY_CTRL_RDY_MSK		(PORT_BASE + 0x2b0)
+#define PHYCTRL_NOT_RDY_MSK		(PORT_BASE + 0x2b4)
+#define PHYCTRL_DWS_RESET_MSK		(PORT_BASE + 0x2b8)
+#define PHYCTRL_PHY_ENA_MSK		(PORT_BASE + 0x2bc)
+#define SL_RX_BCAST_CHK_MSK		(PORT_BASE + 0x2c0)
+#define PHYCTRL_OOB_RESTART_MSK		(PORT_BASE + 0x2c4)
+#define DMA_TX_STATUS			(PORT_BASE + 0x2d0)
+#define DMA_TX_STATUS_BUSY_OFF		0
+#define DMA_TX_STATUS_BUSY_MSK		(0x1 << DMA_TX_STATUS_BUSY_OFF)
+#define DMA_RX_STATUS			(PORT_BASE + 0x2e8)
+#define DMA_RX_STATUS_BUSY_OFF		0
+#define DMA_RX_STATUS_BUSY_MSK		(0x1 << DMA_RX_STATUS_BUSY_OFF)
+
+#define AXI_CFG				(0x5100)
+#define AM_CFG_MAX_TRANS		(0x5010)
+#define AM_CFG_SINGLE_PORT_MAX_TRANS	(0x5014)
+
+/* HW dma structures */
+/* Delivery queue header */
+/* dw0 */
+#define CMD_HDR_RESP_REPORT_OFF		5
+#define CMD_HDR_RESP_REPORT_MSK		(0x1 << CMD_HDR_RESP_REPORT_OFF)
+#define CMD_HDR_TLR_CTRL_OFF		6
+#define CMD_HDR_TLR_CTRL_MSK		(0x3 << CMD_HDR_TLR_CTRL_OFF)
+#define CMD_HDR_PORT_OFF		18
+#define CMD_HDR_PORT_MSK		(0xf << CMD_HDR_PORT_OFF)
+#define CMD_HDR_PRIORITY_OFF		27
+#define CMD_HDR_PRIORITY_MSK		(0x1 << CMD_HDR_PRIORITY_OFF)
+#define CMD_HDR_CMD_OFF			29
+#define CMD_HDR_CMD_MSK			(0x7 << CMD_HDR_CMD_OFF)
+/* dw1 */
+#define CMD_HDR_DIR_OFF			5
+#define CMD_HDR_DIR_MSK			(0x3 << CMD_HDR_DIR_OFF)
+#define CMD_HDR_RESET_OFF		7
+#define CMD_HDR_RESET_MSK		(0x1 << CMD_HDR_RESET_OFF)
+#define CMD_HDR_VDTL_OFF		10
+#define CMD_HDR_VDTL_MSK		(0x1 << CMD_HDR_VDTL_OFF)
+#define CMD_HDR_FRAME_TYPE_OFF		11
+#define CMD_HDR_FRAME_TYPE_MSK		(0x1f << CMD_HDR_FRAME_TYPE_OFF)
+#define CMD_HDR_DEV_ID_OFF		16
+#define CMD_HDR_DEV_ID_MSK		(0xffff << CMD_HDR_DEV_ID_OFF)
+/* dw2 */
+#define CMD_HDR_CFL_OFF			0
+#define CMD_HDR_CFL_MSK			(0x1ff << CMD_HDR_CFL_OFF)
+#define CMD_HDR_NCQ_TAG_OFF		10
+#define CMD_HDR_NCQ_TAG_MSK		(0x1f << CMD_HDR_NCQ_TAG_OFF)
+#define CMD_HDR_MRFL_OFF		15
+#define CMD_HDR_MRFL_MSK		(0x1ff << CMD_HDR_MRFL_OFF)
+#define CMD_HDR_SG_MOD_OFF		24
+#define CMD_HDR_SG_MOD_MSK		(0x3 << CMD_HDR_SG_MOD_OFF)
+#define CMD_HDR_FIRST_BURST_OFF		26
+#define CMD_HDR_FIRST_BURST_MSK		(0x1 << CMD_HDR_SG_MOD_OFF)
+/* dw3 */
+#define CMD_HDR_IPTT_OFF		0
+#define CMD_HDR_IPTT_MSK		(0xffff << CMD_HDR_IPTT_OFF)
+/* dw6 */
+#define CMD_HDR_DIF_SGL_LEN_OFF		0
+#define CMD_HDR_DIF_SGL_LEN_MSK		(0xffff << CMD_HDR_DIF_SGL_LEN_OFF)
+#define CMD_HDR_DATA_SGL_LEN_OFF	16
+#define CMD_HDR_DATA_SGL_LEN_MSK	(0xffff << CMD_HDR_DATA_SGL_LEN_OFF)
+
+/* Completion header */
+/* dw0 */
+#define CMPLT_HDR_RSPNS_XFRD_OFF	10
+#define CMPLT_HDR_RSPNS_XFRD_MSK	(0x1 << CMPLT_HDR_RSPNS_XFRD_OFF)
+#define CMPLT_HDR_ERX_OFF		12
+#define CMPLT_HDR_ERX_MSK		(0x1 << CMPLT_HDR_ERX_OFF)
+/* dw1 */
+#define CMPLT_HDR_IPTT_OFF		0
+#define CMPLT_HDR_IPTT_MSK		(0xffff << CMPLT_HDR_IPTT_OFF)
+#define CMPLT_HDR_DEV_ID_OFF		16
+#define CMPLT_HDR_DEV_ID_MSK		(0xffff << CMPLT_HDR_DEV_ID_OFF)
+
+/* ITCT header */
+/* qw0 */
+#define ITCT_HDR_DEV_TYPE_OFF		0
+#define ITCT_HDR_DEV_TYPE_MSK		(0x3 << ITCT_HDR_DEV_TYPE_OFF)
+#define ITCT_HDR_VALID_OFF		2
+#define ITCT_HDR_VALID_MSK		(0x1 << ITCT_HDR_VALID_OFF)
+#define ITCT_HDR_MCR_OFF		5
+#define ITCT_HDR_MCR_MSK		(0xf << ITCT_HDR_MCR_OFF)
+#define ITCT_HDR_VLN_OFF		9
+#define ITCT_HDR_VLN_MSK		(0xf << ITCT_HDR_VLN_OFF)
+#define ITCT_HDR_PORT_ID_OFF		28
+#define ITCT_HDR_PORT_ID_MSK		(0xf << ITCT_HDR_PORT_ID_OFF)
+/* qw2 */
+#define ITCT_HDR_INLT_OFF		0
+#define ITCT_HDR_INLT_MSK		(0xffffULL << ITCT_HDR_INLT_OFF)
+#define ITCT_HDR_BITLT_OFF		16
+#define ITCT_HDR_BITLT_MSK		(0xffffULL << ITCT_HDR_BITLT_OFF)
+#define ITCT_HDR_MCTLT_OFF		32
+#define ITCT_HDR_MCTLT_MSK		(0xffffULL << ITCT_HDR_MCTLT_OFF)
+#define ITCT_HDR_RTOLT_OFF		48
+#define ITCT_HDR_RTOLT_MSK		(0xffffULL << ITCT_HDR_RTOLT_OFF)
+
 static const struct hisi_sas_hw hisi_sas_v2_hw = {
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 09/23] hisi_sas: add v2 hw init
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
  2016-01-08 14:15   ` [PATCH 02/23] hisi_sas: relocate DEV_IS_EXPANDER John Garry
@ 2016-01-08 14:15   ` John Garry
  2016-01-08 15:07     ` Mark Rutland
  2016-01-08 14:15   ` [PATCH 13/23] hisi_sas: add v2 phy down handler John Garry
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley-wo1vFcy6AUs, martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ
  Cc: linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA, John Garry

Signed-off-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 287 +++++++++++++++++++++++++++++++++
 1 file changed, 287 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 31e4fdc..dbb3968 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -249,7 +249,294 @@
 #define ITCT_HDR_RTOLT_OFF		48
 #define ITCT_HDR_RTOLT_MSK		(0xffffULL << ITCT_HDR_RTOLT_OFF)
 
+struct hisi_sas_complete_v2_hdr {
+	__le32 dw0;
+	__le32 dw1;
+	__le32 act;
+	__le32 dw3;
+};
+
+#define HISI_SAS_COMMAND_ENTRIES_V2_HW 4096
+
+static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
+{
+	void __iomem *regs = hisi_hba->regs + off;
+
+	return readl(regs);
+}
+
+static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val)
+{
+	void __iomem *regs = hisi_hba->regs + off;
+
+	writel(val, regs);
+}
+
+static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, int phy_no,
+				 u32 off, u32 val)
+{
+	void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off;
+
+	writel(val, regs);
+}
+
+static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
+				      int phy_no, u32 off)
+{
+	void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off;
+
+	return readl(regs);
+}
+
+static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
+{
+	int i, reset_val;
+	u32 val;
+	unsigned long end_time;
+	struct device *dev = &hisi_hba->pdev->dev;
+
+	/* The mask needs to be set depending on the number of phys */
+	if (hisi_hba->n_phy == 9)
+		reset_val = 0x1fffff;
+	else
+		reset_val = 0x7ffff;
+
+	/* Disable all of the DQ */
+	for (i = 0; i < HISI_SAS_MAX_QUEUES; i++)
+		hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0);
+
+	/* Disable all of the PHYs */
+	for (i = 0; i < hisi_hba->n_phy; i++) {
+		u32 phy_cfg = hisi_sas_phy_read32(hisi_hba, i, PHY_CFG);
+
+		phy_cfg &= ~PHY_CTRL_RESET_MSK;
+		hisi_sas_phy_write32(hisi_hba, i, PHY_CFG, phy_cfg);
+	}
+	udelay(50);
+
+	/* Ensure DMA tx & rx idle */
+	for (i = 0; i < hisi_hba->n_phy; i++) {
+		u32 dma_tx_status, dma_rx_status;
+
+		end_time = jiffies + msecs_to_jiffies(1000);
+
+		while (1) {
+			dma_tx_status = hisi_sas_phy_read32(hisi_hba, i,
+							    DMA_TX_STATUS);
+			dma_rx_status = hisi_sas_phy_read32(hisi_hba, i,
+							    DMA_RX_STATUS);
+
+			if (!(dma_tx_status & DMA_TX_STATUS_BUSY_MSK) &&
+				!(dma_rx_status & DMA_RX_STATUS_BUSY_MSK))
+				break;
+
+			msleep(20);
+			if (time_after(jiffies, end_time))
+				return -EIO;
+		}
+	}
+
+	/* Ensure axi bus idle */
+	end_time = jiffies + msecs_to_jiffies(1000);
+	while (1) {
+		u32 axi_status =
+			hisi_sas_read32(hisi_hba, AXI_CFG);
+
+		if (axi_status == 0)
+			break;
+
+		msleep(20);
+		if (time_after(jiffies, end_time))
+			return -EIO;
+	}
+
+	/* reset and disable clock*/
+	regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg,
+			reset_val);
+	regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg + 4,
+			reset_val);
+	msleep(1);
+	regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val);
+	if (reset_val != (val & reset_val)) {
+		dev_err(dev, "SAS reset fail.\n");
+		return -EIO;
+	}
+
+	/* De-reset and enable clock*/
+	regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg + 4,
+			reset_val);
+	regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg,
+			reset_val);
+	msleep(1);
+	regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg,
+			&val);
+	if (val & reset_val) {
+		dev_err(dev, "SAS de-reset fail.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
+{
+	struct device *dev = &hisi_hba->pdev->dev;
+	struct device_node *np = dev->of_node;
+	int i;
+
+	/* Global registers init*/
+	if (of_get_property(np, "am-max-trans", NULL)) {
+		hisi_sas_write32(hisi_hba, AM_CFG_MAX_TRANS, 0x2020);
+		hisi_sas_write32(hisi_hba, AM_CFG_SINGLE_PORT_MAX_TRANS,
+				 0x2020);
+	}
+
+	hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE,
+			 (u32)((1ULL << hisi_hba->queue_count) - 1));
+	hisi_sas_write32(hisi_hba, AXI_USER1, 0xc0000000);
+	hisi_sas_write32(hisi_hba, AXI_USER2, 0x10000);
+	hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108);
+	hisi_sas_write32(hisi_hba, HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL, 0x7FF);
+	hisi_sas_write32(hisi_hba, OPENA_WT_CONTI_TIME, 0x1);
+	hisi_sas_write32(hisi_hba, I_T_NEXUS_LOSS_TIME, 0x1F4);
+	hisi_sas_write32(hisi_hba, MAX_CON_TIME_LIMIT_TIME, 0x4E20);
+	hisi_sas_write32(hisi_hba, BUS_INACTIVE_LIMIT_TIME, 0x1);
+	hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1);
+	hisi_sas_write32(hisi_hba, HGC_ERR_STAT_EN, 0x1);
+	hisi_sas_write32(hisi_hba, HGC_GET_ITV_TIME, 0x1);
+	hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
+	hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
+	hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
+	hisi_sas_write32(hisi_hba, ENT_INT_COAL_TIME, 0x1);
+	hisi_sas_write32(hisi_hba, ENT_INT_COAL_CNT, 0x1);
+	hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0x0);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0x7efefefe);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0x7efefefe);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0x7ffffffe);
+	hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0xfffff3c0);
+	for (i = 0; i < hisi_hba->queue_count; i++)
+		hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0);
+
+	hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 1);
+	hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);
+
+
+	for (i = 0; i < hisi_hba->n_phy; i++) {
+		hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855);
+		hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, 0x30b9908);
+		hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d);
+		hisi_sas_phy_write32(hisi_hba, i, DONE_RECEIVED_TIME, 0x10);
+		hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff);
+		hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
+		hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
+		hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
+		hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xffffffff);
+		hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbff);
+		hisi_sas_phy_write32(hisi_hba, i, SL_CFG, 0x23f801fc);
+		hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
+		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
+		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
+		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0);
+		hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0);
+		hisi_sas_phy_write32(hisi_hba, i, CHL_INT_COAL_EN, 0x0);
+		hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x0);
+		hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, 0x199B694);
+	}
+
+	for (i = 0; i < hisi_hba->queue_count; i++) {
+		/* Delivery queue */
+		hisi_sas_write32(hisi_hba,
+				 DLVRY_Q_0_BASE_ADDR_HI + (i * 0x14),
+				 upper_32_bits(hisi_hba->cmd_hdr_dma[i]));
+
+		hisi_sas_write32(hisi_hba, DLVRY_Q_0_BASE_ADDR_LO + (i * 0x14),
+				 lower_32_bits(hisi_hba->cmd_hdr_dma[i]));
+
+		hisi_sas_write32(hisi_hba, DLVRY_Q_0_DEPTH + (i * 0x14),
+				 HISI_SAS_QUEUE_SLOTS);
+
+		/* Completion queue */
+		hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_HI + (i * 0x14),
+				 upper_32_bits(hisi_hba->complete_hdr_dma[i]));
+
+		hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_LO + (i * 0x14),
+				 lower_32_bits(hisi_hba->complete_hdr_dma[i]));
+
+		hisi_sas_write32(hisi_hba, COMPL_Q_0_DEPTH + (i * 0x14),
+				 HISI_SAS_QUEUE_SLOTS);
+	}
+
+	/* itct */
+	hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_LO,
+			 lower_32_bits(hisi_hba->itct_dma));
+
+	hisi_sas_write32(hisi_hba, ITCT_BASE_ADDR_HI,
+			 upper_32_bits(hisi_hba->itct_dma));
+
+	/* iost */
+	hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_LO,
+			 lower_32_bits(hisi_hba->iost_dma));
+
+	hisi_sas_write32(hisi_hba, IOST_BASE_ADDR_HI,
+			 upper_32_bits(hisi_hba->iost_dma));
+
+	/* breakpoint */
+	hisi_sas_write32(hisi_hba, IO_BROKEN_MSG_ADDR_LO,
+			 lower_32_bits(hisi_hba->breakpoint_dma));
+
+	hisi_sas_write32(hisi_hba, IO_BROKEN_MSG_ADDR_HI,
+			 upper_32_bits(hisi_hba->breakpoint_dma));
+
+	/* SATA broken msg */
+	hisi_sas_write32(hisi_hba, IO_SATA_BROKEN_MSG_ADDR_LO,
+			 lower_32_bits(hisi_hba->sata_breakpoint_dma));
+
+	hisi_sas_write32(hisi_hba, IO_SATA_BROKEN_MSG_ADDR_HI,
+			 upper_32_bits(hisi_hba->sata_breakpoint_dma));
+
+	/* SATA initial fis */
+	hisi_sas_write32(hisi_hba, SATA_INITI_D2H_STORE_ADDR_LO,
+			 lower_32_bits(hisi_hba->initial_fis_dma));
+
+	hisi_sas_write32(hisi_hba, SATA_INITI_D2H_STORE_ADDR_HI,
+			 upper_32_bits(hisi_hba->initial_fis_dma));
+}
+
+static int hw_init_v2_hw(struct hisi_hba *hisi_hba)
+{
+	struct device *dev = &hisi_hba->pdev->dev;
+	int rc;
+
+	rc = reset_hw_v2_hw(hisi_hba);
+	if (rc) {
+		dev_err(dev, "hisi_sas_reset_hw failed, rc=%d", rc);
+		return rc;
+	}
+
+	msleep(100);
+	init_reg_v2_hw(hisi_hba);
+
+	return 0;
+}
+
+static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
+{
+	int rc;
+
+	rc = hw_init_v2_hw(hisi_hba);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
 static const struct hisi_sas_hw hisi_sas_v2_hw = {
+	.hw_init = hisi_sas_v2_init,
+	.max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW,
+	.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),
 };
 
 static int hisi_sas_v2_probe(struct platform_device *pdev)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 10/23] hisi_sas: add init_id_frame_v2_hw()
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (6 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 08/23] hisi_sas: add v2 register definitions John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 11/23] hisi_sas: add v2 phy init code John Garry
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 40 ++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index dbb3968..6ab0503 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -288,6 +288,44 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
 	return readl(regs);
 }
 
+static void config_id_frame_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	struct sas_identify_frame identify_frame;
+	u32 *identify_buffer;
+
+	memset(&identify_frame, 0, sizeof(identify_frame));
+	identify_frame.dev_type = SAS_END_DEVICE;
+	identify_frame.frame_type = 0;
+	identify_frame._un1 = 1;
+	identify_frame.initiator_bits = SAS_PROTOCOL_ALL;
+	identify_frame.target_bits = SAS_PROTOCOL_NONE;
+	memcpy(&identify_frame._un4_11[0], hisi_hba->sas_addr, SAS_ADDR_SIZE);
+	memcpy(&identify_frame.sas_addr[0], hisi_hba->sas_addr,	SAS_ADDR_SIZE);
+	identify_frame.phy_id = phy_no;
+	identify_buffer = (u32 *)(&identify_frame);
+
+	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0,
+			__swab32(identify_buffer[0]));
+	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1,
+			identify_buffer[2]);
+	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2,
+			identify_buffer[1]);
+	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3,
+			identify_buffer[4]);
+	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4,
+			identify_buffer[3]);
+	hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5,
+			__swab32(identify_buffer[5]));
+}
+
+static void init_id_frame_v2_hw(struct hisi_hba *hisi_hba)
+{
+	int i;
+
+	for (i = 0; i < hisi_hba->n_phy; i++)
+		config_id_frame_v2_hw(hisi_hba, i);
+}
+
 static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
 {
 	int i, reset_val;
@@ -519,6 +557,8 @@ static int hw_init_v2_hw(struct hisi_hba *hisi_hba)
 	msleep(100);
 	init_reg_v2_hw(hisi_hba);
 
+	init_id_frame_v2_hw(hisi_hba);
+
 	return 0;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 11/23] hisi_sas: add v2 phy init code
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (7 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 10/23] hisi_sas: add init_id_frame_v2_hw() John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 12/23] hisi_sas: add v2 int init and phy up handler John Garry
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 49 ++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 6ab0503..325b287 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -288,6 +288,15 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
 	return readl(regs);
 }
 
+static void config_phy_opt_mode_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);
+
+	cfg &= ~PHY_CFG_DC_OPT_MSK;
+	cfg |= 1 << PHY_CFG_DC_OPT_OFF;
+	hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);
+}
+
 static void config_id_frame_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
 {
 	struct sas_identify_frame identify_frame;
@@ -562,6 +571,44 @@ static int hw_init_v2_hw(struct hisi_hba *hisi_hba)
 	return 0;
 }
 
+static void enable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);
+
+	cfg |= PHY_CFG_ENA_MSK;
+	hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);
+}
+
+static void start_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	config_id_frame_v2_hw(hisi_hba, phy_no);
+	config_phy_opt_mode_v2_hw(hisi_hba, phy_no);
+	enable_phy_v2_hw(hisi_hba, phy_no);
+}
+
+static void start_phys_v2_hw(unsigned long data)
+{
+	struct hisi_hba *hisi_hba = (struct hisi_hba *)data;
+	int i;
+
+	for (i = 0; i < hisi_hba->n_phy; i++)
+		start_phy_v2_hw(hisi_hba, i);
+}
+
+static void phys_init_v2_hw(struct hisi_hba *hisi_hba)
+{
+	int i;
+	struct timer_list *timer = &hisi_hba->timer;
+
+	for (i = 0; i < hisi_hba->n_phy; i++) {
+		hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x6a);
+		hisi_sas_phy_read32(hisi_hba, i, CHL_INT2_MSK);
+	}
+
+	setup_timer(timer, start_phys_v2_hw, (unsigned long)hisi_hba);
+	mod_timer(timer, jiffies + HZ);
+}
+
 static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
 {
 	int rc;
@@ -570,6 +617,8 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
 	if (rc)
 		return rc;
 
+	phys_init_v2_hw(hisi_hba);
+
 	return 0;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 12/23] hisi_sas: add v2 int init and phy up handler
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (8 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 11/23] hisi_sas: add v2 phy init code John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 14/23] hisi_sas: add v2 channel interrupt handler John Garry
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 171 +++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 325b287..ba2f792 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -256,6 +256,11 @@ struct hisi_sas_complete_v2_hdr {
 	__le32 dw3;
 };
 
+enum {
+	HISI_SAS_PHY_PHY_UPDOWN,
+	HISI_SAS_PHY_INT_NR
+};
+
 #define HISI_SAS_COMMAND_ENTRIES_V2_HW 4096
 
 static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
@@ -609,6 +614,167 @@ static void phys_init_v2_hw(struct hisi_hba *hisi_hba)
 	mod_timer(timer, jiffies + HZ);
 }
 
+static void sl_notify_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	u32 sl_control;
+
+	sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
+	sl_control |= SL_CONTROL_NOTIFY_EN_MSK;
+	hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);
+	msleep(1);
+	sl_control = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
+	sl_control &= ~SL_CONTROL_NOTIFY_EN_MSK;
+	hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);
+}
+
+static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
+{
+	int i, res = 0;
+	u32 context, port_id, link_rate, hard_phy_linkrate;
+	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+	struct device *dev = &hisi_hba->pdev->dev;
+	u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd;
+	struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd;
+
+	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
+
+	/* Check for SATA dev */
+	context = hisi_sas_read32(hisi_hba, PHY_CONTEXT);
+	if (context & (1 << phy_no))
+		goto end;
+
+	if (phy_no == 8) {
+		u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);
+
+		port_id = (port_state & PORT_STATE_PHY8_PORT_NUM_MSK) >>
+			  PORT_STATE_PHY8_PORT_NUM_OFF;
+		link_rate = (port_state & PORT_STATE_PHY8_CONN_RATE_MSK) >>
+			    PORT_STATE_PHY8_CONN_RATE_OFF;
+	} else {
+		port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
+		port_id = (port_id >> (4 * phy_no)) & 0xf;
+		link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
+		link_rate = (link_rate >> (phy_no * 4)) & 0xf;
+	}
+
+	if (port_id == 0xf) {
+		dev_err(dev, "phyup: phy%d invalid portid\n", phy_no);
+		res = IRQ_NONE;
+		goto end;
+	}
+
+	for (i = 0; i < 6; i++) {
+		u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no,
+					       RX_IDAF_DWORD0 + (i * 4));
+		frame_rcvd[i] = __swab32(idaf);
+	}
+
+	/* Get the linkrates */
+	link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
+	link_rate = (link_rate >> (phy_no * 4)) & 0xf;
+	sas_phy->linkrate = link_rate;
+	hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
+						HARD_PHY_LINKRATE);
+	phy->maximum_linkrate = hard_phy_linkrate & 0xf;
+	phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
+
+	sas_phy->oob_mode = SAS_OOB_MODE;
+	memcpy(sas_phy->attached_sas_addr, &id->sas_addr, SAS_ADDR_SIZE);
+	dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
+	phy->port_id = port_id;
+	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
+	phy->phy_type |= PORT_TYPE_SAS;
+	phy->phy_attached = 1;
+	phy->identify.device_type = id->dev_type;
+	phy->frame_rcvd_size =	sizeof(struct sas_identify_frame);
+	if (phy->identify.device_type == SAS_END_DEVICE)
+		phy->identify.target_port_protocols =
+			SAS_PROTOCOL_SSP;
+	else if (phy->identify.device_type != SAS_PHY_UNUSED)
+		phy->identify.target_port_protocols =
+			SAS_PROTOCOL_SMP;
+	queue_work(hisi_hba->wq, &phy->phyup_ws);
+
+end:
+	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+			     CHL_INT0_SL_PHY_ENABLE_MSK);
+	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0);
+
+	return res;
+}
+
+static irqreturn_t int_phy_updown_v2_hw(int irq_no, void *p)
+{
+	struct hisi_hba *hisi_hba = p;
+	u32 irq_msk;
+	int phy_no = 0;
+	irqreturn_t res = IRQ_HANDLED;
+
+	irq_msk = (hisi_sas_read32(hisi_hba, HGC_INVLD_DQE_INFO)
+		   >> HGC_INVLD_DQE_INFO_FB_CH0_OFF) & 0x1ff;
+	while (irq_msk) {
+		if (irq_msk  & 1) {
+			u32 irq_value = hisi_sas_phy_read32(hisi_hba, phy_no,
+							    CHL_INT0);
+
+			if (irq_value & CHL_INT0_SL_PHY_ENABLE_MSK)
+				/* phy up */
+				if (phy_up_v2_hw(phy_no, hisi_hba)) {
+					res = IRQ_NONE;
+					goto end;
+				}
+
+		}
+		irq_msk >>= 1;
+		phy_no++;
+	}
+
+end:
+	return res;
+}
+
+static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = {
+	int_phy_updown_v2_hw,
+};
+
+/**
+ * There is a limitation in the hip06 chipset that we need
+ * to map in all mbigen interrupts, even if they are not used.
+ */
+static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
+{
+	struct platform_device *pdev = hisi_hba->pdev;
+	struct device *dev = &pdev->dev;
+	int i, irq, rc, irq_map[128];
+
+
+	for (i = 0; i < 128; i++)
+		irq_map[i] = platform_get_irq(pdev, i);
+
+	for (i = 0; i < HISI_SAS_PHY_INT_NR; i++) {
+		int idx = i;
+
+		irq = irq_map[idx + 1]; /* Phy up/down is irq1 */
+		if (!irq) {
+			dev_err(dev, "irq init: fail map phy interrupt %d\n",
+				idx);
+			return -ENOENT;
+		}
+
+		rc = devm_request_irq(dev, irq, phy_interrupts[i], 0,
+				      DRV_NAME " phy", hisi_hba);
+		if (rc) {
+			dev_err(dev, "irq init: could not request "
+				"phy interrupt %d, rc=%d\n",
+				irq, rc);
+			return -ENOENT;
+		}
+	}
+
+	return 0;
+}
+
 static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
 {
 	int rc;
@@ -617,6 +783,10 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
 	if (rc)
 		return rc;
 
+	rc = interrupt_init_v2_hw(hisi_hba);
+	if (rc)
+		return rc;
+
 	phys_init_v2_hw(hisi_hba);
 
 	return 0;
@@ -624,6 +794,7 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
 
 static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.hw_init = hisi_sas_v2_init,
+	.sl_notify = sl_notify_v2_hw,
 	.max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 13/23] hisi_sas: add v2 phy down handler
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
  2016-01-08 14:15   ` [PATCH 02/23] hisi_sas: relocate DEV_IS_EXPANDER John Garry
  2016-01-08 14:15   ` [PATCH 09/23] hisi_sas: add v2 hw init John Garry
@ 2016-01-08 14:15   ` John Garry
  2016-01-08 14:15   ` [PATCH 18/23] hisi_sas: add v2 code to send smp command John Garry
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley-wo1vFcy6AUs, martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ
  Cc: linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA, John Garry

Signed-off-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 49 ++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index ba2f792..d70e5d7 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -627,6 +627,29 @@ static void sl_notify_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
 	hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);
 }
 
+static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
+{
+	int i, bitmap = 0;
+	u32 phy_port_num_ma = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
+	u32 phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
+
+	for (i = 0; i < (hisi_hba->n_phy < 9 ? hisi_hba->n_phy : 8); i++)
+		if (phy_state & 1 << i)
+			if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id)
+				bitmap |= 1 << i;
+
+	if (hisi_hba->n_phy == 9) {
+		u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);
+
+		if (phy_state & 1 << 8)
+			if (((port_state & PORT_STATE_PHY8_PORT_NUM_MSK) >>
+			     PORT_STATE_PHY8_PORT_NUM_OFF) == port_id)
+				bitmap |= 1 << 9;
+	}
+
+	return bitmap;
+}
+
 static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
 	int i, res = 0;
@@ -704,6 +727,25 @@ end:
 	return res;
 }
 
+static int phy_down_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
+{
+	int res = 0;
+	u32 phy_cfg, phy_state;
+
+	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1);
+
+	phy_cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);
+
+	phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
+
+	hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0);
+
+	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_NOT_RDY_MSK);
+	hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 0);
+
+	return res;
+}
+
 static irqreturn_t int_phy_updown_v2_hw(int irq_no, void *p)
 {
 	struct hisi_hba *hisi_hba = p;
@@ -725,6 +767,12 @@ static irqreturn_t int_phy_updown_v2_hw(int irq_no, void *p)
 					goto end;
 				}
 
+			if (irq_value & CHL_INT0_NOT_RDY_MSK)
+				/* phy down */
+				if (phy_down_v2_hw(phy_no, hisi_hba)) {
+					res = IRQ_NONE;
+					goto end;
+				}
 		}
 		irq_msk >>= 1;
 		phy_no++;
@@ -795,6 +843,7 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
 static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.hw_init = hisi_sas_v2_init,
 	.sl_notify = sl_notify_v2_hw,
+	.get_wideport_bitmap = get_wideport_bitmap_v2_hw,
 	.max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),
 };
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 14/23] hisi_sas: add v2 channel interrupt handler
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (9 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 12/23] hisi_sas: add v2 int init and phy up handler John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 15/23] hisi_sas: add v2 SATA " John Garry
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

This also includes broadcast handler. Unlike v1 hw,
broadcast does not have its own dedicated interrupt.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 79 ++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index d70e5d7..f276d20 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -258,6 +258,7 @@ struct hisi_sas_complete_v2_hdr {
 
 enum {
 	HISI_SAS_PHY_PHY_UPDOWN,
+	HISI_SAS_PHY_CHNL_INT,
 	HISI_SAS_PHY_INT_NR
 };
 
@@ -782,8 +783,86 @@ end:
 	return res;
 }
 
+static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
+{
+	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+	struct sas_ha_struct *sas_ha = &hisi_hba->sha;
+	unsigned long flags;
+
+	hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);
+
+	spin_lock_irqsave(&hisi_hba->lock, flags);
+	sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
+	spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
+	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+			     CHL_INT0_SL_RX_BCST_ACK_MSK);
+	hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
+}
+
+static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
+{
+	struct hisi_hba *hisi_hba = p;
+	struct device *dev = &hisi_hba->pdev->dev;
+	u32 ent_msk, ent_tmp, irq_msk;
+	int phy_no = 0;
+
+	ent_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK3);
+	ent_tmp = ent_msk;
+	ent_msk |= ENT_INT_SRC_MSK3_ENT95_MSK_MSK;
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, ent_msk);
+
+	irq_msk = (hisi_sas_read32(hisi_hba, HGC_INVLD_DQE_INFO) >>
+			HGC_INVLD_DQE_INFO_FB_CH3_OFF) & 0x1ff;
+
+	while (irq_msk) {
+		if (irq_msk & (1 << phy_no)) {
+			u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no,
+							     CHL_INT0);
+			u32 irq_value1 = hisi_sas_phy_read32(hisi_hba, phy_no,
+							     CHL_INT1);
+			u32 irq_value2 = hisi_sas_phy_read32(hisi_hba, phy_no,
+							     CHL_INT2);
+
+			if (irq_value1) {
+				if (irq_value1 & (CHL_INT1_DMAC_RX_ECC_ERR_MSK |
+						  CHL_INT1_DMAC_TX_ECC_ERR_MSK))
+					panic("%s: DMAC RX/TX ecc bad error! (0x%x)",
+						dev_name(dev), irq_value1);
+
+				hisi_sas_phy_write32(hisi_hba, phy_no,
+						     CHL_INT1, irq_value1);
+			}
+
+			if (irq_value2)
+				hisi_sas_phy_write32(hisi_hba, phy_no,
+						     CHL_INT2, irq_value2);
+
+
+			if (irq_value0) {
+				if (irq_value0 & CHL_INT0_SL_RX_BCST_ACK_MSK)
+					phy_bcast_v2_hw(phy_no, hisi_hba);
+
+				hisi_sas_phy_write32(hisi_hba, phy_no,
+						CHL_INT0, irq_value0
+						& (~CHL_INT0_HOTPLUG_TOUT_MSK)
+						& (~CHL_INT0_SL_PHY_ENABLE_MSK)
+						& (~CHL_INT0_NOT_RDY_MSK));
+			}
+		}
+		irq_msk &= ~(1 << phy_no);
+		phy_no++;
+	}
+
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, ent_tmp);
+
+	return IRQ_HANDLED;
+}
+
 static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = {
 	int_phy_updown_v2_hw,
+	int_chnl_int_v2_hw,
 };
 
 /**
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 15/23] hisi_sas: add v2 SATA interrupt handler
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (10 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 14/23] hisi_sas: add v2 channel interrupt handler John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 16/23] hisi_sas: add v2 cq " John Garry
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 99 ++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index f276d20..43a2c95 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -860,6 +860,85 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t sata_int_v2_hw(int irq_no, void *p)
+{
+	struct hisi_sas_phy *phy = p;
+	struct hisi_hba *hisi_hba = phy->hisi_hba;
+	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+	struct device *dev = &hisi_hba->pdev->dev;
+	struct	hisi_sas_initial_fis *initial_fis;
+	struct dev_to_host_fis *fis;
+	u32 ent_tmp, ent_msk, ent_int, port_id, link_rate, hard_phy_linkrate;
+	irqreturn_t res = IRQ_HANDLED;
+	u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};
+	int phy_no;
+
+	phy_no = sas_phy->id;
+	initial_fis = &hisi_hba->initial_fis[phy_no];
+	fis = &initial_fis->fis;
+
+	ent_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK1);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, ent_msk | 1 << phy_no);
+
+	ent_int = hisi_sas_read32(hisi_hba, ENT_INT_SRC1);
+	ent_tmp = ent_int;
+	ent_int >>= ENT_INT_SRC1_D2H_FIS_CH1_OFF * (phy_no % 4);
+	if ((ent_int & ENT_INT_SRC1_D2H_FIS_CH0_MSK) == 0) {
+		dev_warn(dev, "sata int: phy%d did not receive FIS\n", phy_no);
+		hisi_sas_write32(hisi_hba, ENT_INT_SRC1, ent_tmp);
+		hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, ent_msk);
+		res = IRQ_NONE;
+		goto end;
+	}
+
+	if (unlikely(phy_no == 8)) {
+		u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);
+
+		port_id = (port_state & PORT_STATE_PHY8_PORT_NUM_MSK) >>
+			  PORT_STATE_PHY8_PORT_NUM_OFF;
+		link_rate = (port_state & PORT_STATE_PHY8_CONN_RATE_MSK) >>
+			    PORT_STATE_PHY8_CONN_RATE_OFF;
+	} else {
+		port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
+		port_id = (port_id >> (4 * phy_no)) & 0xf;
+		link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
+		link_rate = (link_rate >> (phy_no * 4)) & 0xf;
+	}
+
+	if (port_id == 0xf) {
+		dev_err(dev, "sata int: phy%d invalid portid\n", phy_no);
+		res = IRQ_NONE;
+		goto end;
+	}
+
+	sas_phy->linkrate = link_rate;
+	hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
+						HARD_PHY_LINKRATE);
+	phy->maximum_linkrate = hard_phy_linkrate & 0xf;
+	phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
+
+	sas_phy->oob_mode = SATA_OOB_MODE;
+	/* Make up some unique SAS address */
+	attached_sas_addr[0] = 0x50;
+	attached_sas_addr[7] = phy_no;
+	memcpy(sas_phy->attached_sas_addr, attached_sas_addr, SAS_ADDR_SIZE);
+	memcpy(sas_phy->frame_rcvd, fis, sizeof(struct dev_to_host_fis));
+	dev_info(dev, "sata int phyup: phy%d link_rate=%d\n", phy_no, link_rate);
+	phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
+	phy->phy_type |= PORT_TYPE_SATA;
+	phy->phy_attached = 1;
+	phy->identify.device_type = SAS_SATA_DEV;
+	phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);
+	phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
+	queue_work(hisi_hba->wq, &phy->phyup_ws);
+
+end:
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC1, ent_tmp);
+	hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, ent_msk);
+
+	return res;
+}
+
 static irq_handler_t phy_interrupts[HISI_SAS_PHY_INT_NR] = {
 	int_phy_updown_v2_hw,
 	int_chnl_int_v2_hw,
@@ -899,6 +978,26 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
 		}
 	}
 
+	for (i = 0; i < hisi_hba->n_phy; i++) {
+		struct hisi_sas_phy *phy = &hisi_hba->phy[i];
+		int idx = i + 72; /* First SATA interrupt is irq72 */
+
+		irq = irq_map[idx];
+		if (!irq) {
+			dev_err(dev, "irq init: fail map phy interrupt %d\n",
+				idx);
+			return -ENOENT;
+		}
+
+		rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0,
+				      DRV_NAME " sata", phy);
+		if (rc) {
+			dev_err(dev, "irq init: could not request "
+				"sata interrupt %d, rc=%d\n",
+				irq, rc);
+			return -ENOENT;
+		}
+	}
 	return 0;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 16/23] hisi_sas: add v2 cq interrupt handler
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (11 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 15/23] hisi_sas: add v2 SATA " John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 17:29   ` kbuild test robot
  2016-01-08 14:15 ` [PATCH 17/23] hisi_sas: add v2 path to send ssp frame John Garry
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Also include slot_complete_v2_hw handler

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 196 +++++++++++++++++++++++++++++++++
 1 file changed, 196 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 43a2c95..0beb6a9 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -651,6 +651,112 @@ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
 	return bitmap;
 }
 
+static int
+slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot,
+		    int abort)
+{
+	struct sas_task *task = slot->task;
+	struct hisi_sas_device *sas_dev;
+	struct device *dev = &hisi_hba->pdev->dev;
+	struct task_status_struct *ts;
+	struct domain_device *device;
+	enum exec_status sts;
+	struct hisi_sas_complete_v2_hdr *complete_queue =
+			hisi_hba->complete_hdr[slot->cmplt_queue];
+	struct hisi_sas_complete_v2_hdr *complete_hdr =
+			&complete_queue[slot->cmplt_queue_slot];
+
+	if (unlikely(!task || !task->lldd_task || !task->dev))
+		return -EINVAL;
+
+	ts = &task->task_status;
+	device = task->dev;
+	sas_dev = device->lldd_dev;
+
+	task->task_state_flags &=
+		~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR);
+	task->task_state_flags |= SAS_TASK_STATE_DONE;
+
+	memset(ts, 0, sizeof(*ts));
+	ts->resp = SAS_TASK_COMPLETE;
+
+	if (unlikely(!sas_dev || abort)) {
+		if (!sas_dev)
+			dev_dbg(dev, "slot complete: port has not device\n");
+		ts->stat = SAS_PHY_DOWN;
+		goto out;
+	}
+
+	if ((complete_hdr->dw0) & CMPLT_HDR_ERX_MSK &&
+		!((complete_hdr->dw0) & CMPLT_HDR_RSPNS_XFRD_MSK)) {
+		dev_dbg(dev, "%s slot %d has error info 0x%x\n",
+			__func__, slot->cmplt_queue_slot,
+			(complete_hdr->dw0) & CMPLT_HDR_ERX_MSK);
+
+		goto out;
+	}
+
+	switch (task->task_proto) {
+	case SAS_PROTOCOL_SSP:
+	{
+		struct ssp_response_iu *iu = slot->status_buffer +
+			sizeof(struct hisi_sas_err_record);
+
+		sas_ssp_task_response(dev, task, iu);
+		break;
+	}
+	case SAS_PROTOCOL_SMP:
+	{
+		struct scatterlist *sg_resp = &task->smp_task.smp_resp;
+		void *to;
+
+		ts->stat = SAM_STAT_GOOD;
+		to = kmap_atomic(sg_page(sg_resp));
+
+		dma_unmap_sg(dev, &task->smp_task.smp_resp, 1,
+			     DMA_FROM_DEVICE);
+		dma_unmap_sg(dev, &task->smp_task.smp_req, 1,
+			     DMA_TO_DEVICE);
+		memcpy(to + sg_resp->offset,
+		       slot->status_buffer +
+		       sizeof(struct hisi_sas_err_record),
+		       sg_dma_len(sg_resp));
+		kunmap_atomic(to);
+		break;
+	}
+	case SAS_PROTOCOL_SATA:
+	case SAS_PROTOCOL_STP:
+	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+	{
+		ts->stat = SAM_STAT_GOOD;
+		sata_done_v2_hw(hisi_hba, task, slot);
+		break;
+	}
+
+	default:
+		ts->stat = SAM_STAT_CHECK_CONDITION;
+		break;
+	}
+
+	if (!slot->port->port_attached) {
+		dev_err(dev, "slot complete: port %d has removed\n",
+			slot->port->sas_port.id);
+		ts->stat = SAS_PHY_DOWN;
+	}
+
+out:
+	if (sas_dev && sas_dev->running_req)
+		sas_dev->running_req--;
+
+	hisi_sas_slot_task_free(hisi_hba, task, slot);
+	sts = ts->stat;
+
+	if (task->task_done)
+		task->task_done(task);
+
+	return sts;
+}
+
 static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
 	int i, res = 0;
@@ -860,6 +966,74 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p)
+{
+	struct hisi_sas_cq *cq = p;
+	struct hisi_hba *hisi_hba = cq->hisi_hba;
+	struct hisi_sas_slot *slot;
+	struct hisi_sas_itct *itct;
+	struct hisi_sas_complete_v2_hdr *complete_queue;
+	u32 irq_value, rd_point, wr_point, dev_id;
+	int queue = cq->id;
+
+	complete_queue = hisi_hba->complete_hdr[queue];
+	irq_value = hisi_sas_read32(hisi_hba, OQ_INT_SRC);
+
+	hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue);
+
+	rd_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_RD_PTR +
+				   (0x14 * queue));
+	wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR +
+				   (0x14 * queue));
+
+	while (rd_point != wr_point) {
+		struct hisi_sas_complete_v2_hdr *complete_hdr;
+		int iptt;
+
+		complete_hdr = &complete_queue[rd_point];
+
+		/* Check for NCQ completion */
+		if (complete_hdr->act) {
+			u32 act_tmp = complete_hdr->act;
+			int ncq_tag_count = ffs(act_tmp);
+
+			dev_id = (complete_hdr->dw1 & CMPLT_HDR_DEV_ID_MSK) >>
+				 CMPLT_HDR_DEV_ID_OFF;
+			itct = &hisi_hba->itct[dev_id];
+
+			/* The NCQ tags are held in the itct header */
+			while (ncq_tag_count) {
+				__le64 *ncq_tag = &itct->qw4_15[0];
+
+				ncq_tag_count -= 1;
+				iptt = (ncq_tag[ncq_tag_count / 5]
+					>> (ncq_tag_count % 5) * 12) & 0xfff;
+
+				slot = &hisi_hba->slot_info[iptt];
+				slot->cmplt_queue_slot = rd_point;
+				slot->cmplt_queue = queue;
+				slot_complete_v2_hw(hisi_hba, slot, 0);
+
+				act_tmp &= ~(1 << ncq_tag_count);
+				ncq_tag_count = ffs(act_tmp);
+			}
+		} else {
+			iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
+			slot = &hisi_hba->slot_info[iptt];
+			slot->cmplt_queue_slot = rd_point;
+			slot->cmplt_queue = queue;
+			slot_complete_v2_hw(hisi_hba, slot, 0);
+		}
+
+		if (++rd_point >= HISI_SAS_QUEUE_SLOTS)
+			rd_point = 0;
+	}
+
+	/* update rd_point */
+	hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point);
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t sata_int_v2_hw(int irq_no, void *p)
 {
 	struct hisi_sas_phy *phy = p;
@@ -998,6 +1172,27 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
 			return -ENOENT;
 		}
 	}
+
+	for (i = 0; i < hisi_hba->queue_count; i++) {
+		int idx = i + 96; /* First cq interrupt is irq96 */
+
+		irq = irq_map[idx];
+		if (!irq) {
+			dev_err(dev,
+				"irq init: could not map cq interrupt %d\n",
+				idx);
+			return -ENOENT;
+		}
+		rc = devm_request_irq(dev, irq, cq_interrupt_v2_hw, 0,
+				      DRV_NAME " cq", &hisi_hba->cq[i]);
+		if (rc) {
+			dev_err(dev,
+				"irq init: could not request cq interrupt %d, rc=%d\n",
+				irq, rc);
+			return -ENOENT;
+		}
+	}
+
 	return 0;
 }
 
@@ -1022,6 +1217,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.hw_init = hisi_sas_v2_init,
 	.sl_notify = sl_notify_v2_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v2_hw,
+	.slot_complete = slot_complete_v2_hw,
 	.max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 17/23] hisi_sas: add v2 path to send ssp frame
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (12 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 16/23] hisi_sas: add v2 cq " John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 19/23] hisi_sas: add v2 code for itct setup and free John Garry
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Include code to prep ssp frame and deliver
to hardware.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 185 +++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 0beb6a9..e9d3db9 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -264,6 +264,11 @@ enum {
 
 #define HISI_SAS_COMMAND_ENTRIES_V2_HW 4096
 
+#define DIR_NO_DATA 0
+#define DIR_TO_INI 1
+#define DIR_TO_DEVICE 2
+#define DIR_RESERVED 3
+
 static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
 {
 	void __iomem *regs = hisi_hba->regs + off;
@@ -271,6 +276,13 @@ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
 	return readl(regs);
 }
 
+static u32 hisi_sas_read32_relaxed(struct hisi_hba *hisi_hba, u32 off)
+{
+	void __iomem *regs = hisi_hba->regs + off;
+
+	return readl_relaxed(regs);
+}
+
 static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val)
 {
 	void __iomem *regs = hisi_hba->regs + off;
@@ -651,6 +663,176 @@ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
 	return bitmap;
 }
 
+/**
+ * This function allocates across all queues to load balance.
+ * Slots are allocated from queues in a round-robin fashion.
+ *
+ * The callpath to this function and upto writing the write
+ * queue pointer should be safe from interruption.
+ */
+static int get_free_slot_v2_hw(struct hisi_hba *hisi_hba, int *q, int *s)
+{
+	struct device *dev = &hisi_hba->pdev->dev;
+	u32 r, w;
+	int queue = hisi_hba->queue;
+
+	while (1) {
+		w = hisi_sas_read32_relaxed(hisi_hba,
+					    DLVRY_Q_0_WR_PTR + (queue * 0x14));
+		r = hisi_sas_read32_relaxed(hisi_hba,
+					    DLVRY_Q_0_RD_PTR + (queue * 0x14));
+		if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) {
+			queue = (queue + 1) % hisi_hba->queue_count;
+			if (queue == hisi_hba->queue) {
+				dev_warn(dev, "could not find free slot\n");
+				return -EAGAIN;
+			}
+			continue;
+		}
+		break;
+	}
+	hisi_hba->queue = (queue + 1) % hisi_hba->queue_count;
+	*q = queue;
+	*s = w;
+	return 0;
+}
+
+static void start_delivery_v2_hw(struct hisi_hba *hisi_hba)
+{
+	int dlvry_queue = hisi_hba->slot_prep->dlvry_queue;
+	int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot;
+
+	hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14),
+			 ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS);
+}
+
+static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,
+			      struct hisi_sas_slot *slot,
+			      struct hisi_sas_cmd_hdr *hdr,
+			      struct scatterlist *scatter,
+			      int n_elem)
+{
+	struct device *dev = &hisi_hba->pdev->dev;
+	struct scatterlist *sg;
+	int i;
+
+	if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
+		dev_err(dev, "prd err: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
+			n_elem);
+		return -EINVAL;
+	}
+
+	slot->sge_page = dma_pool_alloc(hisi_hba->sge_page_pool, GFP_ATOMIC,
+					&slot->sge_page_dma);
+	if (!slot->sge_page)
+		return -ENOMEM;
+
+	for_each_sg(scatter, sg, n_elem, i) {
+		struct hisi_sas_sge *entry = &slot->sge_page->sge[i];
+
+		entry->addr = cpu_to_le64(sg_dma_address(sg));
+		entry->page_ctrl_0 = entry->page_ctrl_1 = 0;
+		entry->data_len = cpu_to_le32(sg_dma_len(sg));
+		entry->data_off = 0;
+	}
+
+	hdr->prd_table_addr = cpu_to_le64(slot->sge_page_dma);
+
+	hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF);
+
+	return 0;
+}
+
+static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
+			  struct hisi_sas_slot *slot, int is_tmf,
+			  struct hisi_sas_tmf_task *tmf)
+{
+	struct sas_task *task = slot->task;
+	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+	struct domain_device *device = task->dev;
+	struct hisi_sas_device *sas_dev = device->lldd_dev;
+	struct hisi_sas_port *port = slot->port;
+	struct sas_ssp_task *ssp_task = &task->ssp_task;
+	struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+	int has_data = 0, rc, priority = is_tmf;
+	u8 *buf_cmd;
+	u32 dw1 = 0, dw2 = 0;
+
+	hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) |
+			       (2 << CMD_HDR_TLR_CTRL_OFF) |
+			       (port->id << CMD_HDR_PORT_OFF) |
+			       (priority << CMD_HDR_PRIORITY_OFF) |
+			       (1 << CMD_HDR_CMD_OFF)); /* ssp */
+
+	dw1 = 1 << CMD_HDR_VDTL_OFF;
+	if (is_tmf) {
+		dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF;
+		dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF;
+	} else {
+		dw1 |= 1 << CMD_HDR_FRAME_TYPE_OFF;
+		switch (scsi_cmnd->sc_data_direction) {
+		case DMA_TO_DEVICE:
+			has_data = 1;
+			dw1 |= DIR_TO_DEVICE << CMD_HDR_DIR_OFF;
+			break;
+		case DMA_FROM_DEVICE:
+			has_data = 1;
+			dw1 |= DIR_TO_INI << CMD_HDR_DIR_OFF;
+			break;
+		default:
+			dw1 &= ~CMD_HDR_DIR_MSK;
+		}
+	}
+
+	/* map itct entry */
+	dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+	hdr->dw1 = cpu_to_le32(dw1);
+
+	dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr)
+	      + 3) / 4) << CMD_HDR_CFL_OFF) |
+	      ((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) |
+	      (2 << CMD_HDR_SG_MOD_OFF);
+	hdr->dw2 = cpu_to_le32(dw2);
+
+	hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+	if (has_data) {
+		rc = prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,
+					slot->n_elem);
+		if (rc)
+			return rc;
+	}
+
+	hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
+	hdr->cmd_table_addr = cpu_to_le64(slot->command_table_dma);
+	hdr->sts_buffer_addr = cpu_to_le64(slot->status_buffer_dma);
+
+	buf_cmd = slot->command_table + sizeof(struct ssp_frame_hdr);
+
+	memcpy(buf_cmd, &task->ssp_task.LUN, 8);
+	if (!is_tmf) {
+		buf_cmd[9] = task->ssp_task.task_attr |
+				(task->ssp_task.task_prio << 3);
+		memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd,
+				task->ssp_task.cmd->cmd_len);
+	} else {
+		buf_cmd[10] = tmf->tmf;
+		switch (tmf->tmf) {
+		case TMF_ABORT_TASK:
+		case TMF_QUERY_TASK:
+			buf_cmd[12] =
+				(tmf->tag_of_task_to_be_managed >> 8) & 0xff;
+			buf_cmd[13] =
+				tmf->tag_of_task_to_be_managed & 0xff;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
 static int
 slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot,
 		    int abort)
@@ -1217,6 +1399,9 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.hw_init = hisi_sas_v2_init,
 	.sl_notify = sl_notify_v2_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v2_hw,
+	.prep_ssp = prep_ssp_v2_hw,
+	.get_free_slot = get_free_slot_v2_hw,
+	.start_delivery = start_delivery_v2_hw,
 	.slot_complete = slot_complete_v2_hw,
 	.max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 18/23] hisi_sas: add v2 code to send smp command
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-01-08 14:15   ` [PATCH 13/23] hisi_sas: add v2 phy down handler John Garry
@ 2016-01-08 14:15   ` John Garry
  2016-01-08 14:15   ` [PATCH 20/23] hisi_sas: add v2 path to send ATA command John Garry
  2016-01-08 14:31   ` [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
  5 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley-wo1vFcy6AUs, martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ
  Cc: linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA, John Garry

Signed-off-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 71 ++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index e9d3db9..94499b1 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -743,6 +743,76 @@ static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,
 	return 0;
 }
 
+static int prep_smp_v2_hw(struct hisi_hba *hisi_hba,
+			  struct hisi_sas_slot *slot)
+{
+	struct sas_task *task = slot->task;
+	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+	struct domain_device *device = task->dev;
+	struct device *dev = &hisi_hba->pdev->dev;
+	struct hisi_sas_port *port = slot->port;
+	struct scatterlist *sg_req, *sg_resp;
+	struct hisi_sas_device *sas_dev = device->lldd_dev;
+	dma_addr_t req_dma_addr;
+	unsigned int req_len, resp_len;
+	int elem, rc;
+
+	/*
+	* DMA-map SMP request, response buffers
+	*/
+	/* req */
+	sg_req = &task->smp_task.smp_req;
+	elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE);
+	if (!elem)
+		return -ENOMEM;
+	req_len = sg_dma_len(sg_req);
+	req_dma_addr = sg_dma_address(sg_req);
+
+	/* resp */
+	sg_resp = &task->smp_task.smp_resp;
+	elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE);
+	if (!elem) {
+		rc = -ENOMEM;
+		goto err_out_req;
+	}
+	resp_len = sg_dma_len(sg_resp);
+	if ((req_len & 0x3) || (resp_len & 0x3)) {
+		rc = -EINVAL;
+		goto err_out_resp;
+	}
+
+	/* create header */
+	/* dw0 */
+	hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) |
+			       (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */
+			       (2 << CMD_HDR_CMD_OFF)); /* smp */
+
+	/* map itct entry */
+	hdr->dw1 = cpu_to_le32((sas_dev->device_id << CMD_HDR_DEV_ID_OFF) |
+			       (1 << CMD_HDR_FRAME_TYPE_OFF) |
+			       (DIR_NO_DATA << CMD_HDR_DIR_OFF));
+
+	/* dw2 */
+	hdr->dw2 = cpu_to_le32((((req_len - 4) / 4) << CMD_HDR_CFL_OFF) |
+			       (HISI_SAS_MAX_SMP_RESP_SZ / 4 <<
+			       CMD_HDR_MRFL_OFF));
+
+	hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF);
+
+	hdr->cmd_table_addr = cpu_to_le64(req_dma_addr);
+	hdr->sts_buffer_addr = cpu_to_le64(slot->status_buffer_dma);
+
+	return 0;
+
+err_out_resp:
+	dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1,
+		     DMA_FROM_DEVICE);
+err_out_req:
+	dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1,
+		     DMA_TO_DEVICE);
+	return rc;
+}
+
 static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
 			  struct hisi_sas_slot *slot, int is_tmf,
 			  struct hisi_sas_tmf_task *tmf)
@@ -1399,6 +1469,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.hw_init = hisi_sas_v2_init,
 	.sl_notify = sl_notify_v2_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v2_hw,
+	.prep_smp = prep_smp_v2_hw,
 	.prep_ssp = prep_ssp_v2_hw,
 	.get_free_slot = get_free_slot_v2_hw,
 	.start_delivery = start_delivery_v2_hw,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 19/23] hisi_sas: add v2 code for itct setup and free
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (13 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 17/23] hisi_sas: add v2 path to send ssp frame John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 21/23] hisi_sas: add v2 slot error handler John Garry
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 91 ++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 94499b1..eca505f 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -353,6 +353,95 @@ static void init_id_frame_v2_hw(struct hisi_hba *hisi_hba)
 		config_id_frame_v2_hw(hisi_hba, i);
 }
 
+static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,
+			     struct hisi_sas_device *sas_dev)
+{
+	struct domain_device *device = sas_dev->sas_device;
+	struct device *dev = &hisi_hba->pdev->dev;
+	u64 qw0, device_id = sas_dev->device_id;
+	struct hisi_sas_itct *itct = &hisi_hba->itct[device_id];
+	struct domain_device *parent_dev = device->parent;
+
+	memset(itct, 0, sizeof(*itct));
+
+	/* qw0 */
+	qw0 = 0;
+	switch (sas_dev->dev_type) {
+	case SAS_END_DEVICE:
+	case SAS_EDGE_EXPANDER_DEVICE:
+	case SAS_FANOUT_EXPANDER_DEVICE:
+		qw0 = HISI_SAS_DEV_TYPE_SSP << ITCT_HDR_DEV_TYPE_OFF;
+		break;
+	case SAS_SATA_DEV:
+		if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
+			qw0 = HISI_SAS_DEV_TYPE_STP << ITCT_HDR_DEV_TYPE_OFF;
+		else
+			qw0 = HISI_SAS_DEV_TYPE_SATA << ITCT_HDR_DEV_TYPE_OFF;
+		break;
+	default:
+		dev_warn(dev, "setup itct: unsupported dev type (%d)\n",
+			 sas_dev->dev_type);
+	}
+
+	qw0 |= ((1 << ITCT_HDR_VALID_OFF) |
+		(device->max_linkrate << ITCT_HDR_MCR_OFF) |
+		(1 << ITCT_HDR_VLN_OFF) |
+		(device->port->id << ITCT_HDR_PORT_ID_OFF));
+	itct->qw0 = cpu_to_le64(qw0);
+
+	/* qw1 */
+	memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
+	itct->sas_addr = __swab64(itct->sas_addr);
+
+	/* qw2 */
+	itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_INLT_OFF) |
+				(0xff00ULL << ITCT_HDR_BITLT_OFF) |
+				(0xff00ULL << ITCT_HDR_MCTLT_OFF) |
+				(0xff00ULL << ITCT_HDR_RTOLT_OFF));
+}
+
+static void free_device_v2_hw(struct hisi_hba *hisi_hba,
+			      struct hisi_sas_device *sas_dev)
+{
+	u64 qw0, dev_id = sas_dev->device_id;
+	struct device *dev = &hisi_hba->pdev->dev;
+	struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id];
+	u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
+	int i;
+
+	/* clear the itct interrupt state */
+	if (ENT_INT_SRC3_ITC_INT_MSK & reg_val)
+		hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
+				 ENT_INT_SRC3_ITC_INT_MSK);
+
+	/* clear the itct int*/
+	for (i = 0; i < 2; i++) {
+		/* clear the itct table*/
+		reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR);
+		reg_val |= ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK);
+		hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val);
+
+		udelay(10);
+		reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
+		if (ENT_INT_SRC3_ITC_INT_MSK & reg_val) {
+			dev_dbg(dev, "got clear ITCT done interrupt\n");
+
+			/* invalid the itct state*/
+			qw0 = cpu_to_le64(itct->qw0);
+			qw0 &= ~(1 << ITCT_HDR_VALID_OFF);
+			hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
+					 ENT_INT_SRC3_ITC_INT_MSK);
+			hisi_hba->devices[dev_id].dev_type = SAS_PHY_UNUSED;
+			hisi_hba->devices[dev_id].dev_status = HISI_SAS_DEV_NORMAL;
+
+			/* clear the itct */
+			hisi_sas_write32(hisi_hba, ITCT_CLR, 0);
+			dev_dbg(dev, "clear ITCT ok\n");
+			break;
+		}
+	}
+}
+
 static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
 {
 	int i, reset_val;
@@ -1467,8 +1556,10 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
 
 static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.hw_init = hisi_sas_v2_init,
+	.setup_itct = setup_itct_v2_hw,
 	.sl_notify = sl_notify_v2_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v2_hw,
+	.free_device = free_device_v2_hw,
 	.prep_smp = prep_smp_v2_hw,
 	.prep_ssp = prep_ssp_v2_hw,
 	.get_free_slot = get_free_slot_v2_hw,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 20/23] hisi_sas: add v2 path to send ATA command
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-01-08 14:15   ` [PATCH 18/23] hisi_sas: add v2 code to send smp command John Garry
@ 2016-01-08 14:15   ` John Garry
  2016-01-08 14:31   ` [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
  5 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley-wo1vFcy6AUs, martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ
  Cc: linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA, John Garry

Signed-off-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 drivers/scsi/hisi_sas/hisi_sas.h       |   4 +
 drivers/scsi/hisi_sas/hisi_sas_main.c  |   8 ++
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 160 +++++++++++++++++++++++++++++++++
 3 files changed, 172 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index b2e4b26..f00b55b 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -18,6 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <scsi/sas_ata.h>
 #include <scsi/libsas.h>
 
 #define DRV_VERSION "v1.0"
@@ -35,6 +36,7 @@
 
 #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024)
 #define HISI_SAS_MAX_SMP_RESP_SZ 1028
+#define HISI_SAS_MAX_STP_RESP_SZ 28
 
 #define DEV_IS_EXPANDER(type) \
 	((type == SAS_EDGE_EXPANDER_DEVICE) || \
@@ -135,6 +137,8 @@ struct hisi_sas_hw {
 			struct hisi_sas_tmf_task *tmf);
 	int (*prep_smp)(struct hisi_hba *hisi_hba,
 			struct hisi_sas_slot *slot);
+	int (*prep_stp)(struct hisi_hba *hisi_hba,
+			struct hisi_sas_slot *slot);
 	int (*slot_complete)(struct hisi_hba *hisi_hba,
 			     struct hisi_sas_slot *slot, int abort);
 	void (*phy_enable)(struct hisi_hba *hisi_hba, int phy_no);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index c48df6d..406b515 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -107,6 +107,12 @@ static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba,
 	return hisi_hba->hw->prep_ssp(hisi_hba, slot, is_tmf, tmf);
 }
 
+static int hisi_sas_task_prep_ata(struct hisi_hba *hisi_hba,
+				  struct hisi_sas_slot *slot)
+{
+	return hisi_hba->hw->prep_stp(hisi_hba, slot);
+}
+
 static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
 			      int is_tmf, struct hisi_sas_tmf_task *tmf,
 			      int *pass)
@@ -230,6 +236,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
 	case SAS_PROTOCOL_SATA:
 	case SAS_PROTOCOL_STP:
 	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+		rc = hisi_sas_task_prep_ata(hisi_hba, slot);
+		break;
 	default:
 		dev_err(dev, "task prep: unknown/unsupported proto (0x%x)\n",
 			task->task_proto);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index eca505f..1c5be50 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -269,6 +269,12 @@ enum {
 #define DIR_TO_DEVICE 2
 #define DIR_RESERVED 3
 
+#define SATA_PROTOCOL_NONDATA		0x1
+#define SATA_PROTOCOL_PIO		0x2
+#define SATA_PROTOCOL_DMA		0x4
+#define SATA_PROTOCOL_FPDMA		0x8
+#define SATA_PROTOCOL_ATAPI		0x10
+
 static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
 {
 	void __iomem *regs = hisi_hba->regs + off;
@@ -992,6 +998,19 @@ static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
 	return 0;
 }
 
+static void sata_done_v2_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
+			    struct hisi_sas_slot *slot)
+{
+	struct task_status_struct *ts = &task->task_status;
+	struct ata_task_resp *resp = (struct ata_task_resp *)ts->buf;
+	struct dev_to_host_fis *d2h = slot->status_buffer +
+				      sizeof(struct hisi_sas_err_record);
+
+	resp->frame_len = sizeof(struct dev_to_host_fis);
+	memcpy(&resp->ending_fis[0], d2h, sizeof(struct dev_to_host_fis));
+
+	ts->buf_valid_size = sizeof(*resp);
+}
 static int
 slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot,
 		    int abort)
@@ -1098,6 +1117,146 @@ out:
 	return sts;
 }
 
+static u8 get_ata_protocol(u8 cmd, int direction)
+{
+	switch (cmd) {
+	case ATA_CMD_FPDMA_WRITE:
+	case ATA_CMD_FPDMA_READ:
+	return SATA_PROTOCOL_FPDMA;
+
+	case ATA_CMD_ID_ATA:
+	case ATA_CMD_PMP_READ:
+	case ATA_CMD_READ_LOG_EXT:
+	case ATA_CMD_PIO_READ:
+	case ATA_CMD_PIO_READ_EXT:
+	case ATA_CMD_PMP_WRITE:
+	case ATA_CMD_WRITE_LOG_EXT:
+	case ATA_CMD_PIO_WRITE:
+	case ATA_CMD_PIO_WRITE_EXT:
+	return SATA_PROTOCOL_PIO;
+
+	case ATA_CMD_READ:
+	case ATA_CMD_READ_EXT:
+	case ATA_CMD_READ_LOG_DMA_EXT:
+	case ATA_CMD_WRITE:
+	case ATA_CMD_WRITE_EXT:
+	case ATA_CMD_WRITE_QUEUED:
+	case ATA_CMD_WRITE_LOG_DMA_EXT:
+	return SATA_PROTOCOL_DMA;
+
+	case ATA_CMD_DOWNLOAD_MICRO:
+	case ATA_CMD_DEV_RESET:
+	case ATA_CMD_CHK_POWER:
+	case ATA_CMD_FLUSH:
+	case ATA_CMD_FLUSH_EXT:
+	case ATA_CMD_VERIFY:
+	case ATA_CMD_VERIFY_EXT:
+	case ATA_CMD_SET_FEATURES:
+	case ATA_CMD_STANDBY:
+	case ATA_CMD_STANDBYNOW1:
+	return SATA_PROTOCOL_NONDATA;
+	default:
+		if (direction == DMA_NONE)
+			return SATA_PROTOCOL_NONDATA;
+		return SATA_PROTOCOL_PIO;
+	}
+}
+
+static int get_ncq_tag_v2_hw(struct sas_task *task, u32 *tag)
+{
+	struct ata_queued_cmd *qc = task->uldd_task;
+
+	if (qc) {
+		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
+			qc->tf.command == ATA_CMD_FPDMA_READ) {
+			*tag = qc->tag;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+		struct hisi_sas_slot *slot)
+{
+	struct sas_task *task = slot->task;
+	struct domain_device *device = task->dev;
+	struct domain_device *parent_dev = device->parent;
+	struct hisi_sas_device *sas_dev = device->lldd_dev;
+	struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+	struct asd_sas_port *sas_port = device->port;
+	u8 *buf_cmd;
+	int has_data = 0, rc = 0, hdr_tag = 0;
+	u32 dw1 = 0, dw2 = 0;
+
+	/* create header */
+	/* dw0 */
+	hdr->dw0 = cpu_to_le32(sas_port->id << CMD_HDR_PORT_OFF);
+	if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
+		hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF);
+	else
+		hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF);
+
+	/* dw1 */
+	switch (task->data_dir) {
+	case DMA_TO_DEVICE:
+		has_data = 1;
+		dw1 |= DIR_TO_DEVICE << CMD_HDR_DIR_OFF;
+		break;
+	case DMA_FROM_DEVICE:
+		has_data = 1;
+		dw1 |= DIR_TO_INI << CMD_HDR_DIR_OFF;
+		break;
+	default:
+		dw1 &= ~CMD_HDR_DIR_MSK;
+	}
+
+	if (0 == task->ata_task.fis.command)
+		dw1 |= 1 << CMD_HDR_RESET_OFF;
+
+	dw1 |= (get_ata_protocol(task->ata_task.fis.command, task->data_dir))
+		<< CMD_HDR_FRAME_TYPE_OFF;
+	dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+	hdr->dw1 = cpu_to_le32(dw1);
+
+	/* dw2 */
+	if (task->ata_task.use_ncq && get_ncq_tag_v2_hw(task, &hdr_tag)) {
+		task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
+		dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF;
+	}
+
+	dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF |
+			2 << CMD_HDR_SG_MOD_OFF;
+	hdr->dw2 = cpu_to_le32(dw2);
+
+	/* dw3 */
+	hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+	if (has_data) {
+		rc = prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,
+					slot->n_elem);
+		if (rc)
+			return rc;
+	}
+
+
+	hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
+	hdr->cmd_table_addr = cpu_to_le64(slot->command_table_dma);
+	hdr->sts_buffer_addr = cpu_to_le64(slot->status_buffer_dma);
+
+	buf_cmd = slot->command_table;
+
+	if (likely(!task->ata_task.device_control_reg_update))
+		task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
+	/* fill in command FIS and ATAPI CDB */
+	memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
+	if (device->sata_dev.class == ATA_DEV_ATAPI)
+		memcpy(buf_cmd + 0x20, task->ata_task.atapi_packet,
+		       ATAPI_CDB_LEN);
+
+	return 0;
+}
+
 static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
 {
 	int i, res = 0;
@@ -1562,6 +1721,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.free_device = free_device_v2_hw,
 	.prep_smp = prep_smp_v2_hw,
 	.prep_ssp = prep_ssp_v2_hw,
+	.prep_stp = prep_ata_v2_hw,
 	.get_free_slot = get_free_slot_v2_hw,
 	.start_delivery = start_delivery_v2_hw,
 	.slot_complete = slot_complete_v2_hw,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 21/23] hisi_sas: add v2 slot error handler
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (14 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 19/23] hisi_sas: add v2 code for itct setup and free John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 22/23] hisi_sas: add v2 tmf functions John Garry
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 421 +++++++++++++++++++++++++++++++++
 1 file changed, 421 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 1c5be50..0d9365b 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -256,12 +256,165 @@ struct hisi_sas_complete_v2_hdr {
 	__le32 dw3;
 };
 
+struct hisi_sas_err_record_v2 {
+	/* dw0 */
+	__le32 trans_tx_fail_type;
+
+	/* dw1 */
+	__le32 trans_rx_fail_type;
+
+	/* dw2 */
+	__le16 dma_tx_err_type;
+	__le16 sipc_rx_err_type;
+
+	/* dw3 */
+	__le32 dma_rx_err_type;
+};
+
 enum {
 	HISI_SAS_PHY_PHY_UPDOWN,
 	HISI_SAS_PHY_CHNL_INT,
 	HISI_SAS_PHY_INT_NR
 };
 
+enum {
+	TRANS_TX_FAIL_BASE = 0x0, /* dw0 */
+	TRANS_RX_FAIL_BASE = 0x100, /* dw1 */
+	DMA_TX_ERR_BASE = 0x200, /* dw2 bit 15-0 */
+	SIPC_RX_ERR_BASE = 0x300, /* dw2 bit 31-16*/
+	DMA_RX_ERR_BASE = 0x400, /* dw3 */
+
+	/* trans tx*/
+	TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS = TRANS_TX_FAIL_BASE, /* 0x0 */
+	TRANS_TX_ERR_PHY_NOT_ENABLE, /* 0x1 */
+	TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION, /* 0x2 */
+	TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION, /* 0x3 */
+	TRANS_TX_OPEN_CNX_ERR_BY_OTHER, /* 0x4 */
+	RESERVED0, /* 0x5 */
+	TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT, /* 0x6 */
+	TRANS_TX_OPEN_CNX_ERR_STP_RESOURCES_BUSY, /* 0x7 */
+	TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED, /* 0x8 */
+	TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED, /* 0x9 */
+	TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION, /* 0xa */
+	TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD, /* 0xb */
+	TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER, /* 0xc */
+	TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED, /* 0xd */
+	TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT, /* 0xe */
+	TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION, /* 0xf */
+	TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED, /* 0x10 */
+	TRANS_TX_ERR_FRAME_TXED, /* 0x11 */
+	TRANS_TX_ERR_WITH_BREAK_TIMEOUT, /* 0x12 */
+	TRANS_TX_ERR_WITH_BREAK_REQUEST, /* 0x13 */
+	TRANS_TX_ERR_WITH_BREAK_RECEVIED, /* 0x14 */
+	TRANS_TX_ERR_WITH_CLOSE_TIMEOUT, /* 0x15 */
+	TRANS_TX_ERR_WITH_CLOSE_NORMAL, /* 0x16 for ssp*/
+	TRANS_TX_ERR_WITH_CLOSE_PHYDISALE, /* 0x17 */
+	TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT, /* 0x18 */
+	TRANS_TX_ERR_WITH_CLOSE_COMINIT, /* 0x19 */
+	TRANS_TX_ERR_WITH_NAK_RECEVIED, /* 0x1a for ssp*/
+	TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT, /* 0x1b for ssp*/
+	/*IO_TX_ERR_WITH_R_ERR_RECEVIED, [> 0x1b for sata/stp<] */
+	TRANS_TX_ERR_WITH_CREDIT_TIMEOUT, /* 0x1c for ssp */
+	/*IO_RX_ERR_WITH_SATA_DEVICE_LOST 0x1c for sata/stp */
+	TRANS_TX_ERR_WITH_IPTT_CONFLICT, /* 0x1d for ssp/smp */
+	TRANS_TX_ERR_WITH_OPEN_BY_DES_OR_OTHERS, /* 0x1e */
+	/*IO_TX_ERR_WITH_SYNC_RXD, [> 0x1e <] for sata/stp */
+	TRANS_TX_ERR_WITH_WAIT_RECV_TIMEOUT, /* 0x1f for sata/stp */
+
+	/* trans rx */
+	TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR = TRANS_RX_FAIL_BASE, /* 0x100 */
+	TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR, /* 0x101 for sata/stp */
+	TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM, /* 0x102 for ssp/smp */
+	/*IO_ERR_WITH_RXFIS_8B10B_CODE_ERR, [> 0x102 <] for sata/stp */
+	TRANS_RX_ERR_WITH_RXFIS_DECODE_ERROR, /* 0x103 for sata/stp */
+	TRANS_RX_ERR_WITH_RXFIS_CRC_ERR, /* 0x104 for sata/stp */
+	TRANS_RX_ERR_WITH_RXFRAME_LENGTH_OVERRUN, /* 0x105 for smp */
+	/*IO_ERR_WITH_RXFIS_TX SYNCP, [> 0x105 <] for sata/stp */
+	TRANS_RX_ERR_WITH_RXFIS_RX_SYNCP, /* 0x106 for sata/stp*/
+	TRANS_RX_ERR_WITH_LINK_BUF_OVERRUN, /* 0x107 */
+	TRANS_RX_ERR_WITH_BREAK_TIMEOUT, /* 0x108 */
+	TRANS_RX_ERR_WITH_BREAK_REQUEST, /* 0x109 */
+	TRANS_RX_ERR_WITH_BREAK_RECEVIED, /* 0x10a */
+	RESERVED1, /* 0x10b */
+	TRANS_RX_ERR_WITH_CLOSE_NORMAL, /* 0x10c */
+	TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE, /* 0x10d */
+	TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT, /* 0x10e */
+	TRANS_RX_ERR_WITH_CLOSE_COMINIT, /* 0x10f */
+	TRANS_RX_ERR_WITH_DATA_LEN0, /* 0x110 for ssp/smp */
+	TRANS_RX_ERR_WITH_BAD_HASH, /* 0x111 for ssp */
+	/*IO_RX_ERR_WITH_FIS_TOO_SHORT, [> 0x111 <] for sata/stp */
+	TRANS_RX_XRDY_WLEN_ZERO_ERR, /* 0x112 for ssp*/
+	/*IO_RX_ERR_WITH_FIS_TOO_LONG, [> 0x112 <] for sata/stp */
+	TRANS_RX_SSP_FRM_LEN_ERR, /* 0x113 for ssp */
+	/*IO_RX_ERR_WITH_SATA_DEVICE_LOST, [> 0x113 <] for sata */
+	RESERVED2, /* 0x114 */
+	RESERVED3, /* 0x115 */
+	RESERVED4, /* 0x116 */
+	RESERVED5, /* 0x117 */
+	TRANS_RX_ERR_WITH_BAD_FRM_TYPE, /* 0x118 */
+	TRANS_RX_SMP_FRM_LEN_ERR, /* 0x119 */
+	TRANS_RX_SMP_RESP_TIMEOUT_ERR, /* 0x11a */
+	RESERVED6, /* 0x11b */
+	RESERVED7, /* 0x11c */
+	RESERVED8, /* 0x11d */
+	RESERVED9, /* 0x11e */
+	TRANS_RX_R_ERR, /* 0x11f */
+
+	/* dma tx */
+	DMA_TX_DIF_CRC_ERR = DMA_TX_ERR_BASE, /* 0x200 */
+	DMA_TX_DIF_APP_ERR, /* 0x201 */
+	DMA_TX_DIF_RPP_ERR, /* 0x202 */
+	DMA_TX_DATA_SGL_OVERFLOW, /* 0x203 */
+	DMA_TX_DIF_SGL_OVERFLOW, /* 0x204 */
+	DMA_TX_UNEXP_XFER_ERR, /* 0x205 */
+	DMA_TX_UNEXP_RETRANS_ERR, /* 0x206 */
+	DMA_TX_XFER_LEN_OVERFLOW, /* 0x207 */
+	DMA_TX_XFER_OFFSET_ERR, /* 0x208 */
+	DMA_TX_RAM_ECC_ERR, /* 0x209 */
+	DMA_TX_DIF_LEN_ALIGN_ERR, /* 0x20a */
+
+	/* sipc rx */
+	SIPC_RX_FIS_STATUS_ERR_BIT_VLD = SIPC_RX_ERR_BASE, /* 0x300 */
+	SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR, /* 0x301 */
+	SIPC_RX_FIS_STATUS_BSY_BIT_ERR, /* 0x302 */
+	SIPC_RX_WRSETUP_LEN_ODD_ERR, /* 0x303 */
+	SIPC_RX_WRSETUP_LEN_ZERO_ERR, /* 0x304 */
+	SIPC_RX_WRDATA_LEN_NOT_MATCH_ERR, /* 0x305 */
+	SIPC_RX_NCQ_WRSETUP_OFFSET_ERR, /* 0x306 */
+	SIPC_RX_NCQ_WRSETUP_AUTO_ACTIVE_ERR, /* 0x307 */
+	SIPC_RX_SATA_UNEXP_FIS_ERR, /* 0x308 */
+	SIPC_RX_WRSETUP_ESTATUS_ERR, /* 0x309 */
+	SIPC_RX_DATA_UNDERFLOW_ERR, /* 0x30a */
+
+	/* dma rx */
+	DMA_RX_DIF_CRC_ERR = DMA_RX_ERR_BASE, /* 0x400 */
+	DMA_RX_DIF_APP_ERR, /* 0x401 */
+	DMA_RX_DIF_RPP_ERR, /* 0x402 */
+	DMA_RX_DATA_SGL_OVERFLOW, /* 0x403 */
+	DMA_RX_DIF_SGL_OVERFLOW, /* 0x404 */
+	DMA_RX_DATA_LEN_OVERFLOW, /* 0x405 */
+	DMA_RX_DATA_LEN_UNDERFLOW, /* 0x406 */
+	DMA_RX_DATA_OFFSET_ERR, /* 0x407 */
+	RESERVED10, /* 0x408 */
+	DMA_RX_SATA_FRAME_TYPE_ERR, /* 0x409 */
+	DMA_RX_RESP_BUF_OVERFLOW, /* 0x40a */
+	DMA_RX_UNEXP_RETRANS_RESP_ERR, /* 0x40b */
+	DMA_RX_UNEXP_NORM_RESP_ERR, /* 0x40c */
+	DMA_RX_UNEXP_RDFRAME_ERR, /* 0x40d */
+	DMA_RX_PIO_DATA_LEN_ERR, /* 0x40e */
+	DMA_RX_RDSETUP_STATUS_ERR, /* 0x40f */
+	DMA_RX_RDSETUP_STATUS_DRQ_ERR, /* 0x410 */
+	DMA_RX_RDSETUP_STATUS_BSY_ERR, /* 0x411 */
+	DMA_RX_RDSETUP_LEN_ODD_ERR, /* 0x412 */
+	DMA_RX_RDSETUP_LEN_ZERO_ERR, /* 0x413 */
+	DMA_RX_RDSETUP_LEN_OVER_ERR, /* 0x414 */
+	DMA_RX_RDSETUP_OFFSET_ERR, /* 0x415 */
+	DMA_RX_RDSETUP_ACTIVE_ERR, /* 0x416 */
+	DMA_RX_RDSETUP_ESTATUS_ERR, /* 0x417 */
+	DMA_RX_RAM_ECC_ERR, /* 0x418 */
+	DMA_RX_UNKNOWN_FRM_ERR, /* 0x419 */
+};
+
 #define HISI_SAS_COMMAND_ENTRIES_V2_HW 4096
 
 #define DIR_NO_DATA 0
@@ -1011,6 +1164,273 @@ static void sata_done_v2_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
 
 	ts->buf_valid_size = sizeof(*resp);
 }
+
+/* by default, task resp is complete */
+static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
+			   struct sas_task *task,
+			   struct hisi_sas_slot *slot)
+{
+	struct task_status_struct *ts = &task->task_status;
+	struct hisi_sas_err_record_v2 *err_record = slot->status_buffer;
+	u32 trans_tx_fail_type = cpu_to_le32(err_record->trans_tx_fail_type);
+	u32 trans_rx_fail_type = cpu_to_le32(err_record->trans_rx_fail_type);
+	u16 dma_tx_err_type = cpu_to_le16(err_record->dma_tx_err_type);
+	u16 sipc_rx_err_type = cpu_to_le16(err_record->sipc_rx_err_type);
+	u32 dma_rx_err_type = cpu_to_le32(err_record->dma_rx_err_type);
+	int error = -1;
+
+	if (dma_rx_err_type) {
+		error = ffs(dma_rx_err_type)
+			- 1 + DMA_RX_ERR_BASE;
+	} else if (sipc_rx_err_type) {
+		error = ffs(sipc_rx_err_type)
+			- 1 + SIPC_RX_ERR_BASE;
+	}  else if (dma_tx_err_type) {
+		error = ffs(dma_tx_err_type)
+			- 1 + DMA_TX_ERR_BASE;
+	} else if (trans_rx_fail_type) {
+		error = ffs(trans_rx_fail_type)
+			- 1 + TRANS_RX_FAIL_BASE;
+	} else if (trans_tx_fail_type) {
+		error = ffs(trans_tx_fail_type)
+			- 1 + TRANS_TX_FAIL_BASE;
+	}
+
+	switch (task->task_proto) {
+	case SAS_PROTOCOL_SSP:
+	{
+		switch (error) {
+		case TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_NO_DEST;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_PATH_BLOCKED;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_EPROTO;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_CONN_RATE;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_BAD_DEST;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER:
+		{
+			/* not sure */
+			ts->stat = SAS_DEV_NO_RESPONSE;
+			break;
+		}
+		case TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE:
+		{
+			ts->stat = SAS_PHY_DOWN;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT:
+		{
+			ts->stat = SAS_OPEN_TO;
+			break;
+		}
+		case DMA_RX_DATA_LEN_OVERFLOW:
+		{
+			ts->stat = SAS_DATA_OVERRUN;
+			ts->residual = 0;
+			break;
+		}
+		case DMA_RX_DATA_LEN_UNDERFLOW:
+		case SIPC_RX_DATA_UNDERFLOW_ERR:
+		{
+			ts->residual = trans_tx_fail_type;
+			ts->stat = SAS_DATA_UNDERRUN;
+			break;
+		}
+		case TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS:
+		case TRANS_TX_ERR_PHY_NOT_ENABLE:
+		case TRANS_TX_OPEN_CNX_ERR_BY_OTHER:
+		case TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT:
+		case TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED:
+		case TRANS_TX_ERR_WITH_BREAK_TIMEOUT:
+		case TRANS_TX_ERR_WITH_BREAK_REQUEST:
+		case TRANS_TX_ERR_WITH_BREAK_RECEVIED:
+		case TRANS_TX_ERR_WITH_CLOSE_TIMEOUT:
+		case TRANS_TX_ERR_WITH_CLOSE_NORMAL:
+		case TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT:
+		case TRANS_TX_ERR_WITH_CLOSE_COMINIT:
+		case TRANS_TX_ERR_WITH_NAK_RECEVIED:
+		case TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT:
+		case TRANS_TX_ERR_WITH_IPTT_CONFLICT:
+		case TRANS_TX_ERR_WITH_CREDIT_TIMEOUT:
+		case TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR:
+		case TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR:
+		case TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM:
+		case TRANS_RX_ERR_WITH_BREAK_TIMEOUT:
+		case TRANS_RX_ERR_WITH_BREAK_REQUEST:
+		case TRANS_RX_ERR_WITH_BREAK_RECEVIED:
+		case TRANS_RX_ERR_WITH_CLOSE_NORMAL:
+		case TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT:
+		case TRANS_RX_ERR_WITH_CLOSE_COMINIT:
+		case TRANS_RX_ERR_WITH_DATA_LEN0:
+		case TRANS_RX_ERR_WITH_BAD_HASH:
+		case TRANS_RX_XRDY_WLEN_ZERO_ERR:
+		case TRANS_RX_SSP_FRM_LEN_ERR:
+		case TRANS_RX_ERR_WITH_BAD_FRM_TYPE:
+		case DMA_TX_UNEXP_XFER_ERR:
+		case DMA_TX_UNEXP_RETRANS_ERR:
+		case DMA_TX_XFER_LEN_OVERFLOW:
+		case DMA_TX_XFER_OFFSET_ERR:
+		case DMA_RX_DATA_OFFSET_ERR:
+		case DMA_RX_UNEXP_NORM_RESP_ERR:
+		case DMA_RX_UNEXP_RDFRAME_ERR:
+		case DMA_RX_UNKNOWN_FRM_ERR:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			ts->open_rej_reason = SAS_OREJ_UNKNOWN;
+			break;
+		}
+		default:
+			break;
+		}
+	}
+		break;
+	case SAS_PROTOCOL_SMP:
+		ts->stat = SAM_STAT_CHECK_CONDITION;
+		break;
+
+	case SAS_PROTOCOL_SATA:
+	case SAS_PROTOCOL_STP:
+	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+	{
+		switch (error) {
+		case TRANS_TX_OPEN_CNX_ERR_LOW_PHY_POWER:
+		case TRANS_TX_OPEN_CNX_ERR_PATHWAY_BLOCKED:
+		case TRANS_TX_OPEN_CNX_ERR_NO_DESTINATION:
+		{
+			ts->resp = SAS_TASK_UNDELIVERED;
+			ts->stat = SAS_DEV_NO_RESPONSE;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_PROTOCOL_NOT_SUPPORTED:
+		case TRANS_TX_OPEN_CNX_ERR_CONNECTION_RATE_NOT_SUPPORTED:
+		case TRANS_TX_OPEN_CNX_ERR_BAD_DESTINATION:
+		case TRANS_TX_OPEN_CNX_ERR_BREAK_RCVD:
+		case TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION:
+		case TRANS_TX_OPEN_CNX_ERR_ZONE_VIOLATION:
+		case TRANS_TX_OPEN_CNX_ERR_STP_RESOURCES_BUSY:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			break;
+		}
+		case TRANS_TX_OPEN_CNX_ERR_OPEN_TIMEOUT:
+		{
+			ts->stat = SAS_OPEN_TO;
+			break;
+		}
+		case DMA_RX_DATA_LEN_OVERFLOW:
+		{
+			ts->stat = SAS_DATA_OVERRUN;
+			break;
+		}
+		case TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS:
+		case TRANS_TX_ERR_PHY_NOT_ENABLE:
+		case TRANS_TX_OPEN_CNX_ERR_BY_OTHER:
+		case TRANS_TX_OPEN_CNX_ERR_AIP_TIMEOUT:
+		case TRANS_TX_OPEN_RETRY_ERR_THRESHOLD_REACHED:
+		case TRANS_TX_ERR_WITH_BREAK_TIMEOUT:
+		case TRANS_TX_ERR_WITH_BREAK_REQUEST:
+		case TRANS_TX_ERR_WITH_BREAK_RECEVIED:
+		case TRANS_TX_ERR_WITH_CLOSE_TIMEOUT:
+		case TRANS_TX_ERR_WITH_CLOSE_NORMAL:
+		case TRANS_TX_ERR_WITH_CLOSE_DWS_TIMEOUT:
+		case TRANS_TX_ERR_WITH_CLOSE_COMINIT:
+		case TRANS_TX_ERR_WITH_NAK_RECEVIED:
+		case TRANS_TX_ERR_WITH_ACK_NAK_TIMEOUT:
+		case TRANS_TX_ERR_WITH_CREDIT_TIMEOUT:
+		case TRANS_TX_ERR_WITH_WAIT_RECV_TIMEOUT:
+		case TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR:
+		case TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM:
+		case TRANS_RX_ERR_WITH_RXFIS_DECODE_ERROR:
+		case TRANS_RX_ERR_WITH_RXFIS_CRC_ERR:
+		case TRANS_RX_ERR_WITH_RXFRAME_LENGTH_OVERRUN:
+		case TRANS_RX_ERR_WITH_RXFIS_RX_SYNCP:
+		case TRANS_RX_ERR_WITH_CLOSE_NORMAL:
+		case TRANS_RX_ERR_WITH_CLOSE_PHY_DISABLE:
+		case TRANS_RX_ERR_WITH_CLOSE_DWS_TIMEOUT:
+		case TRANS_RX_ERR_WITH_CLOSE_COMINIT:
+		case TRANS_RX_ERR_WITH_DATA_LEN0:
+		case TRANS_RX_ERR_WITH_BAD_HASH:
+		case TRANS_RX_XRDY_WLEN_ZERO_ERR:
+		case TRANS_RX_SSP_FRM_LEN_ERR:
+		case SIPC_RX_FIS_STATUS_ERR_BIT_VLD:
+		case SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR:
+		case SIPC_RX_FIS_STATUS_BSY_BIT_ERR:
+		case SIPC_RX_WRSETUP_LEN_ODD_ERR:
+		case SIPC_RX_WRSETUP_LEN_ZERO_ERR:
+		case SIPC_RX_WRDATA_LEN_NOT_MATCH_ERR:
+		case SIPC_RX_SATA_UNEXP_FIS_ERR:
+		case DMA_RX_SATA_FRAME_TYPE_ERR:
+		case DMA_RX_UNEXP_RDFRAME_ERR:
+		case DMA_RX_PIO_DATA_LEN_ERR:
+		case DMA_RX_RDSETUP_STATUS_ERR:
+		case DMA_RX_RDSETUP_STATUS_DRQ_ERR:
+		case DMA_RX_RDSETUP_STATUS_BSY_ERR:
+		case DMA_RX_RDSETUP_LEN_ODD_ERR:
+		case DMA_RX_RDSETUP_LEN_ZERO_ERR:
+		case DMA_RX_RDSETUP_LEN_OVER_ERR:
+		case DMA_RX_RDSETUP_OFFSET_ERR:
+		case DMA_RX_RDSETUP_ACTIVE_ERR:
+		case DMA_RX_RDSETUP_ESTATUS_ERR:
+		case DMA_RX_UNKNOWN_FRM_ERR:
+		{
+			ts->stat = SAS_OPEN_REJECT;
+			break;
+		}
+		default:
+		{
+			ts->stat = SAS_PROTO_RESPONSE;
+			break;
+		}
+		}
+		sata_done_v2_hw(hisi_hba, task, slot);
+	}
+		break;
+	default:
+		break;
+	}
+}
+
 static int
 slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot,
 		    int abort)
@@ -1053,6 +1473,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot,
 			__func__, slot->cmplt_queue_slot,
 			(complete_hdr->dw0) & CMPLT_HDR_ERX_MSK);
 
+		slot_err_v2_hw(hisi_hba, task, slot);
 		goto out;
 	}
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 22/23] hisi_sas: add v2 tmf functions
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (15 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 21/23] hisi_sas: add v2 slot error handler John Garry
@ 2016-01-08 14:15 ` John Garry
  2016-01-08 14:15 ` [PATCH 23/23] hisi_sas: update driver version to 1.1 John Garry
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 0d9365b..8a8cf18 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -845,6 +845,14 @@ static void enable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
 	hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);
 }
 
+static void disable_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);
+
+	cfg &= ~PHY_CFG_ENA_MSK;
+	hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);
+}
+
 static void start_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
 {
 	config_id_frame_v2_hw(hisi_hba, phy_no);
@@ -852,6 +860,18 @@ static void start_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
 	enable_phy_v2_hw(hisi_hba, phy_no);
 }
 
+static void stop_phy_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	disable_phy_v2_hw(hisi_hba, phy_no);
+}
+
+static void phy_hard_reset_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+	stop_phy_v2_hw(hisi_hba, phy_no);
+	msleep(100);
+	start_phy_v2_hw(hisi_hba, phy_no);
+}
+
 static void start_phys_v2_hw(unsigned long data)
 {
 	struct hisi_hba *hisi_hba = (struct hisi_hba *)data;
@@ -2146,6 +2166,9 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.get_free_slot = get_free_slot_v2_hw,
 	.start_delivery = start_delivery_v2_hw,
 	.slot_complete = slot_complete_v2_hw,
+	.phy_enable = enable_phy_v2_hw,
+	.phy_disable = disable_phy_v2_hw,
+	.phy_hard_reset = phy_hard_reset_v2_hw,
 	.max_command_entries = HISI_SAS_COMMAND_ENTRIES_V2_HW,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 23/23] hisi_sas: update driver version to 1.1
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (16 preceding siblings ...)
  2016-01-08 14:15 ` [PATCH 22/23] hisi_sas: add v2 tmf functions John Garry
@ 2016-01-08 14:15 ` John Garry
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
  2016-01-11 13:43 ` Hannes Reinecke
  19 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:15 UTC (permalink / raw)
  To: JBottomley, martin.petersen, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree, John Garry

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index f00b55b..9f08c0c 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -21,7 +21,7 @@
 #include <scsi/sas_ata.h>
 #include <scsi/libsas.h>
 
-#define DRV_VERSION "v1.0"
+#define DRV_VERSION "v1.1"
 
 #define HISI_SAS_MAX_PHYS	9
 #define HISI_SAS_MAX_QUEUES	32
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/23] HiSilicon SAS v2 hw support
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
                     ` (4 preceding siblings ...)
  2016-01-08 14:15   ` [PATCH 20/23] hisi_sas: add v2 path to send ATA command John Garry
@ 2016-01-08 14:31   ` John Garry
  5 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-08 14:31 UTC (permalink / raw)
  To: James.Bottomley-JuX6DAaQMKPCXq6kfMZ53/egYHeGw8Jk
  Cc: martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA, JBottomley-wo1vFcy6AUs

My patchset was bounced by JBottomley-wo1vFcy6AUs@public.gmane.org

It seems sudipm.mukherjee-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org had the same issue earlier this 
week, but other contributors seem to continue using the same address - 
shall I resend with alternate address?


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
       [not found]   ` <1452262542-64589-2-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
@ 2016-01-08 14:52     ` Mark Rutland
  2016-01-08 15:15       ` John Garry
  0 siblings, 1 reply; 35+ messages in thread
From: Mark Rutland @ 2016-01-08 14:52 UTC (permalink / raw)
  To: John Garry
  Cc: JBottomley-wo1vFcy6AUs, martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Fri, Jan 08, 2016 at 10:15:20PM +0800, John Garry wrote:
> Add the dt bindings for HiSi SAS controller v2 HW.
> 
> The main difference in the controllers from dt perspective
> is interrupts.
> 
> Signed-off-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> ---
>  .../devicetree/bindings/scsi/hisilicon-sas.txt       | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
> index 0a7a325..2695023 100644
> --- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
> +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
> @@ -5,6 +5,7 @@ The HiSilicon SAS controller supports SAS/SATA.
>  Main node required properties:
>    - compatible : value should be as follows:
>  	(a) "hisilicon,hip05-sas-v1" for v1 hw in hip05 chipset
> +	(b) "hisilicon,hip06-sas-v2" for v2 hw in hip06 chipset
>    - sas-addr : array of 8 bytes for host SAS address
>    - reg : Address and length of the SAS register
>    - hisilicon,sas-syscon: phandle of syscon used for sas control
> @@ -13,11 +14,11 @@ Main node required properties:
>    - ctrl-clock-ena-reg : offset to controller clock enable register in ctrl reg
>    - queue-count : number of delivery and completion queues in the controller
>    - phy-count : number of phys accessible by the controller
> -  - interrupts : Interrupts for phys, completion queues, and fatal
> +  - interrupts : For v1 hw: Interrupts for phys, completion queues, and fatal
>  		sources; the interrupts are ordered in 3 groups, as follows:
> -			- Phy interrupts
> -			- Completion queue interrupts
> -			- Fatal interrupts
> +		  - Phy interrupts
> +		  - Completion queue interrupts
> +		  - Fatal interrupts
>  		Phy interrupts : Each phy has 3 interrupt sources:
>  			- broadcast
>  			- phyup
> @@ -25,11 +26,28 @@ Main node required properties:
>  		The phy interrupts are ordered into groups of 3 per phy
>  		(broadcast, phyup, and abnormal) in increasing order.
>  		Completion queue interrupts : each completion queue has 1
> -			interrupt source.
> -			The interrupts are ordered in increasing order.
> +			interrupt source. The interrupts are ordered in
> +			increasing order.
>  		Fatal interrupts : the fatal interrupts are ordered as follows:
>  			- ECC
>  			- AXI bus
> +		For v2 hw: Interrupts for phys, Sata, and completion queues;
> +		the interrupts are ordered in 3 groups, as follows:
> +		  - Phy interrupts
> +		  - Sata interrupts
> +		  - Completion queue interrupts
> +		Phy interrupts : Each controller has 2 phy interrupts:
> +			- phy up/down
> +			- channel interrupt
> +		Sata interrupts : Each phy on the controller has 1 Sata
> +			interrupt. The interrupts are ordered in increasing
> +			order.
> +		Completion queue interrupts : each completion queue has 1
> +			interrupt source. The interrupts are ordered in
> +			increasing order.

There are no fatal interrupts in V2?

> +Optional main node properties:
> + - am-max-trans : limit controller for am max transmissions

Is this a boolean? Number?

Thanks,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 09/23] hisi_sas: add v2 hw init
  2016-01-08 14:15   ` [PATCH 09/23] hisi_sas: add v2 hw init John Garry
@ 2016-01-08 15:07     ` Mark Rutland
  0 siblings, 0 replies; 35+ messages in thread
From: Mark Rutland @ 2016-01-08 15:07 UTC (permalink / raw)
  To: John Garry
  Cc: JBottomley, martin.petersen, robh+dt, pawel.moll, ijc+devicetree,
	galak, linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree

On Fri, Jan 08, 2016 at 10:15:28PM +0800, John Garry wrote:

> +	/* Global registers init*/
> +	if (of_get_property(np, "am-max-trans", NULL)) {
> +		hisi_sas_write32(hisi_hba, AM_CFG_MAX_TRANS, 0x2020);
> +		hisi_sas_write32(hisi_hba, AM_CFG_SINGLE_PORT_MAX_TRANS,
> +				 0x2020);
> +	}

Use of_property_read_bool for boolean properties like this.

I still don't follow exactly what this property means, and why it is
necessary, but that's an issue for the binding document.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
  2016-01-08 14:52     ` Mark Rutland
@ 2016-01-08 15:15       ` John Garry
  2016-01-08 15:19         ` Mark Rutland
  0 siblings, 1 reply; 35+ messages in thread
From: John Garry @ 2016-01-08 15:15 UTC (permalink / raw)
  To: Mark Rutland
  Cc: JBottomley-wo1vFcy6AUs, martin.petersen-QHcLZuEGTsvQT0dZR+AlfA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, linuxarm-hv44wF8Li93QT0dZR+AlfA,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On 08/01/2016 14:52, Mark Rutland wrote:
> On Fri, Jan 08, 2016 at 10:15:20PM +0800, John Garry wrote:
>> Add the dt bindings for HiSi SAS controller v2 HW.
>>
>> The main difference in the controllers from dt perspective
>> is interrupts.
>>
>> Signed-off-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> ---
>>   .../devicetree/bindings/scsi/hisilicon-sas.txt       | 20 +++++++++++++++++++-
>>   1 file changed, 19 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
>> index 0a7a325..2695023 100644
>> --- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
>> +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
>> @@ -5,6 +5,7 @@ The HiSilicon SAS controller supports SAS/SATA.
>>   Main node required properties:
>>     - compatible : value should be as follows:
>>   	(a) "hisilicon,hip05-sas-v1" for v1 hw in hip05 chipset
>> +	(b) "hisilicon,hip06-sas-v2" for v2 hw in hip06 chipset
>>     - sas-addr : array of 8 bytes for host SAS address
>>     - reg : Address and length of the SAS register
>>     - hisilicon,sas-syscon: phandle of syscon used for sas control
>> @@ -13,11 +14,11 @@ Main node required properties:
>>     - ctrl-clock-ena-reg : offset to controller clock enable register in ctrl reg
>>     - queue-count : number of delivery and completion queues in the controller
>>     - phy-count : number of phys accessible by the controller
>> -  - interrupts : Interrupts for phys, completion queues, and fatal
>> +  - interrupts : For v1 hw: Interrupts for phys, completion queues, and fatal
>>   		sources; the interrupts are ordered in 3 groups, as follows:
>> -			- Phy interrupts
>> -			- Completion queue interrupts
>> -			- Fatal interrupts
>> +		  - Phy interrupts
>> +		  - Completion queue interrupts
>> +		  - Fatal interrupts
>>   		Phy interrupts : Each phy has 3 interrupt sources:
>>   			- broadcast
>>   			- phyup
>> @@ -25,11 +26,28 @@ Main node required properties:
>>   		The phy interrupts are ordered into groups of 3 per phy
>>   		(broadcast, phyup, and abnormal) in increasing order.
>>   		Completion queue interrupts : each completion queue has 1
>> -			interrupt source.
>> -			The interrupts are ordered in increasing order.
>> +			interrupt source. The interrupts are ordered in
>> +			increasing order.
>>   		Fatal interrupts : the fatal interrupts are ordered as follows:
>>   			- ECC
>>   			- AXI bus
>> +		For v2 hw: Interrupts for phys, Sata, and completion queues;
>> +		the interrupts are ordered in 3 groups, as follows:
>> +		  - Phy interrupts
>> +		  - Sata interrupts
>> +		  - Completion queue interrupts
>> +		Phy interrupts : Each controller has 2 phy interrupts:
>> +			- phy up/down
>> +			- channel interrupt
>> +		Sata interrupts : Each phy on the controller has 1 Sata
>> +			interrupt. The interrupts are ordered in increasing
>> +			order.
>> +		Completion queue interrupts : each completion queue has 1
>> +			interrupt source. The interrupts are ordered in
>> +			increasing order.
>
> There are no fatal interrupts in V2?

For v2 hardware, broadcast and fatal interrupts are mutliplexed into the 
general purpose channel interrupt line.

>
>> +Optional main node properties:
>> + - am-max-trans : limit controller for am max transmissions
>
> Is this a boolean? Number?
>

This is a boolean. It is for dealing with a quirk in the chipset: an 
instance of the controller in the hip06 chipset requires registers set 
with a different init value.

> Thanks,
> Mark.
>

thanks,
john


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
  2016-01-08 15:15       ` John Garry
@ 2016-01-08 15:19         ` Mark Rutland
  2016-01-08 15:34           ` John Garry
  0 siblings, 1 reply; 35+ messages in thread
From: Mark Rutland @ 2016-01-08 15:19 UTC (permalink / raw)
  To: John Garry
  Cc: JBottomley, martin.petersen, robh+dt, pawel.moll, ijc+devicetree,
	galak, linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree

> >>@@ -25,11 +26,28 @@ Main node required properties:
> >>  		The phy interrupts are ordered into groups of 3 per phy
> >>  		(broadcast, phyup, and abnormal) in increasing order.
> >>  		Completion queue interrupts : each completion queue has 1
> >>-			interrupt source.
> >>-			The interrupts are ordered in increasing order.
> >>+			interrupt source. The interrupts are ordered in
> >>+			increasing order.
> >>  		Fatal interrupts : the fatal interrupts are ordered as follows:
> >>  			- ECC
> >>  			- AXI bus
> >>+		For v2 hw: Interrupts for phys, Sata, and completion queues;
> >>+		the interrupts are ordered in 3 groups, as follows:
> >>+		  - Phy interrupts
> >>+		  - Sata interrupts
> >>+		  - Completion queue interrupts
> >>+		Phy interrupts : Each controller has 2 phy interrupts:
> >>+			- phy up/down
> >>+			- channel interrupt
> >>+		Sata interrupts : Each phy on the controller has 1 Sata
> >>+			interrupt. The interrupts are ordered in increasing
> >>+			order.
> >>+		Completion queue interrupts : each completion queue has 1
> >>+			interrupt source. The interrupts are ordered in
> >>+			increasing order.
> >
> >There are no fatal interrupts in V2?
> 
> For v2 hardware, broadcast and fatal interrupts are mutliplexed into
> the general purpose channel interrupt line.

Ok, that sounds fine, just thought I should check.

> >>+Optional main node properties:
> >>+ - am-max-trans : limit controller for am max transmissions
> >
> >Is this a boolean? Number?
> >
> 
> This is a boolean. It is for dealing with a quirk in the chipset: an
> instance of the controller in the hip06 chipset requires registers
> set with a different init value.

Ok. I think the property at needs a better description for that.

It's not clear to me how "limit controller for am max transmissions"
maps to writing a specific value to some registers, but I don't know
much about SAS.

Is this some well-known thing, or values specific to hip06?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
  2016-01-08 15:19         ` Mark Rutland
@ 2016-01-08 15:34           ` John Garry
  2016-01-08 16:49             ` Mark Rutland
  0 siblings, 1 reply; 35+ messages in thread
From: John Garry @ 2016-01-08 15:34 UTC (permalink / raw)
  To: Mark Rutland
  Cc: JBottomley, martin.petersen, robh+dt, pawel.moll, ijc+devicetree,
	galak, linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree


>>>> +Optional main node properties:
>>>> + - am-max-trans : limit controller for am max transmissions
>>>
>>> Is this a boolean? Number?
>>>
>>
>> This is a boolean. It is for dealing with a quirk in the chipset: an
>> instance of the controller in the hip06 chipset requires registers
>> set with a different init value.
>
> Ok. I think the property at needs a better description for that.
>
> It's not clear to me how "limit controller for am max transmissions"
> maps to writing a specific value to some registers, but I don't know
> much about SAS.
>
> Is this some well-known thing, or values specific to hip06?
>
> Thanks,
> Mark.
>

This is a specific issue for hip06 chipset. There is a bug in the HW on 
hip06 where controller #1 has to set to 2 registers to non-default 
values to limit "am-max-transmissions". This would not be a common 
SAS/SCSI controller property and is specific to our HW.

Thanks,
John


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
  2016-01-08 15:34           ` John Garry
@ 2016-01-08 16:49             ` Mark Rutland
  2016-01-11 14:00               ` John Garry
  0 siblings, 1 reply; 35+ messages in thread
From: Mark Rutland @ 2016-01-08 16:49 UTC (permalink / raw)
  To: John Garry
  Cc: JBottomley, martin.petersen, robh+dt, pawel.moll, ijc+devicetree,
	galak, linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree

On Fri, Jan 08, 2016 at 03:34:37PM +0000, John Garry wrote:
> 
> >>>>+Optional main node properties:
> >>>>+ - am-max-trans : limit controller for am max transmissions
> >>>
> >>>Is this a boolean? Number?
> >>>
> >>
> >>This is a boolean. It is for dealing with a quirk in the chipset: an
> >>instance of the controller in the hip06 chipset requires registers
> >>set with a different init value.
> >
> >Ok. I think the property at needs a better description for that.
> >
> >It's not clear to me how "limit controller for am max transmissions"
> >maps to writing a specific value to some registers, but I don't know
> >much about SAS.
> >
> >Is this some well-known thing, or values specific to hip06?
> >
> >Thanks,
> >Mark.
> >
> 
> This is a specific issue for hip06 chipset.

Ok. So is this:

* a bug within the SAS controller in hip06, or:

* a requirement/bug of an endpoint attached to the controller, or:

* a requirement/bug of some interconnect between the controller and
  endpoint, or:

* some other integration bug?

Please describe what the issue is that you're trying to work around, not
only your solution to it.

> There is a bug in the HW on hip06 where controller #1 has to set to 2
> registers to non-default values to limit "am-max-transmissions".

I got that. However, I have no idea what "am-max-transmissions" is, no
idea why you need to limit it (hopefully you can describe that a little
better above), nor what the semantics are for "limit".

The description of the property is an imperative, which reads like a
description of a specific driver behaviour rather than a property of the
hardware that leads to that behaviour being necessary. That's a warning
sign that the property is ill-defined, and we may encounter problems in
future due to changes in Linux.

Without knowing _why_ it's necessary to limit this, it's not possible to
know if the property is both necessary and sufficient to solve the
problem such that it doesn't rear its ugly head in future.

For example, if this is simply one way to work around a hip06-specific
integration bug that we cannot imagine occurring elsewhere, it may be
better to instead key off of a platform-specific compatible string for
the v2 SAS controller in hip06. That gives us more freedom to apply
different workarounds if we have to.

I see that the presence of this property will cause the driver to writes
hard-coded values two two registers. Not knowing the format of those
registers, their default values, nor how they respond to writes, I can't
tell:

* If the writes have other effects.

* If the limit is a single bit being flipped (i.e. this is a boolean in
  hardware too).

* If the limit is some arbitrary chosen value which is not described in
  the property or the binding, nor what that value is. If we encounter a
  similar bug requiring a different bound in future, it may be
  problematic to have chosen an arbitrary fixed value, and it may make
  more sense to describe the value in the DT.

So, please:

* Update the DT property description to describe the specific HW issue
  that needs to be worked around, with a full description in the commit
  message.

* Add a comment to the driver to explain what the effect of the register
  writes is intended to be, i.e. what value am max transmissions is
  being set to, and why that value isn't arbitrary.

> This would not be a common SAS/SCSI controller property and is
> specific to our HW.

Ok.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 16/23] hisi_sas: add v2 cq interrupt handler
  2016-01-08 14:15 ` [PATCH 16/23] hisi_sas: add v2 cq " John Garry
@ 2016-01-08 17:29   ` kbuild test robot
  0 siblings, 0 replies; 35+ messages in thread
From: kbuild test robot @ 2016-01-08 17:29 UTC (permalink / raw)
  Cc: kbuild-all, JBottomley, martin.petersen, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, linuxarm, zhangfei.gao,
	xuwei5, john.garry2, linux-scsi, linux-kernel, arnd, devicetree,
	John Garry

[-- Attachment #1: Type: text/plain, Size: 1587 bytes --]

Hi John,

[auto build test ERROR on scsi/for-next]
[also build test ERROR on next-20160108]
[cannot apply to v4.4-rc8]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/John-Garry/HiSilicon-SAS-v2-hw-support/20160108-221730
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: openrisc-allyesconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=openrisc 

Note: the linux-review/John-Garry/HiSilicon-SAS-v2-hw-support/20160108-221730 HEAD 72b5af1de764d94c3832772c1ae177b60745a45d builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/scsi/hisi_sas/hisi_sas_v2_hw.c: In function 'slot_complete_v2_hw':
>> drivers/scsi/hisi_sas/hisi_sas_v2_hw.c:732:3: error: implicit declaration of function 'sata_done_v2_hw'

vim +/sata_done_v2_hw +732 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

   726		}
   727		case SAS_PROTOCOL_SATA:
   728		case SAS_PROTOCOL_STP:
   729		case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
   730		{
   731			ts->stat = SAM_STAT_GOOD;
 > 732			sata_done_v2_hw(hisi_hba, task, slot);
   733			break;
   734		}
   735	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 36139 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/23] HiSilicon SAS v2 hw support
  2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
                   ` (18 preceding siblings ...)
       [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
@ 2016-01-11 13:43 ` Hannes Reinecke
  19 siblings, 0 replies; 35+ messages in thread
From: Hannes Reinecke @ 2016-01-11 13:43 UTC (permalink / raw)
  To: John Garry, JBottomley, martin.petersen, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak
  Cc: linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree

On 01/08/2016 03:15 PM, John Garry wrote:
> This patchset introduces support for the HiSi SAS v2 hw.
> The major difference between v1 and v2 hw is support
> for SATA/STP.
>
> Known limitation:
> - We cannot connect a SATA disk through a 12G expander
>    without disabling the STP buffer. Direcly connecting
>    a SATA disk to the HBA is ok.
>
> John Garry (23):
>    devicetree: bindings: hisi_sas: add v2 HW bindings
>    hisi_sas: relocate DEV_IS_EXPANDER
>    hisi_sas: set max commands as configurable
>    hisi_sas: reduce max itct entries
>    hisi_sas: add hisi_sas_err_record_v1
>    hisi_sas: rename some fields in hisi_sas_itct
>    hisi_sas: add bare v2 hw driver
>    hisi_sas: add v2 register definitions
>    hisi_sas: add v2 hw init
>    hisi_sas: add init_id_frame_v2_hw()
>    hisi_sas: add v2 phy init code
>    hisi_sas: add v2 int init and phy up handler
>    hisi_sas: add v2 phy down handler
>    hisi_sas: add v2 channel interrupt handler
>    hisi_sas: add v2 SATA interrupt handler
>    hisi_sas: add v2 cq interrupt handler
>    hisi_sas: add v2 path to send ssp frame
>    hisi_sas: add v2 code to send smp command
>    hisi_sas: add v2 code for itct setup and free
>    hisi_sas: add v2 path to send ATA command
>    hisi_sas: add v2 slot error handler
>    hisi_sas: add v2 tmf functions
>    hisi_sas: update driver version to 1.1
>
>   .../devicetree/bindings/scsi/hisilicon-sas.txt     |   20 +-
>   drivers/scsi/hisi_sas/Makefile                     |    2 +-
>   drivers/scsi/hisi_sas/hisi_sas.h                   |   39 +-
>   drivers/scsi/hisi_sas/hisi_sas_main.c              |   36 +-
>   drivers/scsi/hisi_sas/hisi_sas_v1_hw.c             |   20 +-
>   drivers/scsi/hisi_sas/hisi_sas_v2_hw.c             | 2206 ++++++++++++++++++++
>   6 files changed, 2277 insertions(+), 46 deletions(-)
>   create mode 100644 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
>
For the entire series:

Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
  2016-01-08 16:49             ` Mark Rutland
@ 2016-01-11 14:00               ` John Garry
       [not found]                 ` <5693B59A.6000705-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 35+ messages in thread
From: John Garry @ 2016-01-11 14:00 UTC (permalink / raw)
  To: Mark Rutland
  Cc: JBottomley, martin.petersen, robh+dt, pawel.moll, ijc+devicetree,
	galak, linuxarm, zhangfei.gao, xuwei5, john.garry2, linux-scsi,
	linux-kernel, arnd, devicetree

>> This is a specific issue for hip06 chipset.
>
> Ok. So is this:
>
> * a bug within the SAS controller in hip06, or:
>
> * a requirement/bug of an endpoint attached to the controller, or:
>
> * a requirement/bug of some interconnect between the controller and
>    endpoint, or:
>
> * some other integration bug?
>

This is related to how the SAS controller IP was integrated into the 
chip. It is related to how many bursts are permitted for this controller 
on the AXI bus.

> Please describe what the issue is that you're trying to work around, not
> only your solution to it.
>
>> There is a bug in the HW on hip06 where controller #1 has to set to 2
>> registers to non-default values to limit "am-max-transmissions".
>
> I got that. However, I have no idea what "am-max-transmissions" is, no
> idea why you need to limit it (hopefully you can describe that a little
> better above), nor what the semantics are for "limit".
>

So am-max-transmissions is a SW configurable feature of the controller. 
 From a high-level, it means how many commands we can send in parallel 
to the end device(s) without waiting for a response. It is dependent on 
the chip bus design.

> The description of the property is an imperative, which reads like a
> description of a specific driver behaviour rather than a property of the
> hardware that leads to that behaviour being necessary. That's a warning
> sign that the property is ill-defined, and we may encounter problems in
> future due to changes in Linux.
>

Agreed.

> Without knowing _why_ it's necessary to limit this, it's not possible to
> know if the property is both necessary and sufficient to solve the
> problem such that it doesn't rear its ugly head in future.
>
> For example, if this is simply one way to work around a hip06-specific
> integration bug that we cannot imagine occurring elsewhere, it may be
> better to instead key off of a platform-specific compatible string for
> the v2 SAS controller in hip06. That gives us more freedom to apply
> different workarounds if we have to.
>
> I see that the presence of this property will cause the driver to writes
> hard-coded values two two registers. Not knowing the format of those
> registers, their default values, nor how they respond to writes, I can't
> tell:
>

As for writing hardcoded values, by default the related registers will 
hold 0x40, which means we can have upto 64 outstanding requests on this 
controller. Due to controller #1 integration restrictions, we can only 
issue 32 requests.

> * If the writes have other effects.
>
> * If the limit is a single bit being flipped (i.e. this is a boolean in
>    hardware too).
>
> * If the limit is some arbitrary chosen value which is not described in
>    the property or the binding, nor what that value is. If we encounter a
>    similar bug requiring a different bound in future, it may be
>    problematic to have chosen an arbitrary fixed value, and it may make
>    more sense to describe the value in the DT.
>
> So, please:
>
> * Update the DT property description to describe the specific HW issue
>    that needs to be worked around, with a full description in the commit
>    message.
>
> * Add a comment to the driver to explain what the effect of the register
>    writes is intended to be, i.e. what value am max transmissions is
>    being set to, and why that value isn't arbitrary.
>

As I understand, there are no more restictions/special requirements for 
controller #1. This v2 controller IP will be used in other chips, so we 
may have this issue again - I am seeking information from HW people. As 
such, it may be useful to know this info before decided on how this is 
decribed in the DT.

>> This would not be a common SAS/SCSI controller property and is
>> specific to our HW.
>
> Ok.
>
> Thanks,
> Mark.
>

Cheers,
John



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings
       [not found]                 ` <5693B59A.6000705-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
@ 2016-01-12 12:16                   ` John Garry
  0 siblings, 0 replies; 35+ messages in thread
From: John Garry @ 2016-01-12 12:16 UTC (permalink / raw)
  To: Mark Rutland
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	martin.petersen-QHcLZuEGTsvQT0dZR+AlfA, pawel.moll-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, JBottomley-wo1vFcy6AUs,
	john.garry2-s/0ZXS5h9803lw97EnAbAg,
	linuxarm-hv44wF8Li93QT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	arnd-r2nGTMty4D4, galak-sgV2jX0FEOL9JmXXK+q4OQ,
	zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A

On 11/01/2016 14:00, John Garry wrote:
>>> This is a specific issue for hip06 chipset.
>>
>> Ok. So is this:
>>
>> * a bug within the SAS controller in hip06, or:
>>
>> * a requirement/bug of an endpoint attached to the controller, or:
>>
>> * a requirement/bug of some interconnect between the controller and
>>    endpoint, or:
>>
>> * some other integration bug?
>>
>
> This is related to how the SAS controller IP was integrated into the
> chip. It is related to how many bursts are permitted for this controller
> on the AXI bus.
>
>> Please describe what the issue is that you're trying to work around, not
>> only your solution to it.
>>
>>> There is a bug in the HW on hip06 where controller #1 has to set to 2
>>> registers to non-default values to limit "am-max-transmissions".
>>
>> I got that. However, I have no idea what "am-max-transmissions" is, no
>> idea why you need to limit it (hopefully you can describe that a little
>> better above), nor what the semantics are for "limit".
>>
>
> So am-max-transmissions is a SW configurable feature of the controller.
>  From a high-level, it means how many commands we can send in parallel
> to the end device(s) without waiting for a response. It is dependent on
> the chip bus design.
>
>> The description of the property is an imperative, which reads like a
>> description of a specific driver behaviour rather than a property of the
>> hardware that leads to that behaviour being necessary. That's a warning
>> sign that the property is ill-defined, and we may encounter problems in
>> future due to changes in Linux.
>>
>
> Agreed.
>
>> Without knowing _why_ it's necessary to limit this, it's not possible to
>> know if the property is both necessary and sufficient to solve the
>> problem such that it doesn't rear its ugly head in future.
>>
>> For example, if this is simply one way to work around a hip06-specific
>> integration bug that we cannot imagine occurring elsewhere, it may be
>> better to instead key off of a platform-specific compatible string for
>> the v2 SAS controller in hip06. That gives us more freedom to apply
>> different workarounds if we have to.
>>
>> I see that the presence of this property will cause the driver to writes
>> hard-coded values two two registers. Not knowing the format of those
>> registers, their default values, nor how they respond to writes, I can't
>> tell:
>>
>
> As for writing hardcoded values, by default the related registers will
> hold 0x40, which means we can have upto 64 outstanding requests on this
> controller. Due to controller #1 integration restrictions, we can only
> issue 32 requests.
>
>> * If the writes have other effects.
>>
>> * If the limit is a single bit being flipped (i.e. this is a boolean in
>>    hardware too).
>>
>> * If the limit is some arbitrary chosen value which is not described in
>>    the property or the binding, nor what that value is. If we encounter a
>>    similar bug requiring a different bound in future, it may be
>>    problematic to have chosen an arbitrary fixed value, and it may make
>>    more sense to describe the value in the DT.
>>
>> So, please:
>>
>> * Update the DT property description to describe the specific HW issue
>>    that needs to be worked around, with a full description in the commit
>>    message.
>>
>> * Add a comment to the driver to explain what the effect of the register
>>    writes is intended to be, i.e. what value am max transmissions is
>>    being set to, and why that value isn't arbitrary.
>>
>
> As I understand, there are no more restictions/special requirements for
> controller #1. This v2 controller IP will be used in other chips, so we
> may have this issue again - I am seeking information from HW people. As
> such, it may be useful to know this info before decided on how this is
> decribed in the DT.

This issue is specific to only SAS controller #1 in hip06. The 
controller is designed to permit upto 64, but, due to chip bus design, 
this specific controller is limited to support 32.
So, after considering this, would a platform-specific compatible string 
be a better way of decribing this specific controller?

>
>>> This would not be a common SAS/SCSI controller property and is
>>> specific to our HW.
>>
>> Ok.
>>
>> Thanks,
>> Mark.
>>
>
thanks,
John

> _______________________________________________
> linuxarm mailing list
> linuxarm-hv44wF8Li93QT0dZR+AlfA@public.gmane.org
> http://rnd-openeuler.huawei.com/mailman/listinfo/linuxarm


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2016-01-12 12:16 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-08 14:15 [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
2016-01-08 14:15 ` [PATCH 01/23] devicetree: bindings: hisi_sas: add v2 HW bindings John Garry
     [not found]   ` <1452262542-64589-2-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2016-01-08 14:52     ` Mark Rutland
2016-01-08 15:15       ` John Garry
2016-01-08 15:19         ` Mark Rutland
2016-01-08 15:34           ` John Garry
2016-01-08 16:49             ` Mark Rutland
2016-01-11 14:00               ` John Garry
     [not found]                 ` <5693B59A.6000705-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2016-01-12 12:16                   ` John Garry
2016-01-08 14:15 ` [PATCH 03/23] hisi_sas: set max commands as configurable John Garry
2016-01-08 14:15 ` [PATCH 04/23] hisi_sas: reduce max itct entries John Garry
2016-01-08 14:15 ` [PATCH 05/23] hisi_sas: add hisi_sas_err_record_v1 John Garry
2016-01-08 14:15 ` [PATCH 06/23] hisi_sas: rename some fields in hisi_sas_itct John Garry
2016-01-08 14:15 ` [PATCH 07/23] hisi_sas: add bare v2 hw driver John Garry
2016-01-08 14:15 ` [PATCH 08/23] hisi_sas: add v2 register definitions John Garry
2016-01-08 14:15 ` [PATCH 10/23] hisi_sas: add init_id_frame_v2_hw() John Garry
2016-01-08 14:15 ` [PATCH 11/23] hisi_sas: add v2 phy init code John Garry
2016-01-08 14:15 ` [PATCH 12/23] hisi_sas: add v2 int init and phy up handler John Garry
2016-01-08 14:15 ` [PATCH 14/23] hisi_sas: add v2 channel interrupt handler John Garry
2016-01-08 14:15 ` [PATCH 15/23] hisi_sas: add v2 SATA " John Garry
2016-01-08 14:15 ` [PATCH 16/23] hisi_sas: add v2 cq " John Garry
2016-01-08 17:29   ` kbuild test robot
2016-01-08 14:15 ` [PATCH 17/23] hisi_sas: add v2 path to send ssp frame John Garry
2016-01-08 14:15 ` [PATCH 19/23] hisi_sas: add v2 code for itct setup and free John Garry
2016-01-08 14:15 ` [PATCH 21/23] hisi_sas: add v2 slot error handler John Garry
2016-01-08 14:15 ` [PATCH 22/23] hisi_sas: add v2 tmf functions John Garry
2016-01-08 14:15 ` [PATCH 23/23] hisi_sas: update driver version to 1.1 John Garry
     [not found] ` <1452262542-64589-1-git-send-email-john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2016-01-08 14:15   ` [PATCH 02/23] hisi_sas: relocate DEV_IS_EXPANDER John Garry
2016-01-08 14:15   ` [PATCH 09/23] hisi_sas: add v2 hw init John Garry
2016-01-08 15:07     ` Mark Rutland
2016-01-08 14:15   ` [PATCH 13/23] hisi_sas: add v2 phy down handler John Garry
2016-01-08 14:15   ` [PATCH 18/23] hisi_sas: add v2 code to send smp command John Garry
2016-01-08 14:15   ` [PATCH 20/23] hisi_sas: add v2 path to send ATA command John Garry
2016-01-08 14:31   ` [PATCH 00/23] HiSilicon SAS v2 hw support John Garry
2016-01-11 13:43 ` Hannes Reinecke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).