1 /* 2 * Copyright 2018-2024 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 * Ron Ben Aroya, sed4906birdie@gmail.com 8 */ 9 #ifndef _SDHCI_H 10 #define _SDHCI_H 11 12 13 #include <device_manager.h> 14 #include <KernelExport.h> 15 16 17 #define SDHCI_PCI_SLOT_INFO 0x40 18 #define SDHCI_PCI_SLOTS(x) ((((x) >> 4) & 0x7) + 1) 19 #define SDHCI_PCI_SLOT_INFO_FIRST_BASE_INDEX(x) ((x) & 0x7) 20 21 // Ricoh specific PCI registers 22 // Ricoh devices start in a vendor-specific mode but can be switched 23 // to standard sdhci using these PCI registers 24 #define SDHCI_PCI_RICOH_MODE_KEY 0xf9 25 #define SDHCI_PCI_RICOH_MODE 0x150 26 #define SDHCI_PCI_RICOH_MODE_SD20 0x10 27 28 #define SDHCI_BUS_TYPE_NAME "bus/sdhci/v1" 29 30 31 class SdhciBus { 32 public: 33 SdhciBus(struct registers* registers, uint8_t irq, bool poll); 34 ~SdhciBus(); 35 36 void EnableInterrupts(uint32_t mask); 37 void DisableInterrupts(); 38 status_t ExecuteCommand(uint8_t command, uint32_t argument, 39 uint32_t* response); 40 int32 HandleInterrupt(); 41 status_t InitCheck(); 42 void Reset(); 43 void SetClock(int kilohertz); 44 status_t DoIO(uint8_t command, IOOperation* operation, 45 bool offsetAsSectors); 46 void SetScanSemaphore(sem_id sem); 47 void SetBusWidth(int width); 48 49 private: 50 bool PowerOn(); 51 void RecoverError(); 52 static status_t _WorkerThread(void*); 53 54 private: 55 struct registers* fRegisters; 56 uint32_t fCommandResult; 57 uint8_t fIrq; 58 sem_id fSemaphore; 59 sem_id fScanSemaphore; 60 status_t fStatus; 61 thread_id fWorkerThread; 62 }; 63 64 65 class SdhciDevice { 66 public: 67 device_node* fNode; 68 uint8_t fRicohOriginalMode; 69 }; 70 71 class TransferMode { 72 public: 73 uint16_t Bits() { return fBits; } 74 75 // TODO response interrupt 76 // TODO response check 77 78 static const uint8_t kR1 = 0 << 6; 79 static const uint8_t kR5 = 1 << 6; 80 81 static const uint8_t kMulti = 1 << 5; 82 static const uint8_t kSingle = 0 << 5; 83 84 static const uint8_t kRead = 1 << 4; 85 static const uint8_t kWrite = 0 << 4; 86 87 static const uint8_t kAutoCmdDisabled = 0 << 2; 88 static const uint8_t kAutoCmd12Enable = 1 << 2; 89 static const uint8_t kAutoCmd23Enable = 2 << 2; 90 static const uint8_t kAutoCmdAutoSelect 91 = kAutoCmd23Enable | kAutoCmd12Enable; 92 93 static const uint8_t kBlockCountEnable = 1 << 1; 94 95 static const uint8_t kDmaEnable = 1; 96 static const uint8_t kNoDmaOrNoData = 0; 97 98 private: 99 volatile uint16_t fBits; 100 } __attribute__((packed)); 101 102 103 class Command { 104 public: 105 uint16_t Bits() { return fBits; } 106 107 void SendCommand(uint8_t command, uint8_t type) 108 { 109 fBits = (command << 8) | type; 110 } 111 112 static const uint8_t kDataPresent = 0x20; 113 static const uint8_t kCheckIndex = 0x10; 114 static const uint8_t kCRCEnable = 0x8; 115 static const uint8_t kSubCommand = 0x4; 116 static const uint8_t kReplySizeMask = 0x3; 117 static const uint8_t k32BitResponse = 0x2; 118 static const uint8_t k128BitResponse = 0x1; 119 static const uint8_t k32BitResponseCheckBusy = 0x3; 120 121 // For simplicity pre-define the standard response types from the SD 122 // card specification 123 static const uint8_t kNoReplyType = 0; 124 static const uint8_t kR1Type = kCheckIndex | kCRCEnable 125 | k32BitResponse; 126 static const uint8_t kR1bType = (kCheckIndex | kCRCEnable 127 | k32BitResponseCheckBusy) & (~ kDataPresent); 128 static const uint8_t kR2Type = kCRCEnable | k128BitResponse; 129 static const uint8_t kR3Type = k32BitResponse; 130 static const uint8_t kR6Type = kCheckIndex | k32BitResponse; 131 static const uint8_t kR7Type = kCheckIndex | kCRCEnable 132 | k32BitResponse; 133 134 private: 135 volatile uint16_t fBits; 136 } __attribute__((packed)); 137 138 139 class PresentState { 140 public: 141 uint32_t Bits() { return fBits; } 142 143 bool IsCardInserted() { return fBits & (1 << 16); } 144 bool CommandInhibit() { return fBits & (1 << 0); } 145 bool DataInhibit() { return fBits & (1 << 1); } 146 147 private: 148 volatile uint32_t fBits; 149 } __attribute__((packed)); 150 151 152 class PowerControl { 153 public: 154 uint8_t Bits() { return fBits; } 155 156 void SetVoltage(int voltage) { 157 fBits |= voltage | kBusPowerOn; 158 } 159 void PowerOff() { fBits &= ~kBusPowerOn; } 160 161 static const uint8_t k3v3 = 7 << 1; 162 static const uint8_t k3v0 = 6 << 1; 163 static const uint8_t k1v8 = 5 << 1; 164 private: 165 volatile uint8_t fBits; 166 167 static const uint8_t kBusPowerOn = 1; 168 } __attribute__((packed)); 169 170 171 class ClockControl 172 { 173 public: 174 uint16_t Bits() { return fBits; } 175 176 uint16_t SetDivider(uint16_t divider) { 177 if (divider == 1) 178 divider = 0; 179 else 180 divider /= 2; 181 uint16_t bits = fBits & ~0xffc0; 182 bits |= divider << 8; 183 bits |= (divider >> 8) & 0xc0; 184 fBits = bits; 185 186 return divider == 0 ? 1 : divider * 2; 187 } 188 189 void EnableInternal() { fBits |= 1 << 0; } 190 bool InternalStable() { return fBits & (1 << 1); } 191 void EnableSD() { fBits |= 1 << 2; } 192 void DisableSD() { fBits &= ~(1 << 2); } 193 void EnablePLL() { fBits |= 1 << 3; } 194 private: 195 volatile uint16_t fBits; 196 } __attribute__((packed)); 197 198 199 class SoftwareReset { 200 public: 201 uint8_t Bits() { return fBits; } 202 203 bool ResetAll() { 204 fBits = 1; 205 int i = 0; 206 // wait up to 100ms 207 while ((fBits & 1) != 0 && i++ < 10) 208 snooze(10000); 209 return i < 10; 210 } 211 212 void ResetCommandLine() { 213 fBits |= 2; 214 while(fBits & 2); 215 } 216 217 private: 218 volatile uint8_t fBits; 219 } __attribute__((packed)); 220 221 222 // #pragma mark Interrupt registers 223 #define SDHCI_INT_CMD_CMP 0x00000001 // command complete enable 224 #define SDHCI_INT_TRANS_CMP 0x00000002 // transfer complete enable 225 #define SDHCI_INT_BUF_READ_READY 0x00000020 // buffer read ready enable 226 #define SDHCI_INT_CARD_INS 0x00000040 // card insertion enable 227 #define SDHCI_INT_CARD_REM 0x00000080 // card removal enable 228 #define SDHCI_INT_ERROR 0x00008000 // error 229 #define SDHCI_INT_TIMEOUT 0x00010000 // Timeout error 230 #define SDHCI_INT_CRC 0x00020000 // CRC error 231 #define SDHCI_INT_END_BIT 0x00040000 // end bit error 232 #define SDHCI_INT_INDEX 0x00080000 // index error 233 #define SDHCI_INT_BUS_POWER 0x00800000 // power fail 234 235 #define SDHCI_INT_CMD_ERROR_MASK (SDHCI_INT_TIMEOUT | \ 236 SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) 237 238 #define SDHCI_INT_CMD_MASK (SDHCI_INT_CMD_CMP | SDHCI_INT_CMD_ERROR_MASK) 239 240 // #pragma mark - 241 class Capabilities 242 { 243 public: 244 uint64_t Bits() { return fBits; } 245 246 uint8_t SupportedVoltages() { return (fBits >> 24) & 7; } 247 uint8_t BaseClockFrequency() { return (fBits >> 8) & 0xFF; } 248 249 static const uint8_t k3v3 = 1; 250 static const uint8_t k3v0 = 2; 251 static const uint8_t k1v8 = 4; 252 253 private: 254 uint64_t fBits; 255 } __attribute__((packed)); 256 257 258 class HostControllerVersion { 259 public: 260 const uint8_t specVersion; 261 const uint8_t vendorVersion; 262 } __attribute__((packed)); 263 264 265 class HostControl { 266 public: 267 void SetDMAMode(uint8_t dmaMode) 268 { 269 value = (value & ~kDmaMask) | dmaMode; 270 } 271 272 void SetDataTransferWidth(uint8_t width) 273 { 274 value = (value & ~kDataTransferWidthMask) | width; 275 } 276 277 static const uint8_t kDmaMask = 3 << 3; 278 static const uint8_t kSdma = 0 << 3; 279 static const uint8_t kAdma32 = 2 << 3; 280 static const uint8_t kAdma64 = 3 << 3; 281 282 // It's convenient to think of this as a single "bit width" setting, 283 // but the bits for 4-bit and 8-bit modes were introduced at different 284 // times and are not next to each other in the register. 285 static const uint8_t kDataTransfer1Bit = 0; 286 static const uint8_t kDataTransfer4Bit = 1 << 1; 287 static const uint8_t kDataTransfer8Bit = 1 << 5; 288 289 static const uint8_t kDataTransferWidthMask 290 = kDataTransfer4Bit | kDataTransfer8Bit; 291 private: 292 volatile uint8_t value; 293 } __attribute__((packed)); 294 295 296 class BlockSize { 297 public: 298 void ConfigureTransfer(uint16_t transferBlockSize, 299 uint16_t dmaBoundary) 300 { 301 value = transferBlockSize | dmaBoundary << 12; 302 } 303 304 static const uint16_t kDmaBoundary4K = 0; 305 static const uint16_t kDmaBoundary8K = 1; 306 static const uint16_t kDmaBoundary16K = 2; 307 static const uint16_t kDmaBoundary32K = 3; 308 static const uint16_t kDmaBoundary64K = 4; 309 static const uint16_t kDmaBoundary128K = 5; 310 static const uint16_t kDmaBoundary256K = 6; 311 static const uint16_t kDmaBoundary512K = 7; 312 313 private: 314 volatile uint16_t value; 315 } __attribute__((packed)); 316 317 318 // #pragma mark - 319 struct registers { 320 // SD command generation 321 volatile uint32_t system_address; 322 BlockSize block_size; 323 volatile uint16_t block_count; 324 volatile uint32_t argument; 325 volatile uint16_t transfer_mode; 326 Command command; 327 328 // Response 329 volatile uint32_t response[4]; 330 331 // Buffer Data Port 332 volatile uint32_t buffer_data_port; 333 334 // Host control 1 335 PresentState present_state; 336 HostControl host_control; 337 PowerControl power_control; 338 volatile uint8_t block_gap_control; 339 volatile uint8_t wakeup_control; 340 ClockControl clock_control; 341 volatile uint8_t timeout_control; 342 SoftwareReset software_reset; 343 344 // Interrupt control 345 volatile uint32_t interrupt_status; 346 volatile uint32_t interrupt_status_enable; 347 volatile uint32_t interrupt_signal_enable; 348 volatile uint16_t auto_cmd12_error_status; 349 350 // Host control 2 351 volatile uint16_t host_control_2; 352 353 // Capabilities 354 Capabilities capabilities; 355 volatile uint64_t max_current_capabilities; 356 357 // Force event 358 volatile uint16_t force_event_acmd_status; 359 volatile uint16_t force_event_error_status; 360 361 // ADMA2 362 volatile uint8_t adma_error_status; 363 volatile uint8_t padding[3]; 364 volatile uint64_t adma_system_address; 365 366 // Preset values 367 volatile uint64_t preset_value[2]; 368 volatile uint32_t padding1 :32; 369 volatile uint16_t uhs2_preset_value; 370 volatile uint16_t padding2 :16; 371 372 // ADMA3 373 volatile uint64_t adma3_id_address; 374 375 // UHS-II 376 volatile uint16_t uhs2_block_size; 377 volatile uint16_t padding3 :16; 378 volatile uint32_t uhs2_block_count; 379 volatile uint8_t uhs2_command_packet[20]; 380 volatile uint16_t uhs2_transfer_mode; 381 volatile uint16_t uhs2_command; 382 volatile uint8_t uhs2_response[20]; 383 volatile uint8_t uhs2_msg_select; 384 volatile uint8_t padding4[3]; 385 volatile uint32_t uhs2_msg; 386 volatile uint16_t uhs2_device_interrupt_status; 387 volatile uint8_t uhs2_device_select; 388 volatile uint8_t uhs2_device_int_code; 389 volatile uint16_t uhs2_software_reset; 390 volatile uint16_t uhs2_timer_control; 391 volatile uint32_t uhs2_error_interrupt_status; 392 volatile uint32_t uhs2_error_interrupt_status_enable; 393 volatile uint32_t uhs2_error_interrupt_signal_enable; 394 volatile uint8_t padding5[16]; 395 396 // Pointers 397 volatile uint16_t uhs2_settings_pointer; 398 volatile uint16_t uhs2_host_capabilities_pointer; 399 volatile uint16_t uhs2_test_pointer; 400 volatile uint16_t embedded_control_pointer; 401 volatile uint16_t vendor_specific_pointer; 402 volatile uint16_t reserved_specific_pointer; 403 volatile uint8_t padding6[16]; 404 405 // Common area 406 volatile uint16_t slot_interrupt_status; 407 HostControllerVersion host_controller_version; 408 } __attribute__((packed)); 409 410 typedef void* sdhci_mmc_bus; 411 412 struct sdhci_crs { 413 uint8 irq; 414 // uint8 irq_triggering; 415 // uint8 irq_polarity; 416 // uint8 irq_shareable; 417 418 uint32 addr_bas; 419 uint32 addr_len; 420 }; 421 422 extern float supports_device_acpi(device_node* parent); 423 extern float supports_device_pci(device_node* parent); 424 425 extern status_t register_child_devices_acpi(void* cookie); 426 extern status_t register_child_devices_pci(void* cookie); 427 428 extern status_t init_device_pci(device_node* node, SdhciDevice* context); 429 extern void uninit_device_pci(SdhciDevice* context, device_node* pciParent); 430 431 extern status_t init_bus_acpi(device_node* node, void** bus_cookie); 432 extern status_t init_bus_pci(device_node* node, void** bus_cookie); 433 434 extern void uninit_bus(void* bus_cookie); 435 extern void bus_removed(void* bus_cookie); 436 437 status_t set_clock(void* controller, uint32_t kilohertz); 438 status_t execute_command(void* controller, uint8_t command, 439 uint32_t argument, uint32_t* response); 440 status_t do_io(void* controller, uint8_t command, 441 IOOperation* operation, bool offsetAsSectors); 442 void set_scan_semaphore(void* controller, sem_id sem); 443 void set_bus_width(void* controller, int width); 444 445 extern mmc_bus_interface gSDHCIACPIDeviceModule; 446 extern mmc_bus_interface gSDHCIPCIDeviceModule; 447 448 extern device_manager_info* gDeviceManager; 449 450 #endif /*_SDHCI_H*/ 451