• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  'Standard' SDIO HOST CONTROLLER driver
3  *
4  * Copyright (C) 1999-2017, Broadcom Corporation
5  *
6  *      Unless you and Broadcom execute a separate written software license
7  * agreement governing use of this software, this software is licensed to you
8  * under the terms of the GNU General Public License version 2 (the "GPL"),
9  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10  * following added to such license:
11  *
12  *      As a special exception, the copyright holders of this software give you
13  * permission to link this software with independent modules, and to copy and
14  * distribute the resulting executable under terms of your choice, provided that
15  * you also meet, for each linked independent module, the terms and conditions of
16  * the license of that module.  An independent module is a module which is not
17  * derived from this software.  The special exception does not apply to any
18  * modifications of the software.
19  *
20  *      Notwithstanding the above, under no circumstances may you combine this
21  * software in any way with any other Broadcom software provided under a license
22  * other than the GPL, without Broadcom's express prior written consent.
23  *
24  *
25  * <<Broadcom-WL-IPTag/Open:>>
26  *
27  * $Id: bcmsdstd.h 514727 2014-11-12 03:02:48Z $
28  */
29 #ifndef    _BCM_SD_STD_H
30 #define    _BCM_SD_STD_H
31 
32 /* global msglevel for debug messages - bitvals come from sdiovar.h */
33 #define sd_err(x)    do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0)
34 #define sd_trace(x)
35 #define sd_info(x)
36 #define sd_debug(x)
37 #define sd_data(x)
38 #define sd_ctrl(x)
39 #define sd_dma(x)
40 
41 #define sd_sync_dma(sd, read, nbytes)
42 #define sd_init_dma(sd)
43 #define sd_ack_intr(sd)
44 #define sd_wakeup(sd);
45 /* Allocate/init/free per-OS private data */
46 extern int sdstd_osinit(sdioh_info_t *sd);
47 extern void sdstd_osfree(sdioh_info_t *sd);
48 
49 #define sd_log(x)
50 
51 #define SDIOH_ASSERT(exp) \
52     do { if (!(exp)) \
53         printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \
54     } while (0)
55 
56 #define BLOCK_SIZE_4318 64
57 #define BLOCK_SIZE_4328 512
58 
59 /* internal return code */
60 #define SUCCESS    0
61 #define ERROR    1
62 
63 /* private bus modes */
64 #define SDIOH_MODE_SPI        0
65 #define SDIOH_MODE_SD1        1
66 #define SDIOH_MODE_SD4        2
67 
68 #define MAX_SLOTS 6     /* For PCI: Only 6 BAR entries => 6 slots */
69 #define SDIOH_REG_WINSZ    0x100 /* Number of registers in Standard Host Controller */
70 
71 #define SDIOH_TYPE_ARASAN_HDK    1
72 #define SDIOH_TYPE_BCM27XX    2
73 #define SDIOH_TYPE_TI_PCIXX21    4    /* TI PCIxx21 Standard Host Controller */
74 #define SDIOH_TYPE_RICOH_R5C822    5    /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */
75 #define SDIOH_TYPE_JMICRON    6    /* JMicron Standard SDIO Host Controller */
76 
77 /* For linux, allow yielding for dongle */
78 #define BCMSDYIELD
79 
80 /* Expected card status value for CMD7 */
81 #define SDIOH_CMD7_EXP_STATUS   0x00001E00
82 
83 #define RETRIES_LARGE 100000
84 #define sdstd_os_yield(sd)    do {} while (0)
85 #define RETRIES_SMALL 100
86 
87 
88 #define USE_BLOCKMODE        0x2    /* Block mode can be single block or multi */
89 #define USE_MULTIBLOCK        0x4
90 
91 #define USE_FIFO        0x8    /* Fifo vs non-fifo */
92 
93 #define CLIENT_INTR         0x100    /* Get rid of this! */
94 
95 #define HC_INTR_RETUNING    0x1000
96 
97 
98 #ifdef BCMSDIOH_TXGLOM
99 /* Total glom pkt can not exceed 64K
100  * need one more slot for glom padding packet
101  */
102 #define SDIOH_MAXGLOM_SIZE    (40+1)
103 
104 typedef struct glom_buf {
105     uint32 count;                /* Total number of pkts queued */
106     void *dma_buf_arr[SDIOH_MAXGLOM_SIZE];    /* Frame address */
107     ulong dma_phys_arr[SDIOH_MAXGLOM_SIZE]; /* DMA_MAPed address of frames */
108     uint16 nbytes[SDIOH_MAXGLOM_SIZE];    /* Size of each frame */
109 } glom_buf_t;
110 #endif
111 
112 struct sdioh_info {
113     uint cfg_bar;                       /* pci cfg address for bar */
114     uint32 caps;                        /* cached value of capabilities reg */
115     uint32 curr_caps;                        /* max current capabilities reg */
116 
117     osl_t         *osh;            /* osh handler */
118     volatile char     *mem_space;        /* pci device memory va */
119     uint        lockcount;         /* nest count of sdstd_lock() calls */
120     bool        client_intr_enabled;    /* interrupt connnected flag */
121     bool        intr_handler_valid;    /* client driver interrupt handler valid */
122     sdioh_cb_fn_t    intr_handler;        /* registered interrupt handler */
123     void        *intr_handler_arg;    /* argument to call interrupt handler */
124     bool        initialized;        /* card initialized */
125     uint        target_dev;        /* Target device ID */
126     uint16        intmask;        /* Current active interrupts */
127     void        *sdos_info;        /* Pointer to per-OS private data */
128     void        *bcmsdh;        /* handler to upper layer stack (bcmsdh) */
129 
130     uint32        controller_type;    /* Host controller type */
131     uint8        version;        /* Host Controller Spec Compliance Version */
132     uint        irq;            /* Client irq */
133     int        intrcount;        /* Client interrupts */
134     int        local_intrcount;    /* Controller interrupts */
135     bool        host_init_done;        /* Controller initted */
136     bool        card_init_done;        /* Client SDIO interface initted */
137     bool        polled_mode;        /* polling for command completion */
138 
139     bool        sd_blockmode;        /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
140                         /*  Must be on for sd_multiblock to be effective */
141     bool        use_client_ints;    /* If this is false, make sure to restore */
142                         /*  polling hack in wl_linux.c:wl_timer() */
143     int        adapter_slot;        /* Maybe dealing with multiple slots/controllers */
144     int        sd_mode;        /* SD1/SD4/SPI */
145     int        client_block_size[SDIOD_MAX_IOFUNCS];        /* Blocksize */
146     uint32        data_xfer_count;    /* Current transfer */
147     uint16        card_rca;        /* Current Address */
148     int8        sd_dma_mode;        /* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */
149     uint8        num_funcs;        /* Supported funcs on client */
150     uint32        com_cis_ptr;
151     uint32        func_cis_ptr[SDIOD_MAX_IOFUNCS];
152     void        *dma_buf;        /* DMA Buffer virtual address */
153     ulong        dma_phys;        /* DMA Buffer physical address */
154     void        *adma2_dscr_buf;    /* ADMA2 Descriptor Buffer virtual address */
155     ulong        adma2_dscr_phys;    /* ADMA2 Descriptor Buffer physical address */
156 
157     /* adjustments needed to make the dma align properly */
158     void        *dma_start_buf;
159     ulong        dma_start_phys;
160     uint        alloced_dma_size;
161     void        *adma2_dscr_start_buf;
162     ulong        adma2_dscr_start_phys;
163     uint        alloced_adma2_dscr_size;
164 
165     int         r_cnt;            /* rx count */
166     int         t_cnt;            /* tx_count */
167     bool        got_hcint;        /* local interrupt flag */
168     uint16        last_intrstatus;    /* to cache intrstatus */
169     int     host_UHSISupported;        /* whether UHSI is supported for HC. */
170     int     card_UHSI_voltage_Supported;     /* whether UHSI is supported for
171                          * Card in terms of Voltage [1.8 or 3.3].
172                          */
173     int    global_UHSI_Supp;    /* type of UHSI support in both host and card.
174                      * HOST_SDR_UNSUPP: capabilities not supported/matched
175                      * HOST_SDR_12_25: SDR12 and SDR25 supported
176                      * HOST_SDR_50_104_DDR: one of SDR50/SDR104 or DDR50 supptd
177                      */
178     volatile int    sd3_dat_state;         /* data transfer state used for retuning check */
179     volatile int    sd3_tun_state;         /* tuning state used for retuning check */
180     bool    sd3_tuning_reqd;     /* tuning requirement parameter */
181     uint32    caps3;            /* cached value of 32 MSbits capabilities reg (SDIO 3.0) */
182 #ifdef BCMSDIOH_TXGLOM
183     glom_buf_t glom_info;        /* pkt information used for glomming */
184     uint    txglom_mode;        /* Txglom mode: 0 - copy, 1 - multi-descriptor */
185 #endif
186 };
187 
188 #define DMA_MODE_NONE    0
189 #define DMA_MODE_SDMA    1
190 #define DMA_MODE_ADMA1    2
191 #define DMA_MODE_ADMA2    3
192 #define DMA_MODE_ADMA2_64 4
193 #define DMA_MODE_AUTO    -1
194 
195 #define USE_DMA(sd)        ((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE))
196 
197 /* States for Tuning and corr data */
198 #define TUNING_IDLE             0
199 #define TUNING_START             1
200 #define TUNING_START_AFTER_DAT     2
201 #define TUNING_ONGOING             3
202 
203 #define DATA_TRANSFER_IDLE         0
204 #define DATA_TRANSFER_ONGOING    1
205 
206 #define CHECK_TUNING_PRE_DATA    1
207 #define CHECK_TUNING_POST_DATA    2
208 
209 
210 #ifdef DHD_DEBUG
211 #define SD_DHD_DISABLE_PERIODIC_TUNING 0x01
212 #define SD_DHD_ENABLE_PERIODIC_TUNING  0x00
213 #endif
214 
215 
216 /************************************************************
217  * Internal interfaces: per-port references into bcmsdstd.c
218  */
219 
220 /* Global message bits */
221 extern uint sd_msglevel;
222 
223 /* OS-independent interrupt handler */
224 extern bool check_client_intr(sdioh_info_t *sd);
225 
226 /* Core interrupt enable/disable of device interrupts */
227 extern void sdstd_devintr_on(sdioh_info_t *sd);
228 extern void sdstd_devintr_off(sdioh_info_t *sd);
229 
230 /* Enable/disable interrupts for local controller events */
231 extern void sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err);
232 extern void sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err);
233 
234 /* Wait for specified interrupt and error bits to be set */
235 extern void sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err);
236 
237 
238 /**************************************************************
239  * Internal interfaces: bcmsdstd.c references to per-port code
240  */
241 
242 /* Register mapping routines */
243 extern uint32 *sdstd_reg_map(osl_t *osh, ulong addr, int size);
244 extern void sdstd_reg_unmap(osl_t *osh, ulong addr, int size);
245 
246 /* Interrupt (de)registration routines */
247 extern int sdstd_register_irq(sdioh_info_t *sd, uint irq);
248 extern void sdstd_free_irq(uint irq, sdioh_info_t *sd);
249 
250 /* OS-specific interrupt wrappers (atomic interrupt enable/disable) */
251 extern void sdstd_lock(sdioh_info_t *sd);
252 extern void sdstd_unlock(sdioh_info_t *sd);
253 extern void sdstd_waitlockfree(sdioh_info_t *sd);
254 
255 /* OS-specific wrappers for safe concurrent register access */
256 extern void sdstd_os_lock_irqsave(sdioh_info_t *sd, ulong* flags);
257 extern void sdstd_os_unlock_irqrestore(sdioh_info_t *sd, ulong* flags);
258 
259 /* OS-specific wait-for-interrupt-or-status */
260 extern int sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield, uint16 *bits);
261 
262 /* used by bcmsdstd_linux [implemented in sdstd] */
263 extern void sdstd_3_enable_retuning_int(sdioh_info_t *sd);
264 extern void sdstd_3_disable_retuning_int(sdioh_info_t *sd);
265 extern bool sdstd_3_is_retuning_int_set(sdioh_info_t *sd);
266 extern void sdstd_3_check_and_do_tuning(sdioh_info_t *sd, int tuning_param);
267 extern bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd);
268 extern int sdstd_3_get_tune_state(sdioh_info_t *sd);
269 extern int sdstd_3_get_data_state(sdioh_info_t *sd);
270 extern void sdstd_3_set_tune_state(sdioh_info_t *sd, int state);
271 extern void sdstd_3_set_data_state(sdioh_info_t *sd, int state);
272 extern uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd);
273 extern uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd);
274 extern int sdstd_3_clk_tuning(sdioh_info_t *sd, uint32 sd3ClkMode);
275 
276 /* used by sdstd [implemented in bcmsdstd_linux/ndis] */
277 extern void sdstd_3_start_tuning(sdioh_info_t *sd);
278 extern void sdstd_3_osinit_tuning(sdioh_info_t *sd);
279 extern void sdstd_3_osclean_tuning(sdioh_info_t *sd);
280 
281 extern void sdstd_enable_disable_periodic_timer(sdioh_info_t * sd, uint val);
282 
283 extern sdioh_info_t *sdioh_attach(osl_t *osh, void *bar0, uint irq);
284 extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *sd);
285 #endif /* _BCM_SD_STD_H */
286