rt-thread/bsp/allwinner/libraries/sunxi-hal/include/hal/sdmmc/card.h

357 lines
14 KiB
C

/*
* Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DRIVER_CHIP_SDMMC_CARD_H_
#define _DRIVER_CHIP_SDMMC_CARD_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "osal/os_mutex.h"
#define CONFIG_SDIO_USE_FUNS
//#define CONFIG_USE_SDIO_COMBO
//#define SD_SUPPORT_VERSION3 /* not support for not support 1V8 */ #error !!
//#define CONFIG_USE_MMC_QUIRK /* not support now */ #error !!
//#define CONFIG_SDIO_USE_FUNS /* close to save code. and not support now */ #error !!
#define SYSTEM_SIMULATION
#ifdef CONFIG_USE_SDIO
struct sdio_func;
typedef void (sdio_irq_handler_t)(struct sdio_func *);
/*
* SDIO function devices
*/
struct sdio_func {
struct mmc_card *card; /* the card this device belongs to */
sdio_irq_handler_t *irq_handler; /* IRQ callback */
uint32_t num; /* function number */
unsigned char class; /* standard interface class */
unsigned short vendor; /* vendor id */
unsigned short device; /* device id */
uint32_t max_blksize; /* maximum block size */
uint32_t cur_blksize; /* current block size */
uint32_t enable_timeout; /* max enable timeout in msec */
uint32_t state; /* function state */
#define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */
uint8_t tmpbuf[4]; /* DMA:able scratch buffer */
unsigned num_info; /* number of info strings */
const char **info; /* info strings */
struct sdio_func_tuple *tuples;
/*for rtl*/
void *drv_prv;
};
#define sdio_func_present(f) ((f)->state & SDIO_STATE_PRESENT)
#define sdio_func_set_present(f) ((f)->state |= SDIO_STATE_PRESENT)
#endif
struct mmc_ocr {
union {
uint32_t vol_window : 24,
to_1v8_acpt : 1,
: 5,
high_capacity : 1,
: 1;
uint32_t ocr;
};
};
struct mmc_cid {
uint16_t oemid;
uint8_t manfid;
uint32_t serial;
uint16_t year;
uint8_t month;
uint8_t hwrev;
uint8_t fwrev;
uint8_t prod_name[6];
};
struct mmc_csd {
uint8_t csd_ver;
//uint8_t c_size_mult;
//uint16_t c_size;
uint32_t max_dtr; /* max transfer speed */
uint16_t read_blk_len;
uint16_t cmdclass;
uint32_t capacity;
};
struct sd_scr {
uint8_t sda_vsn;
uint8_t sda_spec3;
uint8_t sda_spec4;
uint8_t sda_spec5;
uint8_t bus_widths;
uint8_t security_sup;
#define SD_SCR_BUS_WIDTH_1 (1<<0)
#define SD_SCR_BUS_WIDTH_4 (1<<2)
uint8_t cmds;
#define SD_SCR_CMD20_SUPPORT (1<<0)
#define SD_SCR_CMD23_SUPPORT (1<<1)
};
struct sd_ssr {
uint32_t au; /* In sectors */
uint32_t erase_timeout; /* In milliseconds */
uint32_t erase_offset; /* In milliseconds */
};
struct sd_switch_caps {
uint32_t hs_max_dtr;
uint32_t uhs_max_dtr;
#define HIGH_SPEED_MAX_DTR 50000000
#define UHS_SDR104_MAX_DTR 208000000
#define UHS_SDR50_MAX_DTR 100000000
#define UHS_DDR50_MAX_DTR 50000000
#define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR
#define UHS_SDR12_MAX_DTR 25000000
uint32_t sd3_bus_mode;
#define UHS_SDR12_BUS_SPEED 0
#define HIGH_SPEED_BUS_SPEED 1
#define UHS_SDR25_BUS_SPEED 1
#define UHS_SDR50_BUS_SPEED 2
#define UHS_SDR104_BUS_SPEED 3
#define UHS_DDR50_BUS_SPEED 4
#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED)
#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED)
#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED)
#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED)
#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED)
#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED)
uint32_t sd3_drv_type;
#define SD_DRIVER_TYPE_B 0x01
#define SD_DRIVER_TYPE_A 0x02
#define SD_DRIVER_TYPE_C 0x04
#define SD_DRIVER_TYPE_D 0x08
uint32_t sd3_curr_limit;
#define SD_SET_CURRENT_LIMIT_200 0
#define SD_SET_CURRENT_LIMIT_400 1
#define SD_SET_CURRENT_LIMIT_600 2
#define SD_SET_CURRENT_LIMIT_800 3
#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200)
#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400)
#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600)
#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800)
};
struct mmc_ext_csd {
uint8_t version;
uint8_t card_type;
uint8_t csd_struc;
uint8_t hs_timing;
uint8_t bus_width;
uint8_t part_config;
uint8_t boot_bus_cond;
};
struct sdio_cccr {
uint32_t sdio_vsn;
uint32_t sd_vsn;
uint32_t multi_block:1,
low_speed:1,
wide_bus:1,
high_power:1,
high_speed:1,
disable_cd:1;
};
struct sdio_cis {
uint16_t vendor;
uint16_t device;
uint16_t blksize;
uint32_t max_dtr;
};
struct mmc_host;
#define SDIO_MAX_FUNCS 7
/** @bried SD Card Init Structure definition. */
typedef struct {
uint16_t debug_mask;
uint16_t type; /* set card type if we know to speed up scan card, MMC_TYPE_xx */
} SDCard_InitTypeDef;
struct mmc_card {
uint16_t debug_mask;
uint16_t suspend;
//#if ((defined CONFIG_USE_SD) || (defined CONFIG_USE_MMC))
/* register info. */
struct mmc_cid cid;
struct mmc_csd csd;
struct sd_scr scr;
struct sd_ssr ssr;
struct mmc_ext_csd extcsd;
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */
//#endif
/* card information */
uint32_t id;
uint32_t type; /* card type */
#define MMC_TYPE_MMC 1 /* MMC card */
#define MMC_TYPE_SD 2 /* SD card */
#define MMC_TYPE_SDIO 3 /* SDIO card */
#define MMC_TYPE_SD_COMBO 4 /* SD combo (IO+mem) card */
#define MMC_TYPE_MAX 5
uint32_t sd_bus_speed; /* Bus Speed Mode set for the card */
uint32_t state; /* (our) card state */
#define MMC_STATE_PRESENT (1 << 0) /* present */
#define MMC_STATE_READONLY (1 << 1) /* card is read-only */
#define MMC_STATE_HIGHSPEED (1 << 2) /* card is in high speed mode */
#define MMC_STATE_BLOCKADDR (1 << 3) /* card uses block-addressing */
#define MMC_STATE_HIGHSPEED_DDR (1 << 4) /* card is in high speed mode */
#define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */
//#ifdef CONFIG_USE_MMC_QUIRK
uint32_t quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1 << 0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1 << 1) /* use func->cur_blksize */
/* for byte mode */
#define MMC_QUIRK_NONSTD_SDIO (1 << 2) /* non-standard SDIO card attached */
/* (missing CIA registers) */
#define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */
#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */
#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
//#endif
/* missing CIA registers */
//#ifdef CONFIG_SDIO_USE_FUNS
uint32_t erase_size; /* erase size in sectors */
uint32_t erase_shift; /* if erase unit is power 2 */
uint32_t pref_erase; /* in sectors */
uint8_t erased_byte; /* value of erased bytes */
uint32_t raw_cid[4]; /* raw card CID */
uint32_t raw_csd[4]; /* raw card CSD */
uint32_t raw_scr[2]; /* raw card SCR */
uint32_t sdio_funcs; /* number of SDIO functions */
struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
uint32_t num_info; /* number of info strings */
const int8_t **info; /* info strings */
//#ifdef CONFIG_SDIO_IRQ_SUPPORT
// sdio_irq_handler_t *sdio_single_irq; /* IRQ callback, all funs only support one for efficiency! */
struct sdio_func *sdio_single_irq; /* SDIO function when only one IRQ active */
//#endif
//#endif
#ifdef CONFIG_USE_SDIO
uint32_t manfid;
uint32_t cisptr[8];
uint16_t fn_bsize[8];
void *mem_info_p; //if with memory, to store information about memory portion
//struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
struct sdio_cccr cccr; /* common card info */
struct sdio_cis cis; /* common tuple info */
struct sdio_func_tuple *tuples; /* unknown common tuples */
#endif
uint8_t bus_width;
uint8_t speed_class;
uint16_t ref;
OS_Mutex_t mutex;
uint32_t cidno[4];
uint32_t rca; /* relative card address of device */
struct mmc_ocr ocr;
struct mmc_host *host; /* the host this device belongs to */
};
struct mmc_card_info {
struct mmc_card card;
struct sdio_func sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
//const int8_t **info; /* info strings */
//struct sdio_func *sdio_single_irq; /* SDIO function when only one IRQ active */
//void *mem_info_p; //if with memory, to store information about memory portion
#ifdef CONFIG_USE_SDIO
//struct sdio_func_tuple *tuples; /* unknown common tuples */
#endif
uint32_t sdc_id;
};
#define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC)
#define mmc_card_sd(c) ((c)->type == MMC_TYPE_SD)
#define mmc_card_sdio(c) ((c)->type == MMC_TYPE_SDIO)
#define mmc_card_sd_combo(c) ((c)->type == MMC_TYPE_SD_COMBO)
#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
#define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
#define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED)
#define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200)
#define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR)
#define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR)
#define mmc_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP)
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
#define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED)
#define mmc_card_set_hs200(c) ((c)->state |= MMC_STATE_HIGHSPEED_200)
#define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR)
#define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP)
#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP)
#ifdef __cplusplus
}
#endif
#endif /* _DRIVER_CHIP_SDMMC_CARD_H_ */