mmc.c revision 188044
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 188044 2009-02-03 04:28:45Z 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> 64183704Smav#include <sys/endian.h> 65187875Smav#include <sys/sysctl.h> 66163516Simp 67163516Simp#include <dev/mmc/mmcreg.h> 68163516Simp#include <dev/mmc/mmcbrvar.h> 69163516Simp#include <dev/mmc/mmcvar.h> 70163516Simp#include "mmcbr_if.h" 71163516Simp#include "mmcbus_if.h" 72163516Simp 73163516Simpstruct mmc_softc { 74163516Simp device_t dev; 75163516Simp struct mtx sc_mtx; 76163516Simp struct intr_config_hook config_intrhook; 77163516Simp device_t owner; 78163516Simp uint32_t last_rca; 79163516Simp}; 80163516Simp 81163516Simp/* 82163516Simp * Per-card data 83163516Simp */ 84163516Simpstruct mmc_ivars { 85163516Simp uint32_t raw_cid[4]; /* Raw bits of the CID */ 86163516Simp uint32_t raw_csd[4]; /* Raw bits of the CSD */ 87183704Smav uint32_t raw_scr[2]; /* Raw bits of the SCR */ 88183704Smav uint8_t raw_ext_csd[512]; /* Raw bits of the EXT_CSD */ 89184033Smav uint32_t raw_sd_status[16]; /* Raw bits of the SD_STATUS */ 90163516Simp uint16_t rca; 91163516Simp enum mmc_card_mode mode; 92163516Simp struct mmc_cid cid; /* cid decoded */ 93163516Simp struct mmc_csd csd; /* csd decoded */ 94183704Smav struct mmc_scr scr; /* scr decoded */ 95184033Smav struct mmc_sd_status sd_status; /* SD_STATUS decoded */ 96183447Simp u_char read_only; /* True when the device is read-only */ 97183704Smav u_char bus_width; /* Bus width to use */ 98183704Smav u_char timing; /* Bus timing support */ 99183731Smav u_char high_cap; /* High Capacity card (block addressed) */ 100183731Smav uint32_t sec_count; /* Card capacity in 512byte blocks */ 101183704Smav uint32_t tran_speed; /* Max speed in normal mode */ 102183704Smav uint32_t hs_tran_speed; /* Max speed in high speed mode */ 103184033Smav uint32_t erase_sector; /* Card native erase sector size */ 104163516Simp}; 105163516Simp 106163516Simp#define CMD_RETRIES 3 107163516Simp 108188044SimpSYSCTL_NODE(_hw, OID_AUTO, mmc, CTLFLAG_RD, NULL, "mmc driver"); 109187875Smav 110188044Simpstatic int mmc_debug; 111187875SmavSYSCTL_INT(_hw_mmc, OID_AUTO, debug, CTLFLAG_RW, &mmc_debug, 0, "Debug level"); 112187875Smav 113163516Simp/* bus entry points */ 114163516Simpstatic int mmc_probe(device_t dev); 115163516Simpstatic int mmc_attach(device_t dev); 116163516Simpstatic int mmc_detach(device_t dev); 117185721Smavstatic int mmc_suspend(device_t dev); 118185721Smavstatic int mmc_resume(device_t dev); 119163516Simp 120163516Simp#define MMC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 121163516Simp#define MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 122183444Simp#define MMC_LOCK_INIT(_sc) \ 123183444Simp mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ 124163516Simp "mmc", MTX_DEF) 125163516Simp#define MMC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 126163516Simp#define MMC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 127163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 128163516Simp 129183763Smavstatic int mmc_calculate_clock(struct mmc_softc *sc); 130163516Simpstatic void mmc_delayed_attach(void *); 131183449Simpstatic void mmc_power_down(struct mmc_softc *sc); 132163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, 133163516Simp int retries); 134163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 135163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries); 136183704Smavstatic int mmc_select_card(struct mmc_softc *sc, uint16_t rca); 137183763Smavstatic int mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width); 138183704Smavstatic int mmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr); 139183704Smavstatic void mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr); 140183704Smavstatic int mmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd); 141185721Smavstatic void mmc_scan(struct mmc_softc *sc); 142185721Smavstatic int mmc_delete_cards(struct mmc_softc *sc); 143163516Simp 144163516Simpstatic void 145163516Simpmmc_ms_delay(int ms) 146163516Simp{ 147163516Simp DELAY(1000 * ms); /* XXX BAD */ 148163516Simp} 149163516Simp 150163516Simpstatic int 151163516Simpmmc_probe(device_t dev) 152163516Simp{ 153163516Simp 154183445Simp device_set_desc(dev, "MMC/SD bus"); 155163516Simp return (0); 156163516Simp} 157163516Simp 158163516Simpstatic int 159163516Simpmmc_attach(device_t dev) 160163516Simp{ 161163516Simp struct mmc_softc *sc; 162163516Simp 163163516Simp sc = device_get_softc(dev); 164163516Simp sc->dev = dev; 165163516Simp MMC_LOCK_INIT(sc); 166163516Simp 167163516Simp /* We'll probe and attach our children later, but before / mount */ 168163516Simp sc->config_intrhook.ich_func = mmc_delayed_attach; 169163516Simp sc->config_intrhook.ich_arg = sc; 170163516Simp if (config_intrhook_establish(&sc->config_intrhook) != 0) 171163516Simp device_printf(dev, "config_intrhook_establish failed\n"); 172163516Simp return (0); 173163516Simp} 174163516Simp 175163516Simpstatic int 176163516Simpmmc_detach(device_t dev) 177163516Simp{ 178169567Simp struct mmc_softc *sc = device_get_softc(dev); 179185721Smav int err; 180169567Simp 181185721Smav if ((err = mmc_delete_cards(sc)) != 0) 182185721Smav return (err); 183183449Simp mmc_power_down(sc); 184169567Simp MMC_LOCK_DESTROY(sc); 185169567Simp 186183467Simp return (0); 187163516Simp} 188163516Simp 189163516Simpstatic int 190185721Smavmmc_suspend(device_t dev) 191185721Smav{ 192185721Smav struct mmc_softc *sc = device_get_softc(dev); 193185721Smav int err; 194185721Smav 195185721Smav err = bus_generic_suspend(dev); 196185721Smav if (err) 197185721Smav return (err); 198185721Smav mmc_power_down(sc); 199185721Smav return (0); 200185721Smav} 201185721Smav 202185721Smavstatic int 203185721Smavmmc_resume(device_t dev) 204185721Smav{ 205185721Smav struct mmc_softc *sc = device_get_softc(dev); 206185721Smav 207185721Smav mmc_scan(sc); 208185721Smav return (bus_generic_resume(dev)); 209185721Smav} 210185721Smav 211185721Smavstatic int 212163516Simpmmc_acquire_bus(device_t busdev, device_t dev) 213163516Simp{ 214163516Simp struct mmc_softc *sc; 215183704Smav struct mmc_ivars *ivar; 216163516Simp int err; 217163516Simp int rca; 218163516Simp 219183452Simp err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), busdev); 220163516Simp if (err) 221163516Simp return (err); 222163516Simp sc = device_get_softc(busdev); 223163516Simp MMC_LOCK(sc); 224163516Simp if (sc->owner) 225163516Simp panic("mmc: host bridge didn't seralize us."); 226163516Simp sc->owner = dev; 227163516Simp MMC_UNLOCK(sc); 228163516Simp 229163516Simp if (busdev != dev) { 230183453Simp /* 231183453Simp * Keep track of the last rca that we've selected. If 232183453Simp * we're asked to do it again, don't. We never 233183453Simp * unselect unless the bus code itself wants the mmc 234183453Simp * bus, and constantly reselecting causes problems. 235183453Simp */ 236163516Simp rca = mmc_get_rca(dev); 237163516Simp if (sc->last_rca != rca) { 238183704Smav mmc_select_card(sc, rca); 239163516Simp sc->last_rca = rca; 240183704Smav /* Prepare bus width for the new card. */ 241183704Smav ivar = device_get_ivars(dev); 242187875Smav if (bootverbose || mmc_debug) { 243183763Smav device_printf(busdev, 244183763Smav "setting bus width to %d bits\n", 245183775Simp (ivar->bus_width == bus_width_4) ? 4 : 246183775Simp (ivar->bus_width == bus_width_8) ? 8 : 1); 247183763Smav } 248183763Smav mmc_set_card_bus_width(sc, rca, ivar->bus_width); 249183704Smav mmcbr_set_bus_width(busdev, ivar->bus_width); 250183704Smav mmcbr_update_ios(busdev); 251163516Simp } 252163516Simp } else { 253183453Simp /* 254183453Simp * If there's a card selected, stand down. 255183453Simp */ 256163516Simp if (sc->last_rca != 0) { 257183704Smav mmc_select_card(sc, 0); 258163516Simp sc->last_rca = 0; 259163516Simp } 260163516Simp } 261163516Simp 262163516Simp return (0); 263163516Simp} 264163516Simp 265163516Simpstatic int 266163516Simpmmc_release_bus(device_t busdev, device_t dev) 267163516Simp{ 268163516Simp struct mmc_softc *sc; 269163516Simp int err; 270163516Simp 271163516Simp sc = device_get_softc(busdev); 272163516Simp 273163516Simp MMC_LOCK(sc); 274163516Simp if (!sc->owner) 275163516Simp panic("mmc: releasing unowned bus."); 276163516Simp if (sc->owner != dev) 277163516Simp panic("mmc: you don't own the bus. game over."); 278163516Simp MMC_UNLOCK(sc); 279183452Simp err = MMCBR_RELEASE_HOST(device_get_parent(busdev), busdev); 280163516Simp if (err) 281163516Simp return (err); 282163516Simp MMC_LOCK(sc); 283163516Simp sc->owner = NULL; 284163516Simp MMC_UNLOCK(sc); 285163516Simp return (0); 286163516Simp} 287163516Simp 288163516Simpstatic uint32_t 289163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr) 290163516Simp{ 291183446Simp 292183467Simp return (ocr & MMC_OCR_VOLTAGE); 293163516Simp} 294163516Simp 295163516Simpstatic int 296163516Simpmmc_highest_voltage(uint32_t ocr) 297163516Simp{ 298163516Simp int i; 299163516Simp 300163516Simp for (i = 30; i >= 0; i--) 301163516Simp if (ocr & (1 << i)) 302183467Simp return (i); 303163516Simp return (-1); 304163516Simp} 305163516Simp 306163516Simpstatic void 307163516Simpmmc_wakeup(struct mmc_request *req) 308163516Simp{ 309163516Simp struct mmc_softc *sc; 310163516Simp 311163516Simp sc = (struct mmc_softc *)req->done_data; 312163516Simp MMC_LOCK(sc); 313163516Simp req->flags |= MMC_REQ_DONE; 314185721Smav MMC_UNLOCK(sc); 315163516Simp wakeup(req); 316163516Simp} 317163516Simp 318163516Simpstatic int 319163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req) 320163516Simp{ 321163516Simp 322163516Simp req->done = mmc_wakeup; 323163516Simp req->done_data = sc; 324187877Smav if (mmc_debug > 1) { 325187875Smav device_printf(sc->dev, "REQUEST: CMD%d arg %#x flags %#x", 326187875Smav req->cmd->opcode, req->cmd->arg, req->cmd->flags); 327187875Smav if (req->cmd->data) { 328187875Smav printf(" data %d\n", (int)req->cmd->data->len); 329187875Smav } else 330187875Smav printf("\n"); 331187875Smav } 332163516Simp MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req); 333163516Simp MMC_LOCK(sc); 334185721Smav while ((req->flags & MMC_REQ_DONE) == 0) 335185721Smav msleep(req, &sc->sc_mtx, 0, "mmcreq", 0); 336163516Simp MMC_UNLOCK(sc); 337187877Smav if (mmc_debug > 2 || (mmc_debug > 1 && req->cmd->error)) 338187875Smav device_printf(sc->dev, "RESULT: %d\n", req->cmd->error); 339185721Smav return (0); 340163516Simp} 341163516Simp 342163516Simpstatic int 343163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req) 344163516Simp{ 345163516Simp struct mmc_softc *sc = device_get_softc(brdev); 346163516Simp 347183467Simp return (mmc_wait_for_req(sc, req)); 348163516Simp} 349163516Simp 350163516Simpstatic int 351163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries) 352163516Simp{ 353163516Simp struct mmc_request mreq; 354163516Simp 355163516Simp memset(&mreq, 0, sizeof(mreq)); 356163516Simp memset(cmd->resp, 0, sizeof(cmd->resp)); 357163516Simp cmd->retries = retries; 358163516Simp mreq.cmd = cmd; 359163516Simp mmc_wait_for_req(sc, &mreq); 360163516Simp return (cmd->error); 361163516Simp} 362163516Simp 363163516Simpstatic int 364163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca, 365163516Simp struct mmc_command *cmd, int retries) 366163516Simp{ 367163516Simp struct mmc_command appcmd; 368163516Simp int err = MMC_ERR_NONE, i; 369163516Simp 370163516Simp for (i = 0; i <= retries; i++) { 371163516Simp appcmd.opcode = MMC_APP_CMD; 372163516Simp appcmd.arg = rca << 16; 373163516Simp appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 374183470Simp appcmd.data = NULL; 375163516Simp mmc_wait_for_cmd(sc, &appcmd, 0); 376163516Simp err = appcmd.error; 377163516Simp if (err != MMC_ERR_NONE) 378163516Simp continue; 379163516Simp if (!(appcmd.resp[0] & R1_APP_CMD)) 380163516Simp return MMC_ERR_FAILED; 381163516Simp mmc_wait_for_cmd(sc, cmd, 0); 382163516Simp err = cmd->error; 383163516Simp if (err == MMC_ERR_NONE) 384163516Simp break; 385163516Simp } 386163516Simp return (err); 387163516Simp} 388163516Simp 389163516Simpstatic int 390163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, 391163516Simp uint32_t arg, uint32_t flags, uint32_t *resp, int retries) 392163516Simp{ 393163516Simp struct mmc_command cmd; 394163516Simp int err; 395163516Simp 396163516Simp memset(&cmd, 0, sizeof(cmd)); 397163516Simp cmd.opcode = opcode; 398163516Simp cmd.arg = arg; 399163516Simp cmd.flags = flags; 400183470Simp cmd.data = NULL; 401163516Simp err = mmc_wait_for_cmd(sc, &cmd, retries); 402163516Simp if (err) 403163516Simp return (err); 404163516Simp if (cmd.error) 405163516Simp return (cmd.error); 406163516Simp if (resp) { 407163516Simp if (flags & MMC_RSP_136) 408163516Simp memcpy(resp, cmd.resp, 4 * sizeof(uint32_t)); 409163516Simp else 410163516Simp *resp = cmd.resp[0]; 411163516Simp } 412163516Simp return (0); 413163516Simp} 414163516Simp 415163516Simpstatic void 416163516Simpmmc_idle_cards(struct mmc_softc *sc) 417163516Simp{ 418163516Simp device_t dev; 419163516Simp struct mmc_command cmd; 420163516Simp 421163516Simp dev = sc->dev; 422163516Simp mmcbr_set_chip_select(dev, cs_high); 423163516Simp mmcbr_update_ios(dev); 424163516Simp mmc_ms_delay(1); 425163516Simp 426163516Simp memset(&cmd, 0, sizeof(cmd)); 427163516Simp cmd.opcode = MMC_GO_IDLE_STATE; 428163516Simp cmd.arg = 0; 429163516Simp cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; 430183470Simp cmd.data = NULL; 431163516Simp mmc_wait_for_cmd(sc, &cmd, 0); 432163516Simp mmc_ms_delay(1); 433163516Simp 434163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 435163516Simp mmcbr_update_ios(dev); 436163516Simp mmc_ms_delay(1); 437163516Simp} 438163516Simp 439163516Simpstatic int 440163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 441163516Simp{ 442163516Simp struct mmc_command cmd; 443163516Simp int err = MMC_ERR_NONE, i; 444163516Simp 445163516Simp memset(&cmd, 0, sizeof(cmd)); 446163516Simp cmd.opcode = ACMD_SD_SEND_OP_COND; 447163516Simp cmd.arg = ocr; 448163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 449183470Simp cmd.data = NULL; 450163516Simp 451170337Simp for (i = 0; i < 100; i++) { 452163516Simp err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES); 453163516Simp if (err != MMC_ERR_NONE) 454163516Simp break; 455183709Smav if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || 456183709Smav (ocr & MMC_OCR_VOLTAGE) == 0) 457163516Simp break; 458163516Simp err = MMC_ERR_TIMEOUT; 459163516Simp mmc_ms_delay(10); 460163516Simp } 461163516Simp if (rocr && err == MMC_ERR_NONE) 462163516Simp *rocr = cmd.resp[0]; 463183467Simp return (err); 464163516Simp} 465163516Simp 466163516Simpstatic int 467163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr) 468163516Simp{ 469163516Simp struct mmc_command cmd; 470163516Simp int err = MMC_ERR_NONE, i; 471163516Simp 472163516Simp memset(&cmd, 0, sizeof(cmd)); 473163516Simp cmd.opcode = MMC_SEND_OP_COND; 474163516Simp cmd.arg = ocr; 475163516Simp cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 476183470Simp cmd.data = NULL; 477163516Simp 478163516Simp for (i = 0; i < 100; i++) { 479163516Simp err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 480163516Simp if (err != MMC_ERR_NONE) 481163516Simp break; 482183709Smav if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || 483183709Smav (ocr & MMC_OCR_VOLTAGE) == 0) 484163516Simp break; 485163516Simp err = MMC_ERR_TIMEOUT; 486163516Simp mmc_ms_delay(10); 487163516Simp } 488163516Simp if (rocr && err == MMC_ERR_NONE) 489163516Simp *rocr = cmd.resp[0]; 490183467Simp return (err); 491163516Simp} 492163516Simp 493183704Smavstatic int 494183704Smavmmc_send_if_cond(struct mmc_softc *sc, uint8_t vhs) 495183704Smav{ 496183704Smav struct mmc_command cmd; 497183704Smav int err; 498183704Smav 499183704Smav memset(&cmd, 0, sizeof(cmd)); 500183704Smav cmd.opcode = SD_SEND_IF_COND; 501183704Smav cmd.arg = (vhs << 8) + 0xAA; 502183704Smav cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; 503183704Smav cmd.data = NULL; 504183704Smav 505183704Smav err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 506183704Smav return (err); 507183704Smav} 508183704Smav 509163516Simpstatic void 510163516Simpmmc_power_up(struct mmc_softc *sc) 511163516Simp{ 512163516Simp device_t dev; 513163516Simp 514163516Simp dev = sc->dev; 515163516Simp mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev))); 516163516Simp mmcbr_set_bus_mode(dev, opendrain); 517163516Simp mmcbr_set_chip_select(dev, cs_dontcare); 518163516Simp mmcbr_set_bus_width(dev, bus_width_1); 519163516Simp mmcbr_set_power_mode(dev, power_up); 520163516Simp mmcbr_set_clock(dev, 0); 521163516Simp mmcbr_update_ios(dev); 522163516Simp mmc_ms_delay(1); 523163516Simp 524163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev)); 525183704Smav mmcbr_set_timing(dev, bus_timing_normal); 526163516Simp mmcbr_set_power_mode(dev, power_on); 527163516Simp mmcbr_update_ios(dev); 528163516Simp mmc_ms_delay(2); 529163516Simp} 530163516Simp 531183449Simpstatic void 532183449Simpmmc_power_down(struct mmc_softc *sc) 533183449Simp{ 534183449Simp device_t dev = sc->dev; 535183449Simp 536183449Simp mmcbr_set_bus_mode(dev, opendrain); 537183449Simp mmcbr_set_chip_select(dev, cs_dontcare); 538183449Simp mmcbr_set_bus_width(dev, bus_width_1); 539183449Simp mmcbr_set_power_mode(dev, power_off); 540183449Simp mmcbr_set_clock(dev, 0); 541183704Smav mmcbr_set_timing(dev, bus_timing_normal); 542183449Simp mmcbr_update_ios(dev); 543183449Simp} 544183449Simp 545183704Smavstatic int 546183704Smavmmc_select_card(struct mmc_softc *sc, uint16_t rca) 547183704Smav{ 548183775Simp int flags; 549183775Simp 550183775Simp flags = (rca ? MMC_RSP_R1B : MMC_RSP_NONE) | MMC_CMD_AC; 551183775Simp return (mmc_wait_for_command(sc, MMC_SELECT_CARD, (uint32_t)rca << 16, 552183775Simp flags, NULL, CMD_RETRIES)); 553183704Smav} 554183704Smav 555183704Smavstatic int 556183704Smavmmc_switch(struct mmc_softc *sc, uint8_t set, uint8_t index, uint8_t value) 557183704Smav{ 558183704Smav struct mmc_command cmd; 559183704Smav int err; 560183704Smav 561183704Smav cmd.opcode = MMC_SWITCH_FUNC; 562183704Smav cmd.arg = (MMC_SWITCH_FUNC_WR << 24) | 563183704Smav (index << 16) | 564183704Smav (value << 8) | 565183704Smav set; 566183704Smav cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 567183704Smav cmd.data = NULL; 568183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 569183704Smav return (err); 570183704Smav} 571183704Smav 572183704Smavstatic int 573188044Simpmmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, 574188044Simp uint8_t *res) 575183704Smav{ 576183704Smav int err; 577183704Smav struct mmc_command cmd; 578183704Smav struct mmc_data data; 579183704Smav 580183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 581183704Smav memset(&data, 0, sizeof(struct mmc_data)); 582188044Simp memset(res, 0, 64); 583183704Smav 584183704Smav cmd.opcode = SD_SWITCH_FUNC; 585183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 586188044Simp cmd.arg = mode << 31; /* 0 - check, 1 - set */ 587183704Smav cmd.arg |= 0x00FFFFFF; 588183705Smav cmd.arg &= ~(0xF << (grp * 4)); 589183705Smav cmd.arg |= value << (grp * 4); 590183704Smav cmd.data = &data; 591183704Smav 592183704Smav data.data = res; 593183704Smav data.len = 64; 594183704Smav data.flags = MMC_DATA_READ; 595183704Smav 596183704Smav err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 597183704Smav return (err); 598183704Smav} 599183704Smav 600183704Smavstatic int 601183763Smavmmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width) 602183704Smav{ 603187546Simp struct mmc_command cmd; 604183704Smav int err; 605187546Simp uint8_t value; 606183704Smav 607183704Smav if (mmcbr_get_mode(sc->dev) == mode_sd) { 608183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 609183704Smav cmd.opcode = ACMD_SET_BUS_WIDTH; 610183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 611183704Smav switch (width) { 612183704Smav case bus_width_1: 613183704Smav cmd.arg = SD_BUS_WIDTH_1; 614183704Smav break; 615183704Smav case bus_width_4: 616183704Smav cmd.arg = SD_BUS_WIDTH_4; 617183704Smav break; 618183704Smav default: 619183704Smav return (MMC_ERR_INVALID); 620183704Smav } 621183704Smav err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES); 622183704Smav } else { 623183704Smav switch (width) { 624183704Smav case bus_width_1: 625183704Smav value = EXT_CSD_BUS_WIDTH_1; 626183704Smav break; 627183704Smav case bus_width_4: 628183704Smav value = EXT_CSD_BUS_WIDTH_4; 629183704Smav break; 630183704Smav case bus_width_8: 631183704Smav value = EXT_CSD_BUS_WIDTH_8; 632183704Smav break; 633183704Smav default: 634183704Smav return (MMC_ERR_INVALID); 635183704Smav } 636187546Simp err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, 637187546Simp value); 638183704Smav } 639183704Smav return (err); 640183704Smav} 641183704Smav 642183704Smavstatic int 643183704Smavmmc_set_timing(struct mmc_softc *sc, int timing) 644183704Smav{ 645183704Smav int err; 646183704Smav uint8_t value; 647187543Simp u_char switch_res[64]; 648183704Smav 649183704Smav switch (timing) { 650183704Smav case bus_timing_normal: 651183704Smav value = 0; 652183704Smav break; 653183704Smav case bus_timing_hs: 654183704Smav value = 1; 655183704Smav break; 656183704Smav default: 657183704Smav return (MMC_ERR_INVALID); 658183704Smav } 659187543Simp if (mmcbr_get_mode(sc->dev) == mode_sd) 660188044Simp err = mmc_sd_switch(sc, SD_SWITCH_MODE_SET, SD_SWITCH_GROUP1, 661188044Simp value, switch_res); 662187543Simp else 663183704Smav err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, 664183704Smav EXT_CSD_HS_TIMING, value); 665183704Smav return (err); 666183704Smav} 667183704Smav 668183704Smavstatic int 669183704Smavmmc_test_bus_width(struct mmc_softc *sc) 670183704Smav{ 671183704Smav struct mmc_command cmd; 672183704Smav struct mmc_data data; 673183704Smav int err; 674183704Smav uint8_t buf[8]; 675183704Smav uint8_t p8[8] = { 0x55, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 676183704Smav uint8_t p8ok[8] = { 0xAA, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 677183704Smav uint8_t p4[4] = { 0x5A, 0x00, 0x00, 0x00, }; 678183704Smav uint8_t p4ok[4] = { 0xA5, 0x00, 0x00, 0x00, }; 679183704Smav 680183704Smav if (mmcbr_get_caps(sc->dev) & MMC_CAP_8_BIT_DATA) { 681183704Smav mmcbr_set_bus_width(sc->dev, bus_width_8); 682183704Smav mmcbr_update_ios(sc->dev); 683183704Smav 684183704Smav cmd.opcode = MMC_BUSTEST_W; 685183704Smav cmd.arg = 0; 686183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 687183704Smav cmd.data = &data; 688183704Smav 689183704Smav data.data = p8; 690183704Smav data.len = 8; 691183704Smav data.flags = MMC_DATA_WRITE; 692183704Smav mmc_wait_for_cmd(sc, &cmd, 0); 693183704Smav 694183704Smav cmd.opcode = MMC_BUSTEST_R; 695183704Smav cmd.arg = 0; 696183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 697183704Smav cmd.data = &data; 698183704Smav 699183704Smav data.data = buf; 700183704Smav data.len = 8; 701183704Smav data.flags = MMC_DATA_READ; 702183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 703183704Smav 704183704Smav mmcbr_set_bus_width(sc->dev, bus_width_1); 705183704Smav mmcbr_update_ios(sc->dev); 706183704Smav 707183704Smav if (err == MMC_ERR_NONE && memcmp(buf, p8ok, 8) == 0) 708183704Smav return (bus_width_8); 709183704Smav } 710183704Smav 711183704Smav if (mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) { 712183704Smav mmcbr_set_bus_width(sc->dev, bus_width_4); 713183704Smav mmcbr_update_ios(sc->dev); 714183704Smav 715183704Smav cmd.opcode = MMC_BUSTEST_W; 716183704Smav cmd.arg = 0; 717183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 718183704Smav cmd.data = &data; 719183704Smav 720183704Smav data.data = p4; 721183704Smav data.len = 4; 722183704Smav data.flags = MMC_DATA_WRITE; 723183704Smav mmc_wait_for_cmd(sc, &cmd, 0); 724183704Smav 725183704Smav cmd.opcode = MMC_BUSTEST_R; 726183704Smav cmd.arg = 0; 727183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 728183704Smav cmd.data = &data; 729183704Smav 730183704Smav data.data = buf; 731183704Smav data.len = 4; 732183704Smav data.flags = MMC_DATA_READ; 733183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 734183704Smav 735183704Smav mmcbr_set_bus_width(sc->dev, bus_width_1); 736183704Smav mmcbr_update_ios(sc->dev); 737183704Smav 738183704Smav if (err == MMC_ERR_NONE && memcmp(buf, p4ok, 4) == 0) 739183704Smav return (bus_width_4); 740183704Smav } 741183704Smav return (bus_width_1); 742183704Smav} 743183704Smav 744163516Simpstatic uint32_t 745184033Smavmmc_get_bits(uint32_t *bits, int bit_len, int start, int size) 746163516Simp{ 747183729Simp const int i = (bit_len / 32) - (start / 32) - 1; 748163516Simp const int shift = start & 31; 749163516Simp uint32_t retval = bits[i] >> shift; 750163516Simp if (size + shift > 32) 751163516Simp retval |= bits[i - 1] << (32 - shift); 752183467Simp return (retval & ((1 << size) - 1)); 753163516Simp} 754163516Simp 755163516Simpstatic void 756183729Simpmmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid) 757163516Simp{ 758163516Simp int i; 759163516Simp 760183729Simp /* There's no version info, so we take it on faith */ 761163516Simp memset(cid, 0, sizeof(*cid)); 762184033Smav cid->mid = mmc_get_bits(raw_cid, 128, 120, 8); 763184033Smav cid->oid = mmc_get_bits(raw_cid, 128, 104, 16); 764183729Simp for (i = 0; i < 5; i++) 765184033Smav cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8); 766187875Smav cid->pnm[5] = 0; 767184033Smav cid->prv = mmc_get_bits(raw_cid, 128, 56, 8); 768184033Smav cid->psn = mmc_get_bits(raw_cid, 128, 24, 32); 769187875Smav cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2000; 770184033Smav cid->mdt_month = mmc_get_bits(raw_cid, 128, 8, 4); 771163516Simp} 772163516Simp 773183729Simpstatic void 774183729Simpmmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid) 775183729Simp{ 776183729Simp int i; 777183729Simp 778183729Simp /* There's no version info, so we take it on faith */ 779183729Simp memset(cid, 0, sizeof(*cid)); 780184033Smav cid->mid = mmc_get_bits(raw_cid, 128, 120, 8); 781184033Smav cid->oid = mmc_get_bits(raw_cid, 128, 104, 8); 782183729Simp for (i = 0; i < 6; i++) 783184033Smav cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8); 784187875Smav cid->pnm[6] = 0; 785184033Smav cid->prv = mmc_get_bits(raw_cid, 128, 48, 8); 786184033Smav cid->psn = mmc_get_bits(raw_cid, 128, 16, 32); 787184033Smav cid->mdt_month = mmc_get_bits(raw_cid, 128, 12, 4); 788184033Smav cid->mdt_year = mmc_get_bits(raw_cid, 128, 8, 4) + 1997; 789183729Simp} 790183729Simp 791163516Simpstatic const int exp[8] = { 792163516Simp 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 793163516Simp}; 794163516Simpstatic const int mant[16] = { 795163516Simp 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 796163516Simp}; 797163516Simpstatic const int cur_min[8] = { 798163516Simp 500, 1000, 5000, 10000, 25000, 35000, 60000, 100000 799163516Simp}; 800163516Simpstatic const int cur_max[8] = { 801163516Simp 1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000 802163516Simp}; 803163516Simp 804163516Simpstatic void 805183729Simpmmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd) 806163516Simp{ 807163516Simp int v; 808163516Simp int m; 809163516Simp int e; 810163516Simp 811163516Simp memset(csd, 0, sizeof(*csd)); 812184033Smav csd->csd_structure = v = mmc_get_bits(raw_csd, 128, 126, 2); 813183729Simp if (v == 0) { 814184033Smav m = mmc_get_bits(raw_csd, 128, 115, 4); 815184033Smav e = mmc_get_bits(raw_csd, 128, 112, 3); 816183704Smav csd->tacc = exp[e] * mant[m] + 9 / 10; 817184033Smav csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100; 818184033Smav m = mmc_get_bits(raw_csd, 128, 99, 4); 819184033Smav e = mmc_get_bits(raw_csd, 128, 96, 3); 820183704Smav csd->tran_speed = exp[e] * 10000 * mant[m]; 821184033Smav csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12); 822184033Smav csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4); 823184033Smav csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1); 824184033Smav csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1); 825184033Smav csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1); 826184033Smav csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1); 827184033Smav csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 59, 3)]; 828184033Smav csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 56, 3)]; 829184033Smav csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 53, 3)]; 830184033Smav csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 50, 3)]; 831184033Smav m = mmc_get_bits(raw_csd, 128, 62, 12); 832184033Smav e = mmc_get_bits(raw_csd, 128, 47, 3); 833183704Smav csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; 834184033Smav csd->erase_blk_en = mmc_get_bits(raw_csd, 128, 46, 1); 835184033Smav csd->erase_sector = mmc_get_bits(raw_csd, 128, 39, 7) + 1; 836184033Smav csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 7); 837184033Smav csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1); 838184033Smav csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3); 839184033Smav csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4); 840184033Smav csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1); 841183729Simp } else if (v == 1) { 842184033Smav m = mmc_get_bits(raw_csd, 128, 115, 4); 843184033Smav e = mmc_get_bits(raw_csd, 128, 112, 3); 844183729Simp csd->tacc = exp[e] * mant[m] + 9 / 10; 845184033Smav csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100; 846184033Smav m = mmc_get_bits(raw_csd, 128, 99, 4); 847184033Smav e = mmc_get_bits(raw_csd, 128, 96, 3); 848183729Simp csd->tran_speed = exp[e] * 10000 * mant[m]; 849184033Smav csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12); 850184033Smav csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4); 851184033Smav csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1); 852184033Smav csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1); 853184033Smav csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1); 854184033Smav csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1); 855184033Smav csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 128, 48, 22) + 1) * 856183729Simp 512 * 1024; 857184033Smav csd->erase_blk_en = mmc_get_bits(raw_csd, 128, 46, 1); 858184033Smav csd->erase_sector = mmc_get_bits(raw_csd, 128, 39, 7) + 1; 859184033Smav csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 7); 860184033Smav csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1); 861184033Smav csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3); 862184033Smav csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4); 863184033Smav csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1); 864183729Simp } else 865183729Simp panic("unknown SD CSD version"); 866163516Simp} 867163516Simp 868183704Smavstatic void 869183729Simpmmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd) 870183729Simp{ 871183729Simp int m; 872183729Simp int e; 873183729Simp 874183729Simp memset(csd, 0, sizeof(*csd)); 875184033Smav csd->csd_structure = mmc_get_bits(raw_csd, 128, 126, 2); 876184033Smav csd->spec_vers = mmc_get_bits(raw_csd, 128, 122, 4); 877184033Smav m = mmc_get_bits(raw_csd, 128, 115, 4); 878184033Smav e = mmc_get_bits(raw_csd, 128, 112, 3); 879183729Simp csd->tacc = exp[e] * mant[m] + 9 / 10; 880184033Smav csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100; 881184033Smav m = mmc_get_bits(raw_csd, 128, 99, 4); 882184033Smav e = mmc_get_bits(raw_csd, 128, 96, 3); 883183729Simp csd->tran_speed = exp[e] * 10000 * mant[m]; 884184033Smav csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12); 885184033Smav csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4); 886184033Smav csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1); 887184033Smav csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1); 888184033Smav csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1); 889184033Smav csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1); 890184033Smav csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 59, 3)]; 891184033Smav csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 56, 3)]; 892184033Smav csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 53, 3)]; 893184033Smav csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 50, 3)]; 894184033Smav m = mmc_get_bits(raw_csd, 128, 62, 12); 895184033Smav e = mmc_get_bits(raw_csd, 128, 47, 3); 896183729Simp csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len; 897184033Smav csd->erase_blk_en = 0; 898184033Smav csd->erase_sector = (mmc_get_bits(raw_csd, 128, 42, 5) + 1) * 899184033Smav (mmc_get_bits(raw_csd, 128, 37, 5) + 1); 900184033Smav csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 5); 901184033Smav csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1); 902184033Smav csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3); 903184033Smav csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4); 904184033Smav csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1); 905183729Simp} 906183729Simp 907183729Simpstatic void 908183704Smavmmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr) 909183704Smav{ 910183704Smav unsigned int scr_struct; 911183704Smav 912183704Smav memset(scr, 0, sizeof(*scr)); 913183729Simp 914184033Smav scr_struct = mmc_get_bits(raw_scr, 64, 60, 4); 915183704Smav if (scr_struct != 0) { 916183704Smav printf("Unrecognised SCR structure version %d\n", 917183704Smav scr_struct); 918183704Smav return; 919183704Smav } 920184033Smav scr->sda_vsn = mmc_get_bits(raw_scr, 64, 56, 4); 921184033Smav scr->bus_widths = mmc_get_bits(raw_scr, 64, 48, 4); 922183704Smav} 923183704Smav 924184033Smavstatic void 925184033Smavmmc_app_decode_sd_status(uint32_t *raw_sd_status, 926184033Smav struct mmc_sd_status *sd_status) 927184033Smav{ 928184033Smav 929184033Smav memset(sd_status, 0, sizeof(*sd_status)); 930184033Smav 931184033Smav sd_status->bus_width = mmc_get_bits(raw_sd_status, 512, 510, 2); 932184033Smav sd_status->secured_mode = mmc_get_bits(raw_sd_status, 512, 509, 1); 933184033Smav sd_status->card_type = mmc_get_bits(raw_sd_status, 512, 480, 16); 934184033Smav sd_status->prot_area = mmc_get_bits(raw_sd_status, 512, 448, 12); 935184033Smav sd_status->speed_class = mmc_get_bits(raw_sd_status, 512, 440, 8); 936184033Smav sd_status->perf_move = mmc_get_bits(raw_sd_status, 512, 432, 8); 937184033Smav sd_status->au_size = mmc_get_bits(raw_sd_status, 512, 428, 4); 938184033Smav sd_status->erase_size = mmc_get_bits(raw_sd_status, 512, 408, 16); 939184033Smav sd_status->erase_timeout = mmc_get_bits(raw_sd_status, 512, 402, 6); 940184033Smav sd_status->erase_offset = mmc_get_bits(raw_sd_status, 512, 400, 2); 941184033Smav} 942184033Smav 943163516Simpstatic int 944163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid) 945163516Simp{ 946163516Simp struct mmc_command cmd; 947163516Simp int err; 948163516Simp 949163516Simp cmd.opcode = MMC_ALL_SEND_CID; 950163516Simp cmd.arg = 0; 951163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 952183470Simp cmd.data = NULL; 953163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 954163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 955163516Simp return (err); 956163516Simp} 957163516Simp 958163516Simpstatic int 959163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid) 960163516Simp{ 961163516Simp struct mmc_command cmd; 962163516Simp int err; 963163516Simp 964163516Simp cmd.opcode = MMC_SEND_CSD; 965163516Simp cmd.arg = rca << 16; 966163516Simp cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; 967183470Simp cmd.data = NULL; 968163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 969163516Simp memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); 970163516Simp return (err); 971163516Simp} 972163516Simp 973163516Simpstatic int 974183704Smavmmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr) 975183704Smav{ 976183704Smav int err; 977183704Smav struct mmc_command cmd; 978183704Smav struct mmc_data data; 979183704Smav 980183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 981183704Smav memset(&data, 0, sizeof(struct mmc_data)); 982183704Smav 983183704Smav memset(rawscr, 0, 8); 984183704Smav cmd.opcode = ACMD_SEND_SCR; 985183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 986183704Smav cmd.arg = 0; 987183704Smav cmd.data = &data; 988183704Smav 989183704Smav data.data = rawscr; 990183704Smav data.len = 8; 991183704Smav data.flags = MMC_DATA_READ; 992183704Smav 993183704Smav err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES); 994183704Smav rawscr[0] = be32toh(rawscr[0]); 995183704Smav rawscr[1] = be32toh(rawscr[1]); 996183704Smav return (err); 997183704Smav} 998183704Smav 999183704Smavstatic int 1000183704Smavmmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd) 1001183704Smav{ 1002183704Smav int err; 1003183704Smav struct mmc_command cmd; 1004183704Smav struct mmc_data data; 1005183704Smav 1006183704Smav memset(&cmd, 0, sizeof(struct mmc_command)); 1007183704Smav memset(&data, 0, sizeof(struct mmc_data)); 1008183704Smav 1009183704Smav memset(rawextcsd, 0, 512); 1010183704Smav cmd.opcode = MMC_SEND_EXT_CSD; 1011183704Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 1012183704Smav cmd.arg = 0; 1013183704Smav cmd.data = &data; 1014183704Smav 1015183704Smav data.data = rawextcsd; 1016183704Smav data.len = 512; 1017183704Smav data.flags = MMC_DATA_READ; 1018183704Smav 1019183704Smav err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); 1020183704Smav return (err); 1021183704Smav} 1022183704Smav 1023183704Smavstatic int 1024184033Smavmmc_app_sd_status(struct mmc_softc *sc, uint16_t rca, uint32_t *rawsdstatus) 1025184033Smav{ 1026184033Smav int err, i; 1027184033Smav struct mmc_command cmd; 1028184033Smav struct mmc_data data; 1029184033Smav 1030184033Smav memset(&cmd, 0, sizeof(struct mmc_command)); 1031184033Smav memset(&data, 0, sizeof(struct mmc_data)); 1032184033Smav 1033184033Smav memset(rawsdstatus, 0, 64); 1034184033Smav cmd.opcode = ACMD_SD_STATUS; 1035184033Smav cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 1036184033Smav cmd.arg = 0; 1037184033Smav cmd.data = &data; 1038184033Smav 1039184033Smav data.data = rawsdstatus; 1040184033Smav data.len = 64; 1041184033Smav data.flags = MMC_DATA_READ; 1042184033Smav 1043184033Smav err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES); 1044184033Smav for (i = 0; i < 16; i++) 1045184033Smav rawsdstatus[i] = be32toh(rawsdstatus[i]); 1046184033Smav return (err); 1047184033Smav} 1048184033Smav 1049184033Smavstatic int 1050183704Smavmmc_set_relative_addr(struct mmc_softc *sc, uint16_t resp) 1051183704Smav{ 1052183704Smav struct mmc_command cmd; 1053183704Smav int err; 1054183704Smav 1055183704Smav cmd.opcode = MMC_SET_RELATIVE_ADDR; 1056183704Smav cmd.arg = resp << 16; 1057183704Smav cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; 1058183704Smav cmd.data = NULL; 1059183704Smav err = mmc_wait_for_cmd(sc, &cmd, 0); 1060183704Smav return (err); 1061183704Smav} 1062183704Smav 1063183704Smavstatic int 1064163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp) 1065163516Simp{ 1066163516Simp struct mmc_command cmd; 1067163516Simp int err; 1068163516Simp 1069163516Simp cmd.opcode = SD_SEND_RELATIVE_ADDR; 1070163516Simp cmd.arg = 0; 1071163516Simp cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; 1072183470Simp cmd.data = NULL; 1073163516Simp err = mmc_wait_for_cmd(sc, &cmd, 0); 1074163516Simp *resp = cmd.resp[0]; 1075163516Simp return (err); 1076163516Simp} 1077163516Simp 1078163516Simpstatic void 1079187875Smavmmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard) 1080187875Smav{ 1081187875Smav device_printf(dev, "Card at relative address %d%s:\n", 1082187875Smav ivar->rca, newcard ? " added" : ""); 1083187875Smav device_printf(dev, " card: %s%s (0x%x/0x%x/\"%s\" rev %d.%d " 1084187875Smav "m/d %02d.%04d s/n %08x)\n", 1085187875Smav ivar->mode == mode_sd ? "SD" : "MMC", 1086187875Smav ivar->high_cap ? " High Capacity" : "", 1087187875Smav ivar->cid.mid, ivar->cid.oid, 1088187875Smav ivar->cid.pnm, ivar->cid.prv >> 4, ivar->cid.prv & 0x0f, 1089187875Smav ivar->cid.mdt_month, ivar->cid.mdt_year, ivar->cid.psn); 1090187875Smav device_printf(dev, " bus: %ubit, %uMHz%s\n", 1091187875Smav (ivar->bus_width == bus_width_1 ? 1 : 1092187875Smav (ivar->bus_width == bus_width_4 ? 4 : 8)), 1093187875Smav (ivar->timing == bus_timing_hs ? 1094187875Smav ivar->hs_tran_speed : ivar->tran_speed) / 1000000, 1095187875Smav ivar->timing == bus_timing_hs ? ", high speed timing" : ""); 1096187875Smav device_printf(dev, " memory: %u blocks, erase sector %u blocks%s\n", 1097187875Smav ivar->sec_count, ivar->erase_sector, 1098187875Smav ivar->read_only ? ", read-only" : ""); 1099187875Smav} 1100187875Smav 1101187875Smavstatic void 1102163516Simpmmc_discover_cards(struct mmc_softc *sc) 1103163516Simp{ 1104185721Smav struct mmc_ivars *ivar = NULL; 1105185721Smav device_t *devlist; 1106185721Smav int err, i, devcount, newcard; 1107185721Smav uint32_t raw_cid[4]; 1108183731Smav uint32_t resp, sec_count; 1109163516Simp device_t child; 1110183704Smav uint16_t rca = 2; 1111183704Smav u_char switch_res[64]; 1112163516Simp 1113187875Smav if (bootverbose || mmc_debug) 1114187875Smav device_printf(sc->dev, "Probing cards\n"); 1115163516Simp while (1) { 1116185721Smav err = mmc_all_send_cid(sc, raw_cid); 1117163516Simp if (err == MMC_ERR_TIMEOUT) 1118163516Simp break; 1119163516Simp if (err != MMC_ERR_NONE) { 1120183468Simp device_printf(sc->dev, "Error reading CID %d\n", err); 1121163516Simp break; 1122163516Simp } 1123185721Smav newcard = 1; 1124185721Smav if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0) 1125185721Smav return; 1126185721Smav for (i = 0; i < devcount; i++) { 1127185721Smav ivar = device_get_ivars(devlist[i]); 1128185721Smav if (memcmp(ivar->raw_cid, raw_cid, sizeof(raw_cid)) == 0) { 1129185721Smav newcard = 0; 1130185721Smav break; 1131185721Smav } 1132185721Smav } 1133185721Smav free(devlist, M_TEMP); 1134187875Smav if (bootverbose || mmc_debug) { 1135187875Smav device_printf(sc->dev, "%sard detected (CID %08x%08x%08x%08x)\n", 1136187875Smav newcard ? "New c" : "C", 1137187875Smav raw_cid[0], raw_cid[1], raw_cid[2], raw_cid[3]); 1138187875Smav } 1139185721Smav if (newcard) { 1140185721Smav ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, 1141185721Smav M_WAITOK | M_ZERO); 1142185721Smav if (!ivar) 1143185721Smav return; 1144185721Smav memcpy(ivar->raw_cid, raw_cid, sizeof(raw_cid)); 1145185721Smav } 1146183704Smav if (mmcbr_get_ro(sc->dev)) 1147183704Smav ivar->read_only = 1; 1148183704Smav ivar->bus_width = bus_width_1; 1149188044Simp ivar->timing = bus_timing_normal; 1150183704Smav ivar->mode = mmcbr_get_mode(sc->dev); 1151183704Smav if (ivar->mode == mode_sd) { 1152183729Simp mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid); 1153163516Simp mmc_send_relative_addr(sc, &resp); 1154163516Simp ivar->rca = resp >> 16; 1155183704Smav /* Get card CSD. */ 1156163516Simp mmc_send_csd(sc, ivar->rca, ivar->raw_csd); 1157183729Simp mmc_decode_csd_sd(ivar->raw_csd, &ivar->csd); 1158183731Smav ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE; 1159183704Smav if (ivar->csd.csd_structure > 0) 1160183704Smav ivar->high_cap = 1; 1161183704Smav ivar->tran_speed = ivar->csd.tran_speed; 1162184033Smav ivar->erase_sector = ivar->csd.erase_sector * 1163184033Smav ivar->csd.write_bl_len / MMC_SECTOR_SIZE; 1164183704Smav /* Get card SCR. Card must be selected to fetch it. */ 1165183704Smav mmc_select_card(sc, ivar->rca); 1166183704Smav mmc_app_send_scr(sc, ivar->rca, ivar->raw_scr); 1167183704Smav mmc_app_decode_scr(ivar->raw_scr, &ivar->scr); 1168188044Simp /* Get card switch capabilities (command class 10). */ 1169183704Smav if ((ivar->scr.sda_vsn >= 1) && 1170183704Smav (ivar->csd.ccc & (1<<10))) { 1171188044Simp mmc_sd_switch(sc, SD_SWITCH_MODE_CHECK, 1172188044Simp SD_SWITCH_GROUP1, SD_SWITCH_NOCHANGE, 1173188044Simp switch_res); 1174183704Smav if (switch_res[13] & 2) { 1175183704Smav ivar->timing = bus_timing_hs; 1176188044Simp ivar->hs_tran_speed = SD_MAX_HS; 1177183704Smav } 1178183704Smav } 1179184033Smav mmc_app_sd_status(sc, ivar->rca, ivar->raw_sd_status); 1180184033Smav mmc_app_decode_sd_status(ivar->raw_sd_status, 1181184033Smav &ivar->sd_status); 1182184033Smav if (ivar->sd_status.au_size != 0) { 1183184033Smav ivar->erase_sector = 1184184033Smav 16 << ivar->sd_status.au_size; 1185184033Smav } 1186183704Smav mmc_select_card(sc, 0); 1187183704Smav /* Find max supported bus width. */ 1188183704Smav if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) && 1189183704Smav (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) 1190183704Smav ivar->bus_width = bus_width_4; 1191187875Smav if (bootverbose || mmc_debug) 1192187875Smav mmc_log_card(sc->dev, ivar, newcard); 1193185721Smav if (newcard) { 1194185721Smav /* Add device. */ 1195185721Smav child = device_add_child(sc->dev, NULL, -1); 1196185721Smav device_set_ivars(child, ivar); 1197185721Smav } 1198169567Simp return; 1199163516Simp } 1200183729Simp mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid); 1201183704Smav ivar->rca = rca++; 1202183704Smav mmc_set_relative_addr(sc, ivar->rca); 1203183704Smav /* Get card CSD. */ 1204183704Smav mmc_send_csd(sc, ivar->rca, ivar->raw_csd); 1205183729Simp mmc_decode_csd_mmc(ivar->raw_csd, &ivar->csd); 1206183731Smav ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE; 1207183704Smav ivar->tran_speed = ivar->csd.tran_speed; 1208184033Smav ivar->erase_sector = ivar->csd.erase_sector * 1209184033Smav ivar->csd.write_bl_len / MMC_SECTOR_SIZE; 1210183704Smav /* Only MMC >= 4.x cards support EXT_CSD. */ 1211183704Smav if (ivar->csd.spec_vers >= 4) { 1212183704Smav /* Card must be selected to fetch EXT_CSD. */ 1213183704Smav mmc_select_card(sc, ivar->rca); 1214183704Smav mmc_send_ext_csd(sc, ivar->raw_ext_csd); 1215183731Smav /* Handle extended capacity from EXT_CSD */ 1216183731Smav sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] + 1217183731Smav (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 1] << 8) + 1218183731Smav (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 2] << 16) + 1219183731Smav (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 3] << 24); 1220183731Smav if (sec_count != 0) { 1221183731Smav ivar->sec_count = sec_count; 1222183731Smav ivar->high_cap = 1; 1223183731Smav } 1224183704Smav /* Get card speed in high speed mode. */ 1225183704Smav ivar->timing = bus_timing_hs; 1226183731Smav if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] 1227183704Smav & EXT_CSD_CARD_TYPE_52) 1228188044Simp ivar->hs_tran_speed = MMC_TYPE_52_MAX_HS; 1229183731Smav else if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] 1230183704Smav & EXT_CSD_CARD_TYPE_26) 1231188044Simp ivar->hs_tran_speed = MMC_TYPE_26_MAX_HS; 1232183704Smav else 1233183704Smav ivar->hs_tran_speed = ivar->tran_speed; 1234183704Smav /* Find max supported bus width. */ 1235183704Smav ivar->bus_width = mmc_test_bus_width(sc); 1236183704Smav mmc_select_card(sc, 0); 1237184033Smav /* Handle HC erase sector size. */ 1238184033Smav if (ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE] != 0) { 1239184033Smav ivar->erase_sector = 1024 * 1240184033Smav ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE]; 1241184033Smav mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, 1242184033Smav EXT_CSD_ERASE_GRP_DEF, 1); 1243184033Smav } 1244183704Smav } else { 1245183704Smav ivar->bus_width = bus_width_1; 1246183704Smav ivar->timing = bus_timing_normal; 1247183704Smav } 1248187875Smav if (bootverbose || mmc_debug) 1249187875Smav mmc_log_card(sc->dev, ivar, newcard); 1250185721Smav if (newcard) { 1251185721Smav /* Add device. */ 1252185721Smav child = device_add_child(sc->dev, NULL, -1); 1253185721Smav device_set_ivars(child, ivar); 1254185721Smav } 1255163516Simp } 1256163516Simp} 1257163516Simp 1258163516Simpstatic void 1259185721Smavmmc_rescan_cards(struct mmc_softc *sc) 1260185721Smav{ 1261185721Smav struct mmc_ivars *ivar = NULL; 1262185721Smav device_t *devlist; 1263185721Smav int err, i, devcount; 1264185721Smav 1265185721Smav if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0) 1266185721Smav return; 1267185721Smav for (i = 0; i < devcount; i++) { 1268185721Smav ivar = device_get_ivars(devlist[i]); 1269185721Smav if (mmc_select_card(sc, ivar->rca)) { 1270187875Smav if (bootverbose || mmc_debug) 1271187875Smav device_printf(sc->dev, "Card at relative address %d lost.\n", 1272187875Smav ivar->rca); 1273185721Smav device_delete_child(sc->dev, devlist[i]); 1274185721Smav free(ivar, M_DEVBUF); 1275185721Smav } 1276185721Smav } 1277185721Smav free(devlist, M_TEMP); 1278185721Smav mmc_select_card(sc, 0); 1279185721Smav} 1280185721Smav 1281185721Smavstatic int 1282185721Smavmmc_delete_cards(struct mmc_softc *sc) 1283185721Smav{ 1284185721Smav struct mmc_ivars *ivar; 1285185721Smav device_t *devlist; 1286185721Smav int err, i, devcount; 1287185721Smav 1288185721Smav if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0) 1289185721Smav return (err); 1290185721Smav for (i = 0; i < devcount; i++) { 1291185721Smav ivar = device_get_ivars(devlist[i]); 1292187875Smav if (bootverbose || mmc_debug) 1293187875Smav device_printf(sc->dev, "Card at relative address %d deleted.\n", 1294187875Smav ivar->rca); 1295185721Smav device_delete_child(sc->dev, devlist[i]); 1296185721Smav free(ivar, M_DEVBUF); 1297185721Smav } 1298185721Smav free(devlist, M_TEMP); 1299185721Smav return (0); 1300185721Smav} 1301185721Smav 1302185721Smavstatic void 1303163516Simpmmc_go_discovery(struct mmc_softc *sc) 1304163516Simp{ 1305163516Simp uint32_t ocr; 1306163516Simp device_t dev; 1307183704Smav int err; 1308163516Simp 1309163516Simp dev = sc->dev; 1310163516Simp if (mmcbr_get_power_mode(dev) != power_on) { 1311183453Simp /* 1312183453Simp * First, try SD modes 1313183453Simp */ 1314163516Simp mmcbr_set_mode(dev, mode_sd); 1315163516Simp mmc_power_up(sc); 1316163516Simp mmcbr_set_bus_mode(dev, pushpull); 1317187875Smav if (bootverbose || mmc_debug) 1318187875Smav device_printf(sc->dev, "Probing bus\n"); 1319163516Simp mmc_idle_cards(sc); 1320183704Smav err = mmc_send_if_cond(sc, 1); 1321187875Smav if ((bootverbose || mmc_debug) && err == 0) 1322187875Smav device_printf(sc->dev, "SD 2.0 interface conditions: OK\n"); 1323183775Simp if (mmc_send_app_op_cond(sc, err ? 0 : MMC_OCR_CCS, &ocr) != 1324183704Smav MMC_ERR_NONE) { 1325187875Smav if (bootverbose || mmc_debug) 1326187875Smav device_printf(sc->dev, "SD probe: failed\n"); 1327183453Simp /* 1328183453Simp * Failed, try MMC 1329183453Simp */ 1330163516Simp mmcbr_set_mode(dev, mode_mmc); 1331187875Smav if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) { 1332187875Smav if (bootverbose || mmc_debug) 1333187875Smav device_printf(sc->dev, "MMC probe: failed\n"); 1334185721Smav ocr = 0; /* Failed both, powerdown. */ 1335187875Smav } else if (bootverbose || mmc_debug) 1336187875Smav device_printf(sc->dev, 1337187875Smav "MMC probe: OK (OCR: 0x%08x)\n", ocr); 1338187875Smav } else if (bootverbose || mmc_debug) 1339187875Smav device_printf(sc->dev, "SD probe: OK (OCR: 0x%08x)\n", ocr); 1340187875Smav 1341163516Simp mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr)); 1342163516Simp if (mmcbr_get_ocr(dev) != 0) 1343163516Simp mmc_idle_cards(sc); 1344163516Simp } else { 1345163516Simp mmcbr_set_bus_mode(dev, opendrain); 1346163516Simp mmcbr_set_clock(dev, mmcbr_get_f_min(dev)); 1347163516Simp mmcbr_update_ios(dev); 1348183453Simp /* XXX recompute vdd based on new cards? */ 1349163516Simp } 1350163516Simp /* 1351163516Simp * Make sure that we have a mutually agreeable voltage to at least 1352163516Simp * one card on the bus. 1353163516Simp */ 1354187875Smav if (bootverbose || mmc_debug) 1355187875Smav device_printf(sc->dev, "Current OCR: 0x%08x\n", mmcbr_get_ocr(dev)); 1356185721Smav if (mmcbr_get_ocr(dev) == 0) { 1357185721Smav mmc_delete_cards(sc); 1358185721Smav mmc_power_down(sc); 1359163516Simp return; 1360185721Smav } 1361163516Simp /* 1362163516Simp * Reselect the cards after we've idled them above. 1363163516Simp */ 1364183704Smav if (mmcbr_get_mode(dev) == mode_sd) { 1365183704Smav err = mmc_send_if_cond(sc, 1); 1366183704Smav mmc_send_app_op_cond(sc, 1367183775Simp (err ? 0 : MMC_OCR_CCS) | mmcbr_get_ocr(dev), NULL); 1368183704Smav } else 1369163516Simp mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL); 1370163516Simp mmc_discover_cards(sc); 1371185721Smav mmc_rescan_cards(sc); 1372163516Simp 1373163516Simp mmcbr_set_bus_mode(dev, pushpull); 1374163516Simp mmcbr_update_ios(dev); 1375183763Smav mmc_calculate_clock(sc); 1376163516Simp bus_generic_attach(dev); 1377183453Simp/* mmc_update_children_sysctl(dev);*/ 1378163516Simp} 1379163516Simp 1380163516Simpstatic int 1381163516Simpmmc_calculate_clock(struct mmc_softc *sc) 1382163516Simp{ 1383183704Smav int max_dtr, max_hs_dtr, max_timing; 1384163516Simp int nkid, i, f_min, f_max; 1385163516Simp device_t *kids; 1386183704Smav struct mmc_ivars *ivar; 1387163516Simp 1388163516Simp f_min = mmcbr_get_f_min(sc->dev); 1389163516Simp f_max = mmcbr_get_f_max(sc->dev); 1390183704Smav max_dtr = max_hs_dtr = f_max; 1391183704Smav if ((mmcbr_get_caps(sc->dev) & MMC_CAP_HSPEED)) 1392183704Smav max_timing = bus_timing_hs; 1393183704Smav else 1394183704Smav max_timing = bus_timing_normal; 1395163516Simp if (device_get_children(sc->dev, &kids, &nkid) != 0) 1396163516Simp panic("can't get children"); 1397183704Smav for (i = 0; i < nkid; i++) { 1398183704Smav ivar = device_get_ivars(kids[i]); 1399183704Smav if (ivar->timing < max_timing) 1400183704Smav max_timing = ivar->timing; 1401183704Smav if (ivar->tran_speed < max_dtr) 1402183704Smav max_dtr = ivar->tran_speed; 1403187525Smav if (ivar->hs_tran_speed < max_hs_dtr) 1404183704Smav max_hs_dtr = ivar->hs_tran_speed; 1405183704Smav } 1406183704Smav for (i = 0; i < nkid; i++) { 1407183704Smav ivar = device_get_ivars(kids[i]); 1408183704Smav if (ivar->timing == bus_timing_normal) 1409183704Smav continue; 1410183704Smav mmc_select_card(sc, ivar->rca); 1411183704Smav mmc_set_timing(sc, max_timing); 1412183704Smav } 1413183704Smav mmc_select_card(sc, 0); 1414163516Simp free(kids, M_TEMP); 1415183704Smav if (max_timing == bus_timing_hs) 1416183704Smav max_dtr = max_hs_dtr; 1417187875Smav if (bootverbose || mmc_debug) { 1418183775Simp device_printf(sc->dev, 1419183775Simp "setting transfer rate to %d.%03dMHz%s\n", 1420183763Smav max_dtr / 1000000, (max_dtr / 1000) % 1000, 1421183775Simp max_timing == bus_timing_hs ? " (high speed timing)" : ""); 1422183763Smav } 1423183704Smav mmcbr_set_timing(sc->dev, max_timing); 1424183704Smav mmcbr_set_clock(sc->dev, max_dtr); 1425183704Smav mmcbr_update_ios(sc->dev); 1426183704Smav return max_dtr; 1427163516Simp} 1428163516Simp 1429163516Simpstatic void 1430163516Simpmmc_scan(struct mmc_softc *sc) 1431163516Simp{ 1432185721Smav device_t dev = sc->dev; 1433163516Simp 1434163516Simp mmc_acquire_bus(dev, dev); 1435163516Simp mmc_go_discovery(sc); 1436163516Simp mmc_release_bus(dev, dev); 1437163516Simp} 1438163516Simp 1439163516Simpstatic int 1440163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result) 1441163516Simp{ 1442163516Simp struct mmc_ivars *ivar = device_get_ivars(child); 1443163516Simp 1444163516Simp switch (which) { 1445163516Simp default: 1446163516Simp return (EINVAL); 1447163516Simp case MMC_IVAR_DSR_IMP: 1448163516Simp *(int *)result = ivar->csd.dsr_imp; 1449163516Simp break; 1450163516Simp case MMC_IVAR_MEDIA_SIZE: 1451183731Smav *(off_t *)result = ivar->sec_count; 1452163516Simp break; 1453163516Simp case MMC_IVAR_RCA: 1454163516Simp *(int *)result = ivar->rca; 1455163516Simp break; 1456163516Simp case MMC_IVAR_SECTOR_SIZE: 1457183542Simp *(int *)result = MMC_SECTOR_SIZE; 1458163516Simp break; 1459163516Simp case MMC_IVAR_TRAN_SPEED: 1460183763Smav *(int *)result = mmcbr_get_clock(bus); 1461163516Simp break; 1462183447Simp case MMC_IVAR_READ_ONLY: 1463183447Simp *(int *)result = ivar->read_only; 1464183447Simp break; 1465183704Smav case MMC_IVAR_HIGH_CAP: 1466183704Smav *(int *)result = ivar->high_cap; 1467183704Smav break; 1468183763Smav case MMC_IVAR_CARD_TYPE: 1469183763Smav *(int *)result = ivar->mode; 1470183763Smav break; 1471183763Smav case MMC_IVAR_BUS_WIDTH: 1472183763Smav *(int *)result = ivar->bus_width; 1473183763Smav break; 1474184033Smav case MMC_IVAR_ERASE_SECTOR: 1475184033Smav *(int *)result = ivar->erase_sector; 1476184033Smav break; 1477184452Smav case MMC_IVAR_MAX_DATA: 1478184452Smav *(int *)result = mmcbr_get_max_data(bus); 1479184452Smav break; 1480163516Simp } 1481163516Simp return (0); 1482163516Simp} 1483163516Simp 1484163516Simpstatic int 1485163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value) 1486163516Simp{ 1487183453Simp /* 1488183453Simp * None are writable ATM 1489183453Simp */ 1490183453Simp return (EINVAL); 1491163516Simp} 1492163516Simp 1493163516Simp 1494163516Simpstatic void 1495163516Simpmmc_delayed_attach(void *xsc) 1496163516Simp{ 1497163516Simp struct mmc_softc *sc = xsc; 1498163516Simp 1499163516Simp mmc_scan(sc); 1500163516Simp config_intrhook_disestablish(&sc->config_intrhook); 1501163516Simp} 1502163516Simp 1503163516Simpstatic device_method_t mmc_methods[] = { 1504163516Simp /* device_if */ 1505163516Simp DEVMETHOD(device_probe, mmc_probe), 1506163516Simp DEVMETHOD(device_attach, mmc_attach), 1507163516Simp DEVMETHOD(device_detach, mmc_detach), 1508185721Smav DEVMETHOD(device_suspend, mmc_suspend), 1509185721Smav DEVMETHOD(device_resume, mmc_resume), 1510163516Simp 1511163516Simp /* Bus interface */ 1512163516Simp DEVMETHOD(bus_read_ivar, mmc_read_ivar), 1513163516Simp DEVMETHOD(bus_write_ivar, mmc_write_ivar), 1514163516Simp 1515163516Simp /* MMC Bus interface */ 1516163516Simp DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request), 1517163516Simp DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus), 1518163516Simp DEVMETHOD(mmcbus_release_bus, mmc_release_bus), 1519163516Simp 1520163516Simp {0, 0}, 1521163516Simp}; 1522163516Simp 1523163516Simpstatic driver_t mmc_driver = { 1524163516Simp "mmc", 1525163516Simp mmc_methods, 1526163516Simp sizeof(struct mmc_softc), 1527163516Simp}; 1528163516Simpstatic devclass_t mmc_devclass; 1529163516Simp 1530163516Simp 1531188044SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL); 1532188044SimpDRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL); 1533