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

Commit d6652a69 authored by Robert Sprowson's avatar Robert Sprowson Committed by ROOL

Make a substitute for MPHI

The MPHI is (ab)used by DWCDriver as a means to do a FIQ downgrade to IRQ, but Pi 4 has no MPHI, so instead we substitute the GIC. This is essentially a GIC based equivalent to the changes in https://github.com/raspberrypi/linux/commit/0a1cf0d.
Apply these diffs then, in dwc_otg_riscos.c:
* deduce use_swirq by noticing the MPHI base happens to have all 13 LSB clear whereas the GIC doesn't, in just as horrendously Pi specific manner as Linux looking at the size of the memory region to deduce same
* setup the pointers to swirq_set and swirq_clr at GICD_ISPENDRn GICD_ICPENDRn

Version 0.36. Tagged as 'DWCDriver-0_36'
parent ca22f1e5
/* (0.35)
/* (0.36)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.35
#define Module_MajorVersion_CMHG 0.36
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 02 Jun 2018
#define Module_Date_CMHG 29 Feb 2020
#define Module_MajorVersion "0.35"
#define Module_Version 35
#define Module_MajorVersion "0.36"
#define Module_Version 36
#define Module_MinorVersion ""
#define Module_Date "02 Jun 2018"
#define Module_Date "29 Feb 2020"
#define Module_ApplicationDate "02-Jun-18"
#define Module_ApplicationDate "29-Feb-20"
#define Module_ComponentName "DWCDriver"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver"
#define Module_FullVersion "0.35"
#define Module_HelpVersion "0.35 (02 Jun 2018)"
#define Module_LibraryVersionInfo "0:35"
#define Module_FullVersion "0.36"
#define Module_HelpVersion "0.36 (29 Feb 2020)"
#define Module_LibraryVersionInfo "0:36"
......@@ -68,10 +68,10 @@ static int instance = 0; /* Module instance no. */
static int* veneer_code = NULL; /* Pointer to USBDriver call veneer code */
static int hal_device = -1; /* Index of USB device in HAL */
static int usb_device_number; /* USB IRQ number */
static unsigned int usb_device_number; /* USB IRQ number */
static void *dwc_base=NULL; /* HW registers */
static void *mphi_base=NULL; /* MPHI registers */
static int mphi_device_number; /* MPHI IRQ number */
static unsigned int mphi_device_number; /* MPHI IRQ number */
int dma_offset; /* ARM phys addr -> DMA addr offset */
static dwc_softc_t dwc_soft; /* Bus device we register with USBDriver */
......
......@@ -642,28 +642,50 @@ _kernel_oserror *dwc_otg_riscos_init(const uint32_t *hw_base,const uint8_t *mphi
softc->port = dwc_otg_hcd_otg_port(softc->dwc_dev.hcd);
/* Set up variables needed by the FIQ code */
bool use_swirq = ((uintptr_t)mphi_base & 0x1000) != 0;
dprintf(("","Registers at %08x %08x\n",hw_base,mphi_base));
if (use_fiq_fix)
{
softc->dwc_dev.hcd->fiq_state->mphi_regs.base = (volatile void *) (mphi_base);
softc->dwc_dev.hcd->fiq_state->mphi_regs.ctrl = (volatile void *) (mphi_base + 0x4c);
softc->dwc_dev.hcd->fiq_state->mphi_regs.outdda = (volatile void *) (mphi_base + 0x28);
softc->dwc_dev.hcd->fiq_state->mphi_regs.outddb = (volatile void *) (mphi_base + 0x2c);
softc->dwc_dev.hcd->fiq_state->mphi_regs.intstat = (volatile void *) (mphi_base + 0x50);
softc->dwc_dev.hcd->fiq_state->dwc_regs_base = (uint8_t *) hw_base;
/* Enable MPHI peripheral */
DWC_WRITE_REG32(softc->dwc_dev.hcd->fiq_state->mphi_regs.ctrl,0x80000000);
if (use_swirq)
{
/* There's no MPHI peripheral, so use SWIRQ instead */
softc->dwc_dev.hcd->fiq_state->mphi_regs.swirq_set = (volatile void *) (mphi_base + 0x00);
softc->dwc_dev.hcd->fiq_state->mphi_regs.swirq_clr = (volatile void *) (mphi_base + 0x80);
}
else
{
softc->dwc_dev.hcd->fiq_state->mphi_regs.swirq_set =
softc->dwc_dev.hcd->fiq_state->mphi_regs.swirq_clr = NULL;
softc->dwc_dev.hcd->fiq_state->mphi_regs.base = (volatile void *) (mphi_base);
softc->dwc_dev.hcd->fiq_state->mphi_regs.ctrl = (volatile void *) (mphi_base + 0x4c);
softc->dwc_dev.hcd->fiq_state->mphi_regs.outdda = (volatile void *) (mphi_base + 0x28);
softc->dwc_dev.hcd->fiq_state->mphi_regs.outddb = (volatile void *) (mphi_base + 0x2c);
softc->dwc_dev.hcd->fiq_state->mphi_regs.intstat = (volatile void *) (mphi_base + 0x50);
/* Enable MPHI peripheral */
DWC_WRITE_REG32(softc->dwc_dev.hcd->fiq_state->mphi_regs.ctrl,0x80000000);
}
#ifdef RISCOS_FIQ_DOWNGRADE
fiq_downgrade.fiq_downgrade_device = mphi_device_number;
/* Get the MPHI generating an interrupt now */
FIQ_WRITE( softc->dwc_dev.hcd->fiq_state->mphi_regs.outdda, (int) softc->dwc_dev.hcd->fiq_state->dummy_send);
FIQ_WRITE( softc->dwc_dev.hcd->fiq_state->mphi_regs.outddb, (1 << 29));
if (use_swirq)
{
/* Get the SWIRQ generating an interrupt now */
FIQ_WRITE(softc->dwc_dev.hcd->fiq_state->mphi_regs.swirq_set, 1 << (fiq_downgrade.fiq_downgrade_device % 32));
}
else
{
/* Get the MPHI generating an interrupt now */
FIQ_WRITE(softc->dwc_dev.hcd->fiq_state->mphi_regs.outdda, (int) softc->dwc_dev.hcd->fiq_state->dummy_send);
FIQ_WRITE(softc->dwc_dev.hcd->fiq_state->mphi_regs.outddb, (1 << 29));
}
_swix(OS_Hardware,_INR(8,9)|_OUTR(0,1),1,EntryNo_HAL_IRQEnable,&fiq_downgrade.hal_irqenable,&fiq_downgrade.hal_sb);
_swix(OS_Hardware,_INR(8,9)|_OUT(0),1,EntryNo_HAL_IRQDisable,&fiq_downgrade.hal_irqdisable);
_swix(OS_Hardware, _INR(8,9)|_OUTR(0,1), OSHW_LookupRoutine, EntryNo_HAL_IRQEnable,
&fiq_downgrade.hal_irqenable, &fiq_downgrade.hal_sb);
_swix(OS_Hardware, _INR(8,9)|_OUT(0), OSHW_LookupRoutine, EntryNo_HAL_IRQDisable,
&fiq_downgrade.hal_irqdisable);
#endif
}
......
......@@ -807,14 +807,15 @@ static int dwc_otg_driver_probe(
if (!request_mem_region(_dev->resource[1].start,
_dev->resource[1].end - _dev->resource[1].start + 1,
"dwc_otg")) {
dev_dbg(&_dev->dev, "error reserving mapped memory\n");
retval = -EFAULT;
goto fail;
}
dev_dbg(&_dev->dev, "error reserving mapped memory\n");
retval = -EFAULT;
goto fail;
}
dwc_otg_device->os_dep.mphi_base = ioremap_nocache(_dev->resource[1].start,
_dev->resource[1].end -
_dev->resource[1].start + 1);
dwc_otg_device->os_dep.use_swirq = (_dev->resource[1].end - _dev->resource[1].start) == 0x200;
}
#else
......
......@@ -1292,11 +1292,18 @@ void notrace dwc_otg_fiq_fsm(struct fiq_state *state, int num_channels)
/* Flag that we're downgrading an FIQ */
fiq_downgrade.fiq_trigger = true;
/* Enable the IRQ now if the IRQ routine says it's safe to do so */
if(!fiq_downgrade.irq_masked)
if (!fiq_downgrade.irq_masked) {
if (state->mphi_regs.swirq_set)
FIQ_WRITE(state->mphi_regs.swirq_set, 1 << (fiq_downgrade.fiq_downgrade_device % 32));
halcall(fiq_downgrade.fiq_downgrade_device,fiq_downgrade.hal_irqenable,fiq_downgrade.hal_sb);
}
#else
FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send);
FIQ_WRITE(state->mphi_regs.outddb, (1<<29));
if (state->mphi_regs.swirq_set) {
FIQ_WRITE(state->mphi_regs.swirq_set, 1);
} else {
FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma);
FIQ_WRITE(state->mphi_regs.outddb, (1<<29));
}
#endif
}
......@@ -1359,15 +1366,21 @@ void notrace dwc_otg_fiq_nop(struct fiq_state *state)
/* Flag that we're downgrading an FIQ */
fiq_downgrade.fiq_trigger = true;
/* Enable the IRQ now if the IRQ routine says it's safe to do so */
if(!fiq_downgrade.irq_masked)
if (!fiq_downgrade.irq_masked) {
if (state->mphi_regs.swirq_set)
FIQ_WRITE(state->mphi_regs.swirq_set, 1 << (fiq_downgrade.fiq_downgrade_device % 32));
halcall(fiq_downgrade.fiq_downgrade_device,fiq_downgrade.hal_irqenable,fiq_downgrade.hal_sb);
}
#else
/* Force a clear before another dummy send */
FIQ_WRITE(state->mphi_regs.intstat, (1<<29));
FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send);
FIQ_WRITE(state->mphi_regs.outddb, (1<<29));
if (state->mphi_regs.swirq_set) {
FIQ_WRITE(state->mphi_regs.swirq_set, 1);
} else {
/* Force a clear before another dummy send */
FIQ_WRITE(state->mphi_regs.intstat, (1<<29));
FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma);
FIQ_WRITE(state->mphi_regs.outddb, (1<<29));
}
#endif
}
state->fiq_done++;
mb();
......
......@@ -224,20 +224,25 @@ exit_handler_routine:
/* The FIQ could have sneaked another interrupt in. If so, don't clear MPHI */
if ((gintmsk_new.d32 == ~0) && (haintmsk_new.d32 == 0x0000FFFF)) {
#ifndef RISCOS_FIQ_DOWNGRADE
if (dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr) {
DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr, 1);
} else {
DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.intstat, (1<<16));
if (dwc_otg_hcd->fiq_state->mphi_int_count >= 50) {
fiq_print(FIQDBG_INT, dwc_otg_hcd->fiq_state, "MPHI CLR");
}
if (dwc_otg_hcd->fiq_state->mphi_int_count >= 50) {
fiq_print(FIQDBG_INT, dwc_otg_hcd->fiq_state, "MPHI CLR");
DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl, ((1<<31) + (1<<16)));
while (!(DWC_READ_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & (1 << 17)))
;
DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl, (1<<31));
dwc_otg_hcd->fiq_state->mphi_int_count = 0;
}
}
#else
/* No more interrupts left to process, clear the downgrade flag so that we will leave the IRQ disabled on exit from the IRQ handler */
fiq_downgrade.fiq_trigger = false;
/* No more interrupts left to process, clear the downgrade flag so that we will leave
* the IRQ disabled on exit from the IRQ handler */
fiq_downgrade.fiq_trigger = false;
#endif
int_done++;
int_done++;
}
haintmsk.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
/* Re-enable interrupts that the FIQ masked (first time round) */
......
......@@ -132,6 +132,8 @@ typedef struct {
volatile void* outdda;
volatile void* outddb;
volatile void* intstat;
volatile void* swirq_set;
volatile void* swirq_clr;
} mphi_regs_t;
enum fiq_debug_level {
......@@ -173,7 +175,7 @@ typedef struct {
void *hal_sb;
void *hal_irqenable;
void *hal_irqdisable;
int fiq_downgrade_device;
unsigned int fiq_downgrade_device;
volatile bool irq_masked;
volatile bool fiq_trigger;
} fiq_downgrade_t;
......
......@@ -112,6 +112,9 @@ typedef struct os_dependent {
/** Base address for MPHI peripheral */
void *mphi_base;
/** mphi_base actually points to the SWIRQ block */
bool use_swirq;
#ifdef LM_INTERFACE
struct lm_device *lmdev;
#elif defined(PCI_INTERFACE)
......
......@@ -57,9 +57,9 @@ struct dwc_softc_pipe {
typedef struct dwc_softc {
struct usbd_bus sc_bus; /* Base USBDriver struct */
int device_number; /* Current IRQ device number (USB or MPHI) */
int usb_device_number;
int mphi_device_number;
unsigned int device_number; /* Current IRQ device number (USB or MPHI) */
unsigned int usb_device_number;
unsigned int mphi_device_number;
/* USBDriver bits */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment