Skip to content

Commit e8c5947

Browse files
author
Wayne Ren
committed
driver: sdio: fix bugs in write and configuration
1. the original sdio driver is not fully tested for multiple blocks write, which has lots of bugs 2. the sdio configurations for emsdp and iotdk are not correct are not correct. 3. code style cleanup Signed-off-by: Wayne Ren <[email protected]>
1 parent b29cdd9 commit e8c5947

File tree

6 files changed

+47
-34
lines changed

6 files changed

+47
-34
lines changed

board/emsdp/drivers/ip/designware/sdio/dw_sdio_obj.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static void dw_sdio_0_install(void)
9191

9292
dw_sdio_ctrl_ptr->reg_base = (void *) EMSDP_SDIO_BASE;
9393
dw_sdio_ctrl_ptr->intno = EMSDP_SDIO_INTR;
94-
dw_sdio_ctrl_ptr->ref_clk = 200000000;
94+
dw_sdio_ctrl_ptr->ref_clk = EMSDP_REF_CLOCK;
9595
dw_sdio_ctrl_ptr->fifo_depth = 128;
9696

9797
dw_sdio_ptr->open = dw_sdio_0_open;

board/iotdk/drivers/ip/designware/sdio/dw_sdio_obj.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include "embARC_error.h"
3232

3333
#include "iotdk_hardware.h"
34-
3534
#include "ip/designware/sdio/dw_sdio.h"
3635
#include "dw_sdio_obj.h"
3736

@@ -95,7 +94,7 @@ static void dw_sdio_0_install(void)
9594

9695
dw_sdio_ctrl_ptr->reg_base = (void *) BASE_ADDR_SDIO;
9796
dw_sdio_ctrl_ptr->intno = INTNO_SDIO;
98-
dw_sdio_ctrl_ptr->ref_clk = 100000000;
97+
dw_sdio_ctrl_ptr->ref_clk = CLK_CPU;
9998
dw_sdio_ctrl_ptr->fifo_depth = 128;
10099

101100
dw_sdio_ptr->open = dw_sdio_0_open;

board/iotdk/drivers/sysconf/sysconf.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ int32_t pll_fout_config(uint32_t freq)
131131
eflash_clk_div(1);
132132
}
133133

134+
sdio_clk_divisor(1);
135+
134136
return 0;
135137
}
136138

@@ -204,7 +206,7 @@ void apb_clk_disable(uint8_t dev)
204206
*/
205207
void sdio_clk_divisor(uint8_t div)
206208
{
207-
sysconf_reg_ptr->SDIO_REFCLK_DIV;
209+
sysconf_reg_ptr->SDIO_REFCLK_DIV = div;
208210
}
209211

210212

