1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #ifndef _SYS_SDCARD_SDA_H 26 #define _SYS_SDCARD_SDA_H 27 28 #include <sys/types.h> 29 #include <sys/note.h> 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 /* 36 * SD card common framework. This module provides most of the common 37 * functionality so that SecureDigital host adapters and client devices 38 * (such as the sdmem driver) can share common code. 39 */ 40 41 /* 42 * SD Commands. Commmand format is 48-bits as follows: 43 * 44 * bits value desc 45 * ------------------------------------------- 46 * 47 0 start bit 47 * 46 1 transmission bit 48 * 45:40 cmd command index (see values listed below) 49 * 39:8 arg 32-bit command argument 50 * 7:1 crc7 crc7 check value 51 * 0 1 end bit 52 * ------------------------------------------- 53 */ 54 typedef enum { 55 CMD_GO_IDLE = 0, 56 CMD_SEND_OCR = 1, /* MMC only */ 57 CMD_BCAST_CID = 2, 58 CMD_SEND_RCA = 3, 59 CMD_SET_DSR = 4, 60 CMD_IO_SEND_OCR = 5, /* SDIO only */ 61 CMD_SWITCH_FUNC = 6, 62 CMD_SELECT_CARD = 7, 63 CMD_SEND_IF_COND = 8, 64 CMD_SEND_CSD = 9, 65 CMD_SEND_CID = 10, 66 CMD_STOP_TRANSMIT = 12, 67 CMD_SEND_STATUS = 13, 68 CMD_GO_INACTIVE = 15, 69 CMD_SET_BLOCKLEN = 16, 70 CMD_READ_SINGLE = 17, 71 CMD_READ_MULTI = 18, 72 CMD_WRITE_SINGLE = 24, 73 CMD_WRITE_MULTI = 25, 74 CMD_PROGRAM_CSD = 27, 75 CMD_SET_WRITE_PROT = 28, 76 CMD_CLR_WRITE_PROT = 29, 77 CMD_SEND_WRITE_PROT = 30, 78 CMD_ERASE_START = 32, 79 CMD_ERASE_END = 33, 80 CMD_ERASE = 38, 81 CMD_LOCK = 42, 82 CMD_IO_RW_DIRECT = 52, 83 CMD_IO_RW_EXTENDED = 53, 84 CMD_APP_CMD = 55, 85 CMD_GEN_CMD = 56, 86 /* APP CMD values, send ACMD first */ 87 ACMD_SET_BUS_WIDTH = 6, 88 ACMD_SD_STATUS = 13, 89 ACMD_SEND_NUM_WR_BLKS = 22, 90 ACMD_SET_WR_BLK_ERASE_COUNT = 23, 91 ACMD_SD_SEND_OCR = 41, 92 ACMD_SET_CLR_CARD_DETECT = 42, 93 ACMD_SEND_SCR = 51 94 } sda_index_t; 95 96 /* 97 * Classes of response type. Note that we encode the "busy bit" as 98 * value 0x10. 99 */ 100 typedef enum { 101 R0 = 0, 102 R1 = 1, 103 R2 = 2, 104 R3 = 3, 105 R4 = 4, 106 R5 = 5, 107 R6 = 6, 108 R7 = 7, 109 Rb = 0x10, 110 R1b = 0x11, 111 R5b = 0x15 112 } sda_rtype_t; 113 114 /* 115 * R1 status bits. 116 */ 117 #define R1_OUT_OF_RANGE (1U << 31) 118 #define R1_ADDRESS_ERROR (1U << 30) 119 #define R1_BLOCK_LEN_ERROR (1U << 29) 120 #define R1_ERASE_SEQ_ERROR (1U << 28) 121 #define R1_ERASE_PARAM (1U << 27) 122 #define R1_WP_VIOLATION (1U << 26) 123 #define R1_CARD_IS_LOCKED (1U << 25) 124 #define R1_LOCK_FAILED (1U << 24) 125 #define R1_COM_CRC_ERROR (1U << 23) 126 #define R1_ILLEGAL_COMMAND (1U << 22) 127 #define R1_CARD_ECC_FAILED (1U << 21) 128 #define R1_CC_ERROR (1U << 20) 129 #define R1_ERROR (1U << 19) 130 #define R1_CSD_OVERWRITE (1U << 16) 131 #define R1_WP_ERASE_SKIP (1U << 15) 132 #define R1_CARD_ECC_DIS (1U << 14) 133 #define R1_ERASE_RESET (1U << 13) 134 #define R1_READY_FOR_DATA (1U << 8) 135 #define R1_APP_CMD (1U << 5) 136 #define R1_AKE_SEQ_ERROR (1U << 3) 137 138 /* 139 * Note that R1_COM_CRC_ERR, R1_ILLEGAL_COMMAND, R1_ERASE_SEQ_ERROR, and 140 * R1_AKE_SEQ_ERROR errors are delayed error bits reported on the next 141 * command. So we don't list them here. 142 */ 143 #define R1_ERRS (\ 144 R1_ERROR | R1_OUT_OF_RANGE | R1_ADDRESS_ERROR | R1_BLOCK_LEN_ERROR | \ 145 R1_ERASE_PARAM | R1_WP_VIOLATION | R1_LOCK_FAILED | \ 146 R1_CARD_ECC_FAILED | R1_CC_ERROR | R1_CSD_OVERWRITE | \ 147 R1_WP_ERASE_SKIP) 148 149 #define R1_STATE(x) (((x) & 0xf) >> 9) 150 151 /* 152 * R5 status bits. 153 */ 154 #define R5_COM_CRC_ERROR (1U << 7) 155 #define R5_ILLEGAL_COMMAND (1U << 6) 156 #define R5_ERROR (1U << 3) 157 #define R5_RFU (1U << 2) 158 #define R5_FUNCTION_NUMBER (1U << 1) 159 #define R5_OUT_OF_RANGE (1U << 0) 160 161 #define R5_ERRS (R5_ERROR | R5_FUNCTION_NUMBER | R5_OUT_OF_RANGE) 162 163 #define R5_IO_STATE(x) (((x) & 0x3) >> 4) 164 165 /* 166 * R7 bits (CMD8). 167 */ 168 #define R7_VHS_27_36V (1U << 8) 169 #define R7_PATTERN (0xAA) 170 171 /* 172 * OCR bits. 173 */ 174 #define OCR_POWER_UP (1U << 31) 175 #define OCR_CCS (1U << 30) 176 #define OCR_FUNCS(x) (((x) & 7) >> 28) /* SDIO only */ 177 #define OCR_MEM_PRESENT (1U << 27) /* SDIO only */ 178 #define OCR_VOLTAGE_MASK (0xffffffU) /* (bits 0-23 */ 179 #define OCR_HI_MASK (0xff8000U) /* 2.7-3.6V */ 180 #define OCR_35_36V (1U << 23) 181 #define OCR_34_35V (1U << 22) 182 #define OCR_33_34V (1U << 21) 183 #define OCR_32_33V (1U << 20) 184 #define OCR_31_32V (1U << 19) 185 #define OCR_30_31V (1U << 18) 186 #define OCR_29_30V (1U << 17) 187 #define OCR_28_29V (1U << 16) 188 #define OCR_27_28V (1U << 15) 189 #define OCR_26_27V (1U << 14) 190 #define OCR_25_26V (1U << 14) 191 #define OCR_24_25V (1U << 13) 192 #define OCR_23_24V (1U << 12) 193 #define OCR_22_23V (1U << 11) 194 #define OCR_21_22V (1U << 10) 195 #define OCR_20_21V (1U << 9) 196 #define OCR_19_20V (1U << 8) 197 #define OCR_18_19V (1U << 7) 198 #define OCR_17_18V (1U << 6) 199 200 201 /* 202 * Command structure. Used internally by the framework, and by host 203 * drivers. Note that it is forbidden to depend on the size of this 204 * structure. 205 */ 206 typedef struct sda_cmd sda_cmd_t; 207 208 struct sda_cmd { 209 /* 210 * The ordering of these is done to maximize packing. 211 */ 212 sda_index_t sc_index; /* command name */ 213 sda_rtype_t sc_rtype; /* response type expected */ 214 uint16_t sc_flags; 215 uint32_t sc_argument; /* command argument */ 216 217 uint32_t sc_response[4]; 218 219 uint16_t sc_nblks; 220 uint16_t sc_blksz; 221 222 uint32_t sc_resid; 223 224 ddi_dma_handle_t sc_dmah; 225 uint_t sc_ndmac; /* # DMA cookies */ 226 ddi_dma_cookie_t sc_dmac; /* actual DMA cookies */ 227 caddr_t sc_kvaddr; /* kernel virtual address */ 228 229 #define SDA_CMDF_READ 0x0001 /* transfer direction */ 230 #define SDA_CMDF_WRITE 0x0002 /* transfer direction */ 231 #define SDA_CMDF_AUTO_CMD12 0x0004 /* cmd12 requested */ 232 /* private flags .. not for driver consumption */ 233 #define SDA_CMDF_DAT 0x0100 /* data phase pending */ 234 #define SDA_CMDF_BUSY 0x0200 /* cmd in-flight or queued */ 235 #define SDA_CMDF_INIT 0x0400 /* initialization command */ 236 #define SDA_CMDF_MEM 0x0800 /* memory target command */ 237 }; 238 239 /* 240 * The framework has two APIs. The first API is for host controllers, 241 * and is referred to as SDHOST. The second API is for target devices, 242 * and is referred to as SDCLIENT. Please don't mix and match usage outside 243 * of the framework implementation itself! 244 */ 245 246 typedef struct sda_host sda_host_t; 247 248 typedef enum { 249 SDA_PROP_INSERTED = 1, /* R: is card inserted? */ 250 SDA_PROP_WPROTECT = 2, /* R: is card write protected */ 251 SDA_PROP_LED = 3, /* W: LED */ 252 SDA_PROP_CLOCK = 4, /* R: frequency, Hz */ 253 SDA_PROP_BUSWIDTH = 5, /* W: bus width */ 254 SDA_PROP_OCR = 6, /* RW: ocr R: supported, W: set curr */ 255 SDA_PROP_CAP_4BITS = 7, /* R: 4 bit data bus? */ 256 SDA_PROP_CAP_8BITS = 8, /* R: MMC future expansion */ 257 SDA_PROP_CAP_HISPEED = 9, /* R: fast bus rates (> 25MHz) */ 258 SDA_PROP_CAP_INTR = 10, /* R: SDIO interrupt support */ 259 SDA_PROP_CAP_NOPIO = 11, /* R: Never needs bp_mapin */ 260 SDA_PROP_HISPEED = 12 /* W: high speed (>25MHz) */ 261 } sda_prop_t; 262 263 typedef enum { 264 SDA_FAULT_NONE = 0, /* No failure */ 265 SDA_FAULT_ACMD12 = 1, /* Auto CMD12 failure */ 266 SDA_FAULT_CRC7 = 2, /* CRC7 failure on CMD/DAT line */ 267 SDA_FAULT_PROTO = 3, /* SD/MMC protocol error */ 268 SDA_FAULT_CURRENT = 4, /* Current overlimit detected */ 269 SDA_FAULT_INIT = 5, /* Card initialization failure */ 270 SDA_FAULT_TIMEOUT = 6, /* Unexpected timeout failure */ 271 SDA_FAULT_HOST = 7, /* Internal host or slot failure */ 272 SDA_FAULT_RESET = 8, /* Slot failed to reset */ 273 } sda_fault_t; 274 275 typedef enum { 276 SDA_EOK = 0, /* Success */ 277 SDA_ECRC7 = 1, /* CRC7 failure */ 278 SDA_EPROTO = 2, /* SD/MMC protocol error */ 279 SDA_EINVAL = 3, /* Invalid argument */ 280 SDA_ETIME = 4, /* Timeout */ 281 SDA_ECMD12 = 5, /* Failed during stop cmd */ 282 SDA_ENOTSUP = 6, /* Setting/property not supported */ 283 SDA_ERESID = 7, /* Incomplete transfer */ 284 SDA_EFAULT = 8, /* Previous fault condition present */ 285 SDA_ENOMEM = 9, /* Memory exhausted */ 286 SDA_EWPROTECT = 10, /* Media is write protected */ 287 SDA_ENODEV = 11, /* Card removed */ 288 SDA_ERESET = 12, /* Memory card reset */ 289 SDA_EABORT = 13, /* Memory command aborted */ 290 SDA_EIO = 14, /* Other generic error */ 291 SDA_ESUSPENDED = 15, /* Slot has been suspended */ 292 } sda_err_t; 293 294 typedef struct sda_ops { 295 int so_version; 296 #define SDA_OPS_VERSION 1 297 sda_err_t (*so_cmd)(void *, sda_cmd_t *); 298 sda_err_t (*so_getprop)(void *, sda_prop_t, uint32_t *); 299 sda_err_t (*so_setprop)(void *, sda_prop_t, uint32_t); 300 sda_err_t (*so_poll)(void *); 301 sda_err_t (*so_reset)(void *); 302 sda_err_t (*so_halt)(void *); 303 } sda_ops_t; 304 305 /* 306 * Host operations. 307 */ 308 void sda_host_init_ops(struct dev_ops *); 309 void sda_host_fini_ops(struct dev_ops *); 310 sda_host_t *sda_host_alloc(dev_info_t *, int, sda_ops_t *, ddi_dma_attr_t *); 311 void sda_host_free(sda_host_t *); 312 void sda_host_set_private(sda_host_t *, int, void *); 313 int sda_host_attach(sda_host_t *); 314 void sda_host_detach(sda_host_t *); 315 void sda_host_suspend(sda_host_t *); 316 void sda_host_resume(sda_host_t *); 317 void sda_host_detect(sda_host_t *, int); 318 void sda_host_fault(sda_host_t *, int, sda_fault_t); 319 void sda_host_transfer(sda_host_t *, int, sda_err_t); 320 /*PRINTFLIKE3*/ 321 void sda_host_log(sda_host_t *, int, const char *, ...); 322 323 #ifdef __cplusplus 324 } 325 #endif 326 327 #endif /* _SYS_SDCARD_SDA_H */ 328