1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * drivers/dma/fsl_raid.h 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Freescale RAID Engine device driver 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Author: 7*4882a593Smuzhiyun * Harninder Rai <harninder.rai@freescale.com> 8*4882a593Smuzhiyun * Naveen Burmi <naveenburmi@freescale.com> 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * Rewrite: 11*4882a593Smuzhiyun * Xuelin Shi <xuelin.shi@freescale.com> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun * Copyright (c) 2010-2012 Freescale Semiconductor, Inc. 14*4882a593Smuzhiyun * 15*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without 16*4882a593Smuzhiyun * modification, are permitted provided that the following conditions are met: 17*4882a593Smuzhiyun * * Redistributions of source code must retain the above copyright 18*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer. 19*4882a593Smuzhiyun * * Redistributions in binary form must reproduce the above copyright 20*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer in the 21*4882a593Smuzhiyun * documentation and/or other materials provided with the distribution. 22*4882a593Smuzhiyun * * Neither the name of Freescale Semiconductor nor the 23*4882a593Smuzhiyun * names of its contributors may be used to endorse or promote products 24*4882a593Smuzhiyun * derived from this software without specific prior written permission. 25*4882a593Smuzhiyun * 26*4882a593Smuzhiyun * ALTERNATIVELY, this software may be distributed under the terms of the 27*4882a593Smuzhiyun * GNU General Public License ("GPL") as published by the Free Software 28*4882a593Smuzhiyun * Foundation, either version 2 of that License or (at your option) any 29*4882a593Smuzhiyun * later version. 30*4882a593Smuzhiyun * 31*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 32*4882a593Smuzhiyun * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 33*4882a593Smuzhiyun * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 34*4882a593Smuzhiyun * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 35*4882a593Smuzhiyun * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36*4882a593Smuzhiyun * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 37*4882a593Smuzhiyun * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 38*4882a593Smuzhiyun * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39*4882a593Smuzhiyun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 40*4882a593Smuzhiyun * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41*4882a593Smuzhiyun * 42*4882a593Smuzhiyun */ 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun #define FSL_RE_MAX_CHANS 4 45*4882a593Smuzhiyun #define FSL_RE_DPAA_MODE BIT(30) 46*4882a593Smuzhiyun #define FSL_RE_NON_DPAA_MODE BIT(31) 47*4882a593Smuzhiyun #define FSL_RE_GFM_POLY 0x1d000000 48*4882a593Smuzhiyun #define FSL_RE_ADD_JOB(x) ((x) << 16) 49*4882a593Smuzhiyun #define FSL_RE_RMVD_JOB(x) ((x) << 16) 50*4882a593Smuzhiyun #define FSL_RE_CFG1_CBSI 0x08000000 51*4882a593Smuzhiyun #define FSL_RE_CFG1_CBS0 0x00080000 52*4882a593Smuzhiyun #define FSL_RE_SLOT_FULL_SHIFT 8 53*4882a593Smuzhiyun #define FSL_RE_SLOT_FULL(x) ((x) >> FSL_RE_SLOT_FULL_SHIFT) 54*4882a593Smuzhiyun #define FSL_RE_SLOT_AVAIL_SHIFT 8 55*4882a593Smuzhiyun #define FSL_RE_SLOT_AVAIL(x) ((x) >> FSL_RE_SLOT_AVAIL_SHIFT) 56*4882a593Smuzhiyun #define FSL_RE_PQ_OPCODE 0x1B 57*4882a593Smuzhiyun #define FSL_RE_XOR_OPCODE 0x1A 58*4882a593Smuzhiyun #define FSL_RE_MOVE_OPCODE 0x8 59*4882a593Smuzhiyun #define FSL_RE_FRAME_ALIGN 16 60*4882a593Smuzhiyun #define FSL_RE_BLOCK_SIZE 0x3 /* 4096 bytes */ 61*4882a593Smuzhiyun #define FSL_RE_CACHEABLE_IO 0x0 62*4882a593Smuzhiyun #define FSL_RE_BUFFER_OUTPUT 0x0 63*4882a593Smuzhiyun #define FSL_RE_INTR_ON_ERROR 0x1 64*4882a593Smuzhiyun #define FSL_RE_DATA_DEP 0x1 65*4882a593Smuzhiyun #define FSL_RE_ENABLE_DPI 0x0 66*4882a593Smuzhiyun #define FSL_RE_RING_SIZE 0x400 67*4882a593Smuzhiyun #define FSL_RE_RING_SIZE_MASK (FSL_RE_RING_SIZE - 1) 68*4882a593Smuzhiyun #define FSL_RE_RING_SIZE_SHIFT 8 69*4882a593Smuzhiyun #define FSL_RE_ADDR_BIT_SHIFT 4 70*4882a593Smuzhiyun #define FSL_RE_ADDR_BIT_MASK (BIT(FSL_RE_ADDR_BIT_SHIFT) - 1) 71*4882a593Smuzhiyun #define FSL_RE_ERROR 0x40000000 72*4882a593Smuzhiyun #define FSL_RE_INTR 0x80000000 73*4882a593Smuzhiyun #define FSL_RE_CLR_INTR 0x80000000 74*4882a593Smuzhiyun #define FSL_RE_PAUSE 0x80000000 75*4882a593Smuzhiyun #define FSL_RE_ENABLE 0x80000000 76*4882a593Smuzhiyun #define FSL_RE_REG_LIODN_MASK 0x00000FFF 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun #define FSL_RE_CDB_OPCODE_MASK 0xF8000000 79*4882a593Smuzhiyun #define FSL_RE_CDB_OPCODE_SHIFT 27 80*4882a593Smuzhiyun #define FSL_RE_CDB_EXCLEN_MASK 0x03000000 81*4882a593Smuzhiyun #define FSL_RE_CDB_EXCLEN_SHIFT 24 82*4882a593Smuzhiyun #define FSL_RE_CDB_EXCLQ1_MASK 0x00F00000 83*4882a593Smuzhiyun #define FSL_RE_CDB_EXCLQ1_SHIFT 20 84*4882a593Smuzhiyun #define FSL_RE_CDB_EXCLQ2_MASK 0x000F0000 85*4882a593Smuzhiyun #define FSL_RE_CDB_EXCLQ2_SHIFT 16 86*4882a593Smuzhiyun #define FSL_RE_CDB_BLKSIZE_MASK 0x0000C000 87*4882a593Smuzhiyun #define FSL_RE_CDB_BLKSIZE_SHIFT 14 88*4882a593Smuzhiyun #define FSL_RE_CDB_CACHE_MASK 0x00003000 89*4882a593Smuzhiyun #define FSL_RE_CDB_CACHE_SHIFT 12 90*4882a593Smuzhiyun #define FSL_RE_CDB_BUFFER_MASK 0x00000800 91*4882a593Smuzhiyun #define FSL_RE_CDB_BUFFER_SHIFT 11 92*4882a593Smuzhiyun #define FSL_RE_CDB_ERROR_MASK 0x00000400 93*4882a593Smuzhiyun #define FSL_RE_CDB_ERROR_SHIFT 10 94*4882a593Smuzhiyun #define FSL_RE_CDB_NRCS_MASK 0x0000003C 95*4882a593Smuzhiyun #define FSL_RE_CDB_NRCS_SHIFT 6 96*4882a593Smuzhiyun #define FSL_RE_CDB_DEPEND_MASK 0x00000008 97*4882a593Smuzhiyun #define FSL_RE_CDB_DEPEND_SHIFT 3 98*4882a593Smuzhiyun #define FSL_RE_CDB_DPI_MASK 0x00000004 99*4882a593Smuzhiyun #define FSL_RE_CDB_DPI_SHIFT 2 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /* 102*4882a593Smuzhiyun * the largest cf block is 19*sizeof(struct cmpnd_frame), which is 304 bytes. 103*4882a593Smuzhiyun * here 19 = 1(cdb)+2(dest)+16(src), align to 64bytes, that is 320 bytes. 104*4882a593Smuzhiyun * the largest cdb block: struct pq_cdb which is 180 bytes, adding to cf block 105*4882a593Smuzhiyun * 320+180=500, align to 64bytes, that is 512 bytes. 106*4882a593Smuzhiyun */ 107*4882a593Smuzhiyun #define FSL_RE_CF_DESC_SIZE 320 108*4882a593Smuzhiyun #define FSL_RE_CF_CDB_SIZE 512 109*4882a593Smuzhiyun #define FSL_RE_CF_CDB_ALIGN 64 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun struct fsl_re_ctrl { 112*4882a593Smuzhiyun /* General Configuration Registers */ 113*4882a593Smuzhiyun __be32 global_config; /* Global Configuration Register */ 114*4882a593Smuzhiyun u8 rsvd1[4]; 115*4882a593Smuzhiyun __be32 galois_field_config; /* Galois Field Configuration Register */ 116*4882a593Smuzhiyun u8 rsvd2[4]; 117*4882a593Smuzhiyun __be32 jq_wrr_config; /* WRR Configuration register */ 118*4882a593Smuzhiyun u8 rsvd3[4]; 119*4882a593Smuzhiyun __be32 crc_config; /* CRC Configuration register */ 120*4882a593Smuzhiyun u8 rsvd4[228]; 121*4882a593Smuzhiyun __be32 system_reset; /* System Reset Register */ 122*4882a593Smuzhiyun u8 rsvd5[252]; 123*4882a593Smuzhiyun __be32 global_status; /* Global Status Register */ 124*4882a593Smuzhiyun u8 rsvd6[832]; 125*4882a593Smuzhiyun __be32 re_liodn_base; /* LIODN Base Register */ 126*4882a593Smuzhiyun u8 rsvd7[1712]; 127*4882a593Smuzhiyun __be32 re_version_id; /* Version ID register of RE */ 128*4882a593Smuzhiyun __be32 re_version_id_2; /* Version ID 2 register of RE */ 129*4882a593Smuzhiyun u8 rsvd8[512]; 130*4882a593Smuzhiyun __be32 host_config; /* Host I/F Configuration Register */ 131*4882a593Smuzhiyun }; 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun struct fsl_re_chan_cfg { 134*4882a593Smuzhiyun /* Registers for JR interface */ 135*4882a593Smuzhiyun __be32 jr_config_0; /* Job Queue Configuration 0 Register */ 136*4882a593Smuzhiyun __be32 jr_config_1; /* Job Queue Configuration 1 Register */ 137*4882a593Smuzhiyun __be32 jr_interrupt_status; /* Job Queue Interrupt Status Register */ 138*4882a593Smuzhiyun u8 rsvd1[4]; 139*4882a593Smuzhiyun __be32 jr_command; /* Job Queue Command Register */ 140*4882a593Smuzhiyun u8 rsvd2[4]; 141*4882a593Smuzhiyun __be32 jr_status; /* Job Queue Status Register */ 142*4882a593Smuzhiyun u8 rsvd3[228]; 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun /* Input Ring */ 145*4882a593Smuzhiyun __be32 inbring_base_h; /* Inbound Ring Base Address Register - High */ 146*4882a593Smuzhiyun __be32 inbring_base_l; /* Inbound Ring Base Address Register - Low */ 147*4882a593Smuzhiyun __be32 inbring_size; /* Inbound Ring Size Register */ 148*4882a593Smuzhiyun u8 rsvd4[4]; 149*4882a593Smuzhiyun __be32 inbring_slot_avail; /* Inbound Ring Slot Available Register */ 150*4882a593Smuzhiyun u8 rsvd5[4]; 151*4882a593Smuzhiyun __be32 inbring_add_job; /* Inbound Ring Add Job Register */ 152*4882a593Smuzhiyun u8 rsvd6[4]; 153*4882a593Smuzhiyun __be32 inbring_cnsmr_indx; /* Inbound Ring Consumer Index Register */ 154*4882a593Smuzhiyun u8 rsvd7[220]; 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun /* Output Ring */ 157*4882a593Smuzhiyun __be32 oubring_base_h; /* Outbound Ring Base Address Register - High */ 158*4882a593Smuzhiyun __be32 oubring_base_l; /* Outbound Ring Base Address Register - Low */ 159*4882a593Smuzhiyun __be32 oubring_size; /* Outbound Ring Size Register */ 160*4882a593Smuzhiyun u8 rsvd8[4]; 161*4882a593Smuzhiyun __be32 oubring_job_rmvd; /* Outbound Ring Job Removed Register */ 162*4882a593Smuzhiyun u8 rsvd9[4]; 163*4882a593Smuzhiyun __be32 oubring_slot_full; /* Outbound Ring Slot Full Register */ 164*4882a593Smuzhiyun u8 rsvd10[4]; 165*4882a593Smuzhiyun __be32 oubring_prdcr_indx; /* Outbound Ring Producer Index */ 166*4882a593Smuzhiyun }; 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun /* 169*4882a593Smuzhiyun * Command Descriptor Block (CDB) for unicast move command. 170*4882a593Smuzhiyun * In RAID Engine terms, memcpy is done through move command 171*4882a593Smuzhiyun */ 172*4882a593Smuzhiyun struct fsl_re_move_cdb { 173*4882a593Smuzhiyun __be32 cdb32; 174*4882a593Smuzhiyun }; 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun /* Data protection/integrity related fields */ 177*4882a593Smuzhiyun #define FSL_RE_DPI_APPS_MASK 0xC0000000 178*4882a593Smuzhiyun #define FSL_RE_DPI_APPS_SHIFT 30 179*4882a593Smuzhiyun #define FSL_RE_DPI_REF_MASK 0x30000000 180*4882a593Smuzhiyun #define FSL_RE_DPI_REF_SHIFT 28 181*4882a593Smuzhiyun #define FSL_RE_DPI_GUARD_MASK 0x0C000000 182*4882a593Smuzhiyun #define FSL_RE_DPI_GUARD_SHIFT 26 183*4882a593Smuzhiyun #define FSL_RE_DPI_ATTR_MASK 0x03000000 184*4882a593Smuzhiyun #define FSL_RE_DPI_ATTR_SHIFT 24 185*4882a593Smuzhiyun #define FSL_RE_DPI_META_MASK 0x0000FFFF 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun struct fsl_re_dpi { 188*4882a593Smuzhiyun __be32 dpi32; 189*4882a593Smuzhiyun __be32 ref; 190*4882a593Smuzhiyun }; 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun /* 193*4882a593Smuzhiyun * CDB for GenQ command. In RAID Engine terminology, XOR is 194*4882a593Smuzhiyun * done through this command 195*4882a593Smuzhiyun */ 196*4882a593Smuzhiyun struct fsl_re_xor_cdb { 197*4882a593Smuzhiyun __be32 cdb32; 198*4882a593Smuzhiyun u8 gfm[16]; 199*4882a593Smuzhiyun struct fsl_re_dpi dpi_dest_spec; 200*4882a593Smuzhiyun struct fsl_re_dpi dpi_src_spec[16]; 201*4882a593Smuzhiyun }; 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun /* CDB for no-op command */ 204*4882a593Smuzhiyun struct fsl_re_noop_cdb { 205*4882a593Smuzhiyun __be32 cdb32; 206*4882a593Smuzhiyun }; 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun /* 209*4882a593Smuzhiyun * CDB for GenQQ command. In RAID Engine terminology, P/Q is 210*4882a593Smuzhiyun * done through this command 211*4882a593Smuzhiyun */ 212*4882a593Smuzhiyun struct fsl_re_pq_cdb { 213*4882a593Smuzhiyun __be32 cdb32; 214*4882a593Smuzhiyun u8 gfm_q1[16]; 215*4882a593Smuzhiyun u8 gfm_q2[16]; 216*4882a593Smuzhiyun struct fsl_re_dpi dpi_dest_spec[2]; 217*4882a593Smuzhiyun struct fsl_re_dpi dpi_src_spec[16]; 218*4882a593Smuzhiyun }; 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun /* Compound frame */ 221*4882a593Smuzhiyun #define FSL_RE_CF_ADDR_HIGH_MASK 0x000000FF 222*4882a593Smuzhiyun #define FSL_RE_CF_EXT_MASK 0x80000000 223*4882a593Smuzhiyun #define FSL_RE_CF_EXT_SHIFT 31 224*4882a593Smuzhiyun #define FSL_RE_CF_FINAL_MASK 0x40000000 225*4882a593Smuzhiyun #define FSL_RE_CF_FINAL_SHIFT 30 226*4882a593Smuzhiyun #define FSL_RE_CF_LENGTH_MASK 0x000FFFFF 227*4882a593Smuzhiyun #define FSL_RE_CF_BPID_MASK 0x00FF0000 228*4882a593Smuzhiyun #define FSL_RE_CF_BPID_SHIFT 16 229*4882a593Smuzhiyun #define FSL_RE_CF_OFFSET_MASK 0x00001FFF 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun struct fsl_re_cmpnd_frame { 232*4882a593Smuzhiyun __be32 addr_high; 233*4882a593Smuzhiyun __be32 addr_low; 234*4882a593Smuzhiyun __be32 efrl32; 235*4882a593Smuzhiyun __be32 rbro32; 236*4882a593Smuzhiyun }; 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun /* Frame descriptor */ 239*4882a593Smuzhiyun #define FSL_RE_HWDESC_LIODN_MASK 0x3F000000 240*4882a593Smuzhiyun #define FSL_RE_HWDESC_LIODN_SHIFT 24 241*4882a593Smuzhiyun #define FSL_RE_HWDESC_BPID_MASK 0x00FF0000 242*4882a593Smuzhiyun #define FSL_RE_HWDESC_BPID_SHIFT 16 243*4882a593Smuzhiyun #define FSL_RE_HWDESC_ELIODN_MASK 0x0000F000 244*4882a593Smuzhiyun #define FSL_RE_HWDESC_ELIODN_SHIFT 12 245*4882a593Smuzhiyun #define FSL_RE_HWDESC_FMT_SHIFT 29 246*4882a593Smuzhiyun #define FSL_RE_HWDESC_FMT_MASK (0x3 << FSL_RE_HWDESC_FMT_SHIFT) 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun struct fsl_re_hw_desc { 249*4882a593Smuzhiyun __be32 lbea32; 250*4882a593Smuzhiyun __be32 addr_low; 251*4882a593Smuzhiyun __be32 fmt32; 252*4882a593Smuzhiyun __be32 status; 253*4882a593Smuzhiyun }; 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun /* Raid Engine device private data */ 256*4882a593Smuzhiyun struct fsl_re_drv_private { 257*4882a593Smuzhiyun u8 total_chans; 258*4882a593Smuzhiyun struct dma_device dma_dev; 259*4882a593Smuzhiyun struct fsl_re_ctrl *re_regs; 260*4882a593Smuzhiyun struct fsl_re_chan *re_jrs[FSL_RE_MAX_CHANS]; 261*4882a593Smuzhiyun struct dma_pool *cf_desc_pool; 262*4882a593Smuzhiyun struct dma_pool *hw_desc_pool; 263*4882a593Smuzhiyun }; 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun /* Per job ring data structure */ 266*4882a593Smuzhiyun struct fsl_re_chan { 267*4882a593Smuzhiyun char name[16]; 268*4882a593Smuzhiyun spinlock_t desc_lock; /* queue lock */ 269*4882a593Smuzhiyun struct list_head ack_q; /* wait to acked queue */ 270*4882a593Smuzhiyun struct list_head active_q; /* already issued on hw, not completed */ 271*4882a593Smuzhiyun struct list_head submit_q; 272*4882a593Smuzhiyun struct list_head free_q; /* alloc available queue */ 273*4882a593Smuzhiyun struct device *dev; 274*4882a593Smuzhiyun struct fsl_re_drv_private *re_dev; 275*4882a593Smuzhiyun struct dma_chan chan; 276*4882a593Smuzhiyun struct fsl_re_chan_cfg *jrregs; 277*4882a593Smuzhiyun int irq; 278*4882a593Smuzhiyun struct tasklet_struct irqtask; 279*4882a593Smuzhiyun u32 alloc_count; 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun /* hw descriptor ring for inbound queue*/ 282*4882a593Smuzhiyun dma_addr_t inb_phys_addr; 283*4882a593Smuzhiyun struct fsl_re_hw_desc *inb_ring_virt_addr; 284*4882a593Smuzhiyun u32 inb_count; 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun /* hw descriptor ring for outbound queue */ 287*4882a593Smuzhiyun dma_addr_t oub_phys_addr; 288*4882a593Smuzhiyun struct fsl_re_hw_desc *oub_ring_virt_addr; 289*4882a593Smuzhiyun u32 oub_count; 290*4882a593Smuzhiyun }; 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun /* Async transaction descriptor */ 293*4882a593Smuzhiyun struct fsl_re_desc { 294*4882a593Smuzhiyun struct dma_async_tx_descriptor async_tx; 295*4882a593Smuzhiyun struct list_head node; 296*4882a593Smuzhiyun struct fsl_re_hw_desc hwdesc; 297*4882a593Smuzhiyun struct fsl_re_chan *re_chan; 298*4882a593Smuzhiyun 299*4882a593Smuzhiyun /* hwdesc will point to cf_addr */ 300*4882a593Smuzhiyun void *cf_addr; 301*4882a593Smuzhiyun dma_addr_t cf_paddr; 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun void *cdb_addr; 304*4882a593Smuzhiyun dma_addr_t cdb_paddr; 305*4882a593Smuzhiyun int status; 306*4882a593Smuzhiyun }; 307