1 1.1 nisimura /*- 2 1.1 nisimura * Copyright (c) 2012 The NetBSD Foundation, Inc. 3 1.1 nisimura * All rights reserved. 4 1.1 nisimura * 5 1.1 nisimura * This code is derived from software contributed to The NetBSD Foundation 6 1.1 nisimura * by Paul Fleischer <paul (at) xpg.dk> 7 1.1 nisimura * 8 1.1 nisimura * Redistribution and use in source and binary forms, with or without 9 1.1 nisimura * modification, are permitted provided that the following conditions 10 1.1 nisimura * are met: 11 1.1 nisimura * 1. Redistributions of source code must retain the above copyright 12 1.1 nisimura * notice, this list of conditions and the following disclaimer. 13 1.1 nisimura * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 nisimura * notice, this list of conditions and the following disclaimer in the 15 1.1 nisimura * documentation and/or other materials provided with the distribution. 16 1.1 nisimura * 17 1.1 nisimura * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 1.1 nisimura * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 1.1 nisimura * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 1.1 nisimura * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 1.1 nisimura * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 1.1 nisimura * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 1.1 nisimura * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 1.1 nisimura * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 1.1 nisimura * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 1.1 nisimura * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 1.1 nisimura * POSSIBILITY OF SUCH DAMAGE. 28 1.1 nisimura */ 29 1.1 nisimura 30 1.1 nisimura /* 31 1.1 nisimura * All SD/MMC code is taken from various files in sys/dev/sdmmc 32 1.1 nisimura */ 33 1.1 nisimura /* 34 1.1 nisimura * Copyright (c) 2006 Uwe Stuehler <uwe (at) openbsd.org> 35 1.1 nisimura * 36 1.1 nisimura * Permission to use, copy, modify, and distribute this software for any 37 1.1 nisimura * purpose with or without fee is hereby granted, provided that the above 38 1.1 nisimura * copyright notice and this permission notice appear in all copies. 39 1.1 nisimura * 40 1.1 nisimura * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 41 1.1 nisimura * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 42 1.1 nisimura * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 43 1.1 nisimura * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 44 1.1 nisimura * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 45 1.1 nisimura * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 46 1.1 nisimura * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 47 1.1 nisimura */ 48 1.1 nisimura 49 1.1 nisimura /*- 50 1.1 nisimura * Copyright (c) 2007-2010 NONAKA Kimihiro <nonaka (at) netbsd.org> 51 1.1 nisimura * All rights reserved. 52 1.1 nisimura * 53 1.1 nisimura * Redistribution and use in source and binary forms, with or without 54 1.1 nisimura * modification, are permitted provided that the following conditions 55 1.1 nisimura * are met: 56 1.1 nisimura * 1. Redistributions of source code must retain the above copyright 57 1.1 nisimura * notice, this list of conditions and the following disclaimer. 58 1.1 nisimura * 2. Redistributions in binary form must reproduce the above copyright 59 1.1 nisimura * notice, this list of conditions and the following disclaimer in the 60 1.1 nisimura * documentation and/or other materials provided with the distribution. 61 1.1 nisimura * 62 1.1 nisimura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 63 1.1 nisimura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 64 1.1 nisimura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 65 1.1 nisimura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 66 1.1 nisimura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 67 1.1 nisimura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 68 1.1 nisimura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 1.1 nisimura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 70 1.1 nisimura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 71 1.1 nisimura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 72 1.1 nisimura * SUCH DAMAGE. 73 1.1 nisimura */ 74 1.1 nisimura 75 1.1 nisimura #include <machine/limits.h> 76 1.1 nisimura 77 1.1 nisimura #include <sys/param.h> 78 1.1 nisimura #include <sys/types.h> 79 1.1 nisimura #include <sys/disklabel.h> 80 1.1 nisimura 81 1.1 nisimura #include <netinet/in.h> 82 1.1 nisimura 83 1.1 nisimura #include <lib/libsa/stand.h> 84 1.1 nisimura 85 1.1 nisimura #include <lib/libkern/libkern.h> 86 1.1 nisimura #include <lib/libsa/stand.h> 87 1.1 nisimura #include <lib/libsa/iodesc.h> 88 1.1 nisimura 89 1.1 nisimura #include <dev/sdmmc/sdmmcreg.h> 90 1.1 nisimura #include "dev_sdmmc.h" 91 1.1 nisimura #include "s3csdi.h" 92 1.1 nisimura 93 1.1 nisimura //#define SDMMC_DEBUG 94 1.1 nisimura #ifdef SDMMC_DEBUG 95 1.1 nisimura #define DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 96 1.1 nisimura #else 97 1.1 nisimura #define DPRINTF(s) do {} while (/*CONSTCOND*/0) 98 1.1 nisimura #endif 99 1.1 nisimura 100 1.1 nisimura /* SD/MMC device driver structure */ 101 1.1 nisimura struct sdifdv { 102 1.1 nisimura char* name; 103 1.1 nisimura int (*match)(unsigned); 104 1.1 nisimura void* (*init)(unsigned, uint32_t*); 105 1.1 nisimura int (*host_ocr)(void*); 106 1.1 nisimura int (*bus_clock)(void*, int); 107 1.1 nisimura int (*bus_power)(void*, int); 108 1.1 nisimura int (*bus_width)(void*, int); 109 1.1 nisimura void (*exec_cmd)(void*, struct sdmmc_command*); 110 1.1 nisimura int (*get_max_bus_clock)(void*); 111 1.1 nisimura void* priv; 112 1.1 nisimura }; 113 1.1 nisimura 114 1.1 nisimura struct sdmmc_softc; 115 1.1 nisimura 116 1.1 nisimura /* Structure used for of->f_devdata */ 117 1.1 nisimura struct sdmmc_part { 118 1.1 nisimura struct sdmmc_softc *sc; 119 1.1 nisimura struct partition *part; 120 1.1 nisimura }; 121 1.1 nisimura 122 1.1 nisimura /* SD/MMC driver structure */ 123 1.1 nisimura struct sdmmc_softc { 124 1.1 nisimura uint32_t flags; 125 1.1 nisimura uint32_t caps; 126 1.1 nisimura uint16_t rca; /* relative card address */ 127 1.1 nisimura sdmmc_response raw_cid; /* temp. storage for decoding */ 128 1.1 nisimura uint32_t raw_scr[2]; 129 1.1 nisimura struct sdmmc_csd csd; /* decoded CSD value */ 130 1.1 nisimura struct sdmmc_cid cid; /* decoded CID value */ 131 1.1 nisimura struct sdmmc_scr scr; 132 1.1 nisimura int busclk; 133 1.1 nisimura struct sdifdv *sdifdv; 134 1.1 nisimura struct disklabel sc_label; 135 1.1 nisimura int npartitions; 136 1.1 nisimura struct sdmmc_part partitions[MAXPARTITIONS]; 137 1.1 nisimura }; 138 1.1 nisimura 139 1.1 nisimura static struct sdifdv vnifdv[] = { 140 1.1 nisimura {"S3C SD/MMC", s3csd_match, s3csd_init, s3csd_host_ocr, 141 1.1 nisimura s3csd_bus_clock, s3csd_bus_power, s3csd_bus_width, s3csd_exec_cmd, 142 1.1 nisimura s3csd_get_max_bus_clock} 143 1.1 nisimura }; 144 1.1 nisimura static int nnifdv = sizeof(vnifdv)/sizeof(vnifdv[0]); 145 1.1 nisimura 146 1.1 nisimura static struct sdmmc_softc sdmmc_softc; 147 1.1 nisimura static uint8_t sdmmc_initialized = FALSE; 148 1.1 nisimura 149 1.1 nisimura extern time_t getsecs(); 150 1.1 nisimura extern time_t getusecs(); 151 1.1 nisimura extern void usleep(int); 152 1.1 nisimura 153 1.1 nisimura /* Local functions */ 154 1.1 nisimura static int sdmmc_getdisklabel(struct sdmmc_softc *sc); 155 1.1 nisimura static int sdmmc_init(unsigned int tag); 156 1.1 nisimura static int sdmmc_enable(struct sdmmc_softc*); 157 1.1 nisimura 158 1.1 nisimura static int sdmmc_mem_send_if_cond(struct sdmmc_softc*, uint32_t, uint32_t*); 159 1.1 nisimura static int sdmmc_mmc_command(struct sdmmc_softc*, struct sdmmc_command*); 160 1.1 nisimura static void sdmmc_go_idle_state(struct sdmmc_softc*); 161 1.1 nisimura static int sdmmc_mem_send_op_cond(struct sdmmc_softc*, uint32_t, uint32_t *); 162 1.1 nisimura static int sdmmc_set_bus_power(struct sdmmc_softc*, uint32_t, uint32_t); 163 1.1 nisimura static int sdmmc_app_command(struct sdmmc_softc*, uint16_t, 164 1.1 nisimura struct sdmmc_command*); 165 1.1 nisimura static int sdmmc_mmc_command(struct sdmmc_softc*, struct sdmmc_command*); 166 1.1 nisimura static int sdmmc_scan(struct sdmmc_softc*); 167 1.1 nisimura static void sdmmc_mem_scan(struct sdmmc_softc*); 168 1.1 nisimura static int sdmmc_set_relative_addr(struct sdmmc_softc*); 169 1.1 nisimura static int sdmmc_mem_send_cid(struct sdmmc_softc*, sdmmc_response*); 170 1.1 nisimura 171 1.1 nisimura static int sdmmc_mem_send_csd(struct sdmmc_softc*, sdmmc_response*); 172 1.1 nisimura static int sdmmc_decode_csd(struct sdmmc_softc*, sdmmc_response); 173 1.1 nisimura static int sdmmc_decode_cid(struct sdmmc_softc*, sdmmc_response); 174 1.1 nisimura 175 1.1 nisimura static int sdmmc_mem_read_block(struct sdmmc_softc*, uint32_t, u_char*, size_t); 176 1.1 nisimura static int sdmmc_select_card(struct sdmmc_softc*); 177 1.1 nisimura static int sdmmc_mem_set_blocklen(struct sdmmc_softc*); 178 1.1 nisimura 179 1.1 nisimura static int sdmmc_mem_send_scr(struct sdmmc_softc*, uint32_t[2]); 180 1.1 nisimura static int sdmmc_mem_decode_scr(struct sdmmc_softc*); 181 1.1 nisimura static int sdmmc_set_bus_width(struct sdmmc_softc*, int); 182 1.1 nisimura static int sdmmc_mem_sd_switch(struct sdmmc_softc *, int, int, int, void*); 183 1.1 nisimura 184 1.1 nisimura #ifdef SDMMC_DEBUG 185 1.1 nisimura static void sdmmc_dump_data(const char*, void*, size_t); 186 1.1 nisimura static void sdmmc_print_cid(struct sdmmc_cid*); 187 1.1 nisimura static void sdmmc_dump_command(struct sdmmc_softc*, struct sdmmc_command*); 188 1.1 nisimura #endif 189 1.1 nisimura 190 1.1 nisimura int 191 1.1 nisimura sdmmc_open(struct open_file *of, ...) 192 1.1 nisimura { 193 1.1 nisimura va_list ap; 194 1.2 christos int unit __unused, part; 195 1.1 nisimura 196 1.1 nisimura va_start(ap, of); 197 1.1 nisimura unit = va_arg(ap, u_int); /* Not used for now */ 198 1.1 nisimura part = va_arg(ap, u_int); 199 1.1 nisimura va_end(ap); 200 1.1 nisimura 201 1.1 nisimura /* Simply try to initialize SD mem sub system. */ 202 1.1 nisimura if( !sdmmc_init(0) ) { 203 1.1 nisimura return 1; 204 1.1 nisimura } 205 1.1 nisimura 206 1.1 nisimura of->f_devdata = (void*)&sdmmc_softc.partitions[part]; 207 1.1 nisimura 208 1.1 nisimura return 0; 209 1.1 nisimura } 210 1.1 nisimura 211 1.1 nisimura int 212 1.1 nisimura sdmmc_close(struct open_file *f) 213 1.1 nisimura { 214 1.1 nisimura return (0); 215 1.1 nisimura } 216 1.1 nisimura 217 1.1 nisimura int 218 1.1 nisimura sdmmc_get_fstype(void *p) { 219 1.1 nisimura struct sdmmc_part *part = (struct sdmmc_part*)p; 220 1.1 nisimura 221 1.1 nisimura return part->part->p_fstype; 222 1.1 nisimura } 223 1.1 nisimura 224 1.1 nisimura 225 1.1 nisimura int 226 1.1 nisimura sdmmc_strategy(void *d, int f, daddr_t b, size_t s, void *buf, size_t *r) 227 1.1 nisimura { 228 1.1 nisimura struct sdmmc_part *part = (struct sdmmc_part*)d; 229 1.1 nisimura unsigned int offset; 230 1.1 nisimura switch(f) { 231 1.1 nisimura case F_READ: 232 1.1 nisimura offset = part->part->p_offset + b; 233 1.1 nisimura *r = s; 234 1.1 nisimura if(sdmmc_mem_read_block(part->sc, offset, buf, s) == 0) 235 1.1 nisimura return 0; 236 1.1 nisimura else 237 1.1 nisimura return EIO; 238 1.1 nisimura default: 239 1.1 nisimura printf("Unsupported operation\n"); 240 1.1 nisimura break; 241 1.1 nisimura } 242 1.1 nisimura return (EIO); 243 1.1 nisimura } 244 1.1 nisimura 245 1.1 nisimura int 246 1.1 nisimura sdmmc_getdisklabel(struct sdmmc_softc *sc) 247 1.1 nisimura { 248 1.1 nisimura char *msg; 249 1.1 nisimura int sector, i, n; 250 1.1 nisimura size_t rsize; 251 1.1 nisimura struct mbr_partition *dp, *bsdp; 252 1.1 nisimura struct disklabel *lp; 253 1.1 nisimura /*uint8_t *buf = wd->sc_buf;*/ 254 1.1 nisimura uint8_t buf[DEV_BSIZE]; 255 1.1 nisimura 256 1.1 nisimura lp = &sc->sc_label; 257 1.1 nisimura memset(lp, 0, sizeof(struct disklabel)); 258 1.1 nisimura 259 1.1 nisimura sector = 0; 260 1.1 nisimura if (sdmmc_strategy(&sc->partitions[0], F_READ, MBR_BBSECTOR, DEV_BSIZE, 261 1.1 nisimura buf, &rsize)) 262 1.1 nisimura return EOFFSET; 263 1.1 nisimura 264 1.1 nisimura dp = (struct mbr_partition *)(buf + MBR_PART_OFFSET); 265 1.1 nisimura bsdp = NULL; 266 1.1 nisimura for (i = 0; i < MBR_PART_COUNT; i++, dp++) { 267 1.1 nisimura if (dp->mbrp_type == MBR_PTYPE_NETBSD) { 268 1.1 nisimura bsdp = dp; 269 1.1 nisimura break; 270 1.1 nisimura } 271 1.1 nisimura } 272 1.1 nisimura if (!bsdp) { 273 1.1 nisimura /* generate fake disklabel */ 274 1.1 nisimura lp->d_secsize = DEV_BSIZE; 275 1.1 nisimura /*lp->d_ntracks = wd->sc_params.atap_heads; 276 1.1 nisimura lp->d_nsectors = wd->sc_params.atap_sectors; 277 1.1 nisimura lp->d_ncylinders = wd->sc_params.atap_cylinders;*/ 278 1.1 nisimura lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; 279 1.3 christos lp->d_type = DKTYPE_FLASH; 280 1.1 nisimura /*strncpy(lp->d_typename, (char *)wd->sc_params.atap_model, 16);*/ 281 1.1 nisimura strncpy(lp->d_packname, "fictitious", 16); 282 1.1 nisimura /*if (wd->sc_capacity > UINT32_MAX) 283 1.1 nisimura lp->d_secperunit = UINT32_MAX; 284 1.1 nisimura else 285 1.1 nisimura lp->d_secperunit = wd->sc_capacity;*/ 286 1.1 nisimura lp->d_rpm = 3600; 287 1.1 nisimura lp->d_interleave = 1; 288 1.1 nisimura lp->d_flags = 0; 289 1.1 nisimura lp->d_partitions[RAW_PART].p_offset = 0; 290 1.1 nisimura lp->d_partitions[RAW_PART].p_size = 291 1.1 nisimura lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); 292 1.1 nisimura lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; 293 1.1 nisimura lp->d_magic = DISKMAGIC; 294 1.1 nisimura lp->d_magic2 = DISKMAGIC; 295 1.1 nisimura lp->d_checksum = dkcksum(lp); 296 1.1 nisimura 297 1.1 nisimura dp = (struct mbr_partition *)(buf + MBR_PART_OFFSET); 298 1.1 nisimura n = 'e' - 'a'; 299 1.1 nisimura for (i = 0; i < MBR_PART_COUNT; i++, dp++) { 300 1.1 nisimura if (dp->mbrp_type == MBR_PTYPE_UNUSED) 301 1.1 nisimura continue; 302 1.1 nisimura lp->d_partitions[n].p_offset = bswap32(dp->mbrp_start); 303 1.1 nisimura lp->d_partitions[n].p_size = bswap32(dp->mbrp_size); 304 1.1 nisimura switch (dp->mbrp_type) { 305 1.1 nisimura case MBR_PTYPE_FAT12: 306 1.1 nisimura case MBR_PTYPE_FAT16S: 307 1.1 nisimura case MBR_PTYPE_FAT16B: 308 1.1 nisimura case MBR_PTYPE_FAT32: 309 1.1 nisimura case MBR_PTYPE_FAT32L: 310 1.1 nisimura case MBR_PTYPE_FAT16L: 311 1.1 nisimura lp->d_partitions[n].p_fstype = FS_MSDOS; 312 1.1 nisimura break; 313 1.1 nisimura case MBR_PTYPE_LNXEXT2: 314 1.1 nisimura lp->d_partitions[n].p_fstype = FS_EX2FS; 315 1.1 nisimura break; 316 1.1 nisimura default: 317 1.1 nisimura lp->d_partitions[n].p_fstype = FS_OTHER; 318 1.1 nisimura break; 319 1.1 nisimura } 320 1.1 nisimura n += 1; 321 1.1 nisimura } 322 1.1 nisimura lp->d_npartitions = n; 323 1.1 nisimura } 324 1.1 nisimura else { 325 1.1 nisimura sector = bsdp->mbrp_start; 326 1.1 nisimura if (sdmmc_strategy(&sc->partitions[0], F_READ, 327 1.1 nisimura sector + LABELSECTOR, DEV_BSIZE, 328 1.1 nisimura buf, &rsize)) 329 1.1 nisimura return EOFFSET; 330 1.1 nisimura msg = getdisklabel((char *)buf + LABELOFFSET, &sc->sc_label); 331 1.1 nisimura if (msg != NULL) 332 1.1 nisimura printf("getdisklabel: %s\n", msg); 333 1.1 nisimura } 334 1.1 nisimura /*DPRINTF(("label info: d_secsize %d, d_nsectors %d, d_ncylinders %d," 335 1.1 nisimura "d_ntracks %d, d_secpercyl %d\n", 336 1.1 nisimura wd->sc_label.d_secsize, 337 1.1 nisimura wd->sc_label.d_nsectors, 338 1.1 nisimura wd->sc_label.d_ncylinders, 339 1.1 nisimura wd->sc_label.d_ntracks, 340 1.1 nisimura wd->sc_label.d_secpercyl));*/ 341 1.1 nisimura 342 1.1 nisimura return 0; 343 1.1 nisimura } 344 1.1 nisimura 345 1.1 nisimura void 346 1.1 nisimura sdmmc_delay(int us) { 347 1.1 nisimura usleep(us); 348 1.1 nisimura } 349 1.1 nisimura 350 1.1 nisimura /* Initialize the SD/MMC subsystem. Return 1 on success, and 0 on error. 351 1.1 nisimura In case of error, errno will be set to a sane value. 352 1.1 nisimura */ 353 1.1 nisimura int 354 1.1 nisimura sdmmc_init(unsigned int tag) 355 1.1 nisimura { 356 1.1 nisimura struct sdifdv *dv; 357 1.1 nisimura int n; 358 1.1 nisimura int error; 359 1.1 nisimura struct sdmmc_softc *sc = &sdmmc_softc; 360 1.1 nisimura char status[64]; 361 1.1 nisimura 362 1.1 nisimura if (sdmmc_initialized) { 363 1.1 nisimura printf("SD/MMC already initialized\n"); 364 1.1 nisimura return 1; 365 1.1 nisimura } 366 1.1 nisimura 367 1.1 nisimura for (n = 0; n < nnifdv; n++) { 368 1.1 nisimura dv = &vnifdv[n]; 369 1.1 nisimura if ((*dv->match)(tag) > 0) 370 1.1 nisimura goto found; 371 1.1 nisimura } 372 1.1 nisimura errno = ENODEV; 373 1.1 nisimura return 0; 374 1.1 nisimura found: 375 1.1 nisimura sc->caps = 0; 376 1.1 nisimura /* Init should return NULL if no card is present. */ 377 1.1 nisimura sc->sdifdv->priv = (*dv->init)(tag, &sc->caps); 378 1.1 nisimura if (sc->sdifdv->priv == NULL) { 379 1.1 nisimura /* We expect that the device initialization sets 380 1.1 nisimura errno properly */ 381 1.1 nisimura return 0; 382 1.1 nisimura } 383 1.1 nisimura 384 1.1 nisimura sc->flags = 0; 385 1.1 nisimura sc->sdifdv = dv; 386 1.1 nisimura 387 1.6 andvar /* Perform SD-card initialization. */ 388 1.1 nisimura if( sdmmc_enable(sc) ) { 389 1.1 nisimura printf("Failed to enable SD interface\n"); 390 1.1 nisimura errno = EIO; 391 1.1 nisimura return 0; 392 1.1 nisimura } 393 1.1 nisimura sc->busclk = sc->sdifdv->get_max_bus_clock(sc->sdifdv->priv); 394 1.1 nisimura 395 1.1 nisimura if (sdmmc_scan(sc)) { 396 1.1 nisimura printf("No functions\n"); 397 1.1 nisimura errno = EIO; 398 1.1 nisimura return 0; 399 1.1 nisimura } 400 1.1 nisimura 401 1.1 nisimura if (sdmmc_select_card(sc)) { 402 1.1 nisimura printf("Failed to select card\n"); 403 1.1 nisimura errno = EIO; 404 1.1 nisimura return 0; 405 1.1 nisimura } 406 1.1 nisimura 407 1.1 nisimura if (!ISSET(sc->flags, SMF_CARD_SDHC)) { 408 1.1 nisimura sdmmc_mem_set_blocklen(sc); 409 1.1 nisimura } 410 1.1 nisimura 411 1.1 nisimura /* change bus width if supported */ 412 1.1 nisimura if (ISSET(sc->flags, SMF_SD_MODE) ) { 413 1.1 nisimura error = sdmmc_mem_send_scr(sc, sc->raw_scr); 414 1.1 nisimura if (error) { 415 1.1 nisimura DPRINTF(("SD_SEND_SCR send failed.\n")); 416 1.1 nisimura errno = EIO; 417 1.1 nisimura return 0; 418 1.1 nisimura } 419 1.1 nisimura error = sdmmc_mem_decode_scr(sc); 420 1.1 nisimura if (error) { 421 1.1 nisimura errno = EIO; 422 1.1 nisimura return 0; 423 1.1 nisimura } 424 1.1 nisimura 425 1.1 nisimura if (ISSET(sc->caps, SMC_CAPS_4BIT_MODE) && 426 1.1 nisimura ISSET(sc->scr.bus_width, SCR_SD_BUS_WIDTHS_4BIT)) { 427 1.1 nisimura error = sdmmc_set_bus_width(sc, 4); 428 1.1 nisimura if (error) { 429 1.1 nisimura DPRINTF(("can't change bus width" 430 1.1 nisimura " (%d bit)\n", 4)); 431 1.1 nisimura errno = EIO; 432 1.1 nisimura return 0; 433 1.1 nisimura } 434 1.1 nisimura } 435 1.1 nisimura 436 1.1 nisimura #if 1 437 1.1 nisimura if (sc->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 && 438 1.1 nisimura ISSET(sc->csd.ccc, SD_CSD_CCC_SWITCH)) { 439 1.1 nisimura DPRINTF(("switch func mode 0\n")); 440 1.1 nisimura error = sdmmc_mem_sd_switch(sc, 0, 1, 0, status); 441 1.1 nisimura if (error) { 442 1.1 nisimura printf("switch func mode 0 failed\n"); 443 1.1 nisimura errno = error; 444 1.1 nisimura return 0; 445 1.1 nisimura } 446 1.1 nisimura } 447 1.1 nisimura #endif 448 1.1 nisimura sc->sdifdv->bus_clock(sc->sdifdv->priv, sc->busclk); 449 1.1 nisimura } 450 1.1 nisimura 451 1.1 nisimura /* Prepare dummy partition[0] entry used by sdmmc_getdisklabel() */ 452 1.1 nisimura sc->partitions[0].sc = sc; 453 1.1 nisimura sc->partitions[0].part->p_offset = 0; 454 1.1 nisimura 455 1.1 nisimura if(sdmmc_getdisklabel(sc)) { 456 1.1 nisimura errno = EOFFSET; 457 1.1 nisimura return 0; 458 1.1 nisimura } 459 1.1 nisimura 460 1.1 nisimura sc->npartitions = sc->sc_label.d_npartitions; 461 1.1 nisimura for(n=0; n<sc->sc_label.d_npartitions; n++) { 462 1.1 nisimura sc->partitions[n].part = &sc->sc_label.d_partitions[n]; 463 1.1 nisimura sc->partitions[n].sc = sc; 464 1.1 nisimura } 465 1.1 nisimura 466 1.1 nisimura sdmmc_initialized = TRUE; 467 1.1 nisimura 468 1.1 nisimura return 1; 469 1.1 nisimura } 470 1.1 nisimura 471 1.1 nisimura int 472 1.1 nisimura sdmmc_enable(struct sdmmc_softc *sc) 473 1.1 nisimura { 474 1.1 nisimura uint32_t card_ocr; 475 1.1 nisimura uint32_t ocr = 0; 476 1.1 nisimura uint32_t host_ocr; 477 1.1 nisimura int error; 478 1.1 nisimura 479 1.1 nisimura /* 1. Set the maximum power supported by bus */ 480 1.1 nisimura /* For now, we expect the init function to set the maximum 481 1.1 nisimura voltage. And if that is not supported by the SD-card we 482 1.1 nisimura just cannot work with it. 483 1.1 nisimura */ 484 1.1 nisimura 485 1.1 nisimura sc->busclk = 400; 486 1.1 nisimura /* 2. Clock bus at minimum frequency */ 487 1.1 nisimura sc->sdifdv->bus_clock(sc->sdifdv->priv, 400); 488 1.1 nisimura 489 1.1 nisimura /* We expect that the above call has performed any waiting needed.*/ 490 1.1 nisimura 491 1.1 nisimura /* Initialize SD/MMC memory card(s), which is the only thing 492 1.1 nisimura we support. 493 1.1 nisimura */ 494 1.1 nisimura 495 1.1 nisimura /* Set host mode to SD "combo" card or SD memory-only. */ 496 1.1 nisimura SET(sc->flags, SMF_SD_MODE|SMF_MEM_MODE); 497 1.1 nisimura 498 1.1 nisimura sdmmc_go_idle_state(sc); 499 1.1 nisimura 500 1.1 nisimura error = sdmmc_mem_send_if_cond(sc, 0x1aa, &card_ocr); 501 1.1 nisimura if (error == 0 && card_ocr == 0x1aa) 502 1.1 nisimura SET(ocr, MMC_OCR_HCS); 503 1.1 nisimura 504 1.1 nisimura /* 505 1.1 nisimura * Read the SD/MMC memory OCR value by issuing CMD55 followed 506 1.1 nisimura * by ACMD41 to read the OCR value from memory-only SD cards. 507 1.1 nisimura * MMC cards will not respond to CMD55 or ACMD41 and this is 508 1.1 nisimura * how we distinguish them from SD cards. 509 1.1 nisimura */ 510 1.1 nisimura mmc_mode: 511 1.1 nisimura error = sdmmc_mem_send_op_cond(sc, 512 1.1 nisimura ISSET(sc->caps, SMC_CAPS_SPI_MODE) ? ocr : 0, &card_ocr); 513 1.1 nisimura if (error) { 514 1.1 nisimura if (ISSET(sc->flags, SMF_SD_MODE) && 515 1.1 nisimura !ISSET(sc->flags, SMF_IO_MODE)) { 516 1.1 nisimura /* Not a SD card, switch to MMC mode. */ 517 1.1 nisimura DPRINTF(("Switch to MMC mode\n")); 518 1.1 nisimura CLR(sc->flags, SMF_SD_MODE); 519 1.1 nisimura goto mmc_mode; 520 1.1 nisimura } 521 1.1 nisimura if (!ISSET(sc->flags, SMF_SD_MODE)) { 522 1.1 nisimura DPRINTF(("couldn't read memory OCR\n")); 523 1.1 nisimura goto out; 524 1.1 nisimura } else { 525 1.1 nisimura /* Not a "combo" card. */ 526 1.1 nisimura CLR(sc->flags, SMF_MEM_MODE); 527 1.1 nisimura error = 0; 528 1.1 nisimura goto out; 529 1.1 nisimura } 530 1.1 nisimura } 531 1.1 nisimura #if 0 /* SPI NOT SUPPORTED */ 532 1.1 nisimura if (ISSET(ssc->caps, SMC_CAPS_SPI_MODE)) { 533 1.1 nisimura /* get card OCR */ 534 1.1 nisimura error = sdmmc_mem_spi_read_ocr(sc, ocr, &card_ocr); 535 1.1 nisimura if (error) { 536 1.1 nisimura DPRINTF(("%s: couldn't read SPI memory OCR\n", 537 1.1 nisimura SDMMCDEVNAME(sc))); 538 1.1 nisimura goto out; 539 1.1 nisimura } 540 1.1 nisimura } 541 1.1 nisimura #endif 542 1.1 nisimura 543 1.1 nisimura /* Set the lowest voltage supported by the card and host. */ 544 1.1 nisimura host_ocr = sc->sdifdv->host_ocr(sc->sdifdv->priv); 545 1.1 nisimura error = sdmmc_set_bus_power(sc, host_ocr, card_ocr); 546 1.1 nisimura if (error) { 547 1.1 nisimura DPRINTF(("Couldn't supply voltage requested by card\n")); 548 1.1 nisimura goto out; 549 1.1 nisimura } 550 1.1 nisimura host_ocr &= card_ocr; 551 1.1 nisimura host_ocr |= ocr; 552 1.1 nisimura 553 1.1 nisimura /* Send the new OCR value until all cards are ready. */ 554 1.1 nisimura error = sdmmc_mem_send_op_cond(sc, host_ocr, NULL); 555 1.1 nisimura if (error) { 556 1.1 nisimura DPRINTF(("Couldn't send memory OCR\n")); 557 1.1 nisimura goto out; 558 1.1 nisimura } 559 1.1 nisimura 560 1.1 nisimura out: 561 1.1 nisimura return error; 562 1.1 nisimura } 563 1.1 nisimura 564 1.1 nisimura int 565 1.1 nisimura sdmmc_mem_send_if_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp) 566 1.1 nisimura { 567 1.1 nisimura struct sdmmc_command cmd; 568 1.1 nisimura int error; 569 1.1 nisimura 570 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 571 1.1 nisimura cmd.c_arg = ocr; 572 1.1 nisimura cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R7 | SCF_RSP_SPI_R7; 573 1.1 nisimura cmd.c_opcode = SD_SEND_IF_COND; 574 1.1 nisimura 575 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 576 1.1 nisimura if (error == 0 && ocrp != NULL) { 577 1.1 nisimura *ocrp = MMC_R7(cmd.c_resp); 578 1.1 nisimura } 579 1.1 nisimura 580 1.1 nisimura return error; 581 1.1 nisimura } 582 1.1 nisimura 583 1.1 nisimura void 584 1.1 nisimura sdmmc_go_idle_state(struct sdmmc_softc *sc) 585 1.1 nisimura { 586 1.1 nisimura struct sdmmc_command cmd; 587 1.1 nisimura 588 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 589 1.1 nisimura cmd.c_opcode = MMC_GO_IDLE_STATE; 590 1.1 nisimura cmd.c_flags = SCF_CMD_BC | SCF_RSP_R0 | SCF_RSP_SPI_R1; 591 1.1 nisimura 592 1.1 nisimura (void)sdmmc_mmc_command(sc, &cmd); 593 1.1 nisimura } 594 1.1 nisimura int 595 1.1 nisimura sdmmc_mem_send_op_cond(struct sdmmc_softc *sc, uint32_t ocr, uint32_t *ocrp) 596 1.1 nisimura { 597 1.1 nisimura struct sdmmc_command cmd; 598 1.1 nisimura int error; 599 1.1 nisimura int retry; 600 1.1 nisimura 601 1.1 nisimura 602 1.1 nisimura /* 603 1.1 nisimura * If we change the OCR value, retry the command until the OCR 604 1.1 nisimura * we receive in response has the "CARD BUSY" bit set, meaning 605 1.1 nisimura * that all cards are ready for identification. 606 1.1 nisimura */ 607 1.1 nisimura for (retry = 0; retry < 100; retry++) { 608 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 609 1.1 nisimura cmd.c_arg = !ISSET(sc->caps, SMC_CAPS_SPI_MODE) ? 610 1.1 nisimura ocr : (ocr & MMC_OCR_HCS); 611 1.1 nisimura cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3 | SCF_RSP_SPI_R1; 612 1.1 nisimura 613 1.1 nisimura if (ISSET(sc->flags, SMF_SD_MODE)) { 614 1.1 nisimura cmd.c_opcode = SD_APP_OP_COND; 615 1.1 nisimura error = sdmmc_app_command(sc, 0, &cmd); 616 1.1 nisimura } else { 617 1.1 nisimura cmd.c_opcode = MMC_SEND_OP_COND; 618 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 619 1.1 nisimura } 620 1.1 nisimura if (error) 621 1.1 nisimura break; 622 1.1 nisimura 623 1.1 nisimura if (ISSET(sc->caps, SMC_CAPS_SPI_MODE)) { 624 1.1 nisimura if (!ISSET(MMC_SPI_R1(cmd.c_resp), R1_SPI_IDLE)) 625 1.1 nisimura break; 626 1.1 nisimura } else { 627 1.1 nisimura if (ISSET(MMC_R3(cmd.c_resp), MMC_OCR_MEM_READY) || 628 1.1 nisimura ocr == 0) 629 1.1 nisimura break; 630 1.1 nisimura } 631 1.1 nisimura 632 1.1 nisimura error = ETIMEDOUT; 633 1.1 nisimura sdmmc_delay(10000); 634 1.1 nisimura } 635 1.1 nisimura if (error == 0 && 636 1.1 nisimura ocrp != NULL && 637 1.1 nisimura !ISSET(sc->caps, SMC_CAPS_SPI_MODE)) 638 1.1 nisimura *ocrp = MMC_R3(cmd.c_resp); 639 1.1 nisimura DPRINTF(("sdmmc_mem_send_op_cond: error=%d, ocr=%x\n", 640 1.1 nisimura error, MMC_R3(cmd.c_resp))); 641 1.1 nisimura return error; 642 1.1 nisimura } 643 1.1 nisimura 644 1.1 nisimura /* 645 1.1 nisimura * Set the lowest bus voltage supported by the card and the host. 646 1.1 nisimura */ 647 1.1 nisimura int 648 1.1 nisimura sdmmc_set_bus_power(struct sdmmc_softc *sc, uint32_t host_ocr, 649 1.1 nisimura uint32_t card_ocr) 650 1.1 nisimura { 651 1.1 nisimura uint32_t bit; 652 1.1 nisimura 653 1.1 nisimura /* Mask off unsupported voltage levels and select the lowest. */ 654 1.1 nisimura DPRINTF(("host_ocr=%x ", host_ocr)); 655 1.1 nisimura host_ocr &= card_ocr; 656 1.1 nisimura for (bit = 4; bit < 23; bit++) { 657 1.1 nisimura if (ISSET(host_ocr, (1 << bit))) { 658 1.1 nisimura host_ocr &= (3 << bit); 659 1.1 nisimura break; 660 1.1 nisimura } 661 1.1 nisimura } 662 1.1 nisimura DPRINTF(("card_ocr=%x new_ocr=%x\n", card_ocr, host_ocr)); 663 1.1 nisimura 664 1.1 nisimura if (host_ocr == 0 || 665 1.1 nisimura sc->sdifdv->bus_power(sc->sdifdv->priv, host_ocr) != 0) 666 1.1 nisimura return 1; 667 1.1 nisimura return 0; 668 1.1 nisimura } 669 1.1 nisimura 670 1.1 nisimura int 671 1.1 nisimura sdmmc_app_command(struct sdmmc_softc *sc, uint16_t rca, 672 1.1 nisimura struct sdmmc_command *cmd) 673 1.1 nisimura { 674 1.1 nisimura struct sdmmc_command acmd; 675 1.1 nisimura int error; 676 1.1 nisimura 677 1.1 nisimura memset(&acmd, 0, sizeof(acmd)); 678 1.1 nisimura acmd.c_opcode = MMC_APP_CMD; 679 1.1 nisimura if (rca != 0) { 680 1.1 nisimura acmd.c_arg = rca << 16; 681 1.1 nisimura acmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R1; 682 1.1 nisimura } else { 683 1.1 nisimura acmd.c_arg = 0; 684 1.1 nisimura acmd.c_flags = SCF_CMD_BCR | SCF_RSP_R1 | SCF_RSP_SPI_R1; 685 1.1 nisimura } 686 1.1 nisimura 687 1.1 nisimura error = sdmmc_mmc_command(sc, &acmd); 688 1.1 nisimura if (error == 0) { 689 1.1 nisimura if (!ISSET(sc->caps, SMC_CAPS_SPI_MODE) && 690 1.1 nisimura !ISSET(MMC_R1(acmd.c_resp), MMC_R1_APP_CMD)) { 691 1.1 nisimura /* Card does not support application commands. */ 692 1.1 nisimura error = ENODEV; 693 1.1 nisimura } else { 694 1.1 nisimura error = sdmmc_mmc_command(sc, cmd); 695 1.1 nisimura } 696 1.1 nisimura } 697 1.1 nisimura DPRINTF(("sdmmc_app_command: done (error=%d)\n", error)); 698 1.1 nisimura return error; 699 1.1 nisimura } 700 1.1 nisimura 701 1.1 nisimura void 702 1.1 nisimura sdmmc_dump_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd) 703 1.1 nisimura { 704 1.1 nisimura int i; 705 1.1 nisimura 706 1.1 nisimura printf("cmd %u arg=%x data=%p dlen=%d flags=%x (error %d)\n", 707 1.1 nisimura cmd->c_opcode, cmd->c_arg, cmd->c_data, 708 1.1 nisimura cmd->c_datalen, cmd->c_flags, cmd->c_error); 709 1.1 nisimura 710 1.1 nisimura if (cmd->c_error ) 711 1.1 nisimura return; 712 1.1 nisimura 713 1.1 nisimura printf("resp="); 714 1.1 nisimura if (ISSET(cmd->c_flags, SCF_RSP_136)) 715 1.1 nisimura for (i = 0; i < sizeof cmd->c_resp; i++) 716 1.1 nisimura printf("%02x ", ((uint8_t *)cmd->c_resp)[i]); 717 1.1 nisimura else if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) 718 1.1 nisimura for (i = 0; i < 4; i++) 719 1.1 nisimura printf("%02x ", ((uint8_t *)cmd->c_resp)[i]); 720 1.1 nisimura else 721 1.1 nisimura printf("none"); 722 1.1 nisimura printf("\n"); 723 1.1 nisimura } 724 1.1 nisimura 725 1.1 nisimura int 726 1.1 nisimura sdmmc_mmc_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd) 727 1.1 nisimura { 728 1.1 nisimura int error; 729 1.1 nisimura 730 1.1 nisimura DPRINTF(("sdmmc_mmc_command: cmd=%d, arg=%x, flags=%x\n", 731 1.1 nisimura cmd->c_opcode, cmd->c_arg, cmd->c_flags)); 732 1.1 nisimura 733 1.1 nisimura #if 0 734 1.1 nisimura #if defined(DIAGNOSTIC) || defined(SDMMC_DEBUG) 735 1.1 nisimura if (cmd->c_data && !ISSET(sc->caps, SMC_CAPS_SPI_MODE)) { 736 1.1 nisimura if (sc->sc_card == NULL) 737 1.1 nisimura panic("%s: deselected card\n", DEVNAME(sc)); 738 1.1 nisimura } 739 1.1 nisimura #endif 740 1.1 nisimura #endif 741 1.1 nisimura 742 1.1 nisimura sc->sdifdv->exec_cmd(sc->sdifdv->priv, cmd); 743 1.1 nisimura 744 1.1 nisimura #ifdef SDMMC_DEBUG 745 1.1 nisimura 746 1.1 nisimura sdmmc_dump_command(sc, cmd); 747 1.1 nisimura 748 1.1 nisimura #endif 749 1.1 nisimura 750 1.1 nisimura error = cmd->c_error; 751 1.1 nisimura 752 1.1 nisimura DPRINTF(("sdmmc_mmc_command: error=%d\n", error)); 753 1.1 nisimura 754 1.1 nisimura return error; 755 1.1 nisimura } 756 1.1 nisimura 757 1.1 nisimura /* 758 1.1 nisimura * Scan for I/O functions and memory cards on the bus, allocating a 759 1.1 nisimura * sdmmc_function structure for each. 760 1.1 nisimura */ 761 1.1 nisimura int 762 1.1 nisimura sdmmc_scan(struct sdmmc_softc *sc) 763 1.1 nisimura { 764 1.1 nisimura 765 1.1 nisimura #if 0 /* SPI NOT SUPPORTED */ 766 1.1 nisimura if (!ISSET(sc->caps, SMC_CAPS_SPI_MODE)) { 767 1.1 nisimura /* Scan for I/O functions. */ 768 1.1 nisimura if (ISSET(sc->sc_flags, SMF_IO_MODE)) 769 1.1 nisimura sdmmc_io_scan(sc); 770 1.1 nisimura } 771 1.1 nisimura #endif 772 1.1 nisimura 773 1.1 nisimura /* Scan for memory cards on the bus. */ 774 1.1 nisimura if (ISSET(sc->flags, SMF_MEM_MODE)) 775 1.1 nisimura sdmmc_mem_scan(sc); 776 1.1 nisimura 777 1.1 nisimura DPRINTF(("Bus clock speed: %d\n", sc->busclk)); 778 1.1 nisimura return sc->sdifdv->bus_clock(sc->sdifdv->priv, sc->busclk); 779 1.1 nisimura } 780 1.1 nisimura 781 1.1 nisimura /* 782 1.1 nisimura * Read the CSD and CID from all cards and assign each card a unique 783 1.1 nisimura * relative card address (RCA). CMD2 is ignored by SDIO-only cards. 784 1.1 nisimura */ 785 1.1 nisimura void 786 1.1 nisimura sdmmc_mem_scan(struct sdmmc_softc *sc) 787 1.1 nisimura { 788 1.1 nisimura sdmmc_response resp; 789 1.1 nisimura //struct sdmmc_function *sf; 790 1.1 nisimura // uint16_t next_rca; 791 1.1 nisimura int error; 792 1.1 nisimura int retry; 793 1.1 nisimura 794 1.1 nisimura /* 795 1.1 nisimura * CMD2 is a broadcast command understood by SD cards and MMC 796 1.1 nisimura * cards. All cards begin to respond to the command, but back 797 1.1 nisimura * off if another card drives the CMD line to a different level. 798 1.1 nisimura * Only one card will get its entire response through. That 799 1.1 nisimura * card remains silent once it has been assigned a RCA. 800 1.1 nisimura */ 801 1.1 nisimura for (retry = 0; retry < 100; retry++) { 802 1.1 nisimura error = sdmmc_mem_send_cid(sc, &resp); 803 1.1 nisimura if (error) { 804 1.1 nisimura if (!ISSET(sc->caps, SMC_CAPS_SPI_MODE) && 805 1.1 nisimura error == ETIMEDOUT) { 806 1.1 nisimura /* No more cards there. */ 807 1.1 nisimura break; 808 1.1 nisimura } 809 1.1 nisimura DPRINTF(("Couldn't read CID\n")); 810 1.1 nisimura break; 811 1.1 nisimura } 812 1.1 nisimura 813 1.1 nisimura /* In MMC mode, find the next available RCA. */ 814 1.1 nisimura /*next_rca = 1; 815 1.1 nisimura if (!ISSET(dv->flags, SMF_SD_MODE)) { 816 1.1 nisimura SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) 817 1.1 nisimura next_rca++; 818 1.1 nisimura }*/ 819 1.1 nisimura 820 1.1 nisimura /* Allocate a sdmmc_function structure. */ 821 1.1 nisimura /*sf = sdmmc_function_alloc(sc); 822 1.1 nisimura sf->rca = next_rca;*/ 823 1.1 nisimura 824 1.1 nisimura /* 825 1.1 nisimura * Remember the CID returned in the CMD2 response for 826 1.1 nisimura * later decoding. 827 1.1 nisimura */ 828 1.1 nisimura memcpy(sc->raw_cid, resp, sizeof(sc->raw_cid)); 829 1.1 nisimura 830 1.1 nisimura /* 831 1.1 nisimura * Silence the card by assigning it a unique RCA, or 832 1.1 nisimura * querying it for its RCA in the case of SD. 833 1.1 nisimura */ 834 1.1 nisimura if (!ISSET(sc->caps, SMC_CAPS_SPI_MODE)) { 835 1.1 nisimura if (sdmmc_set_relative_addr(sc) != 0) { 836 1.1 nisimura DPRINTF(("couldn't set mem RCA\n")); 837 1.1 nisimura break; 838 1.1 nisimura } 839 1.1 nisimura } 840 1.1 nisimura 841 1.1 nisimura /* 842 1.1 nisimura * If this is a memory-only card, the card responding 843 1.1 nisimura * first becomes an alias for SDIO function 0. 844 1.1 nisimura */ 845 1.1 nisimura /*if (sc->sc_fn0 == NULL) 846 1.1 nisimura sc->sc_fn0 = sf; 847 1.1 nisimura 848 1.1 nisimura SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list);*/ 849 1.1 nisimura 850 1.1 nisimura /* only one function in SPI mode */ 851 1.1 nisimura /*if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) 852 1.1 nisimura break;*/ 853 1.1 nisimura } 854 1.1 nisimura 855 1.1 nisimura /* 856 1.1 nisimura * All cards are either inactive or awaiting further commands. 857 1.1 nisimura * Read the CSDs and decode the raw CID for each card. 858 1.1 nisimura */ 859 1.1 nisimura /* SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {*/ 860 1.1 nisimura error = sdmmc_mem_send_csd(sc, &resp); 861 1.1 nisimura if (error) { 862 1.1 nisimura /*SET(sf->flags, SFF_ERROR); 863 1.1 nisimura continue;*/ 864 1.1 nisimura } 865 1.1 nisimura 866 1.1 nisimura if (sdmmc_decode_csd(sc, resp) != 0 || 867 1.1 nisimura sdmmc_decode_cid(sc, sc->raw_cid) != 0) { 868 1.1 nisimura /*SET(sf->flags, SFF_ERROR); 869 1.1 nisimura continue;*/ 870 1.1 nisimura } 871 1.1 nisimura 872 1.1 nisimura #ifdef SDMMC_DEBUG 873 1.1 nisimura printf("CID: "); 874 1.1 nisimura sdmmc_print_cid(&sc->cid); 875 1.1 nisimura #endif 876 1.1 nisimura /* }*/ 877 1.1 nisimura } 878 1.1 nisimura 879 1.1 nisimura /* 880 1.1 nisimura * Retrieve (SD) or set (MMC) the relative card address (RCA). 881 1.1 nisimura */ 882 1.1 nisimura int 883 1.1 nisimura sdmmc_set_relative_addr(struct sdmmc_softc *sc) 884 1.1 nisimura { 885 1.1 nisimura struct sdmmc_command cmd; 886 1.1 nisimura int error; 887 1.1 nisimura 888 1.1 nisimura /* Don't lock */ 889 1.1 nisimura 890 1.1 nisimura if (ISSET(sc->caps, SMC_CAPS_SPI_MODE)) 891 1.1 nisimura return EIO; 892 1.1 nisimura 893 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 894 1.1 nisimura if (ISSET(sc->flags, SMF_SD_MODE)) { 895 1.1 nisimura cmd.c_opcode = SD_SEND_RELATIVE_ADDR; 896 1.1 nisimura cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R6; 897 1.1 nisimura } else { 898 1.1 nisimura cmd.c_opcode = MMC_SET_RELATIVE_ADDR; 899 1.1 nisimura cmd.c_arg = MMC_ARG_RCA(sc->rca); 900 1.1 nisimura cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1; 901 1.1 nisimura } 902 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 903 1.1 nisimura if (error) 904 1.1 nisimura return error; 905 1.1 nisimura 906 1.1 nisimura if (ISSET(sc->flags, SMF_SD_MODE)) 907 1.1 nisimura sc->rca = SD_R6_RCA(cmd.c_resp); 908 1.1 nisimura 909 1.1 nisimura return 0; 910 1.1 nisimura } 911 1.1 nisimura 912 1.1 nisimura int 913 1.1 nisimura sdmmc_mem_send_cid(struct sdmmc_softc *sc, sdmmc_response *resp) 914 1.1 nisimura { 915 1.1 nisimura struct sdmmc_command cmd; 916 1.1 nisimura int error; 917 1.1 nisimura 918 1.1 nisimura 919 1.1 nisimura memset(&cmd, 0, sizeof cmd); 920 1.1 nisimura cmd.c_opcode = MMC_ALL_SEND_CID; 921 1.1 nisimura cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R2; 922 1.1 nisimura 923 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 924 1.1 nisimura 925 1.1 nisimura #ifdef SDMMC_DEBUG 926 1.1 nisimura sdmmc_dump_data("CID", cmd.c_resp, sizeof(cmd.c_resp)); 927 1.1 nisimura #endif 928 1.1 nisimura if (error == 0 && resp != NULL) 929 1.1 nisimura memcpy(resp, &cmd.c_resp, sizeof(*resp)); 930 1.1 nisimura return error; 931 1.1 nisimura } 932 1.1 nisimura 933 1.1 nisimura void 934 1.1 nisimura sdmmc_dump_data(const char *title, void *ptr, size_t size) 935 1.1 nisimura { 936 1.1 nisimura char buf[16]; 937 1.1 nisimura uint8_t *p = ptr; 938 1.1 nisimura int i, j; 939 1.1 nisimura 940 1.1 nisimura printf("sdmmc_dump_data: %s\n", title ? title : ""); 941 1.1 nisimura printf("--------+--------------------------------------------------+------------------+\n"); 942 1.1 nisimura printf("offset | +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f | data |\n"); 943 1.1 nisimura printf("--------+--------------------------------------------------+------------------+\n"); 944 1.1 nisimura for (i = 0; i < (int)size; i++) { 945 1.1 nisimura if ((i % 16) == 0) { 946 1.1 nisimura printf("%08x| ", i); 947 1.1 nisimura } else if ((i % 16) == 8) { 948 1.1 nisimura printf(" "); 949 1.1 nisimura } 950 1.1 nisimura 951 1.1 nisimura printf("%02x ", p[i]); 952 1.1 nisimura buf[i % 16] = p[i]; 953 1.1 nisimura 954 1.1 nisimura if ((i % 16) == 15) { 955 1.1 nisimura printf("| "); 956 1.1 nisimura for (j = 0; j < 16; j++) { 957 1.1 nisimura if (buf[j] >= 0x20 && buf[j] <= 0x7e) { 958 1.1 nisimura printf("%c", buf[j]); 959 1.1 nisimura } else { 960 1.1 nisimura printf("."); 961 1.1 nisimura } 962 1.1 nisimura } 963 1.1 nisimura printf(" |\n"); 964 1.1 nisimura } 965 1.1 nisimura } 966 1.1 nisimura if ((i % 16) != 0) { 967 1.1 nisimura j = (i % 16); 968 1.1 nisimura for (; j < 16; j++) { 969 1.1 nisimura printf(" "); 970 1.1 nisimura if ((j % 16) == 8) { 971 1.1 nisimura printf(" "); 972 1.1 nisimura } 973 1.1 nisimura } 974 1.1 nisimura 975 1.1 nisimura printf("| "); 976 1.1 nisimura for (j = 0; j < (i % 16); j++) { 977 1.1 nisimura if (buf[j] >= 0x20 && buf[j] <= 0x7e) { 978 1.1 nisimura printf("%c", buf[j]); 979 1.1 nisimura } else { 980 1.1 nisimura printf("."); 981 1.1 nisimura } 982 1.1 nisimura } 983 1.1 nisimura for (; j < 16; j++) { 984 1.1 nisimura printf(" "); 985 1.1 nisimura } 986 1.1 nisimura printf(" |\n"); 987 1.1 nisimura } 988 1.1 nisimura printf("--------+--------------------------------------------------+------------------+\n"); 989 1.1 nisimura } 990 1.1 nisimura 991 1.1 nisimura int 992 1.1 nisimura sdmmc_mem_send_csd(struct sdmmc_softc *sc, sdmmc_response *resp) 993 1.1 nisimura { 994 1.1 nisimura struct sdmmc_command cmd; 995 1.1 nisimura int error; 996 1.1 nisimura 997 1.1 nisimura memset(&cmd, 0, sizeof cmd); 998 1.1 nisimura cmd.c_opcode = MMC_SEND_CSD; 999 1.1 nisimura cmd.c_arg = MMC_ARG_RCA(sc->rca); 1000 1.1 nisimura cmd.c_flags = SCF_CMD_AC | SCF_RSP_R2; 1001 1.1 nisimura 1002 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 1003 1.1 nisimura 1004 1.1 nisimura #ifdef SDMMC_DEBUG 1005 1.1 nisimura sdmmc_dump_data("CSD", cmd.c_resp, sizeof(cmd.c_resp)); 1006 1.1 nisimura #endif 1007 1.1 nisimura if (error == 0 && resp != NULL) 1008 1.1 nisimura memcpy(resp, &cmd.c_resp, sizeof(*resp)); 1009 1.1 nisimura return error; 1010 1.1 nisimura } 1011 1.1 nisimura 1012 1.1 nisimura int 1013 1.1 nisimura sdmmc_decode_csd(struct sdmmc_softc *sc, sdmmc_response resp) 1014 1.1 nisimura { 1015 1.1 nisimura /* TRAN_SPEED(2:0): transfer rate exponent */ 1016 1.1 nisimura static const int speed_exponent[8] = { 1017 1.1 nisimura 100 * 1, /* 100 Kbits/s */ 1018 1.1 nisimura 1 * 1000, /* 1 Mbits/s */ 1019 1.1 nisimura 10 * 1000, /* 10 Mbits/s */ 1020 1.1 nisimura 100 * 1000, /* 100 Mbits/s */ 1021 1.1 nisimura 0, 1022 1.1 nisimura 0, 1023 1.1 nisimura 0, 1024 1.1 nisimura 0, 1025 1.1 nisimura }; 1026 1.1 nisimura /* TRAN_SPEED(6:3): time mantissa */ 1027 1.1 nisimura static const int speed_mantissa[16] = { 1028 1.1 nisimura 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 1029 1.1 nisimura }; 1030 1.1 nisimura struct sdmmc_csd *csd = &sc->csd; 1031 1.1 nisimura int e, m; 1032 1.1 nisimura 1033 1.1 nisimura if (ISSET(sc->flags, SMF_SD_MODE)) { 1034 1.1 nisimura /* 1035 1.1 nisimura * CSD version 1.0 corresponds to SD system 1036 1.1 nisimura * specification version 1.0 - 1.10. (SanDisk, 3.5.3) 1037 1.1 nisimura */ 1038 1.1 nisimura csd->csdver = SD_CSD_CSDVER(resp); 1039 1.1 nisimura switch (csd->csdver) { 1040 1.1 nisimura case SD_CSD_CSDVER_2_0: 1041 1.1 nisimura DPRINTF(("SD Ver.2.0\n")); 1042 1.1 nisimura SET(sc->flags, SMF_CARD_SDHC); 1043 1.1 nisimura csd->capacity = SD_CSD_V2_CAPACITY(resp); 1044 1.1 nisimura csd->read_bl_len = SD_CSD_V2_BL_LEN; 1045 1.1 nisimura csd->ccc = SD_CSD_CCC(resp); 1046 1.1 nisimura break; 1047 1.1 nisimura 1048 1.1 nisimura case SD_CSD_CSDVER_1_0: 1049 1.1 nisimura DPRINTF(("SD Ver.1.0\n")); 1050 1.1 nisimura csd->capacity = SD_CSD_CAPACITY(resp); 1051 1.1 nisimura csd->read_bl_len = SD_CSD_READ_BL_LEN(resp); 1052 1.1 nisimura break; 1053 1.1 nisimura 1054 1.1 nisimura default: 1055 1.1 nisimura printf("unknown SD CSD structure version 0x%x\n", 1056 1.1 nisimura csd->csdver); 1057 1.1 nisimura return 1; 1058 1.1 nisimura } 1059 1.1 nisimura 1060 1.1 nisimura csd->mmcver = SD_CSD_MMCVER(resp); 1061 1.1 nisimura csd->write_bl_len = SD_CSD_WRITE_BL_LEN(resp); 1062 1.1 nisimura csd->r2w_factor = SD_CSD_R2W_FACTOR(resp); 1063 1.1 nisimura e = SD_CSD_SPEED_EXP(resp); 1064 1.1 nisimura m = SD_CSD_SPEED_MANT(resp); 1065 1.1 nisimura csd->tran_speed = speed_exponent[e] * speed_mantissa[m] / 10; 1066 1.1 nisimura } else { 1067 1.1 nisimura csd->csdver = MMC_CSD_CSDVER(resp); 1068 1.1 nisimura if (csd->csdver == MMC_CSD_CSDVER_1_0 ) { 1069 1.1 nisimura printf("unknown MMC CSD structure version 0x%x\n", 1070 1.1 nisimura csd->csdver); 1071 1.1 nisimura return 1; 1072 1.1 nisimura } 1073 1.1 nisimura 1074 1.1 nisimura csd->mmcver = MMC_CSD_MMCVER(resp); 1075 1.1 nisimura csd->capacity = MMC_CSD_CAPACITY(resp); 1076 1.1 nisimura csd->read_bl_len = MMC_CSD_READ_BL_LEN(resp); 1077 1.1 nisimura csd->write_bl_len = MMC_CSD_WRITE_BL_LEN(resp); 1078 1.1 nisimura csd->r2w_factor = MMC_CSD_R2W_FACTOR(resp); 1079 1.1 nisimura e = MMC_CSD_TRAN_SPEED_EXP(resp); 1080 1.1 nisimura m = MMC_CSD_TRAN_SPEED_MANT(resp); 1081 1.1 nisimura csd->tran_speed = speed_exponent[e] * speed_mantissa[m] / 10; 1082 1.1 nisimura } 1083 1.1 nisimura if ((1 << csd->read_bl_len) > SDMMC_SECTOR_SIZE) 1084 1.1 nisimura csd->capacity *= (1 << csd->read_bl_len) / SDMMC_SECTOR_SIZE; 1085 1.1 nisimura 1086 1.1 nisimura 1087 1.1 nisimura if (sc->busclk > csd->tran_speed) 1088 1.1 nisimura sc->busclk = csd->tran_speed; 1089 1.1 nisimura 1090 1.1 nisimura #ifdef SDMMC_DUMP_CSD 1091 1.1 nisimura sdmmc_print_csd(resp, csd); 1092 1.1 nisimura #endif 1093 1.1 nisimura 1094 1.1 nisimura return 0; 1095 1.1 nisimura } 1096 1.1 nisimura 1097 1.1 nisimura int 1098 1.1 nisimura sdmmc_decode_cid(struct sdmmc_softc *sc, sdmmc_response resp) 1099 1.1 nisimura { 1100 1.1 nisimura struct sdmmc_cid *cid = &sc->cid; 1101 1.1 nisimura 1102 1.1 nisimura if (ISSET(sc->flags, SMF_SD_MODE)) { 1103 1.1 nisimura cid->mid = SD_CID_MID(resp); 1104 1.1 nisimura cid->oid = SD_CID_OID(resp); 1105 1.1 nisimura SD_CID_PNM_CPY(resp, cid->pnm); 1106 1.1 nisimura cid->rev = SD_CID_REV(resp); 1107 1.1 nisimura cid->psn = SD_CID_PSN(resp); 1108 1.1 nisimura cid->mdt = SD_CID_MDT(resp); 1109 1.1 nisimura } else { 1110 1.1 nisimura switch(sc->csd.mmcver) { 1111 1.1 nisimura case MMC_CSD_MMCVER_1_0: 1112 1.1 nisimura case MMC_CSD_MMCVER_1_4: 1113 1.1 nisimura cid->mid = MMC_CID_MID_V1(resp); 1114 1.1 nisimura MMC_CID_PNM_V1_CPY(resp, cid->pnm); 1115 1.1 nisimura cid->rev = MMC_CID_REV_V1(resp); 1116 1.1 nisimura cid->psn = MMC_CID_PSN_V1(resp); 1117 1.1 nisimura cid->mdt = MMC_CID_MDT_V1(resp); 1118 1.1 nisimura break; 1119 1.1 nisimura case MMC_CSD_MMCVER_2_0: 1120 1.1 nisimura case MMC_CSD_MMCVER_3_1: 1121 1.1 nisimura case MMC_CSD_MMCVER_4_0: 1122 1.1 nisimura cid->mid = MMC_CID_MID_V2(resp); 1123 1.1 nisimura cid->oid = MMC_CID_OID_V2(resp); 1124 1.1 nisimura MMC_CID_PNM_V2_CPY(resp, cid->pnm); 1125 1.1 nisimura cid->psn = MMC_CID_PSN_V2(resp); 1126 1.1 nisimura break; 1127 1.1 nisimura default: 1128 1.1 nisimura printf("unknown MMC version %d\n", 1129 1.1 nisimura sc->csd.mmcver); 1130 1.1 nisimura return 1; 1131 1.1 nisimura } 1132 1.1 nisimura } 1133 1.1 nisimura return 0; 1134 1.1 nisimura } 1135 1.1 nisimura 1136 1.1 nisimura void 1137 1.1 nisimura sdmmc_print_cid(struct sdmmc_cid *cid) 1138 1.1 nisimura { 1139 1.1 nisimura 1140 1.1 nisimura printf("mid=0x%02x oid=0x%04x pnm=\"%s\" rev=0x%02x psn=0x%08x" 1141 1.1 nisimura " mdt=%03x\n", cid->mid, cid->oid, cid->pnm, cid->rev, cid->psn, 1142 1.1 nisimura cid->mdt); 1143 1.1 nisimura } 1144 1.1 nisimura 1145 1.1 nisimura int 1146 1.1 nisimura sdmmc_mem_read_block(struct sdmmc_softc *sc, uint32_t blkno, 1147 1.1 nisimura u_char *data, size_t datalen) 1148 1.1 nisimura { 1149 1.1 nisimura struct sdmmc_command cmd; 1150 1.1 nisimura int error; 1151 1.1 nisimura 1152 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 1153 1.1 nisimura cmd.c_data = data; 1154 1.1 nisimura cmd.c_datalen = datalen; 1155 1.1 nisimura cmd.c_blklen = SDMMC_SECTOR_SIZE; 1156 1.1 nisimura cmd.c_opcode = (cmd.c_datalen / cmd.c_blklen) > 1 ? 1157 1.1 nisimura MMC_READ_BLOCK_MULTIPLE : MMC_READ_BLOCK_SINGLE; 1158 1.1 nisimura cmd.c_arg = blkno; 1159 1.1 nisimura if (!ISSET(sc->flags, SMF_CARD_SDHC)) 1160 1.1 nisimura cmd.c_arg <<= SDMMC_SECTOR_SIZE_SB; 1161 1.1 nisimura DPRINTF(("Reading block %d (%d)\n", blkno, cmd.c_arg)); 1162 1.1 nisimura cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1 | SCF_RSP_SPI_R1; 1163 1.1 nisimura 1164 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 1165 1.1 nisimura if (error) 1166 1.1 nisimura goto out; 1167 1.1 nisimura 1168 1.1 nisimura if (!ISSET(sc->caps, SMC_CAPS_AUTO_STOP)) { 1169 1.1 nisimura if (cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE) { 1170 1.1 nisimura memset(&cmd, 0, sizeof cmd); 1171 1.1 nisimura cmd.c_opcode = MMC_STOP_TRANSMISSION; 1172 1.1 nisimura cmd.c_arg = MMC_ARG_RCA(sc->rca); 1173 1.1 nisimura cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B | SCF_RSP_SPI_R1B; 1174 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 1175 1.1 nisimura if (error) 1176 1.1 nisimura goto out; 1177 1.1 nisimura } 1178 1.1 nisimura } 1179 1.1 nisimura 1180 1.1 nisimura /*if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {*/ 1181 1.1 nisimura do { 1182 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 1183 1.1 nisimura cmd.c_opcode = MMC_SEND_STATUS; 1184 1.1 nisimura cmd.c_arg = MMC_ARG_RCA(sc->rca); 1185 1.1 nisimura cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R2; 1186 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 1187 1.1 nisimura if (error) 1188 1.1 nisimura break; 1189 1.1 nisimura /* XXX time out */ 1190 1.1 nisimura } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)); 1191 1.1 nisimura /*}*/ 1192 1.1 nisimura 1193 1.1 nisimura out: 1194 1.1 nisimura return error; 1195 1.1 nisimura } 1196 1.1 nisimura 1197 1.1 nisimura int 1198 1.1 nisimura sdmmc_select_card(struct sdmmc_softc *sc) 1199 1.1 nisimura { 1200 1.1 nisimura struct sdmmc_command cmd; 1201 1.1 nisimura int error; 1202 1.1 nisimura 1203 1.1 nisimura /* Don't lock */ 1204 1.1 nisimura 1205 1.1 nisimura /* if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) 1206 1.1 nisimura return EIO;*/ 1207 1.1 nisimura 1208 1.1 nisimura /*if (sc->sc_card == sf 1209 1.1 nisimura || (sf && sc->sc_card && sc->sc_card->rca == sf->rca)) { 1210 1.1 nisimura sc->sc_card = sf; 1211 1.1 nisimura return 0; 1212 1.1 nisimura }*/ 1213 1.1 nisimura 1214 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 1215 1.1 nisimura cmd.c_opcode = MMC_SELECT_CARD; 1216 1.1 nisimura cmd.c_arg = (sc == NULL) ? 0 : MMC_ARG_RCA(sc->rca); 1217 1.1 nisimura cmd.c_flags = SCF_CMD_AC | ((sc == NULL) ? SCF_RSP_R0 : SCF_RSP_R1); 1218 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 1219 1.1 nisimura /*if (error == 0 || sf == NULL) 1220 1.1 nisimura sc->sc_card = sf;*/ 1221 1.1 nisimura 1222 1.1 nisimura return error; 1223 1.1 nisimura } 1224 1.1 nisimura 1225 1.1 nisimura /* 1226 1.1 nisimura * Set the read block length appropriately for this card, according to 1227 1.1 nisimura * the card CSD register value. 1228 1.1 nisimura */ 1229 1.1 nisimura int 1230 1.1 nisimura sdmmc_mem_set_blocklen(struct sdmmc_softc *sc) 1231 1.1 nisimura { 1232 1.1 nisimura struct sdmmc_command cmd; 1233 1.1 nisimura int error; 1234 1.1 nisimura 1235 1.1 nisimura /* Don't lock */ 1236 1.1 nisimura 1237 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 1238 1.1 nisimura cmd.c_opcode = MMC_SET_BLOCKLEN; 1239 1.1 nisimura cmd.c_arg = SDMMC_SECTOR_SIZE; 1240 1.1 nisimura cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R1; 1241 1.1 nisimura 1242 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 1243 1.1 nisimura 1244 1.1 nisimura DPRINTF(("sdmmc_mem_set_blocklen: read_bl_len=%d sector_size=%d\n", 1245 1.1 nisimura 1 << sc->csd.read_bl_len, SDMMC_SECTOR_SIZE)); 1246 1.1 nisimura 1247 1.1 nisimura return error; 1248 1.1 nisimura } 1249 1.1 nisimura 1250 1.1 nisimura int 1251 1.1 nisimura sdmmc_mem_send_scr(struct sdmmc_softc *sc, uint32_t scr[2]) 1252 1.1 nisimura { 1253 1.1 nisimura struct sdmmc_command cmd; 1254 1.1 nisimura void *ptr = NULL; 1255 1.1 nisimura int datalen = 8; 1256 1.1 nisimura int error = 0; 1257 1.1 nisimura 1258 1.1 nisimura ptr = alloc(datalen); //malloc(datalen, M_DEVBUF, M_NOWAIT | M_ZERO); 1259 1.1 nisimura if (ptr == NULL) 1260 1.1 nisimura goto out; 1261 1.1 nisimura 1262 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 1263 1.1 nisimura cmd.c_data = ptr; 1264 1.1 nisimura cmd.c_datalen = datalen; 1265 1.1 nisimura cmd.c_blklen = datalen; 1266 1.1 nisimura cmd.c_arg = 0; 1267 1.1 nisimura cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1 | SCF_RSP_SPI_R1; 1268 1.1 nisimura cmd.c_opcode = SD_APP_SEND_SCR; 1269 1.1 nisimura 1270 1.1 nisimura error = sdmmc_app_command(sc, sc->rca, &cmd); 1271 1.1 nisimura if (error == 0) { 1272 1.1 nisimura memcpy(scr, ptr, datalen); 1273 1.1 nisimura } 1274 1.1 nisimura 1275 1.1 nisimura out: 1276 1.1 nisimura if (ptr != NULL) { 1277 1.1 nisimura dealloc(ptr, datalen); 1278 1.1 nisimura } 1279 1.1 nisimura DPRINTF(("sdmem_mem_send_scr: error = %d\n", 1280 1.1 nisimura error)); 1281 1.1 nisimura if (error) 1282 1.1 nisimura return error; 1283 1.1 nisimura #ifdef SDMMC_DEBUG 1284 1.1 nisimura sdmmc_dump_data("SCR", scr, 8); 1285 1.1 nisimura #endif 1286 1.1 nisimura return error; 1287 1.1 nisimura } 1288 1.1 nisimura 1289 1.1 nisimura int 1290 1.1 nisimura sdmmc_mem_decode_scr(struct sdmmc_softc *sc) 1291 1.1 nisimura { 1292 1.1 nisimura sdmmc_response resp; 1293 1.1 nisimura int ver; 1294 1.1 nisimura 1295 1.1 nisimura memset(resp, 0, sizeof(resp)); 1296 1.1 nisimura /*resp[0] = sc->raw_scr[1]; 1297 1.1 nisimura resp[1] = sc->raw_scr[0];*/ 1298 1.1 nisimura /* 1299 1.1 nisimura * Change the raw-scr received from the DMA stream to resp. 1300 1.1 nisimura */ 1301 1.1 nisimura resp[0] = be32toh(sc->raw_scr[1]) >> 8; // LSW 1302 1.1 nisimura resp[1] = be32toh(sc->raw_scr[0]); // MSW 1303 1.1 nisimura resp[0] |= (resp[1] & 0xff) << 24; 1304 1.1 nisimura resp[1] >>= 8; 1305 1.1 nisimura resp[0] = htole32(resp[0]); 1306 1.1 nisimura resp[1] = htole32(resp[1]); 1307 1.1 nisimura 1308 1.1 nisimura ver = SCR_STRUCTURE(resp); 1309 1.1 nisimura sc->scr.sd_spec = SCR_SD_SPEC(resp); 1310 1.1 nisimura sc->scr.bus_width = SCR_SD_BUS_WIDTHS(resp); 1311 1.1 nisimura 1312 1.1 nisimura DPRINTF(("sdmmc_mem_decode_scr: spec=%d, bus width=%d\n", 1313 1.1 nisimura sc->scr.sd_spec, sc->scr.bus_width)); 1314 1.1 nisimura 1315 1.1 nisimura if (ver != 0) { 1316 1.1 nisimura DPRINTF(("unknown structure version: %d\n", 1317 1.1 nisimura ver)); 1318 1.1 nisimura return EINVAL; 1319 1.1 nisimura } 1320 1.1 nisimura return 0; 1321 1.1 nisimura } 1322 1.1 nisimura 1323 1.1 nisimura int 1324 1.1 nisimura sdmmc_set_bus_width(struct sdmmc_softc *sc, int width) 1325 1.1 nisimura { 1326 1.1 nisimura struct sdmmc_command cmd; 1327 1.1 nisimura int error; 1328 1.1 nisimura 1329 1.1 nisimura if (ISSET(sc->caps, SMC_CAPS_SPI_MODE)) 1330 1.1 nisimura return ENODEV; 1331 1.1 nisimura 1332 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 1333 1.1 nisimura cmd.c_opcode = SD_APP_SET_BUS_WIDTH; 1334 1.1 nisimura cmd.c_flags = SCF_RSP_R1 | SCF_CMD_AC; 1335 1.1 nisimura 1336 1.1 nisimura switch (width) { 1337 1.1 nisimura case 1: 1338 1.1 nisimura cmd.c_arg = SD_ARG_BUS_WIDTH_1; 1339 1.1 nisimura break; 1340 1.1 nisimura 1341 1.1 nisimura case 4: 1342 1.1 nisimura cmd.c_arg = SD_ARG_BUS_WIDTH_4; 1343 1.1 nisimura break; 1344 1.1 nisimura 1345 1.1 nisimura default: 1346 1.1 nisimura return EINVAL; 1347 1.1 nisimura } 1348 1.1 nisimura 1349 1.1 nisimura error = sdmmc_app_command(sc, sc->rca, &cmd); 1350 1.1 nisimura if (error == 0) 1351 1.1 nisimura error = sc->sdifdv->bus_width(sc->sdifdv->priv, width); 1352 1.1 nisimura return error; 1353 1.1 nisimura } 1354 1.1 nisimura 1355 1.1 nisimura #if 1 1356 1.1 nisimura static int 1357 1.1 nisimura sdmmc_mem_sd_switch(struct sdmmc_softc *sc, int mode, int group, 1358 1.1 nisimura int function, void *status) 1359 1.1 nisimura { 1360 1.1 nisimura struct sdmmc_command cmd; 1361 1.1 nisimura void *ptr = NULL; 1362 1.1 nisimura int gsft, error = 0; 1363 1.1 nisimura const int statlen = 64; 1364 1.1 nisimura 1365 1.1 nisimura if (sc->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 && 1366 1.1 nisimura !ISSET(sc->csd.ccc, SD_CSD_CCC_SWITCH)) 1367 1.1 nisimura return EINVAL; 1368 1.1 nisimura 1369 1.1 nisimura if (group <= 0 || group > 6 || 1370 1.1 nisimura function < 0 || function > 16) 1371 1.1 nisimura return EINVAL; 1372 1.1 nisimura 1373 1.1 nisimura gsft = (group - 1) << 2; 1374 1.1 nisimura 1375 1.1 nisimura ptr = alloc(statlen); 1376 1.1 nisimura if (ptr == NULL) 1377 1.1 nisimura goto out; 1378 1.1 nisimura 1379 1.1 nisimura memset(&cmd, 0, sizeof(cmd)); 1380 1.1 nisimura cmd.c_data = ptr; 1381 1.1 nisimura cmd.c_datalen = statlen; 1382 1.1 nisimura cmd.c_blklen = statlen; 1383 1.1 nisimura cmd.c_opcode = SD_SEND_SWITCH_FUNC; 1384 1.1 nisimura cmd.c_arg = 1385 1.1 nisimura (!!mode << 31) | (function << gsft) | (0x00ffffff & ~(0xf << gsft)); 1386 1.1 nisimura cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1 | SCF_RSP_SPI_R1; 1387 1.1 nisimura 1388 1.1 nisimura error = sdmmc_mmc_command(sc, &cmd); 1389 1.1 nisimura if (error == 0) { 1390 1.1 nisimura memcpy(status, ptr, statlen); 1391 1.1 nisimura } 1392 1.1 nisimura 1393 1.1 nisimura out: 1394 1.1 nisimura if (ptr != NULL) { 1395 1.1 nisimura dealloc(ptr, statlen); 1396 1.1 nisimura } 1397 1.1 nisimura return error; 1398 1.1 nisimura } 1399 1.1 nisimura #endif 1400