2 #include <minix/blockdriver.h>
5 #include <minix/spin.h>
23 /* header imported from netbsd */
28 /* omap /hardware related */
34 static int hook_id
= 1;
35 #define OMAP3_MMC1_IRQ 83 /* MMC/SD module 1 */
38 #define SANE_TIMEOUT 500000 /* 500 MS */
40 * Define a structure to be used for logging
42 static struct mmclog log
= {
43 .name
= "mmc_host_mmchs",
44 .log_level
= LEVEL_INFO
,
45 .log_func
= default_log
48 #define REG(x)(*((volatile uint32_t *)(x)))
49 #define BIT(x)(0x1 << x)
51 /* Write a uint32_t value to a memory address. */
53 write32(uint32_t address
, uint32_t value
)
58 /* Read an uint32_t from a memory address */
59 static inline uint32_t
60 read32(uint32_t address
)
66 /* Set a 32 bits value depending on a mask */
68 set32(uint32_t address
, uint32_t mask
, uint32_t value
)
71 val
= read32(address
);
74 /* apply the value using the mask */
75 val
|= (value
& mask
);
76 write32(address
, val
);
79 static uint32_t base_address
;
82 * Initialize the MMC controller given a certain
83 * instance. this driver only handles a single
84 * mmchs controller at a given time.
87 mmchs_init(uint32_t instance
)
92 struct minix_mem_range mr
;
95 mr
.mr_base
= MMCHS1_REG_BASE
;
96 mr
.mr_limit
= MMCHS1_REG_BASE
+ 0x400;
98 if (sys_privctl(SELF
, SYS_PRIV_ADD_MEM
, &mr
) != 0) {
99 panic("Unable to request permission to map memory");
102 /* Set the base address to use */
104 (uint32_t) vm_map_phys(SELF
, (void *) MMCHS1_REG_BASE
, 0x400);
105 if (base_address
== (uint32_t) MAP_FAILED
)
106 panic("Unable to map MMC memory");
108 base_address
= (unsigned long) base_address
- 0x100;
110 /* Soft reset of the controller. This section is documented in the TRM
113 /* Write 1 to sysconfig[0] to trigger a reset */
114 set32(base_address
+ MMCHS_SD_SYSCONFIG
, MMCHS_SD_SYSCONFIG_SOFTRESET
,
115 MMCHS_SD_SYSCONFIG_SOFTRESET
);
117 /* Read sysstatus to know when it's done */
119 spin_init(&spin
, SANE_TIMEOUT
);
120 while (!(read32(base_address
+ MMCHS_SD_SYSSTATUS
)
121 & MMCHS_SD_SYSSTATUS_RESETDONE
)) {
122 if (spin_check(&spin
) == FALSE
) {
123 mmc_log_warn(&log
, "mmc init timeout\n");
128 /* Set SD default capabilities */
129 set32(base_address
+ MMCHS_SD_CAPA
, MMCHS_SD_CAPA_VS_MASK
,
130 MMCHS_SD_CAPA_VS18
| MMCHS_SD_CAPA_VS30
);
132 /* TRM mentions MMCHS_SD_CUR_CAPA but does not describe how to limit
136 MMCHS_SD_SYSCONFIG_AUTOIDLE
| MMCHS_SD_SYSCONFIG_ENAWAKEUP
|
137 MMCHS_SD_SYSCONFIG_STANDBYMODE
| MMCHS_SD_SYSCONFIG_CLOCKACTIVITY
|
138 MMCHS_SD_SYSCONFIG_SIDLEMODE
;
140 /* Automatic clock gating strategy */
141 value
= MMCHS_SD_SYSCONFIG_AUTOIDLE_EN
;
142 /* Enable wake-up capability */
143 value
|= MMCHS_SD_SYSCONFIG_ENAWAKEUP_EN
;
145 value
|= MMCHS_SD_SYSCONFIG_SIDLEMODE_IDLE
;
146 /* Booth the interface and functional can be switched off */
147 value
|= MMCHS_SD_SYSCONFIG_CLOCKACTIVITY_OFF
;
148 /* Go into wake-up mode when possible */
149 value
|= MMCHS_SD_SYSCONFIG_STANDBYMODE_WAKEUP_INTERNAL
;
152 * wake-up configuration
154 set32(base_address
+ MMCHS_SD_SYSCONFIG
, mask
, value
);
156 /* Wake-up on sd interrupt for SDIO */
157 set32(base_address
+ MMCHS_SD_HCTL
, MMCHS_SD_HCTL_IWE
,
158 MMCHS_SD_HCTL_IWE_EN
);
161 * MMC host and bus configuration
164 /* Configure data and command transfer (1 bit mode) */
165 set32(base_address
+ MMCHS_SD_CON
, MMCHS_SD_CON_DW8
,
166 MMCHS_SD_CON_DW8_1BIT
);
167 set32(base_address
+ MMCHS_SD_HCTL
, MMCHS_SD_HCTL_DTW
,
168 MMCHS_SD_HCTL_DTW_1BIT
);
170 /* Configure card voltage to 3.0 volt */
171 set32(base_address
+ MMCHS_SD_HCTL
, MMCHS_SD_HCTL_SDVS
,
172 MMCHS_SD_HCTL_SDVS_VS30
);
174 /* Power on the host controller and wait for the
175 * MMCHS_SD_HCTL_SDBP_POWER_ON to be set */
176 set32(base_address
+ MMCHS_SD_HCTL
, MMCHS_SD_HCTL_SDBP
,
177 MMCHS_SD_HCTL_SDBP_ON
);
179 // /* TODO: Add padconf/pinmux stuff here as documented in the TRM */
180 spin_init(&spin
, SANE_TIMEOUT
);
181 while ((read32(base_address
+ MMCHS_SD_HCTL
) & MMCHS_SD_HCTL_SDBP
)
182 != MMCHS_SD_HCTL_SDBP_ON
) {
183 if (spin_check(&spin
) == FALSE
) {
184 mmc_log_warn(&log
, "mmc init timeout SDBP not set\n");
189 /* Enable internal clock and clock to the card */
190 set32(base_address
+ MMCHS_SD_SYSCTL
, MMCHS_SD_SYSCTL_ICE
,
191 MMCHS_SD_SYSCTL_ICE_EN
);
193 // @TODO Fix external clock enable , this one is very slow
194 // but we first need faster context switching
195 //set32(base_address + MMCHS_SD_SYSCTL, MMCHS_SD_SYSCTL_CLKD,
197 set32(base_address
+ MMCHS_SD_SYSCTL
, MMCHS_SD_SYSCTL_CLKD
,
200 set32(base_address
+ MMCHS_SD_SYSCTL
, MMCHS_SD_SYSCTL_CEN
,
201 MMCHS_SD_SYSCTL_CEN_EN
);
203 spin_init(&spin
, SANE_TIMEOUT
);
204 while ((read32(base_address
+ MMCHS_SD_SYSCTL
) & MMCHS_SD_SYSCTL_ICS
)
205 != MMCHS_SD_SYSCTL_ICS_STABLE
) {
207 if (spin_check(&spin
) == FALSE
) {
208 mmc_log_warn(&log
, "clock not stable\n");
214 * See spruh73e page 3576 Card Detection, Identification, and Selection
217 /* Enable command interrupt */
218 set32(base_address
+ MMCHS_SD_IE
, MMCHS_SD_IE_CC_ENABLE
,
219 MMCHS_SD_IE_CC_ENABLE_ENABLE
);
220 /* Enable transfer complete interrupt */
221 set32(base_address
+ MMCHS_SD_IE
, MMCHS_SD_IE_TC_ENABLE
,
222 MMCHS_SD_IE_TC_ENABLE_ENABLE
);
224 /* enable error interrupts */
225 /* NOTE: We are currently skipping the BADA interrupt it does get
226 * raised for unknown reasons */
227 set32(base_address
+ MMCHS_SD_IE
, MMCHS_SD_IE_ERROR_MASK
, 0x0fffffffu
);
229 /* clean the error interrupts */
230 set32(base_address
+ MMCHS_SD_STAT
, MMCHS_SD_STAT_ERROR_MASK
,
233 /* send a init signal to the host controller. This does not actually
234 * send a command to a card manner */
235 set32(base_address
+ MMCHS_SD_CON
, MMCHS_SD_CON_INIT
,
236 MMCHS_SD_CON_INIT_INIT
);
237 /* command 0 , type other commands not response etc) */
238 write32(base_address
+ MMCHS_SD_CMD
, 0x00);
240 spin_init(&spin
, SANE_TIMEOUT
);
241 while ((read32(base_address
+ MMCHS_SD_STAT
) & MMCHS_SD_STAT_CC
)
242 != MMCHS_SD_STAT_CC_RAISED
) {
243 if (read32(base_address
+ MMCHS_SD_STAT
) & 0x8000) {
244 mmc_log_warn(&log
, "%s, error stat %x\n",
246 read32(base_address
+ MMCHS_SD_STAT
));
250 if (spin_check(&spin
) == FALSE
) {
252 "Interrupt not raised during init\n");
257 /* clear the cc interrupt status */
258 set32(base_address
+ MMCHS_SD_STAT
, MMCHS_SD_IE_CC_ENABLE
,
259 MMCHS_SD_IE_CC_ENABLE_ENABLE
);
262 * Set Set SD_CON[1] INIT bit to 0x0 to end the initialization sequence
264 set32(base_address
+ MMCHS_SD_CON
, MMCHS_SD_CON_INIT
,
265 MMCHS_SD_CON_INIT_NOINIT
);
268 set32(base_address
+ MMCHS_SD_SYSCTL
, MMCHS_SD_SYSCTL_DTO
,
269 MMCHS_SD_SYSCTL_DTO_2POW27
);
271 /* Clean the MMCHS_SD_STAT register */
272 write32(base_address
+ MMCHS_SD_STAT
, 0xffffffffu
);
275 if (sys_irqsetpolicy(OMAP3_MMC1_IRQ
, 0, &hook_id
) != OK
) {
276 printf("mmc: couldn't set IRQ policy %d\n", OMAP3_MMC1_IRQ
);
279 /* enable signaling from MMC controller towards interrupt controller */
280 write32(base_address
+ MMCHS_SD_ISE
, 0xffffffffu
);
287 mmchs_hw_intr(unsigned int irqs
)
289 mmc_log_warn(&log
, "Hardware interrupt left over\n");
292 if (sys_irqenable(&hook_id
) != OK
)
293 printf("couldn't re-enable interrupt \n");
295 /* Leftover interrupt(s) received; ack it/them. */
298 /*===========================================================================*
300 *===========================================================================*/
306 if (sys_irqenable(&hook_id
) != OK
)
307 printf("Failed to enable irqenable irq\n");
308 /* Wait for a task completion interrupt. */
311 int ticks
= SANE_TIMEOUT
* sys_hz() / 1000000;
313 if (ticks
<= 0) ticks
=1;
316 sys_setalarm(ticks
, 0);
317 if ((rr
= driver_receive(ANY
, &m
, &ipc_status
)) != OK
) {
318 panic("driver_receive failed: %d", rr
);
320 if (is_ipc_notify(ipc_status
)) {
321 switch (_ENDPOINT_P(m
.m_source
)) {
324 // w_timeout(); /* a.o. set w_status */
325 mmc_log_warn(&log
, "TIMEOUT\n");
329 v
= read32(base_address
+ MMCHS_SD_STAT
);
333 } else if (v
& (1 << 15)){
334 return 1; /* error */
336 mmc_log_debug(&log
, "unexpected HW interrupt 0x%08x mask 0X%08x\n", v
, mask
);
337 if (sys_irqenable(&hook_id
) != OK
)
339 ("Failed to re-enable irqenable irq\n");
345 * unhandled message. queue it and
346 * handle it in the blockdriver loop.
348 blockdriver_mq_queue(&m
, ipc_status
);
351 mmc_log_debug(&log
, "Other\n");
353 * unhandled message. queue it and handle it in the
356 blockdriver_mq_queue(&m
, ipc_status
);
359 sys_setalarm(0, 0); /* cancel the alarm */
363 spin_init(&spin
, SANE_TIMEOUT
);
364 /* Wait for completion */
368 v
= read32(base_address
+ MMCHS_SD_STAT
);
369 if (spin_check(&spin
) == FALSE
) {
370 mmc_log_warn(&log
, "Timeout waiting for interrupt (%d) value 0x%08x mask 0x%08x\n",counter
, v
,mask
);
375 } else if (v
& 0xFF00) {
376 mmc_log_debug(&log
, "unexpected HW interrupt (%d) 0x%08x mask 0x%08x\n", v
, mask
);
380 return 1; /* unreached */
381 #endif /* USE_INTR */
385 intr_assert(int mask
)
387 if (read32(base_address
+ MMCHS_SD_STAT
) & 0x8000) {
388 mmc_log_debug(&log
, "%s, error stat %08x\n", __FUNCTION__
,
389 read32(base_address
+ MMCHS_SD_STAT
));
390 set32(base_address
+ MMCHS_SD_STAT
, MMCHS_SD_STAT_ERROR_MASK
,
393 write32(base_address
+ MMCHS_SD_STAT
, mask
);
398 mmchs_send_cmd(uint32_t command
, uint32_t arg
)
401 /* Read current interrupt status and fail it an interrupt is already
405 write32(base_address
+ MMCHS_SD_ARG
, arg
);
407 set32(base_address
+ MMCHS_SD_CMD
, MMCHS_SD_CMD_MASK
, command
);
409 if (intr_wait(MMCHS_SD_STAT_CC
| MMCHS_SD_IE_TC_ENABLE_CLEAR
)) {
410 intr_assert(MMCHS_SD_STAT_CC
);
411 mmc_log_warn(&log
, "Failure waiting for interrupt\n");
415 if ((command
& MMCHS_SD_CMD_RSP_TYPE
) ==
416 MMCHS_SD_CMD_RSP_TYPE_48B_BUSY
) {
418 * Command with busy response *CAN* also set the TC bit if they exit busy
420 if ((read32(base_address
+ MMCHS_SD_STAT
)
421 & MMCHS_SD_IE_TC_ENABLE_ENABLE
) == 0) {
422 mmc_log_warn(&log
, "TC should be raised\n");
424 write32(base_address
+ MMCHS_SD_STAT
,
425 MMCHS_SD_IE_TC_ENABLE_CLEAR
);
427 if (intr_wait(MMCHS_SD_STAT_CC
| MMCHS_SD_IE_TC_ENABLE_CLEAR
)) {
428 intr_assert(MMCHS_SD_STAT_CC
);
429 mmc_log_warn(&log
, "Failure waiting for clear\n");
433 intr_assert(MMCHS_SD_STAT_CC
);
438 mmc_send_cmd(struct mmc_command
*c
)
441 /* convert the command to a hsmmc command */
444 cmd
= MMCHS_SD_CMD_INDX_CMD(c
->cmd
);
447 switch (c
->resp_type
) {
448 case RESP_LEN_48_CHK_BUSY
:
449 cmd
|= MMCHS_SD_CMD_RSP_TYPE_48B_BUSY
;
452 cmd
|= MMCHS_SD_CMD_RSP_TYPE_48B
;
455 cmd
|= MMCHS_SD_CMD_RSP_TYPE_136B
;
458 cmd
|= MMCHS_SD_CMD_RSP_TYPE_NO_RESP
;
464 ret
= mmchs_send_cmd(cmd
, arg
);
466 /* copy response into cmd->resp */
467 switch (c
->resp_type
) {
468 case RESP_LEN_48_CHK_BUSY
:
470 c
->resp
[0] = read32(base_address
+ MMCHS_SD_RSP10
);
473 c
->resp
[0] = read32(base_address
+ MMCHS_SD_RSP10
);
474 c
->resp
[1] = read32(base_address
+ MMCHS_SD_RSP32
);
475 c
->resp
[2] = read32(base_address
+ MMCHS_SD_RSP54
);
476 c
->resp
[3] = read32(base_address
+ MMCHS_SD_RSP76
);
487 static struct mmc_command command
;
490 card_goto_idle_state()
492 command
.cmd
= MMC_GO_IDLE_STATE
;
493 command
.resp_type
= NO_RESPONSE
;
495 if (mmc_send_cmd(&command
)) {
503 card_identification()
505 command
.cmd
= MMC_SEND_EXT_CSD
;
506 command
.resp_type
= RESP_LEN_48
;
507 command
.args
= MMCHS_SD_ARG_CMD8_VHS
| MMCHS_SD_ARG_CMD8_CHECK_PATTERN
;
509 if (mmc_send_cmd(&command
)) {
510 // We currently only support 2.0,
514 if (!(command
.resp
[0]
515 == (MMCHS_SD_ARG_CMD8_VHS
| MMCHS_SD_ARG_CMD8_CHECK_PATTERN
))) {
516 mmc_log_warn(&log
, "%s, check pattern check failed %08x\n",
517 __FUNCTION__
, command
.resp
[0]);
524 card_query_voltage_and_type(struct sd_card_regs
*card
)
527 command
.cmd
= MMC_APP_CMD
;
528 command
.resp_type
= RESP_LEN_48
;
529 command
.args
= MMC_ARG_RCA(0x0); /* RCA=0000 */
531 if (mmc_send_cmd(&command
)) {
535 command
.cmd
= SD_APP_OP_COND
;
536 command
.resp_type
= RESP_LEN_48
;
538 /* 0x1 << 30 == send HCS (Host capacity support) and get OCR register */
540 MMC_OCR_3_3V_3_4V
| MMC_OCR_3_2V_3_3V
| MMC_OCR_3_1V_3_2V
|
541 MMC_OCR_3_0V_3_1V
| MMC_OCR_2_9V_3_0V
| MMC_OCR_2_8V_2_9V
|
543 command
.args
|= MMC_OCR_HCS
; /* RCA=0000 */
545 if (mmc_send_cmd(&command
)) {
548 /* @todo wait for max 1 ms */
549 spin_init(&spin
, SANE_TIMEOUT
);
550 while (!(command
.resp
[0] & MMC_OCR_MEM_READY
)) {
551 command
.cmd
= MMC_APP_CMD
;
552 command
.resp_type
= RESP_LEN_48
;
553 command
.args
= MMC_ARG_RCA(0x0); /* RCA=0000 */
554 if (mmc_send_cmd(&command
)) {
559 /* 0x1 << 30 == send HCS (Host capacity support) and get OCR
561 command
.cmd
= SD_APP_OP_COND
;
562 command
.resp_type
= RESP_LEN_48
;
563 /* 0x1 << 30 == send HCS (Host capacity support) */
564 command
.args
= MMC_OCR_3_3V_3_4V
| MMC_OCR_3_2V_3_3V
565 | MMC_OCR_3_1V_3_2V
| MMC_OCR_3_0V_3_1V
| MMC_OCR_2_9V_3_0V
566 | MMC_OCR_2_8V_2_9V
| MMC_OCR_2_7V_2_8V
;
567 command
.args
|= MMC_OCR_HCS
; /* RCA=0000 */
569 if (mmc_send_cmd(&command
)) {
573 /* if bit 31 is set the response is valid */
574 if ((command
.resp
[0] & MMC_OCR_MEM_READY
)) {
577 if (spin_check(&spin
) == FALSE
) {
579 "TIMEOUT waiting for the SD card\n");
583 card
->ocr
= command
.resp
[3];
588 card_identify(struct sd_card_regs
*card
)
591 /* Send cmd 2 (all_send_cid) and expect 136 bits response */
592 command
.cmd
= MMC_ALL_SEND_CID
;
593 command
.resp_type
= RESP_LEN_136
;
594 command
.args
= MMC_ARG_RCA(0x0); /* RCA=0000 */
596 if (mmc_send_cmd(&command
)) {
600 card
->cid
[0] = command
.resp
[0];
601 card
->cid
[1] = command
.resp
[1];
602 card
->cid
[2] = command
.resp
[2];
603 card
->cid
[3] = command
.resp
[3];
605 command
.cmd
= MMC_SET_RELATIVE_ADDR
;
606 command
.resp_type
= RESP_LEN_48
;
607 command
.args
= 0x0; /* RCA=0000 */
610 if (mmc_send_cmd(&command
)) {
614 card
->rca
= SD_R6_RCA(command
.resp
);
615 /* MMHCS only supports a single card so sending MMCHS_SD_CMD_CMD2 is
616 * useless Still we should make it possible in the API to support
623 card_csd(struct sd_card_regs
*card
)
625 /* send_csd -> r2 response */
626 command
.cmd
= MMC_SEND_CSD
;
627 command
.resp_type
= RESP_LEN_136
;
628 command
.args
= MMC_ARG_RCA(card
->rca
); /* card rca */
630 if (mmc_send_cmd(&command
)) {
634 card
->csd
[0] = command
.resp
[0];
635 card
->csd
[1] = command
.resp
[1];
636 card
->csd
[2] = command
.resp
[2];
637 card
->csd
[3] = command
.resp
[3];
639 if (SD_CSD_CSDVER(card
->csd
) != SD_CSD_CSDVER_2_0
) {
640 mmc_log_warn(&log
, "Version 2.0 of CSD register expected\n");
645 // mmc_log_warn(&log,"size = %llu bytes\n", (long long
646 // unsigned)SD_CSD_V2_CAPACITY( card->csd) * 512);
651 select_card(struct sd_card_regs
*card
)
654 command
.cmd
= MMC_SELECT_CARD
;
655 command
.resp_type
= RESP_LEN_48_CHK_BUSY
;
656 command
.args
= MMC_ARG_RCA(card
->rca
); /* card rca */
658 if (mmc_send_cmd(&command
)) {
665 read_single_block(struct sd_card_regs
*card
,
666 uint32_t blknr
, unsigned char *buf
)
673 set32(base_address
+ MMCHS_SD_IE
, MMCHS_SD_IE_BRR_ENABLE
,
674 MMCHS_SD_IE_BRR_ENABLE_ENABLE
);
676 set32(base_address
+ MMCHS_SD_BLK
, MMCHS_SD_BLK_BLEN
, 512);
678 /* read single block */
679 if (mmchs_send_cmd(MMCHS_SD_CMD_INDX_CMD(MMC_READ_BLOCK_SINGLE
)
680 | MMCHS_SD_CMD_DP_DATA
/* Command with data transfer */
681 | MMCHS_SD_CMD_RSP_TYPE_48B
/* type (R1) */
682 | MMCHS_SD_CMD_MSBS_SINGLE
/* single block */
683 | MMCHS_SD_CMD_DDIR_READ
/* read data from card */
685 mmc_log_warn(&log
, "Error sending command\n");
689 if (intr_wait(MMCHS_SD_IE_BRR_ENABLE_ENABLE
)) {
690 intr_assert(MMCHS_SD_IE_BRR_ENABLE_ENABLE
);
691 mmc_log_warn(&log
, "Timeout waiting for interrupt\n");
695 if (!(read32(base_address
+ MMCHS_SD_PSTATE
) & MMCHS_SD_PSTATE_BRE_EN
)) {
696 mmc_log_warn(&log
, "Problem BRE should be true\n");
697 return 1; /* We are not allowed to read data from the
701 for (count
= 0; count
< 512; count
+= 4) {
702 value
= read32(base_address
+ MMCHS_SD_DATA
);
703 buf
[count
] = *((char *) &value
);
704 buf
[count
+ 1] = *((char *) &value
+ 1);
705 buf
[count
+ 2] = *((char *) &value
+ 2);
706 buf
[count
+ 3] = *((char *) &value
+ 3);
710 if (intr_wait(MMCHS_SD_IE_TC_ENABLE_ENABLE
)) {
711 intr_assert(MMCHS_SD_IE_TC_ENABLE_ENABLE
);
712 mmc_log_warn(&log
, "Timeout waiting for interrupt\n");
716 write32(base_address
+ MMCHS_SD_STAT
, MMCHS_SD_IE_TC_ENABLE_CLEAR
);
718 /* clear and disable the bbr interrupt */
719 write32(base_address
+ MMCHS_SD_STAT
, MMCHS_SD_IE_BRR_ENABLE_CLEAR
);
720 set32(base_address
+ MMCHS_SD_IE
, MMCHS_SD_IE_BRR_ENABLE
,
721 MMCHS_SD_IE_BRR_ENABLE_DISABLE
);
726 write_single_block(struct sd_card_regs
*card
,
727 uint32_t blknr
, unsigned char *buf
)
732 if ((read32(base_address
+ MMCHS_SD_STAT
) & 0xffffu
)) {
733 mmc_log_warn(&log
, "%s, interrupt already raised stat %08x\n",
734 __FUNCTION__
, read32(base_address
+ MMCHS_SD_STAT
));
735 write32(base_address
+ MMCHS_SD_STAT
,
736 MMCHS_SD_IE_CC_ENABLE_CLEAR
);
740 set32(base_address
+ MMCHS_SD_IE
, MMCHS_SD_IE_BWR_ENABLE
,
741 MMCHS_SD_IE_BWR_ENABLE_ENABLE
);
744 // set32(base_address + MMCHS_SD_IE, 0xfff , 0xfff);
745 set32(base_address
+ MMCHS_SD_BLK
, MMCHS_SD_BLK_BLEN
, 512);
747 /* write single block */
748 if (mmchs_send_cmd(MMCHS_SD_CMD_INDX_CMD(MMC_WRITE_BLOCK_SINGLE
)
749 | MMCHS_SD_CMD_DP_DATA
/* Command with data transfer */
750 | MMCHS_SD_CMD_RSP_TYPE_48B
/* type (R1b) */
751 | MMCHS_SD_CMD_MSBS_SINGLE
/* single block */
752 | MMCHS_SD_CMD_DDIR_WRITE
/* write to the card */
754 mmc_log_warn(&log
, "Write single block command failed\n");
755 mmc_log_trace(&log
, "STAT=(0x%08x)\n",
756 read32(base_address
+ MMCHS_SD_STAT
));
760 /* Wait for the MMCHS_SD_IE_BWR_ENABLE interrupt */
761 if (intr_wait(MMCHS_SD_IE_BWR_ENABLE
)) {
762 intr_assert(MMCHS_SD_IE_BWR_ENABLE
);
763 mmc_log_warn(&log
, "WFI failed\n");
766 /* clear the interrupt directly */
767 intr_assert(MMCHS_SD_IE_BWR_ENABLE
);
769 if (!(read32(base_address
+ MMCHS_SD_PSTATE
) & MMCHS_SD_PSTATE_BWE_EN
)) {
771 "Error expected Buffer to be write enabled\n");
772 return 1; /* not ready to write data */
776 for (count
= 0; count
< 512; count
+= 4) {
777 while (!(read32(base_address
+ MMCHS_SD_PSTATE
) & MMCHS_SD_PSTATE_BWE_EN
)){
778 mmc_log_trace(&log
, "Error expected Buffer to be write enabled(%d)\n", count
);
780 *((char *) &value
) = buf
[count
];
781 *((char *) &value
+ 1) = buf
[count
+ 1];
782 *((char *) &value
+ 2) = buf
[count
+ 2];
783 *((char *) &value
+ 3) = buf
[count
+ 3];
784 write32(base_address
+ MMCHS_SD_DATA
, value
);
789 if (intr_wait(MMCHS_SD_IE_TC_ENABLE_CLEAR
)) {
790 intr_assert(MMCHS_SD_IE_TC_ENABLE_CLEAR
);
791 mmc_log_warn(&log
, "(Write) Timeout waiting for transfer complete\n");
794 intr_assert(MMCHS_SD_IE_TC_ENABLE_CLEAR
);
795 set32(base_address
+ MMCHS_SD_IE
, MMCHS_SD_IE_BWR_ENABLE
,
796 MMCHS_SD_IE_BWR_ENABLE_DISABLE
);
801 mmchs_host_init(struct mmc_host
*host
)
808 mmchs_set_log_level(int level
)
810 if (level
>= 0 && level
<= 4) {
811 log
.log_level
= level
;
816 mmchs_host_set_instance(struct mmc_host
*host
, int instance
)
818 mmc_log_info(&log
, "Using instance number %d\n", instance
);
826 mmchs_host_reset(struct mmc_host
*host
)
833 mmchs_card_detect(struct sd_slot
*slot
)
835 /* @TODO implement proper card detect */
840 mmchs_card_initialize(struct sd_slot
*slot
)
844 struct sd_card
*card
;
846 memset(card
, 0, sizeof(struct sd_card
));
849 if (card_goto_idle_state()) {
850 mmc_log_warn(&log
, "Failed to go idle state\n");
854 if (card_identification()) {
855 mmc_log_warn(&log
, "Failed to do card_identification\n");
859 if (card_query_voltage_and_type(&slot
->card
.regs
)) {
861 "Failed to do card_query_voltage_and_type\n");
864 if (card_identify(&slot
->card
.regs
)) {
865 mmc_log_warn(&log
, "Failed to identify card\n");
868 /* We have now initialized the hardware identified the card */
869 if (card_csd(&slot
->card
.regs
)) {
871 "failed to read csd (card specific data)\n");
875 if (select_card(&slot
->card
.regs
)) {
876 mmc_log_warn(&log
, "Failed to select card\n");
880 if (SD_CSD_READ_BL_LEN(slot
->card
.regs
.csd
) != 0x09) {
881 /* for CSD version 2.0 the value is fixed to 0x09 and means a
882 * block size of 512 */
883 mmc_log_warn(&log
, "Block size expect to be 512\n");
887 slot
->card
.blk_size
= 512; /* HARDCODED value */
888 slot
->card
.blk_count
= SD_CSD_V2_CAPACITY(slot
->card
.regs
.csd
);
889 slot
->card
.state
= SD_MODE_DATA_TRANSFER_MODE
;
891 memset(slot
->card
.part
, 0, sizeof(slot
->card
.part
));
892 memset(slot
->card
.subpart
, 0, sizeof(slot
->card
.subpart
));
893 slot
->card
.part
[0].dv_base
= 0;
894 slot
->card
.part
[0].dv_size
=
895 (unsigned long long) SD_CSD_V2_CAPACITY(slot
->card
.regs
.csd
) * 512;
899 /* read count blocks into existing buf */
901 mmchs_host_read(struct sd_card
*card
,
902 uint32_t blknr
, uint32_t count
, unsigned char *buf
)
906 for (i
= 0; i
< count
; i
++) {
907 read_single_block(&card
->regs
, blknr
+ i
,
908 buf
+ (i
* card
->blk_size
));
913 /* write count blocks */
915 mmchs_host_write(struct sd_card
*card
,
916 uint32_t blknr
, uint32_t count
, unsigned char *buf
)
921 for (i
= 0; i
< count
; i
++) {
922 write_single_block(&card
->regs
, blknr
+ i
,
923 buf
+ (i
* card
->blk_size
));
930 mmchs_card_release(struct sd_card
*card
)
932 assert(card
->open_ct
== 1);
934 card
->state
= SD_MODE_UNINITIALIZED
;
935 /* TODO:Set card state */
940 host_initialize_host_structure_mmchs(struct mmc_host
*host
)
942 /* Initialize the basic data structures host slots and cards */
945 host
->host_set_instance
= mmchs_host_set_instance
;
946 host
->host_init
= mmchs_host_init
;
947 host
->set_log_level
= mmchs_set_log_level
;
948 host
->host_reset
= mmchs_host_reset
;
949 host
->card_detect
= mmchs_card_detect
;
950 host
->card_initialize
= mmchs_card_initialize
;
951 host
->card_release
= mmchs_card_release
;
952 host
->hw_intr
= mmchs_hw_intr
;
953 host
->read
= mmchs_host_read
;
954 host
->write
= mmchs_host_write
;
956 /* initialize data structures */
957 for (i
= 0; i
< sizeof(host
->slot
) / sizeof(host
->slot
[0]); i
++) {
958 // @TODO set initial card and slot state
959 host
->slot
[i
].host
= host
;
960 host
->slot
[i
].card
.slot
= &host
->slot
[i
];