sdhci.c (b019f5e5375224a003f260c89d424fea7767b7fc) | sdhci.c (ce864603443567b8186dc435ebba08338ef4a6d6) |
---|---|
1/* 2 * SD Association Host Standard Specification v2.0 controller emulation 3 * 4 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 5 * Mitsyanko Igor <i.mitsyanko@samsung.com> 6 * Peter A.G. Crosthwaite <peter.crosthwaite@petalogix.com> 7 * 8 * Based on MMC controller for Samsung S5PC1xx-based board emulation --- 26 unchanged lines hidden (view full) --- 35#include "qemu/log.h" 36#include "trace.h" 37 38#define TYPE_SDHCI_BUS "sdhci-bus" 39#define SDHCI_BUS(obj) OBJECT_CHECK(SDBus, (obj), TYPE_SDHCI_BUS) 40 41#define MASKED_WRITE(reg, mask, val) (reg = (reg & (mask)) | (val)) 42 | 1/* 2 * SD Association Host Standard Specification v2.0 controller emulation 3 * 4 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 5 * Mitsyanko Igor <i.mitsyanko@samsung.com> 6 * Peter A.G. Crosthwaite <peter.crosthwaite@petalogix.com> 7 * 8 * Based on MMC controller for Samsung S5PC1xx-based board emulation --- 26 unchanged lines hidden (view full) --- 35#include "qemu/log.h" 36#include "trace.h" 37 38#define TYPE_SDHCI_BUS "sdhci-bus" 39#define SDHCI_BUS(obj) OBJECT_CHECK(SDBus, (obj), TYPE_SDHCI_BUS) 40 41#define MASKED_WRITE(reg, mask, val) (reg = (reg & (mask)) | (val)) 42 |
43/* Default SD/MMC host controller features information, which will be 44 * presented in CAPABILITIES register of generic SD host controller at reset. 45 * 46 * support: 47 * - 3.3v and 1.8v voltages 48 * - SDMA/ADMA1/ADMA2 49 * - high-speed 50 * max host controller R/W buffers size: 512B 51 * max clock frequency for SDclock: 52 MHz 52 * timeout clock frequency: 52 MHz 53 * 54 * does not support: 55 * - 3.0v voltage 56 * - 64-bit system bus 57 * - suspend/resume 58 */ 59#define SDHC_CAPAB_REG_DEFAULT 0x057834b4 60 | |
61static inline unsigned int sdhci_get_fifolen(SDHCIState *s) 62{ 63 return 1 << (9 + FIELD_EX32(s->capareg, SDHC_CAPAB, MAXBLOCKLENGTH)); 64} 65 66/* return true on error */ 67static bool sdhci_check_capab_freq_range(SDHCIState *s, const char *desc, 68 uint8_t freq, Error **errp) --- 1254 unchanged lines hidden (view full) --- 1323 if (local_err) { 1324 error_propagate(errp, local_err); 1325 return; 1326 } 1327} 1328 1329/* --- qdev common --- */ 1330 | 43static inline unsigned int sdhci_get_fifolen(SDHCIState *s) 44{ 45 return 1 << (9 + FIELD_EX32(s->capareg, SDHC_CAPAB, MAXBLOCKLENGTH)); 46} 47 48/* return true on error */ 49static bool sdhci_check_capab_freq_range(SDHCIState *s, const char *desc, 50 uint8_t freq, Error **errp) --- 1254 unchanged lines hidden (view full) --- 1305 if (local_err) { 1306 error_propagate(errp, local_err); 1307 return; 1308 } 1309} 1310 1311/* --- qdev common --- */ 1312 |
1331#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \ 1332 DEFINE_PROP_UINT8("sd-spec-version", _state, sd_spec_version, 2), \ 1333 DEFINE_PROP_UINT8("uhs", _state, uhs_mode, UHS_NOT_SUPPORTED), \ 1334 \ 1335 /* Capabilities registers provide information on supported 1336 * features of this specific host controller implementation */ \ 1337 DEFINE_PROP_UINT64("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \ 1338 DEFINE_PROP_UINT64("maxcurr", _state, maxcurr, 0) 1339 1340static void sdhci_initfn(SDHCIState *s) | 1313void sdhci_initfn(SDHCIState *s) |
1341{ 1342 qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), 1343 TYPE_SDHCI_BUS, DEVICE(s), "sd-bus"); 1344 1345 s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s); 1346 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s); 1347 1348 s->io_ops = &sdhci_mmio_ops; 1349} 1350 | 1314{ 1315 qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), 1316 TYPE_SDHCI_BUS, DEVICE(s), "sd-bus"); 1317 1318 s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s); 1319 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s); 1320 1321 s->io_ops = &sdhci_mmio_ops; 1322} 1323 |
1351static void sdhci_uninitfn(SDHCIState *s) | 1324void sdhci_uninitfn(SDHCIState *s) |
1352{ 1353 timer_del(s->insert_timer); 1354 timer_free(s->insert_timer); 1355 timer_del(s->transfer_timer); 1356 timer_free(s->transfer_timer); 1357 1358 g_free(s->fifo_buffer); 1359 s->fifo_buffer = NULL; 1360} 1361 | 1325{ 1326 timer_del(s->insert_timer); 1327 timer_free(s->insert_timer); 1328 timer_del(s->transfer_timer); 1329 timer_free(s->transfer_timer); 1330 1331 g_free(s->fifo_buffer); 1332 s->fifo_buffer = NULL; 1333} 1334 |
1362static void sdhci_common_realize(SDHCIState *s, Error **errp) | 1335void sdhci_common_realize(SDHCIState *s, Error **errp) |
1363{ 1364 Error *local_err = NULL; 1365 1366 sdhci_init_readonly_registers(s, &local_err); 1367 if (local_err) { 1368 error_propagate(errp, local_err); 1369 return; 1370 } 1371 s->buf_maxsz = sdhci_get_fifolen(s); 1372 s->fifo_buffer = g_malloc0(s->buf_maxsz); 1373 1374 memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci", 1375 SDHC_REGISTERS_MAP_SIZE); 1376} 1377 | 1336{ 1337 Error *local_err = NULL; 1338 1339 sdhci_init_readonly_registers(s, &local_err); 1340 if (local_err) { 1341 error_propagate(errp, local_err); 1342 return; 1343 } 1344 s->buf_maxsz = sdhci_get_fifolen(s); 1345 s->fifo_buffer = g_malloc0(s->buf_maxsz); 1346 1347 memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci", 1348 SDHC_REGISTERS_MAP_SIZE); 1349} 1350 |
1378static void sdhci_common_unrealize(SDHCIState *s, Error **errp) | 1351void sdhci_common_unrealize(SDHCIState *s, Error **errp) |
1379{ 1380 /* This function is expected to be called only once for each class: 1381 * - SysBus: via DeviceClass->unrealize(), 1382 * - PCI: via PCIDeviceClass->exit(). 1383 * However to avoid double-free and/or use-after-free we still nullify 1384 * this variable (better safe than sorry!). */ 1385 g_free(s->fifo_buffer); 1386 s->fifo_buffer = NULL; --- 53 unchanged lines hidden (view full) --- 1440 VMSTATE_END_OF_LIST() 1441 }, 1442 .subsections = (const VMStateDescription*[]) { 1443 &sdhci_pending_insert_vmstate, 1444 NULL 1445 }, 1446}; 1447 | 1352{ 1353 /* This function is expected to be called only once for each class: 1354 * - SysBus: via DeviceClass->unrealize(), 1355 * - PCI: via PCIDeviceClass->exit(). 1356 * However to avoid double-free and/or use-after-free we still nullify 1357 * this variable (better safe than sorry!). */ 1358 g_free(s->fifo_buffer); 1359 s->fifo_buffer = NULL; --- 53 unchanged lines hidden (view full) --- 1413 VMSTATE_END_OF_LIST() 1414 }, 1415 .subsections = (const VMStateDescription*[]) { 1416 &sdhci_pending_insert_vmstate, 1417 NULL 1418 }, 1419}; 1420 |
1448static void sdhci_common_class_init(ObjectClass *klass, void *data) | 1421void sdhci_common_class_init(ObjectClass *klass, void *data) |
1449{ 1450 DeviceClass *dc = DEVICE_CLASS(klass); 1451 1452 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 1453 dc->vmsd = &sdhci_vmstate; 1454 dc->reset = sdhci_poweron_reset; 1455} 1456 | 1422{ 1423 DeviceClass *dc = DEVICE_CLASS(klass); 1424 1425 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 1426 dc->vmsd = &sdhci_vmstate; 1427 dc->reset = sdhci_poweron_reset; 1428} 1429 |
1457/* --- qdev PCI --- */ 1458 1459static Property sdhci_pci_properties[] = { 1460 DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState), 1461 DEFINE_PROP_END_OF_LIST(), 1462}; 1463 1464static void sdhci_pci_realize(PCIDevice *dev, Error **errp) 1465{ 1466 SDHCIState *s = PCI_SDHCI(dev); 1467 Error *local_err = NULL; 1468 1469 sdhci_initfn(s); 1470 sdhci_common_realize(s, &local_err); 1471 if (local_err) { 1472 error_propagate(errp, local_err); 1473 return; 1474 } 1475 1476 dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */ 1477 dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */ 1478 s->irq = pci_allocate_irq(dev); 1479 s->dma_as = pci_get_address_space(dev); 1480 pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->iomem); 1481} 1482 1483static void sdhci_pci_exit(PCIDevice *dev) 1484{ 1485 SDHCIState *s = PCI_SDHCI(dev); 1486 1487 sdhci_common_unrealize(s, &error_abort); 1488 sdhci_uninitfn(s); 1489} 1490 1491static void sdhci_pci_class_init(ObjectClass *klass, void *data) 1492{ 1493 DeviceClass *dc = DEVICE_CLASS(klass); 1494 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 1495 1496 k->realize = sdhci_pci_realize; 1497 k->exit = sdhci_pci_exit; 1498 k->vendor_id = PCI_VENDOR_ID_REDHAT; 1499 k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI; 1500 k->class_id = PCI_CLASS_SYSTEM_SDHCI; 1501 dc->props = sdhci_pci_properties; 1502 1503 sdhci_common_class_init(klass, data); 1504} 1505 1506static const TypeInfo sdhci_pci_info = { 1507 .name = TYPE_PCI_SDHCI, 1508 .parent = TYPE_PCI_DEVICE, 1509 .instance_size = sizeof(SDHCIState), 1510 .class_init = sdhci_pci_class_init, 1511 .interfaces = (InterfaceInfo[]) { 1512 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 1513 { }, 1514 }, 1515}; 1516 | |
1517/* --- qdev SysBus --- */ 1518 1519static Property sdhci_sysbus_properties[] = { 1520 DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState), 1521 DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk, 1522 false), 1523 DEFINE_PROP_LINK("dma", SDHCIState, 1524 dma_mr, TYPE_MEMORY_REGION, MemoryRegion *), --- 316 unchanged lines hidden (view full) --- 1841static const TypeInfo imx_usdhc_info = { 1842 .name = TYPE_IMX_USDHC, 1843 .parent = TYPE_SYSBUS_SDHCI, 1844 .instance_init = imx_usdhc_init, 1845}; 1846 1847static void sdhci_register_types(void) 1848{ | 1430/* --- qdev SysBus --- */ 1431 1432static Property sdhci_sysbus_properties[] = { 1433 DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState), 1434 DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk, 1435 false), 1436 DEFINE_PROP_LINK("dma", SDHCIState, 1437 dma_mr, TYPE_MEMORY_REGION, MemoryRegion *), --- 316 unchanged lines hidden (view full) --- 1754static const TypeInfo imx_usdhc_info = { 1755 .name = TYPE_IMX_USDHC, 1756 .parent = TYPE_SYSBUS_SDHCI, 1757 .instance_init = imx_usdhc_init, 1758}; 1759 1760static void sdhci_register_types(void) 1761{ |
1849 type_register_static(&sdhci_pci_info); | |
1850 type_register_static(&sdhci_sysbus_info); 1851 type_register_static(&sdhci_bus_info); 1852 type_register_static(&imx_usdhc_info); 1853} 1854 1855type_init(sdhci_register_types) | 1762 type_register_static(&sdhci_sysbus_info); 1763 type_register_static(&sdhci_bus_info); 1764 type_register_static(&imx_usdhc_info); 1765} 1766 1767type_init(sdhci_register_types) |