Commit e24ad6f140f23e1edc1646ea248819698b77f0e2

Authored by pbrook
1 parent 60a9f9ec

OHCI USB PXA support (Andrzej Zaborowski).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2490 c046a42c-6fe2-441c-8c8c-71466251a162
hw/ppc_chrp.c
... ... @@ -501,7 +501,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
501 501 }
502 502  
503 503 if (usb_enabled) {
504   - usb_ohci_init(pci_bus, 3, -1);
  504 + usb_ohci_init_pci(pci_bus, 3, -1);
505 505 }
506 506  
507 507 if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
... ...
hw/ppc_prep.c
... ... @@ -666,7 +666,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
666 666 #endif
667 667  
668 668 if (usb_enabled) {
669   - usb_ohci_init(pci_bus, 3, -1);
  669 + usb_ohci_init_pci(pci_bus, 3, -1);
670 670 }
671 671  
672 672 nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE, 59);
... ...
hw/realview.c
... ... @@ -57,7 +57,7 @@ static void realview_init(int ram_size, int vga_ram_size, int boot_device,
57 57  
58 58 pci_bus = pci_vpb_init(pic, 48, 1);
59 59 if (usb_enabled) {
60   - usb_ohci_init(pci_bus, 3, -1);
  60 + usb_ohci_init_pci(pci_bus, 3, -1);
61 61 }
62 62 scsi_hba = lsi_scsi_init(pci_bus, -1);
63 63 for (n = 0; n < MAX_DISKS; n++) {
... ...
hw/usb-ohci.c
... ... @@ -2,6 +2,7 @@
2 2 * QEMU USB OHCI Emulation
3 3 * Copyright (c) 2004 Gianni Tedesco
4 4 * Copyright (c) 2006 CodeSourcery
  5 + * Copyright (c) 2006 Openedhand Ltd.
5 6 *
6 7 * This library is free software; you can redistribute it and/or
7 8 * modify it under the terms of the GNU Lesser General Public
... ... @@ -52,11 +53,19 @@ typedef struct OHCIPort {
52 53 uint32_t ctrl;
53 54 } OHCIPort;
54 55  
  56 +enum ohci_type {
  57 + OHCI_TYPE_PCI,
  58 + OHCI_TYPE_PXA
  59 +};
  60 +
55 61 typedef struct {
56   - struct PCIDevice pci_dev;
  62 + void *pic;
  63 + int irq;
  64 + enum ohci_type type;
57 65 target_phys_addr_t mem_base;
58 66 int mem;
59 67 int num_ports;
  68 + const char *name;
60 69  
61 70 QEMUTimer *eof_timer;
62 71 int64_t sof_time;
... ... @@ -90,6 +99,12 @@ typedef struct {
90 99 uint32_t rhstatus;
91 100 OHCIPort rhport[OHCI_MAX_PORTS];
92 101  
  102 + /* PXA27x Non-OHCI events */
  103 + uint32_t hstatus;
  104 + uint32_t hmask;
  105 + uint32_t hreset;
  106 + uint32_t htest;
  107 +
93 108 /* Active packets. */
94 109 uint32_t old_ctl;
95 110 USBPacket usb_packet;
... ... @@ -256,6 +271,8 @@ struct ohci_td {
256 271 #define OHCI_CC_BUFFEROVERRUN 0xc
257 272 #define OHCI_CC_BUFFERUNDERRUN 0xd
258 273  
  274 +#define OHCI_HRESET_FSBIR (1 << 0)
  275 +
259 276 /* Update IRQ levels */
260 277 static inline void ohci_intr_update(OHCIState *ohci)
261 278 {
... ... @@ -265,7 +282,10 @@ static inline void ohci_intr_update(OHCIState *ohci)
265 282 (ohci->intr_status & ohci->intr))
266 283 level = 1;
267 284  
268   - pci_set_irq(&ohci->pci_dev, 0, level);
  285 + if (ohci->type == OHCI_TYPE_PCI)
  286 + pci_set_irq((PCIDevice *)ohci->pic, ohci->irq, level);
  287 + else
  288 + pic_set_irq_new(ohci->pic, ohci->irq, level);
269 289 }
270 290  
271 291 /* Set an interrupt */
... ... @@ -295,6 +315,11 @@ static void ohci_attach(USBPort *port1, USBDevice *dev)
295 315 else
296 316 port->ctrl &= ~OHCI_PORT_LSDA;
297 317 port->port.dev = dev;
  318 +
  319 + /* notify of remote-wakeup */
  320 + if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
  321 + ohci_set_interrupt(s, OHCI_INTR_RD);
  322 +
298 323 /* send the attach message */
299 324 usb_send_msg(dev, USB_MSG_ATTACH);
300 325 dprintf("usb-ohci: Attached port %d\n", port1->index);
... ... @@ -367,7 +392,7 @@ static void ohci_reset(OHCIState *ohci)
367 392 usb_cancel_packet(&ohci->usb_packet);
368 393 ohci->async_td = 0;
369 394 }
370   - dprintf("usb-ohci: Reset %s\n", ohci->pci_dev.name);
  395 + dprintf("usb-ohci: Reset %s\n", ohci->name);
371 396 }
372 397  
373 398 /* Get an array of dwords from main memory */
... ... @@ -795,13 +820,12 @@ static int ohci_bus_start(OHCIState *ohci)
795 820 ohci);
796 821  
797 822 if (ohci->eof_timer == NULL) {
798   - fprintf(stderr, "usb-ohci: %s: qemu_new_timer failed\n",
799   - ohci->pci_dev.name);
  823 + fprintf(stderr, "usb-ohci: %s: qemu_new_timer failed\n", ohci->name);
800 824 /* TODO: Signal unrecoverable error */
801 825 return 0;
802 826 }
803 827  
804   - dprintf("usb-ohci: %s: USB Operational\n", ohci->pci_dev.name);
  828 + dprintf("usb-ohci: %s: USB Operational\n", ohci->name);
805 829  
806 830 ohci_sof(ohci);
807 831  
... ... @@ -854,7 +878,7 @@ static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
854 878  
855 879 if (val != ohci->fi) {
856 880 dprintf("usb-ohci: %s: FrameInterval = 0x%x (%u)\n",
857   - ohci->pci_dev.name, ohci->fi, ohci->fi);
  881 + ohci->name, ohci->fi, ohci->fi);
858 882 }
859 883  
860 884 ohci->fi = val;
... ... @@ -892,13 +916,13 @@ static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
892 916 break;
893 917 case OHCI_USB_SUSPEND:
894 918 ohci_bus_stop(ohci);
895   - dprintf("usb-ohci: %s: USB Suspended\n", ohci->pci_dev.name);
  919 + dprintf("usb-ohci: %s: USB Suspended\n", ohci->name);
