3 * Texas Instruments, <www.ti.com>
4 * Syed Mohammed Khasim <khasim@ti.com>
6 * See file CREDITS for list of people who contributed to this
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation's version 2 of
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 const unsigned short mmc_transspeed_val
[15][4] = {
33 {CLKD(10, 1), CLKD(10, 10), CLKD(10, 100), CLKD(10, 1000)},
34 {CLKD(12, 1), CLKD(12, 10), CLKD(12, 100), CLKD(12, 1000)},
35 {CLKD(13, 1), CLKD(13, 10), CLKD(13, 100), CLKD(13, 1000)},
36 {CLKD(15, 1), CLKD(15, 10), CLKD(15, 100), CLKD(15, 1000)},
37 {CLKD(20, 1), CLKD(20, 10), CLKD(20, 100), CLKD(20, 1000)},
38 {CLKD(26, 1), CLKD(26, 10), CLKD(26, 100), CLKD(26, 1000)},
39 {CLKD(30, 1), CLKD(30, 10), CLKD(30, 100), CLKD(30, 1000)},
40 {CLKD(35, 1), CLKD(35, 10), CLKD(35, 100), CLKD(35, 1000)},
41 {CLKD(40, 1), CLKD(40, 10), CLKD(40, 100), CLKD(40, 1000)},
42 {CLKD(45, 1), CLKD(45, 10), CLKD(45, 100), CLKD(45, 1000)},
43 {CLKD(52, 1), CLKD(52, 10), CLKD(52, 100), CLKD(52, 1000)},
44 {CLKD(55, 1), CLKD(55, 10), CLKD(55, 100), CLKD(55, 1000)},
45 {CLKD(60, 1), CLKD(60, 10), CLKD(60, 100), CLKD(60, 1000)},
46 {CLKD(70, 1), CLKD(70, 10), CLKD(70, 100), CLKD(70, 1000)},
47 {CLKD(80, 1), CLKD(80, 10), CLKD(80, 100), CLKD(80, 1000)}
50 mmc_card_data cur_card_data
;
51 static block_dev_desc_t mmc_blk_dev
;
53 block_dev_desc_t
*mmc_get_dev(int dev
)
55 return (block_dev_desc_t
*) &mmc_blk_dev
;
58 void twl4030_mmc_config(void)
63 i2c_write(0x4B, 0x82, 1, &data
, 1);
65 i2c_write(0x4B, 0x85, 1, &data
, 1);
68 unsigned char mmc_board_init(void)
70 unsigned int value
= 0;
74 value
= CONTROL_PBIAS_LITE
;
75 CONTROL_PBIAS_LITE
= value
| (1 << 2) | (1 << 1) | (1 << 9);
77 value
= CONTROL_DEV_CONF0
;
78 CONTROL_DEV_CONF0
= value
| (1 << 24);
83 void mmc_init_stream(void)
85 volatile unsigned int mmc_stat
;
87 OMAP_HSMMC_CON
|= INIT_INITSTREAM
;
89 OMAP_HSMMC_CMD
= MMC_CMD0
;
91 mmc_stat
= OMAP_HSMMC_STAT
;
92 } while (!(mmc_stat
& CC_MASK
));
94 OMAP_HSMMC_STAT
= CC_MASK
;
96 OMAP_HSMMC_CMD
= MMC_CMD0
;
98 mmc_stat
= OMAP_HSMMC_STAT
;
99 } while (!(mmc_stat
& CC_MASK
));
101 OMAP_HSMMC_STAT
= OMAP_HSMMC_STAT
;
102 OMAP_HSMMC_CON
&= ~INIT_INITSTREAM
;
105 unsigned char mmc_clock_config(unsigned int iclk
, unsigned short clk_div
)
109 mmc_reg_out(OMAP_HSMMC_SYSCTL
, (ICE_MASK
| DTO_MASK
| CEN_MASK
),
110 (ICE_STOP
| DTO_15THDTO
| CEN_DISABLE
));
114 val
= MMC_INIT_SEQ_CLK
/ 2;
117 val
= MMC_400kHz_CLK
;
125 mmc_reg_out(OMAP_HSMMC_SYSCTL
,
126 ICE_MASK
| CLKD_MASK
, (val
<< CLKD_OFFSET
) | ICE_OSCILLATE
);
128 while ((OMAP_HSMMC_SYSCTL
& ICS_MASK
) == ICS_NOTREADY
) ;
130 OMAP_HSMMC_SYSCTL
|= CEN_ENABLE
;
134 unsigned char mmc_init_setup(void)
136 unsigned int reg_val
;
140 OMAP_HSMMC_SYSCONFIG
|= MMC_SOFTRESET
;
141 while ((OMAP_HSMMC_SYSSTATUS
& RESETDONE
) == 0) ;
143 OMAP_HSMMC_SYSCTL
|= SOFTRESETALL
;
144 while ((OMAP_HSMMC_SYSCTL
& SOFTRESETALL
) != 0x0) ;
146 OMAP_HSMMC_HCTL
= DTW_1_BITMODE
| SDBP_PWROFF
| SDVS_3V0
;
147 OMAP_HSMMC_CAPA
|= VS30_3V0SUP
| VS18_1V8SUP
;
149 reg_val
= OMAP_HSMMC_CON
& RESERVED_MASK
;
151 OMAP_HSMMC_CON
= CTPL_MMC_SD
| reg_val
| WPP_ACTIVEHIGH
|
152 CDP_ACTIVEHIGH
| MIT_CTO
| DW8_1_4BITMODE
| MODE_FUNC
|
153 STR_BLOCK
| HR_NOHOSTRESP
| INIT_NOINIT
| NOOPENDRAIN
;
155 mmc_clock_config(CLK_INITSEQ
, 0);
156 OMAP_HSMMC_HCTL
|= SDBP_PWRON
;
158 OMAP_HSMMC_IE
= 0x307f0033;
164 unsigned char mmc_send_cmd(unsigned int cmd
, unsigned int arg
,
165 unsigned int *response
)
167 volatile unsigned int mmc_stat
;
169 while ((OMAP_HSMMC_PSTATE
& DATI_MASK
) == DATI_CMDDIS
) ;
171 OMAP_HSMMC_BLK
= BLEN_512BYTESLEN
| NBLK_STPCNT
;
172 OMAP_HSMMC_STAT
= 0xFFFFFFFF;
173 OMAP_HSMMC_ARG
= arg
;
174 OMAP_HSMMC_CMD
= cmd
| CMD_TYPE_NORMAL
| CICE_NOCHECK
|
175 CCCE_NOCHECK
| MSBS_SGLEBLK
| ACEN_DISABLE
| BCE_DISABLE
|
180 mmc_stat
= OMAP_HSMMC_STAT
;
181 } while (mmc_stat
== 0);
183 if ((mmc_stat
& ERRI_MASK
) != 0)
184 return (unsigned char) mmc_stat
;
186 if (mmc_stat
& CC_MASK
) {
187 OMAP_HSMMC_STAT
= CC_MASK
;
188 response
[0] = OMAP_HSMMC_RSP10
;
189 if ((cmd
& RSP_TYPE_MASK
) == RSP_TYPE_LGHT136
) {
190 response
[1] = OMAP_HSMMC_RSP32
;
191 response
[2] = OMAP_HSMMC_RSP54
;
192 response
[3] = OMAP_HSMMC_RSP76
;
200 unsigned char mmc_read_data(unsigned int *output_buf
)
202 volatile unsigned int mmc_stat
;
203 unsigned int read_count
= 0;
210 mmc_stat
= OMAP_HSMMC_STAT
;
211 } while (mmc_stat
== 0);
213 if ((mmc_stat
& ERRI_MASK
) != 0)
214 return (unsigned char) mmc_stat
;
216 if (mmc_stat
& BRR_MASK
) {
219 OMAP_HSMMC_STAT
|= BRR_MASK
;
220 for (k
= 0; k
< MMCSD_SECTOR_SIZE
/ 4; k
++) {
221 *output_buf
= OMAP_HSMMC_DATA
;
227 if (mmc_stat
& BWR_MASK
)
228 OMAP_HSMMC_STAT
|= BWR_MASK
;
230 if (mmc_stat
& TC_MASK
) {
231 OMAP_HSMMC_STAT
|= TC_MASK
;
238 unsigned char mmc_detect_card(mmc_card_data
*mmc_card_cur
)
241 unsigned int argument
= 0;
242 unsigned int ocr_value
, ocr_recvd
, ret_cmd41
, hcs_val
;
243 unsigned int resp
[4];
244 unsigned short retry_cnt
= 2000;
246 /* Set to Initialization Clock */
247 err
= mmc_clock_config(CLK_400KHZ
, 0);
251 mmc_card_cur
->RCA
= MMC_RELATIVE_CARD_ADDRESS
;
252 argument
= 0x00000000;
254 ocr_value
= (0x1FF << 15);
255 err
= mmc_send_cmd(MMC_CMD0
, argument
, resp
);
259 argument
= SD_CMD8_CHECK_PATTERN
| SD_CMD8_2_7_3_6_V_RANGE
;
260 err
= mmc_send_cmd(MMC_SDCMD8
, argument
, resp
);
261 hcs_val
= (err
== 1) ?
262 MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR
:
263 MMC_OCR_REG_HOST_CAPACITY_SUPPORT_BYTE
;
265 argument
= 0x0000 << 16;
266 err
= mmc_send_cmd(MMC_CMD55
, argument
, resp
);
268 mmc_card_cur
->card_type
= SD_CARD
;
269 ocr_value
|= hcs_val
;
270 ret_cmd41
= MMC_ACMD41
;
272 mmc_card_cur
->card_type
= MMC_CARD
;
273 ocr_value
|= MMC_OCR_REG_ACCESS_MODE_SECTOR
;
274 ret_cmd41
= MMC_CMD1
;
275 OMAP_HSMMC_CON
&= ~OD
;
276 OMAP_HSMMC_CON
|= OPENDRAIN
;
279 argument
= ocr_value
;
280 err
= mmc_send_cmd(ret_cmd41
, argument
, resp
);
284 ocr_recvd
= ((mmc_resp_r3
*) resp
)->ocr
;
286 while (!(ocr_recvd
& (0x1 << 31)) && (retry_cnt
> 0)) {
288 if (mmc_card_cur
->card_type
== SD_CARD
) {
289 argument
= 0x0000 << 16;
290 err
= mmc_send_cmd(MMC_CMD55
, argument
, resp
);
293 argument
= ocr_value
;
294 err
= mmc_send_cmd(ret_cmd41
, argument
, resp
);
297 ocr_recvd
= ((mmc_resp_r3
*) resp
)->ocr
;
300 if (!(ocr_recvd
& (0x1 << 31)))
303 if (mmc_card_cur
->card_type
== MMC_CARD
) {
304 if ((ocr_recvd
& MMC_OCR_REG_ACCESS_MODE_MASK
) ==
305 MMC_OCR_REG_ACCESS_MODE_SECTOR
) {
306 mmc_card_cur
->mode
= SECTOR_MODE
;
308 mmc_card_cur
->mode
= BYTE_MODE
;
311 ocr_recvd
&= ~MMC_OCR_REG_ACCESS_MODE_MASK
;
313 if ((ocr_recvd
& MMC_OCR_REG_HOST_CAPACITY_SUPPORT_MASK
)
314 == MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR
) {
315 mmc_card_cur
->mode
= SECTOR_MODE
;
317 mmc_card_cur
->mode
= BYTE_MODE
;
319 ocr_recvd
&= ~MMC_OCR_REG_HOST_CAPACITY_SUPPORT_MASK
;
322 ocr_recvd
&= ~(0x1 << 31);
323 if (!(ocr_recvd
& ocr_value
))
326 err
= mmc_send_cmd(MMC_CMD2
, argument
, resp
);
330 if (mmc_card_cur
->card_type
== MMC_CARD
) {
331 argument
= mmc_card_cur
->RCA
<< 16;
332 err
= mmc_send_cmd(MMC_CMD3
, argument
, resp
);
336 argument
= 0x00000000;
337 err
= mmc_send_cmd(MMC_SDCMD3
, argument
, resp
);
341 mmc_card_cur
->RCA
= ((mmc_resp_r6
*) resp
)->newpublishedrca
;
344 OMAP_HSMMC_CON
&= ~OD
;
345 OMAP_HSMMC_CON
|= NOOPENDRAIN
;
349 unsigned char mmc_read_cardsize(mmc_card_data
*mmc_dev_data
,
350 mmc_csd_reg_t
*cur_csd
)
352 mmc_extended_csd_reg_t ext_csd
;
353 unsigned int size
, count
, blk_len
, blk_no
, card_size
, argument
;
355 unsigned int resp
[4];
357 if (mmc_dev_data
->mode
== SECTOR_MODE
) {
358 if (mmc_dev_data
->card_type
== SD_CARD
) {
360 (((mmc_sd2_csd_reg_t
*) cur_csd
)->
361 c_size_lsb
& MMC_SD2_CSD_C_SIZE_LSB_MASK
) |
362 ((((mmc_sd2_csd_reg_t
*) cur_csd
)->
363 c_size_msb
& MMC_SD2_CSD_C_SIZE_MSB_MASK
)
364 << MMC_SD2_CSD_C_SIZE_MSB_OFFSET
);
365 mmc_dev_data
->size
= card_size
* 1024;
366 if (mmc_dev_data
->size
== 0)
369 argument
= 0x00000000;
370 err
= mmc_send_cmd(MMC_CMD8
, argument
, resp
);
373 err
= mmc_read_data((unsigned int *) &ext_csd
);
376 mmc_dev_data
->size
= ext_csd
.sectorcount
;
378 if (mmc_dev_data
->size
== 0)
379 mmc_dev_data
->size
= 8388608;
382 if (cur_csd
->c_size_mult
>= 8)
385 if (cur_csd
->read_bl_len
>= 12)
389 count
= 1 << (cur_csd
->c_size_mult
+ 2);
390 card_size
= (cur_csd
->c_size_lsb
& MMC_CSD_C_SIZE_LSB_MASK
) |
391 ((cur_csd
->c_size_msb
& MMC_CSD_C_SIZE_MSB_MASK
)
392 << MMC_CSD_C_SIZE_MSB_OFFSET
);
393 blk_no
= (card_size
+ 1) * count
;
394 blk_len
= 1 << cur_csd
->read_bl_len
;
395 size
= blk_no
* blk_len
;
396 mmc_dev_data
->size
= size
/ MMCSD_SECTOR_SIZE
;
397 if (mmc_dev_data
->size
== 0)
403 unsigned char omap_mmc_read_sect(unsigned int start_sec
, unsigned int num_bytes
,
404 mmc_card_data
*mmc_c
,
405 unsigned long *output_buf
)
408 unsigned int argument
;
409 unsigned int resp
[4];
410 unsigned int num_sec_val
=
411 (num_bytes
+ (MMCSD_SECTOR_SIZE
- 1)) / MMCSD_SECTOR_SIZE
;
412 unsigned int sec_inc_val
;
414 if (num_sec_val
== 0)
417 if (mmc_c
->mode
== SECTOR_MODE
) {
418 argument
= start_sec
;
421 argument
= start_sec
* MMCSD_SECTOR_SIZE
;
422 sec_inc_val
= MMCSD_SECTOR_SIZE
;
425 while (num_sec_val
) {
426 err
= mmc_send_cmd(MMC_CMD17
, argument
, resp
);
430 err
= mmc_read_data((unsigned int *) output_buf
);
434 output_buf
+= (MMCSD_SECTOR_SIZE
/ 4);
435 argument
+= sec_inc_val
;
441 unsigned char configure_mmc(mmc_card_data
*mmc_card_cur
)
443 unsigned char ret_val
;
444 unsigned int argument
;
445 unsigned int resp
[4];
446 unsigned int trans_clk
, trans_fact
, trans_unit
, retries
= 2;
447 mmc_csd_reg_t Card_CSD
;
448 unsigned char trans_speed
;
450 ret_val
= mmc_init_setup();
456 ret_val
= mmc_detect_card(mmc_card_cur
);
458 } while ((retries
> 0) && (ret_val
!= 1));
460 argument
= mmc_card_cur
->RCA
<< 16;
461 ret_val
= mmc_send_cmd(MMC_CMD9
, argument
, resp
);
465 ((unsigned int *) &Card_CSD
)[3] = resp
[3];
466 ((unsigned int *) &Card_CSD
)[2] = resp
[2];
467 ((unsigned int *) &Card_CSD
)[1] = resp
[1];
468 ((unsigned int *) &Card_CSD
)[0] = resp
[0];
470 if (mmc_card_cur
->card_type
== MMC_CARD
)
471 mmc_card_cur
->version
= Card_CSD
.spec_vers
;
473 trans_speed
= Card_CSD
.tran_speed
;
475 ret_val
= mmc_send_cmd(MMC_CMD4
, MMC_DSR_DEFAULT
<< 16, resp
);
479 trans_unit
= trans_speed
& MMC_CSD_TRAN_SPEED_UNIT_MASK
;
480 trans_fact
= trans_speed
& MMC_CSD_TRAN_SPEED_FACTOR_MASK
;
482 if (trans_unit
> MMC_CSD_TRAN_SPEED_UNIT_100MHZ
)
485 if ((trans_fact
< MMC_CSD_TRAN_SPEED_FACTOR_1_0
) ||
486 (trans_fact
> MMC_CSD_TRAN_SPEED_FACTOR_8_0
))
492 trans_clk
= mmc_transspeed_val
[trans_fact
- 1][trans_unit
] * 2;
493 ret_val
= mmc_clock_config(CLK_MISC
, trans_clk
);
498 argument
= mmc_card_cur
->RCA
<< 16;
499 ret_val
= mmc_send_cmd(MMC_CMD7_SELECT
, argument
, resp
);
503 /* Configure the block length to 512 bytes */
504 argument
= MMCSD_SECTOR_SIZE
;
505 ret_val
= mmc_send_cmd(MMC_CMD16
, argument
, resp
);
509 /* get the card size in sectors */
510 ret_val
= mmc_read_cardsize(mmc_card_cur
, &Card_CSD
);
516 unsigned long mmc_bread(int dev_num
, unsigned long blknr
, lbaint_t blkcnt
,
519 omap_mmc_read_sect(blknr
, (blkcnt
* MMCSD_SECTOR_SIZE
), &cur_card_data
,
520 (unsigned long *) dst
);
524 int mmc_init(int verbose
)
526 if (configure_mmc(&cur_card_data
) != 1)
529 mmc_blk_dev
.if_type
= IF_TYPE_MMC
;
530 mmc_blk_dev
.part_type
= PART_TYPE_DOS
;
533 mmc_blk_dev
.type
= 0;
535 /* FIXME fill in the correct size (is set to 32MByte) */
536 mmc_blk_dev
.blksz
= MMCSD_SECTOR_SIZE
;
537 mmc_blk_dev
.lba
= 0x10000;
538 mmc_blk_dev
.removable
= 0;
539 mmc_blk_dev
.block_read
= mmc_bread
;
541 fat_register_device(&mmc_blk_dev
, 1);
545 int mmc_read(ulong src
, uchar
*dst
, int size
)
550 int mmc_write(uchar
*src
, ulong dst
, int size
)
555 int mmc2info(ulong addr
)