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