From 3a5aec69332f156a4b6b7fa58c054eb5dda6e80a Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 24 Jun 2020 12:25:37 +0200 Subject: [PATCH] software/liblitesdcard: simplify, switch to DMAs, remove clocking/test functions. --- litex/soc/software/bios/cmds/cmd_litesdcard.c | 50 +-- litex/soc/software/liblitesdcard/sdcard.c | 313 ++++-------------- litex/soc/software/liblitesdcard/sdcard.h | 35 +- 3 files changed, 86 insertions(+), 312 deletions(-) diff --git a/litex/soc/software/bios/cmds/cmd_litesdcard.c b/litex/soc/software/bios/cmds/cmd_litesdcard.c index 66f57f70..34629fdc 100644 --- a/litex/soc/software/bios/cmds/cmd_litesdcard.c +++ b/litex/soc/software/bios/cmds/cmd_litesdcard.c @@ -33,7 +33,7 @@ static void sdclk(int nb_params, char **params) return; } - sdclk_set_clk(frequ); + sdcard_set_clk(frequ); } struct command_struct cmd_sdclk = @@ -68,6 +68,7 @@ static void sdread(int nb_params, char **params) { unsigned int block; char *c; + uint8_t buf[512]; if (nb_params < 1) { printf("sdread "); @@ -80,7 +81,8 @@ static void sdread(int nb_params, char **params) return; } - sdcard_read(block*SD_BLOCK_SIZE, 0); + sdcard_read(block*512, 1, buf); + dump_bytes((uint32_t *)buf, 512, (unsigned long) buf); } define_command(sdread, sdread, "Read SDCard block", LITESDCARD_CMDS); @@ -95,6 +97,8 @@ define_command(sdread, sdread, "Read SDCard block", LITESDCARD_CMDS); #ifdef CSR_SDCORE_BASE static void sdwrite(int nb_params, char **params) { + int i; + uint8_t buf[512]; unsigned int block; char *c; @@ -109,38 +113,18 @@ static void sdwrite(int nb_params, char **params) return; } - sdcard_write(block*SD_BLOCK_SIZE, params[1], 0); -} - -define_command(sdwrite, sdwrite, "Write SDCard block", LITESDCARD_CMDS); -#endif - - -/** - * Command "sdtest" - * - * Perform SDcard read/write tests - * - */ -#ifdef CSR_SDCORE_BASE -static void sdtest(int nb_params, char **params) -{ - unsigned int blocks; - char *c; - - if (nb_params < 1) { - printf("sdtest "); - return; + c = params[1]; + if (params[1] != NULL) { + for(i=0; i<512; i++) { + buf[i] = *c; + if(*(++c) == 0) { + c = params[1]; + } + } } - - blocks = strtoul(params[0], &c, 0); - if (*c != 0) { - printf("Incorrect number of blocks"); - return; - } - - sdcard_test(blocks); + dump_bytes((uint32_t *)buf, 512, (unsigned long) buf); + sdcard_write(block*512, 1, buf); } -define_command(sdtest, sdtest, "Test SDCard Write & Read on N blocks", LITESDCARD_CMDS); +define_command(sdwrite, sdwrite, "Write SDCard block", LITESDCARD_CMDS); #endif diff --git a/litex/soc/software/liblitesdcard/sdcard.c b/litex/soc/software/liblitesdcard/sdcard.c index 2610e178..7202a2d7 100644 --- a/litex/soc/software/liblitesdcard/sdcard.c +++ b/litex/soc/software/liblitesdcard/sdcard.c @@ -23,135 +23,9 @@ unsigned int sdcard_response[SD_RESPONSE_SIZE/4]; -volatile char *sdread_buf = (char*)(SDREAD_BASE); -volatile char *sdwrite_buf = (char*)(SDWRITE_BASE); - -/* clocking */ - -#ifdef CSR_SDCLK_CMD_DATA_ADDR - -static void sdclk_dcm_write(int cmd, int data) -{ - int word; - word = (data << 2) | cmd; - sdclk_cmd_data_write(word); - sdclk_send_cmd_data_write(1); - while(sdclk_status_read() & CLKGEN_STATUS_BUSY); -} - -/* FIXME: add vco frequency check */ -static void sdclk_get_config(unsigned int freq, unsigned int *best_m, unsigned int *best_d) -{ - unsigned int ideal_m, ideal_d; - unsigned int bm, bd; - unsigned int m, d; - unsigned int diff_current; - unsigned int diff_tested; - - ideal_m = freq; - ideal_d = 5000; - - bm = 1; - bd = 0; - for(d=1;d<=256;d++) - for(m=2;m<=256;m++) { - /* common denominator is d*bd*ideal_d */ - diff_current = abs(d*ideal_d*bm - d*bd*ideal_m); - diff_tested = abs(bd*ideal_d*m - d*bd*ideal_m); - if(diff_tested < diff_current) { - bm = m; - bd = d; - } - } - *best_m = bm; - *best_d = bd; -} - -void sdclk_set_clk(unsigned int freq) { - unsigned int clk_m, clk_d; - - printf("Setting SDCard clk freq to %dMHz\n", freq); - sdclk_get_config(100*freq, &clk_m, &clk_d); - sdclk_dcm_write(0x1, clk_d-1); - sdclk_dcm_write(0x3, clk_m-1); - sdclk_send_go_write(1); - while(!(sdclk_status_read() & CLKGEN_STATUS_PROGDONE)); - while(!(sdclk_status_read() & CLKGEN_STATUS_LOCKED)); -} - -#elif CSR_SDCLK_MMCM_DRP_WRITE_ADDR - -static void sdclk_mmcm_write(unsigned int adr, unsigned int data) { - sdclk_mmcm_drp_adr_write(adr); - sdclk_mmcm_drp_dat_w_write(data); - sdclk_mmcm_drp_write_write(1); - while(!sdclk_mmcm_drp_drdy_read()); -} - - -static void sdclk_set_config(unsigned int m, unsigned int d) { - /* clkfbout_mult = m */ - if(m%2) - sdclk_mmcm_write(0x14, 0x1000 | ((m/2)<<6) | (m/2 + 1)); - else - sdclk_mmcm_write(0x14, 0x1000 | ((m/2)<<6) | m/2); - /* divclk_divide = d */ - if (d == 1) - sdclk_mmcm_write(0x16, 0x1000); - else if(d%2) - sdclk_mmcm_write(0x16, ((d/2)<<6) | (d/2 + 1)); - else - sdclk_mmcm_write(0x16, ((d/2)<<6) | d/2); - /* clkout0_divide = 10 */ - sdclk_mmcm_write(0x8, 0x1000 | (5<<6) | 5); - /* clkout1_divide = 2 */ - sdclk_mmcm_write(0xa, 0x1000 | (1<<6) | 1); -} - -/* FIXME: add vco frequency check */ -static void sdclk_get_config(unsigned int freq, unsigned int *best_m, unsigned int *best_d) { - unsigned int ideal_m, ideal_d; - unsigned int bm, bd; - unsigned int m, d; - unsigned int diff_current; - unsigned int diff_tested; - - ideal_m = freq; - ideal_d = 10000; - - bm = 1; - bd = 0; - for(d=1;d<=128;d++) - for(m=2;m<=128;m++) { - /* common denominator is d*bd*ideal_d */ - diff_current = abs(d*ideal_d*bm - d*bd*ideal_m); - diff_tested = abs(bd*ideal_d*m - d*bd*ideal_m); - if(diff_tested < diff_current) { - bm = m; - bd = d; - } - } - *best_m = bm; - *best_d = bd; -} - -void sdclk_set_clk(unsigned int freq) { - unsigned int clk_m, clk_d; - - printf("Setting SDCard clk freq to %dMHz\n", freq); - sdclk_get_config(1000*freq, &clk_m, &clk_d); - sdclk_set_config(clk_m, clk_d); -} - -#else - -void sdclk_set_clk(unsigned int freq) { - printf("No SDClocker, returning.\n"); -} - -#endif - -/* command utils */ +/*-----------------------------------------------------------------------*/ +/* SDCard command helpers */ +/*-----------------------------------------------------------------------*/ static void busy_wait_us(unsigned int us) { @@ -231,7 +105,9 @@ int sdcard_wait_response(void) { return status; } -/* commands */ +/*-----------------------------------------------------------------------*/ +/* SDCard commands functions */ +/*-----------------------------------------------------------------------*/ void sdcard_go_idle(void) { #ifdef SDCARD_DEBUG @@ -392,7 +268,7 @@ int sdcard_write_single_block(unsigned int blockaddr) { int cmd_response = -1; while (cmd_response != SD_OK) { sdcore_argument_write(blockaddr); - sdcore_blocksize_write(SD_BLOCK_SIZE); + sdcore_blocksize_write(512); sdcore_blockcount_write(1); sdcore_command_write((24 << 8) | SDCARD_CTRL_RESPONSE_SHORT | (SDCARD_CTRL_DATA_TRANSFER_WRITE << 5)); @@ -409,7 +285,7 @@ int sdcard_write_multiple_block(unsigned int blockaddr, unsigned int blockcnt) { int cmd_response = -1; while (cmd_response != SD_OK) { sdcore_argument_write(blockaddr); - sdcore_blocksize_write(SD_BLOCK_SIZE); + sdcore_blocksize_write(512); sdcore_blockcount_write(blockcnt); sdcore_command_write((25 << 8) | SDCARD_CTRL_RESPONSE_SHORT | (SDCARD_CTRL_DATA_TRANSFER_WRITE << 5)); @@ -426,7 +302,7 @@ int sdcard_read_single_block(unsigned int blockaddr) { int cmd_response = -1; while (cmd_response != SD_OK) { sdcore_argument_write(blockaddr); - sdcore_blocksize_write(SD_BLOCK_SIZE); + sdcore_blocksize_write(512); sdcore_blockcount_write(1); sdcore_command_write((17 << 8) | SDCARD_CTRL_RESPONSE_SHORT | (SDCARD_CTRL_DATA_TRANSFER_READ << 5)); @@ -443,7 +319,7 @@ int sdcard_read_multiple_block(unsigned int blockaddr, unsigned int blockcnt) { int cmd_response = -1; while (cmd_response != SD_OK) { sdcore_argument_write(blockaddr); - sdcore_blocksize_write(SD_BLOCK_SIZE); + sdcore_blocksize_write(512); sdcore_blockcount_write(blockcnt); sdcore_command_write((18 << 8) | SDCARD_CTRL_RESPONSE_SHORT | (SDCARD_CTRL_DATA_TRANSFER_READ << 5)); @@ -532,44 +408,17 @@ void sdcard_decode_csd(void) { (1 << ((sdcard_response[1] >> 16) & 0xf)), - size * SD_BLOCK_SIZE / (1024 * 1024) + size * 512 / (1024 * 1024) ); } -/* writer / reader */ - -#ifdef CSR_SDDATAWRITER_BASE - -void sdcard_sddatawriter_start(void) { - sddatawriter_reset_write(1); - sddatawriter_start_write(1); -} - -int sdcard_sddatawriter_wait(void) { - unsigned done = 0; - while(!done) { - done = sddatawriter_done_read(); - } - return 0; -} -#endif - -#ifdef CSR_SDDATAREADER_BASE -void sdcard_sddatareader_start(void) { - sddatareader_reset_write(1); - sddatareader_start_write(1); -} +/*-----------------------------------------------------------------------*/ +/* SDCard user functions */ +/*-----------------------------------------------------------------------*/ -int sdcard_sddatareader_wait(void) { - unsigned done = 0; - while((done & 1) == 0) { - done = sddatareader_done_read(); - } - return 0; +void sdcard_set_clk(uint32_t freq) { + printf("No SDClocker, returning.\n"); } -#endif - -/* user */ int sdcard_init(void) { unsigned short rca; @@ -632,98 +481,57 @@ int sdcard_init(void) { sdcard_app_send_scr(); /* set block length */ - sdcard_app_set_blocklen(SD_BLOCK_SIZE); + sdcard_app_set_blocklen(512); return 1; } -extern void dump_bytes(unsigned int *ptr, int count, unsigned long addr); - -void sdcard_write(unsigned int addr, const char *data, char silent) +void sdcard_read(uint32_t sector, uint32_t count, uint8_t* buf) { -#ifdef CSR_SDDATAWRITER_BASE - const char *c = data; - int i; - - if (data != NULL) { - for(i=0; i