revert between 56095 -> 55830 in arch
[AROS.git] / arch / ppc-chrp / efika / ohci / ohci_init.c
blob71e0df5988df495c02e0efc0981f3b1d4f2a145a
1 /*
2 Copyright (C) 2006 by Michal Schulz
3 $Id$
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <inttypes.h>
22 #include <aros/symbolsets.h>
24 #include <asm/io.h>
25 #include <asm/mpc5200b.h>
27 #include <hidd/hidd.h>
28 #include <hidd/pci.h>
30 #include <usb/usb.h>
32 #define DEBUG 1
34 #include <proto/exec.h>
35 #include <proto/oop.h>
36 #include <proto/openfirmware.h>
37 #include <proto/kernel.h>
38 #include <aros/debug.h>
40 #include "ohci.h"
41 #include "../pci/pci.h"
43 #undef SD
44 #define SD(x) (&LIBBASE->sd)
46 static void init_builtin_ohci(struct ohci_staticdata *sd)
48 void *OpenFirmwareBase = OpenResource("openfirmware.resource");
49 void *key;
50 ohci_registers_t *regs;
51 struct timerequest *tr = ohci_CreateTimer();
53 key = OF_OpenKey("/builtin/usb");
54 if (key)
56 void *prop = OF_FindProperty(key, "reg");
57 if (prop)
59 struct pcibase *pci_efika_base = OpenLibrary("pci-efika.hidd",0);
61 intptr_t *base = OF_GetPropValue(prop);
62 regs = (ohci_registers_t *)*base;
63 sd->ramBase[0] = *base;
64 sd->pciDevice[0] = NULL;
65 sd->irqNum[0] = MPC5200B_USB;
67 if (pci_efika_base)
68 sd->pciDriver[0] = OOP_NewObject(pci_efika_base->psd.driverClass, NULL, NULL);
69 else
70 sd->pciDriver[0] = NULL;
72 D(bug("[OHCI_MPC5200B] HC @ %08x\n", sd->ramBase[0]));
74 sd->numDevices = 1;
75 sd->numPorts[0] = HC_RHA_GET_NDP(AROS_OHCI2LONG(mmio(regs->HcRhDescriptorA)));
77 D(bug("[OHCI_MPC5200B] %d-port Device %d @ %08x with MMIO @ %08x\n", sd->numPorts[0], 1, sd->pciDriver[0], sd->ramBase[0]));
79 uint32_t ctrl = AROS_OHCI2LONG(mmio(regs->HcControl));
80 if (ctrl & HC_CTRL_IR)
82 D(bug("[OHCI_MPC5200B] Performing BIOS handoff\n"));
83 int delay = 500; /* 0.5 second */
84 mmio(regs->HcInterruptEnable) = AROS_LONG2OHCI(HC_INTR_OC);
85 mmio(regs->HcCommandStatus) = AROS_LONG2OHCI(HC_CS_OCR);
87 /* Loop */
88 while ((delay > 0) && AROS_OHCI2LONG(mmio(regs->HcControl) & HC_CTRL_IR))
90 delay -= 2;
91 ohci_Delay(tr, 2);
93 if (delay < 0)
94 D(bug("[OHCI_MPC5200B] BIOS handoff failed!\n"));
96 mmio(regs->HcControl) = AROS_LONG2OHCI(ctrl & HC_CTRL_RWC);
99 /* Disable all interrupts */
100 mmio(regs->HcInterruptDisable) = AROS_LONG2OHCI(0xffffffff);
101 mmio(regs->HcInterruptStatus) = AROS_LONG2OHCI(0xffffffff);
103 ohci_DeleteTimer(tr);
108 static
109 AROS_UFH3(void, Enumerator,
110 AROS_UFHA(struct Hook *, hook, A0),
111 AROS_UFHA(OOP_Object *, pciDevice, A2),
112 AROS_UFHA(APTR, message, A1))
114 AROS_USERFUNC_INIT
116 ohci_registers_t *regs;
117 static int counter;
118 struct timerequest *tr = ohci_CreateTimer();
120 if (counter == MAX_OHCI_DEVICES)
121 return;
123 LIBBASETYPE *LIBBASE = (LIBBASETYPE *)hook->h_Data;
125 struct TagItem attrs[] = {
126 { aHidd_PCIDevice_isMEM, TRUE },
127 { aHidd_PCIDevice_isMaster, TRUE },
128 { TAG_DONE, 0UL },
132 OOP_SetAttrs(pciDevice, (struct TagItem *)attrs);
133 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Base0, &LIBBASE->sd.ramBase[counter]);
134 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Driver, (void *)&LIBBASE->sd.pciDriver[counter]);
135 LIBBASE->sd.pciDevice[counter] = pciDevice;
137 regs = (ohci_registers_t *)LIBBASE->sd.ramBase[counter];
139 LIBBASE->sd.numPorts[counter] = HC_RHA_GET_NDP(AROS_OHCI2LONG(mmio(regs->HcRhDescriptorA)));
141 D(bug("[OHCI_MPC5200B] %d-port Device %d @ %08x with MMIO @ %08x\n", LIBBASE->sd.numPorts[counter], counter + 1, pciDevice, LIBBASE->sd.ramBase[counter]));
143 uint32_t ctrl = AROS_OHCI2LONG(mmio(regs->HcControl));
144 if (ctrl & HC_CTRL_IR)
146 D(bug("[OHCI_MPC5200B] Performing BIOS handoff\n"));
147 int delay = 500; /* 0.5 second */
148 mmio(regs->HcInterruptEnable) = AROS_LONG2OHCI(HC_INTR_OC);
149 mmio(regs->HcCommandStatus) = AROS_LONG2OHCI(HC_CS_OCR);
151 /* Loop */
152 while ((delay > 0) && AROS_OHCI2LONG(mmio(regs->HcControl) & HC_CTRL_IR))
154 delay -= 2;
155 ohci_Delay(tr, 2);
157 if (delay < 0)
158 D(bug("[OHCI_MPC5200B] BIOS handoff failed!\n"));
160 mmio(regs->HcControl) = AROS_LONG2OHCI(ctrl & HC_CTRL_RWC);
163 /* Disable all interrupts */
164 mmio(regs->HcInterruptDisable) = AROS_LONG2OHCI(0xffffffff);
165 mmio(regs->HcInterruptStatus) = AROS_LONG2OHCI(0xffffffff);
167 LIBBASE->sd.numDevices = ++counter;
169 ohci_DeleteTimer(tr);
171 AROS_USERFUNC_EXIT
175 static int OHCI_Init(LIBBASETYPEPTR LIBBASE)
177 struct OOP_ABDescr attrbases[] = {
178 { (STRPTR)IID_Hidd, &HiddAttrBase },
179 { (STRPTR)IID_Hidd_PCIDevice, &HiddPCIDeviceAttrBase },
180 { (STRPTR)IID_Hidd_USBDevice, &HiddUSBDeviceAttrBase },
181 { (STRPTR)IID_Hidd_USBHub, &HiddUSBHubAttrBase },
182 { (STRPTR)IID_Hidd_USBDrv, &HiddUSBDrvAttrBase },
183 { NULL, NULL }
186 D(bug("[OHCI_MPC5200B] OHCI_Init()\n"));
188 LIBBASE->sd.usb = OOP_NewObject(NULL, (STRPTR)CLID_Hidd_USB, NULL);
190 NEWLIST(&LIBBASE->sd.tdList);
191 InitSemaphore(&LIBBASE->sd.tdLock);
193 if (!LIBBASE->sd.usb)
195 bug("[OHCI_MPC5200B] Cannot create the instance of base USB class\n");
196 return FALSE;
199 OOP_ObtainAttrBases(attrbases);
201 init_builtin_ohci(&LIBBASE->sd);
203 D(bug("[OHCI_MPC5200B] Done. OHCI devices found: %d\n", LIBBASE->sd.numDevices));
205 if (LIBBASE->sd.numDevices > 0)
207 LIBBASE->sd.memPool = CreatePool(MEMF_CLEAR | MEMF_PUBLIC | MEMF_SEM_PROTECTED, 8192, 4096);
209 if (LIBBASE->sd.memPool)
210 return TRUE;
214 return FALSE;
217 static int OHCI_Expunge(LIBBASETYPEPTR LIBBASE)
219 struct OOP_ABDescr attrbases[] = {
220 { (STRPTR)IID_Hidd, &HiddAttrBase },
221 { (STRPTR)IID_Hidd_PCIDevice, &HiddPCIDeviceAttrBase },
222 { (STRPTR)IID_Hidd_USBDevice, &HiddUSBDeviceAttrBase },
223 { (STRPTR)IID_Hidd_USBHub, &HiddUSBHubAttrBase },
224 { (STRPTR)IID_Hidd_USBDrv, &HiddUSBDrvAttrBase },
225 { NULL, NULL }
228 OOP_ReleaseAttrBases(attrbases);
230 return TRUE;
233 ADD2INITLIB(OHCI_Init, 0)
234 ADD2EXPUNGELIB(OHCI_Expunge, 0)
235 ADD2LIBS((STRPTR)"usb.hidd", 0, static struct Library *, __usbbase)