xref: /linux/drivers/scsi/hisi_sas/hisi_sas.h (revision 784b46b7cba0ae914dd293f23848c5057c6ba017)
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 
154d558c77SJohn Garry #include <linux/acpi.h>
163bc45af8SJohn Garry #include <linux/clk.h>
17e8899fadSJohn Garry #include <linux/dmapool.h>
18a25d0d3dSXiang Chen #include <linux/iopoll.h>
192ba5afb6SXiang Chen #include <linux/lcm.h>
20e8899fadSJohn Garry #include <linux/mfd/syscon.h>
21e8899fadSJohn Garry #include <linux/module.h>
22e8899fadSJohn Garry #include <linux/of_address.h>
2311b75249SJohn Garry #include <linux/pci.h>
24e8899fadSJohn Garry #include <linux/platform_device.h>
254d558c77SJohn Garry #include <linux/property.h>
26e8899fadSJohn Garry #include <linux/regmap.h>
276f2ff1a1SJohn Garry #include <scsi/sas_ata.h>
28e8899fadSJohn Garry #include <scsi/libsas.h>
29e8899fadSJohn Garry 
307eb7869fSJohn Garry #define HISI_SAS_MAX_PHYS	9
316be6de18SJohn Garry #define HISI_SAS_MAX_QUEUES	32
326be6de18SJohn Garry #define HISI_SAS_QUEUE_SLOTS 512
333297ded1SXiang Chen #define HISI_SAS_MAX_ITCT_ENTRIES 1024
347eb7869fSJohn Garry #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
3506ec0fb9SXiang Chen #define HISI_SAS_RESET_BIT	0
36917d3bdaSXiaofei Tan #define HISI_SAS_REJECT_CMD_BIT	1
37*784b46b7SXiang Chen #define HISI_SAS_RESERVED_IPTT_CNT  96
387eb7869fSJohn Garry 
39f557e32cSXiaofei Tan #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
40f557e32cSXiaofei Tan #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
41f557e32cSXiaofei Tan 
42f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr(buf) \
43f557e32cSXiaofei Tan 	(buf + offsetof(struct hisi_sas_slot_buf_table, status_buffer))
44f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr_mem(slot) hisi_sas_status_buf_addr(slot->buf)
45f557e32cSXiaofei Tan #define hisi_sas_status_buf_addr_dma(slot) \
46f557e32cSXiaofei Tan 	hisi_sas_status_buf_addr(slot->buf_dma)
47f557e32cSXiaofei Tan 
48f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr(buf) \
49f557e32cSXiaofei Tan 	(buf + offsetof(struct hisi_sas_slot_buf_table, command_header))
50f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr_mem(slot) hisi_sas_cmd_hdr_addr(slot->buf)
51f557e32cSXiaofei Tan #define hisi_sas_cmd_hdr_addr_dma(slot) hisi_sas_cmd_hdr_addr(slot->buf_dma)
52f557e32cSXiaofei Tan 
53f557e32cSXiaofei Tan #define hisi_sas_sge_addr(buf) \
54f557e32cSXiaofei Tan 	(buf + offsetof(struct hisi_sas_slot_buf_table, sge_page))
55f557e32cSXiaofei Tan #define hisi_sas_sge_addr_mem(slot) hisi_sas_sge_addr(slot->buf)
56f557e32cSXiaofei Tan #define hisi_sas_sge_addr_dma(slot) hisi_sas_sge_addr(slot->buf_dma)
576be6de18SJohn Garry 
5842e7a693SJohn Garry #define HISI_SAS_MAX_SSP_RESP_SZ (sizeof(struct ssp_frame_hdr) + 1024)
5966ee999bSJohn Garry #define HISI_SAS_MAX_SMP_RESP_SZ 1028
606f2ff1a1SJohn Garry #define HISI_SAS_MAX_STP_RESP_SZ 28
6142e7a693SJohn Garry 
6298bf39fcSJohn Garry #define DEV_IS_EXPANDER(type) \
6398bf39fcSJohn Garry 	((type == SAS_EDGE_EXPANDER_DEVICE) || \
6498bf39fcSJohn Garry 	(type == SAS_FANOUT_EXPANDER_DEVICE))
6598bf39fcSJohn Garry 
666c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_NONDATA		0x1
676c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_PIO			0x2
686c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_DMA			0x4
696c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_FPDMA		0x8
706c7bb8a1SXiang Chen #define HISI_SAS_SATA_PROTOCOL_ATAPI		0x10
716c7bb8a1SXiang Chen 
72abda97c2SJohn Garry struct hisi_hba;
73af740dbeSJohn Garry 
7407d78592SJohn Garry enum {
7507d78592SJohn Garry 	PORT_TYPE_SAS = (1U << 1),
7607d78592SJohn Garry 	PORT_TYPE_SATA = (1U << 0),
7707d78592SJohn Garry };
7807d78592SJohn Garry 
79af740dbeSJohn Garry enum dev_status {
80af740dbeSJohn Garry 	HISI_SAS_DEV_NORMAL,
81af740dbeSJohn Garry 	HISI_SAS_DEV_EH,
82af740dbeSJohn Garry };
83abda97c2SJohn Garry 
84441c2740SJohn Garry enum {
85441c2740SJohn Garry 	HISI_SAS_INT_ABT_CMD = 0,
86441c2740SJohn Garry 	HISI_SAS_INT_ABT_DEV = 1,
87441c2740SJohn Garry };
88441c2740SJohn Garry 
89abda97c2SJohn Garry enum hisi_sas_dev_type {
90abda97c2SJohn Garry 	HISI_SAS_DEV_TYPE_STP = 0,
91abda97c2SJohn Garry 	HISI_SAS_DEV_TYPE_SSP,
92abda97c2SJohn Garry 	HISI_SAS_DEV_TYPE_SATA,
93abda97c2SJohn Garry };
94abda97c2SJohn Garry 
952b383351SJohn Garry struct hisi_sas_hw_error {
962b383351SJohn Garry 	u32 irq_msk;
972b383351SJohn Garry 	u32 msk;
982b383351SJohn Garry 	int shift;
992b383351SJohn Garry 	const char *msg;
1002b383351SJohn Garry 	int reg;
101729428caSShiju Jose 	const struct hisi_sas_hw_error *sub;
1022b383351SJohn Garry };
1032b383351SJohn Garry 
104e402acdbSXiaofei Tan struct hisi_sas_rst {
105e402acdbSXiaofei Tan 	struct hisi_hba *hisi_hba;
106e402acdbSXiaofei Tan 	struct completion *completion;
107e402acdbSXiaofei Tan 	struct work_struct work;
108e402acdbSXiaofei Tan 	bool done;
109e402acdbSXiaofei Tan };
110e402acdbSXiaofei Tan 
111e402acdbSXiaofei Tan #define HISI_SAS_RST_WORK_INIT(r, c) \
112e402acdbSXiaofei Tan 	{	.hisi_hba = hisi_hba, \
113e402acdbSXiaofei Tan 		.completion = &c, \
114e402acdbSXiaofei Tan 		.work = __WORK_INITIALIZER(r.work, \
115e402acdbSXiaofei Tan 				hisi_sas_sync_rst_work_handler), \
116e402acdbSXiaofei Tan 		.done = false, \
117e402acdbSXiaofei Tan 		}
118e402acdbSXiaofei Tan 
119e402acdbSXiaofei Tan #define HISI_SAS_DECLARE_RST_WORK_ON_STACK(r) \
120e402acdbSXiaofei Tan 	DECLARE_COMPLETION_ONSTACK(c); \
121e402acdbSXiaofei Tan 	DECLARE_WORK(w, hisi_sas_sync_rst_work_handler); \
122e402acdbSXiaofei Tan 	struct hisi_sas_rst r = HISI_SAS_RST_WORK_INIT(r, c)
123e402acdbSXiaofei Tan 
124e402acdbSXiaofei Tan enum hisi_sas_bit_err_type {
125e402acdbSXiaofei Tan 	HISI_SAS_ERR_SINGLE_BIT_ECC = 0x0,
126e402acdbSXiaofei Tan 	HISI_SAS_ERR_MULTI_BIT_ECC = 0x1,
127e402acdbSXiaofei Tan };
128e402acdbSXiaofei Tan 
129e537b62bSXiaofei Tan enum hisi_sas_phy_event {
130e537b62bSXiaofei Tan 	HISI_PHYE_PHY_UP   = 0U,
131057c3d1fSXiaofei Tan 	HISI_PHYE_LINK_RESET,
132e537b62bSXiaofei Tan 	HISI_PHYES_NUM,
133e537b62bSXiaofei Tan };
134e537b62bSXiaofei Tan 
1357eb7869fSJohn Garry struct hisi_sas_phy {
136e537b62bSXiaofei Tan 	struct work_struct	works[HISI_PHYES_NUM];
137976867e6SJohn Garry 	struct hisi_hba	*hisi_hba;
138976867e6SJohn Garry 	struct hisi_sas_port	*port;
1397eb7869fSJohn Garry 	struct asd_sas_phy	sas_phy;
140976867e6SJohn Garry 	struct sas_identify	identify;
1413e1fb1b8SXiang Chen 	struct completion *reset_completion;
1423e1fb1b8SXiang Chen 	spinlock_t lock;
143976867e6SJohn Garry 	u64		port_id; /* from hw */
144976867e6SJohn Garry 	u64		frame_rcvd_size;
145976867e6SJohn Garry 	u8		frame_rcvd[32];
146976867e6SJohn Garry 	u8		phy_attached;
1473e1fb1b8SXiang Chen 	u8		in_reset;
1483e1fb1b8SXiang Chen 	u8		reserved[2];
149d0ef10c9SJohn Garry 	u32		phy_type;
150976867e6SJohn Garry 	enum sas_linkrate	minimum_linkrate;
151976867e6SJohn Garry 	enum sas_linkrate	maximum_linkrate;
1527eb7869fSJohn Garry };
1537eb7869fSJohn Garry 
1547eb7869fSJohn Garry struct hisi_sas_port {
1557eb7869fSJohn Garry 	struct asd_sas_port	sas_port;
156976867e6SJohn Garry 	u8	port_attached;
157976867e6SJohn Garry 	u8	id; /* from hw */
1587eb7869fSJohn Garry };
1597eb7869fSJohn Garry 
1609101a079SJohn Garry struct hisi_sas_cq {
1619101a079SJohn Garry 	struct hisi_hba *hisi_hba;
162d177c408SJohn Garry 	struct tasklet_struct tasklet;
163e6c346f3SJohn Garry 	int	rd_point;
1649101a079SJohn Garry 	int	id;
1659101a079SJohn Garry };
1669101a079SJohn Garry 
1674fde02adSJohn Garry struct hisi_sas_dq {
1684fde02adSJohn Garry 	struct hisi_hba *hisi_hba;
169fa222db0SXiang Chen 	struct list_head list;
170b1a49412SXiang Chen 	spinlock_t lock;
1714fde02adSJohn Garry 	int	wr_point;
1724fde02adSJohn Garry 	int	id;
1734fde02adSJohn Garry };
1744fde02adSJohn Garry 
175af740dbeSJohn Garry struct hisi_sas_device {
176abda97c2SJohn Garry 	struct hisi_hba		*hisi_hba;
177abda97c2SJohn Garry 	struct domain_device	*sas_device;
178640acc9aSXiang Chen 	struct completion *completion;
179b1a49412SXiang Chen 	struct hisi_sas_dq	*dq;
180405314dfSJohn Garry 	struct list_head	list;
181ad604832SJohn Garry 	enum sas_device_type	dev_type;
182ad604832SJohn Garry 	int device_id;
18332ccba52SXiaofei Tan 	int sata_idx;
184ad604832SJohn Garry 	u8 dev_status;
185af740dbeSJohn Garry };
186af740dbeSJohn Garry 
18778bd2b4fSXiaofei Tan struct hisi_sas_tmf_task {
188b09fcd09SXiaofei Tan 	int force_phy;
189b09fcd09SXiaofei Tan 	int phy_id;
19078bd2b4fSXiaofei Tan 	u8 tmf;
19178bd2b4fSXiaofei Tan 	u16 tag_of_task_to_be_managed;
19278bd2b4fSXiaofei Tan };
19378bd2b4fSXiaofei Tan 
1946be6de18SJohn Garry struct hisi_sas_slot {
19542e7a693SJohn Garry 	struct list_head entry;
196fa222db0SXiang Chen 	struct list_head delivery;
19742e7a693SJohn Garry 	struct sas_task *task;
19842e7a693SJohn Garry 	struct hisi_sas_port	*port;
19942e7a693SJohn Garry 	u64	n_elem;
20042e7a693SJohn Garry 	int	dlvry_queue;
20142e7a693SJohn Garry 	int	dlvry_queue_slot;
20227a3f229SJohn Garry 	int	cmplt_queue;
20327a3f229SJohn Garry 	int	cmplt_queue_slot;
204cac9b2a2SJohn Garry 	int	abort;
205fa222db0SXiang Chen 	int	ready;
20642e7a693SJohn Garry 	void	*cmd_hdr;
20742e7a693SJohn Garry 	dma_addr_t cmd_hdr_dma;
2080844a3ffSJohn Garry 	struct timer_list internal_abort_timer;
209cd938e53SXiang Chen 	bool is_internal;
21078bd2b4fSXiaofei Tan 	struct hisi_sas_tmf_task *tmf;
2112ba5afb6SXiang Chen 	/* Do not reorder/change members after here */
2122ba5afb6SXiang Chen 	void	*buf;
2132ba5afb6SXiang Chen 	dma_addr_t buf_dma;
2142ba5afb6SXiang Chen 	int	idx;
2156be6de18SJohn Garry };
2166be6de18SJohn Garry 
2177eb7869fSJohn Garry struct hisi_sas_hw {
2188ff1d571SJohn Garry 	int (*hw_init)(struct hisi_hba *hisi_hba);
219abda97c2SJohn Garry 	void (*setup_itct)(struct hisi_hba *hisi_hba,
220abda97c2SJohn Garry 			   struct hisi_sas_device *device);
221*784b46b7SXiang Chen 	int (*slot_index_alloc)(struct hisi_hba *hisi_hba,
222685b6d6eSJohn Garry 				struct domain_device *device);
223685b6d6eSJohn Garry 	struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
22466139921SJohn Garry 	void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no);
225b1a49412SXiang Chen 	int (*get_free_slot)(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq);
226b1a49412SXiang Chen 	void (*start_delivery)(struct hisi_sas_dq *dq);
227a2b3820bSXiang Chen 	void (*prep_ssp)(struct hisi_hba *hisi_hba,
22878bd2b4fSXiaofei Tan 			struct hisi_sas_slot *slot);
229a2b3820bSXiang Chen 	void (*prep_smp)(struct hisi_hba *hisi_hba,
23066ee999bSJohn Garry 			struct hisi_sas_slot *slot);
231a2b3820bSXiang Chen 	void (*prep_stp)(struct hisi_hba *hisi_hba,
2326f2ff1a1SJohn Garry 			struct hisi_sas_slot *slot);
233a2b3820bSXiang Chen 	void (*prep_abort)(struct hisi_hba *hisi_hba,
234441c2740SJohn Garry 			  struct hisi_sas_slot *slot,
235441c2740SJohn Garry 			  int device_id, int abort_flag, int tag_to_abort);
23627a3f229SJohn Garry 	int (*slot_complete)(struct hisi_hba *hisi_hba,
237405314dfSJohn Garry 			     struct hisi_sas_slot *slot);
238396b8044SJohn Garry 	void (*phys_init)(struct hisi_hba *hisi_hba);
2391eb8eeacSXiang Chen 	void (*phy_start)(struct hisi_hba *hisi_hba, int phy_no);
240e4189d53SJohn Garry 	void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no);
241e4189d53SJohn Garry 	void (*phy_hard_reset)(struct hisi_hba *hisi_hba, int phy_no);
242c52108c6SXiaofei Tan 	void (*get_events)(struct hisi_hba *hisi_hba, int phy_no);
2432ae75787SXiang Chen 	void (*phy_set_linkrate)(struct hisi_hba *hisi_hba, int phy_no,
2442ae75787SXiang Chen 			struct sas_phy_linkrates *linkrates);
2452ae75787SXiang Chen 	enum sas_linkrate (*phy_get_max_linkrate)(void);
2460258141aSXiaofei Tan 	void (*clear_itct)(struct hisi_hba *hisi_hba,
24727a3f229SJohn Garry 			    struct hisi_sas_device *dev);
2480258141aSXiaofei Tan 	void (*free_device)(struct hisi_sas_device *sas_dev);
249184a4635SJohn Garry 	int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id);
250d30ff263SXiang Chen 	void (*dereg_device)(struct hisi_hba *hisi_hba,
251d30ff263SXiang Chen 				struct domain_device *device);
25206ec0fb9SXiang Chen 	int (*soft_reset)(struct hisi_hba *hisi_hba);
253917d3bdaSXiaofei Tan 	u32 (*get_phys_state)(struct hisi_hba *hisi_hba);
2546379c560SXiaofei Tan 	int (*write_gpio)(struct hisi_hba *hisi_hba, u8 reg_type,
2556379c560SXiaofei Tan 				u8 reg_index, u8 reg_count, u8 *write_data);
256a865ae14SXiaofei Tan 	void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba,
257a865ae14SXiaofei Tan 					   int delay_ms, int timeout_ms);
258a8d547bdSJohn Garry 	int max_command_entries;
2596be6de18SJohn Garry 	int complete_hdr_size;
260235bfc7fSXiang Chen 	struct scsi_host_template *sht;
2617eb7869fSJohn Garry };
2627eb7869fSJohn Garry 
2637eb7869fSJohn Garry struct hisi_hba {
2647eb7869fSJohn Garry 	/* This must be the first element, used by SHOST_TO_SAS_HA */
2657eb7869fSJohn Garry 	struct sas_ha_struct *p;
2667eb7869fSJohn Garry 
26711b75249SJohn Garry 	struct platform_device *platform_dev;
26811b75249SJohn Garry 	struct pci_dev *pci_dev;
26911b75249SJohn Garry 	struct device *dev;
27011b75249SJohn Garry 
271e26b2f40SJohn Garry 	void __iomem *regs;
2726379c560SXiaofei Tan 	void __iomem *sgpio_regs;
273e26b2f40SJohn Garry 	struct regmap *ctrl;
274e26b2f40SJohn Garry 	u32 ctrl_reset_reg;
275e26b2f40SJohn Garry 	u32 ctrl_reset_sts_reg;
276e26b2f40SJohn Garry 	u32 ctrl_clock_ena_reg;
2773bc45af8SJohn Garry 	u32 refclk_frequency_mhz;
2787eb7869fSJohn Garry 	u8 sas_addr[SAS_ADDR_SIZE];
2797eb7869fSJohn Garry 
2807eb7869fSJohn Garry 	int n_phy;
281fa42d80dSJohn Garry 	spinlock_t lock;
282d2fc401eSXiaofei Tan 	struct semaphore sem;
2837eb7869fSJohn Garry 
284fa42d80dSJohn Garry 	struct timer_list timer;
2857e9080e1SJohn Garry 	struct workqueue_struct *wq;
286257efd1fSJohn Garry 
287257efd1fSJohn Garry 	int slot_index_count;
288fa3be0f2SXiang Chen 	int last_slot_index;
2891b865185SXiang Chen 	int last_dev_id;
290257efd1fSJohn Garry 	unsigned long *slot_index_tags;
291c7b9d369SXiaofei Tan 	unsigned long reject_stp_links_msk;
292257efd1fSJohn Garry 
2937eb7869fSJohn Garry 	/* SCSI/SAS glue */
2947eb7869fSJohn Garry 	struct sas_ha_struct sha;
2957eb7869fSJohn Garry 	struct Scsi_Host *shost;
2969101a079SJohn Garry 
2979101a079SJohn Garry 	struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES];
2984fde02adSJohn Garry 	struct hisi_sas_dq dq[HISI_SAS_MAX_QUEUES];
2997eb7869fSJohn Garry 	struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS];
3007eb7869fSJohn Garry 	struct hisi_sas_port port[HISI_SAS_MAX_PHYS];
301e26b2f40SJohn Garry 
302e26b2f40SJohn Garry 	int	queue_count;
3036be6de18SJohn Garry 
304af740dbeSJohn Garry 	struct hisi_sas_device	devices[HISI_SAS_MAX_DEVICES];
3056be6de18SJohn Garry 	struct hisi_sas_cmd_hdr	*cmd_hdr[HISI_SAS_MAX_QUEUES];
3066be6de18SJohn Garry 	dma_addr_t cmd_hdr_dma[HISI_SAS_MAX_QUEUES];
3076be6de18SJohn Garry 	void *complete_hdr[HISI_SAS_MAX_QUEUES];
3086be6de18SJohn Garry 	dma_addr_t complete_hdr_dma[HISI_SAS_MAX_QUEUES];
3096be6de18SJohn Garry 	struct hisi_sas_initial_fis *initial_fis;
3106be6de18SJohn Garry 	dma_addr_t initial_fis_dma;
3116be6de18SJohn Garry 	struct hisi_sas_itct *itct;
3126be6de18SJohn Garry 	dma_addr_t itct_dma;
3136be6de18SJohn Garry 	struct hisi_sas_iost *iost;
3146be6de18SJohn Garry 	dma_addr_t iost_dma;
3156be6de18SJohn Garry 	struct hisi_sas_breakpoint *breakpoint;
3166be6de18SJohn Garry 	dma_addr_t breakpoint_dma;
3176be6de18SJohn Garry 	struct hisi_sas_breakpoint *sata_breakpoint;
3186be6de18SJohn Garry 	dma_addr_t sata_breakpoint_dma;
3196be6de18SJohn Garry 	struct hisi_sas_slot	*slot_info;
32006ec0fb9SXiang Chen 	unsigned long flags;
3217eb7869fSJohn Garry 	const struct hisi_sas_hw *hw;	/* Low level hw interface */
32232ccba52SXiaofei Tan 	unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
32306ec0fb9SXiang Chen 	struct work_struct rst_work;
3244522204aSXiaofei Tan 	u32 phy_state;
3257eb7869fSJohn Garry };
3267eb7869fSJohn Garry 
327c799d6bdSJohn Garry /* Generic HW DMA host memory structures */
328c799d6bdSJohn Garry /* Delivery queue header */
329c799d6bdSJohn Garry struct hisi_sas_cmd_hdr {
330c799d6bdSJohn Garry 	/* dw0 */
331c799d6bdSJohn Garry 	__le32 dw0;
332c799d6bdSJohn Garry 
333c799d6bdSJohn Garry 	/* dw1 */
334c799d6bdSJohn Garry 	__le32 dw1;
335c799d6bdSJohn Garry 
336c799d6bdSJohn Garry 	/* dw2 */
337c799d6bdSJohn Garry 	__le32 dw2;
338c799d6bdSJohn Garry 
339c799d6bdSJohn Garry 	/* dw3 */
340c799d6bdSJohn Garry 	__le32 transfer_tags;
341c799d6bdSJohn Garry 
342c799d6bdSJohn Garry 	/* dw4 */
343c799d6bdSJohn Garry 	__le32 data_transfer_len;
344c799d6bdSJohn Garry 
345c799d6bdSJohn Garry 	/* dw5 */
346c799d6bdSJohn Garry 	__le32 first_burst_num;
347c799d6bdSJohn Garry 
348c799d6bdSJohn Garry 	/* dw6 */
349c799d6bdSJohn Garry 	__le32 sg_len;
350c799d6bdSJohn Garry 
351c799d6bdSJohn Garry 	/* dw7 */
352c799d6bdSJohn Garry 	__le32 dw7;
353c799d6bdSJohn Garry 
354c799d6bdSJohn Garry 	/* dw8-9 */
355c799d6bdSJohn Garry 	__le64 cmd_table_addr;
356c799d6bdSJohn Garry 
357c799d6bdSJohn Garry 	/* dw10-11 */
358c799d6bdSJohn Garry 	__le64 sts_buffer_addr;
359c799d6bdSJohn Garry 
360c799d6bdSJohn Garry 	/* dw12-13 */
361c799d6bdSJohn Garry 	__le64 prd_table_addr;
362c799d6bdSJohn Garry 
363c799d6bdSJohn Garry 	/* dw14-15 */
364c799d6bdSJohn Garry 	__le64 dif_prd_table_addr;
365c799d6bdSJohn Garry };
366c799d6bdSJohn Garry 
367c799d6bdSJohn Garry struct hisi_sas_itct {
368c799d6bdSJohn Garry 	__le64 qw0;
369c799d6bdSJohn Garry 	__le64 sas_addr;
370c799d6bdSJohn Garry 	__le64 qw2;
371c799d6bdSJohn Garry 	__le64 qw3;
372281e3bf6SJohn Garry 	__le64 qw4_15[12];
373c799d6bdSJohn Garry };
374c799d6bdSJohn Garry 
375c799d6bdSJohn Garry struct hisi_sas_iost {
376c799d6bdSJohn Garry 	__le64 qw0;
377c799d6bdSJohn Garry 	__le64 qw1;
378c799d6bdSJohn Garry 	__le64 qw2;
379c799d6bdSJohn Garry 	__le64 qw3;
380c799d6bdSJohn Garry };
381c799d6bdSJohn Garry 
382c799d6bdSJohn Garry struct hisi_sas_err_record {
3838d1eee7dSJohn Garry 	u32	data[4];
384c799d6bdSJohn Garry };
385c799d6bdSJohn Garry 
386c799d6bdSJohn Garry struct hisi_sas_initial_fis {
387c799d6bdSJohn Garry 	struct hisi_sas_err_record err_record;
388c799d6bdSJohn Garry 	struct dev_to_host_fis fis;
389c799d6bdSJohn Garry 	u32 rsvd[3];
390c799d6bdSJohn Garry };
391c799d6bdSJohn Garry 
392c799d6bdSJohn Garry struct hisi_sas_breakpoint {
3933297ded1SXiang Chen 	u8	data[128];
3943297ded1SXiang Chen };
3953297ded1SXiang Chen 
3963297ded1SXiang Chen struct hisi_sas_sata_breakpoint {
3973297ded1SXiang Chen 	struct hisi_sas_breakpoint tag[32];
398c799d6bdSJohn Garry };
399c799d6bdSJohn Garry 
400c799d6bdSJohn Garry struct hisi_sas_sge {
401c799d6bdSJohn Garry 	__le64 addr;
402c799d6bdSJohn Garry 	__le32 page_ctrl_0;
403c799d6bdSJohn Garry 	__le32 page_ctrl_1;
404c799d6bdSJohn Garry 	__le32 data_len;
405c799d6bdSJohn Garry 	__le32 data_off;
406c799d6bdSJohn Garry };
407c799d6bdSJohn Garry 
408c799d6bdSJohn Garry struct hisi_sas_command_table_smp {
409c799d6bdSJohn Garry 	u8 bytes[44];
410c799d6bdSJohn Garry };
411c799d6bdSJohn Garry 
412c799d6bdSJohn Garry struct hisi_sas_command_table_stp {
413c799d6bdSJohn Garry 	struct	host_to_dev_fis command_fis;
414c799d6bdSJohn Garry 	u8	dummy[12];
415c799d6bdSJohn Garry 	u8	atapi_cdb[ATAPI_CDB_LEN];
416c799d6bdSJohn Garry };
417c799d6bdSJohn Garry 
41865e8617fSMing Lin #define HISI_SAS_SGE_PAGE_CNT SG_CHUNK_SIZE
419c799d6bdSJohn Garry struct hisi_sas_sge_page {
420c799d6bdSJohn Garry 	struct hisi_sas_sge sge[HISI_SAS_SGE_PAGE_CNT];
421f557e32cSXiaofei Tan }  __aligned(16);
422c799d6bdSJohn Garry 
423c799d6bdSJohn Garry struct hisi_sas_command_table_ssp {
424c799d6bdSJohn Garry 	struct ssp_frame_hdr hdr;
425c799d6bdSJohn Garry 	union {
426c799d6bdSJohn Garry 		struct {
427c799d6bdSJohn Garry 			struct ssp_command_iu task;
428a14da7a2SXiang Chen 			u32 prot[7];
429c799d6bdSJohn Garry 		};
430c799d6bdSJohn Garry 		struct ssp_tmf_iu ssp_task;
431c799d6bdSJohn Garry 		struct xfer_rdy_iu xfer_rdy;
432c799d6bdSJohn Garry 		struct ssp_response_iu ssp_res;
433c799d6bdSJohn Garry 	} u;
434c799d6bdSJohn Garry };
435c799d6bdSJohn Garry 
436c799d6bdSJohn Garry union hisi_sas_command_table {
437c799d6bdSJohn Garry 	struct hisi_sas_command_table_ssp ssp;
438c799d6bdSJohn Garry 	struct hisi_sas_command_table_smp smp;
439c799d6bdSJohn Garry 	struct hisi_sas_command_table_stp stp;
440f557e32cSXiaofei Tan }  __aligned(16);
441f557e32cSXiaofei Tan 
442f557e32cSXiaofei Tan struct hisi_sas_status_buffer {
443f557e32cSXiaofei Tan 	struct hisi_sas_err_record err;
444f557e32cSXiaofei Tan 	u8	iu[1024];
445f557e32cSXiaofei Tan }  __aligned(16);
446f557e32cSXiaofei Tan 
447f557e32cSXiaofei Tan struct hisi_sas_slot_buf_table {
448f557e32cSXiaofei Tan 	struct hisi_sas_status_buffer status_buffer;
449f557e32cSXiaofei Tan 	union hisi_sas_command_table command_header;
450f557e32cSXiaofei Tan 	struct hisi_sas_sge_page sge_page;
451c799d6bdSJohn Garry };
4522e244f0fSJohn Garry 
453e21fe3a5SJohn Garry extern struct scsi_transport_template *hisi_sas_stt;
454a25d0d3dSXiang Chen extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba);
455e21fe3a5SJohn Garry extern int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost);
456e21fe3a5SJohn Garry extern void hisi_sas_free(struct hisi_hba *hisi_hba);
457468f4b8dSchenxiang extern u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis,
458468f4b8dSchenxiang 				int direction);
4592e244f0fSJohn Garry extern struct hisi_sas_port *to_hisi_sas_port(struct asd_sas_port *sas_port);
46075904077SXiang Chen extern void hisi_sas_sata_done(struct sas_task *task,
46175904077SXiang Chen 			    struct hisi_sas_slot *slot);
462318913c6SXiang Chen extern int hisi_sas_get_ncq_tag(struct sas_task *task, u32 *tag);
4630fa24c19SJohn Garry extern int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba);
4649fb10b54SJohn Garry extern int hisi_sas_probe(struct platform_device *pdev,
4659fb10b54SJohn Garry 			  const struct hisi_sas_hw *ops);
4669fb10b54SJohn Garry extern int hisi_sas_remove(struct platform_device *pdev);
467c799d6bdSJohn Garry 
468235bfc7fSXiang Chen extern int hisi_sas_slave_configure(struct scsi_device *sdev);
469235bfc7fSXiang Chen extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time);
470235bfc7fSXiang Chen extern void hisi_sas_scan_start(struct Scsi_Host *shost);
471235bfc7fSXiang Chen extern struct device_attribute *host_attrs[];
472235bfc7fSXiang Chen extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
473184a4635SJohn Garry extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
47427a3f229SJohn Garry extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
47527a3f229SJohn Garry 				    struct sas_task *task,
47627a3f229SJohn Garry 				    struct hisi_sas_slot *slot);
47706ec0fb9SXiang Chen extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba);
478b4241f0fSXiaofei Tan extern void hisi_sas_rst_work_handler(struct work_struct *work);
479e402acdbSXiaofei Tan extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);
480571295f8SXiaofei Tan extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba);
481e537b62bSXiaofei Tan extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
482e537b62bSXiaofei Tan 				enum hisi_sas_phy_event event);
4834d0951eeSXiang Chen extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba);
484c2c1d9deSXiang Chen extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max);
4854522204aSXiaofei Tan extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba);
4864522204aSXiaofei Tan extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba);
487e8899fadSJohn Garry #endif
488