1 /*- 2 * Copyright (c) 2025, Samsung Electronics Co., Ltd. 3 * Written by Jaeyoon Choi 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8 #include <sys/param.h> 9 #include <sys/bus.h> 10 #include <sys/conf.h> 11 12 #include "ufshci_private.h" 13 #include "ufshci_reg.h" 14 15 static int 16 ufshci_dev_send_query(struct ufshci_controller *ctrlr, 17 struct ufshci_query_param param, 18 struct ufshci_completion_poll_status *status, const char *fail_msg) 19 { 20 int error; 21 22 status->done = 0; 23 error = ufshci_ctrlr_cmd_send_query_request(ctrlr, 24 ufshci_completion_poll_cb, status, param); 25 if (error) 26 return (error); 27 28 ufshci_completion_poll(status); 29 if (status->error) { 30 ufshci_printf(ctrlr, "%s failed!\n", fail_msg); 31 return (ENXIO); 32 } 33 34 return (0); 35 } 36 37 static int 38 ufshci_dev_read_descriptor(struct ufshci_controller *ctrlr, 39 enum ufshci_descriptor_type desc_type, uint8_t index, uint8_t selector, 40 void *desc, size_t desc_size) 41 { 42 struct ufshci_completion_poll_status status; 43 struct ufshci_query_param param; 44 int error; 45 46 param.function = UFSHCI_QUERY_FUNC_STANDARD_READ_REQUEST; 47 param.opcode = UFSHCI_QUERY_OPCODE_READ_DESCRIPTOR; 48 param.type = desc_type; 49 param.index = index; 50 param.selector = selector; 51 param.value = 0; 52 param.desc_size = desc_size; 53 54 error = ufshci_dev_send_query(ctrlr, param, &status, __func__); 55 if (error) 56 return (error); 57 58 memcpy(desc, status.cpl.response_upiu.query_response_upiu.command_data, 59 desc_size); 60 61 return (0); 62 } 63 64 static int 65 ufshci_dev_read_device_descriptor(struct ufshci_controller *ctrlr, 66 struct ufshci_device_descriptor *desc) 67 { 68 return (ufshci_dev_read_descriptor(ctrlr, UFSHCI_DESC_TYPE_DEVICE, 0, 0, 69 desc, sizeof(struct ufshci_device_descriptor))); 70 } 71 72 static int 73 ufshci_dev_read_geometry_descriptor(struct ufshci_controller *ctrlr, 74 struct ufshci_geometry_descriptor *desc) 75 { 76 return (ufshci_dev_read_descriptor(ctrlr, UFSHCI_DESC_TYPE_GEOMETRY, 0, 77 0, desc, sizeof(struct ufshci_geometry_descriptor))); 78 } 79 80 static int 81 ufshci_dev_read_unit_descriptor(struct ufshci_controller *ctrlr, uint8_t lun, 82 struct ufshci_unit_descriptor *desc) 83 { 84 return (ufshci_dev_read_descriptor(ctrlr, UFSHCI_DESC_TYPE_UNIT, lun, 0, 85 desc, sizeof(struct ufshci_unit_descriptor))); 86 } 87 88 static int 89 ufshci_dev_read_flag(struct ufshci_controller *ctrlr, 90 enum ufshci_flags flag_type, uint8_t *flag) 91 { 92 struct ufshci_completion_poll_status status; 93 struct ufshci_query_param param; 94 int error; 95 96 param.function = UFSHCI_QUERY_FUNC_STANDARD_READ_REQUEST; 97 param.opcode = UFSHCI_QUERY_OPCODE_READ_FLAG; 98 param.type = flag_type; 99 param.index = 0; 100 param.selector = 0; 101 param.value = 0; 102 param.desc_size = 0; 103 104 error = ufshci_dev_send_query(ctrlr, param, &status, __func__); 105 if (error) 106 return (error); 107 108 *flag = status.cpl.response_upiu.query_response_upiu.flag_value; 109 110 return (0); 111 } 112 113 static int 114 ufshci_dev_set_flag(struct ufshci_controller *ctrlr, 115 enum ufshci_flags flag_type) 116 { 117 struct ufshci_completion_poll_status status; 118 struct ufshci_query_param param; 119 120 param.function = UFSHCI_QUERY_FUNC_STANDARD_WRITE_REQUEST; 121 param.opcode = UFSHCI_QUERY_OPCODE_SET_FLAG; 122 param.type = flag_type; 123 param.index = 0; 124 param.selector = 0; 125 param.value = 0; 126 param.desc_size = 0; 127 128 return (ufshci_dev_send_query(ctrlr, param, &status, __func__)); 129 } 130 131 static int 132 ufshci_dev_clear_flag(struct ufshci_controller *ctrlr, 133 enum ufshci_flags flag_type) 134 { 135 struct ufshci_completion_poll_status status; 136 struct ufshci_query_param param; 137 138 param.function = UFSHCI_QUERY_FUNC_STANDARD_WRITE_REQUEST; 139 param.opcode = UFSHCI_QUERY_OPCODE_CLEAR_FLAG; 140 param.type = flag_type; 141 param.index = 0; 142 param.selector = 0; 143 param.value = 0; 144 param.desc_size = 0; 145 146 return (ufshci_dev_send_query(ctrlr, param, &status, __func__)); 147 } 148 149 static int 150 ufshci_dev_read_attribute(struct ufshci_controller *ctrlr, 151 enum ufshci_attributes attr_type, uint8_t index, uint8_t selector, 152 uint64_t *value) 153 { 154 struct ufshci_completion_poll_status status; 155 struct ufshci_query_param param; 156 int error; 157 158 param.function = UFSHCI_QUERY_FUNC_STANDARD_READ_REQUEST; 159 param.opcode = UFSHCI_QUERY_OPCODE_READ_ATTRIBUTE; 160 param.type = attr_type; 161 param.index = index; 162 param.selector = selector; 163 param.value = 0; 164 param.desc_size = 0; 165 166 error = ufshci_dev_send_query(ctrlr, param, &status, __func__); 167 if (error) 168 return (error); 169 170 *value = be64toh(status.cpl.response_upiu.query_response_upiu.value_64); 171 172 return (0); 173 } 174 175 static int 176 ufshci_dev_write_attribute(struct ufshci_controller *ctrlr, 177 enum ufshci_attributes attr_type, uint8_t index, uint8_t selector, 178 uint64_t value) 179 { 180 struct ufshci_completion_poll_status status; 181 struct ufshci_query_param param; 182 183 param.function = UFSHCI_QUERY_FUNC_STANDARD_WRITE_REQUEST; 184 param.opcode = UFSHCI_QUERY_OPCODE_WRITE_ATTRIBUTE; 185 param.type = attr_type; 186 param.index = index; 187 param.selector = selector; 188 param.value = value; 189 param.desc_size = 0; 190 191 return (ufshci_dev_send_query(ctrlr, param, &status, __func__)); 192 } 193 194 int 195 ufshci_dev_init(struct ufshci_controller *ctrlr) 196 { 197 int timeout = ticks + MSEC_2_TICKS(ctrlr->device_init_timeout_in_ms); 198 sbintime_t delta_t = SBT_1US; 199 uint8_t flag; 200 int error; 201 const uint8_t device_init_completed = 0; 202 203 error = ufshci_dev_set_flag(ctrlr, UFSHCI_FLAG_F_DEVICE_INIT); 204 if (error) 205 return (error); 206 207 /* Wait for the UFSHCI_FLAG_F_DEVICE_INIT flag to change */ 208 while (1) { 209 error = ufshci_dev_read_flag(ctrlr, UFSHCI_FLAG_F_DEVICE_INIT, 210 &flag); 211 if (error) 212 return (error); 213 if (flag == device_init_completed) 214 break; 215 if (timeout - ticks < 0) { 216 ufshci_printf(ctrlr, 217 "device init did not become %d " 218 "within %d ms\n", 219 device_init_completed, 220 ctrlr->device_init_timeout_in_ms); 221 return (ENXIO); 222 } 223 224 pause_sbt("ufshciinit", delta_t, 0, C_PREL(1)); 225 delta_t = min(SBT_1MS, delta_t * 3 / 2); 226 } 227 228 return (0); 229 } 230 231 int 232 ufshci_dev_reset(struct ufshci_controller *ctrlr) 233 { 234 if (ufshci_uic_send_dme_endpoint_reset(ctrlr)) 235 return (ENXIO); 236 237 return (ufshci_dev_init(ctrlr)); 238 } 239 240 int 241 ufshci_dev_init_reference_clock(struct ufshci_controller *ctrlr) 242 { 243 int error; 244 uint8_t index, selector; 245 uint64_t value; 246 247 index = 0; /* bRefClkFreq is device type attribute */ 248 selector = 0; /* bRefClkFreq is device type attribute */ 249 250 /* 251 * bRefClkFreq is a persistent attribute. Skip the write when 252 * the device already holds the wanted value. 253 */ 254 error = ufshci_dev_read_attribute(ctrlr, UFSHCI_ATTR_B_REF_CLK_FREQ, 255 index, selector, &value); 256 if (error != 0) { 257 ufshci_printf(ctrlr, "bRefClkFreq read failed, writing %u\n", 258 ctrlr->ref_clk); 259 } else if ((uint32_t)value == ctrlr->ref_clk) { 260 return (0); 261 } else { 262 ufshci_printf(ctrlr, "changing bRefClkFreq from %u to %u\n", 263 (uint32_t)value, ctrlr->ref_clk); 264 } 265 266 error = ufshci_dev_write_attribute(ctrlr, UFSHCI_ATTR_B_REF_CLK_FREQ, 267 index, selector, ctrlr->ref_clk); 268 if (error) 269 return (error); 270 271 return (0); 272 } 273 274 int 275 ufshci_dev_init_unipro(struct ufshci_controller *ctrlr) 276 { 277 uint32_t pa_granularity, peer_pa_granularity; 278 uint32_t t_activate, pear_t_activate; 279 280 if (ctrlr->quirks & UFSHCI_QUIRK_LONG_PEER_PA_TACTIVATE) { 281 /* 282 * PA_Granularity: Granularity for PA_TActivate and 283 * PA_Hibern8Time 284 * - 1=1us, 2=4us, 3=8us, 4=16us, 5=32us, 6=100us 285 */ 286 if (ufshci_uic_send_dme_get(ctrlr, PA_Granularity, 287 &pa_granularity)) 288 return (ENXIO); 289 if (ufshci_uic_send_dme_peer_get(ctrlr, PA_Granularity, 290 &peer_pa_granularity)) 291 return (ENXIO); 292 293 /* 294 * PA_TActivate: Time to wait before activating a burst in order 295 * to wake-up peer M-RX UniPro automatically sets timing 296 * information such as PA_TActivate through the 297 * PACP_CAP_EXT1_ind command during Link Startup operation. 298 */ 299 if (ufshci_uic_send_dme_get(ctrlr, PA_TActivate, &t_activate)) 300 return (ENXIO); 301 if (ufshci_uic_send_dme_peer_get(ctrlr, PA_TActivate, 302 &pear_t_activate)) 303 return (ENXIO); 304 305 /* 306 * Intel Lake-field UFSHCI has a quirk. We need to add 200us to 307 * the PEER's PA_TActivate. 308 */ 309 if (pa_granularity == peer_pa_granularity) { 310 pear_t_activate = t_activate + 2; 311 if (ufshci_uic_send_dme_peer_set(ctrlr, PA_TActivate, 312 pear_t_activate)) 313 return (ENXIO); 314 } 315 } 316 317 return (0); 318 } 319 320 int 321 ufshci_dev_init_uic_power_mode(struct ufshci_controller *ctrlr) 322 { 323 /* 324 * TX/RX PWRMode: 325 * - TX[3:0], RX[7:4] 326 * - Fast Mode = 1, Slow Mode = 2, FastAuto Mode = 4, SlowAuto Mode = 5 327 */ 328 const uint32_t fast_mode = 1; 329 const uint32_t rx_bit_shift = 4; 330 uint32_t peer_granularity; 331 332 /* Update lanes with available TX/RX lanes */ 333 if (ufshci_uic_send_dme_get(ctrlr, PA_AvailTxDataLanes, 334 &ctrlr->max_tx_lanes)) 335 return (ENXIO); 336 if (ufshci_uic_send_dme_get(ctrlr, PA_AvailRxDataLanes, 337 &ctrlr->max_rx_lanes)) 338 return (ENXIO); 339 340 /* Get max HS-GEAR value */ 341 if (ufshci_uic_send_dme_get(ctrlr, PA_MaxRxHSGear, 342 &ctrlr->max_rx_hs_gear)) 343 return (ENXIO); 344 345 /* Set the data lane to max */ 346 ctrlr->tx_lanes = ctrlr->max_tx_lanes; 347 ctrlr->rx_lanes = ctrlr->max_rx_lanes; 348 if (ufshci_uic_send_dme_set(ctrlr, PA_ActiveTxDataLanes, 349 ctrlr->tx_lanes)) 350 return (ENXIO); 351 if (ufshci_uic_send_dme_set(ctrlr, PA_ActiveRxDataLanes, 352 ctrlr->rx_lanes)) 353 return (ENXIO); 354 355 if (ctrlr->quirks & UFSHCI_QUIRK_CHANGE_LANE_AND_GEAR_SEPARATELY) { 356 /* Before changing gears, first change the number of lanes. */ 357 if (ufshci_uic_send_dme_get(ctrlr, PA_PWRMode, 358 &ctrlr->tx_rx_power_mode)) 359 return (ENXIO); 360 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRMode, 361 ctrlr->tx_rx_power_mode)) 362 return (ENXIO); 363 364 /* Wait for power mode changed. */ 365 if (ufshci_uic_power_mode_ready(ctrlr)) { 366 ufshci_reg_dump(ctrlr); 367 return (ENXIO); 368 } 369 } 370 371 /* Set HS-GEAR to max gear */ 372 ctrlr->hs_gear = ctrlr->max_rx_hs_gear; 373 if (ufshci_uic_send_dme_set(ctrlr, PA_TxGear, ctrlr->hs_gear)) 374 return (ENXIO); 375 if (ufshci_uic_send_dme_set(ctrlr, PA_RxGear, ctrlr->hs_gear)) 376 return (ENXIO); 377 378 /* 379 * Set termination 380 * - HS-MODE = ON / LS-MODE = OFF 381 */ 382 if (ufshci_uic_send_dme_set(ctrlr, PA_TxTermination, true)) 383 return (ENXIO); 384 if (ufshci_uic_send_dme_set(ctrlr, PA_RxTermination, true)) 385 return (ENXIO); 386 387 /* Set HSSeries */ 388 if (ufshci_uic_send_dme_set(ctrlr, PA_HSSeries, ctrlr->hs_series)) 389 return (ENXIO); 390 391 /* HS-G4 and above need initial adaptation. */ 392 if (ctrlr->hs_gear >= 4 && 393 ufshci_uic_send_dme_set(ctrlr, PA_TxHsAdaptType, PA_INITIAL_ADAPT)) 394 return (ENXIO); 395 396 /* Set Timeout values */ 397 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRModeUserData0, 398 DL_FC0ProtectionTimeOutVal_Default)) 399 return (ENXIO); 400 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRModeUserData1, 401 DL_TC0ReplayTimeOutVal_Default)) 402 return (ENXIO); 403 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRModeUserData2, 404 DL_AFC0ReqTimeOutVal_Default)) 405 return (ENXIO); 406 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRModeUserData3, 407 DL_FC0ProtectionTimeOutVal_Default)) 408 return (ENXIO); 409 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRModeUserData4, 410 DL_TC0ReplayTimeOutVal_Default)) 411 return (ENXIO); 412 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRModeUserData5, 413 DL_AFC0ReqTimeOutVal_Default)) 414 return (ENXIO); 415 416 if (ufshci_uic_send_dme_set(ctrlr, DME_LocalFC0ProtectionTimeOutVal, 417 DL_FC0ProtectionTimeOutVal_Default)) 418 return (ENXIO); 419 if (ufshci_uic_send_dme_set(ctrlr, DME_LocalTC0ReplayTimeOutVal, 420 DL_TC0ReplayTimeOutVal_Default)) 421 return (ENXIO); 422 if (ufshci_uic_send_dme_set(ctrlr, DME_LocalAFC0ReqTimeOutVal, 423 DL_AFC0ReqTimeOutVal_Default)) 424 return (ENXIO); 425 426 /* Set TX/RX PWRMode */ 427 ctrlr->tx_rx_power_mode = (fast_mode << rx_bit_shift) | fast_mode; 428 if (ufshci_uic_send_dme_set(ctrlr, PA_PWRMode, ctrlr->tx_rx_power_mode)) 429 return (ENXIO); 430 431 /* Wait for power mode changed. */ 432 if (ufshci_uic_power_mode_ready(ctrlr)) { 433 ufshci_reg_dump(ctrlr); 434 return (ENXIO); 435 } 436 437 if (ctrlr->quirks & UFSHCI_QUIRK_WAIT_AFTER_POWER_MODE_CHANGE) { 438 /* 439 * Intel Lake-field UFSHCI has a quirk. 440 * We need to wait 1250us and clear dme error. 441 */ 442 pause_sbt("ufshci", ustosbt(1250), 0, C_PREL(1)); 443 444 /* Test with dme_peer_get to make sure there are no errors. */ 445 if (ufshci_uic_send_dme_peer_get(ctrlr, PA_Granularity, 446 &peer_granularity)) 447 return (ENXIO); 448 } 449 450 return (0); 451 } 452 453 void 454 ufshci_dev_enable_auto_hibernate(struct ufshci_controller *ctrlr) 455 { 456 if (!ctrlr->ufs_dev.auto_hibernation_supported) 457 return; 458 459 ufshci_mmio_write_4(ctrlr, ahit, ctrlr->ufs_dev.ahit); 460 } 461 462 void 463 ufshci_dev_init_auto_hibernate(struct ufshci_controller *ctrlr) 464 { 465 ctrlr->ufs_dev.auto_hibernation_supported = 466 UFSHCIV(UFSHCI_CAP_REG_AUTOH8, ctrlr->cap) && 467 !(ctrlr->quirks & UFSHCI_QUIRK_BROKEN_AUTO_HIBERNATE); 468 469 if (!ctrlr->ufs_dev.auto_hibernation_supported) 470 return; 471 472 /* The default value for auto hibernation is 150 ms */ 473 ctrlr->ufs_dev.ahit = 0; 474 ctrlr->ufs_dev.ahit |= UFSHCIF(UFSHCI_AHIT_REG_AH8ITV, 150); 475 ctrlr->ufs_dev.ahit |= UFSHCIF(UFSHCI_AHIT_REG_TS, 3); 476 477 ufshci_dev_enable_auto_hibernate(ctrlr); 478 } 479 480 void 481 ufshci_dev_init_uic_link_state(struct ufshci_controller *ctrlr) 482 { 483 ctrlr->ufs_dev.link_state = UFSHCI_UIC_LINK_STATE_ACTIVE; 484 } 485 486 int 487 ufshci_dev_init_ufs_power_mode(struct ufshci_controller *ctrlr) 488 { 489 ctrlr->ufs_dev.power_mode_supported = false; 490 491 if (ctrlr->quirks & UFSHCI_QUIRK_SKIP_WELL_KNOWN_LUNS) 492 return (0); 493 494 if (ctrlr->ufs_device_wlun_periph == NULL) { 495 /* The returned reference is kept by the cached pointer. */ 496 ctrlr->ufs_device_wlun_periph = ufshci_sim_find_periph(ctrlr, 497 UFSHCI_WLUN_UFS_DEVICE); 498 if (ctrlr->ufs_device_wlun_periph == NULL) { 499 ufshci_printf(ctrlr, 500 "Well-known LUN `UFS Device (0x50)` not found\n"); 501 return (0); 502 } 503 } 504 505 ctrlr->ufs_dev.power_mode_supported = true; 506 ctrlr->ufs_dev.power_mode = UFSHCI_DEV_PWR_ACTIVE; 507 508 return (0); 509 } 510 511 int 512 ufshci_dev_get_descriptor(struct ufshci_controller *ctrlr) 513 { 514 struct ufshci_device *device = &ctrlr->ufs_dev; 515 /* 516 * The kDeviceDensityUnit is defined in the spec as 512. 517 * qTotalRawDeviceCapacity use big-endian byte ordering. 518 */ 519 const uint32_t device_density_unit = 512; 520 uint32_t ver; 521 int error; 522 523 error = ufshci_dev_read_device_descriptor(ctrlr, &device->dev_desc); 524 if (error) 525 return (error); 526 527 ver = be16toh(device->dev_desc.wSpecVersion); 528 ufshci_printf(ctrlr, "UFS device spec version %u.%u.%u\n", 529 UFSHCIV(UFSHCI_VER_REG_MJR, ver), UFSHCIV(UFSHCI_VER_REG_MNR, ver), 530 UFSHCIV(UFSHCI_VER_REG_VS, ver)); 531 ufshci_printf(ctrlr, "%u enabled LUNs found\n", 532 device->dev_desc.bNumberLU); 533 534 error = ufshci_dev_read_geometry_descriptor(ctrlr, &device->geo_desc); 535 if (error) 536 return (error); 537 538 if (device->geo_desc.bMaxNumberLU == 0) { 539 device->max_lun_count = 8; 540 } else if (device->geo_desc.bMaxNumberLU == 1) { 541 device->max_lun_count = 32; 542 } else { 543 ufshci_printf(ctrlr, 544 "Invalid Geometry Descriptor bMaxNumberLU value=%d\n", 545 device->geo_desc.bMaxNumberLU); 546 return (ENXIO); 547 } 548 ctrlr->max_lun_count = device->max_lun_count; 549 550 ufshci_printf(ctrlr, "UFS device total size is %lu bytes\n", 551 be64toh(device->geo_desc.qTotalRawDeviceCapacity) * 552 device_density_unit); 553 554 return (0); 555 } 556 557 static int 558 ufshci_dev_enable_write_booster(struct ufshci_controller *ctrlr) 559 { 560 struct ufshci_device *dev = &ctrlr->ufs_dev; 561 int error; 562 563 /* Enable WriteBooster */ 564 error = ufshci_dev_set_flag(ctrlr, UFSHCI_FLAG_F_WRITE_BOOSTER_EN); 565 if (error) { 566 ufshci_printf(ctrlr, "Failed to enable WriteBooster\n"); 567 return (error); 568 } 569 dev->is_wb_enabled = true; 570 571 /* Enable WriteBooster buffer flush during hibernate */ 572 error = ufshci_dev_set_flag(ctrlr, 573 UFSHCI_FLAG_F_WB_BUFFER_FLUSH_DURING_HIBERNATE); 574 if (error) { 575 ufshci_printf(ctrlr, 576 "Failed to enable WriteBooster buffer flush during hibernate\n"); 577 return (error); 578 } 579 580 /* Enable WriteBooster buffer flush */ 581 error = ufshci_dev_set_flag(ctrlr, UFSHCI_FLAG_F_WB_BUFFER_FLUSH_EN); 582 if (error) { 583 ufshci_printf(ctrlr, 584 "Failed to enable WriteBooster buffer flush\n"); 585 return (error); 586 } 587 dev->is_wb_flush_enabled = true; 588 589 return (0); 590 } 591 592 static int 593 ufshci_dev_disable_write_booster(struct ufshci_controller *ctrlr) 594 { 595 struct ufshci_device *dev = &ctrlr->ufs_dev; 596 int error; 597 598 /* Disable WriteBooster buffer flush */ 599 error = ufshci_dev_clear_flag(ctrlr, UFSHCI_FLAG_F_WB_BUFFER_FLUSH_EN); 600 if (error) { 601 ufshci_printf(ctrlr, 602 "Failed to disable WriteBooster buffer flush\n"); 603 return (error); 604 } 605 dev->is_wb_flush_enabled = false; 606 607 /* Disable WriteBooster buffer flush during hibernate */ 608 error = ufshci_dev_clear_flag(ctrlr, 609 UFSHCI_FLAG_F_WB_BUFFER_FLUSH_DURING_HIBERNATE); 610 if (error) { 611 ufshci_printf(ctrlr, 612 "Failed to disable WriteBooster buffer flush during hibernate\n"); 613 return (error); 614 } 615 616 /* Disable WriteBooster */ 617 error = ufshci_dev_clear_flag(ctrlr, UFSHCI_FLAG_F_WRITE_BOOSTER_EN); 618 if (error) { 619 ufshci_printf(ctrlr, "Failed to disable WriteBooster\n"); 620 return (error); 621 } 622 dev->is_wb_enabled = false; 623 624 return (0); 625 } 626 627 static int 628 ufshci_dev_is_write_booster_buffer_life_time_left( 629 struct ufshci_controller *ctrlr, bool *is_life_time_left) 630 { 631 struct ufshci_device *dev = &ctrlr->ufs_dev; 632 uint8_t buffer_lun; 633 uint64_t life_time; 634 uint32_t error; 635 636 if (dev->wb_buffer_type == UFSHCI_DESC_WB_BUF_TYPE_LU_DEDICATED) 637 buffer_lun = dev->wb_dedicated_lu; 638 else 639 buffer_lun = 0; 640 641 error = ufshci_dev_read_attribute(ctrlr, 642 UFSHCI_ATTR_B_WB_BUFFER_LIFE_TIME_EST, buffer_lun, 0, &life_time); 643 if (error) 644 return (error); 645 646 *is_life_time_left = (life_time != UFSHCI_ATTR_WB_LIFE_EXCEEDED); 647 648 return (0); 649 } 650 651 /* 652 * This function is not yet in use. It will be used when suspend/resume is 653 * implemented. 654 */ 655 static __unused int 656 ufshci_dev_need_write_booster_buffer_flush(struct ufshci_controller *ctrlr, 657 bool *need_flush) 658 { 659 struct ufshci_device *dev = &ctrlr->ufs_dev; 660 bool is_life_time_left = false; 661 uint64_t available_buffer_size, current_buffer_size; 662 uint8_t buffer_lun; 663 uint32_t error; 664 665 *need_flush = false; 666 667 if (!dev->is_wb_enabled) 668 return (0); 669 670 error = ufshci_dev_is_write_booster_buffer_life_time_left(ctrlr, 671 &is_life_time_left); 672 if (error) 673 return (error); 674 675 if (!is_life_time_left) 676 return (ufshci_dev_disable_write_booster(ctrlr)); 677 678 if (dev->wb_buffer_type == UFSHCI_DESC_WB_BUF_TYPE_LU_DEDICATED) 679 buffer_lun = dev->wb_dedicated_lu; 680 else 681 buffer_lun = 0; 682 683 error = ufshci_dev_read_attribute(ctrlr, 684 UFSHCI_ATTR_B_AVAILABLE_WB_BUFFER_SIZE, buffer_lun, 0, 685 &available_buffer_size); 686 if (error) 687 return (error); 688 689 switch (dev->wb_user_space_config_option) { 690 case UFSHCI_DESC_WB_BUF_USER_SPACE_REDUCTION: 691 *need_flush = (available_buffer_size <= 692 UFSHCI_ATTR_WB_AVAILABLE_10); 693 break; 694 case UFSHCI_DESC_WB_BUF_PRESERVE_USER_SPACE: 695 /* 696 * In PRESERVE USER SPACE mode, flush should be performed when 697 * the current buffer is greater than 0 and the available buffer 698 * below write_booster_flush_threshold is left. 699 */ 700 error = ufshci_dev_read_attribute(ctrlr, 701 UFSHCI_ATTR_D_CURRENT_WB_BUFFER_SIZE, buffer_lun, 0, 702 ¤t_buffer_size); 703 if (error) 704 return (error); 705 706 if (current_buffer_size == 0) 707 return (0); 708 709 *need_flush = (available_buffer_size < 710 dev->write_booster_flush_threshold); 711 break; 712 default: 713 ufshci_printf(ctrlr, 714 "Invalid bWriteBoosterBufferPreserveUserSpaceEn value"); 715 return (EINVAL); 716 } 717 718 /* 719 * TODO: Need to handle WRITEBOOSTER_FLUSH_NEEDED exception case from 720 * wExceptionEventStatus attribute. 721 */ 722 723 return (0); 724 } 725 726 int 727 ufshci_dev_config_write_booster(struct ufshci_controller *ctrlr) 728 { 729 struct ufshci_device *dev = &ctrlr->ufs_dev; 730 uint32_t extended_ufs_feature_support; 731 uint32_t alloc_units = 0; 732 struct ufshci_unit_descriptor unit_desc; 733 uint8_t lun; 734 bool is_life_time_left; 735 uint32_t mega_byte = 1024 * 1024; 736 uint32_t error = 0; 737 738 extended_ufs_feature_support = be32toh( 739 dev->dev_desc.dExtendedUfsFeaturesSupport); 740 if (!(extended_ufs_feature_support & 741 UFSHCI_DESC_EXT_UFS_FEATURE_WRITE_BOOSTER)) { 742 /* This device does not support Write Booster */ 743 return (0); 744 } 745 746 if (ufshci_dev_enable_write_booster(ctrlr)) 747 return (0); 748 749 /* Get WriteBooster buffer parameters */ 750 dev->wb_buffer_type = dev->dev_desc.bWriteBoosterBufferType; 751 dev->wb_user_space_config_option = 752 dev->dev_desc.bWriteBoosterBufferPreserveUserSpaceEn; 753 754 /* 755 * Find the size of the write buffer. 756 * With LU-dedicated (00h), the WriteBooster buffer is assigned 757 * exclusively to one chosen LU (not one-per-LU), whereas Shared (01h) 758 * uses a single device-wide buffer shared by multiple LUs. 759 */ 760 if (dev->wb_buffer_type == UFSHCI_DESC_WB_BUF_TYPE_SINGLE_SHARED) { 761 alloc_units = be32toh( 762 dev->dev_desc.dNumSharedWriteBoosterBufferAllocUnits); 763 ufshci_printf(ctrlr, 764 "WriteBooster buffer type = Shared, alloc_units=%d\n", 765 alloc_units); 766 } else if (dev->wb_buffer_type == 767 UFSHCI_DESC_WB_BUF_TYPE_LU_DEDICATED) { 768 ufshci_printf(ctrlr, "WriteBooster buffer type = Dedicated\n"); 769 for (lun = 0; lun < ctrlr->max_lun_count; lun++) { 770 /* Find a dedicated buffer using a unit descriptor */ 771 if (ufshci_dev_read_unit_descriptor(ctrlr, lun, 772 &unit_desc)) 773 continue; 774 775 alloc_units = be32toh( 776 unit_desc.dLUNumWriteBoosterBufferAllocUnits); 777 if (alloc_units) { 778 dev->wb_dedicated_lu = lun; 779 break; 780 } 781 } 782 } else { 783 ufshci_printf(ctrlr, 784 "Not supported WriteBooster buffer type: 0x%x\n", 785 dev->wb_buffer_type); 786 goto out; 787 } 788 789 if (alloc_units == 0) { 790 ufshci_printf(ctrlr, "The WriteBooster buffer size is zero\n"); 791 goto out; 792 } 793 794 dev->wb_buffer_size_mb = alloc_units * 795 dev->geo_desc.bAllocationUnitSize * 796 (be32toh(dev->geo_desc.dSegmentSize)) / 797 (mega_byte / UFSHCI_SECTOR_SIZE); 798 799 /* Set to flush when 40% of the available buffer size remains */ 800 dev->write_booster_flush_threshold = UFSHCI_ATTR_WB_AVAILABLE_40; 801 802 /* 803 * Check if WriteBooster Buffer lifetime is left. 804 * WriteBooster Buffer lifetime — percent of life used based on P/E 805 * cycles. If "preserve user space" is enabled, writes to normal user 806 * space also consume WB life since the area is shared. 807 */ 808 error = ufshci_dev_is_write_booster_buffer_life_time_left(ctrlr, 809 &is_life_time_left); 810 if (error) 811 goto out; 812 813 if (!is_life_time_left) { 814 ufshci_printf(ctrlr, 815 "There is no WriteBooster buffer life time left.\n"); 816 goto out; 817 } 818 819 ufshci_printf(ctrlr, "WriteBooster Enabled\n"); 820 return (0); 821 out: 822 ufshci_dev_disable_write_booster(ctrlr); 823 return (error); 824 } 825 826 int 827 ufshci_dev_get_current_power_mode(struct ufshci_controller *ctrlr, 828 uint8_t *power_mode) 829 { 830 uint64_t value; 831 int err; 832 833 err = ufshci_dev_read_attribute(ctrlr, UFSHCI_ATTR_B_CURRENT_POWER_MODE, 834 /*index*/ 0, /*selector*/ 0, &value); 835 if (err) 836 return (err); 837 838 *power_mode = (uint8_t)value; 839 840 return (0); 841 } 842 843 static int 844 ufshci_dev_hibernate_enter(struct ufshci_controller *ctrlr) 845 { 846 int error; 847 848 error = ufshci_uic_send_dme_hibernate_enter(ctrlr); 849 if (error) 850 return (error); 851 852 return (ufshci_uic_hibernation_ready(ctrlr)); 853 } 854 855 static int 856 ufshci_dev_hibernate_exit(struct ufshci_controller *ctrlr) 857 { 858 int error; 859 860 error = ufshci_uic_send_dme_hibernate_exit(ctrlr); 861 if (error) 862 return (error); 863 864 return (ufshci_uic_hibernation_ready(ctrlr)); 865 } 866 867 int 868 ufshci_dev_link_state_transition(struct ufshci_controller *ctrlr, 869 enum ufshci_uic_link_state target_state) 870 { 871 struct ufshci_device *dev = &ctrlr->ufs_dev; 872 int error = 0; 873 874 if (dev->link_state == target_state) 875 return (0); 876 877 switch (target_state) { 878 case UFSHCI_UIC_LINK_STATE_OFF: 879 error = ufshci_dev_hibernate_enter(ctrlr); 880 if (error) 881 break; 882 error = ufshci_ctrlr_disable(ctrlr); 883 break; 884 case UFSHCI_UIC_LINK_STATE_ACTIVE: 885 if (dev->link_state == UFSHCI_UIC_LINK_STATE_HIBERNATE) 886 error = ufshci_dev_hibernate_exit(ctrlr); 887 else 888 error = EINVAL; 889 break; 890 case UFSHCI_UIC_LINK_STATE_HIBERNATE: 891 if (dev->link_state == UFSHCI_UIC_LINK_STATE_ACTIVE) 892 error = ufshci_dev_hibernate_enter(ctrlr); 893 else 894 error = EINVAL; 895 break; 896 case UFSHCI_UIC_LINK_STATE_BROKEN: 897 break; 898 default: 899 error = EINVAL; 900 break; 901 } 902 903 if (error) 904 return (error); 905 906 dev->link_state = target_state; 907 908 return (0); 909 } 910