1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_SDIO_H_
#define FH_SDIO_H_
#include <rtthread.h>
//#define __ASIC_BRANCH__
enum {
CTRL = 0x0, /** Control */
PWREN = 0x4, /** Power-enable */
CLKDIV = 0x8, /** Clock divider */
CLKSRC = 0xC, /** Clock source */
CLKENA = 0x10, /** Clock enable */
TMOUT = 0x14, /** Timeout */
CTYPE = 0x18, /** Card type */
BLKSIZ = 0x1C, /** Block Size */
BYTCNT = 0x20, /** Byte count */
INTMSK = 0x24, /** Interrupt Mask */
CMDARG = 0x28, /** Command Argument */
CMD = 0x2C, /** Command */
RESP0 = 0x30, /** Response 0 */
RESP1 = 0x34, /** Response 1 */
RESP2 = 0x38, /** Response 2 */
RESP3 = 0x3C, /** Response 3 */
MINTSTS = 0x40, /** Masked interrupt status */
RINTSTS = 0x44, /** Raw interrupt status */
STATUS = 0x48, /** Status */
FIFOTH = 0x4C, /** FIFO threshold */
CDETECT = 0x50, /** Card detect */
WRTPRT = 0x54, /** Write protect */
GPIO = 0x58, /** General Purpose IO */
TCBCNT = 0x5C, /** Transferred CIU byte count */
TBBCNT = 0x60, /** Transferred host/DMA to/from byte count */
DEBNCE = 0x64, /** Card detect debounce */
USRID = 0x68, /** User ID */
VERID = 0x6C, /** Version ID */
HCON = 0x70, /** Hardware Configuration */
UHSREG = 0x74, /** Reserved */
BMOD = 0x80, /** Bus mode Register */
PLDMND = 0x84, /** Poll Demand */
DBADDR = 0x88, /** Descriptor Base Address */
IDSTS = 0x8C, /** Internal DMAC Status */
IDINTEN = 0x90, /** Internal DMAC Interrupt Enable */
DSCADDR = 0x94, /** Current Host Descriptor Address */
BUFADDR = 0x98, /** Current Host Buffer Address */
FIFODAT = 0x200, /** FIFO data read write */
};
/* Control register definitions */
#define CTRL_RESET 0x00000001
#define FIFO_RESET 0x00000002
#define DMA_RESET 0x00000004
#define INT_ENABLE 0x00000010
#define READ_WAIT 0x00000040
#define CTRL_USE_IDMAC 0x02000000
/* Interrupt mask defines */
#define INTMSK_CDETECT 0x00000001
#define INTMSK_RESP_ERR 0x00000002
#define INTMSK_CMD_DONE 0x00000004
#define INTMSK_DAT_OVER 0x00000008
#define INTMSK_TXDR 0x00000010
#define INTMSK_RXDR 0x00000020
#define INTMSK_RCRC 0x00000040
#define INTMSK_DCRC 0x00000080
#define INTMSK_RTO 0x00000100
#define INTMSK_DTO 0x00000200
#define INTMSK_HTO 0x00000400
#define INTMSK_VSI INTMSK_HTO // VSI => Voltage Switch Interrupt
#define INTMSK_FRUN 0x00000800
#define INTMSK_HLE 0x00001000
#define INTMSK_SBE 0x00002000
#define INTMSK_ACD 0x00004000
#define INTMSK_EBE 0x00008000
#define INTMSK_SDIO 0x00010000
#define INTMASK_ERROR (INTMSK_RESP_ERR|INTMSK_RCRC|INTMSK_DCRC|INTMSK_RTO|INTMSK_DTO|INTMSK_HTO|INTMSK_FRUN|INTMSK_HLE|INTMSK_SBE|INTMSK_EBE)
/*BMOD register define */
#define BMOD_SWR 0x00000001
#define BMOD_DE 0x00000080
/* for STATUS register */
#define GET_FIFO_COUNT(x) (((x)&0x3ffe0000)>>17)
#define GET_FIFO_DEPTH(x) ((((x)&0x0FFF0000)>>16)+1)
/* for IDMA intr register */
#define IDMAINTBITS 0x337
/* PMU related registers */
//#define PMU_REG_BASE 0xF0000000
#define PMU_REG_RST 0xF0000100
#define PMU_REG_CLK_DIV3 0xF0000030
#define PMU_SDC0_RST_BIT 9
#define PMU_SDC1_RST_BIT 10
#define PMU_RST_MODULE(x) *((volatile unsigned int*)(PMU_REG_RST)) = (~((1<<(x))))
/* Define Card status bits (R1 response) */
#define R1CS_ADDRESS_OUT_OF_RANGE 0x80000000
#define R1CS_ADDRESS_MISALIGN 0x40000000
#define R1CS_BLOCK_LEN_ERR 0x20000000
#define R1CS_ERASE_SEQ_ERR 0x10000000
#define R1CS_ERASE_PARAM 0x08000000
#define R1CS_WP_VIOLATION 0x04000000
#define R1CS_CARD_IS_LOCKED 0x02000000
#define R1CS_LCK_UNLCK_FAILED 0x01000000
#define R1CS_COM_CRC_ERROR 0x00800000
#define R1CS_ILLEGAL_COMMAND 0x00400000
#define R1CS_CARD_ECC_FAILED 0x00200000
#define R1CS_CC_ERROR 0x00100000
#define R1CS_ERROR 0x00080000
#define R1CS_UNDERRUN 0x00040000
#define R1CS_OVERRUN 0x00020000
#define R1CS_CSD_OVERWRITE 0x00010000
#define R1CS_WP_ERASE_SKIP 0x00008000
#define R1CS_RESERVED_0 0x00004000
#define R1CS_ERASE_RESET 0x00002000
#define R1CS_CURRENT_STATE_MASK 0x00001e00
#define R1CS_READY_FOR_DATA 0x00000100
#define R1CS_SWITCH_ERROR 0x00000080
#define R1CS_RESERVED_1 0x00000040
#define R1CS_APP_CMD 0x00000020
#define R1CS_RESERVED_2 0x00000010
#define R1CS_APP_SPECIFIC_MASK 0x0000000c
#define R1CS_MANUFAC_TEST_MASK 0x00000003
#define R1CS_ERROR_OCCURED_MAP 0xfdffa080
#define R1CS_CURRENT_STATE(x) (((x)&R1CS_CURRENT_STATE_MASK)>>9)
/* R5 response */
#define R5_IO_CRC_ERR 0x00008000
#define R5_IO_BAD_CMD 0x00004000
#define R5_IO_GEN_ERR 0x00000800
#define R5_IO_FUNC_ERR 0x00000200
#define R5_IO_OUT_RANGE 0x00000100
#define R5_IO_ERR_BITS 0x0000cb00
enum {
NONE_TYPE = 0,
SD_TYPE,
SD_2_0_TYPE,
SDIO_TYPE,
};
enum {
CARD_STATE_EMPTY = -1,
CARD_STATE_IDLE = 0,
CARD_STATE_READY = 1,
CARD_STATE_IDENT = 2,
CARD_STATE_STBY = 3,
CARD_STATE_TRAN = 4,
CARD_STATE_DATA = 5,
CARD_STATE_RCV = 6,
CARD_STATE_PRG = 7,
CARD_STATE_DIS = 8,
CARD_STATE_INA = 9
};
enum DmaDescriptorDES1 // Buffer's size field of Descriptor
{
DescBuf2SizMsk = 0x03FFE000, /* Mask for Buffer2 Size 25:13 */
DescBuf2SizeShift = 13, /* Shift value for Buffer2 Size */
DescBuf1SizMsk = 0x00001FFF, /* Mask for Buffer1 Size 12:0 */
DescBuf1SizeShift = 0, /* Shift value for Buffer2 Size */
};
enum DmaDescriptorDES0 // Control and status word of DMA descriptor DES0
{
DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 */
DescCardErrSummary = 0x40000000, /* Indicates EBE/RTO/RCRC/SBE/DRTO/DCRC/RE 30 */
DescEndOfRing = 0x00000020, /* A "1" indicates End of Ring for Ring Mode 05 */
DescSecAddrChained = 0x00000010, /* A "1" indicates DES3 contains Next Desc Address 04 */
DescFirstDesc = 0x00000008, /* A "1" indicates this Desc contains first 03
buffer of the data */
DescLastDesc = 0x00000004, /* A "1" indicates buffer pointed to by this this 02
Desc contains last buffer of Data */
DescDisInt = 0x00000002, /* A "1" in this field disables the RI/TI of IDSTS 01
for data that ends in the buffer pointed to by
this descriptor */
};
typedef struct DmaDescStruct {
unsigned int desc0; /* control and status information of descriptor */
unsigned int desc1; /* buffer sizes */
unsigned int desc2; /* physical address of the buffer 1 */
unsigned int desc3; /* physical address of the buffer 2 */
}DmaDesc;
typedef struct {
unsigned int wkmod;
volatile DmaDesc *pDmaDesc;
unsigned int idma_support;
unsigned int rca;
unsigned int ip_base;
unsigned int card_type;
unsigned int fifo_depth;
unsigned int fifo_threth;
unsigned int sectors;
unsigned int scr[2];
unsigned int csd[4];
unsigned int idsts;
rt_sem_t sem;
rt_sem_t mutex;
void (*cb)(void);
} sdc_t;
#define ONE_BIT_MODE (0)
#define FOUR_BIT_MODE (1)
#define BE32_TO_CPU(x) ((unsigned int)( \
(((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
(((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24)))
#define synopmob_set_bits(reg, bit_id) *((volatile unsigned int *)(reg)) |= ((unsigned int)(bit_id))
#define synopmob_clear_bits(reg, bit_id) *((volatile unsigned int *)(reg)) &= (~((unsigned int)(bit_id)))
#define synopmob_set_register(reg, val) *((volatile unsigned int*)(reg)) = (val)
#define synopmob_read_register(reg) (*((volatile unsigned int*)(reg)))
enum {
ERRNOERROR = 0,
// for raw interrupt status error
ERRRESPRECEP, // 1
ERRRESPCRC,
ERRDCRC,
ERRRESPTIMEOUT,
ERRDRTIMEOUT,
ERRUNDERWRITE,
ERROVERREAD,
ERRHLE,
ERRSTARTBIT,
ERRENDBITERR, // 10
// for R1 response
ERRADDRESSRANGE, // 11
ERRADDRESSMISALIGN,
ERRBLOCKLEN,
ERRERASESEQERR,
ERRERASEPARAM,
ERRPROT,
ERRCARDLOCKED,
ERRCRC,
ERRILLEGALCOMMAND,
ERRECCFAILED,
ERRCCERR,
ERRUNKNOWN,
ERRUNDERRUN,
ERROVERRUN,
ERRCSDOVERWRITE,
ERRERASERESET,
ERRFSMSTATE, // 27
// for R5 response
ERRBADFUNC, // 28
// others
ERRCARDNOTCONN, // 29
ERRCARDWPROTECT,
ERRCMDRETRIESOVER,
ERRNOTSUPPORTED,
ERRHARDWARE,
ERRDATANOTREADY,
ERRCARDINTERNAL,
ERRACMD41TIMEOUT,
ERRIDMA,
ERRNORES,
ERRNOTEQUAL,
};
#ifdef __ASIC_BRANCH__
#define SDC_WHERE() *((volatile unsigned int*)0x9b800000) = ((unsigned int)(__LINE__))
#define SDC_ERROR() do { *((volatile unsigned int*)0x9b800008)=ret; *((volatile unsigned int*)0x9a7ff000) = 0;}while(0)
#define SDC_FINISH() *((volatile unsigned int*)0x9a7ff004) = 0;
#else
#define SDC_WHERE()
#define SDC_ERROR()
#define SDC_FINISH()
#endif //__ASIC_BRANCH__
#define SDC_WKMOD_25M_STAND_SPEED 0x0002 // 25M standard speed
#define SDC_WKMOD_50M_HI_SPEED 0x0004 // 50M high speed
#define SDC_WKMOD_1WIRE 0x0008 // 1 wire transfer mode
#define SDC_WKMOD_4WIRE 0x0010 // 4 wire transfer mode
#define SDC_RW_USE_DMA 0x80000000 // Use DMA transfer?
typedef void* HSDC;
// map to DmaDesc
typedef struct _buf_chain {
unsigned int csi; // desc0
unsigned int size; // desc1
void * buf; // desc2
struct _buf_chain *next; // desc3
}buf_chain_t;
/*
* for SD card
*/
extern int sdc_is_connected(unsigned int which);
extern int sdc_init(unsigned int which, unsigned int wkmod, unsigned int* dma_desc/*4Byte aligned,16 bytes space*/, HSDC* phandle);
extern int sdc_read_block(HSDC handle, unsigned int blk, unsigned int num, unsigned char* buffer);
extern int sdc_write_block(HSDC handle, unsigned int blk, unsigned int num, unsigned char* buffer);
extern int sdc_erase_block(HSDC handle, unsigned int blk, unsigned int num);
extern int sdc_get_sector_num(HSDC handle);
extern int sdc_set_clk_divider(unsigned int divider);
/*
* for SDIO WIFI card
*/
extern void fh_sdio0_init(void);
extern void fh_sdio1_init(void);
extern void fh_sdio_init(void);
extern int sdio_init(unsigned int which, unsigned int wkmod, unsigned int* dma_desc/*4Byte aligned,16 bytes space*/, HSDC* phandle);
extern int sdio_high_speed_mode(HSDC handle, int bitwidth, int freq);
extern int sdio_enable_card_int(HSDC handle, int enable);
extern int sdio_set_card_int_cb(HSDC handle, void (*cb)(void));
extern int sdio_drv_read(HSDC handle, unsigned int addr, unsigned int fn, unsigned int bcnt, unsigned int bsize, unsigned char *buf);
extern int sdio_drv_write(HSDC handle, unsigned int addr, unsigned int fn, unsigned int bcnt, unsigned int bsize, unsigned char *buf);
extern int sdio_drv_creg_read(HSDC handle, int addr, int fn, unsigned int *resp);
extern int sdio_drv_creg_write(HSDC handle, int addr, int fn, unsigned char data, unsigned int *resp);
extern void inv_dcache_range(unsigned long start, unsigned long len);
extern void flush_dcache_range(unsigned long start, unsigned long len);
#endif //__sdcard_h__
|