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 "sdhci_pci.h" 18 19 20 #define TRACE_SDHCI 21 #ifdef TRACE_SDHCI 22 # define TRACE(x...) dprintf("\33[33msdhci_pci:\33[0m " x) 23 #else 24 # define TRACE(x...) ; 25 #endif 26 #define TRACE_ALWAYS(x...) dprintf("\33[33msdhci_pci:\33[0m " x) 27 #define ERROR(x...) dprintf("\33[33msdhci_pci:\33[0m " x) 28 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 29 30 31 #define SDHCI_PCI_DEVICE_MODULE_NAME "busses/mmc/sdhci_pci/driver_v1" 32 #define SDHCI_PCI_MMC_BUS_MODULE_NAME "busses/mmc/sdhci_pci/device/v1" 33 34 #define SLOTS_COUNT "device/slots_count" 35 #define SLOT_NUMBER "device/slot" 36 #define BAR_INDEX "device/bar" 37 38 typedef struct { 39 struct registers* fRegisters; 40 uint8_t fIrq; 41 } sdhci_pci_mmc_bus_info; 42 43 44 device_manager_info* gDeviceManager; 45 device_module_info* gSDHCIDeviceController; 46 static pci_x86_module_info* sPCIx86Module; 47 48 49 static void 50 sdhci_register_dump(uint8_t slot, struct registers* regs) 51 { 52 #ifdef TRACE_SDHCI 53 TRACE("Register values for slot %d:\n", slot); 54 TRACE("system_address: %d\n", regs->system_address); 55 TRACE("%d blocks of size %d\n", regs->block_count, regs->block_size); 56 TRACE("argument: %d\n", regs->argument); 57 TRACE("transfer_mode: %d\n", regs->transfer_mode); 58 TRACE("command: %d\n", regs->command.Bits()); 59 TRACE("response:"); 60 for (int i = 0; i < 8; i++) 61 dprintf(" %d", regs->response[i]); 62 dprintf("\n"); 63 TRACE("buffer_data_port: %d\n", regs->buffer_data_port); 64 TRACE("present_state: %x\n", regs->present_state.Bits()); 65 TRACE("power_control: %d\n", regs->power_control.Bits()); 66 TRACE("host_control: %d\n", regs->host_control); 67 TRACE("wakeup_control: %d\n", regs->wakeup_control); 68 TRACE("block_gap_control: %d\n", regs->block_gap_control); 69 TRACE("clock_control: %x\n", regs->clock_control.Bits()); 70 TRACE("software_reset: %d\n", regs->software_reset.Bits()); 71 TRACE("timeout_control: %d\n", regs->timeout_control); 72 TRACE("interrupt_status: %x enable: %x signal: %x\n", 73 regs->interrupt_status, regs->interrupt_status_enable, 74 regs->interrupt_signal_enable); 75 TRACE("auto_cmd12_error_status: %d\n", regs->auto_cmd12_error_status); 76 TRACE("capabilities: %lld\n", regs->capabilities.Bits()); 77 TRACE("max_current_capabilities: %lld\n", 78 regs->max_current_capabilities); 79 TRACE("slot_interrupt_status: %d\n", regs->slot_interrupt_status); 80 TRACE("host_controller_version spec %x vendor %x\n", 81 regs->host_controller_version.specVersion, 82 regs->host_controller_version.vendorVersion); 83 #endif 84 } 85 86 87 static void 88 sdhci_reset(struct registers* regs) 89 { 90 // if card is not present then no point of reseting the registers 91 if (!regs->present_state.IsCardInserted()) 92 return; 93 94 // enabling software reset all 95 regs->software_reset.ResetAll(); 96 } 97 98 99 static void 100 sdhci_set_clock(struct registers* regs) 101 { 102 int base_clock = regs->capabilities.BaseClockFrequency(); 103 // Try to get as close to 400kHz as possible, but not faster 104 int divider = base_clock * 1000 / 400; 105 106 if (regs->host_controller_version.specVersion <= 1) { 107 // Old controller only support power of two dividers up to 256, 108 // round to next power of two up to 256 109 if (divider > 256) 110 divider = 256; 111 112 divider--; 113 divider |= divider >> 1; 114 divider |= divider >> 2; 115 divider |= divider >> 4; 116 divider++; 117 } 118 119 divider = regs->clock_control.SetDivider(divider); 120 121 // Log the value after possible rounding by SetDivider (only even values 122 // are allowed). 123 TRACE("SDCLK frequency: %dMHz / %d = %dkHz\n", base_clock, divider, 124 base_clock * 1000 / divider); 125 126 // We have set the divider, now we can enable the internal clock. 127 regs->clock_control.EnableInternal(); 128 129 // wait until internal clock is stabilized 130 while (!(regs->clock_control.InternalStable())); 131 132 regs->clock_control.EnablePLL(); 133 while (!(regs->clock_control.InternalStable())); 134 135 // Finally, route the clock to the SD card 136 regs->clock_control.EnableSD(); 137 } 138 139 140 static void 141 sdhci_stop_clock(struct registers* regs) 142 { 143 regs->clock_control.DisableSD(); 144 } 145 146 147 static void 148 sdhci_set_power(struct registers* _regs) 149 { 150 uint8_t supportedVoltages = _regs->capabilities.SupportedVoltages(); 151 if ((supportedVoltages & Capabilities::k3v3) != 0) 152 _regs->power_control.SetVoltage(PowerControl::k3v3); 153 else if ((supportedVoltages & Capabilities::k3v0) != 0) 154 _regs->power_control.SetVoltage(PowerControl::k3v0); 155 else if ((supportedVoltages & Capabilities::k1v8) != 0) 156 _regs->power_control.SetVoltage(PowerControl::k1v8); 157 else { 158 _regs->power_control.PowerOff(); 159 ERROR("No voltage is supported\n"); 160 return; 161 } 162 163 if (!_regs->present_state.IsCardInserted()) { 164 TRACE("Card not inserted\n"); 165 return; 166 } 167 168 TRACE("Execute CMD0\n"); 169 _regs->command.SendCommand(0, false); 170 171 DELAY(1000); 172 } 173 174 175 static status_t 176 init_bus(device_node* node, void** bus_cookie) 177 { 178 CALLED(); 179 status_t status = B_OK; 180 area_id regs_area; 181 volatile uint32_t* regs; 182 uint8_t bar, slot; 183 184 sdhci_pci_mmc_bus_info* bus = new(std::nothrow) sdhci_pci_mmc_bus_info; 185 if (bus == NULL) 186 return B_NO_MEMORY; 187 188 pci_device_module_info* pci; 189 pci_device* device; 190 191 device_node* parent = gDeviceManager->get_parent_node(node); 192 device_node* pciParent = gDeviceManager->get_parent_node(parent); 193 gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci, 194 (void**)&device); 195 gDeviceManager->put_node(pciParent); 196 gDeviceManager->put_node(parent); 197 198 if (get_module(B_PCI_X86_MODULE_NAME, (module_info**)&sPCIx86Module) 199 != B_OK) { 200 sPCIx86Module = NULL; 201 TRACE("PCIx86Module not loaded\n"); 202 } 203 204 if (gDeviceManager->get_attr_uint8(node, SLOT_NUMBER, &slot, false) < B_OK 205 || gDeviceManager->get_attr_uint8(node, BAR_INDEX, &bar, false) < B_OK) 206 return -1; 207 208 TRACE("Register SD bus at slot %d, using bar %d\n", slot + 1, bar); 209 210 pci_info pciInfo; 211 pci->get_pci_info(device, &pciInfo); 212 int msiCount = sPCIx86Module->get_msi_count(pciInfo.bus, 213 pciInfo.device, pciInfo.function); 214 TRACE("interrupts count: %d\n",msiCount); 215 216 // enable bus master and io 217 uint16 pcicmd = pci->read_pci_config(device, PCI_command, 2); 218 pcicmd &= ~(PCI_command_int_disable | PCI_command_io); 219 pcicmd |= PCI_command_master | PCI_command_memory; 220 pci->write_pci_config(device, PCI_command, 2, pcicmd); 221 222 TRACE("init_bus() %p node %p pci %p device %p\n", bus, node, 223 pci, device); 224 225 // mapping the registers by MMUIO method 226 int bar_size = pciInfo->u.h0.base_register_sizes[bar]; 227 228 regs_area = map_physical_memory("sdhc_regs_map", 229 pciInfo.u.h0.base_registers[bar], 230 pciInfo.u.h0.base_register_sizes[bar], B_ANY_KERNEL_BLOCK_ADDRESS, 231 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)®s); 232 233 if (regs_area < B_OK) { 234 TRACE("mapping failed"); 235 return B_BAD_VALUE; 236 } 237 238 struct registers* _regs = (struct registers*)regs; 239 bus->fRegisters = _regs; 240 sdhci_reset(_regs); 241 242 // the interrupt is shared between all busses in an SDHC controller, but 243 // they each register an handler. Not a problem, we will just test the 244 // interrupt registers for all busses one after the other and find no 245 // interrupts on the idle busses. 246 bus->fIrq = pciInfo.u.h0.interrupt_line; 247 248 TRACE("irq interrupt line: %d\n", bus->fIrq); 249 250 if (bus->fIrq == 0 || bus->fIrq == 0xff) { 251 TRACE("PCI IRQ not assigned\n"); 252 if (sPCIx86Module != NULL) { 253 put_module(B_PCI_X86_MODULE_NAME); 254 sPCIx86Module = NULL; 255 } 256 delete_area(regs_area); 257 delete bus; 258 return B_ERROR; 259 } 260 261 status = install_io_interrupt_handler(bus->fIrq, 262 sdhci_generic_interrupt, bus, 0); 263 264 if (status != B_OK) { 265 TRACE("can't install interrupt handler\n"); 266 if (sPCIx86Module != NULL) { 267 put_module(B_PCI_X86_MODULE_NAME); 268 sPCIx86Module = NULL; 269 } 270 delete_area(regs_area); 271 delete bus; 272 return status; 273 } 274 TRACE("interrupt handler installed\n"); 275 276 _regs->interrupt_status_enable = SDHCI_INT_CMD_CMP 277 | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM 278 | SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_INDEX 279 | SDHCI_INT_BUS_POWER | SDHCI_INT_END_BIT; 280 _regs->interrupt_signal_enable = SDHCI_INT_CMD_CMP 281 | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM 282 | SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_INDEX 283 | SDHCI_INT_BUS_POWER | SDHCI_INT_END_BIT; 284 285 sdhci_register_dump(slot, _regs); 286 sdhci_set_clock(_regs); 287 sdhci_set_power(_regs); 288 289 *bus_cookie = bus; 290 return status; 291 } 292 293 294 static void 295 uninit_bus(void* bus_cookie) 296 { 297 sdhci_pci_mmc_bus_info* bus = (sdhci_pci_mmc_bus_info*)bus_cookie; 298 299 bus->fRegisters->interrupt_signal_enable = 0; 300 bus->fRegisters->interrupt_status_enable = 0; 301 302 remove_io_interrupt_handler(bus->fIrq, sdhci_generic_interrupt, bus); 303 304 area_id regs_area = area_for(bus->fRegisters); 305 delete_area(regs_area); 306 307 // FIXME do we need to put() the PCI module here? 308 309 delete bus; 310 } 311 312 313 void 314 sdhci_error_interrupt_recovery(struct registers* _regs) 315 { 316 _regs->interrupt_signal_enable &= ~(SDHCI_INT_CMD_CMP 317 | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM); 318 319 if (_regs->interrupt_status & 7) 320 _regs->software_reset.ResetTransaction(); 321 322 int16_t erorr_status = _regs->interrupt_status; 323 _regs->interrupt_status &= ~(erorr_status); 324 } 325 326 327 int32 328 sdhci_generic_interrupt(void* data) 329 { 330 sdhci_pci_mmc_bus_info* bus = (sdhci_pci_mmc_bus_info*)data; 331 uint32_t intmask = bus->fRegisters->slot_interrupt_status; 332 333 if ((intmask == 0) || (intmask == 0xffffffff)) { 334 return B_UNHANDLED_INTERRUPT; 335 } 336 337 TRACE("interrupt function called\n"); 338 339 // handling card presence interrupt 340 if (intmask & (SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM)) { 341 uint32_t card_present = ((intmask & SDHCI_INT_CARD_INS) != 0); 342 bus->fRegisters->interrupt_status_enable &= ~(SDHCI_INT_CARD_INS 343 | SDHCI_INT_CARD_REM); 344 bus->fRegisters->interrupt_signal_enable &= ~(SDHCI_INT_CARD_INS 345 | SDHCI_INT_CARD_REM); 346 347 bus->fRegisters->interrupt_status_enable |= card_present 348 ? SDHCI_INT_CARD_REM : SDHCI_INT_CARD_INS; 349 bus->fRegisters->interrupt_signal_enable |= card_present 350 ? SDHCI_INT_CARD_REM : SDHCI_INT_CARD_INS; 351 352 bus->fRegisters->interrupt_status |= (intmask & 353 (SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM)); 354 TRACE("Card presence interrupt handled\n"); 355 356 return B_HANDLED_INTERRUPT; 357 } 358 359 // handling command interrupt 360 if (intmask & SDHCI_INT_CMD_MASK) { 361 bus->fRegisters->interrupt_status |= (intmask & SDHCI_INT_CMD_MASK); 362 // TODO do something with the interrupt 363 TRACE("Command interrupt handled\n"); 364 365 return B_HANDLED_INTERRUPT; 366 } 367 368 // handling bus power interrupt 369 if (intmask & SDHCI_INT_BUS_POWER) { 370 bus->fRegisters->interrupt_status |= SDHCI_INT_BUS_POWER; 371 TRACE("card is consuming too much power\n"); 372 373 return B_HANDLED_INTERRUPT; 374 } 375 376 intmask = bus->fRegisters->slot_interrupt_status; 377 if (intmask != 0) { 378 ERROR("Remaining interrupts at end of handler: %x\n", intmask); 379 intmask &= ~(SDHCI_INT_BUS_POWER | SDHCI_INT_CARD_INS 380 | SDHCI_INT_CARD_REM | SDHCI_INT_CMD_MASK); 381 } 382 383 return B_UNHANDLED_INTERRUPT; 384 } 385 386 387 static void 388 bus_removed(void* bus_cookie) 389 { 390 return; 391 } 392 393 394 static status_t 395 register_child_devices(void* cookie) 396 { 397 CALLED(); 398 device_node* node = (device_node*)cookie; 399 device_node* parent = gDeviceManager->get_parent_node(node); 400 pci_device_module_info* pci; 401 pci_device* device; 402 uint8 slots_count, bar, slotsInfo; 403 404 gDeviceManager->get_driver(parent, (driver_module_info**)&pci, 405 (void**)&device); 406 uint16 pciSubDeviceId = pci->read_pci_config(device, PCI_subsystem_id, 2); 407 slotsInfo = pci->read_pci_config(device, SDHCI_PCI_SLOT_INFO, 1); 408 bar = SDHCI_PCI_SLOT_INFO_FIRST_BASE_INDEX(slotsInfo); 409 slots_count = SDHCI_PCI_SLOTS(slotsInfo); 410 411 char prettyName[25]; 412 413 if (slots_count > 6 || bar > 5) { 414 TRACE("Invalid slots count: %d or BAR count: %d \n", slots_count, bar); 415 return B_BAD_VALUE; 416 } 417 418 for (uint8_t slot = 0; slot <= slots_count; slot++) { 419 420 bar = bar + slot; 421 sprintf(prettyName, "SDHC bus %" B_PRIu16 " slot %" 422 B_PRIu8, pciSubDeviceId, slot); 423 device_attr attrs[] = { 424 // properties of this controller for SDHCI bus manager 425 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, 426 { string: prettyName }}, 427 { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, 428 {string: SDHCI_BUS_CONTROLLER_MODULE_NAME}}, 429 {SDHCI_DEVICE_TYPE_ITEM, B_UINT16_TYPE, 430 { ui16: pciSubDeviceId}}, 431 {B_DEVICE_BUS, B_STRING_TYPE,{string: "mmc"}}, 432 {SLOT_NUMBER, B_UINT8_TYPE, 433 { ui8: slot}}, 434 {BAR_INDEX, B_UINT8_TYPE, 435 { ui8: bar}}, 436 { NULL } 437 }; 438 if (gDeviceManager->register_node(node, SDHCI_PCI_MMC_BUS_MODULE_NAME, 439 attrs, NULL, &node) != B_OK) 440 return B_BAD_VALUE; 441 } 442 return B_OK; 443 } 444 445 446 static status_t 447 init_device(device_node* node, void** device_cookie) 448 { 449 CALLED(); 450 *device_cookie = node; 451 return B_OK; 452 } 453 454 455 static status_t 456 register_device(device_node* parent) 457 { 458 device_attr attrs[] = { 459 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "SD Host Controller"}}, 460 {} 461 }; 462 463 return gDeviceManager->register_node(parent, SDHCI_PCI_DEVICE_MODULE_NAME, 464 attrs, NULL, NULL); 465 } 466 467 468 static float 469 supports_device(device_node* parent) 470 { 471 CALLED(); 472 const char* bus; 473 uint16 type, subType; 474 uint8 pciSubDeviceId; 475 476 // make sure parent is a PCI SDHCI device node 477 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) 478 != B_OK || gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, 479 &subType, false) < B_OK || gDeviceManager->get_attr_uint16(parent, 480 B_DEVICE_TYPE, &type, false) < B_OK) 481 return -1; 482 483 if (strcmp(bus, "pci") != 0) 484 return 0.0f; 485 486 if (type == PCI_base_peripheral) { 487 if (subType != PCI_sd_host) 488 return 0.0f; 489 490 pci_device_module_info* pci; 491 pci_device* device; 492 gDeviceManager->get_driver(parent, (driver_module_info**)&pci, 493 (void**)&device); 494 pciSubDeviceId = pci->read_pci_config(device, PCI_revision, 1); 495 TRACE("SDHCI Device found! Subtype: 0x%04x, type: 0x%04x\n", 496 subType, type); 497 return 0.8f; 498 } 499 500 return 0.0f; 501 } 502 503 504 module_dependency module_dependencies[] = { 505 { SDHCI_BUS_CONTROLLER_MODULE_NAME, (module_info**)&gSDHCIDeviceController}, 506 { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, 507 {} 508 }; 509 510 511 static sdhci_mmc_bus_interface gSDHCIPCIDeviceModule = { 512 { 513 { 514 SDHCI_PCI_MMC_BUS_MODULE_NAME, 515 0, 516 NULL 517 }, 518 NULL, // supports device 519 NULL, // register device 520 init_bus, 521 uninit_bus, 522 NULL, // register child devices 523 NULL, // rescan 524 bus_removed, 525 } 526 }; 527 528 529 static driver_module_info sSDHCIDevice = { 530 { 531 SDHCI_PCI_DEVICE_MODULE_NAME, 532 0, 533 NULL 534 }, 535 supports_device, 536 register_device, 537 init_device, 538 NULL, // uninit 539 register_child_devices, 540 NULL, // rescan 541 NULL, // device removed 542 }; 543 544 545 module_info* modules[] = { 546 (module_info* )&sSDHCIDevice, 547 (module_info* )&gSDHCIPCIDeviceModule, 548 NULL 549 }; 550