1 /* 2 * Copyright 2018-2020 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 "mmc_bus.h" 9 10 #include <Errors.h> 11 12 #include <stdint.h> 13 14 15 MMCBus::MMCBus(device_node* node) 16 : 17 fNode(node), 18 fController(NULL), 19 fCookie(NULL), 20 fStatus(B_OK), 21 fWorkerThread(0) 22 { 23 CALLED(); 24 25 // Get the parent info, it includes the API to send commands to the hardware 26 device_node* parent = gDeviceManager->get_parent_node(node); 27 fStatus = gDeviceManager->get_driver(parent, 28 (driver_module_info**)&fController, &fCookie); 29 gDeviceManager->put_node(parent); 30 31 if (fStatus != B_OK) { 32 ERROR("Not able to establish the bus %s\n", 33 strerror(fStatus)); 34 return; 35 } 36 37 fSemaphore = create_sem(0, "MMC bus scan"); 38 fWorkerThread = spawn_kernel_thread(WorkerThread, "SD bus controller", 39 B_NORMAL_PRIORITY, this); 40 resume_thread(fWorkerThread); 41 } 42 43 44 MMCBus::~MMCBus() 45 { 46 CALLED(); 47 48 // stop worker thread 49 fStatus = B_SHUTTING_DOWN; 50 51 status_t result; 52 if (fWorkerThread != 0) 53 wait_for_thread(fWorkerThread, &result); 54 // TODO power off cards, stop clock, etc if needed. 55 } 56 57 58 status_t 59 MMCBus::InitCheck() 60 { 61 return fStatus; 62 } 63 64 65 void 66 MMCBus::Rescan() 67 { 68 // Just wake up the thread for a scan 69 release_sem(fSemaphore); 70 } 71 72 73 status_t 74 MMCBus::ExecuteCommand(uint8_t command, uint32_t argument, uint32_t* response) 75 { 76 return fController->execute_command(fCookie, command, argument, response); 77 } 78 79 80 status_t 81 MMCBus::WorkerThread(void* cookie) 82 { 83 MMCBus* bus = (MMCBus*)cookie; 84 uint32_t response; 85 86 // We assume the bus defaults to 400kHz clock and has already powered on 87 // cards. 88 89 // Reset all cards on the bus 90 bus->ExecuteCommand(0, 0, NULL); 91 92 while (bus->fStatus != B_SHUTTING_DOWN) { 93 // wait for bus to signal a card is inserted 94 acquire_sem(bus->fSemaphore); 95 TRACE("Scanning the bus\n"); 96 97 // Probe the voltage range 98 // FIXME MMC cards will not reply to this! They expect CMD1 instead 99 // SD v1 cards will also not reply, but we can proceed to ACMD41 100 // If ACMD41 also does not work, it may be an SDIO card, too 101 uint32_t probe = (1 << 8) | 0xAA; 102 uint32_t hcs = 1 << 30; 103 if (bus->ExecuteCommand(8, probe, &response) != B_OK) { 104 TRACE("Card does not implement CMD8, may be a V1 SD card\n"); 105 // Do not check for SDHC support in this case 106 hcs = 0; 107 } else if (response != probe) { 108 ERROR("Card does not support voltage range (expected %x, " 109 "reply %x)\n", probe, response); 110 // TODO what now? 111 } 112 113 // Probe OCR, waiting for card to become ready 114 uint32_t ocr; 115 do { 116 uint32_t cardStatus; 117 while (bus->ExecuteCommand(55, 0, &cardStatus) 118 == B_BUSY) { 119 ERROR("Card locked after CMD8...\n"); 120 snooze(1000000); 121 } 122 if ((cardStatus & 0xFFFF8000) != 0) 123 ERROR("SD card reports error %x\n", cardStatus); 124 if ((cardStatus & (1 << 5)) == 0) 125 ERROR("Card did not enter ACMD mode\n"); 126 127 bus->ExecuteCommand(41, hcs | 0xFF8000, &ocr); 128 129 if ((ocr & (1 << 31)) == 0) { 130 TRACE("Card is busy\n"); 131 snooze(100000); 132 } 133 } while (((ocr & (1 << 31)) == 0)); 134 135 // FIXME this should be asked to each card, when there are multiple 136 // ones. So ACMD41 should be moved inside the probing loop below? 137 uint8_t cardType = CARD_TYPE_SD; 138 139 if (ocr & hcs != 0) 140 cardType = CARD_TYPE_SDHC; 141 if (ocr & (1 << 29) != 0) 142 cardType = CARD_TYPE_UHS2; 143 if (ocr & (1 << 24) != 0) 144 TRACE("Card supports 1.8v"); 145 TRACE("Voltage range: %x\n", ocr & 0xFFFFFF); 146 147 // TODO send CMD11 to switch to low voltage mode if card supports it? 148 149 // iterate CMD2/CMD3 to assign an RCA to all cards and publish devices 150 // for each of them 151 uint32_t cid[4]; 152 while (bus->ExecuteCommand(2, 0, cid) == B_OK) { 153 bus->ExecuteCommand(3, 0, &response); 154 155 TRACE("RCA: %x Status: %x\n", response >> 16, response & 0xFFFF); 156 157 if ((response & 0xFF00) != 0x500) { 158 TRACE("Card did not enter data state\n"); 159 // This probably means there are no more cards to scan on the 160 // bus, so exit the loop. 161 break; 162 } 163 164 // The card now has an RCA and it entered the data phase, which 165 // means our initializing job is over, we can pass it on to the 166 // mmc_disk driver. 167 168 uint32_t vendor = cid[3] & 0xFFFFFF; 169 char name[6] = {cid[2] >> 24, cid[2] >> 16, cid[2] >> 8, cid[2], 170 cid[1] >> 24, 0}; 171 uint32_t serial = (cid[1] << 16) | (cid[0] >> 16); 172 uint16_t revision = (cid[1] >> 20) & 0xF; 173 revision *= 100; 174 revision += (cid[1] >> 16) & 0xF; 175 uint8_t month = cid[0] & 0xF; 176 uint16_t year = 2000 + ((cid[0] >> 4) & 0xFF); 177 uint16_t rca = response >> 16; 178 179 device_attr attrs[] = { 180 { B_DEVICE_BUS, B_STRING_TYPE, {string: "mmc" }}, 181 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "mmc device" }}, 182 { B_DEVICE_VENDOR_ID, B_UINT32_TYPE, {ui32: vendor}}, 183 { B_DEVICE_ID, B_STRING_TYPE, {string: name}}, 184 { B_DEVICE_UNIQUE_ID, B_UINT32_TYPE, {ui32: serial}}, 185 { "mmc/revision", B_UINT16_TYPE, {ui16: revision}}, 186 { "mmc/month", B_UINT8_TYPE, {ui8: month}}, 187 { "mmc/year", B_UINT16_TYPE, {ui16: year}}, 188 { "mmc/rca", B_UINT16_TYPE, {ui16: rca}}, 189 { "mmc/type", B_UINT8_TYPE, {ui8: cardType}}, 190 {} 191 }; 192 193 // publish child device for the card 194 gDeviceManager->register_node(bus->fNode, MMC_BUS_MODULE_NAME, 195 attrs, NULL, NULL); 196 } 197 198 // FIXME we also need to unpublish devices that are gone. Probably need 199 // to "ping" all RCAs somehow? Or is there an interrupt we can look for 200 // to detect added/removed cards? 201 } 202 203 TRACE("poller thread terminating"); 204 return B_OK; 205 } 206