1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <inttypes.h> 6#include <stdio.h> 7#include <stdlib.h> 8#include <string.h> 9#include <unistd.h> 10 11#include <sys/param.h> 12#include <ddk/device.h> 13#include <ddk/debug.h> 14#include <ddk/protocol/sdmmc.h> 15#include <ddk/protocol/sdio.h> 16 17#include <zircon/process.h> 18#include <zircon/threads.h> 19 20#include "sdmmc.h" 21#include "sdio.h" 22 23static zx_status_t sdio_rw_byte(sdmmc_device_t *dev, bool write, uint8_t fn_idx, uint32_t addr, 24 uint8_t write_byte, uint8_t *read_byte) { 25 if (!sdio_fn_idx_valid(fn_idx)) { 26 return ZX_ERR_INVALID_ARGS; 27 } 28 read_byte = write ? NULL : read_byte; 29 write_byte = write ? write_byte : 0; 30 return sdio_io_rw_direct(dev, write, fn_idx, addr, write_byte, read_byte); 31} 32 33static zx_status_t sdio_read_after_write_byte(sdmmc_device_t *dev, uint8_t fn_idx, uint32_t addr, 34 uint8_t write_byte, uint8_t *read_byte) { 35 if (!sdio_fn_idx_valid(fn_idx)) { 36 return ZX_ERR_INVALID_ARGS; 37 } 38 return sdio_io_rw_direct(dev, true, fn_idx, addr, write_byte, read_byte); 39} 40 41zx_status_t sdio_rw_data(void *ctx, uint8_t fn_idx, sdio_rw_txn_t *txn) { 42 if (!sdio_fn_idx_valid(fn_idx)) { 43 return ZX_ERR_INVALID_ARGS; 44 } 45 46 sdmmc_device_t *dev = ctx; 47 zx_status_t st = ZX_OK; 48 uint32_t addr = txn->addr; 49 uint32_t data_size = txn->data_size; 50 bool use_dma = txn->use_dma; 51 52 // Single byte reads at some addresses are stuck when using io_rw_extended. 53 // Use io_rw_direct whenever possible. 54 if (!use_dma && data_size == 1) { 55 return sdio_rw_byte(dev, txn->write, fn_idx, addr, 56 *(uintptr_t*)(txn->virt), txn->virt); 57 } 58 59 if ((data_size % 4) != 0) { 60 //TODO(ravoorir): This is definitely needed for PIO mode. Astro has 61 //a hardware bug about not supporting DMA. We end up doing non-dma 62 //transfers on astro.For now restrict the size for dma requests as well. 63 zxlogf(ERROR, "sdio_rw_data: data size is not a multiple of 4\n"); 64 return ZX_ERR_NOT_SUPPORTED; 65 } 66 bool dma_supported = sdmmc_use_dma(dev); 67 void *buf = use_dma ? NULL : txn->virt; 68 zx_handle_t dma_vmo = use_dma ? txn->dma_vmo : ZX_HANDLE_INVALID; 69 uint64_t buf_offset = txn->buf_offset; 70 71 if (txn->use_dma && !dma_supported) { 72 // host does not support dma 73 st = zx_vmar_map(zx_vmar_root_self(), 74 ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 75 0, txn->dma_vmo, txn->buf_offset, data_size, 76 (uintptr_t*)&buf); 77 if (st != ZX_OK) { 78 zxlogf(TRACE, "sdio_rw_data: vmo map error %d\n", st); 79 return ZX_ERR_IO; 80 } 81 use_dma = false; 82 dma_vmo = ZX_HANDLE_INVALID; 83 buf_offset = 0; //set it to 0 since we mapped starting from offset. 84 } 85 86 bool mbs = (dev->sdio_dev.hw_info.caps) & SDIO_CARD_MULTI_BLOCK; 87 uint32_t func_blk_size = (dev->sdio_dev.funcs[fn_idx]).cur_blk_size; 88 uint32_t rem_blocks = (func_blk_size == 0) ? 0 : (data_size / func_blk_size); 89 uint32_t data_processed = 0; 90 while (rem_blocks > 0) { 91 uint32_t num_blocks = 1; 92 if (mbs) { 93 uint32_t max_host_blocks; 94 max_host_blocks = use_dma ? ((dev->host_info.max_transfer_size) / func_blk_size) : 95 ((dev->host_info.max_transfer_size_non_dma) / func_blk_size); 96 // multiblock is supported, determine max number of blocks per cmd 97 num_blocks = MIN(MIN(SDIO_IO_RW_EXTD_MAX_BLKS_PER_CMD, max_host_blocks), rem_blocks); 98 } 99 st = sdio_io_rw_extended(dev, txn->write, fn_idx, addr, txn->incr, num_blocks, 100 func_blk_size, use_dma, buf, dma_vmo, 101 buf_offset + data_processed); 102 if (st != ZX_OK) { 103 zxlogf(ERROR, "sdio_rw_data: Error %sing data.func: %d status: %d\n", 104 txn->write ? "writ" : "read", fn_idx, st); 105 return st; 106 } 107 rem_blocks -= num_blocks; 108 data_processed += num_blocks * func_blk_size; 109 if (txn->incr) { 110 addr += data_processed; 111 } 112 } 113 114 if (data_processed < data_size) { 115 // process remaining data. 116 st = sdio_io_rw_extended(dev, txn->write, fn_idx, addr, txn->incr, 117 1, (data_size - data_processed), use_dma, buf, dma_vmo, 118 buf_offset + data_processed); 119 } 120 121 if (txn->use_dma && !dma_supported) { 122 zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)buf, data_size); 123 } 124 125 return st; 126} 127 128static zx_status_t sdio_read_data32(sdmmc_device_t *dev, uint8_t fn_idx, uint32_t addr, 129 uint32_t *dword) { 130 sdio_rw_txn_t txn; 131 txn.addr = addr; 132 txn.write = false; 133 txn.virt = dword; 134 txn.data_size = 4; 135 txn.incr = true; 136 txn.use_dma = false; 137 txn.buf_offset = 0; 138 return sdio_rw_data(dev, fn_idx, &txn); 139} 140 141static zx_status_t sdio_write_data32(sdmmc_device_t *dev, uint8_t fn_idx, uint32_t addr, 142 uint32_t dword) { 143 sdio_rw_txn_t txn; 144 txn.addr = addr; 145 txn.write = true; 146 txn.virt = (void *)&dword; 147 txn.data_size = 4; 148 txn.incr = true; 149 txn.use_dma = false; 150 txn.buf_offset = 0; 151 return sdio_rw_data(dev, fn_idx, &txn); 152} 153 154static zx_status_t sdio_read_data16(sdmmc_device_t *dev, uint8_t fn_idx, uint32_t addr, 155 uint16_t *word) { 156 uint8_t byte1 = 0, byte2 = 0; 157 zx_status_t st = sdio_rw_byte(dev, false, 0, addr, 0, &byte1); 158 if (st != ZX_OK) { 159 zxlogf(ERROR, "sdio_read_data16: Error reading from addr:0x%x, retcode: %d\n", addr, st); 160 return st; 161 } 162 163 st = sdio_rw_byte(dev, false, 0, addr + 1, 0, &byte2); 164 if (st != ZX_OK) { 165 zxlogf(ERROR, "sdio_read_data16: Error reading from addr:0x%x, retcode: %d\n", addr + 1, 166 st); 167 return st; 168 } 169 170 *word = byte2 << 8 | byte1; 171 return ZX_OK; 172} 173 174static zx_status_t sdio_write_data16(sdmmc_device_t *dev, uint8_t fn_idx, uint32_t addr, 175 uint16_t word) { 176 zx_status_t st = sdio_rw_byte(dev, true, 0, addr, word & 0xff, NULL); 177 if (st != ZX_OK) { 178 zxlogf(ERROR, "sdio_write_data16: Error writing to addr:0x%x, retcode: %d\n", addr, st); 179 return st; 180 } 181 182 st = sdio_rw_byte(dev, true, 0, addr + 1, (word >> 8) & 0xff, NULL); 183 if (st != ZX_OK) { 184 zxlogf(ERROR, "sdio_write_data16: Error writing to addr:0x%x, retcode: %d\n", addr + 1, 185 st); 186 return st; 187 } 188 189 return ZX_OK; 190} 191 192zx_status_t sdio_get_device_hw_info(void *ctx, sdio_hw_info_t *dev_info) { 193 sdmmc_device_t *dev = ctx; 194 sdio_device_t *sdio_dev = &(dev->sdio_dev); 195 memcpy(&(dev_info->dev_hw_info), &(sdio_dev->hw_info), sizeof(sdio_device_hw_info_t)); 196 for (size_t i = 0; i < sdio_dev->hw_info.num_funcs; i++) { 197 memcpy(&(dev_info->funcs_hw_info[i]), &(sdio_dev->funcs[i].hw_info), 198 sizeof(sdio_func_hw_info_t)); 199 } 200 dev_info->host_max_transfer_size = dev->host_info.max_transfer_size; 201 return ZX_OK; 202} 203 204static uint32_t sdio_read_tuple_body(uint8_t *t_body, size_t start, size_t numbytes) { 205 uint32_t res = 0; 206 207 for (size_t i = start; i < (start + numbytes); i++) { 208 res |= t_body[i] << ((i - start)* 8); 209 } 210 return res; 211} 212 213static zx_status_t sdio_process_cccr(sdmmc_device_t *dev) { 214 uint8_t cccr_vsn, sdio_vsn, vsn_info, bus_speed, card_caps, uhs_caps, drv_strength; 215 216 //version info 217 zx_status_t status = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_CCCR_SDIO_VER_ADDR, 0, &vsn_info); 218 if (status != ZX_OK) { 219 zxlogf(ERROR, "sdio_process_cccr: Error reading CCCR reg: %d\n", status); 220 return status; 221 } 222 cccr_vsn = get_bits(vsn_info, SDIO_CIA_CCCR_CCCR_VER_MASK, SDIO_CIA_CCCR_CCCR_VER_LOC); 223 sdio_vsn = get_bits(vsn_info, SDIO_CIA_CCCR_SDIO_VER_MASK, SDIO_CIA_CCCR_SDIO_VER_LOC); 224 if ((cccr_vsn < SDIO_CCCR_FORMAT_VER_3) || (sdio_vsn < SDIO_SDIO_VER_3)) { 225 return ZX_ERR_NOT_SUPPORTED; 226 } 227 dev->sdio_dev.hw_info.cccr_vsn = cccr_vsn; 228 dev->sdio_dev.hw_info.sdio_vsn = sdio_vsn; 229 230 //card capabilities 231 status = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_CARD_CAPS_ADDR, 0, &card_caps); 232 if (status != ZX_OK) { 233 zxlogf(ERROR, "sdio_process_cccr: Error reading CAPS reg: %d\n", status); 234 return status; 235 } 236 dev->sdio_dev.hw_info.caps = 0; 237 if (card_caps & SDIO_CIA_CCCR_CARD_CAP_SMB) { 238 dev->sdio_dev.hw_info.caps |= SDIO_CARD_MULTI_BLOCK; 239 } 240 if (card_caps & SDIO_CIA_CCCR_CARD_CAP_LSC) { 241 dev->sdio_dev.hw_info.caps |= SDIO_CARD_LOW_SPEED; 242 } 243 if (card_caps & SDIO_CIA_CCCR_CARD_CAP_4BLS) { 244 dev->sdio_dev.hw_info.caps |= SDIO_CARD_4BIT_BUS; 245 } 246 247 //speed 248 status = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, 0, &bus_speed); 249 if (status != ZX_OK) { 250 zxlogf(ERROR, "sdio_process_cccr: Error reading SPEED reg: %d\n", status); 251 return status; 252 } 253 if (bus_speed & SDIO_CIA_CCCR_BUS_SPEED_SEL_SHS) { 254 dev->sdio_dev.hw_info.caps |= SDIO_CARD_HIGH_SPEED; 255 } 256 257 // Is UHS supported? 258 status = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_UHS_SUPPORT_ADDR, 0, &uhs_caps); 259 if (status != ZX_OK) { 260 zxlogf(ERROR, "sdio_process_cccr: Error reading SPEED reg: %d\n", status); 261 return status; 262 } 263 if (uhs_caps & SDIO_CIA_CCCR_UHS_SDR50) { 264 dev->sdio_dev.hw_info.caps |= SDIO_CARD_UHS_SDR50; 265 } 266 if (uhs_caps & SDIO_CIA_CCCR_UHS_SDR104) { 267 dev->sdio_dev.hw_info.caps |= SDIO_CARD_UHS_SDR104; 268 } 269 if (uhs_caps & SDIO_CIA_CCCR_UHS_DDR50) { 270 dev->sdio_dev.hw_info.caps |= SDIO_CARD_UHS_DDR50; 271 } 272 273 //drv_strength 274 status = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_DRV_STRENGTH_ADDR, 0, 275 &drv_strength); 276 if (status != ZX_OK) { 277 zxlogf(ERROR, "sdio_process_cccr: Error reading SPEED reg: %d\n", status); 278 return status; 279 } 280 if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTA) { 281 dev->sdio_dev.hw_info.caps |= SDIO_DRIVER_TYPE_A; 282 } 283 if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTB) { 284 dev->sdio_dev.hw_info.caps |= SDIO_DRIVER_TYPE_B; 285 } 286 if (drv_strength & SDIO_CIA_CCCR_DRV_STRENGTH_SDTD) { 287 dev->sdio_dev.hw_info.caps |= SDIO_DRIVER_TYPE_D; 288 } 289 return status; 290} 291 292static zx_status_t sdio_parse_func_ext_tuple(sdmmc_device_t* dev, uint32_t fn_idx, 293 sdio_func_tuple_t *tup) { 294 sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); 295 if (fn_idx == 0) { 296 if (tup->t_body_size < SDIO_CIS_TPL_FUNC0_FUNCE_MIN_BDY_SZ) { 297 return ZX_ERR_IO; 298 } 299 func->hw_info.max_blk_size = sdio_read_tuple_body(tup->t_body, 300 SDIO_CIS_TPL_FUNCE_FUNC0_MAX_BLK_SIZE_LOC, 2); 301 func->hw_info.max_blk_size = MIN(dev->host_info.max_transfer_size, 302 func->hw_info.max_blk_size); 303 uint8_t speed_val = get_bits_u8(tup->t_body[3], SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_VAL_MASK, 304 SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_VAL_LOC); 305 uint8_t speed_unit = get_bits_u8(tup->t_body[3], 306 SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_UNIT_MASK, 307 SDIO_CIS_TPL_FUNCE_MAX_TRAN_SPEED_UNIT_LOC); 308 func->hw_info.max_tran_speed = sdio_cis_tpl_funce_tran_speed_val[speed_val] * 309 sdio_cis_tpl_funce_tran_speed_unit[speed_unit]; 310 return ZX_OK; 311 } 312 313 if (tup->t_body_size < SDIO_CIS_TPL_FUNCx_FUNCE_MIN_BDY_SZ) { 314 zxlogf(ERROR, "sdio_parse_func_ext: Invalid body size: %d for func_ext tuple\n", 315 tup->t_body_size); 316 return ZX_ERR_IO; 317 } 318 func->hw_info.max_blk_size = sdio_read_tuple_body(tup->t_body, 319 SDIO_CIS_TPL_FUNCE_FUNCx_MAX_BLK_SIZE_LOC, 2); 320 return ZX_OK; 321} 322 323static zx_status_t sdio_parse_mfid_tuple(sdmmc_device_t* dev, uint32_t fn_idx, 324 sdio_func_tuple_t *tup) { 325 if (tup->t_body_size < SDIO_CIS_TPL_MANFID_MIN_BDY_SZ) { 326 return ZX_ERR_IO; 327 } 328 sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); 329 func->hw_info.manufacturer_id = sdio_read_tuple_body(tup->t_body, 0, 2); 330 func->hw_info.product_id = sdio_read_tuple_body(tup->t_body, 2, 2); 331 return ZX_OK; 332} 333 334static zx_status_t sdio_parse_fn_tuple(sdmmc_device_t* dev, uint32_t fn_idx, 335 sdio_func_tuple_t *tup) { 336 zx_status_t st = ZX_OK; 337 switch (tup->t_code) { 338 case SDIO_CIS_TPL_CODE_MANFID: 339 st = sdio_parse_mfid_tuple(dev, fn_idx, tup); 340 break; 341 case SDIO_CIS_TPL_CODE_FUNCE: 342 st = sdio_parse_func_ext_tuple(dev, fn_idx, tup); 343 break; 344 default: 345 break; 346 } 347 return st; 348} 349 350static zx_status_t sdio_process_cis(sdmmc_device_t* dev, uint32_t fn_idx) { 351 zx_status_t st = ZX_OK; 352 353 if (fn_idx >= SDIO_MAX_FUNCS) { 354 return ZX_ERR_INVALID_ARGS; 355 } 356 uint32_t cis_ptr = 0; 357 for (size_t i = 0; i < SDIO_CIS_ADDRESS_SIZE; i++) { 358 uint8_t addr; 359 st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_FBR_BASE_ADDR(fn_idx) + 360 SDIO_CIA_FBR_CIS_ADDR + i, 0, &addr); 361 if (st != ZX_OK) { 362 zxlogf(ERROR, "sdio: Error reading CIS of CCCR reg: %d\n", st); 363 return st; 364 } 365 cis_ptr |= addr << (i * 8); 366 } 367 if (!cis_ptr) { 368 zxlogf(ERROR, "sdio: CIS address is invalid\n"); 369 return ZX_ERR_IO; 370 } 371 372 while (true) { 373 uint8_t t_code, t_link; 374 sdio_func_tuple_t cur_tup; 375 st = sdio_io_rw_direct(dev, false, 0, cis_ptr + SDIO_CIS_TPL_FRMT_TCODE_OFF, 376 0, &t_code); 377 if (st != ZX_OK) { 378 zxlogf(ERROR, "sdio: Error reading tuple code for fn %d\n", fn_idx); 379 break; 380 } 381 // Ignore null tuples 382 if (t_code == SDIO_CIS_TPL_CODE_NULL) { 383 cis_ptr++; 384 continue; 385 } 386 if (t_code == SDIO_CIS_TPL_CODE_END) { 387 break; 388 } 389 st = sdio_io_rw_direct(dev, false, 0, cis_ptr + SDIO_CIS_TPL_FRMT_TLINK_OFF, 390 0, &t_link); 391 if (st != ZX_OK) { 392 zxlogf(ERROR, "sdio: Error reading tuple size for fn %d\n", fn_idx); 393 break; 394 } 395 if (t_link == SDIO_CIS_TPL_LINK_END) { 396 break; 397 } 398 399 cur_tup.t_code = t_code; 400 cur_tup.t_body_size = t_link; 401 cur_tup.t_body = NULL; 402 cur_tup.t_body = calloc(1, t_link); 403 if (!(cur_tup.t_body)) { 404 st = ZX_ERR_NO_MEMORY; 405 break; 406 } 407 408 cis_ptr += SDIO_CIS_TPL_FRMT_TBODY_OFF; 409 for (size_t i = 0; i < t_link; i++, cis_ptr++) { 410 st = sdio_io_rw_direct(dev, false, 0, cis_ptr, 0, &(cur_tup.t_body[i])); 411 if (st != ZX_OK) { 412 zxlogf(ERROR, "sdio: Error reading tuple body for fn %d\n", fn_idx); 413 free(cur_tup.t_body); 414 return st; 415 } 416 } 417 sdio_parse_fn_tuple(dev, fn_idx, &cur_tup); 418 free(cur_tup.t_body); 419 } 420 return st; 421} 422 423static zx_status_t sdio_switch_freq(sdmmc_device_t* dev, uint32_t new_freq) { 424 zx_status_t st; 425 if ((st = sdmmc_set_bus_freq(&dev->host, new_freq)) != ZX_OK) { 426 zxlogf(ERROR, "sdio: Error while switching host bus frequency, retcode = %d\n", st); 427 return st; 428 } 429 dev->clock_rate = new_freq; 430 return ZX_OK; 431} 432 433static zx_status_t sdio_switch_hs(sdmmc_device_t *dev) { 434 zx_status_t st = ZX_OK; 435 uint8_t speed = 0; 436 437 if (!(dev->sdio_dev.hw_info.caps & SDIO_CARD_HIGH_SPEED)) { 438 zxlogf(ERROR, "sdio: High speed not supported, retcode = %d\n", st); 439 return ZX_ERR_NOT_SUPPORTED; 440 } 441 st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, 0, &speed); 442 if (st != ZX_OK) { 443 zxlogf(ERROR, "sdio: Error while reading CCCR reg, retcode = %d\n", st); 444 return st; 445 } 446 update_bits_u8(&speed, SDIO_CIA_CCCR_BUS_SPEED_BSS_MASK, SDIO_CIA_CCCR_BUS_SPEED_BSS_LOC, 447 SDIO_BUS_SPEED_EN_HS); 448 st = sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, speed, NULL); 449 if (st != ZX_OK) { 450 zxlogf(ERROR, "sdio: Error while writing to CCCR reg, retcode = %d\n", st); 451 return st; 452 } 453 // Switch the host timing 454 if ((st = sdmmc_set_timing(&dev->host, SDMMC_TIMING_HS)) != ZX_OK) { 455 zxlogf(ERROR, "sdio: failed to switch to hs timing on host : %d\n", st); 456 return st; 457 } 458 459 if ((st = sdio_switch_freq(dev, SDIO_HS_MAX_FREQ)) != ZX_OK) { 460 zxlogf(ERROR, "sdio: failed to switch to hs timing on host : %d\n", st); 461 return st; 462 } 463 return st; 464} 465 466static zx_status_t sdio_switch_uhs(sdmmc_device_t *dev) { 467 zx_status_t st = ZX_OK; 468 uint8_t speed = 0; 469 uint32_t hw_caps = dev->sdio_dev.hw_info.caps; 470 471 uint32_t new_freq = SDIO_DEFAULT_FREQ; 472 uint8_t select_speed = SDIO_BUS_SPEED_SDR50; 473 sdmmc_timing_t timing = SDMMC_TIMING_SDR50; 474 475 st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, 0, &speed); 476 if (st != ZX_OK) { 477 zxlogf(ERROR, "sdio: Error while reading CCCR reg, retcode = %d\n", st); 478 return st; 479 } 480 481 if (hw_caps & SDIO_CARD_UHS_SDR104) { 482 select_speed = SDIO_BUS_SPEED_SDR104; 483 timing = SDMMC_TIMING_SDR104; 484 new_freq = SDIO_UHS_SDR104_MAX_FREQ; 485 } else if (hw_caps & SDIO_CARD_UHS_SDR50) { 486 select_speed = SDIO_BUS_SPEED_SDR50; 487 timing = SDMMC_TIMING_SDR50; 488 new_freq = SDIO_UHS_SDR50_MAX_FREQ; 489 } else if (hw_caps & SDIO_CARD_UHS_DDR50) { 490 select_speed = SDIO_BUS_SPEED_DDR50; 491 timing = SDMMC_TIMING_DDR50; 492 new_freq = SDIO_UHS_DDR50_MAX_FREQ; 493 } else { 494 return ZX_ERR_NOT_SUPPORTED; 495 } 496 497 update_bits_u8(&speed, SDIO_CIA_CCCR_BUS_SPEED_BSS_MASK, SDIO_CIA_CCCR_BUS_SPEED_BSS_LOC, 498 select_speed); 499 500 st = sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_BUS_SPEED_SEL_ADDR, speed, NULL); 501 if (st != ZX_OK) { 502 zxlogf(ERROR, "sdio: Error while writing to CCCR reg, retcode = %d\n", st); 503 return st; 504 } 505 // Switch the host timing 506 if ((st = sdmmc_set_timing(&dev->host, timing)) != ZX_OK) { 507 zxlogf(ERROR, "sdio: failed to switch to hs timing on host : %d\n", st); 508 return st; 509 } 510 511 if ((st = sdio_switch_freq(dev, new_freq)) != ZX_OK) { 512 zxlogf(ERROR, "sdio: failed to switch to hs timing on host : %d\n", st); 513 return st; 514 } 515 return st; 516} 517 518static zx_status_t sdio_enable_4bit_bus(sdmmc_device_t *dev) { 519 zx_status_t st = ZX_OK; 520 if ((dev->sdio_dev.hw_info.caps & SDIO_CARD_LOW_SPEED) && 521 !(dev->sdio_dev.hw_info.caps & SDIO_CARD_4BIT_BUS)) { 522 zxlogf(ERROR, "sdio: Switching to 4-bit bus unsupported\n"); 523 return ZX_ERR_NOT_SUPPORTED; 524 } 525 uint8_t bus_ctrl_reg; 526 if ((st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_BUS_INTF_CTRL_ADDR, 0, 527 &bus_ctrl_reg)) != ZX_OK) { 528 zxlogf(INFO, "sdio: Error reading the current bus width\n"); 529 return st; 530 } 531 update_bits_u8(&bus_ctrl_reg, SDIO_CIA_CCCR_INTF_CTRL_BW_MASK, SDIO_CIA_CCCR_INTF_CTRL_BW_LOC, 532 SDIO_BW_4BIT); 533 if ((st = sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_BUS_INTF_CTRL_ADDR, bus_ctrl_reg, 534 NULL)) != ZX_OK) { 535 zxlogf(ERROR, "sdio: Error while switching the bus width\n"); 536 return st; 537 } 538 if ((st = sdmmc_set_bus_width(&dev->host, SDMMC_BUS_WIDTH_4)) != ZX_OK) { 539 zxlogf(ERROR, "sdio: failed to switch the host bus width to %d, retcode = %d\n", 540 SDMMC_BUS_WIDTH_4, st); 541 return ZX_ERR_INTERNAL; 542 } 543 544 dev->bus_width = SDMMC_BUS_WIDTH_4; 545 return ZX_OK; 546} 547 548static zx_status_t sdio_switch_bus_width(sdmmc_device_t *dev, uint32_t bw) { 549 zx_status_t st = ZX_OK; 550 if (bw != SDIO_BW_1BIT && bw != SDIO_BW_4BIT) { 551 return ZX_ERR_NOT_SUPPORTED; 552 } 553 if (bw == SDIO_BW_4BIT) { 554 if ((st = sdio_enable_4bit_bus(dev)) != ZX_OK) { 555 return st; 556 } 557 } 558 return ZX_OK; 559} 560 561static zx_status_t sdio_process_fbr(sdmmc_device_t *dev, uint8_t fn_idx) { 562 zx_status_t st = ZX_OK; 563 uint8_t fbr, fn_intf_code; 564 565 sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); 566 if ((st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_FBR_BASE_ADDR(fn_idx) + 567 SDIO_CIA_FBR_STD_IF_CODE_ADDR, 0, &fbr)) != ZX_OK) { 568 zxlogf(ERROR, "sdio: Error reading intf code: %d\n", st); 569 return st; 570 } 571 fn_intf_code = get_bits_u8(fbr, SDIO_CIA_FBR_STD_IF_CODE_MASK, SDIO_CIA_FBR_STD_IF_CODE_LOC); 572 if (fn_intf_code == SDIO_CIA_FBR_STD_IF_CODE_MASK) { 573 // fn_code > 0Eh 574 if ((st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_FBR_BASE_ADDR(fn_idx) + 575 SDIO_CIA_FBR_STD_IF_CODE_EXT_ADDR, 0, 576 &fn_intf_code)) != ZX_OK) { 577 zxlogf(ERROR, "sdio: Error while reading the extended intf code %d\n", st); 578 return st; 579 } 580 } 581 func->hw_info.fn_intf_code = fn_intf_code; 582 return ZX_OK; 583} 584 585zx_status_t sdio_get_cur_block_size(void *ctx, uint8_t fn_idx, 586 uint16_t *cur_blk_size) { 587 sdmmc_device_t *dev = ctx; 588 589 zx_status_t st = sdio_read_data16(dev, 0, 590 SDIO_CIA_FBR_BASE_ADDR(fn_idx) + SDIO_CIA_FBR_BLK_SIZE_ADDR, 591 cur_blk_size); 592 if (st != ZX_OK) { 593 zxlogf(ERROR, "sdio_get_cur_block_size: Failed to get block size for fn: %d ret: %d\n", 594 fn_idx, st); 595 } 596 return st; 597} 598 599zx_status_t sdio_modify_block_size(void *ctx, uint8_t fn_idx, uint16_t blk_size, 600 bool set_default) { 601 zx_status_t st = ZX_OK; 602 sdmmc_device_t *dev = ctx; 603 604 sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); 605 if (set_default) { 606 blk_size = func->hw_info.max_blk_size; 607 } 608 609 if (blk_size > func->hw_info.max_blk_size) { 610 return ZX_ERR_INVALID_ARGS; 611 } 612 613 if (func->cur_blk_size == blk_size) { 614 return ZX_OK; 615 } 616 617 st = sdio_write_data16(dev, 0, SDIO_CIA_FBR_BASE_ADDR(fn_idx) + SDIO_CIA_FBR_BLK_SIZE_ADDR, 618 blk_size); 619 if (st != ZX_OK) { 620 zxlogf(ERROR, "sdio_modify_block_size: Error setting blk size.fn: %d blk_sz: %d ret: %d\n", 621 fn_idx, blk_size, st); 622 return st; 623 } 624 625 func->cur_blk_size = blk_size; 626 return st; 627} 628 629zx_status_t sdio_enable_function(void *ctx, uint8_t fn_idx) { 630 uint8_t ioex_reg = 0; 631 zx_status_t st = ZX_OK; 632 sdmmc_device_t *dev = ctx; 633 634 if (!sdio_fn_idx_valid(fn_idx)) { 635 return ZX_ERR_INVALID_ARGS; 636 } 637 638 sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); 639 if (func->enabled) { 640 return ZX_OK; 641 } 642 if ((st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, 0, 643 &ioex_reg)) != ZX_OK) { 644 zxlogf(ERROR, "sdio_enable_function: Error enabling func:%d status:%d\n", 645 fn_idx, st); 646 return st; 647 } 648 649 ioex_reg |= (1 << fn_idx); 650 if ((st = sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, ioex_reg, NULL)) 651 != ZX_OK) { 652 zxlogf(ERROR, "sdio_enable_function: Error enabling func:%d status:%d\n", 653 fn_idx, st); 654 return st; 655 } 656 //wait for the device to enable the func. 657 usleep(10 * 1000); 658 if ((st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, 0, 659 &ioex_reg)) != ZX_OK) { 660 zxlogf(ERROR, "sdio_enable_function: Error enabling func:%d status:%d\n", 661 fn_idx, st); 662 return st; 663 } 664 665 if (!(ioex_reg & (1 << fn_idx))) { 666 st = ZX_ERR_IO; 667 zxlogf(ERROR, "sdio_enable_function: Failed to enable func %d\n", fn_idx); 668 return st; 669 } 670 671 func->enabled = true; 672 zxlogf(TRACE, "sdio_enable_function: Func %d is enabled\n", fn_idx); 673 return st; 674} 675 676zx_status_t sdio_disable_function(void *ctx, uint8_t fn_idx) { 677 uint8_t ioex_reg = 0; 678 zx_status_t st = ZX_OK; 679 sdmmc_device_t *dev = ctx; 680 681 if (!sdio_fn_idx_valid(fn_idx)) { 682 return ZX_ERR_INVALID_ARGS; 683 } 684 685 sdio_function_t *func = &(dev->sdio_dev.funcs[fn_idx]); 686 if (!func->enabled) { 687 zxlogf(ERROR, "sdio_disable_function: Func %d is not enabled\n", fn_idx); 688 return ZX_ERR_IO; 689 } 690 691 if ((st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, 0, 692 &ioex_reg)) != ZX_OK) { 693 zxlogf(ERROR, "sdio_disable_function: Error reading IOEx reg. func: %d status: %d\n", 694 fn_idx, st); 695 return st; 696 } 697 698 ioex_reg &= ~(1 << fn_idx); 699 if ((st = sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_IOEx_EN_FUNC_ADDR, ioex_reg, NULL)) 700 != ZX_OK) { 701 zxlogf(ERROR, "sdio_disable_function: Error writing IOEx reg. func: %d status:%d\n", 702 fn_idx, st); 703 return st; 704 } 705 706 func->enabled = false; 707 zxlogf(TRACE, "sdio_disable_function: Function %d is disabled\n", fn_idx); 708 return st; 709} 710 711static zx_status_t sdio_init_func(sdmmc_device_t *dev, uint8_t fn_idx) { 712 zx_status_t st = ZX_OK; 713 714 if ((st = sdio_process_fbr(dev, fn_idx)) != ZX_OK) { 715 return st; 716 } 717 718 if ((st = sdio_process_cis(dev, fn_idx)) != ZX_OK) { 719 return st; 720 } 721 722 // Enable all func for now. Should move to wifi driver ? 723 if ((st = sdio_enable_function(dev, fn_idx)) != ZX_OK) { 724 return st; 725 } 726 727 // Set default block size 728 if ((st = sdio_modify_block_size(dev, fn_idx, 0, true)) != ZX_OK) { 729 return st; 730 } 731 732 return st; 733} 734 735zx_status_t sdmmc_sdio_reset(sdmmc_device_t* dev) { 736 zx_status_t st = ZX_OK; 737 uint8_t abort_byte; 738 739 st = sdio_io_rw_direct(dev, false, 0, SDIO_CIA_CCCR_ASx_ABORT_SEL_CR_ADDR, 0, &abort_byte); 740 if (st != ZX_OK) { 741 abort_byte = SDIO_CIA_CCCR_ASx_ABORT_SOFT_RESET; 742 } else { 743 abort_byte |= SDIO_CIA_CCCR_ASx_ABORT_SOFT_RESET; 744 } 745 return sdio_io_rw_direct(dev, true, 0, SDIO_CIA_CCCR_ASx_ABORT_SEL_CR_ADDR, abort_byte, NULL); 746} 747 748 749zx_status_t sdmmc_probe_sdio(sdmmc_device_t* dev) { 750 zx_status_t st = sdmmc_sdio_reset(dev); 751 752 if ((st = sdmmc_go_idle(dev)) != ZX_OK) { 753 zxlogf(ERROR, "sdmmc: SDMMC_GO_IDLE_STATE failed, retcode = %d\n", st); 754 return st; 755 } 756 757 uint32_t ocr; 758 if ((st = sdio_send_op_cond(dev, 0, &ocr)) != ZX_OK) { 759 zxlogf(ERROR, "sdmmc_probe_sdio: SDIO_SEND_OP_COND failed, retcode = %d\n", st); 760 return st; 761 } 762 //Select voltage 3.3 V. Also request for 1.8V. Section 3.2 SDIO spec 763 if (ocr & SDIO_SEND_OP_COND_IO_OCR_33V) { 764 uint32_t new_ocr = SDIO_SEND_OP_COND_IO_OCR_33V | SDIO_SEND_OP_COND_CMD_S18R; 765 if ((st = sdio_send_op_cond(dev, new_ocr, &ocr)) != ZX_OK) { 766 zxlogf(ERROR, "sdmmc_probe_sdio: SDIO_SEND_OP_COND failed, retcode = %d\n", st); 767 return st; 768 } 769 } 770 if (ocr & SDIO_SEND_OP_COND_RESP_MEM_PRESENT) { 771 //Combo cards not supported 772 zxlogf(ERROR, "sdmmc_probe_sdio: Combo card not supported\n"); 773 return ZX_ERR_NOT_SUPPORTED; 774 } 775 dev->type = SDMMC_TYPE_SDIO; 776 dev->signal_voltage = SDMMC_VOLTAGE_180; 777 dev->sdio_dev.hw_info.num_funcs = get_bits(ocr, SDIO_SEND_OP_COND_RESP_NUM_FUNC_MASK, 778 SDIO_SEND_OP_COND_RESP_NUM_FUNC_LOC); 779 uint16_t addr = 0; 780 if ((st = sd_send_relative_addr(dev, &addr)) != ZX_OK) { 781 zxlogf(ERROR, "sdmcc_probe_sdio: SD_SEND_RELATIVE_ADDR failed, retcode = %d\n", st); 782 return st; 783 } 784 dev->rca = addr; 785 if ((st = mmc_select_card(dev)) != ZX_OK) { 786 zxlogf(ERROR, "sdmmc_probe_sdio: MMC_SELECT_CARD failed, retcode = %d\n", st); 787 return st; 788 } 789 790 if ((st = sdio_process_cccr(dev)) != ZX_OK) { 791 zxlogf(ERROR, "sdmmc_probe_sdio: Read CCCR failed, retcode = %d\n", st); 792 return st; 793 } 794 795 //Read CIS to get max block size 796 if ((st = sdio_process_cis(dev, 0)) != ZX_OK) { 797 zxlogf(ERROR, "sdmmc_probe_sdio: Read CIS failed, retcode = %d\n", st); 798 return st; 799 } 800 801 if (ocr & SDIO_SEND_OP_COND_RESP_S18A) { 802 if ((st = sd_switch_uhs_voltage(dev, ocr)) != ZX_OK) { 803 zxlogf(INFO, "Failed to switch voltage to 1.8V\n"); 804 return st; 805 } 806 } 807 808 //TODO(ravoorir):Re-enable ultra high speed when wifi stack is more stable. 809 /* if (sdio_is_uhs_supported(dev->sdio_dev.hw_info.caps)) { 810 if ((st = sdio_switch_bus_width(dev, SDIO_BW_4BIT)) != ZX_OK) { 811 zxlogf(ERROR, "sdmmc_probe_sdio: Swtiching to 4-bit bus width failed, retcode = %d\n", 812 st); 813 goto high_speed; 814 } 815 if ((st = sdio_switch_uhs(dev)) != ZX_OK) { 816 zxlogf(ERROR, "sdmmc_probe_sdio: Switching to high speed failed, retcode = %d\n", st); 817 goto high_speed; 818 } 819 uint32_t hw_caps = dev->sdio_dev.hw_info.caps; 820 821 if ((hw_caps & SDIO_CARD_UHS_SDR104) || (hw_caps & SDIO_CARD_UHS_SDR50)) { 822 st = sdmmc_perform_tuning(&dev->host, SD_SEND_TUNING_BLOCK); 823 if (st != ZX_OK) { 824 zxlogf(ERROR, "mmc: tuning failed %d\n", st); 825 goto high_speed; 826 } 827 } 828 goto complete; 829 } 830 831high_speed: */ 832 if (dev->sdio_dev.hw_info.caps & SDIO_CARD_HIGH_SPEED) { 833 if ((st = sdio_switch_hs(dev)) != ZX_OK) { 834 zxlogf(ERROR, "sdmmc_probe_sdio: Switching to high speed failed, retcode = %d\n", st); 835 goto default_speed; 836 } 837 838 if ((st = sdio_switch_bus_width(dev, SDIO_BW_4BIT)) != ZX_OK) { 839 zxlogf(ERROR, "sdmmc_probe_sdio: Swtiching to 4-bit bus width failed, retcode = %d\n", 840 st); 841 goto default_speed; 842 } 843 goto complete; 844 } 845 846default_speed: 847 if ((st = sdio_switch_freq(dev, SDIO_DEFAULT_FREQ)) != ZX_OK) { 848 zxlogf(ERROR, "sdmmc_probe_sdio: Switch freq retcode = %d\n", st); 849 return st; 850 } 851 852complete: 853 sdio_modify_block_size(dev, 0, 0, true); 854 // 0 is the common function. Already initialized 855 for (size_t i = 1; i < dev->sdio_dev.hw_info.num_funcs; i++) { 856 st = sdio_init_func(dev, i); 857 } 858 859 zxlogf(INFO, "sdmmc_probe_sdio: sdio device initialized successfully\n"); 860 zxlogf(INFO, " Manufacturer: 0x%x\n", dev->sdio_dev.funcs[0].hw_info.manufacturer_id); 861 zxlogf(INFO, " Product: 0x%x\n", dev->sdio_dev.funcs[0].hw_info.product_id); 862 zxlogf(INFO, " cccr vsn: 0x%x\n", dev->sdio_dev.hw_info.cccr_vsn); 863 zxlogf(INFO, " SDIO vsn: 0x%x\n", dev->sdio_dev.hw_info.sdio_vsn); 864 zxlogf(INFO, " num funcs: %d\n", dev->sdio_dev.hw_info.num_funcs); 865 return ZX_OK; 866} 867