genode/repos/dde_linux/src/lib/usb/arm/platform_rpi/platform.cc

244 lines
5.6 KiB
C++

/*
* \brief USB initialization for Raspberry Pi
* \author Norman Feske
* \date 2013-09-11
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <io_mem_session/connection.h>
#include <irq_session/connection.h>
#include <util/mmio.h>
#include <platform_session/connection.h>
/* emulation */
#include <platform/platform.h>
#include <platform.h>
#include <extern_c_begin.h>
#include <lx_emul.h>
#include <extern_c_end.h>
/* dwc-otg */
#define new new_
#include <dwc_otg_dbg.h>
#undef new
using namespace Genode;
/************************************************
** Resource info passed to the dwc_otg driver **
************************************************/
enum {
DWC_BASE = 0x20980000,
DWC_SIZE = 0x20000,
DWC_IRQ = 17,
};
static resource _dwc_otg_resource[] =
{
{ DWC_BASE, DWC_BASE + DWC_SIZE - 1, "dwc_otg", IORESOURCE_MEM },
{ DWC_IRQ, DWC_IRQ, "dwc_otg-irq" /* name unused */, IORESOURCE_IRQ }
};
/***************************************
** Supplement to lx_emul environment **
***************************************/
#if VERBOSE_LX_EMUL
#define TRACE dde_kit_printf("\033[32m%s\033[0m called, not implemented\n", __PRETTY_FUNCTION__)
#else
#define TRACE
#endif
#define DUMMY(retval, name) \
extern "C" long name() { \
dde_kit_printf("\033[32m%s\033[0m called, not implemented, stop\n", #name); \
bt(); \
for (;;); \
return retval; \
}
#define CHECKED_DUMMY(retval, name) \
extern "C" long name() { \
dde_kit_printf("\033[32m%s\033[0m called, not implemented, ignored\n", #name); \
bt(); \
return retval; \
}
#define SILENT_DUMMY(retval, name) \
extern "C" long name() { return retval; }
/*********************
** linux/hardirq.h **
*********************/
int in_irq()
{
TRACE; PDBG("called by %p", __builtin_return_address(0));
return 0;
}
/*******************
** linux/delay.h **
*******************/
unsigned long loops_per_jiffy = 1;
/*********************
** linux/jiffies.h **
*********************/
unsigned int jiffies_to_msecs(const unsigned long j)
{
PDBG("not implemented. stop");
return 1;
}
/***********************************
** Dummies for unused PCD driver **
***********************************/
/*
* The PCD driver is used for driving the DWC-OTG device as gadget. The
* Raspberry Pi solely supports the use of the controller as host device.
* Hence, the PCD parts are not needed.
*/
DUMMY(-1, dwc_otg_pcd_disconnect_us);
DUMMY(-1, dwc_otg_pcd_remote_wakeup);
DUMMY(-1, dwc_otg_pcd_get_rmwkup_enable);
DUMMY(-1, dwc_otg_pcd_initiate_srp);
DUMMY(-1, pcd_remove);
SILENT_DUMMY( 0, pcd_init);
DUMMY(-1, printk_once);
/************************************************************************
** Prevent use of FIQ fix, need to resolve FIQ-related symbols anyway **
************************************************************************/
void local_fiq_disable() { }
void local_fiq_enable() { }
int claim_fiq(struct fiq_handler *f) { return 0; }
void set_fiq_regs(struct pt_regs const *regs) { }
void set_fiq_handler(void *start, unsigned int length) { }
void enable_fiq() { }
void __FIQ_Branch(unsigned long *regs) { TRACE; }
extern "C" int fiq_fsm_too_late(struct fiq_state *st, int n) { TRACE; return 0; }
extern "C" void dwc_otg_fiq_nop(struct fiq_state *state) { TRACE; }
extern "C" void dwc_otg_fiq_fsm(struct fiq_state *state, int num_channels) { TRACE; }
unsigned char _dwc_otg_fiq_stub, _dwc_otg_fiq_stub_end;
extern int fiq_enable, fiq_fsm_enable;
/***********************
** linux/workqueue.h **
***********************/
struct workqueue_struct *create_singlethread_workqueue(char *)
{
workqueue_struct *wq = (workqueue_struct *)kzalloc(sizeof(workqueue_struct), 0);
return wq;
}
void destroy_workqueue(struct workqueue_struct *wq) { TRACE; }
bool queue_work(struct workqueue_struct *wq, struct work_struct *work) { TRACE; return 0; }
/***********************
** asm/dma_mapping.h **
***********************/
void *dma_to_virt(struct device *dev, dma_addr_t phys)
{
return phys_to_virt(phys);
}
/*******************
** linux/timer.h **
*******************/
struct tvec_base { };
struct tvec_base boot_tvec_bases;
/*******************
** Init function **
*******************/
extern "C" void module_dwc_otg_driver_init();
extern "C" int module_usbnet_init();
extern "C" int module_smsc95xx_driver_init();
void platform_hcd_init(Services *services)
{
/* enable USB power */
Platform::Connection platform;
platform.power_state(Platform::Session::POWER_USB_HCD, true);
/* register network */
if (services->nic) {
module_usbnet_init();
module_smsc95xx_driver_init();
}
/* disable fiq optimization */
fiq_enable = false;
fiq_fsm_enable = false;
bool const verbose = false;
if (verbose)
g_dbg_lvl = DBG_HCD | DBG_CIL | DBG_HCD_URB;
module_dwc_otg_driver_init();
/* setup host-controller platform device */
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
pdev->name = (char *)"dwc_otg";
pdev->id = 0;
pdev->num_resources = sizeof(_dwc_otg_resource)/sizeof(resource);
pdev->resource = _dwc_otg_resource;
/* needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */
static u64 dma_mask = ~(u64)0;
pdev->dev.dma_mask = &dma_mask;
pdev->dev.coherent_dma_mask = ~0;
platform_device_register(pdev);
}
Genode::Irq_session_capability platform_irq_activate(int irq)
{
try {
Genode::Irq_connection conn(irq);
conn.on_destruction(Genode::Irq_connection::KEEP_OPEN);
return conn;
} catch (...) { }
return Genode::Irq_session_capability();
}