338 lines
9.9 KiB
C
338 lines
9.9 KiB
C
|
/*
|
||
|
* Copyright (c) 2015, 2016 Freescale Semiconductor, Inc.
|
||
|
* Copyright 2017-2021 NXP
|
||
|
*
|
||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef SD_MMC_H
|
||
|
#define SD_MMC_H
|
||
|
|
||
|
#include <lib/mmio.h>
|
||
|
|
||
|
/* operating freq */
|
||
|
#define CARD_IDENTIFICATION_FREQ 400000
|
||
|
#define SD_SS_25MHZ 20000000
|
||
|
#define SD_HS_50MHZ 40000000
|
||
|
#define MMC_SS_20MHZ 15000000
|
||
|
#define MMC_HS_26MHZ 20000000
|
||
|
#define MMC_HS_52MHZ 40000000
|
||
|
|
||
|
/* Need to check this value ? */
|
||
|
#define MAX_PLATFORM_CLOCK 800000000
|
||
|
|
||
|
/* eSDHC system control register defines */
|
||
|
#define ESDHC_SYSCTL_DTOCV(t) (((t) & 0xF) << 16)
|
||
|
#define ESDHC_SYSCTL_SDCLKFS(f) (((f) & 0xFF) << 8)
|
||
|
#define ESDHC_SYSCTL_DVS(d) (((d) & 0xF) << 4)
|
||
|
#define ESDHC_SYSCTL_SDCLKEN (0x00000008)
|
||
|
#define ESDHC_SYSCTL_RSTA (0x01000000)
|
||
|
|
||
|
/* Data timeout counter value. SDHC_CLK x 227 */
|
||
|
#define TIMEOUT_COUNTER_SDCLK_2_27 0xE
|
||
|
#define ESDHC_SYSCTL_INITA 0x08000000
|
||
|
|
||
|
/* eSDHC interrupt status enable register defines */
|
||
|
#define ESDHC_IRQSTATEN_CINS 0x00000040
|
||
|
#define ESDHC_IRQSTATEN_BWR 0x00000010
|
||
|
|
||
|
/* eSDHC interrupt status register defines */
|
||
|
#define ESDHC_IRQSTAT_DMAE (0x10000000)
|
||
|
#define ESDHC_IRQSTAT_AC12E (0x01000000)
|
||
|
#define ESDHC_IRQSTAT_DEBE (0x00400000)
|
||
|
#define ESDHC_IRQSTAT_DCE (0x00200000)
|
||
|
#define ESDHC_IRQSTAT_DTOE (0x00100000)
|
||
|
#define ESDHC_IRQSTAT_CIE (0x00080000)
|
||
|
#define ESDHC_IRQSTAT_CEBE (0x00040000)
|
||
|
#define ESDHC_IRQSTAT_CCE (0x00020000)
|
||
|
#define ESDHC_IRQSTAT_CTOE (0x00010000)
|
||
|
#define ESDHC_IRQSTAT_CINT (0x00000100)
|
||
|
#define ESDHC_IRQSTAT_CRM (0x00000080)
|
||
|
#define ESDHC_IRQSTAT_CINS (0x00000040)
|
||
|
#define ESDHC_IRQSTAT_BRR (0x00000020)
|
||
|
#define ESDHC_IRQSTAT_BWR (0x00000010)
|
||
|
#define ESDHC_IRQSTAT_DINT (0x00000008)
|
||
|
#define ESDHC_IRQSTAT_BGE (0x00000004)
|
||
|
#define ESDHC_IRQSTAT_TC (0x00000002)
|
||
|
#define ESDHC_IRQSTAT_CC (0x00000001)
|
||
|
#define ESDHC_IRQSTAT_CMD_ERR (ESDHC_IRQSTAT_CIE |\
|
||
|
ESDHC_IRQSTAT_CEBE |\
|
||
|
ESDHC_IRQSTAT_CCE)
|
||
|
#define ESDHC_IRQSTAT_DATA_ERR (ESDHC_IRQSTAT_DEBE |\
|
||
|
ESDHC_IRQSTAT_DCE |\
|
||
|
ESDHC_IRQSTAT_DTOE)
|
||
|
#define ESDHC_IRQSTAT_CLEAR_ALL (0xFFFFFFFF)
|
||
|
|
||
|
/* eSDHC present state register defines */
|
||
|
#define ESDHC_PRSSTAT_CLSL 0x00800000
|
||
|
#define ESDHC_PRSSTAT_WPSPL 0x00080000
|
||
|
#define ESDHC_PRSSTAT_CDPL 0x00040000
|
||
|
#define ESDHC_PRSSTAT_CINS 0x00010000
|
||
|
#define ESDHC_PRSSTAT_BREN 0x00000800
|
||
|
#define ESDHC_PRSSTAT_BWEN 0x00000400
|
||
|
#define ESDHC_PRSSTAT_RTA 0x00000200
|
||
|
#define ESDHC_PRSSTAT_WTA 0x00000100
|
||
|
#define ESDHC_PRSSTAT_SDOFF 0x00000080
|
||
|
#define ESDHC_PRSSTAT_PEROFF 0x00000040
|
||
|
#define ESDHC_PRSSTAT_HCKOFF 0x00000020
|
||
|
#define ESDHC_PRSSTAT_IPGOFF 0x00000010
|
||
|
#define ESDHC_PRSSTAT_DLA 0x00000004
|
||
|
#define ESDHC_PRSSTAT_CDIHB 0x00000002
|
||
|
#define ESDHC_PRSSTAT_CIHB 0x00000001
|
||
|
|
||
|
/* eSDHC protocol control register defines */
|
||
|
#define ESDHC_PROCTL_EMODE_LE 0x00000020
|
||
|
#define ESDHC_PROCTL_DTW_1BIT 0x00000000
|
||
|
#define ESDHC_PROCTL_DTW_4BIT 0x00000002
|
||
|
#define ESDHC_PROCTL_DTW_8BIT 0x00000004
|
||
|
|
||
|
/* Watermark Level Register (WML) */
|
||
|
#define ESDHC_WML_RD_WML(w) ((w) & 0x7F)
|
||
|
#define ESDHC_WML_WR_WML(w) (((w) & 0x7F) << 16)
|
||
|
#define ESDHC_WML_RD_BRST(w) (((w) & 0xF) << 8)
|
||
|
#define ESDHC_WML_WR_BRST(w) (((w) & 0xF) << 24)
|
||
|
#define ESDHC_WML_WR_BRST_MASK (0x0F000000)
|
||
|
#define ESDHC_WML_RD_BRST_MASK (0x00000F00)
|
||
|
#define ESDHC_WML_RD_WML_MASK (0x0000007F)
|
||
|
#define ESDHC_WML_WR_WML_MASK (0x007F0000)
|
||
|
#define WML_512_BYTES (0x0)
|
||
|
#define BURST_128_BYTES (0x0)
|
||
|
|
||
|
/* eSDHC control register define */
|
||
|
#define ESDHC_DCR_SNOOP 0x00000040
|
||
|
|
||
|
/* ESDHC Block attributes register */
|
||
|
#define ESDHC_BLKATTR_BLKCNT(c) (((c) & 0xffff) << 16)
|
||
|
#define ESDHC_BLKATTR_BLKSZE(s) ((s) & 0xfff)
|
||
|
|
||
|
/* Transfer Type Register */
|
||
|
#define ESDHC_XFERTYP_CMD(c) (((c) & 0x3F) << 24)
|
||
|
#define ESDHC_XFERTYP_CMDTYP_NORMAL (0x0)
|
||
|
#define ESDHC_XFERTYP_CMDTYP_SUSPEND (0x00400000)
|
||
|
#define ESDHC_XFERTYP_CMDTYP_RESUME (0x00800000)
|
||
|
#define ESDHC_XFERTYP_CMDTYP_ABORT (0x00C00000)
|
||
|
#define ESDHC_XFERTYP_DPSEL (0x00200000)
|
||
|
#define ESDHC_XFERTYP_CICEN (0x00100000)
|
||
|
#define ESDHC_XFERTYP_CCCEN (0x00080000)
|
||
|
#define ESDHC_XFERTYP_RSPTYP_NONE (0x0)
|
||
|
#define ESDHC_XFERTYP_RSPTYP_136 (0x00010000)
|
||
|
#define ESDHC_XFERTYP_RSPTYP_48 (0x00020000)
|
||
|
#define ESDHC_XFERTYP_RSPTYP_48_BUSY (0x00030000)
|
||
|
#define ESDHC_XFERTYP_MSBSEL (0x00000020)
|
||
|
#define ESDHC_XFERTYP_DTDSEL (0x00000010)
|
||
|
#define ESDHC_XFERTYP_AC12EN (0x00000004)
|
||
|
#define ESDHC_XFERTYP_BCEN (0x00000002)
|
||
|
#define ESDHC_XFERTYP_DMAEN (0x00000001)
|
||
|
|
||
|
#define MMC_VDD_HIGH_VOLTAGE 0x00000100
|
||
|
|
||
|
/* command index */
|
||
|
#define CMD0 0
|
||
|
#define CMD1 1
|
||
|
#define CMD2 2
|
||
|
#define CMD3 3
|
||
|
#define CMD5 5
|
||
|
#define CMD6 6
|
||
|
#define CMD7 7
|
||
|
#define CMD8 8
|
||
|
#define CMD9 9
|
||
|
#define CMD12 12
|
||
|
#define CMD13 13
|
||
|
#define CMD14 14
|
||
|
#define CMD16 16
|
||
|
#define CMD17 17
|
||
|
#define CMD18 18
|
||
|
#define CMD19 19
|
||
|
#define CMD24 24
|
||
|
#define CMD41 41
|
||
|
#define CMD42 42
|
||
|
#define CMD51 51
|
||
|
#define CMD55 55
|
||
|
#define CMD56 56
|
||
|
#define ACMD6 CMD6
|
||
|
#define ACMD13 CMD13
|
||
|
#define ACMD41 CMD41
|
||
|
#define ACMD42 CMD42
|
||
|
#define ACMD51 CMD51
|
||
|
|
||
|
/* commands abbreviations */
|
||
|
#define CMD_GO_IDLE_STATE CMD0
|
||
|
#define CMD_MMC_SEND_OP_COND CMD1
|
||
|
#define CMD_ALL_SEND_CID CMD2
|
||
|
#define CMD_SEND_RELATIVE_ADDR CMD3
|
||
|
#define CMD_SET_DSR CMD4
|
||
|
#define CMD_SWITCH_FUNC CMD6
|
||
|
#define CMD_SELECT_CARD CMD7
|
||
|
#define CMD_DESELECT_CARD CMD7
|
||
|
#define CMD_SEND_IF_COND CMD8
|
||
|
#define CMD_MMC_SEND_EXT_CSD CMD8
|
||
|
#define CMD_SEND_CSD CMD9
|
||
|
#define CMD_SEND_CID CMD10
|
||
|
#define CMD_STOP_TRANSMISSION CMD12
|
||
|
#define CMD_SEND_STATUS CMD13
|
||
|
#define CMD_BUS_TEST_R CMD14
|
||
|
#define CMD_GO_INACTIVE_STATE CMD15
|
||
|
#define CMD_SET_BLOCKLEN CMD16
|
||
|
#define CMD_READ_SINGLE_BLOCK CMD17
|
||
|
#define CMD_READ_MULTIPLE_BLOCK CMD18
|
||
|
#define CMD_WRITE_SINGLE_BLOCK CMD24
|
||
|
#define CMD_BUS_TEST_W CMD19
|
||
|
#define CMD_APP_CMD CMD55
|
||
|
#define CMD_GEN_CMD CMD56
|
||
|
#define CMD_SET_BUS_WIDTH ACMD6
|
||
|
#define CMD_SD_STATUS ACMD13
|
||
|
#define CMD_SD_SEND_OP_COND ACMD41
|
||
|
#define CMD_SET_CLR_CARD_DETECT ACMD42
|
||
|
#define CMD_SEND_SCR ACMD51
|
||
|
|
||
|
/* MMC card spec version */
|
||
|
#define MMC_CARD_VERSION_1_2 0
|
||
|
#define MMC_CARD_VERSION_1_4 1
|
||
|
#define MMC_CARD_VERSION_2_X 2
|
||
|
#define MMC_CARD_VERSION_3_X 3
|
||
|
#define MMC_CARD_VERSION_4_X 4
|
||
|
|
||
|
/* SD Card Spec Version */
|
||
|
/* May need to add version 3 here? */
|
||
|
#define SD_CARD_VERSION_1_0 0
|
||
|
#define SD_CARD_VERSION_1_10 1
|
||
|
#define SD_CARD_VERSION_2_0 2
|
||
|
|
||
|
/* card types */
|
||
|
#define MMC_CARD 0
|
||
|
#define SD_CARD 1
|
||
|
#define NOT_SD_CARD MMC_CARD
|
||
|
|
||
|
/* Card rca */
|
||
|
#define SD_MMC_CARD_RCA 0x1
|
||
|
#define BLOCK_LEN_512 512
|
||
|
|
||
|
/* card state */
|
||
|
#define STATE_IDLE 0
|
||
|
#define STATE_READY 1
|
||
|
#define STATE_IDENT 2
|
||
|
#define STATE_STBY 3
|
||
|
#define STATE_TRAN 4
|
||
|
#define STATE_DATA 5
|
||
|
#define STATE_RCV 6
|
||
|
#define STATE_PRG 7
|
||
|
#define STATE_DIS 8
|
||
|
|
||
|
/* Card OCR register */
|
||
|
/* VDD voltage window 1,65 to 1.95 */
|
||
|
#define MMC_OCR_VDD_165_195 0x00000080
|
||
|
/* VDD voltage window 2.7-2.8 */
|
||
|
#define MMC_OCR_VDD_FF8 0x00FF8000
|
||
|
#define MMC_OCR_CCS 0x40000000/* Card Capacity */
|
||
|
#define MMC_OCR_BUSY 0x80000000/* busy bit */
|
||
|
#define SD_OCR_HCS 0x40000000/* High capacity host */
|
||
|
#define MMC_OCR_SECTOR_MODE 0x40000000/* Access Mode as Sector */
|
||
|
|
||
|
/* mmc Switch function */
|
||
|
#define SET_EXT_CSD_HS_TIMING 0x03B90100/* set High speed */
|
||
|
|
||
|
/* check supports switching or not */
|
||
|
#define SD_SWITCH_FUNC_CHECK_MODE 0x00FFFFF1
|
||
|
#define SD_SWITCH_FUNC_SWITCH_MODE 0x80FFFFF1/* switch */
|
||
|
#define SD_SWITCH_FUNC_HIGH_SPEED 0x02/* HIGH SPEED FUNC */
|
||
|
#define SWITCH_ERROR 0x00000080
|
||
|
|
||
|
/* errors in sending commands */
|
||
|
#define RESP_TIMEOUT 0x1
|
||
|
#define COMMAND_ERROR 0x2
|
||
|
/* error in response */
|
||
|
#define R1_ERROR (1 << 19)
|
||
|
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9)
|
||
|
|
||
|
/* Host Controller Capabilities */
|
||
|
#define ESDHC_HOSTCAPBLT_DMAS (0x00400000)
|
||
|
|
||
|
|
||
|
/* SD/MMC memory map */
|
||
|
struct esdhc_regs {
|
||
|
uint32_t dsaddr; /* dma system address */
|
||
|
uint32_t blkattr; /* Block attributes */
|
||
|
uint32_t cmdarg; /* Command argument */
|
||
|
uint32_t xfertyp; /* Command transfer type */
|
||
|
uint32_t cmdrsp[4]; /* Command response0,1,2,3 */
|
||
|
uint32_t datport; /* Data buffer access port */
|
||
|
uint32_t prsstat; /* Present state */
|
||
|
uint32_t proctl; /* Protocol control */
|
||
|
uint32_t sysctl; /* System control */
|
||
|
uint32_t irqstat; /* Interrupt status */
|
||
|
uint32_t irqstaten; /* Interrupt status enable */
|
||
|
uint32_t irqsigen; /* Interrupt signal enable */
|
||
|
uint32_t autoc12err; /* Auto CMD12 status */
|
||
|
uint32_t hostcapblt; /* Host controller capabilities */
|
||
|
uint32_t wml; /* Watermark level */
|
||
|
uint32_t res1[2];
|
||
|
uint32_t fevt; /* Force event */
|
||
|
uint32_t res2;
|
||
|
uint32_t adsaddrl;
|
||
|
uint32_t adsaddrh;
|
||
|
uint32_t res3[39];
|
||
|
uint32_t hostver; /* Host controller version */
|
||
|
uint32_t res4;
|
||
|
uint32_t dmaerr; /* DMA error address */
|
||
|
uint32_t dmaerrh; /* DMA error address high */
|
||
|
uint32_t dmaerrattr; /* DMA error atrribute */
|
||
|
uint32_t res5;
|
||
|
uint32_t hostcapblt2;/* Host controller capabilities2 */
|
||
|
uint32_t res6[2];
|
||
|
uint32_t tcr; /* Tuning control */
|
||
|
uint32_t res7[7];
|
||
|
uint32_t dirctrl; /* Direction control */
|
||
|
uint32_t ccr; /* Clock control */
|
||
|
uint32_t res8[177];
|
||
|
uint32_t ctl; /* Control register */
|
||
|
};
|
||
|
|
||
|
/* SD/MMC card attributes */
|
||
|
struct card_attributes {
|
||
|
uint32_t type; /* sd or mmc card */
|
||
|
uint32_t version; /* version */
|
||
|
uint32_t block_len; /* block length */
|
||
|
uint32_t bus_freq; /* sdhc bus frequency */
|
||
|
uint16_t rca; /* relative card address */
|
||
|
uint8_t is_high_capacity; /* high capacity */
|
||
|
};
|
||
|
|
||
|
struct mmc {
|
||
|
struct esdhc_regs *esdhc_regs;
|
||
|
struct card_attributes card;
|
||
|
|
||
|
uint32_t block_len;
|
||
|
uint32_t voltages_caps; /* supported voltaes */
|
||
|
uint32_t dma_support; /* DMA support */
|
||
|
};
|
||
|
|
||
|
enum cntrl_num {
|
||
|
SDHC1 = 0,
|
||
|
SDHC2
|
||
|
};
|
||
|
|
||
|
int sd_emmc_init(uintptr_t *block_dev_spec,
|
||
|
uintptr_t nxp_esdhc_addr,
|
||
|
size_t nxp_sd_block_offset,
|
||
|
size_t nxp_sd_block_size,
|
||
|
bool card_detect);
|
||
|
|
||
|
int esdhc_emmc_init(struct mmc *mmc, bool card_detect);
|
||
|
int esdhc_read(struct mmc *mmc, uint32_t src_offset, uintptr_t dst,
|
||
|
size_t size);
|
||
|
int esdhc_write(struct mmc *mmc, uintptr_t src, uint32_t dst_offset,
|
||
|
size_t size);
|
||
|
|
||
|
#ifdef NXP_ESDHC_BE
|
||
|
#define esdhc_in32(a) bswap32(mmio_read_32((uintptr_t)(a)))
|
||
|
#define esdhc_out32(a, v) mmio_write_32((uintptr_t)(a), bswap32(v))
|
||
|
#elif defined(NXP_ESDHC_LE)
|
||
|
#define esdhc_in32(a) mmio_read_32((uintptr_t)(a))
|
||
|
#define esdhc_out32(a, v) mmio_write_32((uintptr_t)(a), (v))
|
||
|
#else
|
||
|
#error Please define CCSR ESDHC register endianness
|
||
|
#endif
|
||
|
|
||
|
#endif /*SD_MMC_H*/
|