12 #ifdef SPI_SDCARD_DEBUG
13 #define dprintk(fmt, args...) \
14 printk(BIOS_DEBUG, fmt, ##args)
16 #define dprintk(fmt, args...) \
20 #define SDCARD_TYPE_SDSC 1
21 #define SDCARD_TYPE_SDHC 2
22 #define SDCARD_TYPE_SDXC 3
25 #define GO_IDLE_STATE 0
26 #define SEND_OP_COND 1
28 #define SEND_IF_COND 8
31 #define STOP_TRANSMISSION 12
32 #define SEND_STATUS 13
33 #define SET_BLOCKLEN 16
34 #define READ_SINGLE_BLOCK 17
35 #define READ_MULTIPLEBLOCK 18
36 #define WRITE_BLOCK 24
37 #define WRITE_MULTIPLEBLOCK 25
38 #define PROGRAM_CSD 27
39 #define SET_WRITE_PROT 28
40 #define CLR_WRITE_PROT 29
41 #define SEND_WRITE_PROT 30
42 #define ERASE_WR_BLK_START_ADDR 32
43 #define ERASE_WR_BLK_END_ADDR 33
45 #define LOCK_UNLOCK 42
53 #define SEND_NUM_WR_BLOCKS 22
54 #define SET_WR_BLK_ERASE_COUNT 23
55 #define SD_SEND_OP_COND 41
56 #define SET_CLR_CARD_DETECT 42
60 #define CT_BLOCK_START 0xfe
61 #define CT_MULTIPLE_BLOCK_START 0xfc
62 #define CT_MULTIPLE_BLOCK_STOP 0xfd
63 #define CT_RESPONSE_MASK 0x1f
64 #define CT_RESPONSE_ACCEPTED 0x05
65 #define CT_RESPONSE_REJECTED_CRC 0x0b
66 #define CT_RESPONSE_REJECTED_WRITE_ERR 0x0d
77 #define RSP_ERR_CARD_IS_LOCKED (1 << 0)
78 #define RSP_ERR_WP_ERASE_SKIP (1 << 1)
79 #define RSP_ERR_GENERAL (1 << 2)
80 #define RSP_ERR_CC (1 << 3)
81 #define RSP_ERR_ECC (1 << 4)
82 #define RSP_ERR_WP_VIOLATION (1 << 5)
83 #define RSP_ERR_ERASE_PARAM (1 << 6)
84 #define RSP_ERR_OUT_OF_RANGE (1 << 7)
85 #define RSP_ERR_IN_IDLE (1 << 8)
86 #define RSP_ERR_ERASE_RESET (1 << 9)
87 #define RSP_ERR_ILLEGAL_COMMAND (1 << 10)
88 #define RSP_ERR_COM_CRC (1 << 11)
89 #define RSP_ERR_ERASE_SEQUENCE (1 << 12)
90 #define RSP_ERR_ADDRESS (1 << 13)
91 #define RSP_ERR_PARAMETER (1 << 14)
93 #define BLOCK_SIZE 512
96 int width,
int start,
int end)
98 unsigned long long r = 0;
99 for (
int i = end; i >= start; i--) {
100 int bitpos =
width - i - 1;
102 int shift = 7 - bitpos % 8;
103 r = (r << 1) | ((buff[b] >> shift) & 1);
135 crc =
crc7_byte(crc, (cmd | 0x40) & 0x7f);
136 crc =
crc7_byte(crc, (argument >> (3 * 8)) & 0xff);
137 crc =
crc7_byte(crc, (argument >> (2 * 8)) & 0xff);
138 crc =
crc7_byte(crc, (argument >> (1 * 8)) & 0xff);
139 crc =
crc7_byte(crc, (argument >> (0 * 8)) & 0xff);
197 switch (response_type) {
213 __unused static const char *
const sd_err[] = {
215 "wp erase skip | lock/unlok cmd failed",
221 "out of range | csd overwrite",
226 "erase sequence error",
232 if ((response_type ==
RSP_R1)
234 || (response_type ==
RSP_R2)
235 || (response_type ==
RSP_R3)
236 || (response_type ==
RSP_R7))
239 if (response_type ==
RSP_R2)
242 if (((response_type ==
RSP_R3) || (response_type ==
RSP_R7))
243 && (out_register !=
NULL)) {
245 *out_register = (*out_register << 8) | response[1];
246 *out_register = (*out_register << 8) | response[2];
247 *out_register = (*out_register << 8) | response[3];
248 *out_register = (*out_register << 8) | response[4];
251 if (r1 != 0 || r2 != 0) {
256 dprintk(
"SDCARD ERROR: %s\n", sd_err[i]);
260 return (r1 << 8) | r2;
279 dprintk(
"\nsdcard execute acmd%d, argument = %#x, crc = %#x\n",
282 dprintk(
"\nsdcard execute cmd%d, argument = %#x, crc = %#x\n",
320 for (
int i = 0; i <
length; i++) {
328 while (
c == 0 && --
wait)
386 for (
int i = 0; i < 16; i++) {
409 return (c_size + 1) * mult * (1 << read_bl_len);
415 return (c_size + 1) * 512 * 1024;
422 const unsigned int bus,
const unsigned int cs)
433 for (
int i = 0; i < 10; i++)
483 if ((ocr & 0x40000000) == 0)
497 size_t block_address,
504 block_address = block_address * 512;
523 for (
int i = 0; i < 512; i++) {
545 size_t start_block_address,
546 size_t end_block_address,
550 int block_num = end_block_address - start_block_address + 1;
552 start_block_address = start_block_address * 512;
553 end_block_address = end_block_address * 512;
563 for (
int i = 0; i < block_num; i++) {
576 for (
int k = 0; k < 512; k++) {
578 ((
uint8_t *)buff)[512 * i + k] = tmp;
613 if (start_block_address == end_block_address) {
632 if (start_block_address + has_begin <= end_block_address - has_end) {
633 size_t start_lba = start_block_address + has_begin;
634 size_t end_lba = end_block_address - has_end;
636 if (start_lba < end_lba) {
659 size_t block_address,
665 block_address = block_address * 512;
677 for (
int i = 0; i < 512; i++) {
708 size_t start_block_address,
709 size_t end_block_address,
713 int block_num = end_block_address - start_block_address + 1;
715 start_block_address = start_block_address * 512;
716 end_block_address = end_block_address * 512;
720 start_block_address,
NULL))
726 for (
int i = 0; i < block_num; i++) {
735 for (
int k = 0; k < 512; k++) {
773 size_t start_block_address,
774 size_t end_block_address)
777 start_block_address = start_block_address * 512;
778 end_block_address = end_block_address * 512;
783 start_block_address,
NULL))
788 end_block_address,
NULL))
void * memcpy(void *dest, const void *src, size_t n)
uint16_t crc16_byte(uint16_t prev_crc, uint8_t data)
uint8_t crc7_byte(uint8_t prev_crc, uint8_t data)
static void wait(unsigned int bus)
int spi_claim_bus(const struct spi_slave *slave)
int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin)
void spi_release_bus(const struct spi_slave *slave)
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
#define CT_RESPONSE_ACCEPTED
#define READ_SINGLE_BLOCK
#define STOP_TRANSMISSION
#define READ_MULTIPLEBLOCK
static void spi_sdcard_sendbyte(const struct spi_sdcard *card, uint8_t b)
#define ERASE_WR_BLK_END_ADDR
static int lookup_acmd_response_type(uint8_t cmd)
#define dprintk(fmt, args...)
int spi_sdcard_multiple_write(const struct spi_sdcard *card, size_t start_block_address, size_t end_block_address, void *buff)
static uint8_t spi_sdcard_recvbyte(const struct spi_sdcard *card)
static void spi_sdcard_disable_cs(const struct spi_sdcard *card)
int spi_sdcard_read(const struct spi_sdcard *card, void *dest, size_t offset, size_t count)
#define CT_MULTIPLE_BLOCK_STOP
static int spi_sdcard_do_app_command(const struct spi_sdcard *card, uint8_t cmd, uint32_t argument, uint32_t *out_register)
static void spi_sdcard_enable_cs(const struct spi_sdcard *card)
#define ERASE_WR_BLK_START_ADDR
#define SET_WR_BLK_ERASE_COUNT
static int lookup_response_length(int response_type)
#define WRITE_MULTIPLEBLOCK
#define SEND_NUM_WR_BLOCKS
static int spi_sdcard_do_command_help(const struct spi_sdcard *card, int is_acmd, uint8_t cmd, uint32_t argument, uint32_t *out_register)
static unsigned long long extract_bits(uint8_t *buff, int width, int start, int end)
int spi_sdcard_single_write(const struct spi_sdcard *card, size_t block_address, void *buff)
static int spi_sdcard_do_command(const struct spi_sdcard *card, uint8_t cmd, uint32_t argument, uint32_t *out_register)
static int lookup_cmd_response_type(uint8_t cmd)
int spi_sdcard_erase(const struct spi_sdcard *card, size_t start_block_address, size_t end_block_address)
static uint8_t spi_sdcard_calculate_command_crc(uint8_t cmd, uint32_t argument)
static int response_resolve(int response_type, uint8_t *response, uint32_t *out_register)
int spi_sdcard_erase_all(const struct spi_sdcard *card)
int spi_sdcard_single_read(const struct spi_sdcard *card, size_t block_address, void *buff)
#define SET_CLR_CARD_DETECT
int spi_sdcard_init(struct spi_sdcard *card, const unsigned int bus, const unsigned int cs)
int spi_sdcard_multiple_read(const struct spi_sdcard *card, size_t start_block_address, size_t end_block_address, void *buff)
#define CT_MULTIPLE_BLOCK_START
size_t spi_sdcard_size(const struct spi_sdcard *card)
#define RSP_ERR_ILLEGAL_COMMAND
#define c(value, pmcreg, dst_bits)