896 920 break;
897 921 case OHCI_USB_RESUME:
898   - dprintf("usb-ohci: %s: USB Resume\n", ohci->pci_dev.name);
  922 + dprintf("usb-ohci: %s: USB Resume\n", ohci->name);
899 923 break;
900 924 case OHCI_USB_RESET:
901   - dprintf("usb-ohci: %s: USB Reset\n", ohci->pci_dev.name);
  925 + dprintf("usb-ohci: %s: USB Reset\n", ohci->name);
902 926 break;
903 927 }
904 928 }
... ... @@ -1086,6 +1110,19 @@ static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
1086 1110 case 20: /* HcRhStatus */
1087 1111 return ohci->rhstatus;
1088 1112  
  1113 + /* PXA27x specific registers */
  1114 + case 24: /* HcStatus */
  1115 + return ohci->hstatus & ohci->hmask;
  1116 +
  1117 + case 25: /* HcHReset */
  1118 + return ohci->hreset;
  1119 +
  1120 + case 26: /* HcHInterruptEnable */
  1121 + return ohci->hmask;
  1122 +
  1123 + case 27: /* HcHInterruptTest */
  1124 + return ohci->htest;
  1125 +
1089 1126 default:
1090 1127 fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr);
1091 1128 return 0xffffffff;
... ... @@ -1187,6 +1224,24 @@ static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
1187 1224 ohci_set_hub_status(ohci, val);
1188 1225 break;
1189 1226  
  1227 + /* PXA27x specific registers */
  1228 + case 24: /* HcStatus */
  1229 + ohci->hstatus &= ~(val & ohci->hmask);
  1230 +
  1231 + case 25: /* HcHReset */
  1232 + ohci->hreset = val & ~OHCI_HRESET_FSBIR;
  1233 + if (val & OHCI_HRESET_FSBIR)
  1234 + ohci_reset(ohci);
  1235 + break;
  1236 +
  1237 + case 26: /* HcHInterruptEnable */
  1238 + ohci->hmask = val;
  1239 + break;
  1240 +
  1241 + case 27: /* HcHInterruptTest */
  1242 + ohci->htest = val;
  1243 + break;
  1244 +
1190 1245 default:
1191 1246 fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr);
1192 1247 break;
... ... @@ -1207,22 +1262,11 @@ static CPUWriteMemoryFunc *ohci_writefn[3]={
1207 1262 ohci_mem_write
1208 1263 };
1209 1264  
1210   -static void ohci_mapfunc(PCIDevice *pci_dev, int i,
1211   - uint32_t addr, uint32_t size, int type)
1212   -{
1213   - OHCIState *ohci = (OHCIState *)pci_dev;
1214   - ohci->mem_base = addr;
1215   - cpu_register_physical_memory(addr, size, ohci->mem);
1216   -}
1217   -
1218   -void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn)
  1265 +static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
  1266 + void *pic, int irq, enum ohci_type type, const char *name)
