1 /* $NetBSD: pl181.c,v 1.4 2017/06/04 15:08:30 jmcneill Exp $ */ 2 3 /*- 4 * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: pl181.c,v 1.4 2017/06/04 15:08:30 jmcneill Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/device.h> 35 #include <sys/intr.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 39 #include <dev/sdmmc/sdmmcvar.h> 40 #include <dev/sdmmc/sdmmcchip.h> 41 #include <dev/sdmmc/sdmmc_ioreg.h> 42 43 #include <dev/ic/pl181reg.h> 44 #include <dev/ic/pl181var.h> 45 46 /* 47 * Data length register is 16 bits for a maximum of 65535 bytes. Round 48 * maximum transfer size down to the nearest sector. 49 */ 50 #define PLMMC_MAXXFER rounddown(65535, SDMMC_SECTOR_SIZE) 51 52 static int plmmc_host_reset(sdmmc_chipset_handle_t); 53 static uint32_t plmmc_host_ocr(sdmmc_chipset_handle_t); 54 static int plmmc_host_maxblklen(sdmmc_chipset_handle_t); 55 static int plmmc_card_detect(sdmmc_chipset_handle_t); 56 static int plmmc_write_protect(sdmmc_chipset_handle_t); 57 static int plmmc_bus_power(sdmmc_chipset_handle_t, uint32_t); 58 static int plmmc_bus_clock(sdmmc_chipset_handle_t, int); 59 static int plmmc_bus_width(sdmmc_chipset_handle_t, int); 60 static int plmmc_bus_rod(sdmmc_chipset_handle_t, int); 61 static void plmmc_exec_command(sdmmc_chipset_handle_t, 62 struct sdmmc_command *); 63 static void plmmc_card_enable_intr(sdmmc_chipset_handle_t, int); 64 static void plmmc_card_intr_ack(sdmmc_chipset_handle_t); 65 66 static int plmmc_wait_status(struct plmmc_softc *, uint32_t, int); 67 static int plmmc_pio_wait(struct plmmc_softc *, 68 struct sdmmc_command *); 69 static int plmmc_pio_transfer(struct plmmc_softc *, 70 struct sdmmc_command *, int); 71 72 static struct sdmmc_chip_functions plmmc_chip_functions = { 73 .host_reset = plmmc_host_reset, 74 .host_ocr = plmmc_host_ocr, 75 .host_maxblklen = plmmc_host_maxblklen, 76 .card_detect = plmmc_card_detect, 77 .write_protect = plmmc_write_protect, 78 .bus_power = plmmc_bus_power, 79 .bus_clock = plmmc_bus_clock, 80 .bus_width = plmmc_bus_width, 81 .bus_rod = plmmc_bus_rod, 82 .exec_command = plmmc_exec_command, 83 .card_enable_intr = plmmc_card_enable_intr, 84 .card_intr_ack = plmmc_card_intr_ack, 85 }; 86 87 #define MMCI_WRITE(sc, reg, val) \ 88 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 89 #define MMCI_READ(sc, reg) \ 90 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 91 92 void 93 plmmc_init(struct plmmc_softc *sc) 94 { 95 struct sdmmcbus_attach_args saa; 96 97 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO); 98 cv_init(&sc->sc_intr_cv, "plmmcirq"); 99 100 #ifdef PLMMC_DEBUG 101 device_printf(sc->sc_dev, "PeriphID %#x %#x %#x %#x\n", 102 MMCI_READ(sc, MMCI_PERIPH_ID0_REG), 103 MMCI_READ(sc, MMCI_PERIPH_ID1_REG), 104 MMCI_READ(sc, MMCI_PERIPH_ID2_REG), 105 MMCI_READ(sc, MMCI_PERIPH_ID3_REG)); 106 device_printf(sc->sc_dev, "PCellID %#x %#x %#x %#x\n", 107 MMCI_READ(sc, MMCI_PCELL_ID0_REG), 108 MMCI_READ(sc, MMCI_PCELL_ID1_REG), 109 MMCI_READ(sc, MMCI_PCELL_ID2_REG), 110 MMCI_READ(sc, MMCI_PCELL_ID3_REG)); 111 #endif 112 113 plmmc_bus_clock(sc, 400); 114 MMCI_WRITE(sc, MMCI_POWER_REG, 0); 115 delay(10000); 116 MMCI_WRITE(sc, MMCI_POWER_REG, MMCI_POWER_CTRL_POWERUP); 117 delay(10000); 118 MMCI_WRITE(sc, MMCI_POWER_REG, MMCI_POWER_CTRL_POWERON); 119 plmmc_host_reset(sc); 120 121 memset(&saa, 0, sizeof(saa)); 122 saa.saa_busname = "sdmmc"; 123 saa.saa_sct = &plmmc_chip_functions; 124 saa.saa_sch = sc; 125 saa.saa_clkmin = 400; 126 saa.saa_clkmax = sc->sc_max_freq > 0 ? 127 sc->sc_max_freq / 1000 : sc->sc_clock_freq / 1000; 128 saa.saa_caps = SMC_CAPS_4BIT_MODE; 129 130 sc->sc_sdmmc_dev = config_found(sc->sc_dev, &saa, NULL); 131 } 132 133 int 134 plmmc_intr(void *priv) 135 { 136 struct plmmc_softc *sc = priv; 137 uint32_t status; 138 139 mutex_enter(&sc->sc_intr_lock); 140 status = MMCI_READ(sc, MMCI_STATUS_REG); 141 #ifdef PLMMC_DEBUG 142 printf("%s: MMCI_STATUS_REG = %#x\n", __func__, status); 143 #endif 144 if (!status) { 145 mutex_exit(&sc->sc_intr_lock); 146 return 0; 147 } 148 149 sc->sc_intr_status |= status; 150 cv_broadcast(&sc->sc_intr_cv); 151 152 mutex_exit(&sc->sc_intr_lock); 153 154 return 1; 155 } 156 157 static int 158 plmmc_wait_status(struct plmmc_softc *sc, uint32_t mask, int timeout) 159 { 160 int retry, error; 161 162 KASSERT(mutex_owned(&sc->sc_intr_lock)); 163 164 if (sc->sc_intr_status & mask) 165 return 0; 166 167 retry = timeout / hz; 168 if (sc->sc_ih == NULL) 169 retry *= 1000; 170 171 while (retry > 0) { 172 if (sc->sc_ih == NULL) { 173 sc->sc_intr_status |= MMCI_READ(sc, MMCI_STATUS_REG); 174 if (sc->sc_intr_status & mask) 175 return 0; 176 delay(10000); 177 } else { 178 error = cv_timedwait(&sc->sc_intr_cv, 179 &sc->sc_intr_lock, hz); 180 if (error && error != EWOULDBLOCK) { 181 device_printf(sc->sc_dev, 182 "cv_timedwait returned %d\n", error); 183 return error; 184 } 185 if (sc->sc_intr_status & mask) 186 return 0; 187 } 188 --retry; 189 } 190 191 device_printf(sc->sc_dev, "%s timeout, MMCI_STATUS_REG = %#x\n", 192 __func__, MMCI_READ(sc, MMCI_STATUS_REG)); 193 194 return ETIMEDOUT; 195 } 196 197 static int 198 plmmc_pio_wait(struct plmmc_softc *sc, struct sdmmc_command *cmd) 199 { 200 uint32_t bit = (cmd->c_flags & SCF_CMD_READ) ? 201 MMCI_INT_RX_DATA_AVAIL : MMCI_INT_TX_FIFO_EMPTY; 202 203 MMCI_WRITE(sc, MMCI_CLEAR_REG, bit); 204 const int error = plmmc_wait_status(sc, 205 bit | MMCI_INT_DATA_END | MMCI_INT_DATA_BLOCK_END, hz*2); 206 sc->sc_intr_status &= ~bit; 207 208 return error; 209 } 210 211 static int 212 plmmc_pio_transfer(struct plmmc_softc *sc, struct sdmmc_command *cmd, 213 int xferlen) 214 { 215 uint32_t *datap = (uint32_t *)cmd->c_buf; 216 int i; 217 218 for (i = 0; i < xferlen / 4; i++) { 219 if (plmmc_pio_wait(sc, cmd)) 220 return ETIMEDOUT; 221 if (cmd->c_flags & SCF_CMD_READ) { 222 datap[i] = MMCI_READ(sc, MMCI_FIFO_REG); 223 } else { 224 MMCI_WRITE(sc, MMCI_FIFO_REG, datap[i]); 225 } 226 cmd->c_resid -= 4; 227 cmd->c_buf += 4; 228 } 229 230 return 0; 231 } 232 233 static int 234 plmmc_host_reset(sdmmc_chipset_handle_t sch) 235 { 236 struct plmmc_softc *sc = sch; 237 238 MMCI_WRITE(sc, MMCI_MASK0_REG, 0); 239 MMCI_WRITE(sc, MMCI_MASK1_REG, 0); 240 MMCI_WRITE(sc, MMCI_CLEAR_REG, 0xffffffff); 241 242 return 0; 243 } 244 245 static uint32_t 246 plmmc_host_ocr(sdmmc_chipset_handle_t sch) 247 { 248 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V; 249 } 250 251 static int 252 plmmc_host_maxblklen(sdmmc_chipset_handle_t sch) 253 { 254 return 2048; 255 } 256 257 static int 258 plmmc_card_detect(sdmmc_chipset_handle_t sch) 259 { 260 return 1; 261 } 262 263 static int 264 plmmc_write_protect(sdmmc_chipset_handle_t sch) 265 { 266 return 0; 267 } 268 269 static int 270 plmmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 271 { 272 return 0; 273 } 274 275 static int 276 plmmc_bus_clock(sdmmc_chipset_handle_t sch, int freq) 277 { 278 struct plmmc_softc *sc = sch; 279 u_int pll_freq, clk_div; 280 uint32_t clock; 281 282 clock = MMCI_CLOCK_PWRSAVE; 283 if (freq) { 284 pll_freq = sc->sc_clock_freq / 1000; 285 clk_div = (howmany(pll_freq, freq) >> 1) - 1; 286 clock |= __SHIFTIN(clk_div, MMCI_CLOCK_CLKDIV); 287 clock |= MMCI_CLOCK_ENABLE; 288 } 289 MMCI_WRITE(sc, MMCI_CLOCK_REG, clock); 290 291 return 0; 292 } 293 294 static int 295 plmmc_bus_width(sdmmc_chipset_handle_t sch, int width) 296 { 297 return 0; 298 } 299 300 static int 301 plmmc_bus_rod(sdmmc_chipset_handle_t sch, int on) 302 { 303 struct plmmc_softc *sc = sch; 304 uint32_t power; 305 306 307 power = MMCI_READ(sc, MMCI_POWER_REG); 308 if (on) { 309 power |= MMCI_POWER_ROD; 310 } else { 311 power &= ~MMCI_POWER_ROD; 312 } 313 MMCI_WRITE(sc, MMCI_POWER_REG, power); 314 315 return 0; 316 } 317 318 static void 319 plmmc_do_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 320 { 321 struct plmmc_softc *sc = sch; 322 uint32_t cmdval = MMCI_COMMAND_ENABLE; 323 324 KASSERT(mutex_owned(&sc->sc_intr_lock)); 325 326 const int xferlen = min(cmd->c_resid, PLMMC_MAXXFER); 327 328 #ifdef PLMMC_DEBUG 329 device_printf(sc->sc_dev, 330 "opcode %d flags %#x datalen %d resid %d xferlen %d\n", 331 cmd->c_opcode, cmd->c_flags, cmd->c_datalen, cmd->c_resid, xferlen); 332 #endif 333 334 MMCI_WRITE(sc, MMCI_COMMAND_REG, 0); 335 MMCI_WRITE(sc, MMCI_MASK0_REG, 0); 336 MMCI_WRITE(sc, MMCI_CLEAR_REG, 0xffffffff); 337 MMCI_WRITE(sc, MMCI_MASK0_REG, 338 MMCI_INT_CMD_TIMEOUT | MMCI_INT_DATA_TIMEOUT | 339 MMCI_INT_RX_DATA_AVAIL | MMCI_INT_TX_FIFO_EMPTY | 340 MMCI_INT_DATA_END | MMCI_INT_DATA_BLOCK_END | 341 MMCI_INT_CMD_RESP_END | MMCI_INT_CMD_SENT); 342 343 sc->sc_intr_status = 0; 344 345 if (cmd->c_flags & SCF_RSP_PRESENT) 346 cmdval |= MMCI_COMMAND_RESPONSE; 347 if (cmd->c_flags & SCF_RSP_136) 348 cmdval |= MMCI_COMMAND_LONGRSP; 349 350 uint32_t arg = cmd->c_arg; 351 352 if (xferlen > 0) { 353 unsigned int nblks = xferlen / cmd->c_blklen; 354 if (nblks == 0 || (xferlen % cmd->c_blklen) != 0) 355 ++nblks; 356 357 const uint32_t dir = (cmd->c_flags & SCF_CMD_READ) ? 1 : 0; 358 const uint32_t blksize = ffs(cmd->c_blklen) - 1; 359 360 MMCI_WRITE(sc, MMCI_DATA_TIMER_REG, 0xffffffff); 361 MMCI_WRITE(sc, MMCI_DATA_LENGTH_REG, nblks * cmd->c_blklen); 362 MMCI_WRITE(sc, MMCI_DATA_CTRL_REG, 363 __SHIFTIN(dir, MMCI_DATA_CTRL_DIRECTION) | 364 __SHIFTIN(blksize, MMCI_DATA_CTRL_BLOCKSIZE) | 365 MMCI_DATA_CTRL_ENABLE); 366 367 /* Adjust blkno if necessary */ 368 u_int blkoff = 369 (cmd->c_datalen - cmd->c_resid) / SDMMC_SECTOR_SIZE; 370 if (!ISSET(cmd->c_flags, SCF_XFER_SDHC)) 371 blkoff <<= SDMMC_SECTOR_SIZE_SB; 372 arg += blkoff; 373 } 374 375 MMCI_WRITE(sc, MMCI_ARGUMENT_REG, arg); 376 MMCI_WRITE(sc, MMCI_COMMAND_REG, cmdval | cmd->c_opcode); 377 378 if (xferlen > 0) { 379 cmd->c_error = plmmc_pio_transfer(sc, cmd, xferlen); 380 if (cmd->c_error) { 381 device_printf(sc->sc_dev, 382 "error (%d) waiting for xfer\n", cmd->c_error); 383 goto done; 384 } 385 } 386 387 if ((cmd->c_flags & SCF_RSP_PRESENT) && cmd->c_resid == 0) { 388 cmd->c_error = plmmc_wait_status(sc, 389 MMCI_INT_CMD_RESP_END|MMCI_INT_CMD_TIMEOUT, hz * 2); 390 if (cmd->c_error == 0 && 391 (sc->sc_intr_status & MMCI_INT_CMD_TIMEOUT)) { 392 cmd->c_error = ETIMEDOUT; 393 } 394 if (cmd->c_error) { 395 #ifdef PLMMC_DEBUG 396 device_printf(sc->sc_dev, 397 "error (%d) waiting for resp\n", cmd->c_error); 398 #endif 399 goto done; 400 } 401 402 if (cmd->c_flags & SCF_RSP_136) { 403 cmd->c_resp[3] = MMCI_READ(sc, MMCI_RESP0_REG); 404 cmd->c_resp[2] = MMCI_READ(sc, MMCI_RESP1_REG); 405 cmd->c_resp[1] = MMCI_READ(sc, MMCI_RESP2_REG); 406 cmd->c_resp[0] = MMCI_READ(sc, MMCI_RESP3_REG); 407 if (cmd->c_flags & SCF_RSP_CRC) { 408 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 409 (cmd->c_resp[1] << 24); 410 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 411 (cmd->c_resp[2] << 24); 412 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 413 (cmd->c_resp[3] << 24); 414 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 415 } 416 } else { 417 cmd->c_resp[0] = MMCI_READ(sc, MMCI_RESP0_REG); 418 } 419 } 420 421 done: 422 MMCI_WRITE(sc, MMCI_COMMAND_REG, 0); 423 MMCI_WRITE(sc, MMCI_MASK0_REG, 0); 424 MMCI_WRITE(sc, MMCI_CLEAR_REG, 0xffffffff); 425 MMCI_WRITE(sc, MMCI_DATA_CNT_REG, 0); 426 427 #ifdef PLMMC_DEBUG 428 device_printf(sc->sc_dev, "MMCI_STATUS_REG = %#x\n", 429 MMCI_READ(sc, MMCI_STATUS_REG)); 430 #endif 431 } 432 433 static void 434 plmmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 435 { 436 struct plmmc_softc *sc = sch; 437 438 #ifdef PLMMC_DEBUG 439 device_printf(sc->sc_dev, "opcode %d flags %#x data %p datalen %d\n", 440 cmd->c_opcode, cmd->c_flags, cmd->c_data, cmd->c_datalen); 441 #endif 442 443 mutex_enter(&sc->sc_intr_lock); 444 cmd->c_resid = cmd->c_datalen; 445 cmd->c_buf = cmd->c_data; 446 do { 447 plmmc_do_command(sch, cmd); 448 449 if (cmd->c_resid > 0 && cmd->c_error == 0) { 450 /* 451 * Multi block transfer and there is still data 452 * remaining. Send a stop cmd between transfers. 453 */ 454 struct sdmmc_command stop_cmd; 455 memset(&stop_cmd, 0, sizeof(stop_cmd)); 456 stop_cmd.c_opcode = MMC_STOP_TRANSMISSION; 457 stop_cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B | 458 SCF_RSP_SPI_R1B; 459 plmmc_do_command(sch, &stop_cmd); 460 } 461 } while (cmd->c_resid > 0 && cmd->c_error == 0); 462 cmd->c_flags |= SCF_ITSDONE; 463 mutex_exit(&sc->sc_intr_lock); 464 } 465 466 static void 467 plmmc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) 468 { 469 } 470 471 static void 472 plmmc_card_intr_ack(sdmmc_chipset_handle_t sch) 473 { 474 } 475