1 /* 2 * Copyright 2018-2019 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * B Krishnan Iyer, krishnaniyer97@gmail.com 7 */ 8 #include <new> 9 #include <stdio.h> 10 #include <string.h> 11 12 #include <bus/PCI.h> 13 #include <PCI_x86.h> 14 15 #include <KernelExport.h> 16 17 #include "mmc.h" 18 #include "sdhci_pci.h" 19 20 21 #define TRACE_SDHCI 22 #ifdef TRACE_SDHCI 23 # define TRACE(x...) dprintf("\33[33msdhci_pci:\33[0m " x) 24 #else 25 # define TRACE(x...) ; 26 #endif 27 #define TRACE_ALWAYS(x...) dprintf("\33[33msdhci_pci:\33[0m " x) 28 #define ERROR(x...) dprintf("\33[33msdhci_pci:\33[0m " x) 29 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 30 31 32 #define SDHCI_PCI_DEVICE_MODULE_NAME "busses/mmc/sdhci_pci/driver_v1" 33 #define SDHCI_PCI_MMC_BUS_MODULE_NAME "busses/mmc/sdhci_pci/device/v1" 34 35 #define SLOTS_COUNT "device/slots_count" 36 #define SLOT_NUMBER "device/slot" 37 #define BAR_INDEX "device/bar" 38 39 40 class SdhciBus { 41 public: 42 SdhciBus(struct registers* registers, uint8_t irq); 43 ~SdhciBus(); 44 45 void EnableInterrupts(uint32_t mask); 46 status_t ExecuteCommand(uint8_t command, uint32_t argument, 47 uint32_t* response); 48 int32 HandleInterrupt(); 49 status_t InitCheck(); 50 void Reset(); 51 void SetClock(int kilohertz); 52 53 private: 54 void DumpRegisters(uint8_t slot); 55 bool PowerOn(); 56 void RecoverError(); 57 58 private: 59 struct registers* fRegisters; 60 uint8_t fIrq; 61 sem_id fSemaphore; 62 status_t fStatus; 63 }; 64 65 66 device_manager_info* gDeviceManager; 67 device_module_info* gMMCBusController; 68 static pci_x86_module_info* sPCIx86Module; 69 70 71 static int32 72 sdhci_generic_interrupt(void* data) 73 { 74 SdhciBus* bus = (SdhciBus*)data; 75 return bus->HandleInterrupt(); 76 } 77 78 79 SdhciBus::SdhciBus(struct registers* registers, uint8_t irq) 80 : 81 fRegisters(registers), 82 fIrq(irq), 83 fSemaphore(0) 84 { 85 if (irq == 0 || irq == 0xff) { 86 ERROR("PCI IRQ not assigned\n"); 87 fStatus = B_BAD_DATA; 88 return; 89 } 90 91 fSemaphore = create_sem(0, "SDHCI command"); 92 93 fStatus = install_io_interrupt_handler(fIrq, 94 sdhci_generic_interrupt, this, 0); 95 96 if (fStatus != B_OK) { 97 ERROR("can't install interrupt handler\n"); 98 return; 99 } 100 101 // First of all, we have to make sure we are in a sane state. The easiest 102 // way is to reset everything. 103 Reset(); 104 105 // Then we configure the clock to the frequency needed for initialization 106 SetClock(400); 107 108 // And we turn on the power supply to the card 109 // FIXME maybe this should only be done when a card is inserted? 110 if (!PowerOn()) { 111 ERROR("Failed to power on the card\n"); 112 fStatus = B_NO_INIT; 113 return; 114 } 115 116 // FIXME do we need all these? Wouldn't card insertion/removal and command 117 // completion be enough? 118 EnableInterrupts(SDHCI_INT_CMD_CMP 119 | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM 120 | SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_INDEX 121 | SDHCI_INT_BUS_POWER | SDHCI_INT_END_BIT); 122 123 fRegisters->interrupt_status_enable |= SDHCI_INT_ERROR; 124 } 125 126 127 SdhciBus::~SdhciBus() 128 { 129 if (fSemaphore != 0) 130 delete_sem(fSemaphore); 131 132 EnableInterrupts(0); 133 if (fIrq != 0) 134 remove_io_interrupt_handler(fIrq, sdhci_generic_interrupt, this); 135 136 area_id regs_area = area_for(fRegisters); 137 delete_area(regs_area); 138 } 139 140 141 void 142 SdhciBus::DumpRegisters(uint8_t slot) 143 { 144 #ifdef TRACE_SDHCI 145 TRACE("Register values for slot %d:\n", slot); 146 TRACE("system_address: %d\n", fRegisters->system_address); 147 TRACE("%d blocks of size %d\n", fRegisters->block_count, 148 fRegisters->block_size); 149 TRACE("argument: %x\n", fRegisters->argument); 150 TRACE("transfer_mode: %d\n", fRegisters->transfer_mode); 151 TRACE("command: %x\n", fRegisters->command.Bits()); 152 TRACE("response:"); 153 for (int i = 0; i < 4; i++) 154 dprintf(" %d", fRegisters->response[i]); 155 dprintf("\n"); 156 TRACE("buffer_data_port: %d\n", fRegisters->buffer_data_port); 157 TRACE("present_state: %x\n", fRegisters->present_state.Bits()); 158 TRACE("power_control: %d\n", fRegisters->power_control.Bits()); 159 TRACE("host_control: %d\n", fRegisters->host_control); 160 TRACE("wakeup_control: %d\n", fRegisters->wakeup_control); 161 TRACE("block_gap_control: %d\n", fRegisters->block_gap_control); 162 TRACE("clock_control: %x\n", fRegisters->clock_control.Bits()); 163 TRACE("software_reset: %d\n", fRegisters->software_reset.Bits()); 164 TRACE("timeout_control: %d\n", fRegisters->timeout_control); 165 TRACE("interrupt_status: %x enable: %x signal: %x\n", 166 fRegisters->interrupt_status, fRegisters->interrupt_status_enable, 167 fRegisters->interrupt_signal_enable); 168 TRACE("auto_cmd12_error_status: %d\n", fRegisters->auto_cmd12_error_status); 169 TRACE("capabilities: %lld\n", fRegisters->capabilities.Bits()); 170 TRACE("max_current_capabilities: %lld\n", 171 fRegisters->max_current_capabilities); 172 TRACE("slot_interrupt_status: %d\n", fRegisters->slot_interrupt_status); 173 TRACE("host_controller_version spec %x vendor %x\n", 174 fRegisters->host_controller_version.specVersion, 175 fRegisters->host_controller_version.vendorVersion); 176 #endif 177 } 178 179 180 void 181 SdhciBus::EnableInterrupts(uint32_t mask) 182 { 183 fRegisters->interrupt_status_enable = mask; 184 fRegisters->interrupt_signal_enable = mask; 185 } 186 187 188 status_t 189 SdhciBus::ExecuteCommand(uint8_t command, uint32_t argument, uint32_t* response) 190 { 191 TRACE("ExecuteCommand(%d, %x)\n", command, argument); 192 if (fRegisters->present_state.CommandInhibit()) { 193 ERROR("Execution aborted, command inhibit\n"); 194 return B_BUSY; 195 } 196 197 fRegisters->argument = argument; 198 199 uint32_t replyType; 200 201 switch(command) { 202 case 0: 203 replyType = Command::kNoReplyType; 204 break; 205 case 2: 206 replyType = Command::kR2Type; 207 break; 208 case 55: 209 replyType = Command::kR1Type; 210 break; 211 case 41: // ACMD 212 replyType = Command::kR3Type; 213 break; 214 case 3: 215 replyType = Command::kR6Type; 216 break; 217 case 8: 218 replyType = Command::kR7Type; 219 break; 220 default: 221 ERROR("Unknown command\n"); 222 return B_BAD_DATA; 223 } 224 225 fRegisters->command.SendCommand(command, replyType); 226 acquire_sem(fSemaphore); 227 228 if (fRegisters->interrupt_status & SDHCI_INT_ERROR) { 229 fRegisters->interrupt_status |= SDHCI_INT_ERROR; 230 ERROR("Command execution failed\n"); 231 // TODO look at errors in interrupt_status register for more details 232 // and return a more appropriate error code 233 return B_ERROR; 234 } 235 236 if (fRegisters->present_state.CommandInhibit()) { 237 TRACE("Command execution failed, card stalled\n"); 238 // Clear the stall 239 fRegisters->software_reset.ResetCommandLine(); 240 return B_ERROR; 241 } 242 243 if (replyType == Command::kNoReplyType) { 244 // No response 245 } else if (replyType == Command::kR2Type) { 246 // 128 bit response 247 response[0] = fRegisters->response[0]; 248 response[1] = fRegisters->response[1]; 249 response[2] = fRegisters->response[2]; 250 response[3] = fRegisters->response[3]; 251 } else { 252 // 32 bit response 253 *response = fRegisters->response[0]; 254 } 255 256 ERROR("Command execution complete\n"); 257 return B_OK; 258 } 259 260 261 status_t 262 SdhciBus::InitCheck() 263 { 264 return fStatus; 265 } 266 267 268 void 269 SdhciBus::Reset() 270 { 271 fRegisters->software_reset.ResetAll(); 272 } 273 274 275 void 276 SdhciBus::SetClock(int kilohertz) 277 { 278 int base_clock = fRegisters->capabilities.BaseClockFrequency(); 279 // Try to get as close to 400kHz as possible, but not faster 280 int divider = base_clock * 1000 / kilohertz; 281 282 if (fRegisters->host_controller_version.specVersion <= 1) { 283 // Old controller only support power of two dividers up to 256, 284 // round to next power of two up to 256 285 if (divider > 256) 286 divider = 256; 287 288 divider--; 289 divider |= divider >> 1; 290 divider |= divider >> 2; 291 divider |= divider >> 4; 292 divider++; 293 } 294 295 divider = fRegisters->clock_control.SetDivider(divider); 296 297 // Log the value after possible rounding by SetDivider (only even values 298 // are allowed). 299 TRACE("SDCLK frequency: %dMHz / %d = %dkHz\n", base_clock, divider, 300 base_clock * 1000 / divider); 301 302 // We have set the divider, now we can enable the internal clock. 303 fRegisters->clock_control.EnableInternal(); 304 305 // wait until internal clock is stabilized 306 while (!(fRegisters->clock_control.InternalStable())); 307 308 fRegisters->clock_control.EnablePLL(); 309 while (!(fRegisters->clock_control.InternalStable())); 310 311 // Finally, route the clock to the SD card 312 fRegisters->clock_control.EnableSD(); 313 } 314 315 316 static void 317 sdhci_stop_clock(struct registers* regs) 318 { 319 regs->clock_control.DisableSD(); 320 } 321 322 323 bool 324 SdhciBus::PowerOn() 325 { 326 if (!fRegisters->present_state.IsCardInserted()) { 327 TRACE("Card not inserted, not powering on for now\n"); 328 return false; 329 } 330 331 uint8_t supportedVoltages = fRegisters->capabilities.SupportedVoltages(); 332 if ((supportedVoltages & Capabilities::k3v3) != 0) 333 fRegisters->power_control.SetVoltage(PowerControl::k3v3); 334 else if ((supportedVoltages & Capabilities::k3v0) != 0) 335 fRegisters->power_control.SetVoltage(PowerControl::k3v0); 336 else if ((supportedVoltages & Capabilities::k1v8) != 0) 337 fRegisters->power_control.SetVoltage(PowerControl::k1v8); 338 else { 339 fRegisters->power_control.PowerOff(); 340 ERROR("No voltage is supported\n"); 341 return false; 342 } 343 344 return true; 345 } 346 347 348 static status_t 349 init_bus(device_node* node, void** bus_cookie) 350 { 351 CALLED(); 352 353 // Get the PCI driver and device 354 pci_device_module_info* pci; 355 pci_device* device; 356 357 device_node* parent = gDeviceManager->get_parent_node(node); 358 device_node* pciParent = gDeviceManager->get_parent_node(parent); 359 gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci, 360 (void**)&device); 361 gDeviceManager->put_node(pciParent); 362 gDeviceManager->put_node(parent); 363 364 if (get_module(B_PCI_X86_MODULE_NAME, (module_info**)&sPCIx86Module) 365 != B_OK) { 366 sPCIx86Module = NULL; 367 ERROR("PCIx86Module not loaded\n"); 368 // FIXME try probing FDT as well 369 return -1; 370 } 371 372 uint8_t bar, slot; 373 if (gDeviceManager->get_attr_uint8(node, SLOT_NUMBER, &slot, false) < B_OK 374 || gDeviceManager->get_attr_uint8(node, BAR_INDEX, &bar, false) < B_OK) 375 return -1; 376 377 TRACE("Register SD bus at slot %d, using bar %d\n", slot + 1, bar); 378 379 pci_info pciInfo; 380 pci->get_pci_info(device, &pciInfo); 381 int msiCount = sPCIx86Module->get_msi_count(pciInfo.bus, 382 pciInfo.device, pciInfo.function); 383 TRACE("interrupts count: %d\n",msiCount); 384 // FIXME if available, use MSI rather than good old IRQ... 385 386 // enable bus master and io 387 uint16 pcicmd = pci->read_pci_config(device, PCI_command, 2); 388 pcicmd &= ~(PCI_command_int_disable | PCI_command_io); 389 pcicmd |= PCI_command_master | PCI_command_memory; 390 pci->write_pci_config(device, PCI_command, 2, pcicmd); 391 392 // map the slot registers 393 area_id regs_area; 394 struct registers* _regs; 395 regs_area = map_physical_memory("sdhc_regs_map", 396 pciInfo.u.h0.base_registers[bar], 397 pciInfo.u.h0.base_register_sizes[bar], B_ANY_KERNEL_BLOCK_ADDRESS, 398 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&_regs); 399 400 if (regs_area < B_OK) { 401 ERROR("Could not map registers\n"); 402 return B_BAD_VALUE; 403 } 404 405 // the interrupt is shared between all busses in an SDHC controller, but 406 // they each register an handler. Not a problem, we will just test the 407 // interrupt registers for all busses one after the other and find no 408 // interrupts on the idle busses. 409 uint8_t irq = pciInfo.u.h0.interrupt_line; 410 TRACE("irq interrupt line: %d\n", irq); 411 412 SdhciBus* bus = new(std::nothrow) SdhciBus(_regs, irq); 413 414 status_t status = B_NO_MEMORY; 415 if (bus != NULL) 416 status = bus->InitCheck(); 417 418 if (status != B_OK) { 419 if (sPCIx86Module != NULL) { 420 put_module(B_PCI_X86_MODULE_NAME); 421 sPCIx86Module = NULL; 422 } 423 424 if (bus != NULL) 425 delete bus; 426 else 427 delete_area(regs_area); 428 return status; 429 } 430 431 // Store the created object as a cookie, allowing users of the bus to 432 // locate it. 433 *bus_cookie = bus; 434 435 return status; 436 } 437 438 439 static void 440 uninit_bus(void* bus_cookie) 441 { 442 SdhciBus* bus = (SdhciBus*)bus_cookie; 443 delete bus; 444 445 // FIXME do we need to put() the PCI module here? 446 } 447 448 449 void 450 SdhciBus::RecoverError() 451 { 452 fRegisters->interrupt_signal_enable &= ~(SDHCI_INT_CMD_CMP 453 | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM); 454 455 if (fRegisters->interrupt_status & 7) 456 fRegisters->software_reset.ResetCommandLine(); 457 458 int16_t error_status = fRegisters->interrupt_status; 459 fRegisters->interrupt_status &= ~(error_status); 460 } 461 462 463 int32 464 SdhciBus::HandleInterrupt() 465 { 466 uint32_t intmask = fRegisters->slot_interrupt_status; 467 468 if ((intmask == 0) || (intmask == 0xffffffff)) { 469 return B_UNHANDLED_INTERRUPT; 470 } 471 472 TRACE("interrupt function called\n"); 473 474 // FIXME use the global "slot interrupt" register to quickly decide if an 475 // interrupt is targetted to this slot 476 477 // handling card presence interrupt 478 if (intmask & (SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM)) { 479 uint32_t card_present = ((intmask & SDHCI_INT_CARD_INS) != 0); 480 fRegisters->interrupt_status_enable &= ~(SDHCI_INT_CARD_INS 481 | SDHCI_INT_CARD_REM); 482 fRegisters->interrupt_signal_enable &= ~(SDHCI_INT_CARD_INS 483 | SDHCI_INT_CARD_REM); 484 485 fRegisters->interrupt_status_enable |= card_present 486 ? SDHCI_INT_CARD_REM : SDHCI_INT_CARD_INS; 487 fRegisters->interrupt_signal_enable |= card_present 488 ? SDHCI_INT_CARD_REM : SDHCI_INT_CARD_INS; 489 490 fRegisters->interrupt_status |= (intmask & 491 (SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM)); 492 TRACE("Card presence interrupt handled\n"); 493 494 return B_HANDLED_INTERRUPT; 495 } 496 497 // handling command interrupt 498 if (intmask & SDHCI_INT_CMD_MASK) { 499 fRegisters->interrupt_status |= (intmask & SDHCI_INT_CMD_MASK); 500 // Notify the thread 501 release_sem_etc(fSemaphore, 1, B_DO_NOT_RESCHEDULE); 502 TRACE("Command interrupt handled\n"); 503 504 return B_HANDLED_INTERRUPT; 505 } 506 507 // handling bus power interrupt 508 if (intmask & SDHCI_INT_BUS_POWER) { 509 fRegisters->interrupt_status |= SDHCI_INT_BUS_POWER; 510 TRACE("card is consuming too much power\n"); 511 512 return B_HANDLED_INTERRUPT; 513 } 514 515 intmask = fRegisters->slot_interrupt_status; 516 if (intmask != 0) { 517 ERROR("Remaining interrupts at end of handler: %x\n", intmask); 518 } 519 520 return B_UNHANDLED_INTERRUPT; 521 } 522 523 524 static void 525 bus_removed(void* bus_cookie) 526 { 527 return; 528 } 529 530 531 static status_t 532 register_child_devices(void* cookie) 533 { 534 CALLED(); 535 device_node* node = (device_node*)cookie; 536 device_node* parent = gDeviceManager->get_parent_node(node); 537 pci_device_module_info* pci; 538 pci_device* device; 539 uint8 slots_count, bar, slotsInfo; 540 541 gDeviceManager->get_driver(parent, (driver_module_info**)&pci, 542 (void**)&device); 543 slotsInfo = pci->read_pci_config(device, SDHCI_PCI_SLOT_INFO, 1); 544 bar = SDHCI_PCI_SLOT_INFO_FIRST_BASE_INDEX(slotsInfo); 545 slots_count = SDHCI_PCI_SLOTS(slotsInfo); 546 547 char prettyName[25]; 548 549 if (slots_count > 6 || bar > 5) { 550 ERROR("Invalid slots count: %d or BAR count: %d \n", slots_count, bar); 551 return B_BAD_VALUE; 552 } 553 554 for (uint8_t slot = 0; slot <= slots_count; slot++) { 555 556 bar = bar + slot; 557 sprintf(prettyName, "SDHC bus %" B_PRIu8, slot); 558 device_attr attrs[] = { 559 // properties of this controller for SDHCI bus manager 560 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: prettyName } }, 561 { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, 562 {string: MMC_BUS_MODULE_NAME} }, 563 { B_DEVICE_BUS, B_STRING_TYPE, {string: "mmc"} }, 564 { SLOT_NUMBER, B_UINT8_TYPE, { ui8: slot} }, 565 { BAR_INDEX, B_UINT8_TYPE, { ui8: bar} }, 566 { NULL } 567 }; 568 if (gDeviceManager->register_node(node, SDHCI_PCI_MMC_BUS_MODULE_NAME, 569 attrs, NULL, &node) != B_OK) 570 return B_BAD_VALUE; 571 } 572 return B_OK; 573 } 574 575 576 static status_t 577 init_device(device_node* node, void** device_cookie) 578 { 579 CALLED(); 580 *device_cookie = node; 581 return B_OK; 582 } 583 584 585 static status_t 586 register_device(device_node* parent) 587 { 588 device_attr attrs[] = { 589 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "SD Host Controller"}}, 590 {} 591 }; 592 593 return gDeviceManager->register_node(parent, SDHCI_PCI_DEVICE_MODULE_NAME, 594 attrs, NULL, NULL); 595 } 596 597 598 static float 599 supports_device(device_node* parent) 600 { 601 CALLED(); 602 const char* bus; 603 uint16 type, subType; 604 uint8 pciSubDeviceId; 605 606 // make sure parent is a PCI SDHCI device node 607 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) 608 != B_OK || gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, 609 &subType, false) < B_OK || gDeviceManager->get_attr_uint16(parent, 610 B_DEVICE_TYPE, &type, false) < B_OK) { 611 ERROR("Could not find required attribute device/bus\n"); 612 return -1; 613 } 614 615 if (strcmp(bus, "pci") != 0) 616 return 0.0f; 617 618 if (type == PCI_base_peripheral) { 619 if (subType != PCI_sd_host) 620 return 0.0f; 621 622 pci_device_module_info* pci; 623 pci_device* device; 624 gDeviceManager->get_driver(parent, (driver_module_info**)&pci, 625 (void**)&device); 626 pciSubDeviceId = pci->read_pci_config(device, PCI_revision, 1); 627 TRACE("SDHCI Device found! Subtype: 0x%04x, type: 0x%04x\n", 628 subType, type); 629 return 0.8f; 630 } 631 632 return 0.0f; 633 } 634 635 636 static status_t 637 set_clock(void* controller, uint32_t kilohertz) 638 { 639 SdhciBus* bus = (SdhciBus*)controller; 640 bus->SetClock(kilohertz); 641 return B_OK; 642 } 643 644 645 static status_t 646 execute_command(void* controller, uint8_t command, uint32_t argument, 647 uint32_t* response) 648 { 649 SdhciBus* bus = (SdhciBus*)controller; 650 return bus->ExecuteCommand(command, argument, response); 651 } 652 653 654 module_dependency module_dependencies[] = { 655 { MMC_BUS_MODULE_NAME, (module_info**)&gMMCBusController}, 656 { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, 657 {} 658 }; 659 660 661 // Device node registered for each SD slot. It implements the MMC operations so 662 // the bus manager can use it to communicate with SD cards. 663 static mmc_bus_interface gSDHCIPCIDeviceModule = { 664 { 665 { 666 SDHCI_PCI_MMC_BUS_MODULE_NAME, 667 0, 668 NULL 669 }, 670 NULL, // supports device 671 NULL, // register device 672 init_bus, 673 uninit_bus, 674 NULL, // register child devices 675 NULL, // rescan 676 bus_removed, 677 }, 678 679 set_clock, 680 execute_command, 681 }; 682 683 684 // Root device that binds to the PCI bus. It will register an mmc_bus_interface 685 // node for each SD slot in the device. 686 static driver_module_info sSDHCIDevice = { 687 { 688 SDHCI_PCI_DEVICE_MODULE_NAME, 689 0, 690 NULL 691 }, 692 supports_device, 693 register_device, 694 init_device, 695 NULL, // uninit 696 register_child_devices, 697 NULL, // rescan 698 NULL, // device removed 699 }; 700 701 702 module_info* modules[] = { 703 (module_info* )&sSDHCIDevice, 704 (module_info* )&gSDHCIPCIDeviceModule, 705 NULL 706 }; 707