diff --git a/apps/Makefile b/apps/Makefile index 79e9e6e..bfef2e6 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -12,9 +12,6 @@ obj-y += btusbaudio/ obj-y += usbaudio/ endif -ifeq ($(APP_TEST_SDMMC),1) -obj-y += sdmmc/ -endif ifeq ($(ANC_APP),1) obj-y += anc/ @@ -35,7 +32,6 @@ endif subdir-ccflags-y += -Iapps/apptester \ -Iapps/audioplayers \ -Iapps/common \ - -Iapps/sdmmc \ -Iapps/main \ -Iapps/cmd \ -Iapps/key \ diff --git a/apps/sdmmc/Makefile b/apps/sdmmc/Makefile deleted file mode 100644 index d15ef32..0000000 --- a/apps/sdmmc/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) -obj-y := $(obj-y:.c=.o) -obj-y := $(obj-y:.cpp=.o) -obj-y := $(obj-y:.S=.o) - -subdir-ccflags-y += -Iservices/fs/sd \ - -Iservices/fs/fat \ - -Iservices/fs/fat/ChaN - -ifeq ($(APP_TEST_SDMMC),1) -ccflags-y += -D__APP_TEST_SDMMC__ -endif diff --git a/apps/sdmmc/app_sdmmc.cpp b/apps/sdmmc/app_sdmmc.cpp deleted file mode 100644 index f612292..0000000 --- a/apps/sdmmc/app_sdmmc.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "cmsis_os.h" -#include "hal_trace.h" -//#include "app_thread.h" - -//#include "hal_sdmmc.h" -#include "SDFileSystem.h" -#include "app_sdmmc.h" -#include "audiobuffer.h" -#include "audioflinger.h" - -#define APP_TEST_PLAYBACK_BUFF_SIZE (120 * 20) -#define APP_TEST_CAPTURE_BUFF_SIZE (120 * 20) -extern uint8_t app_test_playback_buff[APP_TEST_PLAYBACK_BUFF_SIZE] - __attribute__((aligned(4))); -extern uint8_t app_test_capture_buff[APP_TEST_CAPTURE_BUFF_SIZE] - __attribute__((aligned(4))); -SDFileSystem sdfs("sd"); - -int sd_open() { - DIR *d = opendir("/sd"); - if (!d) { - TRACE(0, "sd file system borked\n"); - return -1; - } - - TRACE(0, "---------root---------\n"); - struct dirent *p; - while ((p = readdir(d))) { - int len = sizeof(dirent); - TRACE(2, "%s %d\n", p->d_name, len); - } - closedir(d); - TRACE(0, "--------root end-------\n"); -} - -extern uint32_t play_wav_file(char *file_path); -extern uint32_t stop_wav_file(void); -extern uint32_t wav_file_audio_more_data(uint8_t *buf, uint32_t len); - -void test_wave_play(bool on) { - struct AF_STREAM_CONFIG_T stream_cfg; - uint32_t reallen; - uint32_t totalreadsize; - uint32_t stime, etime; - - char wave[] = "/sd/test_music.wav"; - - static bool isRun = false; - - if (isRun == on) - return; - else - isRun = on; - - TRACE(2, "%s %d\n", __func__, on); - memset(&stream_cfg, 0, sizeof(stream_cfg)); - if (on) { - play_wav_file(wave); - - stream_cfg.bits = AUD_BITS_16; - stream_cfg.channel_num = AUD_CHANNEL_NUM_2; - stream_cfg.sample_rate = AUD_SAMPRATE_48000; - - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; - stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; - stream_cfg.vol = 0x03; - - stream_cfg.handler = wav_file_audio_more_data; - stream_cfg.data_ptr = app_test_playback_buff; - stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; - - af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); - af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - } else { - stop_wav_file(); - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - } - - return; -} - -FIL pcm_fil; -FRESULT pcm_res; -UINT pcm_num; -uint32_t pcm_save_more_data(uint8_t *buf, uint32_t len) { - // TRACE(2,"%s\n len:%d", __func__, len); - - audio_buffer_set_stereo2mono_16bits(buf, len, 1); - pcm_res = f_write(&pcm_fil, (uint8_t *)buf, len >> 1, &pcm_num); - if (pcm_res != FR_OK) { - TRACE(2, "[%s]:error-->res = %d", __func__, pcm_res); - } - return 0; -} - -void ad_tester(bool run) { - char filename[] = "/sd/audio_dump.bin"; - - struct AF_STREAM_CONFIG_T stream_cfg; - - TRACE(2, "%s %d\n", __func__, run); - - if (run) { - memset(&stream_cfg, 0, sizeof(stream_cfg)); - pcm_res = f_open(&pcm_fil, "test2.bin", FA_CREATE_ALWAYS | FA_WRITE); - if (pcm_res) { - TRACE(2, "[%s]:Cannot creat test2.bin...%d", __func__, pcm_res); - return; - } - - stream_cfg.bits = AUD_BITS_16; - stream_cfg.channel_num = AUD_CHANNEL_NUM_2; - stream_cfg.sample_rate = AUD_SAMPRATE_48000; - - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; - stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; - stream_cfg.vol = 0x03; - - stream_cfg.handler = pcm_save_more_data; - stream_cfg.data_ptr = app_test_playback_buff; - stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; - - af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); - af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - } else { - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - osDelay(1000); - - f_close(&pcm_fil); - } -} - -// if dump data into sd, buffer length should make sd card speed enough -// Bench32.exe can test sd card speed in PC, then make sure bufer length, buffer -// length < 16k(sd driver) -void dump_data2sd(enum APP_SDMMC_DUMP_T opt, uint8_t *buf, uint32_t len) { - static FIL sd_fil; - FRESULT res; - - ASSERT(opt < APP_SDMMC_DUMP_NUM, "[%s] opt(%d) >= APP_SDMMC_DUMP_NUM", - __func__, opt); - - if (opt == APP_SDMMC_DUMP_OPEN) { - // res = f_open(&sd_fil,"dump.bin",FA_CREATE_ALWAYS | FA_WRITE); - res = f_open(&sd_fil, "test.txt", FA_READ); - - // ASSERT(pcm_res == FR_OK,"[%s]:Cannot creat dump.bin, res = - // %d",__func__, pcm_res); - } - if (opt == APP_SDMMC_DUMP_READ) { - res = f_read(&sd_fil, buf, len, &pcm_num); - - // ASSERT(pcm_res == FR_OK,"[%s]:Cannot creat dump.bin, res = - // %d",__func__, pcm_res); - } else if (opt == APP_SDMMC_DUMP_WRITE) { - res = f_write(&sd_fil, buf, len, &pcm_num); - - // ASSERT(pcm_res == FR_OK,"[%s]:Write dump.bin failed, res = %d", - // __func__, pcm_res); - } else if (opt == APP_SDMMC_DUMP_CLOSE) { - res = f_close(&sd_fil); - } - - if (res == FR_OK) { - TRACE(3, "[%s] SUCESS: opt = %d, res = %d", __func__, opt, res); - } else { - TRACE(3, "[%s] ERROR: opt = %d, res = %d", __func__, opt, res); - } -} diff --git a/apps/sdmmc/app_sdmmc.h b/apps/sdmmc/app_sdmmc.h deleted file mode 100644 index 01dced3..0000000 --- a/apps/sdmmc/app_sdmmc.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __APP_SDMMC_H__ -#define __APP_SDMMC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -enum APP_SDMMC_DUMP_T{ - APP_SDMMC_DUMP_OPEN = 0, - APP_SDMMC_DUMP_READ, - APP_SDMMC_DUMP_WRITE, - APP_SDMMC_DUMP_CLOSE, - APP_SDMMC_DUMP_NUM -}; - -int sd_open(); - -void dump_data2sd(enum APP_SDMMC_DUMP_T opt, uint8_t *buf, uint32_t len); - -#ifdef __cplusplus - } -#endif - -#endif//__FMDEC_H__ diff --git a/platform/hal/best2300p/hal_cmu_best2300p.c b/platform/hal/best2300p/hal_cmu_best2300p.c index 6a5d2ff..2b01473 100644 --- a/platform/hal/best2300p/hal_cmu_best2300p.c +++ b/platform/hal/best2300p/hal_cmu_best2300p.c @@ -1826,7 +1826,6 @@ PERPH_SET_DIV_FUNC(uart1, UART1, UART_CLK); PERPH_SET_DIV_FUNC(uart2, UART2, UART_CLK); PERPH_SET_DIV_FUNC(spi, SPI1, SYS_DIV); PERPH_SET_DIV_FUNC(slcd, SPI0, SYS_DIV); -PERPH_SET_DIV_FUNC(sdmmc, SDMMC, PERIPH_CLK); PERPH_SET_DIV_FUNC(i2c, I2C, I2C_CLK); #define PERPH_SET_FREQ_FUNC(f, F, r) \ @@ -1851,7 +1850,6 @@ PERPH_SET_FREQ_FUNC(uart1, UART1, UART_CLK); PERPH_SET_FREQ_FUNC(uart2, UART2, UART_CLK); PERPH_SET_FREQ_FUNC(spi, SPI1, SYS_DIV); PERPH_SET_FREQ_FUNC(slcd, SPI0, SYS_DIV); -PERPH_SET_FREQ_FUNC(sdmmc, SDMMC, PERIPH_CLK); PERPH_SET_FREQ_FUNC(i2c, I2C, I2C_CLK); int hal_cmu_ispi_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq) { diff --git a/platform/hal/hal_sdmmc.c b/platform/hal/hal_sdmmc.c deleted file mode 100644 index 134655a..0000000 --- a/platform/hal/hal_sdmmc.c +++ /dev/null @@ -1,2789 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifdef CHIP_HAS_SDMMC - -#include "hal_sdmmc.h" -#include "cmsis_nvic.h" -#include "errno.h" -#include "hal_cmu.h" -#include "hal_dma.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hal_uart.h" -#include "plat_addr_map.h" -#include "reg_sdmmcip.h" -#include "stdarg.h" -#include "stdio.h" -#include "string.h" - -#ifndef ETIMEDOUT -#define ETIMEDOUT 110 /* Connection timed out */ -#endif - -#define HAL_SDMMC_USE_DMA 1 -// #define __BUS_WIDTH_SUPPORT_4BIT__ 1 - -#define HAL_SDMMC_TRACE(...) -// #define HAL_SDMMC_TRACE TRACE -#define HAL_SDMMC_ASSERT(...) -// #define HAL_SDMMC_ASSERT ASSERT - -#define _SDMMC_CLOCK 52000000 - -#define _SDMMC_DMA_MINALIGN 32 - -#define _sdmmc_be32_to_cpu(x) \ - ((uint32_t)((((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))) - -#define _SDMMC_DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) -#define _SDMMC_ROUND(a, b) (((a) + (b)-1) & ~((b)-1)) - -#define _SDMMC_PAD_COUNT(s, pad) (((s)-1) / (pad) + 1) -#define _SDMMC_PAD_SIZE(s, pad) (_SDMMC_PAD_COUNT(s, pad) * pad) -#define _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \ - char __##name[_SDMMC_ROUND(_SDMMC_PAD_SIZE((size) * sizeof(type), pad), \ - align) + \ - (align - 1)]; \ - type *name = (type *)ALIGN((uint32_t)__##name, align) - -#define _SDMMC_ALLOC_ALIGN_BUFFER(type, name, size, align) \ - _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1) -#define _SDMMC_ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \ - _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, _SDMMC_DMA_MINALIGN, pad) -#define _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \ - _SDMMC_ALLOC_ALIGN_BUFFER(type, name, size, _SDMMC_DMA_MINALIGN) - -typedef struct block_dev_desc { - int if_type; /* type of the interface */ - int dev; /* device number */ - unsigned char part_type; /* partition type */ - unsigned char target; /* target SCSI ID */ - unsigned char lun; /* target LUN */ - unsigned char type; /* device type */ - unsigned char removable; /* removable device */ -#ifdef CONFIG_LBA48 - unsigned char lba48; /* device can use 48bit addr (ATA/ATAPI v7) */ -#endif - uint32_t lba; /* number of blocks */ - unsigned long blksz; /* block size */ - int log2blksz; /* for convenience: log2(blksz) */ - char vendor[40 + 1]; /* IDE model, SCSI Vendor */ - char product[20 + 1]; /* IDE Serial no, SCSI product */ - char revision[8 + 1]; /* firmware revision */ - void *priv; /* driver private struct pointer */ -} block_dev_desc_t; - -/* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */ -#define SD_VERSION_SD (1U << 31) -#define MMC_VERSION_MMC (1U << 30) - -#define MAKE_SDMMC_VERSION(a, b, c) \ - ((((uint32_t)(a)) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(c)) -#define MAKE_SD_VERSION(a, b, c) (SD_VERSION_SD | MAKE_SDMMC_VERSION(a, b, c)) -#define MAKE_MMC_VERSION(a, b, c) \ - (MMC_VERSION_MMC | MAKE_SDMMC_VERSION(a, b, c)) - -#define EXTRACT_SDMMC_MAJOR_VERSION(x) (((uint32_t)(x) >> 16) & 0xff) -#define EXTRACT_SDMMC_MINOR_VERSION(x) (((uint32_t)(x) >> 8) & 0xff) -#define EXTRACT_SDMMC_CHANGE_VERSION(x) ((uint32_t)(x)&0xff) - -#define SD_VERSION_3 MAKE_SD_VERSION(3, 0, 0) -#define SD_VERSION_2 MAKE_SD_VERSION(2, 0, 0) -#define SD_VERSION_1_0 MAKE_SD_VERSION(1, 0, 0) -#define SD_VERSION_1_10 MAKE_SD_VERSION(1, 10, 0) - -#define MMC_VERSION_UNKNOWN MAKE_MMC_VERSION(0, 0, 0) -#define MMC_VERSION_1_2 MAKE_MMC_VERSION(1, 2, 0) -#define MMC_VERSION_1_4 MAKE_MMC_VERSION(1, 4, 0) -#define MMC_VERSION_2_2 MAKE_MMC_VERSION(2, 2, 0) -#define MMC_VERSION_3 MAKE_MMC_VERSION(3, 0, 0) -#define MMC_VERSION_4 MAKE_MMC_VERSION(4, 0, 0) -#define MMC_VERSION_4_1 MAKE_MMC_VERSION(4, 1, 0) -#define MMC_VERSION_4_2 MAKE_MMC_VERSION(4, 2, 0) -#define MMC_VERSION_4_3 MAKE_MMC_VERSION(4, 3, 0) -#define MMC_VERSION_4_41 MAKE_MMC_VERSION(4, 4, 1) -#define MMC_VERSION_4_5 MAKE_MMC_VERSION(4, 5, 0) -#define MMC_VERSION_5_0 MAKE_MMC_VERSION(5, 0, 0) - -#define MMC_MODE_HS (1 << 0) -#define MMC_MODE_HS_52MHz (1 << 1) -#define MMC_MODE_4BIT (1 << 2) -#define MMC_MODE_8BIT (1 << 3) -#define MMC_MODE_SPI (1 << 4) -#define MMC_MODE_DDR_52MHz (1 << 5) - -#define SD_DATA_4BIT 0x00040000 - -#define IS_SD(x) ((x)->version & SD_VERSION_SD) -#define IS_MMC(x) ((x)->version & MMC_VERSION_MMC) - -#define MMC_DATA_READ 1 -#define MMC_DATA_WRITE 2 - -#define NO_CARD_ERR -16 /* No SD/MMC card inserted */ -#define UNUSABLE_ERR -17 /* Unusable Card */ -#define COMM_ERR -18 /* Communications Error */ -#define TIMEOUT -19 -#define SWITCH_ERR -20 /* Card reports failure to switch mode */ - -#define MMC_CMD_GO_IDLE_STATE 0 -#define MMC_CMD_SEND_OP_COND 1 -#define MMC_CMD_ALL_SEND_CID 2 -#define MMC_CMD_SET_RELATIVE_ADDR 3 -#define MMC_CMD_SET_DSR 4 -#define MMC_CMD_SWITCH 6 -#define MMC_CMD_SELECT_CARD 7 -#define MMC_CMD_SEND_EXT_CSD 8 -#define MMC_CMD_SEND_CSD 9 -#define MMC_CMD_SEND_CID 10 -#define MMC_CMD_STOP_TRANSMISSION 12 -#define MMC_CMD_SEND_STATUS 13 -#define MMC_CMD_SET_BLOCKLEN 16 -#define MMC_CMD_READ_SINGLE_BLOCK 17 -#define MMC_CMD_READ_MULTIPLE_BLOCK 18 -#define MMC_CMD_SET_BLOCK_COUNT 23 -#define MMC_CMD_WRITE_SINGLE_BLOCK 24 -#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25 -#define MMC_CMD_ERASE_GROUP_START 35 -#define MMC_CMD_ERASE_GROUP_END 36 -#define MMC_CMD_ERASE 38 -#define MMC_CMD_APP_CMD 55 -#define MMC_CMD_SPI_READ_OCR 58 -#define MMC_CMD_SPI_CRC_ON_OFF 59 -#define MMC_CMD_RES_MAN 62 - -#define MMC_CMD62_ARG1 0xefac62ec -#define MMC_CMD62_ARG2 0xcbaea7 - -#define SD_CMD_SEND_RELATIVE_ADDR 3 -#define SD_CMD_SWITCH_FUNC 6 -#define SD_CMD_SEND_IF_COND 8 -#define SD_CMD_SWITCH_UHS18V 11 - -#define SD_CMD_APP_SET_BUS_WIDTH 6 -#define SD_CMD_ERASE_WR_BLK_START 32 -#define SD_CMD_ERASE_WR_BLK_END 33 -#define SD_CMD_APP_SEND_OP_COND 41 -#define SD_CMD_APP_SEND_SCR 51 - -/* SCR definitions in different words */ -#define SD_HIGHSPEED_BUSY 0x00020000 -#define SD_HIGHSPEED_SUPPORTED 0x00020000 - -#define OCR_BUSY 0x80000000 -#define OCR_HCS 0x40000000 -#define OCR_VOLTAGE_MASK 0x007FFF80 -#define OCR_ACCESS_MODE 0x60000000 - -#define SECURE_ERASE 0x80000000 - -#define MMC_STATUS_MASK (~0x0206BF7F) -#define MMC_STATUS_SWITCH_ERROR (1 << 7) -#define MMC_STATUS_RDY_FOR_DATA (1 << 8) -#define MMC_STATUS_CURR_STATE (0xf << 9) -#define MMC_STATUS_ERROR (1 << 19) - -#define MMC_STATE_PRG (7 << 9) - -#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ -#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ -#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ -#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ -#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ -#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ -#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ -#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ -#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ -#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ -#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ -#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ -#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ -#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ -#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ -#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ -#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ - -#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ -#define MMC_SWITCH_MODE_SET_BITS \ - 0x01 /* Set bits in EXT_CSD byte \ -addressed by index which are \ -1 in value field */ -#define MMC_SWITCH_MODE_CLEAR_BITS \ - 0x02 /* Clear bits in EXT_CSD byte \ - addressed by index, which are \ - 1 in value field */ -#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target byte to value */ - -#define SD_SWITCH_CHECK 0 -#define SD_SWITCH_SWITCH 1 - -/* - * EXT_CSD fields - */ -#define EXT_CSD_ENH_START_ADDR 136 /* R/W */ -#define EXT_CSD_ENH_SIZE_MULT 140 /* R/W */ -#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ -#define EXT_CSD_PARTITION_SETTING 155 /* R/W */ -#define EXT_CSD_PARTITIONS_ATTRIBUTE 156 /* R/W */ -#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* R */ -#define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ -#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ -#define EXT_CSD_WR_REL_PARAM 166 /* R */ -#define EXT_CSD_WR_REL_SET 167 /* R/W */ -#define EXT_CSD_RPMB_MULT 168 /* RO */ -#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ -#define EXT_CSD_BOOT_BUS_WIDTH 177 -#define EXT_CSD_PART_CONF 179 /* R/W */ -#define EXT_CSD_BUS_WIDTH 183 /* R/W */ -#define EXT_CSD_HS_TIMING 185 /* R/W */ -#define EXT_CSD_REV 192 /* RO */ -#define EXT_CSD_CARD_TYPE 196 /* RO */ -#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ -#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ -#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ -#define EXT_CSD_BOOT_MULT 226 /* RO */ - -/* - * EXT_CSD field definitions - */ - -#define EXT_CSD_CMD_SET_NORMAL (1 << 0) -#define EXT_CSD_CMD_SET_SECURE (1 << 1) -#define EXT_CSD_CMD_SET_CPSECURE (1 << 2) - -#define EXT_CSD_CARD_TYPE_26 (1 << 0) /* Card can run at 26MHz */ -#define EXT_CSD_CARD_TYPE_52 (1 << 1) /* Card can run at 52MHz */ -#define EXT_CSD_CARD_TYPE_DDR_1_8V (1 << 2) -#define EXT_CSD_CARD_TYPE_DDR_1_2V (1 << 3) -#define EXT_CSD_CARD_TYPE_DDR_52 \ - (EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_2V) - -#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ -#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ -#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ -#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ -#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ - -#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) -#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) -#define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) -#define EXT_CSD_PARTITION_ACCESS_DISABLE (0 << 0) - -#define EXT_CSD_BOOT_ACK(x) (x << 6) -#define EXT_CSD_BOOT_PART_NUM(x) (x << 3) -#define EXT_CSD_PARTITION_ACCESS(x) (x << 0) - -#define EXT_CSD_BOOT_BUS_WIDTH_MODE(x) (x << 3) -#define EXT_CSD_BOOT_BUS_WIDTH_RESET(x) (x << 2) -#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x) (x) - -#define EXT_CSD_PARTITION_SETTING_COMPLETED (1 << 0) - -#define EXT_CSD_ENH_USR (1 << 0) /* user data area is enhanced */ -#define EXT_CSD_ENH_GP(x) (1 << ((x) + 1)) /* GP part (x+1) is enhanced */ - -#define EXT_CSD_HS_CTRL_REL (1 << 0) /* host controlled WR_REL_SET */ - -#define EXT_CSD_WR_DATA_REL_USR (1 << 0) /* user data area WR_REL */ -#define EXT_CSD_WR_DATA_REL_GP(x) (1 << ((x) + 1)) /* GP part (x+1) WR_REL */ - -#define R1_ILLEGAL_COMMAND (1 << 22) -#define R1_APP_CMD (1 << 5) - -#define MMC_RSP_PRESENT (1 << 0) -#define MMC_RSP_136 (1 << 1) /* 136 bit response */ -#define MMC_RSP_CRC (1 << 2) /* expect valid crc */ -#define MMC_RSP_BUSY (1 << 3) /* card may send busy */ -#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ - -#define MMC_RSP_NONE (0) -#define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R1b \ - (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY) -#define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC) -#define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R4 (MMC_RSP_PRESENT) -#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) - -#define MMCPART_NOAVAILABLE (0xff) -#define PART_ACCESS_MASK (0x7) -#define PART_SUPPORT (0x1) -#define ENHNCD_SUPPORT (0x2) -#define PART_ENH_ATTRIB (0x1f) - -/* Maximum block size for MMC */ -#define MMC_MAX_BLOCK_LEN 512 - -/* The number of MMC physical partitions. These consist of: - * boot partitions (2), general purpose partitions (4) in MMC v4.4. - */ -#define MMC_NUM_BOOT_PARTITION 2 -#define MMC_PART_RPMB 3 /* RPMB partition number */ - -struct mmc_cid { - unsigned long psn; - unsigned short oid; - uint8_t mid; - uint8_t prv; - uint8_t mdt; - char pnm[7]; -}; - -struct mmc_cmd { - u16 cmdidx; - uint32_t resp_type; - uint32_t cmdarg; - uint32_t response[4]; -}; - -struct mmc_data { - union { - char *dest; - const char *src; /* src buffers don't get written to */ - }; - uint32_t flags; - uint32_t blocks; - uint32_t blocksize; -}; - -/* forward decl. */ -struct mmc; - -struct mmc_ops { - int (*send_cmd)(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data); - void (*set_ios)(struct mmc *mmc); - int (*init)(struct mmc *mmc); - int (*getcd)(struct mmc *mmc); - int (*getwp)(struct mmc *mmc); -}; - -struct mmc_config { - const struct mmc_ops *ops; - uint32_t host_caps; - uint32_t voltages; - uint32_t f_min; - uint32_t f_max; - uint32_t b_max; - uint8_t part_type; -}; - -/* TODO struct mmc should be in mmc_private but it's hard to fix right now */ -struct mmc { - const struct mmc_config *cfg; /* provided configuration */ - uint32_t version; - void *priv; - uint32_t has_init; - int high_capacity; - uint32_t bus_width; - uint32_t clock; - uint32_t card_caps; - uint32_t ocr; - uint32_t dsr; - uint32_t dsr_imp; - uint32_t scr[2]; - uint32_t csd[4]; - uint32_t cid[4]; - u16 rca; - u8 part_support; - u8 part_attr; - u8 wr_rel_set; - char part_config; - char part_num; - uint32_t tran_speed; - uint32_t read_bl_len; - uint32_t write_bl_len; - uint32_t erase_grp_size; /* in 512-byte sectors */ - uint32_t hc_wp_grp_size; /* in 512-byte sectors */ - uint64_t capacity; - uint64_t capacity_user; - uint64_t capacity_boot; - uint64_t capacity_rpmb; - uint64_t capacity_gp[4]; - uint64_t enh_user_start; - uint64_t enh_user_size; - block_dev_desc_t block_dev; - char op_cond_pending; /* 1 if we are waiting on an op_cond command */ - char init_in_progress; /* 1 if we have done mmc_start_init() */ - char preinit; /* start init as early as possible */ - int ddr_mode; -}; - -struct mmc_hwpart_conf { - struct { - uint32_t enh_start; /* in 512-byte sectors */ - uint32_t enh_size; /* in 512-byte sectors, if 0 no enh area */ - unsigned wr_rel_change : 1; - unsigned wr_rel_set : 1; - } user; - struct { - uint32_t size; /* in 512-byte sectors */ - unsigned enhanced : 1; - unsigned wr_rel_change : 1; - unsigned wr_rel_set : 1; - } gp_part[4]; -}; - -enum mmc_hwpart_conf_mode { - MMC_HWPART_CONF_CHECK, - MMC_HWPART_CONF_SET, - MMC_HWPART_CONF_COMPLETE, -}; - -struct sdmmcip_host { - void *ioaddr; - unsigned int quirks; - unsigned int caps; - unsigned int version; - unsigned int clock; - unsigned int bus_hz; - unsigned int div; - int dev_index; - int dev_id; - int buswidth; - uint32_t fifoth_val; - bool detect_enb; - struct mmc *mmc; - void *priv; - - void (*clksel)(struct sdmmcip_host *host); - void (*board_init)(struct sdmmcip_host *host); - unsigned int (*get_mmc_clk)(struct sdmmcip_host *host); - - struct mmc_config cfg; - -#ifdef HAL_SDMMC_USE_DMA - /* TODO : os and non-os condition */ - uint8_t dma_ch; - volatile uint32_t sdmmc_dma_lock; - HAL_DMA_IRQ_HANDLER_T tx_dma_handler; - HAL_DMA_IRQ_HANDLER_T rx_dma_handler; -#endif -}; - -struct sdmmcip_idmac { - uint32_t flags; - uint32_t cnt; - uint32_t addr; - uint32_t next_addr; -}; - -static void hal_sdmmc_delay(uint32_t ms); - -static HAL_SDMMC_DELAY_FUNC sdmmc_delay = NULL; - -static inline void sdmmcip_writel(struct sdmmcip_host *host, int reg, - uint32_t val) { - *((volatile uint32_t *)(host->ioaddr + reg)) = val; -} - -static inline uint32_t sdmmcip_readl(struct sdmmcip_host *host, int reg) { - return *((volatile uint32_t *)(host->ioaddr + reg)); -} - -#ifdef CONFIG_MMC_SPI -#define sdmmc_host_is_spi(mmc) ((mmc)->cfg->host_caps & MMC_MODE_SPI) -#else -#define sdmmc_host_is_spi(mmc) 0 -#endif - -#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT -#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535 -#endif - -static void (*sdmmc_detected_callback)(uint8_t) = NULL; -static uint32_t sdmmc_ip_base[HAL_SDMMC_ID_NUM] = { - SDMMC_BASE, -}; -static struct sdmmcip_host sdmmc_host[HAL_SDMMC_ID_NUM]; -static struct mmc sdmmc_devices[HAL_SDMMC_ID_NUM]; -// static const char * const invalid_id = "Invalid SDMMC ID: %d\n"; - -#ifdef HAL_SDMMC_USE_DMA -static void sdmmcip0_ext_dma_tx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli); -static void sdmmcip0_ext_dma_rx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli); -static HAL_DMA_IRQ_HANDLER_T - sdmmcip_ext_dma_irq_handlers[HAL_SDMMC_ID_NUM * 2] = { - sdmmcip0_ext_dma_tx_handler, - sdmmcip0_ext_dma_rx_handler, -}; -#endif - -uint32_t _sdmmc_div64_32(uint64_t *n, uint32_t base) { - uint64_t rem = *n; - uint64_t b = base; - uint64_t res, d = 1; - uint32_t high = rem >> 32; - - /* Reduce the thing a bit first */ - res = 0; - if (high >= base) { - high /= base; - res = (uint64_t)high << 32; - rem -= (uint64_t)(high * base) << 32; - } - - while ((int64_t)b > 0 && b < rem) { - b = b + b; - d = d + d; - } - - do { - if (rem >= b) { - rem -= b; - res += d; - } - b >>= 1; - d >>= 1; - } while (d); - - *n = res; - return rem; -} - -/* The unnecessary pointer compare is there - * * to check for type safety (n must be 64bit) - * */ -#define _sdmmc_do_div(n, base) \ - ({ \ - uint32_t __base = (base); \ - uint32_t __rem; \ - (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ - if (((n) >> 32) == 0) { \ - __rem = (uint32_t)(n) % __base; \ - (n) = (uint32_t)(n) / __base; \ - } else \ - __rem = _sdmmc_div64_32(&(n), __base); \ - __rem; \ - }) - -/* Wrapper for _sdmmc_do_div(). Doesn't modify dividend and returns - * * the result, not reminder. - * */ -static inline uint64_t _sdmmc_lldiv(uint64_t dividend, uint32_t divisor) { - uint64_t __res = dividend; - _sdmmc_do_div(__res, divisor); - return (__res); -} - -static void mmc_udelay(int cnt) { - volatile uint32_t i = 0, c = 0; - for (i = 0; i < cnt; ++i) { - c++; - __asm("nop"); - } -} - -static int sdmmcip_wait_reset(struct sdmmcip_host *host, uint32_t value) { - uint32_t ctrl; - unsigned long timeout = 1000; - - sdmmcip_writel(host, SDMMCIP_REG_CTRL, value); - - while (timeout--) { - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - if (!(ctrl & SDMMCIP_REG_RESET_ALL)) - return 1; - } - return 0; -} - -#ifdef HAL_SDMMC_USE_DMA -static void sdmmcip0_ext_dma_tx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli) { - uint32_t ip_raw_int_status = 0; - struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; - HAL_SDMMC_TRACE(2, "%s:%d\n", __func__, __LINE__); - ip_raw_int_status = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - HAL_SDMMC_TRACE(3, "%s:%d, tx ip_raw_int_status 0x%x\n", __func__, __LINE__, - ip_raw_int_status); - if (ip_raw_int_status & (SDMMCIP_REG_DATA_ERR | SDMMCIP_REG_DATA_TOUT)) { - HAL_SDMMC_TRACE(3, "%s:%d, sdmmcip0 tx dma error 0x%x\n", __func__, - __LINE__, ip_raw_int_status); - } - - /* TODO : os and non-os condition */ - host->sdmmc_dma_lock = 0; -} - -static void sdmmcip0_ext_dma_rx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli) { - uint32_t ip_raw_int_status = 0; - struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; - HAL_SDMMC_TRACE(2, "%s:%d\n", __func__, __LINE__); - ip_raw_int_status = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - HAL_SDMMC_TRACE(3, "%s:%d, ip_raw_int_status 0x%x\n", __func__, __LINE__, - ip_raw_int_status); - if (ip_raw_int_status & (SDMMCIP_REG_DATA_ERR | SDMMCIP_REG_DATA_TOUT)) { - HAL_SDMMC_TRACE(3, "%s:%d, sdmmcip0 rx dma error 0x%x\n", __func__, - __LINE__, ip_raw_int_status); - } - - /* TODO : os and non-os condition */ - host->sdmmc_dma_lock = 0; -} -#endif - -static void sdmmcip_prepare_data(struct sdmmcip_host *host, - struct mmc_data *data, - struct sdmmcip_idmac *cur_idmac, - void *bounce_buffer) { -#ifdef HAL_SDMMC_USE_DMA - uint32_t ctrl = 0; - struct HAL_DMA_CH_CFG_T dma_cfg; -#endif - sdmmcip_writel(host, SDMMCIP_REG_BLKSIZ, data->blocksize); - sdmmcip_writel(host, SDMMCIP_REG_BYTCNT, data->blocksize * data->blocks); - - /* use dma */ -#ifdef HAL_SDMMC_USE_DMA - - HAL_SDMMC_TRACE(0, "sdmmc use dma\n"); - /* enable sdmmcip e-dma */ - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl |= (SDMMCIP_REG_DMA_EN); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - host->sdmmc_dma_lock = 1; - - memset(&dma_cfg, 0, sizeof(dma_cfg)); - if (data->flags & MMC_DATA_READ) { - HAL_SDMMC_TRACE(0, "sdmmc use dma read\n"); - dma_cfg.dst = (uint32_t)data->dest; - // HAL_SDMMC_TRACE(2,"sddma :len %d, buf 0x%x\n", - // data->blocksize*data->blocks, dma_cfg.dst); - if ((dma_cfg.dst % 4) != 0) { - dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE; - } else { - dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; - } - dma_cfg.dst_bsize = HAL_DMA_BSIZE_1; - dma_cfg.dst_periph = 0; // useless - // dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; - dma_cfg.handler = host->rx_dma_handler; - dma_cfg.src_bsize = HAL_DMA_BSIZE_1; - dma_cfg.src_periph = HAL_GPDMA_SDMMC; - dma_cfg.src_tsize = data->blocks * data->blocksize / 4; - HAL_SDMMC_TRACE(1, "sdmmc use dma tsize %d\n", dma_cfg.src_tsize); - dma_cfg.src_width = HAL_DMA_WIDTH_WORD; - dma_cfg.try_burst = 1; - dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; - dma_cfg.src = (uint32_t)0; // useless - dma_cfg.ch = hal_gpdma_get_chan(dma_cfg.src_periph, HAL_DMA_HIGH_PRIO); - HAL_SDMMC_TRACE(1, "sdmmc use dma get ch %d\n", dma_cfg.ch); - } else { - HAL_SDMMC_TRACE(0, "sdmmc use dma write\n"); - dma_cfg.dst = 0; // useless - dma_cfg.dst_bsize = HAL_DMA_BSIZE_1; - dma_cfg.dst_periph = HAL_GPDMA_SDMMC; - dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; - dma_cfg.handler = host->tx_dma_handler; - dma_cfg.src_bsize = HAL_DMA_BSIZE_1; - dma_cfg.src_periph = 0; // useless - // dma_cfg.src_tsize = data->blocks*data->blocksize/4; - HAL_SDMMC_TRACE(1, "sdmmc use dma tsize %d\n", dma_cfg.src_tsize); - // dma_cfg.src_width = HAL_DMA_WIDTH_WORD; - dma_cfg.try_burst = 1; - dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; - dma_cfg.src = (uint32_t)data->src; - // uart_printf("sddma :len %d, buf 0x%x\n", data->blocksize*data->blocks, - // dma_cfg.src); - if ((dma_cfg.src % 4) != 0) { - dma_cfg.src_width = HAL_DMA_WIDTH_BYTE; - dma_cfg.src_tsize = data->blocks * data->blocksize; - } else { - dma_cfg.src_width = HAL_DMA_WIDTH_WORD; - dma_cfg.src_tsize = data->blocks * data->blocksize / 4; - } - dma_cfg.ch = hal_gpdma_get_chan(dma_cfg.dst_periph, HAL_DMA_HIGH_PRIO); - HAL_SDMMC_TRACE(1, "sdmmc use dma get ch %d\n", dma_cfg.ch); - - // uart_printf("%s:%d src 0x%x\n", __func__, __LINE__, dma_cfg.src); - } - - host->dma_ch = dma_cfg.ch; - - hal_gpdma_start(&dma_cfg); -#endif -} - -static int sdmmcip_set_transfer_mode(struct sdmmcip_host *host, - struct mmc_data *data) { - unsigned long mode; - - mode = SDMMCIP_REG_CMD_DATA_EXP; - if (data->flags & MMC_DATA_WRITE) - mode |= SDMMCIP_REG_CMD_RW; - - return mode; -} - -static int sdmmcip_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) { - int ret = 0; - int flags = 0, i; - uint32_t retry = 1000000; - uint32_t mask, ctrl; - int busy_tmo = MS_TO_TICKS(1000), busy_t = 0; -#ifndef HAL_SDMMC_USE_DMA - uint32_t status = 0, fifo_data = 0; -#endif - struct sdmmcip_host *host = mmc->priv; - - busy_t = hal_sys_timer_get(); - - while ((sdmmcip_readl(host, SDMMCIP_REG_STATUS) & SDMMCIP_REG_BUSY) && - hal_sys_timer_get() < (busy_t + busy_tmo)) { - HAL_SDMMC_TRACE(0, "[sdmmc]busy\n"); - } - - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CD); - - if (data) { - sdmmcip_prepare_data(host, data, 0, 0); - } - - sdmmcip_writel(host, SDMMCIP_REG_CMDARG, cmd->cmdarg); - - if (data) - flags = sdmmcip_set_transfer_mode(host, data); - - if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) - return -1; - - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) - flags |= SDMMCIP_REG_CMD_ABORT_STOP; - else - flags |= SDMMCIP_REG_CMD_PRV_DAT_WAIT; - - if (cmd->resp_type & MMC_RSP_PRESENT) { - flags |= SDMMCIP_REG_CMD_RESP_EXP; - if (cmd->resp_type & MMC_RSP_136) - flags |= SDMMCIP_REG_CMD_RESP_LENGTH; - } - - if (cmd->resp_type & MMC_RSP_CRC) - flags |= SDMMCIP_REG_CMD_CHECK_CRC; - - flags |= (cmd->cmdidx | SDMMCIP_REG_CMD_START | SDMMCIP_REG_CMD_USE_HOLD_REG); - - sdmmcip_writel(host, SDMMCIP_REG_CMD, flags); - - for (i = 0; i < retry; i++) { - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - if (mask & SDMMCIP_REG_INTMSK_CDONE) { - if (!data) - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CDONE); - break; - } - } - - if (i == retry) { - HAL_SDMMC_TRACE(1, "%s: Timeout.\n", __func__); - return TIMEOUT; - } - - if (mask & SDMMCIP_REG_INTMSK_RTO) { - /* - * Timeout here is not necessarily fatal. (e)MMC cards - * will splat here when they receive CMD55 as they do - * not support this command and that is exactly the way - * to tell them apart from SD cards. Thus, this output - * below shall be TRACE(). eMMC cards also do not favor - * CMD8, please keep that in mind. - */ - HAL_SDMMC_TRACE(1, "%s: Response Timeout.\n", __func__); - return TIMEOUT; - } else if (mask & SDMMCIP_REG_INTMSK_RE) { - HAL_SDMMC_TRACE(1, "%s: Response Error.\n", __func__); - return -1; - } - - if (cmd->resp_type & MMC_RSP_PRESENT) { - if (cmd->resp_type & MMC_RSP_136) { - cmd->response[0] = sdmmcip_readl(host, SDMMCIP_REG_RESP3); - cmd->response[1] = sdmmcip_readl(host, SDMMCIP_REG_RESP2); - cmd->response[2] = sdmmcip_readl(host, SDMMCIP_REG_RESP1); - cmd->response[3] = sdmmcip_readl(host, SDMMCIP_REG_RESP0); - } else { - cmd->response[0] = sdmmcip_readl(host, SDMMCIP_REG_RESP0); - } - } - -#ifndef HAL_SDMMC_USE_DMA - if (data) { - i = 0; - while (1) { - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - if (mask & (SDMMCIP_REG_DATA_ERR | SDMMCIP_REG_DATA_TOUT)) { - HAL_SDMMC_TRACE(1, "%s: READ DATA ERROR!\n", __func__); - ret = -1; - goto out; - } - status = sdmmcip_readl(host, SDMMCIP_REG_STATUS); - if (data->flags == MMC_DATA_READ) { - if (status & SDMMCIP_REG_FIFO_COUNT_MASK) { - fifo_data = sdmmcip_readl(host, SDMMCIP_REG_FIFO_OFFSET); - // HAL_SDMMC_TRACE(3,"%s: count %d, read -> 0x%x\n", __func__, i, - // fifo_data); - /* FIXME: now we just deal with 32bit width fifo one time */ - if (i < data->blocks * data->blocksize) { - memcpy(data->dest + i, &fifo_data, sizeof(fifo_data)); - i += sizeof(fifo_data); - } else { - HAL_SDMMC_TRACE(1, "%s: fifo data too much\n", __func__); - ret = -1; - goto out; - } - } - /* nothing to read from fifo and DTO is set */ - else if (mask & SDMMCIP_REG_INTMSK_DTO) { - if (i != data->blocks * data->blocksize) { - HAL_SDMMC_TRACE(3, "%s: need to read %d, actually read %d\n", - __func__, data->blocks * data->blocksize, i); - } - ret = 0; - goto out; - } - } else { - /* nothing to write to fifo and DTO is set */ - if (mask & SDMMCIP_REG_INTMSK_DTO) { - /* check if number is right */ - if (i != data->blocks * data->blocksize) { - HAL_SDMMC_TRACE(3, "%s: need to write %d, actually written %d\n", - __func__, data->blocks * data->blocksize, i); - } - ret = 0; - goto out; - } else if (!(status & SDMMCIP_REG_FIFO_COUNT_MASK)) { - /* FIXME: now we just deal with 32bit width fifo one time */ - if (i < data->blocks * data->blocksize) { - memcpy(&fifo_data, data->src + i, sizeof(fifo_data)); - // HAL_SDMMC_TRACE(4,"%s: fifo %d, count %d, write -> 0x%x\n", - // __func__, ((status & - // SDMMCIP_REG_FIFO_COUNT_MASK)>>SDMMCIP_REG_FIFO_COUNT_SHIFT), i, - // fifo_data); - i += sizeof(fifo_data); - sdmmcip_writel(host, SDMMCIP_REG_FIFO_OFFSET, fifo_data); - } else { - HAL_SDMMC_TRACE(1, "%s: no data to write to fifo, do nothing\n", - __func__); - } - } - } - } - } -#endif - -#ifdef HAL_SDMMC_USE_DMA - while (host->sdmmc_dma_lock) - ; - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl |= SDMMCIP_REG_CTRL_DMA_RESET; - sdmmcip_wait_reset(host, ctrl); - if (data) { - hal_gpdma_free_chan(host->dma_ch); -#if 0 - if (data->flags & MMC_DATA_READ) { - for (int ccc = 0; ccc < 400; ++ccc) { - HAL_SDMMC_TRACE(2,"%d-0x%x ", ccc, data->dest[ccc]); - } - HAL_SDMMC_TRACE(0,"\n"); - } -#endif - } -#endif - -#ifndef HAL_SDMMC_USE_DMA -out: -#endif - - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, mask & (~SDMMCIP_REG_INTMSK_CD)); - - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl &= ~(SDMMCIP_REG_DMA_EN); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - mmc_udelay(100); - - return ret; -} - -static int sdmmcip_setup_bus(struct sdmmcip_host *host, uint32_t freq) { - uint32_t div, status; - int timeout = 10000; - unsigned long sclk; - - if ((freq == host->clock) || (freq == 0)) - return 0; - /* - * If host->get_mmc_clk isn't defined, - * then assume that host->bus_hz is source clock value. - * host->bus_hz should be set by user. - */ - if (host->get_mmc_clk) - sclk = host->get_mmc_clk(host); - else if (host->bus_hz) - sclk = host->bus_hz; - else { - HAL_SDMMC_TRACE(1, "%s: Didn't get source clock value.\n", __func__); - return -EINVAL; - } - - if (sclk == freq) - div = 0; /* bypass mode */ - else - div = _SDMMC_DIV_ROUND_UP(sclk, 2 * freq); - - HAL_SDMMC_TRACE(4, "%s : freq %d, sclk %ld, div %d\n", __func__, freq, sclk, - div); - - sdmmcip_writel(host, SDMMCIP_REG_CLKENA, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x03000000); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x11000000); - - sdmmcip_writel(host, SDMMCIP_REG_CLKDIV, div); - sdmmcip_writel(host, SDMMCIP_REG_CMD, - SDMMCIP_REG_CMD_PRV_DAT_WAIT | SDMMCIP_REG_CMD_UPD_CLK | - SDMMCIP_REG_CMD_START); - - do { - status = sdmmcip_readl(host, SDMMCIP_REG_CMD); - if (timeout-- < 0) { - HAL_SDMMC_TRACE(1, "%s: Timeout!\n", __func__); - return -ETIMEDOUT; - } - } while (status & SDMMCIP_REG_CMD_START); - - sdmmcip_writel(host, SDMMCIP_REG_CLKENA, - SDMMCIP_REG_CLKEN_ENABLE | SDMMCIP_REG_CLKEN_LOW_PWR); - // sdmmcip_writel(host, SDMMCIP_REG_CLKENA, SDMMCIP_REG_CLKEN_ENABLE); - - sdmmcip_writel(host, SDMMCIP_REG_CMD, - SDMMCIP_REG_CMD_PRV_DAT_WAIT | SDMMCIP_REG_CMD_UPD_CLK | - SDMMCIP_REG_CMD_START); - - timeout = 10000; - do { - status = sdmmcip_readl(host, SDMMCIP_REG_CMD); - if (timeout-- < 0) { - HAL_SDMMC_TRACE(1, "%s: Timeout!\n", __func__); - return -ETIMEDOUT; - } - } while (status & SDMMCIP_REG_CMD_START); - - host->clock = freq; - - return 0; -} - -static void sdmmcip_set_ios(struct mmc *mmc) { - struct sdmmcip_host *host = (struct sdmmcip_host *)mmc->priv; - uint32_t ctype, regs; - - HAL_SDMMC_TRACE(2, "Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock); - - sdmmcip_setup_bus(host, mmc->clock); - - switch (mmc->bus_width) { - case 8: - ctype = SDMMCIP_REG_CTYPE_8BIT; - break; - case 4: - ctype = SDMMCIP_REG_CTYPE_4BIT; - break; - default: - ctype = SDMMCIP_REG_CTYPE_1BIT; - break; - } - - sdmmcip_writel(host, SDMMCIP_REG_CTYPE, ctype); - - regs = sdmmcip_readl(host, SDMMCIP_REG_UHS_REG); - if (mmc->ddr_mode) - regs |= SDMMCIP_REG_DDR_MODE; - else - regs &= ~SDMMCIP_REG_DDR_MODE; - - sdmmcip_writel(host, SDMMCIP_REG_UHS_REG, regs); - - if (host->clksel) - host->clksel(host); -} - -static int sdmmcip_init(struct mmc *mmc) { - struct sdmmcip_host *host = mmc->priv; - - if (host->board_init) - host->board_init(host); - - HAL_SDMMC_TRACE(2, "host->ioaddr %x, SDMMCIP_REG_PWREN %x\n", host->ioaddr, - SDMMCIP_REG_PWREN); - sdmmcip_writel(host, SDMMCIP_REG_PWREN, 1); - - if (!sdmmcip_wait_reset(host, SDMMCIP_REG_RESET_ALL)) { - HAL_SDMMC_TRACE(2, "%s[%d] Fail-reset!!\n", __func__, __LINE__); - return -1; - } - - /* Enumerate at 400KHz */ - sdmmcip_setup_bus(host, mmc->cfg->f_min); - - if (host->detect_enb) { - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, - SDMMCIP_REG_INTMSK_ALL & (~SDMMCIP_REG_INTMSK_CD)); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, SDMMCIP_REG_INTMSK_CD); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, SDMMCIP_REG_INT_EN); - } else { - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_ALL); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, ~SDMMCIP_REG_INTMSK_ALL); - } - - sdmmcip_writel(host, SDMMCIP_REG_TMOUT, 0xFFFFFFFF); - - sdmmcip_writel(host, SDMMCIP_REG_IDINTEN, 0); - sdmmcip_writel(host, SDMMCIP_REG_BMOD, 1); - - sdmmcip_writel(host, SDMMCIP_REG_FIFOTH, host->fifoth_val); - - sdmmcip_writel(host, SDMMCIP_REG_CLKENA, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x03000000); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x11000000); - - sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 0); - mmc_udelay(1000); - sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 1); - mmc_udelay(1000); - mmc_udelay(1000); - sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 0); - // sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 1); - - return 0; -} - -static const struct mmc_ops sdmmcip_ops = { - .send_cmd = sdmmcip_send_cmd, - .set_ios = sdmmcip_set_ios, - .init = sdmmcip_init, -}; - -int board_mmc_getcd(struct mmc *mmc) { return -1; } - -int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { - int ret; - - int i; - uint8_t *ptr; - - HAL_SDMMC_TRACE(1, "CMD_SEND:%d\n", cmd->cmdidx); - HAL_SDMMC_TRACE(1, "\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); - ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); - HAL_SDMMC_TRACE(0, "send cmd end..."); - switch (cmd->resp_type) { - case MMC_RSP_NONE: - HAL_SDMMC_TRACE(0, "\t\tMMC_RSP_NONE\n"); - break; - case MMC_RSP_R1: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n", cmd->response[0]); - break; - case MMC_RSP_R1b: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R1b\t\t 0x%08X \n", cmd->response[0]); - break; - case MMC_RSP_R2: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R2\t\t 0x%08X \n", cmd->response[0]); - HAL_SDMMC_TRACE(1, "\t\t \t\t 0x%08X \n", cmd->response[1]); - HAL_SDMMC_TRACE(1, "\t\t \t\t 0x%08X \n", cmd->response[2]); - HAL_SDMMC_TRACE(1, "\t\t \t\t 0x%08X \n", cmd->response[3]); - HAL_SDMMC_TRACE(0, "\n"); - HAL_SDMMC_TRACE(0, "\t\t\t\t\tDUMPING DATA\n"); - for (i = 0; i < 4; i++) { - int j; - HAL_SDMMC_TRACE(1, "\t\t\t\t\t%03d - ", i * 4); - ptr = (uint8_t *)&cmd->response[i]; - ptr += 3; - for (j = 0; j < 4; j++) - HAL_SDMMC_TRACE(1, "%02X ", *ptr--); - HAL_SDMMC_TRACE(0, "\n"); - } - break; - case MMC_RSP_R3: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R3,4\t\t 0x%08X \n", cmd->response[0]); - break; - default: - HAL_SDMMC_TRACE(0, "\t\tERROR MMC rsp not supported\n"); - break; - } - return ret; -} - -int mmc_send_status(struct mmc *mmc, int timeout) { - struct mmc_cmd cmd; - int err, retries = 5; - int POSSIBLY_UNUSED status; - - cmd.cmdidx = MMC_CMD_SEND_STATUS; - cmd.resp_type = MMC_RSP_R1; - if (!sdmmc_host_is_spi(mmc)) - cmd.cmdarg = mmc->rca << 16; - - while (1) { - err = mmc_send_cmd(mmc, &cmd, NULL); - if (!err) { - if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) && - (cmd.response[0] & MMC_STATUS_CURR_STATE) != MMC_STATE_PRG) - break; - else if (cmd.response[0] & MMC_STATUS_MASK) { - return COMM_ERR; - } - } else if (--retries < 0) - return err; - - if (timeout-- <= 0) - break; - - mmc_udelay(1000); - } - - status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; - HAL_SDMMC_TRACE(1, "CURR STATE:%d\n", status); - if (timeout <= 0) { - return TIMEOUT; - } - if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR) - return SWITCH_ERR; - - return 0; -} - -int mmc_set_blocklen(struct mmc *mmc, int len) { - struct mmc_cmd cmd; - - if (mmc->ddr_mode) - return 0; - - cmd.cmdidx = MMC_CMD_SET_BLOCKLEN; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = len; - - return mmc_send_cmd(mmc, &cmd, NULL); -} - -struct mmc *find_mmc_device(int dev_num) { return &sdmmc_devices[dev_num]; } - -static int mmc_read_blocks(struct mmc *mmc, void *dst, uint32_t start, - uint32_t blkcnt) { - struct mmc_cmd cmd; - struct mmc_data data; - - if (blkcnt > 1) - cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; - else - cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK; - - if (mmc->high_capacity) - cmd.cmdarg = start; - else - cmd.cmdarg = start * mmc->read_bl_len; - - cmd.resp_type = MMC_RSP_R1; - - data.dest = dst; - data.blocks = blkcnt; - data.blocksize = mmc->read_bl_len; - data.flags = MMC_DATA_READ; - - if (mmc_send_cmd(mmc, &cmd, &data)) - return 0; - - if (blkcnt > 1) { - cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_R1b; - if (mmc_send_cmd(mmc, &cmd, NULL)) { - return 0; - } - } - - return blkcnt; -} - -static unsigned long mmc_bread(int dev_num, uint32_t start, uint32_t blkcnt, - void *dst) { - uint32_t cur, blocks_todo = blkcnt; - - if (blkcnt == 0) - return 0; - - struct mmc *mmc = find_mmc_device(dev_num); - if (!mmc) - return 0; - - if ((start + blkcnt) > mmc->block_dev.lba) { - return 0; - } - - if (mmc_set_blocklen(mmc, mmc->read_bl_len)) - return 0; - - do { - cur = (blocks_todo > mmc->cfg->b_max) ? mmc->cfg->b_max : blocks_todo; - if (mmc_read_blocks(mmc, dst, start, cur) != cur) - return 0; - blocks_todo -= cur; - start += cur; - dst += cur * mmc->read_bl_len; - } while (blocks_todo > 0); - - return blkcnt; -} - -static unsigned long mmc_erase_t(struct mmc *mmc, unsigned long start, - uint32_t blkcnt) { - struct mmc_cmd cmd; - unsigned long end; - int err, start_cmd, end_cmd; - - if (mmc->high_capacity) { - end = start + blkcnt - 1; - } else { - end = (start + blkcnt - 1) * mmc->write_bl_len; - start *= mmc->write_bl_len; - } - - if (IS_SD(mmc)) { - start_cmd = SD_CMD_ERASE_WR_BLK_START; - end_cmd = SD_CMD_ERASE_WR_BLK_END; - } else { - start_cmd = MMC_CMD_ERASE_GROUP_START; - end_cmd = MMC_CMD_ERASE_GROUP_END; - } - - cmd.cmdidx = start_cmd; - cmd.cmdarg = start; - cmd.resp_type = MMC_RSP_R1; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - cmd.cmdidx = end_cmd; - cmd.cmdarg = end; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - cmd.cmdidx = MMC_CMD_ERASE; - cmd.cmdarg = SECURE_ERASE; - cmd.resp_type = MMC_RSP_R1b; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - return 0; - -err_out: - // puts("mmc erase failed\n"); - return err; -} - -unsigned long mmc_berase(int dev_num, uint32_t start, uint32_t blkcnt) { - int err = 0; - struct mmc *mmc = find_mmc_device(dev_num); - uint32_t blk = 0, blk_r = 0; - int timeout = 1000; - - if (!mmc) - return -1; - - if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size)) - // printf("\n\nCaution! Your devices Erase group is 0x%x\n" - // "The erase range would be change to " - // "0x" LBAF "~0x" LBAF "\n\n", - // mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), - // ((start + blkcnt + mmc->erase_grp_size) - // & ~(mmc->erase_grp_size - 1)) - 1); - - while (blk < blkcnt) { - blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? mmc->erase_grp_size - : (blkcnt - blk); - err = mmc_erase_t(mmc, start + blk, blk_r); - if (err) - break; - - blk += blk_r; - - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return 0; - } - - return blk; -} - -static unsigned long mmc_write_blocks(struct mmc *mmc, uint32_t start, - uint32_t blkcnt, const void *src) { - struct mmc_cmd cmd; - struct mmc_data data; - int timeout = 1000; - - if ((start + blkcnt) > mmc->block_dev.lba) { - return 0; - } - - if (blkcnt == 0) - return 0; - else if (blkcnt == 1) - cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; - else - cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; - - if (mmc->high_capacity) - cmd.cmdarg = start; - else - cmd.cmdarg = start * mmc->write_bl_len; - - cmd.resp_type = MMC_RSP_R1; - - data.src = src; - data.blocks = blkcnt; - data.blocksize = mmc->write_bl_len; - data.flags = MMC_DATA_WRITE; - - if (mmc_send_cmd(mmc, &cmd, &data)) { - HAL_SDMMC_TRACE(0, "mmc write failed\n"); - return 0; - } - - /* SPI multiblock writes terminate using a special - * token, not a STOP_TRANSMISSION request. - */ - if (!sdmmc_host_is_spi(mmc) && blkcnt > 1) { - cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_R1b; - if (mmc_send_cmd(mmc, &cmd, NULL)) { - HAL_SDMMC_TRACE(0, "mmc fail to send stop cmd\n"); - return 0; - } - } - - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return 0; - - return blkcnt; -} - -unsigned long mmc_bwrite(int dev_num, uint32_t start, uint32_t blkcnt, - const void *src) { - uint32_t cur, blocks_todo = blkcnt; - - struct mmc *mmc = find_mmc_device(dev_num); - if (!mmc) - return 0; - - if (mmc_set_blocklen(mmc, mmc->write_bl_len)) - return 0; - - do { - cur = (blocks_todo > mmc->cfg->b_max) ? mmc->cfg->b_max : blocks_todo; - if (mmc_write_blocks(mmc, start, cur, src) != cur) - return 0; - blocks_todo -= cur; - start += cur; - src += cur * mmc->write_bl_len; - } while (blocks_todo > 0); - - return blkcnt; -} - -static int mmc_go_idle(struct mmc *mmc) { - struct mmc_cmd cmd; - int err; - - mmc_udelay(1000); - - cmd.cmdidx = MMC_CMD_GO_IDLE_STATE; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_NONE; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - mmc_udelay(2000); - - return 0; -} - -static int sd_send_op_cond(struct mmc *mmc) { - int timeout = 1000; - int err; - struct mmc_cmd cmd; - - while (1) { - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SEND_OP_COND; - cmd.resp_type = MMC_RSP_R3; - - /* - * Most cards do not answer if some reserved bits - * in the ocr are set. However, Some controller - * can set bit 7 (reserved for low voltages), but - * how to manage low voltages SD card is not yet - * specified. - */ - cmd.cmdarg = sdmmc_host_is_spi(mmc) ? 0 : (mmc->cfg->voltages & 0xff8000); - - if (mmc->version == SD_VERSION_2) - cmd.cmdarg |= OCR_HCS; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if (cmd.response[0] & OCR_BUSY) - break; - - if (timeout-- <= 0) - return UNUSABLE_ERR; - - mmc_udelay(1000); - } - - if (mmc->version != SD_VERSION_2) - mmc->version = SD_VERSION_1_0; - - if (sdmmc_host_is_spi(mmc)) { /* read OCR for spi */ - cmd.cmdidx = MMC_CMD_SPI_READ_OCR; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } - - mmc->ocr = cmd.response[0]; - - mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); - mmc->rca = 0; - - return 0; -} - -static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg) { - struct mmc_cmd cmd; - int err; - - cmd.cmdidx = MMC_CMD_SEND_OP_COND; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - if (use_arg && !sdmmc_host_is_spi(mmc)) - cmd.cmdarg = OCR_HCS | - (mmc->cfg->voltages & (mmc->ocr & OCR_VOLTAGE_MASK)) | - (mmc->ocr & OCR_ACCESS_MODE); - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - mmc->ocr = cmd.response[0]; - return 0; -} - -static int mmc_send_op_cond(struct mmc *mmc) { - int err, i; - - /* Some cards seem to need this */ - // mmc_go_idle(mmc); - - /* Asking to the card its capabilities */ - for (i = 0; i < 2; i++) { - err = mmc_send_op_cond_iter(mmc, i != 0); - if (err) - return err; - - /* exit if not busy (flag seems to be inverted) */ - if (mmc->ocr & OCR_BUSY) - break; - } - mmc->op_cond_pending = 1; - return 0; -} - -static int mmc_complete_op_cond(struct mmc *mmc) { - struct mmc_cmd cmd; - int err; - - mmc->op_cond_pending = 0; - if (!(mmc->ocr & OCR_BUSY)) { - while (1) { - err = mmc_send_op_cond_iter(mmc, 1); - if (err) - return err; - if (mmc->ocr & OCR_BUSY) - break; - mmc_udelay(100); - } - } - - if (sdmmc_host_is_spi(mmc)) { /* read OCR for spi */ - cmd.cmdidx = MMC_CMD_SPI_READ_OCR; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - mmc->ocr = cmd.response[0]; - } - - mmc->version = MMC_VERSION_UNKNOWN; - - mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); - mmc->rca = 1; - - return 0; -} - -static int mmc_send_ext_csd(struct mmc *mmc, uint8_t *ext_csd) { - struct mmc_cmd cmd; - struct mmc_data data; - int err; - - /* Get the Card Status Register */ - cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - data.dest = (char *)ext_csd; - data.blocks = 1; - data.blocksize = MMC_MAX_BLOCK_LEN; - data.flags = MMC_DATA_READ; - - HAL_SDMMC_TRACE(1, "[%s] start...", __func__); - err = mmc_send_cmd(mmc, &cmd, &data); - HAL_SDMMC_TRACE(2, "[%s] err = %d", __func__, err); - - return err; -} - -static int mmc_switch(struct mmc *mmc, uint8_t set, uint8_t index, - uint8_t value) { - struct mmc_cmd cmd; - int timeout = 1000; - int ret; - - cmd.cmdidx = MMC_CMD_SWITCH; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = - (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (index << 16) | (value << 8); - - ret = mmc_send_cmd(mmc, &cmd, NULL); - - /* Waiting for the ready status */ - if (!ret) - ret = mmc_send_status(mmc, timeout); - - return ret; -} - -static int mmc_change_freq(struct mmc *mmc) { - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, ext_csd, MMC_MAX_BLOCK_LEN); - char cardtype; - int err; - - mmc->card_caps = 0; - - if (sdmmc_host_is_spi(mmc)) - return 0; - - /* Only version 4 supports high-speed */ - if (mmc->version < MMC_VERSION_4) - return 0; - - mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT; - - err = mmc_send_ext_csd(mmc, ext_csd); - - if (err) - return err; - - cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); - - if (err) - return err == SWITCH_ERR ? 0 : err; - - /* Now check to see that it worked */ - err = mmc_send_ext_csd(mmc, ext_csd); - - if (err) - return err; - - /* No high-speed support */ - if (!ext_csd[EXT_CSD_HS_TIMING]) - return 0; - - /* High Speed is set, there are two types: 52MHz and 26MHz */ - if (cardtype & EXT_CSD_CARD_TYPE_52) { - if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V) - mmc->card_caps |= MMC_MODE_DDR_52MHz; - mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; - } else { - mmc->card_caps |= MMC_MODE_HS; - } - - return 0; -} - -static int mmc_set_capacity(struct mmc *mmc, int part_num) { - switch (part_num) { - case 0: - mmc->capacity = mmc->capacity_user; - break; - case 1: - case 2: - mmc->capacity = mmc->capacity_boot; - break; - case 3: - mmc->capacity = mmc->capacity_rpmb; - break; - case 4: - case 5: - case 6: - case 7: - mmc->capacity = mmc->capacity_gp[part_num - 4]; - break; - default: - return -1; - } - - mmc->block_dev.lba = _sdmmc_lldiv(mmc->capacity, mmc->read_bl_len); - - return 0; -} - -int mmc_getcd(struct mmc *mmc) { - int cd; - - cd = board_mmc_getcd(mmc); - - if (cd < 0) { - if (mmc->cfg->ops->getcd) - cd = mmc->cfg->ops->getcd(mmc); - else - cd = 1; - } - - return cd; -} - -static int sd_switch(struct mmc *mmc, int mode, int group, uint8_t value, - uint8_t *resp) { - struct mmc_cmd cmd; - struct mmc_data data; - - /* Switch the frequency */ - cmd.cmdidx = SD_CMD_SWITCH_FUNC; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = (mode << 31) | 0xffffff; - cmd.cmdarg &= ~(0xf << (group * 4)); - cmd.cmdarg |= value << (group * 4); - - data.dest = (char *)resp; - data.blocksize = 64; - data.blocks = 1; - data.flags = MMC_DATA_READ; - - hal_sdmmc_delay(1); - - return mmc_send_cmd(mmc, &cmd, &data); -} - -static int sd_change_freq(struct mmc *mmc) { - int err; - struct mmc_cmd cmd; - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint32_t, scr, 2); - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint32_t, switch_status, 16); - struct mmc_data data; - int timeout; - - mmc->card_caps = 0; - - if (sdmmc_host_is_spi(mmc)) - return 0; - - /* Read the SCR to find out if this card supports higher speeds */ - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SEND_SCR; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - timeout = 3; - -retry_scr: - data.dest = (char *)scr; - data.blocksize = 8; - data.blocks = 1; - data.flags = MMC_DATA_READ; - - err = mmc_send_cmd(mmc, &cmd, &data); - - if (err) { - if (timeout--) - goto retry_scr; - - return err; - } - - mmc->scr[0] = _sdmmc_be32_to_cpu(scr[0]); - mmc->scr[1] = _sdmmc_be32_to_cpu(scr[1]); - - switch ((mmc->scr[0] >> 24) & 0xf) { - case 0: - mmc->version = SD_VERSION_1_0; - break; - case 1: - mmc->version = SD_VERSION_1_10; - break; - case 2: - mmc->version = SD_VERSION_2; - if ((mmc->scr[0] >> 15) & 0x1) - mmc->version = SD_VERSION_3; - break; - default: - mmc->version = SD_VERSION_1_0; - break; - } - - if (mmc->scr[0] & SD_DATA_4BIT) - mmc->card_caps |= MMC_MODE_4BIT; - - /* Version 1.0 doesn't support switching */ - if (mmc->version == SD_VERSION_1_0) - return 0; - - timeout = 4; - while (timeout--) { - err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1, (uint8_t *)switch_status); - - if (err) - return err; - - /* The high-speed function is busy. Try again */ - if (!(_sdmmc_be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY)) - break; - } - - /* If high-speed isn't supported, we return */ - if (!(_sdmmc_be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)) - return 0; - - /* - * If the host doesn't support SD_HIGHSPEED, do not switch card to - * HIGHSPEED mode even if the card support SD_HIGHSPPED. - * This can avoid furthur problem when the card runs in different - * mode between the host. - */ - if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) && - (mmc->cfg->host_caps & MMC_MODE_HS))) - return 0; - - err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (uint8_t *)switch_status); - - if (err) - return err; - - if ((_sdmmc_be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000) - mmc->card_caps |= MMC_MODE_HS; - - return 0; -} - -/* frequency bases */ -/* divided by 10 to be nice to platforms without floating point */ -static const int fbase[] = { - 10000, - 100000, - 1000000, - 10000000, -}; - -/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice - * to platforms without floating point. - */ -static const int multipliers[] = { - 0, /* reserved */ - 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, -}; - -static void mmc_set_ios(struct mmc *mmc) { - if (mmc->cfg->ops->set_ios) - mmc->cfg->ops->set_ios(mmc); -} - -void mmc_set_clock(struct mmc *mmc, uint32_t clock) { - if (clock > mmc->cfg->f_max) - clock = mmc->cfg->f_max; - - if (clock < mmc->cfg->f_min) - clock = mmc->cfg->f_min; - - mmc->clock = clock; - - mmc_set_ios(mmc); -} - -static void mmc_set_bus_width(struct mmc *mmc, uint32_t width) { - mmc->bus_width = width; - - mmc_set_ios(mmc); -} - -static int mmc_startup(struct mmc *mmc) { - int err, i; - uint32_t mult, freq; - uint32_t cmult, csize, capacity; - struct mmc_cmd cmd; - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, ext_csd, MMC_MAX_BLOCK_LEN); - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, test_csd, MMC_MAX_BLOCK_LEN); - int timeout = 1000; - bool has_parts = false; - bool part_completed; - -#ifdef CONFIG_MMC_SPI_CRC_ON - if (sdmmc_host_is_spi(mmc)) { /* enable CRC check for spi */ - cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 1; - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } -#endif - - /* Put the Card in Identify Mode */ - cmd.cmdidx = sdmmc_host_is_spi(mmc) - ? MMC_CMD_SEND_CID - : MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */ - cmd.resp_type = MMC_RSP_R2; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - memcpy(mmc->cid, cmd.response, 16); - - /* - * For MMC cards, set the Relative Address. - * For SD cards, get the Relatvie Address. - * This also puts the cards into Standby State - */ - if (!sdmmc_host_is_spi(mmc)) { /* cmd not supported in spi */ - cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR; - cmd.cmdarg = mmc->rca << 16; - cmd.resp_type = MMC_RSP_R6; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if (IS_SD(mmc)) - mmc->rca = (cmd.response[0] >> 16) & 0xffff; - } - - /* Get the Card-Specific Data */ - cmd.cmdidx = MMC_CMD_SEND_CSD; - cmd.resp_type = MMC_RSP_R2; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - /* Waiting for the ready status */ - mmc_send_status(mmc, timeout); - - if (err) - return err; - - mmc->csd[0] = cmd.response[0]; - mmc->csd[1] = cmd.response[1]; - mmc->csd[2] = cmd.response[2]; - mmc->csd[3] = cmd.response[3]; - - if (mmc->version == MMC_VERSION_UNKNOWN) { - int version = (cmd.response[0] >> 26) & 0xf; - - switch (version) { - case 0: - mmc->version = MMC_VERSION_1_2; - break; - case 1: - mmc->version = MMC_VERSION_1_4; - break; - case 2: - mmc->version = MMC_VERSION_2_2; - break; - case 3: - mmc->version = MMC_VERSION_3; - break; - case 4: - mmc->version = MMC_VERSION_4; - break; - default: - mmc->version = MMC_VERSION_1_2; - break; - } - } - - /* divide frequency by 10, since the mults are 10x bigger */ - freq = fbase[(cmd.response[0] & 0x7)]; - mult = multipliers[((cmd.response[0] >> 3) & 0xf)]; - - mmc->tran_speed = freq * mult; - - mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1); - mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf); - - if (IS_SD(mmc)) - mmc->write_bl_len = mmc->read_bl_len; - else - mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf); - - if (mmc->high_capacity) { - csize = (mmc->csd[1] & 0x3f) << 16 | (mmc->csd[2] & 0xffff0000) >> 16; - cmult = 8; - } else { - csize = (mmc->csd[1] & 0x3ff) << 2 | (mmc->csd[2] & 0xc0000000) >> 30; - cmult = (mmc->csd[2] & 0x00038000) >> 15; - } - - mmc->capacity_user = (csize + 1) << (cmult + 2); - mmc->capacity_user *= mmc->read_bl_len; - mmc->capacity_boot = 0; - mmc->capacity_rpmb = 0; - for (i = 0; i < 4; i++) - mmc->capacity_gp[i] = 0; - - if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) - mmc->read_bl_len = MMC_MAX_BLOCK_LEN; - - if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) - mmc->write_bl_len = MMC_MAX_BLOCK_LEN; - - if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) { - cmd.cmdidx = MMC_CMD_SET_DSR; - cmd.cmdarg = (mmc->dsr & 0xffff) << 16; - cmd.resp_type = MMC_RSP_NONE; - if (mmc_send_cmd(mmc, &cmd, NULL)) { - HAL_SDMMC_TRACE(0, "MMC: SET_DSR failed\n"); - } - } - - /* Select the card, and put it into Transfer Mode */ - if (!sdmmc_host_is_spi(mmc)) { /* cmd not supported in spi */ - cmd.cmdidx = MMC_CMD_SELECT_CARD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } - - /* - * For SD, its erase group is always one sector - */ - mmc->erase_grp_size = 1; - mmc->part_config = MMCPART_NOAVAILABLE; - if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { - /* check ext_csd version and capacity */ - err = mmc_send_ext_csd(mmc, ext_csd); - if (err) - return err; - if (ext_csd[EXT_CSD_REV] >= 2) { - /* - * According to the JEDEC Standard, the value of - * ext_csd's capacity is valid if the value is more - * than 2GB - */ - capacity = ext_csd[EXT_CSD_SEC_CNT] << 0 | - ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | - ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | - ext_csd[EXT_CSD_SEC_CNT + 3] << 24; - capacity *= MMC_MAX_BLOCK_LEN; - if ((capacity >> 20) > 2 * 1024) - mmc->capacity_user = capacity; - } - - switch (ext_csd[EXT_CSD_REV]) { - case 1: - mmc->version = MMC_VERSION_4_1; - break; - case 2: - mmc->version = MMC_VERSION_4_2; - break; - case 3: - mmc->version = MMC_VERSION_4_3; - break; - case 5: - mmc->version = MMC_VERSION_4_41; - break; - case 6: - mmc->version = MMC_VERSION_4_5; - break; - case 7: - mmc->version = MMC_VERSION_5_0; - break; - } - - /* The partition data may be non-zero but it is only - * effective if PARTITION_SETTING_COMPLETED is set in - * EXT_CSD, so ignore any data if this bit is not set, - * except for enabling the high-capacity group size - * definition (see below). */ - part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] & - EXT_CSD_PARTITION_SETTING_COMPLETED); - - /* store the partition info of emmc */ - mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT]; - if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || - ext_csd[EXT_CSD_BOOT_MULT]) - mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; - if (part_completed && - (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT)) - mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE]; - - mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17; - - mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17; - - for (i = 0; i < 4; i++) { - int idx = EXT_CSD_GP_SIZE_MULT + i * 3; - uint32_t mult = - (ext_csd[idx + 2] << 16) + (ext_csd[idx + 1] << 8) + ext_csd[idx]; - if (mult) - has_parts = true; - if (!part_completed) - continue; - mmc->capacity_gp[i] = mult; - mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; - mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - mmc->capacity_gp[i] <<= 19; - } - - if (part_completed) { - mmc->enh_user_size = (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) + - (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) + - ext_csd[EXT_CSD_ENH_SIZE_MULT]; - mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; - mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - mmc->enh_user_size <<= 19; - mmc->enh_user_start = (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) + - (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) + - (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) + - ext_csd[EXT_CSD_ENH_START_ADDR]; - if (mmc->high_capacity) - mmc->enh_user_start <<= 9; - } - - /* - * Host needs to enable ERASE_GRP_DEF bit if device is - * partitioned. This bit will be lost every time after a reset - * or power off. This will affect erase size. - */ - if (part_completed) - has_parts = true; - if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) && - (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) - has_parts = true; - if (has_parts) { - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1); - - if (err) - return err; - else - ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1; - } - - if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) { - /* Read out group size from ext_csd */ - mmc->erase_grp_size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024; - /* - * if high capacity and partition setting completed - * SEC_COUNT is valid even if it is smaller than 2 GiB - * JEDEC Standard JESD84-B45, 6.2.4 - */ - if (mmc->high_capacity && part_completed) { - capacity = (ext_csd[EXT_CSD_SEC_CNT]) | - (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) | - (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) | - (ext_csd[EXT_CSD_SEC_CNT + 3] << 24); - capacity *= MMC_MAX_BLOCK_LEN; - mmc->capacity_user = capacity; - } - } else { - /* Calculate the group size from the csd value. */ - int erase_gsz, erase_gmul; - erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10; - erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; - mmc->erase_grp_size = (erase_gsz + 1) * (erase_gmul + 1); - } - - mmc->hc_wp_grp_size = 1024 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * - ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - - mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; - } - - err = mmc_set_capacity(mmc, mmc->part_num); - if (err) - return err; - - if (IS_SD(mmc)) - err = sd_change_freq(mmc); - else - err = mmc_change_freq(mmc); - - if (err) - return err; - - /* Restrict card's capabilities by what the host can do */ - mmc->card_caps &= mmc->cfg->host_caps; - - if (IS_SD(mmc)) { -#ifdef __BUS_WIDTH_SUPPORT_4BIT__ - if (mmc->card_caps & MMC_MODE_4BIT) { - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 2; - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - mmc_set_bus_width(mmc, 4); - } -#endif - if (mmc->card_caps & MMC_MODE_HS) - mmc->tran_speed = 50000000; - else - mmc->tran_speed = 25000000; - } else if (mmc->version >= MMC_VERSION_4) { - /* Only version 4 of MMC supports wider bus widths */ - int idx; - - /* An array of possible bus widths in order of preference */ - static unsigned ext_csd_bits[] = { - EXT_CSD_DDR_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_4, EXT_CSD_BUS_WIDTH_8, - EXT_CSD_BUS_WIDTH_4, EXT_CSD_BUS_WIDTH_1, - }; - - /* An array to map CSD bus widths to host cap bits */ - static unsigned ext_to_hostcaps[] = { - [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz | MMC_MODE_4BIT, - [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz | MMC_MODE_8BIT, - [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT, - [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT, - }; - - /* An array to map chosen bus width to an integer */ - static unsigned widths[] = { - 8, 4, 8, 4, 1, - }; - - for (idx = 0; idx < ARRAY_SIZE(ext_csd_bits); idx++) { - unsigned int extw = ext_csd_bits[idx]; - unsigned int caps = ext_to_hostcaps[extw]; - - /* - * If the bus width is still not changed, - * don't try to set the default again. - * Otherwise, recover from switch attempts - * by switching to 1-bit bus width. - */ - if (extw == EXT_CSD_BUS_WIDTH_1 && mmc->bus_width == 1) { - err = 0; - break; - } - - /* - * Check to make sure the card and controller support - * these capabilities - */ - if ((mmc->card_caps & caps) != caps) - continue; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, extw); - - if (err) - continue; - - mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0; - mmc_set_bus_width(mmc, widths[idx]); - - err = mmc_send_ext_csd(mmc, test_csd); - - if (err) - continue; - - /* Only compare read only fields */ - if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] == - test_csd[EXT_CSD_PARTITIONING_SUPPORT] && - ext_csd[EXT_CSD_HC_WP_GRP_SIZE] == test_csd[EXT_CSD_HC_WP_GRP_SIZE] && - ext_csd[EXT_CSD_REV] == test_csd[EXT_CSD_REV] && - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] == - test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] && - memcmp(&ext_csd[EXT_CSD_SEC_CNT], &test_csd[EXT_CSD_SEC_CNT], 4) == 0) - break; - else - err = SWITCH_ERR; - } - - if (err) - return err; - - if (mmc->card_caps & MMC_MODE_HS) { - if (mmc->card_caps & MMC_MODE_HS_52MHz) - mmc->tran_speed = 52000000; - else - mmc->tran_speed = 26000000; - } - } - - mmc_set_clock(mmc, mmc->tran_speed); - - /* Fix the block length for DDR mode */ - if (mmc->ddr_mode) { - mmc->read_bl_len = MMC_MAX_BLOCK_LEN; - mmc->write_bl_len = MMC_MAX_BLOCK_LEN; - } - - /* fill in device description */ - mmc->block_dev.lun = 0; - mmc->block_dev.type = 0; - mmc->block_dev.blksz = mmc->read_bl_len; - // mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz); - mmc->block_dev.lba = _sdmmc_lldiv(mmc->capacity, mmc->read_bl_len); -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x", - (unsigned)(mmc->cid[0] >> 24), (unsigned)(mmc->cid[2] & 0xffff), - (unsigned)((mmc->cid[3] >> 16) & 0xffff)); - sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", (char)mmc->cid[0], - (char)(mmc->cid[1] >> 24), (char)(mmc->cid[1] >> 16), - (char)(mmc->cid[1] >> 8), (char)mmc->cid[1], - (char)(mmc->cid[2] >> 24)); - sprintf(mmc->block_dev.revision, "%d.%d", - (unsigned)((mmc->cid[2] >> 20) & 0xf), - (unsigned)((mmc->cid[2] >> 16) & 0xf)); -#else - mmc->block_dev.vendor[0] = 0; - mmc->block_dev.product[0] = 0; - mmc->block_dev.revision[0] = 0; -#endif - - HAL_SDMMC_TRACE(1, "%s done\n", __func__); - return 0; -} - -static int mmc_send_if_cond(struct mmc *mmc) { - struct mmc_cmd cmd; - int err; - - cmd.cmdidx = SD_CMD_SEND_IF_COND; - /* We set the bit if the host supports voltages between 2.7 and 3.6 V */ - cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa; - cmd.resp_type = MMC_RSP_R7; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if ((cmd.response[0] & 0xff) != 0xaa) - return UNUSABLE_ERR; - else - mmc->version = SD_VERSION_2; - - return 0; -} - -struct mmc *mmc_create(int id, const struct mmc_config *cfg, void *priv) { - struct mmc *mmc; - - /* quick validation */ - if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL || - cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0) - return NULL; - - mmc = &sdmmc_devices[id]; - if (mmc == NULL) - return NULL; - - mmc->cfg = cfg; - mmc->priv = priv; - - /* the following chunk was mmc_register() */ - - /* Setup dsr related values */ - mmc->dsr_imp = 0; - mmc->dsr = 0xffffffff; - /* Setup the universal parts of the block interface just once */ - mmc->block_dev.removable = 1; - /* setup initial part type */ - mmc->block_dev.part_type = mmc->cfg->part_type; - - return mmc; -} - -int mmc_start_init(struct mmc *mmc) { - int err; - - /* we pretend there's no card when init is NULL */ - if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) { - mmc->has_init = 0; - HAL_SDMMC_TRACE(1, "%s : no card present\n", __func__); - return NO_CARD_ERR; - } - - if (mmc->has_init) - return 0; - - /* made sure it's not NULL earlier */ - err = mmc->cfg->ops->init(mmc); - HAL_SDMMC_TRACE(1, "%s : init done\n", __func__); - - if (err) - return err; - - mmc->ddr_mode = 0; - mmc_set_bus_width(mmc, 1); - mmc_set_clock(mmc, 1); - - /* Reset the Card */ - err = mmc_go_idle(mmc); - HAL_SDMMC_TRACE(1, "%s : idle done\n", __func__); - - if (err) - return err; - - /* The internal partition reset to user partition(0) at every CMD0*/ - mmc->part_num = 0; - - /* Test for SD version 2 */ - err = mmc_send_if_cond(mmc); - - /* Now try to get the SD card's operating condition */ - err = sd_send_op_cond(mmc); - - /* If the command timed out, we check for an MMC card */ - if (err == TIMEOUT) { - err = mmc_send_op_cond(mmc); - - if (err) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - HAL_SDMMC_TRACE(1, "%s : Card did not respond to voltage select!\n", - __func__); -#endif - return UNUSABLE_ERR; - } - } - - if (!err) - mmc->init_in_progress = 1; - - HAL_SDMMC_TRACE(1, "%s : done\n", __func__); - return err; -} - -static int mmc_complete_init(struct mmc *mmc) { - int err = 0; - - mmc->init_in_progress = 0; - if (mmc->op_cond_pending) - err = mmc_complete_op_cond(mmc); - - if (!err) - err = mmc_startup(mmc); - if (err) - mmc->has_init = 0; - else - mmc->has_init = 1; - return err; -} - -void hal_sdmmc_irq_handler(void) { - uint32_t cdetect, mask; - struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - - if (mask & SDMMCIP_REG_INTMSK_CD) { - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CD); - cdetect = sdmmcip_readl(host, SDMMCIP_REG_CDETECT); - HAL_SDMMC_TRACE(3, "%s cdetect:%d mask:%x\n", __func__, cdetect, mask); - if (sdmmc_detected_callback) - sdmmc_detected_callback(cdetect & 0x01 ? 0 : 1); - } -} - -int hal_sdmmc_enable_detecter(enum HAL_SDMMC_ID_T id, void (*cb)(uint8_t)) { - uint32_t ctrl; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_TRACE(1, "%s\n", __func__); - - sdmmc_detected_callback = cb; - - host = &sdmmc_host[id]; - host->ioaddr = (void *)sdmmc_ip_base[id]; - - if (!sdmmcip_wait_reset(host, SDMMCIP_REG_RESET_ALL)) { - HAL_SDMMC_TRACE(2, "%s[%d] Fail-reset!!\n", __func__, __LINE__); - return -1; - } - - host->detect_enb = true; - - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, 0xFFFFFFFF); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, SDMMCIP_REG_INTMSK_CD); - - ctrl = SDMMCIP_REG_INT_EN; - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - NVIC_SetVector(SDMMC_IRQn, (uint32_t)hal_sdmmc_irq_handler); - NVIC_SetPriority(SDMMC_IRQn, IRQ_PRIORITY_NORMAL); - NVIC_ClearPendingIRQ(SDMMC_IRQn); - NVIC_EnableIRQ(SDMMC_IRQn); - return 0; -} - -void hal_sdmmc_disable_detecter(enum HAL_SDMMC_ID_T id) { - uint32_t ctrl = 0; - struct sdmmcip_host *host = NULL; - host = &sdmmc_host[id]; - - NVIC_DisableIRQ(SDMMC_IRQn); - NVIC_SetVector(SDMMC_IRQn, (uint32_t)NULL); - - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, 0xFFFFFFFF); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, ~SDMMCIP_REG_INTMSK_ALL); - - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl |= (SDMMCIP_REG_DMA_EN); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - host->detect_enb = false; - sdmmc_detected_callback = NULL; -} - -int mmc_init(struct mmc *mmc) { - int err = 0; - if (mmc->has_init) - return 0; - - if (!mmc->init_in_progress) - err = mmc_start_init(mmc); - - if (!err) - err = mmc_complete_init(mmc); - - return err; -} - -/* hal api */ -static void hal_sdmmc_delay(uint32_t ms) { - if (sdmmc_delay) { - sdmmc_delay(ms); - } else { - hal_sys_timer_delay(MS_TO_TICKS(ms)); - } -} - -HAL_SDMMC_DELAY_FUNC hal_sdmmc_set_delay_func(HAL_SDMMC_DELAY_FUNC new_func) { - HAL_SDMMC_DELAY_FUNC old_func = sdmmc_delay; - sdmmc_delay = new_func; - return old_func; -} - -int32_t hal_sdmmc_open(enum HAL_SDMMC_ID_T id) { - int32_t ret = 0; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - hal_cmu_sdmmc_set_freq(HAL_CMU_PERIPH_FREQ_52M); - - hal_cmu_clock_enable(HAL_CMU_MOD_O_SDMMC); - hal_cmu_clock_enable(HAL_CMU_MOD_H_SDMMC); - hal_cmu_reset_clear(HAL_CMU_MOD_O_SDMMC); - hal_cmu_reset_clear(HAL_CMU_MOD_H_SDMMC); - - host = &sdmmc_host[id]; - - host->ioaddr = (void *)sdmmc_ip_base[id]; - // host->buswidth = 4; - host->buswidth = 1; - host->clksel = 0; - host->bus_hz = _SDMMC_CLOCK; - host->dev_index = id; - /* fifo threshold : MSIZE 0 - 1 transter, rx water mark 0 - greater than 0 - * word triiger dma-req, tx water mark 1 - less than or equal 1 word triiger - * dma-req */ - host->fifoth_val = MSIZE(0) | RX_WMARK(0) | TX_WMARK(1); - - host->cfg.ops = &sdmmcip_ops; - host->cfg.f_min = 400000; - // host->cfg.f_min = 1000000; - // host->cfg.f_min = 25000000; - // host->cfg.f_min = 52000000; - // host->cfg.f_max = 1000000; - host->cfg.f_max = 26000000; - // host->cfg.f_max = 52000000; - host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - host->cfg.host_caps = 0; - -#ifdef HAL_SDMMC_USE_DMA - host->tx_dma_handler = sdmmcip_ext_dma_irq_handlers[id * 2]; - host->rx_dma_handler = sdmmcip_ext_dma_irq_handlers[id * 2 + 1]; -#endif - - if (host->buswidth == 8) { - host->cfg.host_caps |= MMC_MODE_8BIT; - host->cfg.host_caps &= ~MMC_MODE_4BIT; - } else if (host->buswidth == 4) { - host->cfg.host_caps |= MMC_MODE_4BIT; - host->cfg.host_caps &= ~MMC_MODE_8BIT; - } else { - // host->cfg.host_caps &= ~MMC_MODE_4BIT; - host->cfg.host_caps |= MMC_MODE_4BIT; - host->cfg.host_caps &= ~MMC_MODE_8BIT; - } - - host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz; - - host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - host->mmc = mmc_create(host->dev_index, &host->cfg, host); - - ret = mmc_init(host->mmc); - - hal_sdmmc_dump(HAL_SDMMC_ID_0); - - return ret; -} -uint32_t hal_sdmmc_read_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, - uint32_t block_count, uint8_t *dest) { - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - return mmc_bread(id, start_block, block_count, dest); -} - -uint32_t hal_sdmmc_write_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, - uint32_t block_count, uint8_t *src) { - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - return mmc_bwrite(id, start_block, block_count, src); -} - -void hal_sdmmc_close(enum HAL_SDMMC_ID_T id) { - struct sdmmcip_host *host = NULL; - - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - HAL_SDMMC_TRACE(1, "%s\n", __func__); - - host = &sdmmc_host[id]; - while (host->mmc->init_in_progress) - hal_sdmmc_delay(1); - - host->mmc->has_init = 0; - - hal_cmu_reset_set(HAL_CMU_MOD_H_SDMMC); - hal_cmu_reset_set(HAL_CMU_MOD_O_SDMMC); - hal_cmu_clock_disable(HAL_CMU_MOD_H_SDMMC); - hal_cmu_clock_disable(HAL_CMU_MOD_O_SDMMC); -} - -void hal_sdmmc_dump(enum HAL_SDMMC_ID_T id) { - struct mmc *mmc = NULL; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - host = &sdmmc_host[id]; - mmc = host->mmc; - - HAL_SDMMC_TRACE(0, "-----------hal_sdmmc_dump-------------\n"); - HAL_SDMMC_TRACE(1, " [sdmmc id] : %d\n", id); - HAL_SDMMC_TRACE(1, " [io register address] : 0x%x\n", - sdmmc_ip_base[id]); - HAL_SDMMC_TRACE(1, " [ddr mode] : %d\n", - mmc->ddr_mode); - switch (mmc->version) { - case SD_VERSION_1_0: - HAL_SDMMC_TRACE(0, - " [version] : SD_VERSION_1_0\n"); - break; - case SD_VERSION_1_10: - HAL_SDMMC_TRACE(0, - " [version] : SD_VERSION_1_10\n"); - break; - case SD_VERSION_2: - HAL_SDMMC_TRACE(0, " [version] : SD_VERSION_2\n"); - break; - case SD_VERSION_3: - HAL_SDMMC_TRACE(0, " [version] : SD_VERSION_3\n"); - break; - case MMC_VERSION_5_0: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_5_0\n"); - break; - case MMC_VERSION_4_5: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_5\n"); - break; - case MMC_VERSION_4_41: - HAL_SDMMC_TRACE( - 0, " [version] : MMC_VERSION_4_41\n"); - break; - case MMC_VERSION_4_3: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_3\n"); - break; - case MMC_VERSION_4_2: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_2\n"); - break; - case MMC_VERSION_4_1: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_1\n"); - break; - case MMC_VERSION_4: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4\n"); - break; - case MMC_VERSION_3: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_3\n"); - break; - case MMC_VERSION_2_2: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_2_2\n"); - break; - case MMC_VERSION_1_4: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_1_4\n"); - break; - case MMC_VERSION_1_2: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_1_2\n"); - break; - default: - HAL_SDMMC_TRACE(0, - " [version] : unkown version\n"); - break; - } - HAL_SDMMC_TRACE(1, " [is SD card] : 0x%x\n", - IS_SD(mmc)); - HAL_SDMMC_TRACE(1, " [high_capacity] : 0x%x\n", - mmc->high_capacity); - HAL_SDMMC_TRACE(1, " [bus_width] : 0x%x\n", - mmc->bus_width); - HAL_SDMMC_TRACE(1, " [clock] : %d\n", mmc->clock); - HAL_SDMMC_TRACE(1, " [card_caps] : 0x%x\n", - mmc->card_caps); - HAL_SDMMC_TRACE(1, " [ocr] : 0x%x\n", mmc->ocr); - HAL_SDMMC_TRACE(1, " [dsr] : 0x%x\n", mmc->dsr); - HAL_SDMMC_TRACE(1, " [capacity_user/1024] : %d(K)\n", - (uint32_t)(mmc->capacity_user / 1024)); - HAL_SDMMC_TRACE(1, " [capacity_user/1024/1024] : %d(M)\n", - (uint32_t)(mmc->capacity_user / 1024 / 1024)); - HAL_SDMMC_TRACE(1, " [capacity_user/1024/1024/1024] : %d(G)\n", - (uint32_t)(mmc->capacity_user / 1024 / 1024 / 1024)); - HAL_SDMMC_TRACE(1, " [read_bl_len] : %d\n", - mmc->read_bl_len); - HAL_SDMMC_TRACE(1, " [write_bl_len] : %d\n", - mmc->write_bl_len); - HAL_SDMMC_TRACE(0, "--------------------------------------\n"); -} -void hal_sdmmc_info(enum HAL_SDMMC_ID_T id, uint32_t *sector_count, - uint32_t *sector_size) { - struct mmc *mmc = NULL; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - host = &sdmmc_host[id]; - mmc = host->mmc; - - if (sector_size) { - *sector_size = mmc->read_bl_len; - HAL_SDMMC_TRACE(1, "[sdmmc] sector_size %d\n", *sector_size); - } - if (sector_count) { - if (mmc->read_bl_len != 0) - *sector_count = mmc->capacity_user / mmc->read_bl_len; - else - *sector_count = 0; - HAL_SDMMC_TRACE(1, "[sdmmc] sector_count %d\n", *sector_count); - } -} - -#endif // CHIP_HAS_SDMMC diff --git a/platform/hal/hal_sdmmc.h b/platform/hal/hal_sdmmc.h deleted file mode 100644 index 5c64fb4..0000000 --- a/platform/hal/hal_sdmmc.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef _HAL_SDMMC_H_ -#define _HAL_SDMMC_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" - -enum HAL_SDMMC_ID_T { - HAL_SDMMC_ID_0 = 0, - HAL_SDMMC_ID_NUM, -}; - -typedef void (*HAL_SDMMC_DELAY_FUNC)(uint32_t ms); - -/* hal api */ -HAL_SDMMC_DELAY_FUNC hal_sdmmc_set_delay_func(HAL_SDMMC_DELAY_FUNC new_func); -int32_t hal_sdmmc_open(enum HAL_SDMMC_ID_T id); -void hal_sdmmc_info(enum HAL_SDMMC_ID_T id, uint32_t *sector_count, uint32_t *sector_size); -uint32_t hal_sdmmc_read_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* dest); -uint32_t hal_sdmmc_write_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* src); -void hal_sdmmc_close(enum HAL_SDMMC_ID_T id); -void hal_sdmmc_dump(enum HAL_SDMMC_ID_T id); -int hal_sdmmc_enable_detecter(enum HAL_SDMMC_ID_T id,void (* cb)(uint8_t)); - -#ifdef __cplusplus -} -#endif - -#endif /* _HAL_SDMMC_H_ */ diff --git a/platform/hal/reg_sdmmcip.h b/platform/hal/reg_sdmmcip.h deleted file mode 100644 index cd69b0a..0000000 --- a/platform/hal/reg_sdmmcip.h +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __SDMMCIP_REG_HW_H -#define __SDMMCIP_REG_HW_H - -#include "plat_types.h" - -#define SDMMCIP_REG_CTRL 0x000 -#define SDMMCIP_REG_PWREN 0x004 -#define SDMMCIP_REG_CLKDIV 0x008 -#define SDMMCIP_REG_CLKSRC 0x00C -#define SDMMCIP_REG_CLKENA 0x010 -#define SDMMCIP_REG_TMOUT 0x014 -#define SDMMCIP_REG_CTYPE 0x018 -#define SDMMCIP_REG_BLKSIZ 0x01C -#define SDMMCIP_REG_BYTCNT 0x020 -#define SDMMCIP_REG_INTMASK 0x024 -#define SDMMCIP_REG_CMDARG 0x028 -#define SDMMCIP_REG_CMD 0x02C -#define SDMMCIP_REG_RESP0 0x030 -#define SDMMCIP_REG_RESP1 0x034 -#define SDMMCIP_REG_RESP2 0x038 -#define SDMMCIP_REG_RESP3 0x03C -#define SDMMCIP_REG_MINTSTS 0x040 -#define SDMMCIP_REG_RINTSTS 0x044 -#define SDMMCIP_REG_STATUS 0x048 -#define SDMMCIP_REG_FIFOTH 0x04C -#define SDMMCIP_REG_CDETECT 0x050 -#define SDMMCIP_REG_WRTPRT 0x054 -#define SDMMCIP_REG_GPIO 0x058 -#define SDMMCIP_REG_TCMCNT 0x05C -#define SDMMCIP_REG_TBBCNT 0x060 -#define SDMMCIP_REG_DEBNCE 0x064 -#define SDMMCIP_REG_USRID 0x068 -#define SDMMCIP_REG_VERID 0x06C -#define SDMMCIP_REG_HCON 0x070 -#define SDMMCIP_REG_UHS_REG 0x074 -#define SDMMCIP_REG_RESET_CARD 0x078 -#define SDMMCIP_REG_BMOD 0x080 -#define SDMMCIP_REG_PLDMND 0x084 -#define SDMMCIP_REG_DBADDR 0x088 -#define SDMMCIP_REG_IDSTS 0x08C -#define SDMMCIP_REG_IDINTEN 0x090 -#define SDMMCIP_REG_DSCADDR 0x094 -#define SDMMCIP_REG_BUFADDR 0x098 -#define SDMMCIP_REG_DATA 0x200 - -/* Interrupt Mask register */ -#define SDMMCIP_REG_INTMSK_ALL 0xffffffff -#define SDMMCIP_REG_INTMSK_CD (1 << 0) -#define SDMMCIP_REG_INTMSK_RE (1 << 1) -#define SDMMCIP_REG_INTMSK_CDONE (1 << 2) -#define SDMMCIP_REG_INTMSK_DTO (1 << 3) -#define SDMMCIP_REG_INTMSK_TXDR (1 << 4) -#define SDMMCIP_REG_INTMSK_RXDR (1 << 5) -#define SDMMCIP_REG_INTMSK_DCRC (1 << 7) -#define SDMMCIP_REG_INTMSK_RTO (1 << 8) -#define SDMMCIP_REG_INTMSK_DRTO (1 << 9) -#define SDMMCIP_REG_INTMSK_HTO (1 << 10) -#define SDMMCIP_REG_INTMSK_FRUN (1 << 11) -#define SDMMCIP_REG_INTMSK_HLE (1 << 12) -#define SDMMCIP_REG_INTMSK_SBE (1 << 13) -#define SDMMCIP_REG_INTMSK_ACD (1 << 14) -#define SDMMCIP_REG_INTMSK_EBE (1 << 15) - -/* Raw interrupt Regsiter */ -#define SDMMCIP_REG_DATA_ERR (SDMMCIP_REG_INTMSK_EBE | SDMMCIP_REG_INTMSK_SBE | SDMMCIP_REG_INTMSK_HLE |\ - SDMMCIP_REG_INTMSK_FRUN | SDMMCIP_REG_INTMSK_EBE | SDMMCIP_REG_INTMSK_DCRC) -#define SDMMCIP_REG_DATA_TOUT (SDMMCIP_REG_INTMSK_HTO | SDMMCIP_REG_INTMSK_DRTO) -/* CTRL register */ -#define SDMMCIP_REG_CTRL_RESET (1 << 0) -#define SDMMCIP_REG_CTRL_FIFO_RESET (1 << 1) -#define SDMMCIP_REG_CTRL_DMA_RESET (1 << 2) -#define SDMMCIP_REG_INT_EN (1 << 4) -#define SDMMCIP_REG_DMA_EN (1 << 5) -#define SDMMCIP_REG_CTRL_SEND_AS_CCSD (1 << 10) -#define SDMMCIP_REG_IDMAC_EN (1 << 25) -#define SDMMCIP_REG_RESET_ALL (SDMMCIP_REG_CTRL_RESET | SDMMCIP_REG_CTRL_FIFO_RESET |\ - SDMMCIP_REG_CTRL_DMA_RESET) - -/* CMD register */ -#define SDMMCIP_REG_CMD_RESP_EXP (1 << 6) -#define SDMMCIP_REG_CMD_RESP_LENGTH (1 << 7) -#define SDMMCIP_REG_CMD_CHECK_CRC (1 << 8) -#define SDMMCIP_REG_CMD_DATA_EXP (1 << 9) -#define SDMMCIP_REG_CMD_RW (1 << 10) -#define SDMMCIP_REG_CMD_SEND_STOP (1 << 12) -#define SDMMCIP_REG_CMD_ABORT_STOP (1 << 14) -#define SDMMCIP_REG_CMD_PRV_DAT_WAIT (1 << 13) -#define SDMMCIP_REG_CMD_UPD_CLK (1 << 21) -#define SDMMCIP_REG_CMD_USE_HOLD_REG (1 << 29) -#define SDMMCIP_REG_CMD_START (1 << 31) - -/* CLKENA register */ -#define SDMMCIP_REG_CLKEN_ENABLE (1 << 0) -#define SDMMCIP_REG_CLKEN_LOW_PWR (1 << 16) - -/* Card-type registe */ -#define SDMMCIP_REG_CTYPE_1BIT 0 -#define SDMMCIP_REG_CTYPE_4BIT (1 << 0) -#define SDMMCIP_REG_CTYPE_8BIT (1 << 16) - -/* Status Register */ -#define SDMMCIP_REG_BUSY (1 << 9) -#define SDMMCIP_REG_FIFO_FULL (1 << 3) -#define SDMMCIP_REG_FIFO_EMPTY (1 << 2) -#define SDMMCIP_REG_FIFO_COUNT_SHIFT (17) -#define SDMMCIP_REG_FIFO_COUNT_MASK (0x1fff << SDMMCIP_REG_FIFO_COUNT_SHIFT) - -/* FIFOTH Register */ -#define MSIZE(x) ((x) << 28) -#define RX_WMARK(x) ((x) << 16) -#define TX_WMARK(x) (x) -#define RX_WMARK_SHIFT 16 -#define RX_WMARK_MASK (0xfff << RX_WMARK_SHIFT) - -#define SDMMCIP_REG_IDMAC_OWN (1 << 31) -#define SDMMCIP_REG_IDMAC_CH (1 << 4) -#define SDMMCIP_REG_IDMAC_FS (1 << 3) -#define SDMMCIP_REG_IDMAC_LD (1 << 2) - -/* Bus Mode Register */ -#define SDMMCIP_REG_BMOD_IDMAC_RESET (1 << 0) -#define SDMMCIP_REG_BMOD_IDMAC_FB (1 << 1) -#define SDMMCIP_REG_BMOD_IDMAC_EN (1 << 7) - -/* UHS register */ -#define SDMMCIP_REG_DDR_MODE (1 << 16) - -/* quirks */ -#define SDMMCIP_REG_QUIRK_DISABLE_SMU (1 << 0) - -/* FIFO Register */ -#define SDMMCIP_REG_FIFO_OFFSET 0x200 - -#endif /* __SDMMCIP_REG_HW_H */