mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
dwc_otg: FIQ support on SMP. Set up FIQ stack and handler on Core 0 only.
This commit is contained in:
@@ -397,7 +397,55 @@ static struct fiq_handler fh = {
|
|||||||
.name = "usb_fiq",
|
.name = "usb_fiq",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void hcd_init_fiq(void *cookie)
|
||||||
|
{
|
||||||
|
dwc_otg_device_t *otg_dev = cookie;
|
||||||
|
dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
|
||||||
|
struct pt_regs regs;
|
||||||
|
|
||||||
|
if (claim_fiq(&fh)) {
|
||||||
|
DWC_ERROR("Can't claim FIQ");
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
|
||||||
|
DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
|
||||||
|
set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
|
||||||
|
regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
|
||||||
|
if (fiq_fsm_enable) {
|
||||||
|
regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
|
||||||
|
//regs.ARM_r10 = dwc_otg_hcd->dma;
|
||||||
|
regs.ARM_fp = (long) dwc_otg_fiq_fsm;
|
||||||
|
} else {
|
||||||
|
regs.ARM_fp = (long) dwc_otg_fiq_nop;
|
||||||
|
}
|
||||||
|
|
||||||
|
regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
|
||||||
|
|
||||||
|
// __show_regs(®s);
|
||||||
|
set_fiq_regs(®s);
|
||||||
|
|
||||||
|
//Set the mphi periph to the required registers
|
||||||
|
dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
|
||||||
|
dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
|
||||||
|
dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
|
||||||
|
dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
|
||||||
|
dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
|
||||||
|
dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
|
||||||
|
DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
|
||||||
|
//Enable mphi peripheral
|
||||||
|
writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
|
||||||
|
DWC_WARN("MPHI periph has been enabled");
|
||||||
|
else
|
||||||
|
DWC_WARN("MPHI periph has NOT been enabled");
|
||||||
|
#endif
|
||||||
|
// Enable FIQ interrupt from USB peripheral
|
||||||
|
enable_fiq(INTERRUPT_VC_USB);
|
||||||
|
local_fiq_enable();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the HCD. This function allocates memory for and initializes the
|
* Initializes the HCD. This function allocates memory for and initializes the
|
||||||
@@ -412,7 +460,6 @@ int hcd_init(dwc_bus_dev_t *_dev)
|
|||||||
dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
|
dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
u64 dmamask;
|
u64 dmamask;
|
||||||
struct pt_regs regs;
|
|
||||||
|
|
||||||
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
|
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
|
||||||
|
|
||||||
@@ -464,52 +511,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fiq_enable)
|
if (fiq_enable)
|
||||||
{
|
smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
|
||||||
if (claim_fiq(&fh)) {
|
|
||||||
DWC_ERROR("Can't claim FIQ");
|
|
||||||
goto error2;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
|
|
||||||
DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
|
|
||||||
|
|
||||||
set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
|
|
||||||
memset(®s,0,sizeof(regs));
|
|
||||||
|
|
||||||
regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
|
|
||||||
if (fiq_fsm_enable) {
|
|
||||||
regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
|
|
||||||
//regs.ARM_r10 = dwc_otg_hcd->dma;
|
|
||||||
regs.ARM_fp = (long) dwc_otg_fiq_fsm;
|
|
||||||
} else {
|
|
||||||
regs.ARM_fp = (long) dwc_otg_fiq_nop;
|
|
||||||
}
|
|
||||||
|
|
||||||
regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
|
|
||||||
|
|
||||||
// __show_regs(®s);
|
|
||||||
set_fiq_regs(®s);
|
|
||||||
|
|
||||||
//Set the mphi periph to the required registers
|
|
||||||
dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
|
|
||||||
dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
|
|
||||||
dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
|
|
||||||
dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
|
|
||||||
dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
|
|
||||||
dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
|
|
||||||
DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
|
|
||||||
//Enable mphi peripheral
|
|
||||||
writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
|
|
||||||
DWC_WARN("MPHI periph has been enabled");
|
|
||||||
else
|
|
||||||
DWC_WARN("MPHI periph has NOT been enabled");
|
|
||||||
#endif
|
|
||||||
// Enable FIQ interrupt from USB peripheral
|
|
||||||
enable_fiq(INTERRUPT_VC_USB);
|
|
||||||
local_fiq_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
otg_dev->hcd->otg_dev = otg_dev;
|
otg_dev->hcd->otg_dev = otg_dev;
|
||||||
|
|||||||
Reference in New Issue
Block a user