blob: 32b41f137435628fdc623107e70d71cc7adce2d8 [file] [log] [blame]
/*
* 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*/