Pankaj Gupta | 7d2f40f | 2020-12-09 14:02:39 +0530 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2015, 2016 Freescale Semiconductor, Inc. |
Pankaj Gupta | 7834b46 | 2021-03-25 15:15:52 +0530 | [diff] [blame] | 3 | * Copyright 2017-2021 NXP |
Pankaj Gupta | 7d2f40f | 2020-12-09 14:02:39 +0530 | [diff] [blame] | 4 | * |
| 5 | * SPDX-License-Identifier: BSD-3-Clause |
| 6 | * |
| 7 | */ |
| 8 | |
| 9 | #ifndef SD_MMC_H |
| 10 | #define SD_MMC_H |
| 11 | |
| 12 | #include <lib/mmio.h> |
| 13 | |
| 14 | /* operating freq */ |
| 15 | #define CARD_IDENTIFICATION_FREQ 400000 |
| 16 | #define SD_SS_25MHZ 20000000 |
| 17 | #define SD_HS_50MHZ 40000000 |
| 18 | #define MMC_SS_20MHZ 15000000 |
| 19 | #define MMC_HS_26MHZ 20000000 |
| 20 | #define MMC_HS_52MHZ 40000000 |
| 21 | |
| 22 | /* Need to check this value ? */ |
| 23 | #define MAX_PLATFORM_CLOCK 800000000 |
| 24 | |
| 25 | /* eSDHC system control register defines */ |
| 26 | #define ESDHC_SYSCTL_DTOCV(t) (((t) & 0xF) << 16) |
| 27 | #define ESDHC_SYSCTL_SDCLKFS(f) (((f) & 0xFF) << 8) |
| 28 | #define ESDHC_SYSCTL_DVS(d) (((d) & 0xF) << 4) |
| 29 | #define ESDHC_SYSCTL_SDCLKEN (0x00000008) |
| 30 | #define ESDHC_SYSCTL_RSTA (0x01000000) |
| 31 | |
| 32 | /* Data timeout counter value. SDHC_CLK x 227 */ |
| 33 | #define TIMEOUT_COUNTER_SDCLK_2_27 0xE |
| 34 | #define ESDHC_SYSCTL_INITA 0x08000000 |
| 35 | |
| 36 | /* eSDHC interrupt status enable register defines */ |
| 37 | #define ESDHC_IRQSTATEN_CINS 0x00000040 |
| 38 | #define ESDHC_IRQSTATEN_BWR 0x00000010 |
| 39 | |
| 40 | /* eSDHC interrupt status register defines */ |
| 41 | #define ESDHC_IRQSTAT_DMAE (0x10000000) |
| 42 | #define ESDHC_IRQSTAT_AC12E (0x01000000) |
| 43 | #define ESDHC_IRQSTAT_DEBE (0x00400000) |
| 44 | #define ESDHC_IRQSTAT_DCE (0x00200000) |
| 45 | #define ESDHC_IRQSTAT_DTOE (0x00100000) |
| 46 | #define ESDHC_IRQSTAT_CIE (0x00080000) |
| 47 | #define ESDHC_IRQSTAT_CEBE (0x00040000) |
| 48 | #define ESDHC_IRQSTAT_CCE (0x00020000) |
| 49 | #define ESDHC_IRQSTAT_CTOE (0x00010000) |
| 50 | #define ESDHC_IRQSTAT_CINT (0x00000100) |
| 51 | #define ESDHC_IRQSTAT_CRM (0x00000080) |
| 52 | #define ESDHC_IRQSTAT_CINS (0x00000040) |
| 53 | #define ESDHC_IRQSTAT_BRR (0x00000020) |
| 54 | #define ESDHC_IRQSTAT_BWR (0x00000010) |
| 55 | #define ESDHC_IRQSTAT_DINT (0x00000008) |
| 56 | #define ESDHC_IRQSTAT_BGE (0x00000004) |
| 57 | #define ESDHC_IRQSTAT_TC (0x00000002) |
| 58 | #define ESDHC_IRQSTAT_CC (0x00000001) |
| 59 | #define ESDHC_IRQSTAT_CMD_ERR (ESDHC_IRQSTAT_CIE |\ |
| 60 | ESDHC_IRQSTAT_CEBE |\ |
| 61 | ESDHC_IRQSTAT_CCE) |
| 62 | #define ESDHC_IRQSTAT_DATA_ERR (ESDHC_IRQSTAT_DEBE |\ |
| 63 | ESDHC_IRQSTAT_DCE |\ |
| 64 | ESDHC_IRQSTAT_DTOE) |
| 65 | #define ESDHC_IRQSTAT_CLEAR_ALL (0xFFFFFFFF) |
| 66 | |
| 67 | /* eSDHC present state register defines */ |
| 68 | #define ESDHC_PRSSTAT_CLSL 0x00800000 |
| 69 | #define ESDHC_PRSSTAT_WPSPL 0x00080000 |
| 70 | #define ESDHC_PRSSTAT_CDPL 0x00040000 |
| 71 | #define ESDHC_PRSSTAT_CINS 0x00010000 |
| 72 | #define ESDHC_PRSSTAT_BREN 0x00000800 |
| 73 | #define ESDHC_PRSSTAT_BWEN 0x00000400 |
| 74 | #define ESDHC_PRSSTAT_RTA 0x00000200 |
| 75 | #define ESDHC_PRSSTAT_WTA 0x00000100 |
| 76 | #define ESDHC_PRSSTAT_SDOFF 0x00000080 |
| 77 | #define ESDHC_PRSSTAT_PEROFF 0x00000040 |
| 78 | #define ESDHC_PRSSTAT_HCKOFF 0x00000020 |
| 79 | #define ESDHC_PRSSTAT_IPGOFF 0x00000010 |
| 80 | #define ESDHC_PRSSTAT_DLA 0x00000004 |
| 81 | #define ESDHC_PRSSTAT_CDIHB 0x00000002 |
| 82 | #define ESDHC_PRSSTAT_CIHB 0x00000001 |
| 83 | |
| 84 | /* eSDHC protocol control register defines */ |
| 85 | #define ESDHC_PROCTL_EMODE_LE 0x00000020 |
| 86 | #define ESDHC_PROCTL_DTW_1BIT 0x00000000 |
| 87 | #define ESDHC_PROCTL_DTW_4BIT 0x00000002 |
| 88 | #define ESDHC_PROCTL_DTW_8BIT 0x00000004 |
| 89 | |
| 90 | /* Watermark Level Register (WML) */ |
| 91 | #define ESDHC_WML_RD_WML(w) ((w) & 0x7F) |
| 92 | #define ESDHC_WML_WR_WML(w) (((w) & 0x7F) << 16) |
| 93 | #define ESDHC_WML_RD_BRST(w) (((w) & 0xF) << 8) |
| 94 | #define ESDHC_WML_WR_BRST(w) (((w) & 0xF) << 24) |
| 95 | #define ESDHC_WML_WR_BRST_MASK (0x0F000000) |
| 96 | #define ESDHC_WML_RD_BRST_MASK (0x00000F00) |
| 97 | #define ESDHC_WML_RD_WML_MASK (0x0000007F) |
| 98 | #define ESDHC_WML_WR_WML_MASK (0x007F0000) |
| 99 | #define WML_512_BYTES (0x0) |
| 100 | #define BURST_128_BYTES (0x0) |
| 101 | |
| 102 | /* eSDHC control register define */ |
| 103 | #define ESDHC_DCR_SNOOP 0x00000040 |
| 104 | |
| 105 | /* ESDHC Block attributes register */ |
| 106 | #define ESDHC_BLKATTR_BLKCNT(c) (((c) & 0xffff) << 16) |
| 107 | #define ESDHC_BLKATTR_BLKSZE(s) ((s) & 0xfff) |
| 108 | |
| 109 | /* Transfer Type Register */ |
| 110 | #define ESDHC_XFERTYP_CMD(c) (((c) & 0x3F) << 24) |
| 111 | #define ESDHC_XFERTYP_CMDTYP_NORMAL (0x0) |
| 112 | #define ESDHC_XFERTYP_CMDTYP_SUSPEND (0x00400000) |
| 113 | #define ESDHC_XFERTYP_CMDTYP_RESUME (0x00800000) |
| 114 | #define ESDHC_XFERTYP_CMDTYP_ABORT (0x00C00000) |
| 115 | #define ESDHC_XFERTYP_DPSEL (0x00200000) |
| 116 | #define ESDHC_XFERTYP_CICEN (0x00100000) |
| 117 | #define ESDHC_XFERTYP_CCCEN (0x00080000) |
| 118 | #define ESDHC_XFERTYP_RSPTYP_NONE (0x0) |
| 119 | #define ESDHC_XFERTYP_RSPTYP_136 (0x00010000) |
| 120 | #define ESDHC_XFERTYP_RSPTYP_48 (0x00020000) |
| 121 | #define ESDHC_XFERTYP_RSPTYP_48_BUSY (0x00030000) |
| 122 | #define ESDHC_XFERTYP_MSBSEL (0x00000020) |
| 123 | #define ESDHC_XFERTYP_DTDSEL (0x00000010) |
| 124 | #define ESDHC_XFERTYP_AC12EN (0x00000004) |
| 125 | #define ESDHC_XFERTYP_BCEN (0x00000002) |
| 126 | #define ESDHC_XFERTYP_DMAEN (0x00000001) |
| 127 | |
| 128 | #define MMC_VDD_HIGH_VOLTAGE 0x00000100 |
| 129 | |
| 130 | /* command index */ |
| 131 | #define CMD0 0 |
| 132 | #define CMD1 1 |
| 133 | #define CMD2 2 |
| 134 | #define CMD3 3 |
| 135 | #define CMD5 5 |
| 136 | #define CMD6 6 |
| 137 | #define CMD7 7 |
| 138 | #define CMD8 8 |
| 139 | #define CMD9 9 |
| 140 | #define CMD12 12 |
| 141 | #define CMD13 13 |
| 142 | #define CMD14 14 |
| 143 | #define CMD16 16 |
| 144 | #define CMD17 17 |
| 145 | #define CMD18 18 |
| 146 | #define CMD19 19 |
| 147 | #define CMD24 24 |
| 148 | #define CMD41 41 |
| 149 | #define CMD42 42 |
| 150 | #define CMD51 51 |
| 151 | #define CMD55 55 |
| 152 | #define CMD56 56 |
| 153 | #define ACMD6 CMD6 |
| 154 | #define ACMD13 CMD13 |
| 155 | #define ACMD41 CMD41 |
| 156 | #define ACMD42 CMD42 |
| 157 | #define ACMD51 CMD51 |
| 158 | |
| 159 | /* commands abbreviations */ |
| 160 | #define CMD_GO_IDLE_STATE CMD0 |
| 161 | #define CMD_MMC_SEND_OP_COND CMD1 |
| 162 | #define CMD_ALL_SEND_CID CMD2 |
| 163 | #define CMD_SEND_RELATIVE_ADDR CMD3 |
| 164 | #define CMD_SET_DSR CMD4 |
| 165 | #define CMD_SWITCH_FUNC CMD6 |
| 166 | #define CMD_SELECT_CARD CMD7 |
| 167 | #define CMD_DESELECT_CARD CMD7 |
| 168 | #define CMD_SEND_IF_COND CMD8 |
| 169 | #define CMD_MMC_SEND_EXT_CSD CMD8 |
| 170 | #define CMD_SEND_CSD CMD9 |
| 171 | #define CMD_SEND_CID CMD10 |
| 172 | #define CMD_STOP_TRANSMISSION CMD12 |
| 173 | #define CMD_SEND_STATUS CMD13 |
| 174 | #define CMD_BUS_TEST_R CMD14 |
| 175 | #define CMD_GO_INACTIVE_STATE CMD15 |
| 176 | #define CMD_SET_BLOCKLEN CMD16 |
| 177 | #define CMD_READ_SINGLE_BLOCK CMD17 |
| 178 | #define CMD_READ_MULTIPLE_BLOCK CMD18 |
| 179 | #define CMD_WRITE_SINGLE_BLOCK CMD24 |
| 180 | #define CMD_BUS_TEST_W CMD19 |
| 181 | #define CMD_APP_CMD CMD55 |
| 182 | #define CMD_GEN_CMD CMD56 |
| 183 | #define CMD_SET_BUS_WIDTH ACMD6 |
| 184 | #define CMD_SD_STATUS ACMD13 |
| 185 | #define CMD_SD_SEND_OP_COND ACMD41 |
| 186 | #define CMD_SET_CLR_CARD_DETECT ACMD42 |
| 187 | #define CMD_SEND_SCR ACMD51 |
| 188 | |
| 189 | /* MMC card spec version */ |
| 190 | #define MMC_CARD_VERSION_1_2 0 |
| 191 | #define MMC_CARD_VERSION_1_4 1 |
| 192 | #define MMC_CARD_VERSION_2_X 2 |
| 193 | #define MMC_CARD_VERSION_3_X 3 |
| 194 | #define MMC_CARD_VERSION_4_X 4 |
| 195 | |
| 196 | /* SD Card Spec Version */ |
| 197 | /* May need to add version 3 here? */ |
| 198 | #define SD_CARD_VERSION_1_0 0 |
| 199 | #define SD_CARD_VERSION_1_10 1 |
| 200 | #define SD_CARD_VERSION_2_0 2 |
| 201 | |
| 202 | /* card types */ |
| 203 | #define MMC_CARD 0 |
| 204 | #define SD_CARD 1 |
| 205 | #define NOT_SD_CARD MMC_CARD |
| 206 | |
| 207 | /* Card rca */ |
| 208 | #define SD_MMC_CARD_RCA 0x1 |
| 209 | #define BLOCK_LEN_512 512 |
| 210 | |
| 211 | /* card state */ |
| 212 | #define STATE_IDLE 0 |
| 213 | #define STATE_READY 1 |
| 214 | #define STATE_IDENT 2 |
| 215 | #define STATE_STBY 3 |
| 216 | #define STATE_TRAN 4 |
| 217 | #define STATE_DATA 5 |
| 218 | #define STATE_RCV 6 |
| 219 | #define STATE_PRG 7 |
| 220 | #define STATE_DIS 8 |
| 221 | |
| 222 | /* Card OCR register */ |
| 223 | /* VDD voltage window 1,65 to 1.95 */ |
| 224 | #define MMC_OCR_VDD_165_195 0x00000080 |
| 225 | /* VDD voltage window 2.7-2.8 */ |
| 226 | #define MMC_OCR_VDD_FF8 0x00FF8000 |
| 227 | #define MMC_OCR_CCS 0x40000000/* Card Capacity */ |
| 228 | #define MMC_OCR_BUSY 0x80000000/* busy bit */ |
| 229 | #define SD_OCR_HCS 0x40000000/* High capacity host */ |
| 230 | #define MMC_OCR_SECTOR_MODE 0x40000000/* Access Mode as Sector */ |
| 231 | |
| 232 | /* mmc Switch function */ |
| 233 | #define SET_EXT_CSD_HS_TIMING 0x03B90100/* set High speed */ |
| 234 | |
| 235 | /* check supports switching or not */ |
| 236 | #define SD_SWITCH_FUNC_CHECK_MODE 0x00FFFFF1 |
| 237 | #define SD_SWITCH_FUNC_SWITCH_MODE 0x80FFFFF1/* switch */ |
| 238 | #define SD_SWITCH_FUNC_HIGH_SPEED 0x02/* HIGH SPEED FUNC */ |
| 239 | #define SWITCH_ERROR 0x00000080 |
| 240 | |
| 241 | /* errors in sending commands */ |
| 242 | #define RESP_TIMEOUT 0x1 |
| 243 | #define COMMAND_ERROR 0x2 |
| 244 | /* error in response */ |
| 245 | #define R1_ERROR (1 << 19) |
| 246 | #define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) |
| 247 | |
| 248 | /* Host Controller Capabilities */ |
| 249 | #define ESDHC_HOSTCAPBLT_DMAS (0x00400000) |
| 250 | |
| 251 | |
| 252 | /* SD/MMC memory map */ |
| 253 | struct esdhc_regs { |
| 254 | uint32_t dsaddr; /* dma system address */ |
| 255 | uint32_t blkattr; /* Block attributes */ |
| 256 | uint32_t cmdarg; /* Command argument */ |
| 257 | uint32_t xfertyp; /* Command transfer type */ |
| 258 | uint32_t cmdrsp[4]; /* Command response0,1,2,3 */ |
| 259 | uint32_t datport; /* Data buffer access port */ |
| 260 | uint32_t prsstat; /* Present state */ |
| 261 | uint32_t proctl; /* Protocol control */ |
| 262 | uint32_t sysctl; /* System control */ |
| 263 | uint32_t irqstat; /* Interrupt status */ |
| 264 | uint32_t irqstaten; /* Interrupt status enable */ |
| 265 | uint32_t irqsigen; /* Interrupt signal enable */ |
| 266 | uint32_t autoc12err; /* Auto CMD12 status */ |
| 267 | uint32_t hostcapblt; /* Host controller capabilities */ |
| 268 | uint32_t wml; /* Watermark level */ |
| 269 | uint32_t res1[2]; |
| 270 | uint32_t fevt; /* Force event */ |
| 271 | uint32_t res2; |
| 272 | uint32_t adsaddrl; |
| 273 | uint32_t adsaddrh; |
| 274 | uint32_t res3[39]; |
| 275 | uint32_t hostver; /* Host controller version */ |
| 276 | uint32_t res4; |
| 277 | uint32_t dmaerr; /* DMA error address */ |
| 278 | uint32_t dmaerrh; /* DMA error address high */ |
| 279 | uint32_t dmaerrattr; /* DMA error atrribute */ |
| 280 | uint32_t res5; |
| 281 | uint32_t hostcapblt2;/* Host controller capabilities2 */ |
| 282 | uint32_t res6[2]; |
| 283 | uint32_t tcr; /* Tuning control */ |
| 284 | uint32_t res7[7]; |
| 285 | uint32_t dirctrl; /* Direction control */ |
| 286 | uint32_t ccr; /* Clock control */ |
| 287 | uint32_t res8[177]; |
| 288 | uint32_t ctl; /* Control register */ |
| 289 | }; |
| 290 | |
| 291 | /* SD/MMC card attributes */ |
| 292 | struct card_attributes { |
| 293 | uint32_t type; /* sd or mmc card */ |
| 294 | uint32_t version; /* version */ |
| 295 | uint32_t block_len; /* block length */ |
| 296 | uint32_t bus_freq; /* sdhc bus frequency */ |
| 297 | uint16_t rca; /* relative card address */ |
| 298 | uint8_t is_high_capacity; /* high capacity */ |
| 299 | }; |
| 300 | |
| 301 | struct mmc { |
| 302 | struct esdhc_regs *esdhc_regs; |
| 303 | struct card_attributes card; |
| 304 | |
| 305 | uint32_t block_len; |
| 306 | uint32_t voltages_caps; /* supported voltaes */ |
| 307 | uint32_t dma_support; /* DMA support */ |
| 308 | }; |
| 309 | |
| 310 | enum cntrl_num { |
| 311 | SDHC1 = 0, |
| 312 | SDHC2 |
| 313 | }; |
| 314 | |
| 315 | int sd_emmc_init(uintptr_t *block_dev_spec, |
| 316 | uintptr_t nxp_esdhc_addr, |
| 317 | size_t nxp_sd_block_offset, |
| 318 | size_t nxp_sd_block_size, |
| 319 | bool card_detect); |
| 320 | |
| 321 | int esdhc_emmc_init(struct mmc *mmc, bool card_detect); |
| 322 | int esdhc_read(struct mmc *mmc, uint32_t src_offset, uintptr_t dst, |
| 323 | size_t size); |
| 324 | int esdhc_write(struct mmc *mmc, uintptr_t src, uint32_t dst_offset, |
| 325 | size_t size); |
| 326 | |
| 327 | #ifdef NXP_ESDHC_BE |
| 328 | #define esdhc_in32(a) bswap32(mmio_read_32((uintptr_t)(a))) |
| 329 | #define esdhc_out32(a, v) mmio_write_32((uintptr_t)(a), bswap32(v)) |
| 330 | #elif defined(NXP_ESDHC_LE) |
| 331 | #define esdhc_in32(a) mmio_read_32((uintptr_t)(a)) |
| 332 | #define esdhc_out32(a, v) mmio_write_32((uintptr_t)(a), (v)) |
| 333 | #else |
| 334 | #error Please define CCSR ESDHC register endianness |
| 335 | #endif |
| 336 | |
| 337 | #endif /*SD_MMC_H*/ |