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