xref: /linux/drivers/scsi/hisi_sas/hisi_sas.h (revision fa42d80dc3c5196b0359fab9a212cc4ede257502)
1e8899fadSJohn Garry /*
2e8899fadSJohn Garry  * Copyright (c) 2015 Linaro Ltd.
3e8899fadSJohn Garry  * Copyright (c) 2015 Hisilicon Limited.
4e8899fadSJohn Garry  *
5e8899fadSJohn Garry  * This program is free software; you can redistribute it and/or modify
6e8899fadSJohn Garry  * it under the terms of the GNU General Public License as published by
7e8899fadSJohn Garry  * the Free Software Foundation; either version 2 of the License, or
8e8899fadSJohn Garry  * (at your option) any later version.
9e8899fadSJohn Garry  *
10e8899fadSJohn Garry  */
11e8899fadSJohn Garry 
12e8899fadSJohn Garry #ifndef _HISI_SAS_H_
13e8899fadSJohn Garry #define _HISI_SAS_H_
14e8899fadSJohn Garry 
15e8899fadSJohn Garry #include <linux/dmapool.h>
16e8899fadSJohn Garry #include <linux/mfd/syscon.h>
17e8899fadSJohn Garry #include <linux/module.h>
18e8899fadSJohn Garry #include <linux/of_address.h>
19e8899fadSJohn Garry #include <linux/of_irq.h>
20e8899fadSJohn Garry #include <linux/platform_device.h>
21e8899fadSJohn Garry #include <linux/regmap.h>
22e8899fadSJohn Garry #include <scsi/libsas.h>
23e8899fadSJohn Garry 
24e8899fadSJohn Garry #define DRV_VERSION "v1.0"
25e8899fadSJohn Garry 
267eb7869fSJohn Garry #define HISI_SAS_MAX_PHYS	9
276be6de18SJohn Garry #define HISI_SAS_MAX_QUEUES	32
286be6de18SJohn Garry #define HISI_SAS_QUEUE_SLOTS 512
297eb7869fSJohn Garry #define HISI_SAS_MAX_ITCT_ENTRIES 4096
307eb7869fSJohn Garry #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
317eb7869fSJohn Garry #define HISI_SAS_COMMAND_ENTRIES 8192
327eb7869fSJohn Garry 
336be6de18SJohn Garry #define HISI_SAS_STATUS_BUF_SZ \
346be6de18SJohn Garry 		(sizeof(struct hisi_sas_err_record) + 1024)
356be6de18SJohn Garry #define HISI_SAS_COMMAND_TABLE_SZ \
366be6de18SJohn Garry 		(((sizeof(union hisi_sas_command_table)+3)/4)*4)
376be6de18SJohn Garry 
38e26b2f40SJohn Garry #define HISI_SAS_NAME_LEN 32
39e26b2f40SJohn Garry 
40af740dbeSJohn Garry 
41af740dbeSJohn Garry enum dev_status {
42af740dbeSJohn Garry 	HISI_SAS_DEV_NORMAL,
43af740dbeSJohn Garry 	HISI_SAS_DEV_EH,
44af740dbeSJohn Garry };
457eb7869fSJohn Garry struct hisi_sas_phy {
46976867e6SJohn Garry 	struct hisi_hba	*hisi_hba;
47976867e6SJohn Garry 	struct hisi_sas_port	*port;
487eb7869fSJohn Garry 	struct asd_sas_phy	sas_phy;
49976867e6SJohn Garry 	struct sas_identify	identify;
50976867e6SJohn Garry 	struct timer_list	timer;
51976867e6SJohn Garry 	u64		port_id; /* from hw */
525d74242eSJohn Garry 	u64		dev_sas_addr;
53976867e6SJohn Garry 	u64		phy_type;
54976867e6SJohn Garry 	u64		frame_rcvd_size;
55976867e6SJohn Garry 	u8		frame_rcvd[32];
56976867e6SJohn Garry 	u8		phy_attached;
57976867e6SJohn Garry 	u8		reserved[3];
58976867e6SJohn Garry 	enum sas_linkrate	minimum_linkrate;
59976867e6SJohn Garry 	enum sas_linkrate	maximum_linkrate;
607eb7869fSJohn Garry };
617eb7869fSJohn Garry 
627eb7869fSJohn Garry struct hisi_sas_port {
637eb7869fSJohn Garry 	struct asd_sas_port	sas_port;
64976867e6SJohn Garry 	u8	port_attached;
65976867e6SJohn Garry 	u8	id; /* from hw */
66976867e6SJohn Garry 	struct list_head	list;
677eb7869fSJohn Garry };
687eb7869fSJohn Garry 
699101a079SJohn Garry struct hisi_sas_cq {
709101a079SJohn Garry 	struct hisi_hba *hisi_hba;
719101a079SJohn Garry 	int	id;
729101a079SJohn Garry };
739101a079SJohn Garry 
74af740dbeSJohn Garry struct hisi_sas_device {
75af740dbeSJohn Garry 	enum sas_device_type	dev_type;
76af740dbeSJohn Garry 	u64 device_id;
77af740dbeSJohn Garry 	u8 dev_status;
78af740dbeSJohn Garry };
79af740dbeSJohn Garry 
806be6de18SJohn Garry struct hisi_sas_slot {
816be6de18SJohn Garry };
826be6de18SJohn Garry 
837eb7869fSJohn Garry struct hisi_sas_hw {
846be6de18SJohn Garry 	int complete_hdr_size;
857eb7869fSJohn Garry };
867eb7869fSJohn Garry 
877eb7869fSJohn Garry struct hisi_hba {
887eb7869fSJohn Garry 	/* This must be the first element, used by SHOST_TO_SAS_HA */
897eb7869fSJohn Garry 	struct sas_ha_struct *p;
907eb7869fSJohn Garry 
917eb7869fSJohn Garry 	struct platform_device *pdev;
92e26b2f40SJohn Garry 	void __iomem *regs;
93e26b2f40SJohn Garry 	struct regmap *ctrl;
94e26b2f40SJohn Garry 	u32 ctrl_reset_reg;
95e26b2f40SJohn Garry 	u32 ctrl_reset_sts_reg;
96e26b2f40SJohn Garry 	u32 ctrl_clock_ena_reg;
977eb7869fSJohn Garry 	u8 sas_addr[SAS_ADDR_SIZE];
987eb7869fSJohn Garry 
997eb7869fSJohn Garry 	int n_phy;
100*fa42d80dSJohn Garry 	spinlock_t lock;
1017eb7869fSJohn Garry 
102*fa42d80dSJohn Garry 	struct timer_list timer;
1037e9080e1SJohn Garry 	struct workqueue_struct *wq;
104257efd1fSJohn Garry 
105257efd1fSJohn Garry 	int slot_index_count;
106257efd1fSJohn Garry 	unsigned long *slot_index_tags;
107257efd1fSJohn Garry 
1087eb7869fSJohn Garry 	/* SCSI/SAS glue */
1097eb7869fSJohn Garry 	struct sas_ha_struct sha;
1107eb7869fSJohn Garry 	struct Scsi_Host *shost;
1119101a079SJohn Garry 
1129101a079SJohn Garry 	struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES];
1137eb7869fSJohn Garry 	struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS];
1147eb7869fSJohn Garry 	struct hisi_sas_port port[HISI_SAS_MAX_PHYS];
115e26b2f40SJohn Garry 
116e26b2f40SJohn Garry 	int	queue_count;
117e26b2f40SJohn Garry 	char	*int_names;
1186be6de18SJohn Garry 
1196be6de18SJohn Garry 	struct dma_pool *sge_page_pool;
120af740dbeSJohn Garry 	struct hisi_sas_device	devices[HISI_SAS_MAX_DEVICES];
1216be6de18SJohn Garry 	struct dma_pool *command_table_pool;
1226be6de18SJohn Garry 	struct dma_pool *status_buffer_pool;
1236be6de18SJohn Garry 	struct hisi_sas_cmd_hdr	*cmd_hdr[HISI_SAS_MAX_QUEUES];
1246be6de18SJohn Garry 	dma_addr_t cmd_hdr_dma[HISI_SAS_MAX_QUEUES];
1256be6de18SJohn Garry 	void *complete_hdr[HISI_SAS_MAX_QUEUES];
1266be6de18SJohn Garry 	dma_addr_t complete_hdr_dma[HISI_SAS_MAX_QUEUES];
1276be6de18SJohn Garry 	struct hisi_sas_initial_fis *initial_fis;
1286be6de18SJohn Garry 	dma_addr_t initial_fis_dma;
1296be6de18SJohn Garry 	struct hisi_sas_itct *itct;
1306be6de18SJohn Garry 	dma_addr_t itct_dma;
1316be6de18SJohn Garry 	struct hisi_sas_iost *iost;
1326be6de18SJohn Garry 	dma_addr_t iost_dma;
1336be6de18SJohn Garry 	struct hisi_sas_breakpoint *breakpoint;
1346be6de18SJohn Garry 	dma_addr_t breakpoint_dma;
1356be6de18SJohn Garry 	struct hisi_sas_breakpoint *sata_breakpoint;
1366be6de18SJohn Garry 	dma_addr_t sata_breakpoint_dma;
1376be6de18SJohn Garry 	struct hisi_sas_slot	*slot_info;
1387eb7869fSJohn Garry 	const struct hisi_sas_hw *hw;	/* Low level hw interface */
1397eb7869fSJohn Garry };
1407eb7869fSJohn Garry 
141c799d6bdSJohn Garry /* Generic HW DMA host memory structures */
142c799d6bdSJohn Garry /* Delivery queue header */
143c799d6bdSJohn Garry struct hisi_sas_cmd_hdr {
144c799d6bdSJohn Garry 	/* dw0 */
145c799d6bdSJohn Garry 	__le32 dw0;
146c799d6bdSJohn Garry 
147c799d6bdSJohn Garry 	/* dw1 */
148c799d6bdSJohn Garry 	__le32 dw1;
149c799d6bdSJohn Garry 
150c799d6bdSJohn Garry 	/* dw2 */
151c799d6bdSJohn Garry 	__le32 dw2;
152c799d6bdSJohn Garry 
153c799d6bdSJohn Garry 	/* dw3 */
154c799d6bdSJohn Garry 	__le32 transfer_tags;
155c799d6bdSJohn Garry 
156c799d6bdSJohn Garry 	/* dw4 */
157c799d6bdSJohn Garry 	__le32 data_transfer_len;
158c799d6bdSJohn Garry 
159c799d6bdSJohn Garry 	/* dw5 */
160c799d6bdSJohn Garry 	__le32 first_burst_num;
161c799d6bdSJohn Garry 
162c799d6bdSJohn Garry 	/* dw6 */
163c799d6bdSJohn Garry 	__le32 sg_len;
164c799d6bdSJohn Garry 
165c799d6bdSJohn Garry 	/* dw7 */
166c799d6bdSJohn Garry 	__le32 dw7;
167c799d6bdSJohn Garry 
168c799d6bdSJohn Garry 	/* dw8-9 */
169c799d6bdSJohn Garry 	__le64 cmd_table_addr;
170c799d6bdSJohn Garry 
171c799d6bdSJohn Garry 	/* dw10-11 */
172c799d6bdSJohn Garry 	__le64 sts_buffer_addr;
173c799d6bdSJohn Garry 
174c799d6bdSJohn Garry 	/* dw12-13 */
175c799d6bdSJohn Garry 	__le64 prd_table_addr;
176c799d6bdSJohn Garry 
177c799d6bdSJohn Garry 	/* dw14-15 */
178c799d6bdSJohn Garry 	__le64 dif_prd_table_addr;
179c799d6bdSJohn Garry };
180c799d6bdSJohn Garry 
181c799d6bdSJohn Garry struct hisi_sas_itct {
182c799d6bdSJohn Garry 	__le64 qw0;
183c799d6bdSJohn Garry 	__le64 sas_addr;
184c799d6bdSJohn Garry 	__le64 qw2;
185c799d6bdSJohn Garry 	__le64 qw3;
186c799d6bdSJohn Garry 	__le64 qw4;
187c799d6bdSJohn Garry 	__le64 qw_sata_ncq0_3;
188c799d6bdSJohn Garry 	__le64 qw_sata_ncq7_4;
189c799d6bdSJohn Garry 	__le64 qw_sata_ncq11_8;
190c799d6bdSJohn Garry 	__le64 qw_sata_ncq15_12;
191c799d6bdSJohn Garry 	__le64 qw_sata_ncq19_16;
192c799d6bdSJohn Garry 	__le64 qw_sata_ncq23_20;
193c799d6bdSJohn Garry 	__le64 qw_sata_ncq27_24;
194c799d6bdSJohn Garry 	__le64 qw_sata_ncq31_28;
195c799d6bdSJohn Garry 	__le64 qw_non_ncq_iptt;
196c799d6bdSJohn Garry 	__le64 qw_rsvd0;
197c799d6bdSJohn Garry 	__le64 qw_rsvd1;
198c799d6bdSJohn Garry };
199c799d6bdSJohn Garry 
200c799d6bdSJohn Garry struct hisi_sas_iost {
201c799d6bdSJohn Garry 	__le64 qw0;
202c799d6bdSJohn Garry 	__le64 qw1;
203c799d6bdSJohn Garry 	__le64 qw2;
204c799d6bdSJohn Garry 	__le64 qw3;
205c799d6bdSJohn Garry };
206c799d6bdSJohn Garry 
207c799d6bdSJohn Garry struct hisi_sas_err_record {
208c799d6bdSJohn Garry 	/* dw0 */
209c799d6bdSJohn Garry 	__le32 dma_err_type;
210c799d6bdSJohn Garry 
211c799d6bdSJohn Garry 	/* dw1 */
212c799d6bdSJohn Garry 	__le32 trans_tx_fail_type;
213c799d6bdSJohn Garry 
214c799d6bdSJohn Garry 	/* dw2 */
215c799d6bdSJohn Garry 	__le32 trans_rx_fail_type;
216c799d6bdSJohn Garry 
217c799d6bdSJohn Garry 	/* dw3 */
218c799d6bdSJohn Garry 	u32 rsvd;
219c799d6bdSJohn Garry };
220c799d6bdSJohn Garry 
221c799d6bdSJohn Garry struct hisi_sas_initial_fis {
222c799d6bdSJohn Garry 	struct hisi_sas_err_record err_record;
223c799d6bdSJohn Garry 	struct dev_to_host_fis fis;
224c799d6bdSJohn Garry 	u32 rsvd[3];
225c799d6bdSJohn Garry };
226c799d6bdSJohn Garry 
227c799d6bdSJohn Garry struct hisi_sas_breakpoint {
228c799d6bdSJohn Garry 	u8	data[128];	/*io128 byte*/
229c799d6bdSJohn Garry };
230c799d6bdSJohn Garry 
231c799d6bdSJohn Garry struct hisi_sas_sge {
232c799d6bdSJohn Garry 	__le64 addr;
233c799d6bdSJohn Garry 	__le32 page_ctrl_0;
234c799d6bdSJohn Garry 	__le32 page_ctrl_1;
235c799d6bdSJohn Garry 	__le32 data_len;
236c799d6bdSJohn Garry 	__le32 data_off;
237c799d6bdSJohn Garry };
238c799d6bdSJohn Garry 
239c799d6bdSJohn Garry struct hisi_sas_command_table_smp {
240c799d6bdSJohn Garry 	u8 bytes[44];
241c799d6bdSJohn Garry };
242c799d6bdSJohn Garry 
243c799d6bdSJohn Garry struct hisi_sas_command_table_stp {
244c799d6bdSJohn Garry 	struct	host_to_dev_fis command_fis;
245c799d6bdSJohn Garry 	u8	dummy[12];
246c799d6bdSJohn Garry 	u8	atapi_cdb[ATAPI_CDB_LEN];
247c799d6bdSJohn Garry };
248c799d6bdSJohn Garry 
2497eb7869fSJohn Garry #define HISI_SAS_SGE_PAGE_CNT SCSI_MAX_SG_SEGMENTS
250c799d6bdSJohn Garry struct hisi_sas_sge_page {
251c799d6bdSJohn Garry 	struct hisi_sas_sge sge[HISI_SAS_SGE_PAGE_CNT];
252c799d6bdSJohn Garry };
253c799d6bdSJohn Garry 
254c799d6bdSJohn Garry struct hisi_sas_command_table_ssp {
255c799d6bdSJohn Garry 	struct ssp_frame_hdr hdr;
256c799d6bdSJohn Garry 	union {
257c799d6bdSJohn Garry 		struct {
258c799d6bdSJohn Garry 			struct ssp_command_iu task;
259c799d6bdSJohn Garry 			u32 prot[6];
260c799d6bdSJohn Garry 		};
261c799d6bdSJohn Garry 		struct ssp_tmf_iu ssp_task;
262c799d6bdSJohn Garry 		struct xfer_rdy_iu xfer_rdy;
263c799d6bdSJohn Garry 		struct ssp_response_iu ssp_res;
264c799d6bdSJohn Garry 	} u;
265c799d6bdSJohn Garry };
266c799d6bdSJohn Garry 
267c799d6bdSJohn Garry union hisi_sas_command_table {
268c799d6bdSJohn Garry 	struct hisi_sas_command_table_ssp ssp;
269c799d6bdSJohn Garry 	struct hisi_sas_command_table_smp smp;
270c799d6bdSJohn Garry 	struct hisi_sas_command_table_stp stp;
271c799d6bdSJohn Garry };
272c799d6bdSJohn Garry 
273e8899fadSJohn Garry #endif
274