device/ip/designware/sdio/dw_sdio.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
*
2929
--------------------------------------------- */
30-
3130
#include "embARC_toolchain.h"
3231
#include "embARC_error.h"
3332
#include "arc_exception.h"
@@ -60,7 +59,10 @@ Inline void dw_sdio_fifo_read_poll(DW_SDIO_CTRL_PTR sdio, uint32_t *buf, uint32_
6059
uint32_t i;
6160

6261
while (size) {
63-
len = dw_sdio_reg_read(sdio, DWSDIO_REG_STATUS);
62+
do {
63+
len = dw_sdio_reg_read(sdio, DWSDIO_REG_STATUS);
64+
} while (len & DWSDIO_STATUS_FIFO_EMPTY);
65+
6466
len = (len & DWSDIO_STATUS_MASK_FIFO) >> DWSDIO_STATUS_BIT_FIFO;
6567

6668
len = min(size, len);
@@ -96,8 +98,11 @@ Inline void dw_sdio_fifo_write_poll(DW_SDIO_CTRL_PTR sdio, uint32_t *buf, uint32
9698
uint32_t i;
9799
uint32_t fifo_depth = sdio->fifo_depth;
98100

99-
while (size) {
100-
len = dw_sdio_reg_read(sdio, DWSDIO_REG_STATUS);
101+
while (size) {
102+
do {
103+
len = dw_sdio_reg_read(sdio, DWSDIO_REG_STATUS);
104+
} while (len & DWSDIO_STATUS_FIFO_FULL);
105+
101106
len = fifo_depth - ((len & DWSDIO_STATUS_MASK_FIFO) >> DWSDIO_STATUS_BIT_FIFO);
102107
len = min(size, len);
103108

@@ -188,7 +193,6 @@ static int32_t dw_sdio_bus_freq_set(DW_SDIO_CTRL_PTR sdio, uint32_t card_number,
188193
dw_sdio_reg_write(sdio, DWSDIO_REG_CLKSRC, 0);
189194
dw_sdio_reg_write(sdio, DWSDIO_REG_CLKDIV, div);
190195

191-
192196
dw_sdio_reg_write(sdio, DWSDIO_REG_CMD, DWSDIO_CMD_PRV_DAT_WAIT |
193197
DWSDIO_CMD_UPD_CLK | DWSDIO_CMD_START | DWSDIO_CMD_USE_HOLD_REG);
194198

@@ -284,7 +288,6 @@ static int32_t dw_sdio_data_transfer_poll(DW_SDIO_CTRL_PTR sdio, SDIO_DATA_PTR d
284288
{
285289
uint32_t size;
286290
uint32_t status;
287-
int32_t ret;
288291
uint32_t timeout = 1000;
289292
uint32_t start = OSP_GET_CUR_MS();
290293

@@ -295,30 +298,28 @@ static int32_t dw_sdio_data_transfer_poll(DW_SDIO_CTRL_PTR sdio, SDIO_DATA_PTR d
295298

296299
if (status & (DWSDIO_INT_DATA_ERR | DWSDIO_INT_DATA_TMO)) {
297300
DBG("%s:, data transfer error!\r\n", __func__);
298-
ret = E_SYS;
299-
break;
301+
return E_SYS;
302+
}
303+
304+
if (status & DWSDIO_INT_DTO) {
305+
return E_OK;
300306
}
301307

302-
if (data->flags == SDIO_DATA_READ && (status & DWSDIO_INT_RXDR)) {
308+
if (data->flags == SDIO_DATA_READ && (status & DWSDIO_INT_RXDR) && size) {
303309
dw_sdio_fifo_read_poll(sdio, (uint32_t *)data->in, size);
310+
size = 0;
304311
dw_sdio_reg_write(sdio, DWSDIO_REG_RINTSTS, DWSDIO_INT_RXDR);
305-
} else if (data->flags == SDIO_DATA_WRITE && (status & DWSDIO_INT_TXDR)) {
312+
} else if (data->flags == SDIO_DATA_WRITE && (status & DWSDIO_INT_TXDR) && size) {
306313
dw_sdio_fifo_write_poll(sdio, (uint32_t *)data->out, size);
314+
size = 0;
307315
dw_sdio_reg_write(sdio, DWSDIO_REG_RINTSTS, DWSDIO_INT_TXDR);
308316
}
309317

310-
if (status & DWSDIO_INT_DTO) {
311-
ret = E_OK;
312-
break;
313-
}
314-
315318
if ((OSP_GET_CUR_MS() - start) > timeout) {
316319
DBG("%s: timeout on data transfer\r\n", __func__);
317320
return E_TMOUT;
318321
}
319322
}
320-
321-
return ret;
322323
}
323324

324325
void dw_sdio_isr(DEV_SDIO *sdio_obj, void *ptr)
@@ -419,7 +420,6 @@ int32_t dw_sdio_cmd_poll(DEV_SDIO *sdio_obj, SDIO_CMD_PTR cmd, SDIO_DATA_PTR dat
419420
return E_SYS;
420421
}
421422

422-
423423
if (cmd->resp_type & SDIO_RSP_PRESENT) {
424424
if (cmd->resp_type & SDIO_RSP_136) {
425425
cmd->resp[0] = dw_sdio_reg_read(sdio, DWSDIO_REG_RESP3);
@@ -509,9 +509,9 @@ int32_t dw_sdio_cd(DEV_SDIO *sdio_obj, uint32_t card_number)
509509
* Some use 0 (CD pin to GNU) to indicate card detect.
510510
*/
511511
#ifdef DWSDIO_CARD_DETECT_HIGH_LEVEL
512-
val = dw_sdio_reg_read(sdio, DWSDIO_REG_CDETECT);
512+
val = dw_sdio_reg_read(sdio, DWSDIO_REG_CDETECT);
513513
#else
514-
val = ~dw_sdio_reg_read(sdio, DWSDIO_REG_CDETECT);
514+
val = ~dw_sdio_reg_read(sdio, DWSDIO_REG_CDETECT);
515515
#endif
516516

517517
if ((val & (1 << card_number)) == (1 << card_number)) {
@@ -523,13 +523,12 @@ int32_t dw_sdio_cd(DEV_SDIO *sdio_obj, uint32_t card_number)
523523

524524
int32_t dw_sdio_wp(DEV_SDIO *sdio_obj, uint32_t card_number)
525525
{
526-
527526
uint32_t val;
528527

529528
DEV_SDIO_INFO_PTR sdio_info_ptr = &(sdio_obj->sdio_info);
530529
DW_SDIO_CTRL_PTR sdio = (DW_SDIO_CTRL_PTR)sdio_info_ptr->sdio_ctrl;
531530

532-
val = dw_sdio_reg_read(sdio, DWSDIO_REG_WRTPRT);
531+
val = dw_sdio_reg_read(sdio, DWSDIO_REG_WRTPRT);
533532

534533
if ((val & (1 << card_number)) == (1 << card_number)) {
535534
return 1; /* the specific card is write-protect */
@@ -554,8 +553,8 @@ int32_t dw_sdio_control(DEV_SDIO *sdio_obj, SDIO_CTRL_CMD_PTR ctrl_cmd, void *pa
554553
dw_sdio_bus_type_set(sdio, card, (uint32_t)param);
555554
break;
556555
case SDIO_CMD_SET_BUS_FREQ:
557-
dw_sdio_bus_freq_set(sdio, card, (uint32_t)param);
558-
break;
556+
dw_sdio_bus_freq_set(sdio, card, (uint32_t)param);
557+
break;
559558
/* \todo add more cmds */
560559
default:
561560
ret = E_PAR;

device/ip/designware/sdio/dw_sdio_hal.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@
198198

199199

200200
#define DWSDIO_STATUS_BIT_FIFO (17)
201+
#define DWSDIO_STATUS_FIFO_FULL (0x8)
202+
#define DWSDIO_STATUS_FIFO_EMPTY (0x4)
201203
#define DWSDIO_STATUS_MASK_FIFO (0x3ffe0000)
202204

203205
/* status bit */
@@ -211,9 +213,8 @@
211213
#define DWSDIO_FIFOTH_BIT_DMA_M_SIZE 28
212214
#define DWSDIO_FIFOTH_MASK_DMA_M_SIZE (0x7 << DWSDIO_FIFOTH_BIT_DMA_M_SIZE)
213215
#define DWSDIO_FIFOTH_M_SIZE(x) ((x) << DWSDIO_FIFOTH_BIT_DMA_M_SIZE)
214-
#define DWSDIO_FIFOTH_TX_WMASK(x) ((x))
215-
#define DWSDIO_FIFOTH_RX_WMASK(x) ((x) << DWSDIO_FIFOTH_BIT_RX_WMARK)
216-
216+
#define DWSDIO_FIFOTH_TX_WMASK(x) ((x))
217+
#define DWSDIO_FIFOTH_RX_WMASK(x) ((x) << DWSDIO_FIFOTH_BIT_RX_WMARK)
217218

218219
/* interrupt status bit */
219220
#define DWSDIO_INT_CAD (0x1U) //Card Detected
@@ -237,7 +238,6 @@
237238
DWSDIO_INT_FRUN | DWSDIO_INT_DCRC)
238239
#define DWSDIO_INT_DATA_TMO (DWSDIO_INT_DRTO | DWSDIO_INT_HTO)
239240

240-
241-
#define DWSDIO_ENUMERATION_FREQ (400000) /* 400 Khz for card enumeration */
241+
#define DWSDIO_ENUMERATION_FREQ (400000) /* 400 Khz for card enumeration */
242242

243243
#endif /* _DW_SDIO_HAL_H_ */

middleware/fatfs/source/diskdrv/ff_sdcard_sdio.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ static int32_t sdio_write_blocks(FS_SDCARD_SDIO_CTRL_PTR sd_dev, const void *buf
483483
if (sd_dev->card_info.version & SDCARD_CT_SDC) {
484484
cmd.cmdidx = CMD55;
485485
cmd.resp_type = SDIO_RSP_R1;
486-
cmd.arg = 0;
486+
cmd.arg = sd_dev->card_info.rca << 16;;
487487

488488
ret = sd_host->cmd_poll(&cmd, NULL);
489489

@@ -516,6 +516,19 @@ static int32_t sdio_write_blocks(FS_SDCARD_SDIO_CTRL_PTR sd_dev, const void *buf
516516
return ret;
517517
}
518518

519+
if (blkcnt > 1) {
520+
cmd.cmdidx = CMD12;
521+
cmd.arg = 0;
522+
cmd.resp_type= SDIO_RSP_R1b;
523+
524+
ret = sd_host->cmd_poll(&cmd, NULL);
525+
if (ret < 0 ) {
526+
DBG("fail to send stop cmd\r\n");
527+
return ret;
528+
}
529+
}
530+
531+
519532
return blkcnt;
520533
}
521534

0 commit comments

Comments
 (0)