1*0bf96f94SGerd Hoffmann /* 2*0bf96f94SGerd Hoffmann * QEMU USB EHCI Emulation 3*0bf96f94SGerd Hoffmann * 4*0bf96f94SGerd Hoffmann * This library is free software; you can redistribute it and/or 5*0bf96f94SGerd Hoffmann * modify it under the terms of the GNU Lesser General Public 6*0bf96f94SGerd Hoffmann * License as published by the Free Software Foundation; either 7*0bf96f94SGerd Hoffmann * version 2 of the License, or(at your option) any later version. 8*0bf96f94SGerd Hoffmann * 9*0bf96f94SGerd Hoffmann * This library is distributed in the hope that it will be useful, 10*0bf96f94SGerd Hoffmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 11*0bf96f94SGerd Hoffmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12*0bf96f94SGerd Hoffmann * Lesser General Public License for more details. 13*0bf96f94SGerd Hoffmann * 14*0bf96f94SGerd Hoffmann * You should have received a copy of the GNU General Public License 15*0bf96f94SGerd Hoffmann * along with this program; if not, see <http://www.gnu.org/licenses/>. 16*0bf96f94SGerd Hoffmann */ 17*0bf96f94SGerd Hoffmann 18*0bf96f94SGerd Hoffmann #include "hw/usb/hcd-ehci.h" 19*0bf96f94SGerd Hoffmann #include "hw/pci.h" 20*0bf96f94SGerd Hoffmann 21*0bf96f94SGerd Hoffmann typedef struct EHCIPCIState { 22*0bf96f94SGerd Hoffmann PCIDevice pcidev; 23*0bf96f94SGerd Hoffmann EHCIState ehci; 24*0bf96f94SGerd Hoffmann } EHCIPCIState; 25*0bf96f94SGerd Hoffmann 26*0bf96f94SGerd Hoffmann static int usb_ehci_pci_initfn(PCIDevice *dev) 27*0bf96f94SGerd Hoffmann { 28*0bf96f94SGerd Hoffmann EHCIPCIState *i = DO_UPCAST(EHCIPCIState, pcidev, dev); 29*0bf96f94SGerd Hoffmann EHCIState *s = &i->ehci; 30*0bf96f94SGerd Hoffmann uint8_t *pci_conf = dev->config; 31*0bf96f94SGerd Hoffmann 32*0bf96f94SGerd Hoffmann pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20); 33*0bf96f94SGerd Hoffmann 34*0bf96f94SGerd Hoffmann /* capabilities pointer */ 35*0bf96f94SGerd Hoffmann pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00); 36*0bf96f94SGerd Hoffmann /* pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50); */ 37*0bf96f94SGerd Hoffmann 38*0bf96f94SGerd Hoffmann pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); /* interrupt pin D */ 39*0bf96f94SGerd Hoffmann pci_set_byte(&pci_conf[PCI_MIN_GNT], 0); 40*0bf96f94SGerd Hoffmann pci_set_byte(&pci_conf[PCI_MAX_LAT], 0); 41*0bf96f94SGerd Hoffmann 42*0bf96f94SGerd Hoffmann /* pci_conf[0x50] = 0x01; *//* power management caps */ 43*0bf96f94SGerd Hoffmann 44*0bf96f94SGerd Hoffmann pci_set_byte(&pci_conf[USB_SBRN], USB_RELEASE_2); /* release # (2.1.4) */ 45*0bf96f94SGerd Hoffmann pci_set_byte(&pci_conf[0x61], 0x20); /* frame length adjustment (2.1.5) */ 46*0bf96f94SGerd Hoffmann pci_set_word(&pci_conf[0x62], 0x00); /* port wake up capability (2.1.6) */ 47*0bf96f94SGerd Hoffmann 48*0bf96f94SGerd Hoffmann pci_conf[0x64] = 0x00; 49*0bf96f94SGerd Hoffmann pci_conf[0x65] = 0x00; 50*0bf96f94SGerd Hoffmann pci_conf[0x66] = 0x00; 51*0bf96f94SGerd Hoffmann pci_conf[0x67] = 0x00; 52*0bf96f94SGerd Hoffmann pci_conf[0x68] = 0x01; 53*0bf96f94SGerd Hoffmann pci_conf[0x69] = 0x00; 54*0bf96f94SGerd Hoffmann pci_conf[0x6a] = 0x00; 55*0bf96f94SGerd Hoffmann pci_conf[0x6b] = 0x00; /* USBLEGSUP */ 56*0bf96f94SGerd Hoffmann pci_conf[0x6c] = 0x00; 57*0bf96f94SGerd Hoffmann pci_conf[0x6d] = 0x00; 58*0bf96f94SGerd Hoffmann pci_conf[0x6e] = 0x00; 59*0bf96f94SGerd Hoffmann pci_conf[0x6f] = 0xc0; /* USBLEFCTLSTS */ 60*0bf96f94SGerd Hoffmann 61*0bf96f94SGerd Hoffmann s->caps[0x09] = 0x68; /* EECP */ 62*0bf96f94SGerd Hoffmann 63*0bf96f94SGerd Hoffmann s->irq = dev->irq[3]; 64*0bf96f94SGerd Hoffmann s->dma = pci_dma_context(dev); 65*0bf96f94SGerd Hoffmann 66*0bf96f94SGerd Hoffmann s->capsbase = 0x00; 67*0bf96f94SGerd Hoffmann s->opregbase = 0x20; 68*0bf96f94SGerd Hoffmann 69*0bf96f94SGerd Hoffmann usb_ehci_initfn(s, DEVICE(dev)); 70*0bf96f94SGerd Hoffmann pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem); 71*0bf96f94SGerd Hoffmann 72*0bf96f94SGerd Hoffmann return 0; 73*0bf96f94SGerd Hoffmann } 74*0bf96f94SGerd Hoffmann 75*0bf96f94SGerd Hoffmann static Property ehci_pci_properties[] = { 76*0bf96f94SGerd Hoffmann DEFINE_PROP_UINT32("maxframes", EHCIPCIState, ehci.maxframes, 128), 77*0bf96f94SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 78*0bf96f94SGerd Hoffmann }; 79*0bf96f94SGerd Hoffmann 80*0bf96f94SGerd Hoffmann static const VMStateDescription vmstate_ehci_pci = { 81*0bf96f94SGerd Hoffmann .name = "ehci", 82*0bf96f94SGerd Hoffmann .version_id = 2, 83*0bf96f94SGerd Hoffmann .minimum_version_id = 1, 84*0bf96f94SGerd Hoffmann .fields = (VMStateField[]) { 85*0bf96f94SGerd Hoffmann VMSTATE_PCI_DEVICE(pcidev, EHCIPCIState), 86*0bf96f94SGerd Hoffmann VMSTATE_STRUCT(ehci, EHCIPCIState, 2, vmstate_ehci, EHCIState), 87*0bf96f94SGerd Hoffmann } 88*0bf96f94SGerd Hoffmann }; 89*0bf96f94SGerd Hoffmann 90*0bf96f94SGerd Hoffmann static void ehci_class_init(ObjectClass *klass, void *data) 91*0bf96f94SGerd Hoffmann { 92*0bf96f94SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 93*0bf96f94SGerd Hoffmann PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 94*0bf96f94SGerd Hoffmann 95*0bf96f94SGerd Hoffmann k->init = usb_ehci_pci_initfn; 96*0bf96f94SGerd Hoffmann k->vendor_id = PCI_VENDOR_ID_INTEL; 97*0bf96f94SGerd Hoffmann k->device_id = PCI_DEVICE_ID_INTEL_82801D; /* ich4 */ 98*0bf96f94SGerd Hoffmann k->revision = 0x10; 99*0bf96f94SGerd Hoffmann k->class_id = PCI_CLASS_SERIAL_USB; 100*0bf96f94SGerd Hoffmann dc->vmsd = &vmstate_ehci; 101*0bf96f94SGerd Hoffmann dc->props = ehci_pci_properties; 102*0bf96f94SGerd Hoffmann } 103*0bf96f94SGerd Hoffmann 104*0bf96f94SGerd Hoffmann static TypeInfo ehci_info = { 105*0bf96f94SGerd Hoffmann .name = "usb-ehci", 106*0bf96f94SGerd Hoffmann .parent = TYPE_PCI_DEVICE, 107*0bf96f94SGerd Hoffmann .instance_size = sizeof(EHCIState), 108*0bf96f94SGerd Hoffmann .class_init = ehci_class_init, 109*0bf96f94SGerd Hoffmann }; 110*0bf96f94SGerd Hoffmann 111*0bf96f94SGerd Hoffmann static void ich9_ehci_class_init(ObjectClass *klass, void *data) 112*0bf96f94SGerd Hoffmann { 113*0bf96f94SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 114*0bf96f94SGerd Hoffmann PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 115*0bf96f94SGerd Hoffmann 116*0bf96f94SGerd Hoffmann k->init = usb_ehci_pci_initfn; 117*0bf96f94SGerd Hoffmann k->vendor_id = PCI_VENDOR_ID_INTEL; 118*0bf96f94SGerd Hoffmann k->device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1; 119*0bf96f94SGerd Hoffmann k->revision = 0x03; 120*0bf96f94SGerd Hoffmann k->class_id = PCI_CLASS_SERIAL_USB; 121*0bf96f94SGerd Hoffmann dc->vmsd = &vmstate_ehci; 122*0bf96f94SGerd Hoffmann dc->props = ehci_pci_properties; 123*0bf96f94SGerd Hoffmann } 124*0bf96f94SGerd Hoffmann 125*0bf96f94SGerd Hoffmann static TypeInfo ich9_ehci_info = { 126*0bf96f94SGerd Hoffmann .name = "ich9-usb-ehci1", 127*0bf96f94SGerd Hoffmann .parent = TYPE_PCI_DEVICE, 128*0bf96f94SGerd Hoffmann .instance_size = sizeof(EHCIState), 129*0bf96f94SGerd Hoffmann .class_init = ich9_ehci_class_init, 130*0bf96f94SGerd Hoffmann }; 131*0bf96f94SGerd Hoffmann 132*0bf96f94SGerd Hoffmann static void ehci_pci_register_types(void) 133*0bf96f94SGerd Hoffmann { 134*0bf96f94SGerd Hoffmann type_register_static(&ehci_info); 135*0bf96f94SGerd Hoffmann type_register_static(&ich9_ehci_info); 136*0bf96f94SGerd Hoffmann } 137*0bf96f94SGerd Hoffmann 138*0bf96f94SGerd Hoffmann type_init(ehci_pci_register_types) 139