mmc.c revision 183763
1163516Simp/*- 2163516Simp * Copyright (c) 2006 Bernd Walter. All rights reserved. 3163516Simp * Copyright (c) 2006 M. Warner Losh. All rights reserved. 4163516Simp * 5163516Simp * Redistribution and use in source and binary forms, with or without 6163516Simp * modification, are permitted provided that the following conditions 7163516Simp * are met: 8163516Simp * 1. Redistributions of source code must retain the above copyright 9163516Simp * notice, this list of conditions and the following disclaimer. 10163516Simp * 2. Redistributions in binary form must reproduce the above copyright 11163516Simp * notice, this list of conditions and the following disclaimer in the 12163516Simp * documentation and/or other materials provided with the distribution. 13163516Simp * 14163516Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15163516Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16163516Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17163516Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18163516Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19163516Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20163516Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21163516Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22163516Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23163516Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24170002Simp * 25170002Simp * Portions of this software may have been developed with reference to 26170002Simp * the SD Simplified Specification. The following disclaimer may apply: 27170002Simp * 28170002Simp * The following conditions apply to the release of the simplified 29170002Simp * specification ("Simplified Specification") by the SD Card Association and 30170002Simp * the SD Group. The Simplified Specification is a subset of the complete SD 31170002Simp * Specification which is owned by the SD Card Association and the SD 32170002Simp * Group. This Simplified Specification is provided on a non-confidential 33170002Simp * basis subject to the disclaimers below. Any implementation of the 34170002Simp * Simplified Specification may require a license from the SD Card 35170002Simp * Association, SD Group, SD-3C LLC or other third parties. 36170002Simp * 37170002Simp * Disclaimers: 38170002Simp * 39170002Simp * The information contained in the Simplified Specification is presented only 40170002Simp * as a standard specification for SD Cards and SD Host/Ancillary products and 41170002Simp * is provided "AS-IS" without any representations or warranties of any 42170002Simp * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD 43170002Simp * Card Association for any damages, any infringements of patents or other 44170002Simp * right of the SD Group, SD-3C LLC, the SD Card Association or any third 45170002Simp * parties, which may result from its use. No license is granted by 46170002Simp * implication, estoppel or otherwise under any patent or other rights of the 47170002Simp * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing 48170002Simp * herein shall be construed as an obligation by the SD Group, the SD-3C LLC 49170002Simp * or the SD Card Association to disclose or distribute any technical 50170002Simp * information, know-how or other confidential information to any third party. 51163516Simp */ 52163516Simp 53163516Simp#include <sys/cdefs.h> 54163516Simp__FBSDID("$FreeBSD: head/sys/dev/mmc/mmc.c 183763 2008-10-11 13:05:13Z mav $"); 55163516Simp 56163516Simp#include <sys/param.h> 57163516Simp#include <sys/systm.h> 58163516Simp#include <sys/kernel.h> 59163516Simp#include <sys/malloc.h> 60163516Simp#include <sys/lock.h> 61163516Simp#include <sys/module.h> 62163516Simp#include <sys/mutex.h> 63163516Simp#include <sys/bus.h> 64183704Smav#include <sys/endian.h> 65163516Simp 66163516Simp#include <dev/mmc/mmcreg.h> 67163516Simp#include <dev/mmc/mmcbrvar.h> 68163516Simp#include <dev/mmc/mmcvar.h> 69163516Simp#include "mmcbr_if.h" 70163516Simp#include "mmcbus_if.h" 71163516Simp 72163516Simpstruct mmc_softc { 73163516Simp device_t dev; 74163516Simp struct mtx sc_mtx; 75163516Simp struct intr_config_hook config_intrhook; 76163516Simp device_t owner; 77163516Simp uint32_t last_rca; 78163516Simp}; 79163516Simp 80163516Simp/* 81163516Simp * Per-card data 82163516Simp */ 83163516Simpstruct mmc_ivars { 84163516Simp uint32_t raw_cid[4]; /* Raw bits of the CID */ 85163516Simp uint32_t raw_csd[4]; /* Raw bits of the CSD */ 86183704Smav uint32_t raw_scr[2]; /* Raw bits of the SCR */ 87183704Smav uint8_t raw_ext_csd[512]; /* Raw bits of the EXT_CSD */ 88163516Simp uint16_t rca; 89163516Simp enum mmc_card_mode mode; 90163516Simp struct mmc_cid cid; /* cid decoded */ 91163516Simp struct mmc_csd csd; /* csd decoded */ 92183704Smav struct mmc_scr scr; /* scr decoded */ 93183447Simp u_char read_only; /* True when the device is read-only */ 94183704Smav u_char bus_width; /* Bus width to use */ 95183704Smav u_char timing; /* Bus timing support */ 96183731Smav u_char high_cap; /* High Capacity card (block addressed) */ 97183731Smav uint32_t sec_count; /* Card capacity in 512byte blocks */ 98183704Smav uint32_t tran_speed; /* Max speed in normal mode */ 99183704Smav uint32_t hs_tran_speed; /* Max speed in high speed mode */ 100163516Simp}; 101163516Simp 102163516Simp#define CMD_RETRIES 3 103163516Simp 104163516Simp/* bus entry points */ 105163516Simpstatic int mmc_probe(device_t dev); 106163516Simpstatic int mmc_attach(device_t dev); 107163516Simpstatic int mmc_detach(device_t dev); 108163516Simp 109163516Simp#define MMC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 110163516Simp#define MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 111183444Simp#define MMC_LOCK_INIT(_sc) \ 112183444Simp mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ 113163516Simp "mmc", MTX_DEF) 114163516Simp#define MMC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 115163516Simp#define MMC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 116163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 117163516Simp 118183763Smavstatic int mmc_calculate_clock(struct mmc_softc *sc); 119163516Simpstatic void mmc_delayed_attach(void *); 120183449Simpstatic void mmc_power_down(struct mmc_softc *sc); 121163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, 122163516Simp int retries); 123163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 124163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries); 125183704Smavstatic int mmc_select_card(struct mmc_softc *sc, uint16_t rca); 126183763Smavstatic int mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width); 127183704Smavstatic int mmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr); 128183704Smavstatic void mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr); 129183704Smavstatic int mmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd); 130163516Simp 131163516Simpstatic void 132163516Simpmmc_ms_delay(int ms) 133163516Simp{ 134163516Simp DELAY(1000 * ms); /* XXX BAD */ 135163516Simp} 136163516Simp 137163516Simpstatic int 138163516Simpmmc_probe(device_t dev) 139163516Simp{ 140163516Simp 141183445Simp device_set_desc(dev, "MMC/SD bus"); 142163516Simp return (0); 143163516Simp} 144163516Simp 145163516Simpstatic int 146163516Simpmmc_attach(device_t dev) 147163516Simp{ 148163516Simp struct mmc_softc *sc; 149163516Simp 150163516Simp sc = device_get_softc(dev); 151163516Simp sc->dev = dev; 152163516Simp MMC_LOCK_INIT(sc); 153163516Simp 154163516Simp /* We'll probe and attach our children later, but before / mount */ 155163516Simp sc->config_intrhook.ich_func = mmc_delayed_attach; 156163516Simp sc->config_intrhook.ich_arg = sc; 157163516Simp if (config_intrhook_establish(&sc->config_intrhook) != 0) 158163516Simp device_printf(dev, "config_intrhook_establish failed\n"); 159163516Simp return (0); 160163516Simp} 161163516Simp 162163516Simpstatic int 163163516Simpmmc_detach(device_t dev) 164163516Simp{ 165169567Simp struct mmc_softc *sc = device_get_softc(dev); 166169567Simp device_t *kids; 167169567Simp int i, nkid; 168169567Simp 169169567Simp /* kill children [ph33r]. -sorbo */ 170169567Simp if (device_get_children(sc->dev, &kids, &nkid) != 0) 171183467Simp return (0); 172169567Simp for (i = 0; i < nkid; i++) { 173169567Simp device_t kid = kids[i]; 174169567Simp void *ivar = device_get_ivars(kid); 175169567Simp 176169567Simp device_detach(kid); 177169567Simp device_delete_child(sc->dev, kid); 178169567Simp free(ivar, M_DEVBUF); 179169567Simp } 180169567Simp free(kids, M_TEMP); 181183449Simp mmc_power_down(sc); 182169567Simp 183169567Simp MMC_LOCK_DESTROY(sc); 184169567Simp 185183467Simp return (0); 186163516Simp} 187163516Simp 188163516Simpstatic int 189163516Simpmmc_acquire_bus(device_t busdev, device_t dev) 190163516Simp{ 191163516Simp struct mmc_softc *sc; 192183704Smav struct mmc_ivars *ivar; 193163516Simp int err; 194163516Simp int rca; 195163516Simp 196183452Simp err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), busdev); 197163516Simp if (err) 198163516Simp return (err); 199163516Simp sc = device_get_softc(busdev); 200163516Simp MMC_LOCK(sc); 201163516Simp if (sc->owner) 202163516Simp panic("mmc: host bridge didn't seralize us."); 203163516Simp sc->owner = dev; 204163516Simp MMC_UNLOCK(sc); 205163516Simp 206163516Simp if (busdev != dev) { 207183453Simp /* 208183453Simp * Keep track of the last rca that we've selected. If 209183453Simp * we're asked to do it again, don't. We never 210183453Simp * unselect unless the bus code itself wants the mmc 211183453Simp * bus, and constantly reselecting causes problems. 212183453Simp */ 213163516Simp rca = mmc_get_rca(dev); 214163516Simp if (sc->last_rca != rca) { 215183704Smav mmc_select_card(sc, rca); 216163516Simp sc->last_rca = rca; 217183704Smav /* Prepare bus width for the new card. */ 218183704Smav ivar = device_get_ivars(dev); 219183763Smav if (bootverbose) { 220183763Smav device_printf(busdev, 221183763Smav "setting bus width to %d bits\n", 222183763Smav (ivar->bus_width == bus_width_4)?4: 223183763Smav (ivar->bus_width == bus_width_8)?8:1); 224183763Smav } 225183763Smav mmc_set_card_bus_width(sc, rca, ivar->bus_width); 226183704Smav mmcbr_set_bus_width(busdev, ivar->bus_width); 227183704Smav mmcbr_update_ios(busdev); 228163516Simp } 229163516Simp } else { 230183453Simp /* 231183453Simp * If there's a card selected, stand down. 232183453Simp */ 233163516Simp if (sc->last_rca != 0) { 234183704Smav mmc_select_card(sc, 0); 235163516Simp sc->last_rca = 0; 236163516Simp } 237163516Simp } 238163516Simp 239163516Simp return (0); 240163516Simp} 241163516Simp 242163516Simpstatic int 243163516Simpmmc_release_bus(device_t busdev, device_t dev) 244163516Simp{ 245163516Simp struct mmc_softc *sc; 246163516Simp int err; 247163516Simp 248163516Simp sc = device_get_softc(busdev); 249163516Simp 250163516Simp MMC_LOCK(sc); 251163516Simp if (!sc->owner) 252163516Simp panic("mmc: releasing unowned bus."); 253163516Simp if (sc->owner != dev) 254163516Simp panic("mmc: you don't own the bus. game over."); 255163516Simp MMC_UNLOCK(sc); 256183452Simp err = MMCBR_RELEASE_HOST(device_get_parent(busdev), busdev); 257163516Simp if (err) 258163516Simp return (err); 259163516Simp MMC_LOCK(sc); 260163516Simp sc->owner = NULL; 261163516Simp MMC_UNLOCK(sc); 262163516Simp return (0); 263163516Simp} 264163516Simp 265163516Simpstatic void 266163516Simpmmc_rescan_cards(struct mmc_softc *sc) 267163516Simp{ 268163516Simp /* XXX: Look at the children and see if they respond to status */ 269163516Simp} 270163516Simp 271163516Simpstatic uint32_t 272163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr) 273163516Simp{ 274183446Simp 275183467Simp return (ocr & MMC_OCR_VOLTAGE); 276163516Simp} 277163516Simp 278163516Simpstatic int 279163516Simpmmc_highest_voltage(uint32_t ocr) 280163516Simp{ 281163516Simp int i; 282163516Simp 283163516Simp for (i = 30; i >= 0; i--) 284163516Simp if (ocr & (1 << i)) 285183467Simp return (i); 286163516Simp return (-1); 287163516Simp} 288163516Simp 289163516Simpstatic void 290163516Simpmmc_wakeup(struct mmc_request *req) 291163516Simp{ 292163516Simp struct mmc_softc *sc; 293163516Simp 294183453Simp/* printf("Wakeup for req %p done_data %p\n", req, req->done_data); */ 295163516Simp sc = (struct mmc_softc *)req->done_data; 296163516Simp MMC_LOCK(sc); 297163516Simp req->flags |= MMC_REQ_DONE; 298163516Simp wakeup(req); 299163516Simp MMC_UNLOCK(sc); 300163516Simp} 301163516Simp 302163516Simpstatic int 303163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req) 304163516Simp{ 305163516Simp int err; 306163516Simp 307163516Simp req->done = mmc_wakeup; 308163516Simp req->done_data = sc; 309183453Simp/* printf("Submitting request %p sc %p\n", req, sc); */ 310163516Simp MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req); 311163516Simp MMC_LOCK(sc); 312163516Simp do { 313163516Simp err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq", 314163516Simp hz / 10); 315163516Simp } while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN); 316183453Simp/* printf("Request %p done with error %d\n", req, err); */ 317163516Simp MMC_UNLOCK(sc); 318163516Simp return (err); 319163516Simp} 320163516Simp 321163516Simpstatic int 322163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req) 323163516Simp{ 324163516Simp struct mmc_softc *sc = device_get_softc(brdev); 325163516Simp 326183467Simp return (mmc_wait_for_req(sc, req)); 327163516Simp} 328163516Simp 329163516Simpstatic int 330163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries) 331163516Simp{ 332163516Simp struct mmc_request mreq; 333163516Simp 334163516Simp memset(&mreq, 0, sizeof(mreq)); 335163516Simp memset(cmd->resp, 0, sizeof(cmd->resp)); 336163516Simp cmd->retries = retries; 337163516Simp mreq.cmd = cmd; 338183453Simp/* printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); */ 339163516Simp mmc_wait_for_req(sc, &mreq); 340163516Simp return (cmd->error); 341163516Simp} 342163516Simp 343163516Simpstatic int 344163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca, 345163516Simp struct mmc_command *cmd, int retries) 346163516Simp{ 347163516Simp struct mmc_command appcmd; 348163516Simp int err = MMC_ERR_NONE, i; 349163516Simp 350163516Simp for (i = 0; i <= retries; i++) { 351163516Simp appcmd.opcode = MMC_APP_CMD; 352163516Simp appcmd.arg = rca << 16; 353163516Simp appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 354183470Simp appcmd.data = NULL; 355163516Simp mmc_wait_for_cmd(sc, &appcmd, 0); 356163516Simp err = appcmd.error; 357163516Simp if (err != MMC_ERR_NONE) 358163516Simp continue; 359163516Simp if (!(appcmd.resp[0] & R1_APP_CMD)) 360163516Simp return MMC_ERR_FAILED; 361163516Simp mmc_wait_for_cmd(sc, cmd, 0); 362163516Simp err = cmd->error; 363163516Simp if (err == MMC_ERR_NONE) 364163516Simp break; 365163516Simp } 366163516Simp return (err); 367163516Simp} 368163516Simp 369163516Simpstatic int 370163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 371163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries) 372163516Simp{ 373163516Simp struct mmc_command cmd; 374163516Simp int err; 375163516Simp 376163516Simp memset(&cmd, 0, sizeof(cmd)); 377163516Simp cmd.opcode = opcode; 378163516Simp cmd.arg = arg; 379163516Simp cmd.flags = flags; 380183470Simp cmd.data = NULL; 381163516Simp err = mmc_wait_for_cmd(sc, &cmd, retries); 382163516Simp if (err) 383163516Simp return (err); 384163516Simp if (cmd.error) 385163516Simp return (cmd.error); 386163516Simp if (resp) { 387163516Simp if (flags & MMC_RSP_136) 388163516Simp memcpy(resp, cmd.resp, 4 * sizeof(uint32_t)); 389163516Simp else 390163516Simp *resp = cmd.resp[0]; 391163516Simp } 392163516Simp return (0); 393163516Simp} 394163516Simp 395163516Simpstatic void 396163516Simpmmc_idle_cards(struct mmc_softc *sc) 397163516Simp{ 398163516Simp device_t dev; 399163516Simp struct mmc_command cmd; 400163516Simp 401163516Simp dev = sc->dev; 402163516Simp mmcbr_set_chip_select(dev, cs_high); 403163516Simp mmcbr_update_ios(dev); 404163516Simp mmc_ms_delay(1); 405163516Simp 406163516Simp memset(&cmd, 0, sizeof(cmd)); 407163516Simp cmd.opcode = MMC_GO_IDLE_STATE; 408163516Simp cmd.arg = 0; 409163516Simp cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; 410183470Simp cmd.data = NULL; 411163516Simp mmc_wait_for_cmd(sc, &cmd, 0); 412163516Simp mmc_ms_delay(1); 413163516Simp 414163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 415163516Simp mmcbr_update_ios(dev); 416163516Simp mmc_ms_delay(1); 417163516Simp} 418163516Simp 419163516Simpstatic int 420163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 421163516Simp{ 422163516Simp struct mmc_command cmd; 423163516Simp int err = MMC_ERR_NONE, i; 424163516Simp 425163516Simp memset(&cmd, 0, sizeof(cmd)); 426163516Simp cmd.opcode = ACMD_SD_SEND_OP_COND; 427163516Simp cmd.arg = ocr; 428163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 429183470Simp cmd.data = NULL; 430163516Simp 431170337Simp for (i = 0; i < 100; i++) { 432163516Simp err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES); 433163516Simp if (err != MMC_ERR_NONE) 434163516Simp break; 435183709Smav if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || 436183709Smav (ocr & MMC_OCR_VOLTAGE) == 0) 437163516Simp break; 438163516Simp err = MMC_ERR_TIMEOUT; 439163516Simp mmc_ms_delay(10); 440163516Simp } 441163516Simp if (rocr && err == MMC_ERR_NONE) 442163516Simp *rocr = cmd.resp[0]; 443183467Simp return (err); 444163516Simp} 445163516Simp 446163516Simpstatic int 447163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 448163516Simp{ 449163516Simp struct mmc_command cmd; 450163516Simp int err = MMC_ERR_NONE, i; 451163516Simp 452163516Simp memset(&cmd, 0, sizeof(cmd)); 453163516Simp cmd.opcode = MMC_SEND_OP_COND; 454163516Simp cmd.arg = ocr; 455163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 456183470Simp cmd.data = NULL; 457163516Simp 458163516Simp for (i = 0; i < 100; i++) { 459163516Simp err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 460163516Simp if (err != MMC_ERR_NONE) 461163516Simp break; 462183709Smav if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || 463183709Smav (ocr & MMC_OCR_VOLTAGE) == 0) 464163516Simp break; 465163516Simp err = MMC_ERR_TIMEOUT; 466163516Simp mmc_ms_delay(10); 467163516Simp } 468163516Simp if (rocr && err == MMC_ERR_NONE) 469163516Simp *rocr = cmd.resp[0]; 470183467Simp return (err); 471163516Simp} 472163516Simp 473183704Smavstatic int 474183704Smavmmc_send_if_cond(struct mmc_softc *sc, uint8_t vhs) 475183704Smav{ 476183704Smav struct mmc_command cmd; 477183704Smav int err; 478183704Smav 479183704Smav memset(&cmd, 0, sizeof(cmd)); 480183704Smav cmd.opcode = SD_SEND_IF_COND; 481183704Smav cmd.arg = (vhs << 8) + 0xAA; 482183704Smav cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; 483183704Smav cmd.data = NULL; 484183704Smav 485183704Smav err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 486183704Smav return (err); 487183704Smav} 488183704Smav 489163516Simpstatic void 490163516Simpmmc_power_up(struct mmc_softc *sc) 491163516Simp{ 492163516Simp device_t dev; 493163516Simp 494163516Simp dev = sc->dev; 495163516Simp mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev))); 496163516Simp mmcbr_set_bus_mode(dev, opendrain); 497163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 498163516Simp mmcbr_set_bus_width(dev, bus_width_1); 499163516Simp mmcbr_set_power_mode(dev, power_up); 500163516Simp mmcbr_set_clock(dev, 0); 501163516Simp mmcbr_update_ios(dev); 502163516Simp mmc_ms_delay(1); 503163516Simp 504163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev)); 505183704Smav mmcbr_set_timing(dev, bus_timing_normal); 506163516Simp mmcbr_set_power_mode(dev, power_on); 507163516Simp mmcbr_update_ios(dev); 508163516Simp mmc_ms_delay(2); 509163516Simp} 510163516Simp 511183449Simpstatic void 512183449Simpmmc_power_down(struct mmc_softc *sc) 513183449Simp{ 514183449Simp device_t dev = sc->dev; 515183449Simp 516183449Simp mmcbr_set_bus_mode(dev, opendrain); 517183449Simp mmcbr_set_chip_select(dev, cs_dontcare); 518183449Simp mmcbr_set_bus_width(dev, bus_width_1); 519183449Simp mmcbr_set_power_mode(dev, power_off); 520183449Simp mmcbr_set_clock(dev, 0); 521183704Smav mmcbr_set_timing(dev, bus_timing_normal); 522183449Simp mmcbr_update_ios(dev); 523183449Simp} 524183449Simp 525183704Smavstatic int 526183704Smavmmc_select_card(struct mmc_softc *sc, uint16_t rca) 527183704Smav{ 528183704Smav return (mmc_wait_for_command(sc, MMC_SELECT_CARD, ((uint32_t)rca) << 16, 529183704Smav MMC_RSP_R1B | MMC_CMD_AC, NULL, CMD_RETRIES)); 530183704Smav} 531183704Smav 532183704Smavstatic int 533183704Smavmmc_switch(struct mmc_softc *sc, uint8_t set, uint8_t index, uint8_t value) 534183704Smav{ 535183704Smav struct mmc_command cmd; 536183704Smav int err; 537183704Smav 538183704Smav cmd.opcode = MMC_SWITCH_FUNC; 539183704Smav cmd.arg = (MMC_SWITCH_FUNC_WR << 24) | 540183704Smav (index << 16) | 541183704Smav (value << 8) | 542183704Smav set; 543183704Smav cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 544183704Smav cmd.data = NULL; 545183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 546183704Smav return (err); 547183704Smav} 548183704Smav 549183704Smavstatic int 550183704Smavmmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, uint8_t *res) 551183704Smav{ 552183704Smav int err; 553183704Smav struct mmc_command cmd; 554183704Smav struct mmc_data data; 555183704Smav 556183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 557183704Smav memset(&data, 0, sizeof(struct mmc_data)); 558183704Smav 559183704Smav memset(res, 0, 64); 560183704Smav cmd.opcode = SD_SWITCH_FUNC; 561183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 562183704Smav cmd.arg = mode << 31; 563183704Smav cmd.arg |= 0x00FFFFFF; 564183705Smav cmd.arg &= ~(0xF << (grp * 4)); 565183705Smav cmd.arg |= value << (grp * 4); 566183704Smav cmd.data = &data; 567183704Smav 568183704Smav data.data = res; 569183704Smav data.len = 64; 570183704Smav data.flags = MMC_DATA_READ; 571183704Smav 572183704Smav err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 573183704Smav return (err); 574183704Smav} 575183704Smav 576183704Smavstatic int 577183763Smavmmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width) 578183704Smav{ 579183704Smav int err; 580183704Smav 581183704Smav if (mmcbr_get_mode(sc->dev) == mode_sd) { 582183704Smav struct mmc_command cmd; 583183704Smav 584183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 585183704Smav cmd.opcode = ACMD_SET_BUS_WIDTH; 586183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 587183704Smav switch (width) { 588183704Smav case bus_width_1: 589183704Smav cmd.arg = SD_BUS_WIDTH_1; 590183704Smav break; 591183704Smav case bus_width_4: 592183704Smav cmd.arg = SD_BUS_WIDTH_4; 593183704Smav break; 594183704Smav default: 595183704Smav return (MMC_ERR_INVALID); 596183704Smav } 597183704Smav err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES); 598183704Smav } else { 599183704Smav uint8_t value; 600183704Smav 601183704Smav switch (width) { 602183704Smav case bus_width_1: 603183704Smav value = EXT_CSD_BUS_WIDTH_1; 604183704Smav break; 605183704Smav case bus_width_4: 606183704Smav value = EXT_CSD_BUS_WIDTH_4; 607183704Smav break; 608183704Smav case bus_width_8: 609183704Smav value = EXT_CSD_BUS_WIDTH_8; 610183704Smav break; 611183704Smav default: 612183704Smav return (MMC_ERR_INVALID); 613183704Smav } 614183704Smav err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, value); 615183704Smav } 616183704Smav return (err); 617183704Smav} 618183704Smav 619183704Smavstatic int 620183704Smavmmc_set_timing(struct mmc_softc *sc, int timing) 621183704Smav{ 622183704Smav int err; 623183704Smav uint8_t value; 624183704Smav 625183704Smav switch (timing) { 626183704Smav case bus_timing_normal: 627183704Smav value = 0; 628183704Smav break; 629183704Smav case bus_timing_hs: 630183704Smav value = 1; 631183704Smav break; 632183704Smav default: 633183704Smav return (MMC_ERR_INVALID); 634183704Smav } 635183704Smav if (mmcbr_get_mode(sc->dev) == mode_sd) { 636183704Smav u_char switch_res[64]; 637183704Smav 638183704Smav err = mmc_sd_switch(sc, 1, 0, value, switch_res); 639183704Smav } else { 640183704Smav err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, 641183704Smav EXT_CSD_HS_TIMING, value); 642183704Smav } 643183704Smav return (err); 644183704Smav} 645183704Smav 646183704Smavstatic int 647183704Smavmmc_test_bus_width(struct mmc_softc *sc) 648183704Smav{ 649183704Smav struct mmc_command cmd; 650183704Smav struct mmc_data data; 651183704Smav int err; 652183704Smav uint8_t buf[8]; 653183704Smav uint8_t p8[8] = { 0x55, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 654183704Smav uint8_t p8ok[8] = { 0xAA, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 655183704Smav uint8_t p4[4] = { 0x5A, 0x00, 0x00, 0x00, }; 656183704Smav uint8_t p4ok[4] = { 0xA5, 0x00, 0x00, 0x00, }; 657183704Smav 658183704Smav if (mmcbr_get_caps(sc->dev) & MMC_CAP_8_BIT_DATA) { 659183704Smav mmcbr_set_bus_width(sc->dev, bus_width_8); 660183704Smav mmcbr_update_ios(sc->dev); 661183704Smav 662183704Smav cmd.opcode = MMC_BUSTEST_W; 663183704Smav cmd.arg = 0; 664183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 665183704Smav cmd.data = &data; 666183704Smav 667183704Smav data.data = p8; 668183704Smav data.len = 8; 669183704Smav data.flags = MMC_DATA_WRITE; 670183704Smav mmc_wait_for_cmd(sc, &cmd, 0); 671183704Smav 672183704Smav cmd.opcode = MMC_BUSTEST_R; 673183704Smav cmd.arg = 0; 674183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 675183704Smav cmd.data = &data; 676183704Smav 677183704Smav data.data = buf; 678183704Smav data.len = 8; 679183704Smav data.flags = MMC_DATA_READ; 680183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 681183704Smav 682183704Smav mmcbr_set_bus_width(sc->dev, bus_width_1); 683183704Smav mmcbr_update_ios(sc->dev); 684183704Smav 685183704Smav if (err == MMC_ERR_NONE && memcmp(buf, p8ok, 8) == 0) 686183704Smav return (bus_width_8); 687183704Smav } 688183704Smav 689183704Smav if (mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) { 690183704Smav mmcbr_set_bus_width(sc->dev, bus_width_4); 691183704Smav mmcbr_update_ios(sc->dev); 692183704Smav 693183704Smav cmd.opcode = MMC_BUSTEST_W; 694183704Smav cmd.arg = 0; 695183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 696183704Smav cmd.data = &data; 697183704Smav 698183704Smav data.data = p4; 699183704Smav data.len = 4; 700183704Smav data.flags = MMC_DATA_WRITE; 701183704Smav mmc_wait_for_cmd(sc, &cmd, 0); 702183704Smav 703183704Smav cmd.opcode = MMC_BUSTEST_R; 704183704Smav cmd.arg = 0; 705183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 706183704Smav cmd.data = &data; 707183704Smav 708183704Smav data.data = buf; 709183704Smav data.len = 4; 710183704Smav data.flags = MMC_DATA_READ; 711183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 712183704Smav 713183704Smav mmcbr_set_bus_width(sc->dev, bus_width_1); 714183704Smav mmcbr_update_ios(sc->dev); 715183704Smav 716183704Smav if (err == MMC_ERR_NONE && memcmp(buf, p4ok, 4) == 0) 717183704Smav return (bus_width_4); 718183704Smav } 719183704Smav return (bus_width_1); 720183704Smav} 721183704Smav 722163516Simpstatic uint32_t 723163516Simpmmc_get_bits(uint32_t *bits, int start, int size) 724163516Simp{ 725183729Simp const int bit_len = 128; 726183729Simp const int i = (bit_len / 32) - (start / 32) - 1; 727163516Simp const int shift = start & 31; 728163516Simp uint32_t retval = bits[i] >> shift; 729163516Simp if (size + shift > 32) 730163516Simp retval |= bits[i - 1] << (32 - shift); 731183467Simp return (retval & ((1 << size) - 1)); 732163516Simp} 733163516Simp 734163516Simpstatic void 735183729Simpmmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid) 736163516Simp{ 737163516Simp int i; 738163516Simp 739183729Simp /* There's no version info, so we take it on faith */ 740163516Simp memset(cid, 0, sizeof(*cid)); 741183729Simp cid->mid = mmc_get_bits(raw_cid, 120, 8); 742183729Simp cid->oid = mmc_get_bits(raw_cid, 104, 16); 743183729Simp for (i = 0; i < 5; i++) 744183729Simp cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8); 745183729Simp cid->prv = mmc_get_bits(raw_cid, 56, 8); 746183729Simp cid->psn = mmc_get_bits(raw_cid, 24, 32); 747183729Simp cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001; 748183729Simp cid->mdt_month = mmc_get_bits(raw_cid, 8, 4); 749163516Simp} 750163516Simp 751183729Simpstatic void 752183729Simpmmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid) 753183729Simp{ 754183729Simp int i; 755183729Simp 756183729Simp /* There's no version info, so we take it on faith */ 757183729Simp memset(cid, 0, sizeof(*cid)); 758183729Simp cid->mid = mmc_get_bits(raw_cid, 120, 8); 759183729Simp cid->oid = mmc_get_bits(raw_cid, 104, 8); 760183729Simp for (i = 0; i < 6; i++) 761183729Simp cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8); 762183729Simp cid->prv = mmc_get_bits(raw_cid, 48, 8); 763183729Simp cid->psn = mmc_get_bits(raw_cid, 16, 32); 764183729Simp cid->mdt_month = mmc_get_bits(raw_cid, 12, 4); 765183729Simp cid->mdt_year = mmc_get_bits(raw_cid, 8, 4) + 1997; 766183729Simp} 767183729Simp 768163516Simpstatic const int exp[8] = { 769163516Simp 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 770163516Simp}; 771163516Simpstatic const int mant[16] = { 772163516Simp 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 773163516Simp}; 774163516Simpstatic const int cur_min[8] = { 775163516Simp 500, 1000, 5000, 10000, 25000, 35000, 60000, 100000 776163516Simp}; 777163516Simpstatic const int cur_max[8] = { 778163516Simp 1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000 779163516Simp}; 780163516Simp 781163516Simpstatic void 782183729Simpmmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd) 783163516Simp{ 784163516Simp int v; 785163516Simp int m; 786163516Simp int e; 787163516Simp 788163516Simp memset(csd, 0, sizeof(*csd)); 789183729Simp csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2); 790183729Simp if (v == 0) { 791183704Smav m = mmc_get_bits(raw_csd, 115, 4); 792183704Smav e = mmc_get_bits(raw_csd, 112, 3); 793183704Smav csd->tacc = exp[e] * mant[m] + 9 / 10; 794183704Smav csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100; 795183704Smav m = mmc_get_bits(raw_csd, 99, 4); 796183704Smav e = mmc_get_bits(raw_csd, 96, 3); 797183704Smav csd->tran_speed = exp[e] * 10000 * mant[m]; 798183704Smav csd->ccc = mmc_get_bits(raw_csd, 84, 12); 799183704Smav csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4); 800183704Smav csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1); 801183704Smav csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1); 802183704Smav csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1); 803183704Smav csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1); 804183704Smav csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)]; 805183704Smav csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)]; 806183704Smav csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)]; 807183704Smav csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)]; 808183704Smav m = mmc_get_bits(raw_csd, 62, 12); 809183704Smav e = mmc_get_bits(raw_csd, 47, 3); 810183704Smav csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; 811183729Simp csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1); 812183729Simp csd->sector_size = mmc_get_bits(raw_csd, 39, 7); 813183729Simp csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7); 814183704Smav csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1); 815183704Smav csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3); 816183704Smav csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4); 817183704Smav csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1); 818183729Simp } else if (v == 1) { 819183729Simp m = mmc_get_bits(raw_csd, 115, 4); 820183729Simp e = mmc_get_bits(raw_csd, 112, 3); 821183729Simp csd->tacc = exp[e] * mant[m] + 9 / 10; 822183729Simp csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100; 823183729Simp m = mmc_get_bits(raw_csd, 99, 4); 824183729Simp e = mmc_get_bits(raw_csd, 96, 3); 825183729Simp csd->tran_speed = exp[e] * 10000 * mant[m]; 826183729Simp csd->ccc = mmc_get_bits(raw_csd, 84, 12); 827183729Simp csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4); 828183729Simp csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1); 829183729Simp csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1); 830183729Simp csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1); 831183729Simp csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1); 832183729Simp csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 48, 22) + 1) * 833183729Simp 512 * 1024; 834183729Simp csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1); 835183729Simp csd->sector_size = mmc_get_bits(raw_csd, 39, 7); 836183729Simp csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7); 837183729Simp csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1); 838183729Simp csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3); 839183729Simp csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4); 840183729Simp csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1); 841183729Simp } else 842183729Simp panic("unknown SD CSD version"); 843163516Simp} 844163516Simp 845183704Smavstatic void 846183729Simpmmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd) 847183729Simp{ 848183729Simp int m; 849183729Simp int e; 850183729Simp 851183729Simp memset(csd, 0, sizeof(*csd)); 852183729Simp csd->csd_structure = mmc_get_bits(raw_csd, 126, 2); 853183729Simp csd->spec_vers = mmc_get_bits(raw_csd, 122, 4); 854183729Simp m = mmc_get_bits(raw_csd, 115, 4); 855183729Simp e = mmc_get_bits(raw_csd, 112, 3); 856183729Simp csd->tacc = exp[e] * mant[m] + 9 / 10; 857183729Simp csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100; 858183729Simp m = mmc_get_bits(raw_csd, 99, 4); 859183729Simp e = mmc_get_bits(raw_csd, 96, 3); 860183729Simp csd->tran_speed = exp[e] * 10000 * mant[m]; 861183729Simp csd->ccc = mmc_get_bits(raw_csd, 84, 12); 862183729Simp csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4); 863183729Simp csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1); 864183729Simp csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1); 865183729Simp csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1); 866183729Simp csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1); 867183729Simp csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)]; 868183729Simp csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)]; 869183729Simp csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)]; 870183729Simp csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)]; 871183729Simp m = mmc_get_bits(raw_csd, 62, 12); 872183729Simp e = mmc_get_bits(raw_csd, 47, 3); 873183729Simp csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; 874183729Simp// csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1); 875183729Simp// csd->sector_size = mmc_get_bits(raw_csd, 39, 7); 876183729Simp csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 5); 877183729Simp csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1); 878183729Simp csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3); 879183729Simp csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4); 880183729Simp csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1); 881183729Simp} 882183729Simp 883183729Simpstatic void 884183704Smavmmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr) 885183704Smav{ 886183704Smav unsigned int scr_struct; 887183704Smav uint32_t tmp[4]; 888183704Smav 889183704Smav tmp[3] = raw_scr[1]; 890183704Smav tmp[2] = raw_scr[0]; 891183704Smav 892183704Smav memset(scr, 0, sizeof(*scr)); 893183729Simp 894183704Smav scr_struct = mmc_get_bits(tmp, 60, 4); 895183704Smav if (scr_struct != 0) { 896183704Smav printf("Unrecognised SCR structure version %d\n", 897183704Smav scr_struct); 898183704Smav return; 899183704Smav } 900183704Smav scr->sda_vsn = mmc_get_bits(tmp, 56, 4); 901183704Smav scr->bus_widths = mmc_get_bits(tmp, 48, 4); 902183704Smav} 903183704Smav 904163516Simpstatic int 905163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid) 906163516Simp{ 907163516Simp struct mmc_command cmd; 908163516Simp int err; 909163516Simp 910163516Simp cmd.opcode = MMC_ALL_SEND_CID; 911163516Simp cmd.arg = 0; 912163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 913183470Simp cmd.data = NULL; 914163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 915163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 916163516Simp return (err); 917163516Simp} 918163516Simp 919163516Simpstatic int 920163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid) 921163516Simp{ 922163516Simp struct mmc_command cmd; 923163516Simp int err; 924163516Simp 925163516Simp cmd.opcode = MMC_SEND_CSD; 926163516Simp cmd.arg = rca << 16; 927163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 928183470Simp cmd.data = NULL; 929163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 930163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 931163516Simp return (err); 932163516Simp} 933163516Simp 934163516Simpstatic int 935183704Smavmmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr) 936183704Smav{ 937183704Smav int err; 938183704Smav struct mmc_command cmd; 939183704Smav struct mmc_data data; 940183704Smav 941183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 942183704Smav memset(&data, 0, sizeof(struct mmc_data)); 943183704Smav 944183704Smav memset(rawscr, 0, 8); 945183704Smav cmd.opcode = ACMD_SEND_SCR; 946183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 947183704Smav cmd.arg = 0; 948183704Smav cmd.data = &data; 949183704Smav 950183704Smav data.data = rawscr; 951183704Smav data.len = 8; 952183704Smav data.flags = MMC_DATA_READ; 953183704Smav 954183704Smav err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES); 955183704Smav rawscr[0] = be32toh(rawscr[0]); 956183704Smav rawscr[1] = be32toh(rawscr[1]); 957183704Smav return (err); 958183704Smav} 959183704Smav 960183704Smavstatic int 961183704Smavmmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd) 962183704Smav{ 963183704Smav int err; 964183704Smav struct mmc_command cmd; 965183704Smav struct mmc_data data; 966183704Smav 967183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 968183704Smav memset(&data, 0, sizeof(struct mmc_data)); 969183704Smav 970183704Smav memset(rawextcsd, 0, 512); 971183704Smav cmd.opcode = MMC_SEND_EXT_CSD; 972183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 973183704Smav cmd.arg = 0; 974183704Smav cmd.data = &data; 975183704Smav 976183704Smav data.data = rawextcsd; 977183704Smav data.len = 512; 978183704Smav data.flags = MMC_DATA_READ; 979183704Smav 980183704Smav err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 981183704Smav return (err); 982183704Smav} 983183704Smav 984183704Smavstatic int 985183704Smavmmc_set_relative_addr(struct mmc_softc *sc, uint16_t resp) 986183704Smav{ 987183704Smav struct mmc_command cmd; 988183704Smav int err; 989183704Smav 990183704Smav cmd.opcode = MMC_SET_RELATIVE_ADDR; 991183704Smav cmd.arg = resp << 16; 992183704Smav cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; 993183704Smav cmd.data = NULL; 994183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 995183704Smav return (err); 996183704Smav} 997183704Smav 998183704Smavstatic int 999163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp) 1000163516Simp{ 1001163516Simp struct mmc_command cmd; 1002163516Simp int err; 1003163516Simp 1004163516Simp cmd.opcode = SD_SEND_RELATIVE_ADDR; 1005163516Simp cmd.arg = 0; 1006163516Simp cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; 1007183470Simp cmd.data = NULL; 1008163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 1009163516Simp *resp = cmd.resp[0]; 1010163516Simp return (err); 1011163516Simp} 1012163516Simp 1013163516Simpstatic void 1014163516Simpmmc_discover_cards(struct mmc_softc *sc) 1015163516Simp{ 1016163516Simp struct mmc_ivars *ivar; 1017163516Simp int err; 1018183731Smav uint32_t resp, sec_count; 1019163516Simp device_t child; 1020183704Smav uint16_t rca = 2; 1021183704Smav u_char switch_res[64]; 1022163516Simp 1023163516Simp while (1) { 1024183468Simp ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, 1025183468Simp M_WAITOK | M_ZERO); 1026169567Simp if (!ivar) 1027169567Simp return; 1028163516Simp err = mmc_all_send_cid(sc, ivar->raw_cid); 1029163516Simp if (err == MMC_ERR_TIMEOUT) 1030163516Simp break; 1031163516Simp if (err != MMC_ERR_NONE) { 1032183468Simp device_printf(sc->dev, "Error reading CID %d\n", err); 1033163516Simp break; 1034163516Simp } 1035183704Smav if (mmcbr_get_ro(sc->dev)) 1036183704Smav ivar->read_only = 1; 1037183704Smav ivar->bus_width = bus_width_1; 1038183704Smav ivar->mode = mmcbr_get_mode(sc->dev); 1039183704Smav if (ivar->mode == mode_sd) { 1040183729Simp mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid); 1041163516Simp mmc_send_relative_addr(sc, &resp); 1042163516Simp ivar->rca = resp >> 16; 1043183704Smav /* Get card CSD. */ 1044163516Simp mmc_send_csd(sc, ivar->rca, ivar->raw_csd); 1045183729Simp mmc_decode_csd_sd(ivar->raw_csd, &ivar->csd); 1046183731Smav ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE; 1047183704Smav if (ivar->csd.csd_structure > 0) 1048183704Smav ivar->high_cap = 1; 1049183704Smav ivar->tran_speed = ivar->csd.tran_speed; 1050183704Smav /* Get card SCR. Card must be selected to fetch it. */ 1051183704Smav mmc_select_card(sc, ivar->rca); 1052183704Smav mmc_app_send_scr(sc, ivar->rca, ivar->raw_scr); 1053183704Smav mmc_app_decode_scr(ivar->raw_scr, &ivar->scr); 1054183704Smav /* Get card switch capabilities. */ 1055183704Smav if ((ivar->scr.sda_vsn >= 1) && 1056183704Smav (ivar->csd.ccc & (1<<10))) { 1057183704Smav mmc_sd_switch(sc, 0, 0, 0xF, switch_res); 1058183704Smav if (switch_res[13] & 2) { 1059183704Smav ivar->timing = bus_timing_hs; 1060183704Smav ivar->hs_tran_speed = 50000000; 1061183704Smav } 1062183704Smav } 1063183704Smav mmc_select_card(sc, 0); 1064183704Smav /* Find max supported bus width. */ 1065183704Smav if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) && 1066183704Smav (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) 1067183704Smav ivar->bus_width = bus_width_4; 1068183704Smav /* Add device. */ 1069163516Simp child = device_add_child(sc->dev, NULL, -1); 1070163516Simp device_set_ivars(child, ivar); 1071169567Simp return; 1072163516Simp } 1073183729Simp mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid); 1074183704Smav ivar->rca = rca++; 1075183704Smav mmc_set_relative_addr(sc, ivar->rca); 1076183704Smav /* Get card CSD. */ 1077183704Smav mmc_send_csd(sc, ivar->rca, ivar->raw_csd); 1078183729Simp mmc_decode_csd_mmc(ivar->raw_csd, &ivar->csd); 1079183731Smav ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE; 1080183704Smav ivar->tran_speed = ivar->csd.tran_speed; 1081183704Smav /* Only MMC >= 4.x cards support EXT_CSD. */ 1082183704Smav if (ivar->csd.spec_vers >= 4) { 1083183704Smav /* Card must be selected to fetch EXT_CSD. */ 1084183704Smav mmc_select_card(sc, ivar->rca); 1085183704Smav mmc_send_ext_csd(sc, ivar->raw_ext_csd); 1086183731Smav /* Handle extended capacity from EXT_CSD */ 1087183731Smav sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] + 1088183731Smav (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 1] << 8) + 1089183731Smav (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 2] << 16) + 1090183731Smav (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 3] << 24); 1091183731Smav if (sec_count != 0) { 1092183731Smav ivar->sec_count = sec_count; 1093183731Smav ivar->high_cap = 1; 1094183731Smav } 1095183704Smav /* Get card speed in high speed mode. */ 1096183704Smav ivar->timing = bus_timing_hs; 1097183731Smav if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] 1098183704Smav & EXT_CSD_CARD_TYPE_52) 1099183704Smav ivar->hs_tran_speed = 52000000; 1100183731Smav else if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] 1101183704Smav & EXT_CSD_CARD_TYPE_26) 1102183704Smav ivar->hs_tran_speed = 26000000; 1103183704Smav else 1104183704Smav ivar->hs_tran_speed = ivar->tran_speed; 1105183704Smav /* Find max supported bus width. */ 1106183704Smav ivar->bus_width = mmc_test_bus_width(sc); 1107183704Smav mmc_select_card(sc, 0); 1108183704Smav } else { 1109183704Smav ivar->bus_width = bus_width_1; 1110183704Smav ivar->timing = bus_timing_normal; 1111183704Smav } 1112183704Smav /* Add device. */ 1113183704Smav child = device_add_child(sc->dev, NULL, -1); 1114183704Smav device_set_ivars(child, ivar); 1115163516Simp } 1116169567Simp free(ivar, M_DEVBUF); 1117163516Simp} 1118163516Simp 1119163516Simpstatic void 1120163516Simpmmc_go_discovery(struct mmc_softc *sc) 1121163516Simp{ 1122163516Simp uint32_t ocr; 1123163516Simp device_t dev; 1124183704Smav int err; 1125163516Simp 1126163516Simp dev = sc->dev; 1127163516Simp if (mmcbr_get_power_mode(dev) != power_on) { 1128183453Simp /* 1129183453Simp * First, try SD modes 1130183453Simp */ 1131163516Simp mmcbr_set_mode(dev, mode_sd); 1132163516Simp mmc_power_up(sc); 1133163516Simp mmcbr_set_bus_mode(dev, pushpull); 1134163516Simp mmc_idle_cards(sc); 1135183704Smav err = mmc_send_if_cond(sc, 1); 1136183704Smav if (mmc_send_app_op_cond(sc, err?0:MMC_OCR_CCS, &ocr) != 1137183704Smav MMC_ERR_NONE) { 1138183453Simp /* 1139183453Simp * Failed, try MMC 1140183453Simp */ 1141163516Simp mmcbr_set_mode(dev, mode_mmc); 1142163516Simp if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) 1143183453Simp return; /* Failed both, punt! XXX powerdown? */ 1144163516Simp } 1145163516Simp mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr)); 1146163516Simp if (mmcbr_get_ocr(dev) != 0) 1147163516Simp mmc_idle_cards(sc); 1148163516Simp } else { 1149163516Simp mmcbr_set_bus_mode(dev, opendrain); 1150163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(dev)); 1151163516Simp mmcbr_update_ios(dev); 1152183453Simp /* XXX recompute vdd based on new cards? */ 1153163516Simp } 1154163516Simp /* 1155163516Simp * Make sure that we have a mutually agreeable voltage to at least 1156163516Simp * one card on the bus. 1157163516Simp */ 1158163516Simp if (mmcbr_get_ocr(dev) == 0) 1159163516Simp return; 1160163516Simp /* 1161163516Simp * Reselect the cards after we've idled them above. 1162163516Simp */ 1163183704Smav if (mmcbr_get_mode(dev) == mode_sd) { 1164183704Smav err = mmc_send_if_cond(sc, 1); 1165183704Smav mmc_send_app_op_cond(sc, 1166183704Smav (err?0:MMC_OCR_CCS)|mmcbr_get_ocr(dev), NULL); 1167183704Smav } else 1168163516Simp mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL); 1169163516Simp mmc_discover_cards(sc); 1170163516Simp 1171163516Simp mmcbr_set_bus_mode(dev, pushpull); 1172163516Simp mmcbr_update_ios(dev); 1173183763Smav mmc_calculate_clock(sc); 1174163516Simp bus_generic_attach(dev); 1175183453Simp/* mmc_update_children_sysctl(dev);*/ 1176163516Simp} 1177163516Simp 1178163516Simpstatic int 1179163516Simpmmc_calculate_clock(struct mmc_softc *sc) 1180163516Simp{ 1181183704Smav int max_dtr, max_hs_dtr, max_timing; 1182163516Simp int nkid, i, f_min, f_max; 1183163516Simp device_t *kids; 1184183704Smav struct mmc_ivars *ivar; 1185163516Simp 1186163516Simp f_min = mmcbr_get_f_min(sc->dev); 1187163516Simp f_max = mmcbr_get_f_max(sc->dev); 1188183704Smav max_dtr = max_hs_dtr = f_max; 1189183704Smav if ((mmcbr_get_caps(sc->dev) & MMC_CAP_HSPEED)) 1190183704Smav max_timing = bus_timing_hs; 1191183704Smav else 1192183704Smav max_timing = bus_timing_normal; 1193163516Simp if (device_get_children(sc->dev, &kids, &nkid) != 0) 1194163516Simp panic("can't get children"); 1195183704Smav for (i = 0; i < nkid; i++) { 1196183704Smav ivar = device_get_ivars(kids[i]); 1197183704Smav if (ivar->timing < max_timing) 1198183704Smav max_timing = ivar->timing; 1199183704Smav if (ivar->tran_speed < max_dtr) 1200183704Smav max_dtr = ivar->tran_speed; 1201183704Smav if (ivar->hs_tran_speed < max_dtr) 1202183704Smav max_hs_dtr = ivar->hs_tran_speed; 1203183704Smav } 1204183704Smav for (i = 0; i < nkid; i++) { 1205183704Smav ivar = device_get_ivars(kids[i]); 1206183704Smav if (ivar->timing == bus_timing_normal) 1207183704Smav continue; 1208183704Smav mmc_select_card(sc, ivar->rca); 1209183704Smav mmc_set_timing(sc, max_timing); 1210183704Smav } 1211183704Smav mmc_select_card(sc, 0); 1212163516Simp free(kids, M_TEMP); 1213183704Smav if (max_timing == bus_timing_hs) 1214183704Smav max_dtr = max_hs_dtr; 1215183763Smav if (bootverbose) { 1216183763Smav device_printf(sc->dev, "setting transfer rate to %d.%03dMHz%s\n", 1217183763Smav max_dtr / 1000000, (max_dtr / 1000) % 1000, 1218183763Smav (max_timing == bus_timing_hs)?" with high speed timing":""); 1219183763Smav } 1220183704Smav mmcbr_set_timing(sc->dev, max_timing); 1221183704Smav mmcbr_set_clock(sc->dev, max_dtr); 1222183704Smav mmcbr_update_ios(sc->dev); 1223183704Smav return max_dtr; 1224163516Simp} 1225163516Simp 1226163516Simpstatic void 1227163516Simpmmc_scan(struct mmc_softc *sc) 1228163516Simp{ 1229163516Simp device_t dev; 1230163516Simp 1231163516Simp dev = sc->dev; 1232163516Simp mmc_acquire_bus(dev, dev); 1233163516Simp 1234163516Simp if (mmcbr_get_power_mode(dev) == power_on) 1235163516Simp mmc_rescan_cards(sc); 1236163516Simp mmc_go_discovery(sc); 1237163516Simp 1238163516Simp mmc_release_bus(dev, dev); 1239183453Simp /* XXX probe/attach/detach children? */ 1240163516Simp} 1241163516Simp 1242163516Simpstatic int 1243163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result) 1244163516Simp{ 1245163516Simp struct mmc_ivars *ivar = device_get_ivars(child); 1246163516Simp 1247163516Simp switch (which) { 1248163516Simp default: 1249163516Simp return (EINVAL); 1250163516Simp case MMC_IVAR_DSR_IMP: 1251163516Simp *(int *)result = ivar->csd.dsr_imp; 1252163516Simp break; 1253163516Simp case MMC_IVAR_MEDIA_SIZE: 1254183731Smav *(off_t *)result = ivar->sec_count; 1255163516Simp break; 1256163516Simp case MMC_IVAR_RCA: 1257163516Simp *(int *)result = ivar->rca; 1258163516Simp break; 1259163516Simp case MMC_IVAR_SECTOR_SIZE: 1260183542Simp *(int *)result = MMC_SECTOR_SIZE; 1261163516Simp break; 1262163516Simp case MMC_IVAR_TRAN_SPEED: 1263183763Smav *(int *)result = mmcbr_get_clock(bus); 1264163516Simp break; 1265183447Simp case MMC_IVAR_READ_ONLY: 1266183447Simp *(int *)result = ivar->read_only; 1267183447Simp break; 1268183704Smav case MMC_IVAR_HIGH_CAP: 1269183704Smav *(int *)result = ivar->high_cap; 1270183704Smav break; 1271183763Smav case MMC_IVAR_CARD_TYPE: 1272183763Smav *(int *)result = ivar->mode; 1273183763Smav break; 1274183763Smav case MMC_IVAR_BUS_WIDTH: 1275183763Smav *(int *)result = ivar->bus_width; 1276183763Smav break; 1277163516Simp } 1278163516Simp return (0); 1279163516Simp} 1280163516Simp 1281163516Simpstatic int 1282163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value) 1283163516Simp{ 1284183453Simp /* 1285183453Simp * None are writable ATM 1286183453Simp */ 1287183453Simp return (EINVAL); 1288163516Simp} 1289163516Simp 1290163516Simp 1291163516Simpstatic void 1292163516Simpmmc_delayed_attach(void *xsc) 1293163516Simp{ 1294163516Simp struct mmc_softc *sc = xsc; 1295163516Simp 1296163516Simp mmc_scan(sc); 1297163516Simp config_intrhook_disestablish(&sc->config_intrhook); 1298163516Simp} 1299163516Simp 1300163516Simpstatic device_method_t mmc_methods[] = { 1301163516Simp /* device_if */ 1302163516Simp DEVMETHOD(device_probe, mmc_probe), 1303163516Simp DEVMETHOD(device_attach, mmc_attach), 1304163516Simp DEVMETHOD(device_detach, mmc_detach), 1305163516Simp 1306163516Simp /* Bus interface */ 1307163516Simp DEVMETHOD(bus_read_ivar, mmc_read_ivar), 1308163516Simp DEVMETHOD(bus_write_ivar, mmc_write_ivar), 1309163516Simp 1310163516Simp /* MMC Bus interface */ 1311163516Simp DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request), 1312163516Simp DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus), 1313163516Simp DEVMETHOD(mmcbus_release_bus, mmc_release_bus), 1314163516Simp 1315163516Simp {0, 0}, 1316163516Simp}; 1317163516Simp 1318163516Simpstatic driver_t mmc_driver = { 1319163516Simp "mmc", 1320163516Simp mmc_methods, 1321163516Simp sizeof(struct mmc_softc), 1322163516Simp}; 1323163516Simpstatic devclass_t mmc_devclass; 1324163516Simp 1325163516Simp 1326163516SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0); 1327183708SmavDRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, 0, 0); 1328