mmc.c revision 183453
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 183453 2008-09-29 01:32:21Z imp $"); 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> 64163516Simp 65163516Simp#include <dev/mmc/mmcreg.h> 66163516Simp#include <dev/mmc/mmcbrvar.h> 67163516Simp#include <dev/mmc/mmcvar.h> 68163516Simp#include "mmcbr_if.h" 69163516Simp#include "mmcbus_if.h" 70163516Simp 71163516Simpstruct mmc_softc { 72163516Simp device_t dev; 73163516Simp struct mtx sc_mtx; 74163516Simp struct intr_config_hook config_intrhook; 75163516Simp device_t owner; 76163516Simp uint32_t last_rca; 77163516Simp}; 78163516Simp 79163516Simp/* 80163516Simp * Per-card data 81163516Simp */ 82163516Simpstruct mmc_ivars { 83163516Simp uint32_t raw_cid[4]; /* Raw bits of the CID */ 84163516Simp uint32_t raw_csd[4]; /* Raw bits of the CSD */ 85163516Simp uint16_t rca; 86163516Simp enum mmc_card_mode mode; 87163516Simp struct mmc_cid cid; /* cid decoded */ 88163516Simp struct mmc_csd csd; /* csd decoded */ 89183447Simp u_char read_only; /* True when the device is read-only */ 90163516Simp}; 91163516Simp 92163516Simp#define CMD_RETRIES 3 93163516Simp 94163516Simp/* bus entry points */ 95163516Simpstatic int mmc_probe(device_t dev); 96163516Simpstatic int mmc_attach(device_t dev); 97163516Simpstatic int mmc_detach(device_t dev); 98163516Simp 99163516Simp#define MMC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 100163516Simp#define MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 101183444Simp#define MMC_LOCK_INIT(_sc) \ 102183444Simp mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ 103163516Simp "mmc", MTX_DEF) 104163516Simp#define MMC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 105163516Simp#define MMC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 106163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 107163516Simp 108163516Simpstatic void mmc_delayed_attach(void *); 109183449Simpstatic void mmc_power_down(struct mmc_softc *sc); 110163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, 111163516Simp int retries); 112163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 113163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries); 114163516Simp 115163516Simpstatic void 116163516Simpmmc_ms_delay(int ms) 117163516Simp{ 118163516Simp DELAY(1000 * ms); /* XXX BAD */ 119163516Simp} 120163516Simp 121163516Simpstatic int 122163516Simpmmc_probe(device_t dev) 123163516Simp{ 124163516Simp 125183445Simp device_set_desc(dev, "MMC/SD bus"); 126163516Simp return (0); 127163516Simp} 128163516Simp 129163516Simpstatic int 130163516Simpmmc_attach(device_t dev) 131163516Simp{ 132163516Simp struct mmc_softc *sc; 133163516Simp 134163516Simp sc = device_get_softc(dev); 135163516Simp sc->dev = dev; 136163516Simp MMC_LOCK_INIT(sc); 137163516Simp 138163516Simp /* We'll probe and attach our children later, but before / mount */ 139163516Simp sc->config_intrhook.ich_func = mmc_delayed_attach; 140163516Simp sc->config_intrhook.ich_arg = sc; 141163516Simp if (config_intrhook_establish(&sc->config_intrhook) != 0) 142163516Simp device_printf(dev, "config_intrhook_establish failed\n"); 143163516Simp return (0); 144163516Simp} 145163516Simp 146163516Simpstatic int 147163516Simpmmc_detach(device_t dev) 148163516Simp{ 149169567Simp struct mmc_softc *sc = device_get_softc(dev); 150169567Simp device_t *kids; 151169567Simp int i, nkid; 152169567Simp 153169567Simp /* kill children [ph33r]. -sorbo */ 154169567Simp if (device_get_children(sc->dev, &kids, &nkid) != 0) 155169567Simp return 0; 156169567Simp for (i = 0; i < nkid; i++) { 157169567Simp device_t kid = kids[i]; 158169567Simp void *ivar = device_get_ivars(kid); 159169567Simp 160169567Simp device_detach(kid); 161169567Simp device_delete_child(sc->dev, kid); 162169567Simp free(ivar, M_DEVBUF); 163169567Simp } 164169567Simp free(kids, M_TEMP); 165183449Simp mmc_power_down(sc); 166169567Simp 167169567Simp MMC_LOCK_DESTROY(sc); 168169567Simp 169169567Simp return 0; 170163516Simp} 171163516Simp 172163516Simpstatic int 173163516Simpmmc_acquire_bus(device_t busdev, device_t dev) 174163516Simp{ 175163516Simp struct mmc_softc *sc; 176163516Simp int err; 177163516Simp int rca; 178163516Simp 179183452Simp err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), busdev); 180163516Simp if (err) 181163516Simp return (err); 182163516Simp sc = device_get_softc(busdev); 183163516Simp MMC_LOCK(sc); 184163516Simp if (sc->owner) 185163516Simp panic("mmc: host bridge didn't seralize us."); 186163516Simp sc->owner = dev; 187163516Simp MMC_UNLOCK(sc); 188163516Simp 189163516Simp if (busdev != dev) { 190183453Simp /* 191183453Simp * Keep track of the last rca that we've selected. If 192183453Simp * we're asked to do it again, don't. We never 193183453Simp * unselect unless the bus code itself wants the mmc 194183453Simp * bus, and constantly reselecting causes problems. 195183453Simp */ 196163516Simp rca = mmc_get_rca(dev); 197163516Simp if (sc->last_rca != rca) { 198163516Simp mmc_wait_for_command(sc, MMC_SELECT_CARD, rca << 16, 199163516Simp MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES); 200163516Simp sc->last_rca = rca; 201163516Simp } 202183453Simp /* XXX should set bus width here? */ 203163516Simp } else { 204183453Simp /* 205183453Simp * If there's a card selected, stand down. 206183453Simp */ 207163516Simp if (sc->last_rca != 0) { 208163516Simp mmc_wait_for_command(sc, MMC_SELECT_CARD, 0, 209163516Simp MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES); 210163516Simp sc->last_rca = 0; 211163516Simp } 212183453Simp /* XXX should set bus width here? */ 213163516Simp } 214163516Simp 215163516Simp return (0); 216163516Simp} 217163516Simp 218163516Simpstatic int 219163516Simpmmc_release_bus(device_t busdev, device_t dev) 220163516Simp{ 221163516Simp struct mmc_softc *sc; 222163516Simp int err; 223163516Simp 224163516Simp sc = device_get_softc(busdev); 225163516Simp 226163516Simp MMC_LOCK(sc); 227163516Simp if (!sc->owner) 228163516Simp panic("mmc: releasing unowned bus."); 229163516Simp if (sc->owner != dev) 230163516Simp panic("mmc: you don't own the bus. game over."); 231163516Simp MMC_UNLOCK(sc); 232183452Simp err = MMCBR_RELEASE_HOST(device_get_parent(busdev), busdev); 233163516Simp if (err) 234163516Simp return (err); 235163516Simp MMC_LOCK(sc); 236163516Simp sc->owner = NULL; 237163516Simp MMC_UNLOCK(sc); 238163516Simp return (0); 239163516Simp} 240163516Simp 241163516Simpstatic void 242163516Simpmmc_rescan_cards(struct mmc_softc *sc) 243163516Simp{ 244163516Simp /* XXX: Look at the children and see if they respond to status */ 245163516Simp} 246163516Simp 247163516Simpstatic uint32_t 248163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr) 249163516Simp{ 250183446Simp 251183446Simp return ocr & MMC_OCR_VOLTAGE; 252163516Simp} 253163516Simp 254163516Simpstatic int 255163516Simpmmc_highest_voltage(uint32_t ocr) 256163516Simp{ 257163516Simp int i; 258163516Simp 259163516Simp for (i = 30; i >= 0; i--) 260163516Simp if (ocr & (1 << i)) 261163516Simp return i; 262163516Simp return (-1); 263163516Simp} 264163516Simp 265163516Simpstatic void 266163516Simpmmc_wakeup(struct mmc_request *req) 267163516Simp{ 268163516Simp struct mmc_softc *sc; 269163516Simp 270183453Simp/* printf("Wakeup for req %p done_data %p\n", req, req->done_data); */ 271163516Simp sc = (struct mmc_softc *)req->done_data; 272163516Simp MMC_LOCK(sc); 273163516Simp req->flags |= MMC_REQ_DONE; 274163516Simp wakeup(req); 275163516Simp MMC_UNLOCK(sc); 276163516Simp} 277163516Simp 278163516Simpstatic int 279163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req) 280163516Simp{ 281163516Simp int err; 282163516Simp 283163516Simp req->done = mmc_wakeup; 284163516Simp req->done_data = sc; 285183453Simp/* printf("Submitting request %p sc %p\n", req, sc); */ 286163516Simp MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req); 287163516Simp MMC_LOCK(sc); 288163516Simp do { 289163516Simp err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq", 290163516Simp hz / 10); 291163516Simp } while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN); 292183453Simp/* printf("Request %p done with error %d\n", req, err); */ 293163516Simp MMC_UNLOCK(sc); 294163516Simp return (err); 295163516Simp} 296163516Simp 297163516Simpstatic int 298163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req) 299163516Simp{ 300163516Simp struct mmc_softc *sc = device_get_softc(brdev); 301163516Simp 302163516Simp return mmc_wait_for_req(sc, req); 303163516Simp} 304163516Simp 305163516Simpstatic int 306163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries) 307163516Simp{ 308163516Simp struct mmc_request mreq; 309163516Simp 310163516Simp memset(&mreq, 0, sizeof(mreq)); 311163516Simp memset(cmd->resp, 0, sizeof(cmd->resp)); 312163516Simp cmd->retries = retries; 313163516Simp cmd->data = NULL; 314163516Simp mreq.cmd = cmd; 315183453Simp/* printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); */ 316163516Simp mmc_wait_for_req(sc, &mreq); 317163516Simp return (cmd->error); 318163516Simp} 319163516Simp 320163516Simpstatic int 321163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca, 322163516Simp struct mmc_command *cmd, int retries) 323163516Simp{ 324163516Simp struct mmc_command appcmd; 325163516Simp int err = MMC_ERR_NONE, i; 326163516Simp 327163516Simp for (i = 0; i <= retries; i++) { 328163516Simp appcmd.opcode = MMC_APP_CMD; 329163516Simp appcmd.arg = rca << 16; 330163516Simp appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 331163516Simp mmc_wait_for_cmd(sc, &appcmd, 0); 332163516Simp err = appcmd.error; 333163516Simp if (err != MMC_ERR_NONE) 334163516Simp continue; 335163516Simp if (!(appcmd.resp[0] & R1_APP_CMD)) 336163516Simp return MMC_ERR_FAILED; 337163516Simp mmc_wait_for_cmd(sc, cmd, 0); 338163516Simp err = cmd->error; 339163516Simp if (err == MMC_ERR_NONE) 340163516Simp break; 341163516Simp } 342163516Simp return (err); 343163516Simp} 344163516Simp 345163516Simpstatic int 346163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 347163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries) 348163516Simp{ 349163516Simp struct mmc_command cmd; 350163516Simp int err; 351163516Simp 352163516Simp memset(&cmd, 0, sizeof(cmd)); 353163516Simp cmd.opcode = opcode; 354163516Simp cmd.arg = arg; 355163516Simp cmd.flags = flags; 356163516Simp err = mmc_wait_for_cmd(sc, &cmd, retries); 357163516Simp if (err) 358163516Simp return (err); 359163516Simp if (cmd.error) 360163516Simp return (cmd.error); 361163516Simp if (resp) { 362163516Simp if (flags & MMC_RSP_136) 363163516Simp memcpy(resp, cmd.resp, 4 * sizeof(uint32_t)); 364163516Simp else 365163516Simp *resp = cmd.resp[0]; 366163516Simp } 367163516Simp return (0); 368163516Simp} 369163516Simp 370163516Simpstatic void 371163516Simpmmc_idle_cards(struct mmc_softc *sc) 372163516Simp{ 373163516Simp device_t dev; 374163516Simp struct mmc_command cmd; 375163516Simp 376163516Simp dev = sc->dev; 377163516Simp mmcbr_set_chip_select(dev, cs_high); 378163516Simp mmcbr_update_ios(dev); 379163516Simp mmc_ms_delay(1); 380163516Simp 381163516Simp memset(&cmd, 0, sizeof(cmd)); 382163516Simp cmd.opcode = MMC_GO_IDLE_STATE; 383163516Simp cmd.arg = 0; 384163516Simp cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; 385163516Simp mmc_wait_for_cmd(sc, &cmd, 0); 386163516Simp mmc_ms_delay(1); 387163516Simp 388163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 389163516Simp mmcbr_update_ios(dev); 390163516Simp mmc_ms_delay(1); 391163516Simp} 392163516Simp 393163516Simpstatic int 394163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 395163516Simp{ 396163516Simp struct mmc_command cmd; 397163516Simp int err = MMC_ERR_NONE, i; 398163516Simp 399163516Simp memset(&cmd, 0, sizeof(cmd)); 400163516Simp cmd.opcode = ACMD_SD_SEND_OP_COND; 401163516Simp cmd.arg = ocr; 402163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 403163516Simp 404170337Simp for (i = 0; i < 100; i++) { 405163516Simp err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES); 406163516Simp if (err != MMC_ERR_NONE) 407163516Simp break; 408163516Simp if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0) 409163516Simp break; 410163516Simp err = MMC_ERR_TIMEOUT; 411163516Simp mmc_ms_delay(10); 412163516Simp } 413163516Simp if (rocr && err == MMC_ERR_NONE) 414163516Simp *rocr = cmd.resp[0]; 415163516Simp return err; 416163516Simp} 417163516Simp 418163516Simpstatic int 419163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 420163516Simp{ 421163516Simp struct mmc_command cmd; 422163516Simp int err = MMC_ERR_NONE, i; 423163516Simp 424163516Simp memset(&cmd, 0, sizeof(cmd)); 425163516Simp cmd.opcode = MMC_SEND_OP_COND; 426163516Simp cmd.arg = ocr; 427163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 428163516Simp 429163516Simp for (i = 0; i < 100; i++) { 430163516Simp err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 431163516Simp if (err != MMC_ERR_NONE) 432163516Simp break; 433163516Simp if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0) 434163516Simp break; 435163516Simp err = MMC_ERR_TIMEOUT; 436163516Simp mmc_ms_delay(10); 437163516Simp } 438163516Simp if (rocr && err == MMC_ERR_NONE) 439163516Simp *rocr = cmd.resp[0]; 440163516Simp return err; 441163516Simp} 442163516Simp 443163516Simpstatic void 444163516Simpmmc_power_up(struct mmc_softc *sc) 445163516Simp{ 446163516Simp device_t dev; 447163516Simp 448163516Simp dev = sc->dev; 449163516Simp mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev))); 450163516Simp mmcbr_set_bus_mode(dev, opendrain); 451163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 452163516Simp mmcbr_set_bus_width(dev, bus_width_1); 453163516Simp mmcbr_set_power_mode(dev, power_up); 454163516Simp mmcbr_set_clock(dev, 0); 455163516Simp mmcbr_update_ios(dev); 456163516Simp mmc_ms_delay(1); 457163516Simp 458163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev)); 459163516Simp mmcbr_set_power_mode(dev, power_on); 460163516Simp mmcbr_update_ios(dev); 461163516Simp mmc_ms_delay(2); 462163516Simp} 463163516Simp 464183449Simpstatic void 465183449Simpmmc_power_down(struct mmc_softc *sc) 466183449Simp{ 467183449Simp device_t dev = sc->dev; 468183449Simp 469183449Simp mmcbr_set_bus_mode(dev, opendrain); 470183449Simp mmcbr_set_chip_select(dev, cs_dontcare); 471183449Simp mmcbr_set_bus_width(dev, bus_width_1); 472183449Simp mmcbr_set_power_mode(dev, power_off); 473183449Simp mmcbr_set_clock(dev, 0); 474183449Simp mmcbr_update_ios(dev); 475183449Simp} 476183449Simp 477163516Simpstatic uint32_t 478163516Simpmmc_get_bits(uint32_t *bits, int start, int size) 479163516Simp{ 480163516Simp const int i = 3 - (start / 32); 481163516Simp const int shift = start & 31; 482163516Simp uint32_t retval = bits[i] >> shift; 483163516Simp if (size + shift > 32) 484163516Simp retval |= bits[i - 1] << (32 - shift); 485163516Simp return retval & ((1 << size) - 1); 486163516Simp} 487163516Simp 488163516Simpstatic void 489163516Simpmmc_decode_cid(int is_sd, uint32_t *raw_cid, struct mmc_cid *cid) 490163516Simp{ 491163516Simp int i; 492163516Simp 493163516Simp memset(cid, 0, sizeof(*cid)); 494163516Simp if (is_sd) { 495163516Simp /* There's no version info, so we take it on faith */ 496163516Simp cid->mid = mmc_get_bits(raw_cid, 120, 8); 497163516Simp cid->oid = mmc_get_bits(raw_cid, 104, 16); 498163516Simp for (i = 0; i < 5; i++) 499163516Simp cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8); 500163516Simp cid->prv = mmc_get_bits(raw_cid, 56, 8); 501163516Simp cid->psn = mmc_get_bits(raw_cid, 24, 32); 502163516Simp cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001; 503163516Simp cid->mdt_month = mmc_get_bits(raw_cid, 8, 4); 504163516Simp } else { 505183453Simp /* XXX write me */ 506163516Simp panic("write mmc cid decoder"); 507163516Simp } 508163516Simp} 509163516Simp 510163516Simpstatic const int exp[8] = { 511163516Simp 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 512163516Simp}; 513163516Simpstatic const int mant[16] = { 514163516Simp 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 515163516Simp}; 516163516Simpstatic const int cur_min[8] = { 517163516Simp 500, 1000, 5000, 10000, 25000, 35000, 60000, 100000 518163516Simp}; 519163516Simpstatic const int cur_max[8] = { 520163516Simp 1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000 521163516Simp}; 522163516Simp 523163516Simpstatic void 524163516Simpmmc_decode_csd(int is_sd, uint32_t *raw_csd, struct mmc_csd *csd) 525163516Simp{ 526163516Simp int v; 527163516Simp int m; 528163516Simp int e; 529163516Simp 530163516Simp memset(csd, 0, sizeof(*csd)); 531163516Simp if (is_sd) { 532163516Simp csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2); 533163516Simp if (v == 0) { 534163516Simp m = mmc_get_bits(raw_csd, 115, 4); 535163516Simp e = mmc_get_bits(raw_csd, 112, 3); 536163516Simp csd->tacc = exp[e] * mant[m] + 9 / 10; 537163516Simp csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100; 538163516Simp m = mmc_get_bits(raw_csd, 99, 4); 539163516Simp e = mmc_get_bits(raw_csd, 96, 3); 540163516Simp csd->tran_speed = exp[e] * 10000 * mant[m]; 541163516Simp csd->ccc = mmc_get_bits(raw_csd, 84, 12); 542163516Simp csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4); 543163516Simp csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1); 544163516Simp csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1); 545163516Simp csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1); 546163516Simp csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1); 547163516Simp csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)]; 548163516Simp csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)]; 549163516Simp csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)]; 550163516Simp csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)]; 551163516Simp m = mmc_get_bits(raw_csd, 62, 12); 552163516Simp e = mmc_get_bits(raw_csd, 47, 3); 553163516Simp csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; 554163516Simp csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1); 555163516Simp csd->sector_size = mmc_get_bits(raw_csd, 39, 7); 556163516Simp csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7); 557163516Simp csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1); 558163516Simp csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3); 559163516Simp csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4); 560163516Simp csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1); 561163516Simp } else if (v == 1) { 562163516Simp panic("Write SDHC CSD parser"); 563163516Simp } else 564163516Simp panic("unknown SD CSD version"); 565163516Simp } else { 566163516Simp panic("Write a MMC CSD parser"); 567163516Simp } 568163516Simp} 569163516Simp 570163516Simpstatic int 571163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid) 572163516Simp{ 573163516Simp struct mmc_command cmd; 574163516Simp int err; 575163516Simp 576163516Simp cmd.opcode = MMC_ALL_SEND_CID; 577163516Simp cmd.arg = 0; 578163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 579163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 580163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 581163516Simp return (err); 582163516Simp} 583163516Simp 584163516Simpstatic int 585163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid) 586163516Simp{ 587163516Simp struct mmc_command cmd; 588163516Simp int err; 589163516Simp 590163516Simp cmd.opcode = MMC_SEND_CSD; 591163516Simp cmd.arg = rca << 16; 592163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 593163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 594163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 595163516Simp return (err); 596163516Simp} 597163516Simp 598163516Simpstatic int 599163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp) 600163516Simp{ 601163516Simp struct mmc_command cmd; 602163516Simp int err; 603163516Simp 604163516Simp cmd.opcode = SD_SEND_RELATIVE_ADDR; 605163516Simp cmd.arg = 0; 606163516Simp cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; 607163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 608163516Simp *resp = cmd.resp[0]; 609163516Simp return (err); 610163516Simp} 611163516Simp 612163516Simpstatic void 613163516Simpmmc_discover_cards(struct mmc_softc *sc) 614163516Simp{ 615163516Simp struct mmc_ivars *ivar; 616163516Simp int err; 617163516Simp uint32_t resp; 618163516Simp device_t child; 619163516Simp 620163516Simp while (1) { 621163516Simp ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, M_WAITOK); 622169567Simp if (!ivar) 623169567Simp return; 624163516Simp err = mmc_all_send_cid(sc, ivar->raw_cid); 625163516Simp if (err == MMC_ERR_TIMEOUT) 626163516Simp break; 627163516Simp if (err != MMC_ERR_NONE) { 628163516Simp printf("Error reading CID %d\n", err); 629163516Simp break; 630163516Simp } 631163516Simp if (mmcbr_get_mode(sc->dev) == mode_sd) { 632163516Simp ivar->mode = mode_sd; 633163516Simp mmc_decode_cid(1, ivar->raw_cid, &ivar->cid); 634163516Simp mmc_send_relative_addr(sc, &resp); 635163516Simp ivar->rca = resp >> 16; 636183447Simp if (mmcbr_get_ro(sc->dev)) 637183447Simp ivar->read_only = 1; 638163516Simp mmc_send_csd(sc, ivar->rca, ivar->raw_csd); 639163516Simp mmc_decode_csd(1, ivar->raw_csd, &ivar->csd); 640169567Simp printf("SD CARD: %lld bytes\n", (long long) 641169567Simp ivar->csd.capacity); 642163516Simp child = device_add_child(sc->dev, NULL, -1); 643163516Simp device_set_ivars(child, ivar); 644169567Simp return; 645163516Simp } 646163516Simp panic("Write MMC card code here"); 647163516Simp } 648169567Simp free(ivar, M_DEVBUF); 649163516Simp} 650163516Simp 651163516Simpstatic void 652163516Simpmmc_go_discovery(struct mmc_softc *sc) 653163516Simp{ 654163516Simp uint32_t ocr; 655163516Simp device_t dev; 656163516Simp 657163516Simp dev = sc->dev; 658163516Simp if (mmcbr_get_power_mode(dev) != power_on) { 659183453Simp /* 660183453Simp * First, try SD modes 661183453Simp */ 662163516Simp mmcbr_set_mode(dev, mode_sd); 663163516Simp mmc_power_up(sc); 664163516Simp mmcbr_set_bus_mode(dev, pushpull); 665163516Simp mmc_idle_cards(sc); 666163516Simp if (mmc_send_app_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) { 667183453Simp /* 668183453Simp * Failed, try MMC 669183453Simp */ 670163516Simp mmcbr_set_mode(dev, mode_mmc); 671163516Simp if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) 672183453Simp return; /* Failed both, punt! XXX powerdown? */ 673163516Simp } 674163516Simp mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr)); 675163516Simp if (mmcbr_get_ocr(dev) != 0) 676163516Simp mmc_idle_cards(sc); 677163516Simp } else { 678163516Simp mmcbr_set_bus_mode(dev, opendrain); 679163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(dev)); 680163516Simp mmcbr_update_ios(dev); 681183453Simp /* XXX recompute vdd based on new cards? */ 682163516Simp } 683163516Simp /* 684163516Simp * Make sure that we have a mutually agreeable voltage to at least 685163516Simp * one card on the bus. 686163516Simp */ 687163516Simp if (mmcbr_get_ocr(dev) == 0) 688163516Simp return; 689163516Simp /* 690163516Simp * Reselect the cards after we've idled them above. 691163516Simp */ 692163516Simp if (mmcbr_get_mode(dev) == mode_sd) 693163516Simp mmc_send_app_op_cond(sc, mmcbr_get_ocr(dev), NULL); 694163516Simp else 695163516Simp mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL); 696163516Simp mmc_discover_cards(sc); 697163516Simp 698163516Simp mmcbr_set_bus_mode(dev, pushpull); 699163516Simp mmcbr_update_ios(dev); 700163516Simp bus_generic_attach(dev); 701183453Simp/* mmc_update_children_sysctl(dev);*/ 702163516Simp} 703163516Simp 704163516Simpstatic int 705163516Simpmmc_calculate_clock(struct mmc_softc *sc) 706163516Simp{ 707163516Simp int max_dtr = 0; 708163516Simp int nkid, i, f_min, f_max; 709163516Simp device_t *kids; 710163516Simp 711163516Simp f_min = mmcbr_get_f_min(sc->dev); 712163516Simp f_max = mmcbr_get_f_max(sc->dev); 713163516Simp max_dtr = f_max; 714163516Simp if (device_get_children(sc->dev, &kids, &nkid) != 0) 715163516Simp panic("can't get children"); 716163516Simp for (i = 0; i < nkid; i++) 717163516Simp if (mmc_get_tran_speed(kids[i]) < max_dtr) 718163516Simp max_dtr = mmc_get_tran_speed(kids[i]); 719163516Simp free(kids, M_TEMP); 720163516Simp device_printf(sc->dev, "setting transfer rate to %d.%03dMHz\n", 721163516Simp max_dtr / 1000000, (max_dtr / 1000) % 1000); 722163516Simp return max_dtr; 723163516Simp} 724163516Simp 725163516Simpstatic void 726163516Simpmmc_scan(struct mmc_softc *sc) 727163516Simp{ 728163516Simp device_t dev; 729163516Simp 730163516Simp dev = sc->dev; 731163516Simp mmc_acquire_bus(dev, dev); 732163516Simp 733163516Simp if (mmcbr_get_power_mode(dev) == power_on) 734163516Simp mmc_rescan_cards(sc); 735163516Simp mmc_go_discovery(sc); 736163516Simp mmcbr_set_clock(dev, mmc_calculate_clock(sc)); 737163516Simp mmcbr_update_ios(dev); 738163516Simp 739163516Simp mmc_release_bus(dev, dev); 740183453Simp /* XXX probe/attach/detach children? */ 741163516Simp} 742163516Simp 743163516Simpstatic int 744163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result) 745163516Simp{ 746163516Simp struct mmc_ivars *ivar = device_get_ivars(child); 747163516Simp 748163516Simp switch (which) { 749163516Simp default: 750163516Simp return (EINVAL); 751163516Simp case MMC_IVAR_DSR_IMP: 752163516Simp *(int *)result = ivar->csd.dsr_imp; 753163516Simp break; 754163516Simp case MMC_IVAR_MEDIA_SIZE: 755163516Simp *(int *)result = ivar->csd.capacity; 756163516Simp break; 757163516Simp case MMC_IVAR_RCA: 758163516Simp *(int *)result = ivar->rca; 759163516Simp break; 760163516Simp case MMC_IVAR_SECTOR_SIZE: 761163516Simp *(int *)result = 512; 762163516Simp break; 763163516Simp case MMC_IVAR_TRAN_SPEED: 764163516Simp *(int *)result = ivar->csd.tran_speed; 765163516Simp break; 766183447Simp case MMC_IVAR_READ_ONLY: 767183447Simp *(int *)result = ivar->read_only; 768183447Simp break; 769163516Simp } 770163516Simp return (0); 771163516Simp} 772163516Simp 773163516Simpstatic int 774163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value) 775163516Simp{ 776183453Simp /* 777183453Simp * None are writable ATM 778183453Simp */ 779183453Simp return (EINVAL); 780163516Simp} 781163516Simp 782163516Simp 783163516Simpstatic void 784163516Simpmmc_delayed_attach(void *xsc) 785163516Simp{ 786163516Simp struct mmc_softc *sc = xsc; 787163516Simp 788163516Simp mmc_scan(sc); 789163516Simp config_intrhook_disestablish(&sc->config_intrhook); 790163516Simp} 791163516Simp 792163516Simpstatic device_method_t mmc_methods[] = { 793163516Simp /* device_if */ 794163516Simp DEVMETHOD(device_probe, mmc_probe), 795163516Simp DEVMETHOD(device_attach, mmc_attach), 796163516Simp DEVMETHOD(device_detach, mmc_detach), 797163516Simp 798163516Simp /* Bus interface */ 799163516Simp DEVMETHOD(bus_read_ivar, mmc_read_ivar), 800163516Simp DEVMETHOD(bus_write_ivar, mmc_write_ivar), 801163516Simp 802163516Simp /* MMC Bus interface */ 803163516Simp DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request), 804163516Simp DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus), 805163516Simp DEVMETHOD(mmcbus_release_bus, mmc_release_bus), 806163516Simp 807163516Simp {0, 0}, 808163516Simp}; 809163516Simp 810163516Simpstatic driver_t mmc_driver = { 811163516Simp "mmc", 812163516Simp mmc_methods, 813163516Simp sizeof(struct mmc_softc), 814163516Simp}; 815163516Simpstatic devclass_t mmc_devclass; 816163516Simp 817163516Simp 818163516SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0); 819169567SimpDRIVER_MODULE(mmc, sdh, mmc_driver, mmc_devclass, 0, 0); 820