mmc.c revision 163516
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. 24163516Simp */ 25163516Simp 26163516Simp#include <sys/cdefs.h> 27163516Simp__FBSDID("$FreeBSD: head/sys/dev/mmc/mmc.c 163516 2006-10-20 06:39:59Z imp $"); 28163516Simp 29163516Simp#include <sys/param.h> 30163516Simp#include <sys/systm.h> 31163516Simp#include <sys/kernel.h> 32163516Simp#include <sys/malloc.h> 33163516Simp#include <sys/lock.h> 34163516Simp#include <sys/module.h> 35163516Simp#include <sys/mutex.h> 36163516Simp#include <sys/bus.h> 37163516Simp 38163516Simp#include <dev/mmc/mmcreg.h> 39163516Simp#include <dev/mmc/mmcbrvar.h> 40163516Simp#include <dev/mmc/mmcvar.h> 41163516Simp#include "mmcbr_if.h" 42163516Simp#include "mmcbus_if.h" 43163516Simp 44163516Simpstruct mmc_softc { 45163516Simp device_t dev; 46163516Simp struct mtx sc_mtx; 47163516Simp struct intr_config_hook config_intrhook; 48163516Simp device_t owner; 49163516Simp uint32_t last_rca; 50163516Simp}; 51163516Simp 52163516Simp/* 53163516Simp * Per-card data 54163516Simp */ 55163516Simpstruct mmc_ivars { 56163516Simp uint32_t raw_cid[4]; /* Raw bits of the CID */ 57163516Simp uint32_t raw_csd[4]; /* Raw bits of the CSD */ 58163516Simp uint16_t rca; 59163516Simp enum mmc_card_mode mode; 60163516Simp struct mmc_cid cid; /* cid decoded */ 61163516Simp struct mmc_csd csd; /* csd decoded */ 62163516Simp}; 63163516Simp 64163516Simp#define CMD_RETRIES 3 65163516Simp 66163516Simp/* bus entry points */ 67163516Simpstatic int mmc_probe(device_t dev); 68163516Simpstatic int mmc_attach(device_t dev); 69163516Simpstatic int mmc_detach(device_t dev); 70163516Simp 71163516Simp#define MMC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 72163516Simp#define MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 73163516Simp#define MMC_LOCK_INIT(_sc) \ 74163516Simp mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ 75163516Simp "mmc", MTX_DEF) 76163516Simp#define MMC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 77163516Simp#define MMC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 78163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 79163516Simp 80163516Simpstatic void mmc_delayed_attach(void *); 81163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, 82163516Simp int retries); 83163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 84163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries); 85163516Simp 86163516Simpstatic void 87163516Simpmmc_ms_delay(int ms) 88163516Simp{ 89163516Simp DELAY(1000 * ms); /* XXX BAD */ 90163516Simp} 91163516Simp 92163516Simpstatic int 93163516Simpmmc_probe(device_t dev) 94163516Simp{ 95163516Simp 96163516Simp device_set_desc(dev, "mmc/sd bus"); 97163516Simp return (0); 98163516Simp} 99163516Simp 100163516Simpstatic int 101163516Simpmmc_attach(device_t dev) 102163516Simp{ 103163516Simp struct mmc_softc *sc; 104163516Simp 105163516Simp sc = device_get_softc(dev); 106163516Simp sc->dev = dev; 107163516Simp MMC_LOCK_INIT(sc); 108163516Simp 109163516Simp /* We'll probe and attach our children later, but before / mount */ 110163516Simp sc->config_intrhook.ich_func = mmc_delayed_attach; 111163516Simp sc->config_intrhook.ich_arg = sc; 112163516Simp if (config_intrhook_establish(&sc->config_intrhook) != 0) 113163516Simp device_printf(dev, "config_intrhook_establish failed\n"); 114163516Simp return (0); 115163516Simp} 116163516Simp 117163516Simpstatic int 118163516Simpmmc_detach(device_t dev) 119163516Simp{ 120163516Simp return (EBUSY); /* XXX */ 121163516Simp} 122163516Simp 123163516Simpstatic int 124163516Simpmmc_acquire_bus(device_t busdev, device_t dev) 125163516Simp{ 126163516Simp struct mmc_softc *sc; 127163516Simp int err; 128163516Simp int rca; 129163516Simp 130163516Simp err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), dev); 131163516Simp if (err) 132163516Simp return (err); 133163516Simp sc = device_get_softc(busdev); 134163516Simp MMC_LOCK(sc); 135163516Simp if (sc->owner) 136163516Simp panic("mmc: host bridge didn't seralize us."); 137163516Simp sc->owner = dev; 138163516Simp MMC_UNLOCK(sc); 139163516Simp 140163516Simp if (busdev != dev) { 141163516Simp // Keep track of the last rca that we've selected. If 142163516Simp // we're asked to do it again, don't. We never unselect 143163516Simp // unless the bus code itself wants the mmc bus. 144163516Simp rca = mmc_get_rca(dev); 145163516Simp if (sc->last_rca != rca) { 146163516Simp mmc_wait_for_command(sc, MMC_SELECT_CARD, rca << 16, 147163516Simp MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES); 148163516Simp sc->last_rca = rca; 149163516Simp } 150163516Simp // XXX should set bus width here? 151163516Simp } else { 152163516Simp // If there's a card selected, stand down. 153163516Simp if (sc->last_rca != 0) { 154163516Simp mmc_wait_for_command(sc, MMC_SELECT_CARD, 0, 155163516Simp MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES); 156163516Simp sc->last_rca = 0; 157163516Simp } 158163516Simp // XXX should set bus width here? 159163516Simp } 160163516Simp 161163516Simp return (0); 162163516Simp} 163163516Simp 164163516Simpstatic int 165163516Simpmmc_release_bus(device_t busdev, device_t dev) 166163516Simp{ 167163516Simp struct mmc_softc *sc; 168163516Simp int err; 169163516Simp 170163516Simp sc = device_get_softc(busdev); 171163516Simp 172163516Simp MMC_LOCK(sc); 173163516Simp if (!sc->owner) 174163516Simp panic("mmc: releasing unowned bus."); 175163516Simp if (sc->owner != dev) 176163516Simp panic("mmc: you don't own the bus. game over."); 177163516Simp MMC_UNLOCK(sc); 178163516Simp err = MMCBR_RELEASE_HOST(device_get_parent(busdev), dev); 179163516Simp if (err) 180163516Simp return (err); 181163516Simp MMC_LOCK(sc); 182163516Simp sc->owner = NULL; 183163516Simp MMC_UNLOCK(sc); 184163516Simp return (0); 185163516Simp} 186163516Simp 187163516Simpstatic void 188163516Simpmmc_rescan_cards(struct mmc_softc *sc) 189163516Simp{ 190163516Simp /* XXX: Look at the children and see if they respond to status */ 191163516Simp} 192163516Simp 193163516Simpstatic uint32_t 194163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr) 195163516Simp{ 196163516Simp // XXX 197163516Simp return ocr; 198163516Simp} 199163516Simp 200163516Simpstatic int 201163516Simpmmc_highest_voltage(uint32_t ocr) 202163516Simp{ 203163516Simp int i; 204163516Simp 205163516Simp for (i = 30; i >= 0; i--) 206163516Simp if (ocr & (1 << i)) 207163516Simp return i; 208163516Simp return (-1); 209163516Simp} 210163516Simp 211163516Simpstatic void 212163516Simpmmc_wakeup(struct mmc_request *req) 213163516Simp{ 214163516Simp struct mmc_softc *sc; 215163516Simp 216163516Simp// printf("Wakeup for req %p done_data %p\n", req, req->done_data); 217163516Simp sc = (struct mmc_softc *)req->done_data; 218163516Simp MMC_LOCK(sc); 219163516Simp req->flags |= MMC_REQ_DONE; 220163516Simp wakeup(req); 221163516Simp MMC_UNLOCK(sc); 222163516Simp} 223163516Simp 224163516Simpstatic int 225163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req) 226163516Simp{ 227163516Simp int err; 228163516Simp 229163516Simp req->done = mmc_wakeup; 230163516Simp req->done_data = sc; 231163516Simp// printf("Submitting request %p sc %p\n", req, sc); 232163516Simp MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req); 233163516Simp MMC_LOCK(sc); 234163516Simp do { 235163516Simp err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq", 236163516Simp hz / 10); 237163516Simp } while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN); 238163516Simp// printf("Request %p done with error %d\n", req, err); 239163516Simp MMC_UNLOCK(sc); 240163516Simp return (err); 241163516Simp} 242163516Simp 243163516Simpstatic int 244163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req) 245163516Simp{ 246163516Simp struct mmc_softc *sc = device_get_softc(brdev); 247163516Simp 248163516Simp return mmc_wait_for_req(sc, req); 249163516Simp} 250163516Simp 251163516Simpstatic int 252163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries) 253163516Simp{ 254163516Simp struct mmc_request mreq; 255163516Simp 256163516Simp memset(&mreq, 0, sizeof(mreq)); 257163516Simp memset(cmd->resp, 0, sizeof(cmd->resp)); 258163516Simp cmd->retries = retries; 259163516Simp cmd->data = NULL; 260163516Simp mreq.cmd = cmd; 261163516Simp// printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); 262163516Simp mmc_wait_for_req(sc, &mreq); 263163516Simp return (cmd->error); 264163516Simp} 265163516Simp 266163516Simpstatic int 267163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca, 268163516Simp struct mmc_command *cmd, int retries) 269163516Simp{ 270163516Simp struct mmc_command appcmd; 271163516Simp int err = MMC_ERR_NONE, i; 272163516Simp 273163516Simp for (i = 0; i <= retries; i++) { 274163516Simp appcmd.opcode = MMC_APP_CMD; 275163516Simp appcmd.arg = rca << 16; 276163516Simp appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 277163516Simp mmc_wait_for_cmd(sc, &appcmd, 0); 278163516Simp err = appcmd.error; 279163516Simp if (err != MMC_ERR_NONE) 280163516Simp continue; 281163516Simp if (!(appcmd.resp[0] & R1_APP_CMD)) 282163516Simp return MMC_ERR_FAILED; 283163516Simp mmc_wait_for_cmd(sc, cmd, 0); 284163516Simp err = cmd->error; 285163516Simp if (err == MMC_ERR_NONE) 286163516Simp break; 287163516Simp } 288163516Simp return (err); 289163516Simp} 290163516Simp 291163516Simpstatic int 292163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 293163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries) 294163516Simp{ 295163516Simp struct mmc_command cmd; 296163516Simp int err; 297163516Simp 298163516Simp memset(&cmd, 0, sizeof(cmd)); 299163516Simp cmd.opcode = opcode; 300163516Simp cmd.arg = arg; 301163516Simp cmd.flags = flags; 302163516Simp err = mmc_wait_for_cmd(sc, &cmd, retries); 303163516Simp if (err) 304163516Simp return (err); 305163516Simp if (cmd.error) 306163516Simp return (cmd.error); 307163516Simp if (resp) { 308163516Simp if (flags & MMC_RSP_136) 309163516Simp memcpy(resp, cmd.resp, 4 * sizeof(uint32_t)); 310163516Simp else 311163516Simp *resp = cmd.resp[0]; 312163516Simp } 313163516Simp return (0); 314163516Simp} 315163516Simp 316163516Simpstatic void 317163516Simpmmc_idle_cards(struct mmc_softc *sc) 318163516Simp{ 319163516Simp device_t dev; 320163516Simp struct mmc_command cmd; 321163516Simp 322163516Simp dev = sc->dev; 323163516Simp mmcbr_set_chip_select(dev, cs_high); 324163516Simp mmcbr_update_ios(dev); 325163516Simp mmc_ms_delay(1); 326163516Simp 327163516Simp memset(&cmd, 0, sizeof(cmd)); 328163516Simp cmd.opcode = MMC_GO_IDLE_STATE; 329163516Simp cmd.arg = 0; 330163516Simp cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; 331163516Simp mmc_wait_for_cmd(sc, &cmd, 0); 332163516Simp mmc_ms_delay(1); 333163516Simp 334163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 335163516Simp mmcbr_update_ios(dev); 336163516Simp mmc_ms_delay(1); 337163516Simp} 338163516Simp 339163516Simpstatic int 340163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 341163516Simp{ 342163516Simp struct mmc_command cmd; 343163516Simp int err = MMC_ERR_NONE, i; 344163516Simp 345163516Simp memset(&cmd, 0, sizeof(cmd)); 346163516Simp cmd.opcode = ACMD_SD_SEND_OP_COND; 347163516Simp cmd.arg = ocr; 348163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 349163516Simp 350163516Simp for (i = 0; i < 10; i++) { 351163516Simp err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES); 352163516Simp if (err != MMC_ERR_NONE) 353163516Simp break; 354163516Simp if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0) 355163516Simp break; 356163516Simp err = MMC_ERR_TIMEOUT; 357163516Simp mmc_ms_delay(10); 358163516Simp } 359163516Simp if (rocr && err == MMC_ERR_NONE) 360163516Simp *rocr = cmd.resp[0]; 361163516Simp return err; 362163516Simp} 363163516Simp 364163516Simpstatic int 365163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 366163516Simp{ 367163516Simp struct mmc_command cmd; 368163516Simp int err = MMC_ERR_NONE, i; 369163516Simp 370163516Simp memset(&cmd, 0, sizeof(cmd)); 371163516Simp cmd.opcode = MMC_SEND_OP_COND; 372163516Simp cmd.arg = ocr; 373163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 374163516Simp 375163516Simp for (i = 0; i < 100; i++) { 376163516Simp err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 377163516Simp if (err != MMC_ERR_NONE) 378163516Simp break; 379163516Simp if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0) 380163516Simp break; 381163516Simp err = MMC_ERR_TIMEOUT; 382163516Simp mmc_ms_delay(10); 383163516Simp } 384163516Simp if (rocr && err == MMC_ERR_NONE) 385163516Simp *rocr = cmd.resp[0]; 386163516Simp return err; 387163516Simp} 388163516Simp 389163516Simpstatic void 390163516Simpmmc_power_up(struct mmc_softc *sc) 391163516Simp{ 392163516Simp device_t dev; 393163516Simp 394163516Simp dev = sc->dev; 395163516Simp mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev))); 396163516Simp mmcbr_set_bus_mode(dev, opendrain); 397163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 398163516Simp mmcbr_set_bus_width(dev, bus_width_1); 399163516Simp mmcbr_set_power_mode(dev, power_up); 400163516Simp mmcbr_set_clock(dev, 0); 401163516Simp mmcbr_update_ios(dev); 402163516Simp mmc_ms_delay(1); 403163516Simp 404163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev)); 405163516Simp mmcbr_set_power_mode(dev, power_on); 406163516Simp mmcbr_update_ios(dev); 407163516Simp mmc_ms_delay(2); 408163516Simp} 409163516Simp 410163516Simp// I wonder if the following is endian safe. 411163516Simpstatic uint32_t 412163516Simpmmc_get_bits(uint32_t *bits, int start, int size) 413163516Simp{ 414163516Simp const int i = 3 - (start / 32); 415163516Simp const int shift = start & 31; 416163516Simp uint32_t retval = bits[i] >> shift; 417163516Simp if (size + shift > 32) 418163516Simp retval |= bits[i - 1] << (32 - shift); 419163516Simp return retval & ((1 << size) - 1); 420163516Simp} 421163516Simp 422163516Simpstatic void 423163516Simpmmc_decode_cid(int is_sd, uint32_t *raw_cid, struct mmc_cid *cid) 424163516Simp{ 425163516Simp int i; 426163516Simp 427163516Simp memset(cid, 0, sizeof(*cid)); 428163516Simp if (is_sd) { 429163516Simp /* There's no version info, so we take it on faith */ 430163516Simp cid->mid = mmc_get_bits(raw_cid, 120, 8); 431163516Simp cid->oid = mmc_get_bits(raw_cid, 104, 16); 432163516Simp for (i = 0; i < 5; i++) 433163516Simp cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8); 434163516Simp cid->prv = mmc_get_bits(raw_cid, 56, 8); 435163516Simp cid->psn = mmc_get_bits(raw_cid, 24, 32); 436163516Simp cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001; 437163516Simp cid->mdt_month = mmc_get_bits(raw_cid, 8, 4); 438163516Simp } else { 439163516Simp // XXX write me 440163516Simp panic("write mmc cid decoder"); 441163516Simp } 442163516Simp} 443163516Simp 444163516Simpstatic const int exp[8] = { 445163516Simp 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 446163516Simp}; 447163516Simpstatic const int mant[16] = { 448163516Simp 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 449163516Simp}; 450163516Simpstatic const int cur_min[8] = { 451163516Simp 500, 1000, 5000, 10000, 25000, 35000, 60000, 100000 452163516Simp}; 453163516Simpstatic const int cur_max[8] = { 454163516Simp 1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000 455163516Simp}; 456163516Simp 457163516Simpstatic void 458163516Simpmmc_decode_csd(int is_sd, uint32_t *raw_csd, struct mmc_csd *csd) 459163516Simp{ 460163516Simp int v; 461163516Simp int m; 462163516Simp int e; 463163516Simp 464163516Simp memset(csd, 0, sizeof(*csd)); 465163516Simp if (is_sd) { 466163516Simp csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2); 467163516Simp if (v == 0) { 468163516Simp m = mmc_get_bits(raw_csd, 115, 4); 469163516Simp e = mmc_get_bits(raw_csd, 112, 3); 470163516Simp csd->tacc = exp[e] * mant[m] + 9 / 10; 471163516Simp csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100; 472163516Simp m = mmc_get_bits(raw_csd, 99, 4); 473163516Simp e = mmc_get_bits(raw_csd, 96, 3); 474163516Simp csd->tran_speed = exp[e] * 10000 * mant[m]; 475163516Simp csd->ccc = mmc_get_bits(raw_csd, 84, 12); 476163516Simp csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4); 477163516Simp csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1); 478163516Simp csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1); 479163516Simp csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1); 480163516Simp csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1); 481163516Simp csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)]; 482163516Simp csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)]; 483163516Simp csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)]; 484163516Simp csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)]; 485163516Simp m = mmc_get_bits(raw_csd, 62, 12); 486163516Simp e = mmc_get_bits(raw_csd, 47, 3); 487163516Simp csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; 488163516Simp csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1); 489163516Simp csd->sector_size = mmc_get_bits(raw_csd, 39, 7); 490163516Simp csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7); 491163516Simp csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1); 492163516Simp csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3); 493163516Simp csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4); 494163516Simp csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1); 495163516Simp } else if (v == 1) { 496163516Simp panic("Write SDHC CSD parser"); 497163516Simp } else 498163516Simp panic("unknown SD CSD version"); 499163516Simp } else { 500163516Simp panic("Write a MMC CSD parser"); 501163516Simp } 502163516Simp} 503163516Simp 504163516Simpstatic int 505163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid) 506163516Simp{ 507163516Simp struct mmc_command cmd; 508163516Simp int err; 509163516Simp 510163516Simp cmd.opcode = MMC_ALL_SEND_CID; 511163516Simp cmd.arg = 0; 512163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 513163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 514163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 515163516Simp return (err); 516163516Simp} 517163516Simp 518163516Simpstatic int 519163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid) 520163516Simp{ 521163516Simp struct mmc_command cmd; 522163516Simp int err; 523163516Simp 524163516Simp cmd.opcode = MMC_SEND_CSD; 525163516Simp cmd.arg = rca << 16; 526163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 527163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 528163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 529163516Simp return (err); 530163516Simp} 531163516Simp 532163516Simpstatic int 533163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp) 534163516Simp{ 535163516Simp struct mmc_command cmd; 536163516Simp int err; 537163516Simp 538163516Simp cmd.opcode = SD_SEND_RELATIVE_ADDR; 539163516Simp cmd.arg = 0; 540163516Simp cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; 541163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 542163516Simp *resp = cmd.resp[0]; 543163516Simp return (err); 544163516Simp} 545163516Simp 546163516Simpstatic void 547163516Simpmmc_discover_cards(struct mmc_softc *sc) 548163516Simp{ 549163516Simp struct mmc_ivars *ivar; 550163516Simp int err; 551163516Simp uint32_t resp; 552163516Simp device_t child; 553163516Simp 554163516Simp while (1) { 555163516Simp ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, M_WAITOK); 556163516Simp err = mmc_all_send_cid(sc, ivar->raw_cid); 557163516Simp if (err == MMC_ERR_TIMEOUT) 558163516Simp break; 559163516Simp if (err != MMC_ERR_NONE) { 560163516Simp printf("Error reading CID %d\n", err); 561163516Simp break; 562163516Simp } 563163516Simp if (mmcbr_get_mode(sc->dev) == mode_sd) { 564163516Simp ivar->mode = mode_sd; 565163516Simp mmc_decode_cid(1, ivar->raw_cid, &ivar->cid); 566163516Simp mmc_send_relative_addr(sc, &resp); 567163516Simp ivar->rca = resp >> 16; 568163516Simp // RO check 569163516Simp mmc_send_csd(sc, ivar->rca, ivar->raw_csd); 570163516Simp mmc_decode_csd(1, ivar->raw_csd, &ivar->csd); 571163516Simp printf("SD CARD: %lld bytes\n", ivar->csd.capacity); 572163516Simp child = device_add_child(sc->dev, NULL, -1); 573163516Simp device_set_ivars(child, ivar); 574163516Simp break; 575163516Simp } 576163516Simp panic("Write MMC card code here"); 577163516Simp } 578163516Simp} 579163516Simp 580163516Simpstatic void 581163516Simpmmc_go_discovery(struct mmc_softc *sc) 582163516Simp{ 583163516Simp uint32_t ocr; 584163516Simp device_t dev; 585163516Simp 586163516Simp dev = sc->dev; 587163516Simp if (mmcbr_get_power_mode(dev) != power_on) { 588163516Simp // First, try SD modes 589163516Simp mmcbr_set_mode(dev, mode_sd); 590163516Simp mmc_power_up(sc); 591163516Simp mmcbr_set_bus_mode(dev, pushpull); 592163516Simp mmc_idle_cards(sc); 593163516Simp if (mmc_send_app_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) { 594163516Simp // Failed, try MMC 595163516Simp mmcbr_set_mode(dev, mode_mmc); 596163516Simp if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) 597163516Simp return; // Failed both, punt! XXX power down? 598163516Simp } 599163516Simp mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr)); 600163516Simp if (mmcbr_get_ocr(dev) != 0) 601163516Simp mmc_idle_cards(sc); 602163516Simp } else { 603163516Simp mmcbr_set_bus_mode(dev, opendrain); 604163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(dev)); 605163516Simp mmcbr_update_ios(dev); 606163516Simp // XXX recompute vdd based on new cards? 607163516Simp } 608163516Simp /* 609163516Simp * Make sure that we have a mutually agreeable voltage to at least 610163516Simp * one card on the bus. 611163516Simp */ 612163516Simp if (mmcbr_get_ocr(dev) == 0) 613163516Simp return; 614163516Simp /* 615163516Simp * Reselect the cards after we've idled them above. 616163516Simp */ 617163516Simp if (mmcbr_get_mode(dev) == mode_sd) 618163516Simp mmc_send_app_op_cond(sc, mmcbr_get_ocr(dev), NULL); 619163516Simp else 620163516Simp mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL); 621163516Simp mmc_discover_cards(sc); 622163516Simp 623163516Simp mmcbr_set_bus_mode(dev, pushpull); 624163516Simp mmcbr_update_ios(dev); 625163516Simp bus_generic_attach(dev); 626163516Simp// mmc_update_children_sysctl(dev); 627163516Simp} 628163516Simp 629163516Simpstatic int 630163516Simpmmc_calculate_clock(struct mmc_softc *sc) 631163516Simp{ 632163516Simp int max_dtr = 0; 633163516Simp int nkid, i, f_min, f_max; 634163516Simp device_t *kids; 635163516Simp 636163516Simp f_min = mmcbr_get_f_min(sc->dev); 637163516Simp f_max = mmcbr_get_f_max(sc->dev); 638163516Simp max_dtr = f_max; 639163516Simp if (device_get_children(sc->dev, &kids, &nkid) != 0) 640163516Simp panic("can't get children"); 641163516Simp for (i = 0; i < nkid; i++) 642163516Simp if (mmc_get_tran_speed(kids[i]) < max_dtr) 643163516Simp max_dtr = mmc_get_tran_speed(kids[i]); 644163516Simp free(kids, M_TEMP); 645163516Simp device_printf(sc->dev, "setting transfer rate to %d.%03dMHz\n", 646163516Simp max_dtr / 1000000, (max_dtr / 1000) % 1000); 647163516Simp return max_dtr; 648163516Simp} 649163516Simp 650163516Simpstatic void 651163516Simpmmc_scan(struct mmc_softc *sc) 652163516Simp{ 653163516Simp device_t dev; 654163516Simp 655163516Simp dev = sc->dev; 656163516Simp mmc_acquire_bus(dev, dev); 657163516Simp 658163516Simp if (mmcbr_get_power_mode(dev) == power_on) 659163516Simp mmc_rescan_cards(sc); 660163516Simp mmc_go_discovery(sc); 661163516Simp mmcbr_set_clock(dev, mmc_calculate_clock(sc)); 662163516Simp mmcbr_update_ios(dev); 663163516Simp 664163516Simp mmc_release_bus(dev, dev); 665163516Simp // XXX probe/attach/detach children? 666163516Simp} 667163516Simp 668163516Simpstatic int 669163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result) 670163516Simp{ 671163516Simp struct mmc_ivars *ivar = device_get_ivars(child); 672163516Simp 673163516Simp switch (which) { 674163516Simp default: 675163516Simp return (EINVAL); 676163516Simp case MMC_IVAR_DSR_IMP: 677163516Simp *(int *)result = ivar->csd.dsr_imp; 678163516Simp break; 679163516Simp case MMC_IVAR_MEDIA_SIZE: 680163516Simp *(int *)result = ivar->csd.capacity; 681163516Simp break; 682163516Simp case MMC_IVAR_MODE: 683163516Simp *(int *)result = ivar->mode; 684163516Simp break; 685163516Simp case MMC_IVAR_RCA: 686163516Simp *(int *)result = ivar->rca; 687163516Simp break; 688163516Simp case MMC_IVAR_SECTOR_SIZE: 689163516Simp *(int *)result = 512; 690163516Simp break; 691163516Simp case MMC_IVAR_TRAN_SPEED: 692163516Simp *(int *)result = ivar->csd.tran_speed; 693163516Simp break; 694163516Simp } 695163516Simp return (0); 696163516Simp} 697163516Simp 698163516Simpstatic int 699163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value) 700163516Simp{ 701163516Simp // None are writable ATM 702163516Simp switch (which) { 703163516Simp default: 704163516Simp return (EINVAL); 705163516Simp } 706163516Simp return (0); 707163516Simp} 708163516Simp 709163516Simp 710163516Simpstatic void 711163516Simpmmc_delayed_attach(void *xsc) 712163516Simp{ 713163516Simp struct mmc_softc *sc = xsc; 714163516Simp 715163516Simp mmc_scan(sc); 716163516Simp config_intrhook_disestablish(&sc->config_intrhook); 717163516Simp} 718163516Simp 719163516Simpstatic device_method_t mmc_methods[] = { 720163516Simp /* device_if */ 721163516Simp DEVMETHOD(device_probe, mmc_probe), 722163516Simp DEVMETHOD(device_attach, mmc_attach), 723163516Simp DEVMETHOD(device_detach, mmc_detach), 724163516Simp 725163516Simp /* Bus interface */ 726163516Simp DEVMETHOD(bus_read_ivar, mmc_read_ivar), 727163516Simp DEVMETHOD(bus_write_ivar, mmc_write_ivar), 728163516Simp 729163516Simp /* MMC Bus interface */ 730163516Simp DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request), 731163516Simp DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus), 732163516Simp DEVMETHOD(mmcbus_release_bus, mmc_release_bus), 733163516Simp 734163516Simp {0, 0}, 735163516Simp}; 736163516Simp 737163516Simpstatic driver_t mmc_driver = { 738163516Simp "mmc", 739163516Simp mmc_methods, 740163516Simp sizeof(struct mmc_softc), 741163516Simp}; 742163516Simpstatic devclass_t mmc_devclass; 743163516Simp 744163516Simp 745163516SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0); 746