1219 1267 {
1220   - OHCIState *ohci;
1221   - int vid = 0x106b;
1222   - int did = 0x003f;
1223 1268 int i;
1224 1269  
1225   -
1226 1270 if (usb_frame_time == 0) {
1227 1271 #if OHCI_TIME_WARP
1228 1272 usb_frame_time = ticks_per_sec;
... ... @@ -1239,8 +1283,43 @@ void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn)
1239 1283 usb_frame_time, usb_bit_time);
1240 1284 }
1241 1285  
1242   - ohci = (OHCIState *)pci_register_device(bus, "OHCI USB", sizeof(*ohci),
1243   - devfn, NULL, NULL);
  1286 + ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
  1287 + ohci->name = name;
  1288 +
  1289 + ohci->pic = pic;
  1290 + ohci->irq = irq;
  1291 + ohci->type = type;
  1292 +
  1293 + ohci->num_ports = num_ports;
  1294 + for (i = 0; i < num_ports; i++) {
  1295 + qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
  1296 + }
  1297 +
  1298 + ohci->async_td = 0;
  1299 + ohci_reset(ohci);
  1300 +}
  1301 +
  1302 +typedef struct {
  1303 + PCIDevice pci_dev;
  1304 + OHCIState state;
  1305 +} OHCIPCIState;
  1306 +
  1307 +static void ohci_mapfunc(PCIDevice *pci_dev, int i,
  1308 + uint32_t addr, uint32_t size, int type)
  1309 +{
  1310 + OHCIPCIState *ohci = (OHCIPCIState *)pci_dev;
  1311 + ohci->state.mem_base = addr;
  1312 + cpu_register_physical_memory(addr, size, ohci->state.mem);
  1313 +}
  1314 +
  1315 +void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn)
  1316 +{
  1317 + OHCIPCIState *ohci;
  1318 + int vid = 0x106b;
  1319 + int did = 0x003f;
  1320 +
  1321 + ohci = (OHCIPCIState *)pci_register_device(bus, "OHCI USB", sizeof(*ohci),
  1322 + devfn, NULL, NULL);
1244 1323 if (ohci == NULL) {
1245 1324 fprintf(stderr, "usb-ohci: Failed to register PCI device\n");
1246 1325 return;
... ... @@ -1255,16 +1334,21 @@ void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn)
1255 1334 ohci->pci_dev.config[0x0b] = 0xc;
1256 1335 ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
1257 1336  
1258   - ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
  1337 + usb_ohci_init(&ohci->state, num_ports, devfn, &ohci->pci_dev,
  1338 + 0, OHCI_TYPE_PCI, ohci->pci_dev.name);
1259 1339  
1260 1340 pci_register_io_region((struct PCIDevice *)ohci, 0, 256,
1261 1341 PCI_ADDRESS_SPACE_MEM, ohci_mapfunc);
  1342 +}
1262 1343  
1263   - ohci->num_ports = num_ports;
1264   - for (i = 0; i < num_ports; i++) {
1265   - qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
1266   - }
  1344 +void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
  1345 + void *pic, int irq)
  1346 +{
  1347 + OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
1267 1348  
1268   - ohci->async_td = 0;
1269   - ohci_reset(ohci);
  1349 + usb_ohci_init(ohci, num_ports, devfn, pic, irq,
  1350 + OHCI_TYPE_PXA, "OHCI USB");
  1351 + ohci->mem_base = base;
  1352 +
  1353 + cpu_register_physical_memory(ohci->mem_base, 0xfff, ohci->mem);
1270 1354 }
... ...
hw/usb.h
... ... @@ -206,7 +206,9 @@ USBDevice *usb_hub_init(int nb_ports);
206 206 void usb_uhci_init(PCIBus *bus, int devfn);
207 207  
208 208 /* usb-ohci.c */
209   -void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn);
  209 +void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn);
  210 +void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
  211 + void *pic, int irq);
210 212  
211 213 /* usb-linux.c */
212 214 USBDevice *usb_host_device_open(const char *devname);
... ...
hw/versatilepb.c
... ... @@ -195,7 +195,7 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
195 195 }
196 196 }
197 197 if (usb_enabled) {
198   - usb_ohci_init(pci_bus, 3, -1);
  198 + usb_ohci_init_pci(pci_bus, 3, -1);
199 199 }
200 200 scsi_hba = lsi_scsi_init(pci_bus, -1);
201 201 for (n = 0; n < MAX_DISKS; n++) {
... ...