GitLab has been upgraded to 13.3.6. If you encounter any issues mail code@riscosopen.org

Commit d854b974 authored by Jeffrey Lee's avatar Jeffrey Lee

Update to version 3.00 of DWC_otg

Detail:
  This big batch of changes brings us in line with rev 70428950df of the Raspberry Pi Linux github.
  Briefly:
  * Deleted HTML docs as they're a waste of space
  * Dropped the SOF fix (which we never used anyway)
  * Dropped our implementation of the microframe scheduling patch, in favour of their implementation
  * Updated to version 3.00 of the DWC sources. Hard to tell what useful changes this brings, due to API tweaks resulting in pretty much every file being littered with changes.
Admin:
  Tested on Raspberry Pi with high processor vectors
  This new version seems like it might be a bit more sensitive to insufficient power supplies. Beware!


Version 0.09. Tagged as 'DWCDriver-0_09'
parent 75f42235
......@@ -47,18 +47,12 @@ VPATH = ^.^.build ^.^.dev.usb dwc.driver dwc.dwc_common_port
# DWC bits
CFLAGS += -DDWC_EN_ISOC -Idwc.dwc_common_port -DDWC_HOST_ONLY
OBJS += dwc_otg_cil dwc_otg_cil_intr dwc_otg_hcd dwc_otg_hcd_intr dwc_otg_hcd_queue dwc_otg_hcd_ddma
OBJS += dwc_cc dwc_modpow dwc_notifier dwc_mem
OBJS += dwc_otg_cil dwc_otg_cil_intr dwc_otg_hcd dwc_otg_hcd_intr dwc_otg_hcd_queue dwc_otg_hcd_ddma dwc_otg_adp
# OBJS += dwc_cc dwc_modpow dwc_notifier dwc_mem
# Use this flag to enable Broadcom SoC/BCM2835-specific changes
CFLAGS += -DBCM2835
# Use this flag to reduce SOF interrupt service overhead
#CFLAGS += -DSOF_FIX
# Use this flag to enable the microframe scheduling patch. Note - will break controllers that use descriptor DMA
CFLAGS += -DSCHEDULE_PATCH
include CModule
${DIRS}::
......
/* (0.08)
/* (0.09)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.08
#define Module_MajorVersion_CMHG 0.09
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 04 Aug 2012
#define Module_Date_CMHG 17 Sep 2012
#define Module_MajorVersion "0.08"
#define Module_Version 8
#define Module_MajorVersion "0.09"
#define Module_Version 9
#define Module_MinorVersion ""
#define Module_Date "04 Aug 2012"
#define Module_Date "17 Sep 2012"
#define Module_ApplicationDate "04-Aug-12"
#define Module_ApplicationDate "17-Sep-12"
#define Module_ComponentName "DWCDriver"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver"
#define Module_FullVersion "0.08"
#define Module_HelpVersion "0.08 (04 Aug 2012)"
#define Module_LibraryVersionInfo "0:8"
#define Module_FullVersion "0.09"
#define Module_HelpVersion "0.09 (17 Sep 2012)"
#define Module_LibraryVersionInfo "0:9"
......@@ -79,6 +79,8 @@ static bool driver_init=false; /* True/false for whether DWC layer is initialise
int dwcdebug; /* Debug level */
#endif
bool microframe_schedule = true;
extern int * init_veneer (void);
static _kernel_oserror* register_bus(void *in,struct device **out)
......@@ -460,8 +462,8 @@ riscos_cancel_abort_pipe (void* v)
_kernel_oserror *endpoint_disable_cb(_kernel_swi_regs *r,void *pw,void *handle)
{
dprintf(("","endpoint_disable_cb: %08x\n",handle));
dwc_otg_hcd_endpoint_disable(dwc_soft.hcd,handle,250);
DPRINTFN(15,("endpoint_disable_cb: %08x\n",handle));
dwc_otg_hcd_endpoint_disable(dwc_soft.dwc_dev.hcd,handle,250);
return NULL;
}
......@@ -475,10 +477,3 @@ int address_valid(void *addr,int align)
return 1;
}
#endif
#ifdef SOF_FIX
int sof_setting(void)
{
return 1;
}
#endif
......@@ -34,11 +34,18 @@
#include "Interface/RTSupport.h"
#include "callx/callx.h"
#include "sys/queue.h"
#include <sys/callout.h>
#include <sys/queue.h>
#include <machine/bus.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include "cmodule.h"
#include "dwc_os.h"
#include "dwc_common_riscos.h"
#include "dwc_otg_riscos.h"
extern uint32_t g_dbg_lvl;
uint32_t g_dbg_lvl = 0;
......@@ -57,6 +64,11 @@ dwc_bool_t DWC_IN_IRQ(void)
return ((_swi(RT_ReadInfo,_IN(0)|_RETURN(0),RTReadInfo_Handle) == -1)?YES:NO);
}
dwc_bool_t DWC_IN_BH(void)
{
return NO;
}
/* Diagnostic messages */
void __DWC_WARN(char *format,...)
......@@ -95,8 +107,9 @@ void __DWC_DEBUG(char *format,...)
/* Memory management */
void *__DWC_DMA_ALLOC(uint32_t size, dwc_dma_t *dma_addr)
void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
{
(void) dma_ctx;
void *mem;
_kernel_oserror *e = _swix(PCI_RAMAlloc,_INR(0,2)|_OUTR(0,1),size,0,0,&mem,dma_addr);
if(e)
......@@ -110,14 +123,15 @@ void *__DWC_DMA_ALLOC(uint32_t size, dwc_dma_t *dma_addr)
return mem;
}
void *__DWC_DMA_ALLOC_ATOMIC(uint32_t size, dwc_dma_t *dma_addr)
void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
{
/* TODO - probably want to be clever about this */
return __DWC_DMA_ALLOC(size,dma_addr);
return __DWC_DMA_ALLOC(dma_ctx,size,dma_addr);
}
void __DWC_DMA_FREE(uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
{
(void) dma_ctx;
(void) size;
(void) dma_addr;
_swix(PCI_RAMFree,_IN(0),virt_addr);
......@@ -144,8 +158,9 @@ struct mem_chain {
static struct mem_chain *mem_buckets[MAX_BUCKET_SIZE/BUCKET_GRANULARITY];
void *__DWC_ALLOC(uint32_t size)
void *__DWC_ALLOC(void *mem_ctx, uint32_t size)
{
(void) mem_ctx;
/* Round allocation size to bucket size
We need 8 bytes of overhead: 4 for the 'bucket' ptr in allocated blocks, and 4 bytes for the size field the heap manager's size field
If we were feeling naughty we could peek at the heap manager's size field to work out which bucket an allocated block belongs in, but for now let's do it by the book */
......@@ -177,27 +192,28 @@ void *__DWC_ALLOC(uint32_t size)
}
block->u.bucket = bucket;
memset(block+1,0,size-8); /* Subtract 8 bytes for heap block header and our header */
dprintf(("","dwc_alloc -> %08x\n",block+1));
DPRINTFN(20,("dwc_alloc -> %08x\n",block+1));
return block+1;
}
void *__DWC_ALLOC_ATOMIC(uint32_t size)
void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size)
{
/* Heap manager is atomic */
return __DWC_ALLOC(size);
return __DWC_ALLOC(mem_ctx,size);
}
void __DWC_FREE(void *addr)
void __DWC_FREE(void *mem_ctx, void *addr)
{
(void) mem_ctx;
if(!addr)
return;
dprintf(("","dwc_free -> %08x\n",addr));
DPRINTFN(20,("dwc_free -> %08x\n",addr));
struct mem_chain *block = ((struct mem_chain *) addr)-1;
uint32_t flags = block->u.flags & 0x3;
block->u.flags &= ~flags;
if(flags & BUCKET_FLAG_PENDING_CB)
{
dprintf(("","cancelling endpoint_disable_cb\n"));
DPRINTFN(15,("cancelling endpoint_disable_cb\n"));
callx_remove_callback(endpoint_disable_cb,addr);
}
struct mem_chain **bucket = block->u.bucket;
......@@ -226,7 +242,7 @@ void register_endpoint_disable_cb(void *addr)
if(!addr)
return;
struct mem_chain *block = ((struct mem_chain *) addr)-1;
dprintf(("","register_endpoint_disable_cb: %08x %d\n",addr,block->u.flags & BUCKET_FLAG_PENDING_CB));
DPRINTFN(15,("register_endpoint_disable_cb: %08x %d\n",addr,block->u.flags & BUCKET_FLAG_PENDING_CB));
if(block->u.flags & BUCKET_FLAG_PENDING_CB)
return;
block->u.flags |= BUCKET_FLAG_PENDING_CB;
......@@ -432,24 +448,9 @@ int DWC_THREAD_STOP(dwc_thread_t *thread)
return ret;
}
dwc_bool_t DWC_THREAD_SHOULD_STOP(void)
dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread)
{
uint32_t rt_handle;
_swix(RT_ReadInfo,_IN(0)|_OUT(0),RTReadInfo_Handle,&rt_handle);
/* Icky linear search */
dwc_thread_t *t;
int irq = ensure_irqs_off();
LIST_FOREACH(t,&thread_list,list)
{
if(t->rt_handle == rt_handle)
{
restore_irqs(irq);
return t->stop;
}
}
restore_irqs(irq);
dwc_assert(0,"Thread not found");
return YES;
return thread->stop;
}
/* Work queues */
......@@ -675,8 +676,9 @@ static __value_in_regs RT_routine_result_t tasklet_wrapper(struct tasklet_state
return (RT_routine_result_t) { 0, 0, 0 };
}
dwc_tasklet_t *DWC_TASK_ALLOC(dwc_tasklet_callback_t cb, void *data)
dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data)
{
(void) name;
dwc_tasklet_t *t = DWC_ALLOC(sizeof(dwc_tasklet_t));
if(!t)
return NULL;
......@@ -775,26 +777,41 @@ void DWC_TIMER_CANCEL(dwc_timer_t *timer)
/* Spinlocks */
struct dwc_spinlock
{
int irq;
};
dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void)
{
return (dwc_spinlock_t *) 1;
return (dwc_spinlock_t *) DWC_ALLOC(sizeof(struct dwc_spinlock));
}
void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock)
{
(void) lock;
DWC_FREE(lock);
}
void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, uint64_t *flags)
void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags)
{
(void) lock;
*((int *) flags) = ensure_irqs_off();
*flags = ensure_irqs_off();
}
void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, uint64_t flags)
void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags)
{
(void) lock;
restore_irqs((int) flags);
restore_irqs((int)flags);
}
void DWC_SPINLOCK(dwc_spinlock_t *lock)
{
((struct dwc_spinlock *) lock)->irq = ensure_irqs_off();
}
void DWC_SPINUNLOCK(dwc_spinlock_t *lock)
{
restore_irqs(((struct dwc_spinlock *) lock)->irq);
}
/* non-IRQSAVE/IRQRESTORE versions aren't used */
......
......@@ -105,7 +105,7 @@ static _kernel_oserror *softc_root_intr_ticker(_kernel_swi_regs *r,void *pw,void
usbd_xfer_handle xfer = sc->sc_intrxfer;
if(!xfer || !xfer->length)
return NULL;
if(dwc_otg_hcd_is_status_changed(sc->hcd,sc->port) <= 0)
if(dwc_otg_hcd_is_status_changed(sc->dwc_dev.hcd,sc->port) <= 0)
return NULL;
u_char *p = KERNADDR(&xfer->dmabuf, 0);
memset(p,0,xfer->length);
......@@ -245,17 +245,17 @@ usbd_status softc_open(usbd_pipe_handle pipe)
epipe->pipe.methods = &softc_device_methods;
/* Allocate URB */
epipe->urb = dwc_otg_hcd_urb_alloc(sc->hcd,0,0); /* DWCTODO - ISOC */
epipe->urb = dwc_otg_hcd_urb_alloc(sc->dwc_dev.hcd,0,0); /* DWCTODO - ISOC */
if(!epipe->urb)
return USBD_NOMEM;
if(xfertype == UE_CONTROL)
{
/* Allocate DMA buffer for request packet */
epipe->request = dwc_dma_alloc(sizeof(usb_device_request_t),&epipe->dma_req);
epipe->request = dwc_dma_alloc(NULL,sizeof(usb_device_request_t),&epipe->dma_req);
if(!epipe->request)
{
dwc_free(epipe->urb);
dwc_free(NULL,epipe->urb);
return USBD_NOMEM;
}
}
......@@ -485,7 +485,7 @@ _kernel_oserror *dwc_otg_riscos_init(const uint32_t *hw_base,int device_number,d
/* Initialise the common interface layer */
dprintf(("","dwc_otg_cil_init\n"));
softc->core_if = dwc_otg_cil_init(hw_base);
softc->dwc_dev.core_if = dwc_otg_cil_init(hw_base);
/* DWCTODO - params should come from HAL */
struct dwc_otg_driver_module_params s_params;
......@@ -500,7 +500,7 @@ _kernel_oserror *dwc_otg_riscos_init(const uint32_t *hw_base,int device_number,d
dprintf(("","Setting device parameters\n"));
#define SETPARAM(X) \
if(params->X != -1) \
ret += dwc_otg_set_param_ ## X(softc->core_if,params->X);
ret += dwc_otg_set_param_ ## X(softc->dwc_dev.core_if,params->X);
SETPARAM(otg_cap)
SETPARAM(dma_enable)
SETPARAM(dma_desc_enable)
......@@ -531,9 +531,9 @@ _kernel_oserror *dwc_otg_riscos_init(const uint32_t *hw_base,int device_number,d
for(int i=0;i<15;i++)
{
if(params->dev_perio_tx_fifo_size[i] != -1)
ret += dwc_otg_set_param_dev_perio_tx_fifo_size(softc->core_if,params->dev_perio_tx_fifo_size[i],i);
ret += dwc_otg_set_param_dev_perio_tx_fifo_size(softc->dwc_dev.core_if,params->dev_perio_tx_fifo_size[i],i);
if(params->dev_tx_fifo_size[i] != -1)
ret += dwc_otg_set_param_dev_tx_fifo_size(softc->core_if,params->dev_tx_fifo_size[i],i);
ret += dwc_otg_set_param_dev_tx_fifo_size(softc->dwc_dev.core_if,params->dev_tx_fifo_size[i],i);
}
SETPARAM(thr_ctl)
SETPARAM(mpi_enable)
......@@ -546,13 +546,13 @@ _kernel_oserror *dwc_otg_riscos_init(const uint32_t *hw_base,int device_number,d
if(ret)
{
dwc_otg_cil_remove(softc->core_if);
dwc_otg_cil_remove(softc->dwc_dev.core_if);
return (_kernel_oserror *) "\0\0\0\0Incorrect device parameters";
}
/* Disable global interrupts */
dprintf(("","Setting up IRQs\n"));
dwc_otg_disable_global_interrupts(softc->core_if);
dwc_otg_disable_global_interrupts(softc->dwc_dev.core_if);
/* Claim IRQ */
_swix (OS_ClaimDeviceVector, _INR(0,4), softc->device_number, usb_irq_entry, private_word, 0, 0);
......@@ -560,19 +560,15 @@ _kernel_oserror *dwc_otg_riscos_init(const uint32_t *hw_base,int device_number,d
/* Initialise CIL */
dprintf(("","dwc_otg_core_init\n"));
dwc_otg_core_init(softc->core_if);
/* Enable IRQs */
dprintf(("","dwc_otg_enable_global_interrupts\n"));
dwc_otg_enable_global_interrupts(softc->core_if);
dwc_otg_core_init(softc->dwc_dev.core_if);
/* Create HCD instance */
dprintf(("","dwc_otg_hcd_alloc_hcd\n"));
softc->hcd = dwc_otg_hcd_alloc_hcd();
softc->dwc_dev.hcd = dwc_otg_hcd_alloc_hcd();
/* Initialise */
dprintf(("","dwc_otg_hcd_init\n"));
ret = dwc_otg_hcd_init(softc->hcd, softc->core_if);
ret = dwc_otg_hcd_init(softc->dwc_dev.hcd, softc->dwc_dev.core_if);
if(ret)
{
/* DWCTODO - Tidy up properly */
......@@ -580,12 +576,16 @@ _kernel_oserror *dwc_otg_riscos_init(const uint32_t *hw_base,int device_number,d
}
/* Get port number */
softc->port = dwc_otg_hcd_otg_port(softc->hcd);
softc->port = dwc_otg_hcd_otg_port(softc->dwc_dev.hcd);
/* Enable IRQs */
dprintf(("","dwc_otg_enable_global_interrupts\n"));
dwc_otg_enable_global_interrupts(softc->dwc_dev.core_if);
/* Start HCD */
dprintf(("","dwc_otg_hcd_start\n"));
softc->hcd_on = true;
ret = dwc_otg_hcd_start(softc->hcd, &hcd_ops);
ret = dwc_otg_hcd_start(softc->dwc_dev.hcd, &hcd_ops);
if(ret)
{
/* DWCTODO - Tidy up properly */
......@@ -606,20 +606,20 @@ void dwc_otg_riscos_shutdown(dwc_softc_t *softc)
{
callx_remove_callevery(softc_root_intr_ticker,softc);
dwc_otg_hcd_stop(softc->hcd);
dwc_otg_hcd_stop(softc->dwc_dev.hcd);
softc->hcd_on = false;
}
if(softc->hcd)
if(softc->dwc_dev.hcd)
{
dwc_otg_hcd_remove(softc->hcd);
softc->hcd = NULL;
dwc_otg_hcd_remove(softc->dwc_dev.hcd);
softc->dwc_dev.hcd = NULL;
}
if(softc->core_if)
if(softc->dwc_dev.core_if)
{
dwc_otg_cil_remove(softc->core_if);
softc->core_if = NULL;
dwc_otg_cil_remove(softc->dwc_dev.core_if);
softc->dwc_dev.core_if = NULL;
}
/* Relase IRQ */
......@@ -642,13 +642,13 @@ int dwc_otg_riscos_irq(dwc_softc_t *softc)
if(softc->hcd_on)
{
/* Check HCD interrupt first, likely to be more common */
ret = dwc_otg_hcd_handle_intr(softc->hcd);
ret = dwc_otg_hcd_handle_intr(softc->dwc_dev.hcd);
if(ret)
return 0;
}
/* Check CIL */
ret = dwc_otg_handle_common_intr(softc->core_if);
ret = dwc_otg_handle_common_intr(&softc->dwc_dev);
if(ret)
return 0;
......
......@@ -137,7 +137,7 @@ usbd_status softc_device_start(usbd_xfer_handle xfer)
callout_reset(&(ex->xfer.timeout_handle), (MS_TO_TICKS(ex->xfer.timeout)), (softc_device_timeout), (ex));
}
int ret = dwc_otg_hcd_urb_enqueue(sc->hcd,epipe->urb,&epipe->dwc_priv);
int ret = dwc_otg_hcd_urb_enqueue(sc->dwc_dev.hcd,epipe->urb,&epipe->dwc_priv,0);
if(ret)
{
......@@ -183,14 +183,14 @@ void softc_device_close(usbd_pipe_handle pipe)
dwc_assert(!epipe->xfer,"Pipe should be idle here");
/* Free endpoint */
dwc_otg_hcd_endpoint_disable(sc->hcd,epipe->dwc_priv,250);
dwc_otg_hcd_endpoint_disable(sc->dwc_dev.hcd,epipe->dwc_priv,250);
/* Free urb */
dwc_free(epipe->urb);
dwc_free(NULL,epipe->urb);
/* Free request buffer */
if(epipe->request)
dwc_dma_free(sizeof(usb_device_request_t),epipe->request,epipe->dma_req);
dwc_dma_free(NULL,sizeof(usb_device_request_t),epipe->request,epipe->dma_req);
}
void softc_device_clear_toggle(usbd_pipe_handle pipe)
......@@ -224,7 +224,7 @@ void softc_abort_xfer(usbd_xfer_handle xfer,usbd_status status)
{
DPRINTFN(10,("dequeing urb\n"));
/* Cancel the urb */
dwc_otg_hcd_urb_dequeue(sc->hcd,epipe->urb);
dwc_otg_hcd_urb_dequeue(sc->dwc_dev.hcd,epipe->urb);
/* Mark pipe as idle */
epipe->xfer = NULL;
......
......@@ -330,7 +330,7 @@ usbd_status softc_root_ctrl_start(usbd_xfer_handle xfer)
break;
default:
/* All other requests (e.g. hub requests) get sent to DWC layer */
s = dwc_otg_hcd_hub_control(sc->hcd,C(req->bRequest, req->bmRequestType),value,index,buf,len);
s = dwc_otg_hcd_hub_control(sc->dwc_dev.hcd,C(req->bRequest, req->bmRequestType),value,index,buf,len);
if(s != 0)
{
</