1 /* 2 * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <endian.h> 9 #include <errno.h> 10 #include <stdint.h> 11 #include <string.h> 12 13 #include <platform_def.h> 14 15 #include <arch_helpers.h> 16 #include <common/debug.h> 17 #include <drivers/delay_timer.h> 18 #include <drivers/ufs.h> 19 #include <lib/mmio.h> 20 21 #define CDB_ADDR_MASK 127 22 #define ALIGN_CDB(x) (((x) + CDB_ADDR_MASK) & ~CDB_ADDR_MASK) 23 #define ALIGN_8(x) (((x) + 7) & ~7) 24 25 #define UFS_DESC_SIZE 0x400 26 #define MAX_UFS_DESC_SIZE 0x8000 /* 32 descriptors */ 27 28 #define MAX_PRDT_SIZE 0x40000 /* 256KB */ 29 30 static ufs_params_t ufs_params; 31 static int nutrs; /* Number of UTP Transfer Request Slots */ 32 33 int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd) 34 { 35 unsigned int data; 36 37 if (base == 0 || cmd == NULL) 38 return -EINVAL; 39 40 data = mmio_read_32(base + HCS); 41 if ((data & HCS_UCRDY) == 0) 42 return -EBUSY; 43 mmio_write_32(base + IS, ~0); 44 mmio_write_32(base + UCMDARG1, cmd->arg1); 45 mmio_write_32(base + UCMDARG2, cmd->arg2); 46 mmio_write_32(base + UCMDARG3, cmd->arg3); 47 mmio_write_32(base + UICCMD, cmd->op); 48 49 do { 50 data = mmio_read_32(base + IS); 51 } while ((data & UFS_INT_UCCS) == 0); 52 mmio_write_32(base + IS, UFS_INT_UCCS); 53 return mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK; 54 } 55 56 int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val) 57 { 58 uintptr_t base; 59 unsigned int data; 60 int result, retries; 61 uic_cmd_t cmd; 62 63 assert(ufs_params.reg_base != 0); 64 65 if (val == NULL) 66 return -EINVAL; 67 68 base = ufs_params.reg_base; 69 for (retries = 0; retries < 100; retries++) { 70 data = mmio_read_32(base + HCS); 71 if ((data & HCS_UCRDY) != 0) 72 break; 73 mdelay(1); 74 } 75 if (retries >= 100) 76 return -EBUSY; 77 78 cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx); 79 cmd.arg2 = 0; 80 cmd.arg3 = 0; 81 cmd.op = DME_GET; 82 for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) { 83 result = ufshc_send_uic_cmd(base, &cmd); 84 if (result == 0) 85 break; 86 data = mmio_read_32(base + IS); 87 if (data & UFS_INT_UE) 88 return -EINVAL; 89 } 90 if (retries >= UFS_UIC_COMMAND_RETRIES) 91 return -EIO; 92 93 *val = mmio_read_32(base + UCMDARG3); 94 return 0; 95 } 96 97 int ufshc_dme_set(unsigned int attr, unsigned int idx, unsigned int val) 98 { 99 uintptr_t base; 100 unsigned int data; 101 int result, retries; 102 uic_cmd_t cmd; 103 104 assert((ufs_params.reg_base != 0)); 105 106 base = ufs_params.reg_base; 107 cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx); 108 cmd.arg2 = 0; 109 cmd.arg3 = val; 110 cmd.op = DME_SET; 111 112 for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) { 113 result = ufshc_send_uic_cmd(base, &cmd); 114 if (result == 0) 115 break; 116 data = mmio_read_32(base + IS); 117 if (data & UFS_INT_UE) 118 return -EINVAL; 119 } 120 if (retries >= UFS_UIC_COMMAND_RETRIES) 121 return -EIO; 122 123 return 0; 124 } 125 126 static int ufshc_hce_enable(uintptr_t base) 127 { 128 unsigned int data; 129 int retries; 130 131 /* Enable Host Controller */ 132 mmio_write_32(base + HCE, HCE_ENABLE); 133 134 /* Wait until basic initialization sequence completed */ 135 for (retries = 0; retries < HCE_ENABLE_INNER_RETRIES; ++retries) { 136 data = mmio_read_32(base + HCE); 137 if (data & HCE_ENABLE) { 138 break; 139 } 140 udelay(HCE_ENABLE_TIMEOUT_US); 141 } 142 if (retries >= HCE_ENABLE_INNER_RETRIES) { 143 return -ETIMEDOUT; 144 } 145 146 return 0; 147 } 148 149 static int ufshc_hce_disable(uintptr_t base) 150 { 151 unsigned int data; 152 int timeout; 153 154 /* Disable Host Controller */ 155 mmio_write_32(base + HCE, HCE_DISABLE); 156 timeout = HCE_DISABLE_TIMEOUT_US; 157 do { 158 data = mmio_read_32(base + HCE); 159 if ((data & HCE_ENABLE) == HCE_DISABLE) { 160 break; 161 } 162 udelay(1); 163 } while (--timeout > 0); 164 165 if (timeout <= 0) { 166 return -ETIMEDOUT; 167 } 168 169 return 0; 170 } 171 172 173 static int ufshc_reset(uintptr_t base) 174 { 175 unsigned int data; 176 int retries, result; 177 178 /* disable controller if enabled */ 179 if (mmio_read_32(base + HCE) & HCE_ENABLE) { 180 result = ufshc_hce_disable(base); 181 if (result != 0) { 182 return -EIO; 183 } 184 } 185 186 for (retries = 0; retries < HCE_ENABLE_OUTER_RETRIES; ++retries) { 187 result = ufshc_hce_enable(base); 188 if (result == 0) { 189 break; 190 } 191 } 192 if (retries >= HCE_ENABLE_OUTER_RETRIES) { 193 return -EIO; 194 } 195 196 /* Enable Interrupts */ 197 data = UFS_INT_UCCS | UFS_INT_ULSS | UFS_INT_UE | UFS_INT_UTPES | 198 UFS_INT_DFES | UFS_INT_HCFES | UFS_INT_SBFES; 199 mmio_write_32(base + IE, data); 200 201 return 0; 202 } 203 204 static int ufshc_dme_link_startup(uintptr_t base) 205 { 206 uic_cmd_t cmd; 207 208 memset(&cmd, 0, sizeof(cmd)); 209 cmd.op = DME_LINKSTARTUP; 210 return ufshc_send_uic_cmd(base, &cmd); 211 } 212 213 static int ufshc_link_startup(uintptr_t base) 214 { 215 int data, result; 216 int retries; 217 218 for (retries = DME_LINKSTARTUP_RETRIES; retries > 0; retries--) { 219 result = ufshc_dme_link_startup(base); 220 if (result != 0) { 221 /* Reset controller before trying again */ 222 result = ufshc_reset(base); 223 if (result != 0) { 224 return result; 225 } 226 continue; 227 } 228 assert(mmio_read_32(base + HCS) & HCS_DP); 229 data = mmio_read_32(base + IS); 230 if (data & UFS_INT_ULSS) 231 mmio_write_32(base + IS, UFS_INT_ULSS); 232 return 0; 233 } 234 return -EIO; 235 } 236 237 /* Read Door Bell register to check if slot zero is available */ 238 static int is_slot_available(void) 239 { 240 if (mmio_read_32(ufs_params.reg_base + UTRLDBR) & 0x1) { 241 return -EBUSY; 242 } 243 return 0; 244 } 245 246 static void get_utrd(utp_utrd_t *utrd) 247 { 248 uintptr_t base; 249 int result; 250 utrd_header_t *hd; 251 252 assert(utrd != NULL); 253 result = is_slot_available(); 254 assert(result == 0); 255 256 /* clear utrd */ 257 memset((void *)utrd, 0, sizeof(utp_utrd_t)); 258 base = ufs_params.desc_base; 259 /* clear the descriptor */ 260 memset((void *)base, 0, UFS_DESC_SIZE); 261 262 utrd->header = base; 263 utrd->task_tag = 1; /* We always use the first slot */ 264 /* CDB address should be aligned with 128 bytes */ 265 utrd->upiu = ALIGN_CDB(utrd->header + sizeof(utrd_header_t)); 266 utrd->resp_upiu = ALIGN_8(utrd->upiu + sizeof(cmd_upiu_t)); 267 utrd->size_upiu = utrd->resp_upiu - utrd->upiu; 268 utrd->size_resp_upiu = ALIGN_8(sizeof(resp_upiu_t)); 269 utrd->prdt = utrd->resp_upiu + utrd->size_resp_upiu; 270 271 hd = (utrd_header_t *)utrd->header; 272 hd->ucdba = utrd->upiu & UINT32_MAX; 273 hd->ucdbau = (utrd->upiu >> 32) & UINT32_MAX; 274 /* Both RUL and RUO is based on DWORD */ 275 hd->rul = utrd->size_resp_upiu >> 2; 276 hd->ruo = utrd->size_upiu >> 2; 277 (void)result; 278 } 279 280 /* 281 * Prepare UTRD, Command UPIU, Response UPIU. 282 */ 283 static int ufs_prepare_cmd(utp_utrd_t *utrd, uint8_t op, uint8_t lun, 284 int lba, uintptr_t buf, size_t length) 285 { 286 utrd_header_t *hd; 287 cmd_upiu_t *upiu; 288 prdt_t *prdt; 289 unsigned int ulba; 290 unsigned int lba_cnt; 291 int prdt_size; 292 293 hd = (utrd_header_t *)utrd->header; 294 upiu = (cmd_upiu_t *)utrd->upiu; 295 296 hd->i = 1; 297 hd->ct = CT_UFS_STORAGE; 298 hd->ocs = OCS_MASK; 299 300 upiu->trans_type = CMD_UPIU; 301 upiu->task_tag = utrd->task_tag; 302 upiu->cdb[0] = op; 303 ulba = (unsigned int)lba; 304 lba_cnt = (unsigned int)(length >> UFS_BLOCK_SHIFT); 305 switch (op) { 306 case CDBCMD_TEST_UNIT_READY: 307 break; 308 case CDBCMD_READ_CAPACITY_10: 309 hd->dd = DD_OUT; 310 upiu->flags = UPIU_FLAGS_R | UPIU_FLAGS_ATTR_S; 311 upiu->lun = lun; 312 break; 313 case CDBCMD_READ_10: 314 hd->dd = DD_OUT; 315 upiu->flags = UPIU_FLAGS_R | UPIU_FLAGS_ATTR_S; 316 upiu->lun = lun; 317 upiu->cdb[1] = RW_WITHOUT_CACHE; 318 /* set logical block address */ 319 upiu->cdb[2] = (ulba >> 24) & 0xff; 320 upiu->cdb[3] = (ulba >> 16) & 0xff; 321 upiu->cdb[4] = (ulba >> 8) & 0xff; 322 upiu->cdb[5] = ulba & 0xff; 323 /* set transfer length */ 324 upiu->cdb[7] = (lba_cnt >> 8) & 0xff; 325 upiu->cdb[8] = lba_cnt & 0xff; 326 break; 327 case CDBCMD_WRITE_10: 328 hd->dd = DD_IN; 329 upiu->flags = UPIU_FLAGS_W | UPIU_FLAGS_ATTR_S; 330 upiu->lun = lun; 331 upiu->cdb[1] = RW_WITHOUT_CACHE; 332 /* set logical block address */ 333 upiu->cdb[2] = (ulba >> 24) & 0xff; 334 upiu->cdb[3] = (ulba >> 16) & 0xff; 335 upiu->cdb[4] = (ulba >> 8) & 0xff; 336 upiu->cdb[5] = ulba & 0xff; 337 /* set transfer length */ 338 upiu->cdb[7] = (lba_cnt >> 8) & 0xff; 339 upiu->cdb[8] = lba_cnt & 0xff; 340 break; 341 default: 342 assert(0); 343 break; 344 } 345 if (hd->dd == DD_IN) 346 flush_dcache_range(buf, length); 347 else if (hd->dd == DD_OUT) 348 inv_dcache_range(buf, length); 349 if (length) { 350 upiu->exp_data_trans_len = htobe32(length); 351 assert(lba_cnt <= UINT16_MAX); 352 prdt = (prdt_t *)utrd->prdt; 353 354 prdt_size = 0; 355 while (length > 0) { 356 prdt->dba = (unsigned int)(buf & UINT32_MAX); 357 prdt->dbau = (unsigned int)((buf >> 32) & UINT32_MAX); 358 /* prdt->dbc counts from 0 */ 359 if (length > MAX_PRDT_SIZE) { 360 prdt->dbc = MAX_PRDT_SIZE - 1; 361 length = length - MAX_PRDT_SIZE; 362 } else { 363 prdt->dbc = length - 1; 364 length = 0; 365 } 366 buf += MAX_PRDT_SIZE; 367 prdt++; 368 prdt_size += sizeof(prdt_t); 369 } 370 utrd->size_prdt = ALIGN_8(prdt_size); 371 hd->prdtl = utrd->size_prdt >> 2; 372 hd->prdto = (utrd->size_upiu + utrd->size_resp_upiu) >> 2; 373 } 374 375 flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE); 376 return 0; 377 } 378 379 static int ufs_prepare_query(utp_utrd_t *utrd, uint8_t op, uint8_t idn, 380 uint8_t index, uint8_t sel, 381 uintptr_t buf, size_t length) 382 { 383 utrd_header_t *hd; 384 query_upiu_t *query_upiu; 385 386 387 hd = (utrd_header_t *)utrd->header; 388 query_upiu = (query_upiu_t *)utrd->upiu; 389 390 hd->i = 1; 391 hd->ct = CT_UFS_STORAGE; 392 hd->ocs = OCS_MASK; 393 394 query_upiu->trans_type = QUERY_REQUEST_UPIU; 395 query_upiu->task_tag = utrd->task_tag; 396 query_upiu->ts.desc.opcode = op; 397 query_upiu->ts.desc.idn = idn; 398 query_upiu->ts.desc.index = index; 399 query_upiu->ts.desc.selector = sel; 400 switch (op) { 401 case QUERY_READ_DESC: 402 query_upiu->query_func = QUERY_FUNC_STD_READ; 403 query_upiu->ts.desc.length = htobe16(length); 404 break; 405 case QUERY_WRITE_DESC: 406 query_upiu->query_func = QUERY_FUNC_STD_WRITE; 407 query_upiu->ts.desc.length = htobe16(length); 408 memcpy((void *)(utrd->upiu + sizeof(query_upiu_t)), 409 (void *)buf, length); 410 break; 411 case QUERY_READ_ATTR: 412 case QUERY_READ_FLAG: 413 query_upiu->query_func = QUERY_FUNC_STD_READ; 414 break; 415 case QUERY_CLEAR_FLAG: 416 case QUERY_SET_FLAG: 417 query_upiu->query_func = QUERY_FUNC_STD_WRITE; 418 break; 419 case QUERY_WRITE_ATTR: 420 query_upiu->query_func = QUERY_FUNC_STD_WRITE; 421 query_upiu->ts.attr.value = htobe32(*((uint32_t *)buf)); 422 break; 423 default: 424 assert(0); 425 break; 426 } 427 flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE); 428 return 0; 429 } 430 431 static void ufs_prepare_nop_out(utp_utrd_t *utrd) 432 { 433 utrd_header_t *hd; 434 nop_out_upiu_t *nop_out; 435 436 hd = (utrd_header_t *)utrd->header; 437 nop_out = (nop_out_upiu_t *)utrd->upiu; 438 439 hd->i = 1; 440 hd->ct = CT_UFS_STORAGE; 441 hd->ocs = OCS_MASK; 442 443 nop_out->trans_type = 0; 444 nop_out->task_tag = utrd->task_tag; 445 flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE); 446 } 447 448 static void ufs_send_request(int task_tag) 449 { 450 unsigned int data; 451 int slot; 452 453 slot = task_tag - 1; 454 /* clear all interrupts */ 455 mmio_write_32(ufs_params.reg_base + IS, ~0); 456 457 mmio_write_32(ufs_params.reg_base + UTRLRSR, 1); 458 assert(mmio_read_32(ufs_params.reg_base + UTRLRSR) == 1); 459 460 data = UTRIACR_IAEN | UTRIACR_CTR | UTRIACR_IACTH(0x1F) | 461 UTRIACR_IATOVAL(0xFF); 462 mmio_write_32(ufs_params.reg_base + UTRIACR, data); 463 /* send request */ 464 mmio_setbits_32(ufs_params.reg_base + UTRLDBR, 1 << slot); 465 } 466 467 static int ufs_check_resp(utp_utrd_t *utrd, int trans_type) 468 { 469 utrd_header_t *hd; 470 resp_upiu_t *resp; 471 sense_data_t *sense; 472 unsigned int data; 473 int slot; 474 475 hd = (utrd_header_t *)utrd->header; 476 resp = (resp_upiu_t *)utrd->resp_upiu; 477 do { 478 data = mmio_read_32(ufs_params.reg_base + IS); 479 if ((data & ~(UFS_INT_UCCS | UFS_INT_UTRCS)) != 0) 480 return -EIO; 481 } while ((data & UFS_INT_UTRCS) == 0); 482 slot = utrd->task_tag - 1; 483 484 data = mmio_read_32(ufs_params.reg_base + UTRLDBR); 485 assert((data & (1 << slot)) == 0); 486 /* 487 * Invalidate the header after DMA read operation has 488 * completed to avoid cpu referring to the prefetched 489 * data brought in before DMA completion. 490 */ 491 inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE); 492 assert(hd->ocs == OCS_SUCCESS); 493 assert((resp->trans_type & TRANS_TYPE_CODE_MASK) == trans_type); 494 495 sense = &resp->sd.sense; 496 if (sense->resp_code == SENSE_DATA_VALID && 497 sense->sense_key == SENSE_KEY_UNIT_ATTENTION && sense->asc == 0x29 && 498 sense->ascq == 0) { 499 WARN("Unit Attention Condition\n"); 500 return -EAGAIN; 501 } 502 503 (void)resp; 504 (void)slot; 505 return 0; 506 } 507 508 static void ufs_send_cmd(utp_utrd_t *utrd, uint8_t cmd_op, uint8_t lun, int lba, uintptr_t buf, 509 size_t length) 510 { 511 int result, i; 512 513 for (i = 0; i < UFS_CMD_RETRIES; ++i) { 514 get_utrd(utrd); 515 result = ufs_prepare_cmd(utrd, cmd_op, lun, lba, buf, length); 516 assert(result == 0); 517 ufs_send_request(utrd->task_tag); 518 result = ufs_check_resp(utrd, RESPONSE_UPIU); 519 if (result == 0 || result == -EIO) { 520 break; 521 } 522 } 523 assert(result == 0); 524 (void)result; 525 } 526 527 #ifdef UFS_RESP_DEBUG 528 static void dump_upiu(utp_utrd_t *utrd) 529 { 530 utrd_header_t *hd; 531 int i; 532 533 hd = (utrd_header_t *)utrd->header; 534 INFO("utrd:0x%x, ruo:0x%x, rul:0x%x, ocs:0x%x, UTRLDBR:0x%x\n", 535 (unsigned int)(uintptr_t)utrd, hd->ruo, hd->rul, hd->ocs, 536 mmio_read_32(ufs_params.reg_base + UTRLDBR)); 537 for (i = 0; i < sizeof(utrd_header_t); i += 4) { 538 INFO("[%lx]:0x%x\n", 539 (uintptr_t)utrd->header + i, 540 *(unsigned int *)((uintptr_t)utrd->header + i)); 541 } 542 543 for (i = 0; i < sizeof(cmd_upiu_t); i += 4) { 544 INFO("cmd[%lx]:0x%x\n", 545 utrd->upiu + i, 546 *(unsigned int *)(utrd->upiu + i)); 547 } 548 for (i = 0; i < sizeof(resp_upiu_t); i += 4) { 549 INFO("resp[%lx]:0x%x\n", 550 utrd->resp_upiu + i, 551 *(unsigned int *)(utrd->resp_upiu + i)); 552 } 553 for (i = 0; i < sizeof(prdt_t); i += 4) { 554 INFO("prdt[%lx]:0x%x\n", 555 utrd->prdt + i, 556 *(unsigned int *)(utrd->prdt + i)); 557 } 558 } 559 #endif 560 561 static void ufs_verify_init(void) 562 { 563 utp_utrd_t utrd; 564 int result; 565 566 get_utrd(&utrd); 567 ufs_prepare_nop_out(&utrd); 568 ufs_send_request(utrd.task_tag); 569 result = ufs_check_resp(&utrd, NOP_IN_UPIU); 570 assert(result == 0); 571 (void)result; 572 } 573 574 static void ufs_verify_ready(void) 575 { 576 utp_utrd_t utrd; 577 ufs_send_cmd(&utrd, CDBCMD_TEST_UNIT_READY, 0, 0, 0, 0); 578 } 579 580 static void ufs_query(uint8_t op, uint8_t idn, uint8_t index, uint8_t sel, 581 uintptr_t buf, size_t size) 582 { 583 utp_utrd_t utrd; 584 query_resp_upiu_t *resp; 585 int result; 586 587 switch (op) { 588 case QUERY_READ_FLAG: 589 case QUERY_READ_ATTR: 590 case QUERY_READ_DESC: 591 case QUERY_WRITE_DESC: 592 case QUERY_WRITE_ATTR: 593 assert(((buf & 3) == 0) && (size != 0)); 594 break; 595 default: 596 /* Do nothing in default case */ 597 break; 598 } 599 get_utrd(&utrd); 600 ufs_prepare_query(&utrd, op, idn, index, sel, buf, size); 601 ufs_send_request(utrd.task_tag); 602 result = ufs_check_resp(&utrd, QUERY_RESPONSE_UPIU); 603 assert(result == 0); 604 resp = (query_resp_upiu_t *)utrd.resp_upiu; 605 #ifdef UFS_RESP_DEBUG 606 dump_upiu(&utrd); 607 #endif 608 assert(resp->query_resp == QUERY_RESP_SUCCESS); 609 610 switch (op) { 611 case QUERY_READ_FLAG: 612 *(uint32_t *)buf = (uint32_t)resp->ts.flag.value; 613 break; 614 case QUERY_READ_DESC: 615 memcpy((void *)buf, 616 (void *)(utrd.resp_upiu + sizeof(query_resp_upiu_t)), 617 size); 618 break; 619 case QUERY_READ_ATTR: 620 *(uint32_t *)buf = htobe32(resp->ts.attr.value); 621 break; 622 default: 623 /* Do nothing in default case */ 624 break; 625 } 626 (void)result; 627 } 628 629 unsigned int ufs_read_attr(int idn) 630 { 631 unsigned int value; 632 633 ufs_query(QUERY_READ_ATTR, idn, 0, 0, 634 (uintptr_t)&value, sizeof(value)); 635 return value; 636 } 637 638 void ufs_write_attr(int idn, unsigned int value) 639 { 640 ufs_query(QUERY_WRITE_ATTR, idn, 0, 0, 641 (uintptr_t)&value, sizeof(value)); 642 } 643 644 unsigned int ufs_read_flag(int idn) 645 { 646 unsigned int value; 647 648 ufs_query(QUERY_READ_FLAG, idn, 0, 0, 649 (uintptr_t)&value, sizeof(value)); 650 return value; 651 } 652 653 void ufs_set_flag(int idn) 654 { 655 ufs_query(QUERY_SET_FLAG, idn, 0, 0, 0, 0); 656 } 657 658 void ufs_clear_flag(int idn) 659 { 660 ufs_query(QUERY_CLEAR_FLAG, idn, 0, 0, 0, 0); 661 } 662 663 void ufs_read_desc(int idn, int index, uintptr_t buf, size_t size) 664 { 665 ufs_query(QUERY_READ_DESC, idn, index, 0, buf, size); 666 } 667 668 void ufs_write_desc(int idn, int index, uintptr_t buf, size_t size) 669 { 670 ufs_query(QUERY_WRITE_DESC, idn, index, 0, buf, size); 671 } 672 673 static int ufs_read_capacity(int lun, unsigned int *num, unsigned int *size) 674 { 675 utp_utrd_t utrd; 676 resp_upiu_t *resp; 677 sense_data_t *sense; 678 unsigned char data[CACHE_WRITEBACK_GRANULE << 1]; 679 uintptr_t buf; 680 int retries = UFS_READ_CAPACITY_RETRIES; 681 682 assert((ufs_params.reg_base != 0) && 683 (ufs_params.desc_base != 0) && 684 (ufs_params.desc_size >= UFS_DESC_SIZE) && 685 (num != NULL) && (size != NULL)); 686 687 /* align buf address */ 688 buf = (uintptr_t)data; 689 buf = (buf + CACHE_WRITEBACK_GRANULE - 1) & 690 ~(CACHE_WRITEBACK_GRANULE - 1); 691 do { 692 ufs_send_cmd(&utrd, CDBCMD_READ_CAPACITY_10, lun, 0, 693 buf, READ_CAPACITY_LENGTH); 694 #ifdef UFS_RESP_DEBUG 695 dump_upiu(&utrd); 696 #endif 697 resp = (resp_upiu_t *)utrd.resp_upiu; 698 sense = &resp->sd.sense; 699 if (!((sense->resp_code == SENSE_DATA_VALID) && 700 (sense->sense_key == SENSE_KEY_UNIT_ATTENTION) && 701 (sense->asc == 0x29) && (sense->ascq == 0))) { 702 inv_dcache_range(buf, CACHE_WRITEBACK_GRANULE); 703 /* last logical block address */ 704 *num = be32toh(*(unsigned int *)buf); 705 if (*num) 706 *num += 1; 707 /* logical block length in bytes */ 708 *size = be32toh(*(unsigned int *)(buf + 4)); 709 710 return 0; 711 } 712 713 } while (retries-- > 0); 714 715 return -ETIMEDOUT; 716 } 717 718 size_t ufs_read_blocks(int lun, int lba, uintptr_t buf, size_t size) 719 { 720 utp_utrd_t utrd; 721 resp_upiu_t *resp; 722 723 assert((ufs_params.reg_base != 0) && 724 (ufs_params.desc_base != 0) && 725 (ufs_params.desc_size >= UFS_DESC_SIZE)); 726 727 ufs_send_cmd(&utrd, CDBCMD_READ_10, lun, lba, buf, size); 728 #ifdef UFS_RESP_DEBUG 729 dump_upiu(&utrd); 730 #endif 731 /* 732 * Invalidate prefetched cache contents before cpu 733 * accesses the buf. 734 */ 735 inv_dcache_range(buf, size); 736 resp = (resp_upiu_t *)utrd.resp_upiu; 737 return size - resp->res_trans_cnt; 738 } 739 740 size_t ufs_write_blocks(int lun, int lba, const uintptr_t buf, size_t size) 741 { 742 utp_utrd_t utrd; 743 resp_upiu_t *resp; 744 745 assert((ufs_params.reg_base != 0) && 746 (ufs_params.desc_base != 0) && 747 (ufs_params.desc_size >= UFS_DESC_SIZE)); 748 749 ufs_send_cmd(&utrd, CDBCMD_WRITE_10, lun, lba, buf, size); 750 #ifdef UFS_RESP_DEBUG 751 dump_upiu(&utrd); 752 #endif 753 resp = (resp_upiu_t *)utrd.resp_upiu; 754 return size - resp->res_trans_cnt; 755 } 756 757 static int ufs_set_fdevice_init(void) 758 { 759 unsigned int result; 760 int timeout; 761 762 ufs_set_flag(FLAG_DEVICE_INIT); 763 764 timeout = FDEVICEINIT_TIMEOUT_MS; 765 do { 766 result = ufs_read_flag(FLAG_DEVICE_INIT); 767 if (!result) { 768 break; 769 } 770 mdelay(5); 771 timeout -= 5; 772 } while (timeout > 0); 773 774 if (result != 0U) { 775 return -ETIMEDOUT; 776 } 777 778 return 0; 779 } 780 781 static void ufs_enum(void) 782 { 783 unsigned int blk_num, blk_size; 784 int i, result; 785 786 mmio_write_32(ufs_params.reg_base + UTRLBA, 787 ufs_params.desc_base & UINT32_MAX); 788 mmio_write_32(ufs_params.reg_base + UTRLBAU, 789 (ufs_params.desc_base >> 32) & UINT32_MAX); 790 791 ufs_verify_init(); 792 ufs_verify_ready(); 793 794 result = ufs_set_fdevice_init(); 795 assert(result == 0); 796 797 blk_num = 0; 798 blk_size = 0; 799 800 /* dump available LUNs */ 801 for (i = 0; i < UFS_MAX_LUNS; i++) { 802 result = ufs_read_capacity(i, &blk_num, &blk_size); 803 if (result != 0) { 804 WARN("UFS LUN%d dump failed\n", i); 805 } 806 if (blk_num && blk_size) { 807 INFO("UFS LUN%d contains %d blocks with %d-byte size\n", 808 i, blk_num, blk_size); 809 } 810 } 811 812 (void)result; 813 } 814 815 static void ufs_get_device_info(struct ufs_dev_desc *card_data) 816 { 817 uint8_t desc_buf[DESC_DEVICE_MAX_SIZE]; 818 819 ufs_query(QUERY_READ_DESC, DESC_TYPE_DEVICE, 0, 0, 820 (uintptr_t)desc_buf, DESC_DEVICE_MAX_SIZE); 821 822 /* 823 * getting vendor (manufacturerID) and Bank Index in big endian 824 * format 825 */ 826 card_data->wmanufacturerid = (uint16_t)((desc_buf[DEVICE_DESC_PARAM_MANF_ID] << 8) | 827 (desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1])); 828 } 829 830 int ufs_init(const ufs_ops_t *ops, ufs_params_t *params) 831 { 832 int result; 833 unsigned int data; 834 uic_cmd_t cmd; 835 struct ufs_dev_desc card = {0}; 836 837 assert((params != NULL) && 838 (params->reg_base != 0) && 839 (params->desc_base != 0) && 840 (params->desc_size >= UFS_DESC_SIZE)); 841 842 memcpy(&ufs_params, params, sizeof(ufs_params_t)); 843 844 /* 0 means 1 slot */ 845 nutrs = (mmio_read_32(ufs_params.reg_base + CAP) & CAP_NUTRS_MASK) + 1; 846 if (nutrs > (ufs_params.desc_size / UFS_DESC_SIZE)) { 847 nutrs = ufs_params.desc_size / UFS_DESC_SIZE; 848 } 849 850 851 if (ufs_params.flags & UFS_FLAGS_SKIPINIT) { 852 mmio_write_32(ufs_params.reg_base + UTRLBA, 853 ufs_params.desc_base & UINT32_MAX); 854 mmio_write_32(ufs_params.reg_base + UTRLBAU, 855 (ufs_params.desc_base >> 32) & UINT32_MAX); 856 857 result = ufshc_dme_get(0x1571, 0, &data); 858 assert(result == 0); 859 result = ufshc_dme_get(0x41, 0, &data); 860 assert(result == 0); 861 if (data == 1) { 862 /* prepare to exit hibernate mode */ 863 memset(&cmd, 0, sizeof(uic_cmd_t)); 864 cmd.op = DME_HIBERNATE_EXIT; 865 result = ufshc_send_uic_cmd(ufs_params.reg_base, 866 &cmd); 867 assert(result == 0); 868 data = mmio_read_32(ufs_params.reg_base + UCMDARG2); 869 assert(data == 0); 870 do { 871 data = mmio_read_32(ufs_params.reg_base + IS); 872 } while ((data & UFS_INT_UHXS) == 0); 873 mmio_write_32(ufs_params.reg_base + IS, UFS_INT_UHXS); 874 data = mmio_read_32(ufs_params.reg_base + HCS); 875 assert((data & HCS_UPMCRS_MASK) == HCS_PWR_LOCAL); 876 } 877 result = ufshc_dme_get(0x1568, 0, &data); 878 assert(result == 0); 879 assert((data > 0) && (data <= 3)); 880 } else { 881 assert((ops != NULL) && (ops->phy_init != NULL) && 882 (ops->phy_set_pwr_mode != NULL)); 883 884 result = ufshc_reset(ufs_params.reg_base); 885 assert(result == 0); 886 ops->phy_init(&ufs_params); 887 result = ufshc_link_startup(ufs_params.reg_base); 888 assert(result == 0); 889 890 ufs_enum(); 891 892 ufs_get_device_info(&card); 893 if (card.wmanufacturerid == UFS_VENDOR_SKHYNIX) { 894 ufs_params.flags |= UFS_FLAGS_VENDOR_SKHYNIX; 895 } 896 897 ops->phy_set_pwr_mode(&ufs_params); 898 } 899 900 (void)result; 901 return 0; 902 } 903