mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-05 09:00:55 +00:00
dde_linux: use new platform API for usb_host_drv
Introduce a common platform device initialization routine for all ARM SoCs by using the new platform driver API. Fix #3865
This commit is contained in:
parent
e223be32ce
commit
a5f6d0f081
@ -1,4 +1,5 @@
|
|||||||
_/src/imx8_fb_drv
|
_/src/imx8_fb_drv
|
||||||
|
_/src/platform_drv
|
||||||
_/src/usb_host_drv
|
_/src/usb_host_drv
|
||||||
_/src/usb_hid_drv
|
_/src/usb_hid_drv
|
||||||
_/raw/drivers_interactive-imx8q_evk
|
_/raw/drivers_interactive-imx8q_evk
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<config>
|
<config verbose="true">
|
||||||
|
|
||||||
<parent-provides>
|
<parent-provides>
|
||||||
<service name="IRQ"/>
|
<service name="IRQ"/>
|
||||||
@ -26,6 +26,35 @@
|
|||||||
</route>
|
</route>
|
||||||
</start>
|
</start>
|
||||||
|
|
||||||
|
<start name="platform_drv" caps="150">
|
||||||
|
<binary name="imx8mq_platform_drv"/>
|
||||||
|
<resource name="RAM" quantum="1M"/>
|
||||||
|
<provides> <service name="Platform"/> </provides>
|
||||||
|
<config>
|
||||||
|
<device name="usb_host_2">
|
||||||
|
<io_mem address="0x38200000" size="0x10000"/>
|
||||||
|
<irq number="73"/>
|
||||||
|
<power-domain name="usb_otg_2"/>
|
||||||
|
<clock name="usb_phy_ref_clk_root"
|
||||||
|
driver_name="usb_phy_root_clk"
|
||||||
|
parent="system_pll1_div8"
|
||||||
|
rate="100000000"/>
|
||||||
|
<clock name="usb_core_ref_clk_root"
|
||||||
|
parent="system_pll1_div8"
|
||||||
|
rate="100000000"/>
|
||||||
|
<clock name="usb_bus_clk_root"
|
||||||
|
parent="system_pll2_div2"
|
||||||
|
rate="500000000"/>
|
||||||
|
<clock name="usb_ctrl2_gate"/>
|
||||||
|
<clock name="usb_phy2_gate"/>
|
||||||
|
<property name="compatible" value="snps,dwc3"/>
|
||||||
|
<property name="dr_mode" value="host"/>
|
||||||
|
</device>
|
||||||
|
<policy label="usb_drv -> "> <device name="usb_host_2"/> </policy>
|
||||||
|
</config>
|
||||||
|
<route> <any-service> <parent/> </any-service> </route>
|
||||||
|
</start>
|
||||||
|
|
||||||
<start name="usb_drv" caps="150">
|
<start name="usb_drv" caps="150">
|
||||||
<binary name="imx8q_evk_usb_host_drv"/>
|
<binary name="imx8q_evk_usb_host_drv"/>
|
||||||
<resource name="RAM" quantum="12M"/>
|
<resource name="RAM" quantum="12M"/>
|
||||||
|
@ -49,7 +49,6 @@ if { [get_cmd_switch --autopilot] && [have_include "power_on/qemu"] } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if { [get_cmd_switch --autopilot] &&
|
if { [get_cmd_switch --autopilot] &&
|
||||||
![have_spec arndale] &&
|
|
||||||
![have_spec rpi] &&
|
![have_spec rpi] &&
|
||||||
![have_spec x86] &&
|
![have_spec x86] &&
|
||||||
![have_spec imx6q_sabrelite] &&
|
![have_spec imx6q_sabrelite] &&
|
||||||
@ -58,6 +57,78 @@ if { [get_cmd_switch --autopilot] &&
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc platform_drv_config_non_x86 {} {
|
||||||
|
if {[have_spec imx8q_evk]} {
|
||||||
|
return {
|
||||||
|
<device name="usb_host_2">
|
||||||
|
<io_mem address="0x38200000" size="0x10000"/>
|
||||||
|
<irq number="73"/>
|
||||||
|
<power-domain name="usb_otg_2"/>
|
||||||
|
<clock name="usb_phy_ref_clk_root"
|
||||||
|
driver_name="usb_phy_root_clk"
|
||||||
|
parent="system_pll1_div8"
|
||||||
|
rate="100000000"/>
|
||||||
|
<clock name="usb_core_ref_clk_root"
|
||||||
|
parent="system_pll1_div8"
|
||||||
|
rate="100000000"/>
|
||||||
|
<clock name="usb_bus_clk_root"
|
||||||
|
parent="system_pll2_div2"
|
||||||
|
rate="500000000"/>
|
||||||
|
<clock name="usb_ctrl2_gate"/>
|
||||||
|
<clock name="usb_phy2_gate"/>
|
||||||
|
<property name="compatible" value="snps,dwc3"/>
|
||||||
|
<property name="dr_mode" value="host"/>
|
||||||
|
</device>
|
||||||
|
<policy label="usb_drv -> "> <device name="usb_host_2"/> </policy>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if {[have_spec imx6q_sabrelite]} {
|
||||||
|
return {
|
||||||
|
<device name="mxs_phy">
|
||||||
|
<io_mem address="0x020ca000" size="0xfff"/>
|
||||||
|
<irq number="77"/>
|
||||||
|
<property name="compatible" value="fsl,imx6q-usbphy"/>
|
||||||
|
<property name="fsl,anatop" value="0xdeaddead"/>
|
||||||
|
</device>
|
||||||
|
<device name="usbmisc_imx">
|
||||||
|
<io_mem address="0x02184800" size="0x1ff"/>
|
||||||
|
<property name="compatible" value="fsl,imx6q-usbmisc"/>
|
||||||
|
</device>
|
||||||
|
<device name="imx_usb">
|
||||||
|
<io_mem address="0x02184200" size="0x1ff"/>
|
||||||
|
<irq number="72"/>
|
||||||
|
<property name="compatible" value="fsl,imx6q-usb"/>
|
||||||
|
<property name="fsl,usbmisc" value="usbmisc_imx"/>
|
||||||
|
<property name="dr_mode" value="host"/>
|
||||||
|
</device>
|
||||||
|
<policy label="usb_drv -> ">
|
||||||
|
<device name="mxs_phy"/>
|
||||||
|
<device name="usbmisc_imx"/>
|
||||||
|
<device name="imx_usb"/>
|
||||||
|
</policy>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if {[have_spec rpi]} {
|
||||||
|
return {
|
||||||
|
<device name="dwc_otg">
|
||||||
|
<io_mem address="0x20980000" size="0x10000"/>
|
||||||
|
<irq number="9"/>
|
||||||
|
<power-domain name="usb"/>
|
||||||
|
<property name="compatible" value="brcm,bcm2835-usb"/>
|
||||||
|
</device>
|
||||||
|
<policy label="usb_drv -> "> <device name="dwc_otg"/> </policy>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
proc platform_drv_binary_non_x86 {} {
|
||||||
|
if {[have_spec imx8q_evk]} { return imx8mq_platform_drv }
|
||||||
|
if {[have_spec imx6q_sabrelite]} { return platform_drv }
|
||||||
|
if {[have_spec rpi]} { return rpi_new_platform_drv }
|
||||||
|
return no_platform_drv_available
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build
|
# Build
|
||||||
#
|
#
|
||||||
@ -71,11 +142,12 @@ set build_components {
|
|||||||
server/report_rom
|
server/report_rom
|
||||||
}
|
}
|
||||||
|
|
||||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
lappend_if [have_spec gpio] build_components drivers/gpio
|
||||||
|
|
||||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||||
append_platform_drv_build_components
|
if { [have_spec x86] } { append_platform_drv_build_components
|
||||||
|
} else { append build_components { drivers/platform }
|
||||||
|
}
|
||||||
build $build_components
|
build $build_components
|
||||||
|
|
||||||
create_boot_directory
|
create_boot_directory
|
||||||
@ -99,16 +171,32 @@ append config {
|
|||||||
<default-route>
|
<default-route>
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
</default-route>
|
</default-route>
|
||||||
<default caps="100"/>}
|
<default caps="100"/>
|
||||||
|
}
|
||||||
|
|
||||||
append_if [have_spec gpio] config "
|
append_if [have_spec gpio] config "
|
||||||
<start name=\"[gpio_drv]\" caps=\"150\">
|
<start name=\"[gpio_drv]\" caps=\"150\">
|
||||||
<resource name=\"RAM\" quantum=\"4M\"/>
|
<resource name=\"RAM\" quantum=\"4M\"/>
|
||||||
<provides><service name=\"Gpio\"/></provides>
|
<provides><service name=\"Gpio\"/></provides>
|
||||||
<config/>
|
<config/>
|
||||||
</start>"
|
</start>
|
||||||
|
"
|
||||||
|
|
||||||
append_platform_drv_config
|
if { [have_spec x86] } { append_platform_drv_config
|
||||||
|
} else {
|
||||||
|
append config "<start name=\"[platform_drv_binary_non_x86]\">"
|
||||||
|
append config {
|
||||||
|
<resource name="RAM" quantum="1M"/>
|
||||||
|
<provides><service name="Platform"/></provides>
|
||||||
|
<config>
|
||||||
|
}
|
||||||
|
append config "[platform_drv_config_non_x86]"
|
||||||
|
append config {
|
||||||
|
</config>
|
||||||
|
<route> <any-service> <parent/> </any-service> </route>
|
||||||
|
</start>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
append config {
|
append config {
|
||||||
<start name="timer">
|
<start name="timer">
|
||||||
@ -202,10 +290,11 @@ set boot_modules {
|
|||||||
core ld.lib.so init timer usb_hid_drv event_dump dynamic_rom report_rom
|
core ld.lib.so init timer usb_hid_drv event_dump dynamic_rom report_rom
|
||||||
}
|
}
|
||||||
|
|
||||||
append boot_modules [usb_host_drv_binary]
|
append boot_modules " [usb_host_drv_binary] "
|
||||||
lappend_if [have_spec gpio] boot_modules [gpio_drv]
|
lappend_if [have_spec gpio] boot_modules [gpio_drv]
|
||||||
|
|
||||||
append_platform_drv_boot_modules
|
if {[have_spec x86]} { append_platform_drv_boot_modules
|
||||||
|
} else { append boot_modules " [platform_drv_binary_non_x86] " }
|
||||||
|
|
||||||
build_boot_image $boot_modules
|
build_boot_image $boot_modules
|
||||||
|
|
||||||
|
@ -805,9 +805,8 @@ int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
|
|||||||
|
|
||||||
static int platform_match(struct device *dev, struct device_driver *drv)
|
static int platform_match(struct device *dev, struct device_driver *drv)
|
||||||
{
|
{
|
||||||
if (!dev->name)
|
if (of_match_device(drv->of_match_table, dev)) return 1;
|
||||||
return 0;
|
if (!dev->name) return 0;
|
||||||
|
|
||||||
|
|
||||||
printk("MATCH %s %s\n", dev->name, drv->name);
|
printk("MATCH %s %s\n", dev->name, drv->name);
|
||||||
return (Genode::strcmp(dev->name, drv->name) == 0);
|
return (Genode::strcmp(dev->name, drv->name) == 0);
|
||||||
@ -889,6 +888,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
|
|||||||
return r ? r->start : -1;
|
return r ? r->start : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct platform_device * platform_device_list = nullptr;
|
||||||
|
|
||||||
int platform_device_register(struct platform_device *pdev)
|
int platform_device_register(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
@ -897,6 +897,16 @@ int platform_device_register(struct platform_device *pdev)
|
|||||||
/*Set parent to ourselfs */
|
/*Set parent to ourselfs */
|
||||||
if (!pdev->dev.parent)
|
if (!pdev->dev.parent)
|
||||||
pdev->dev.parent = &pdev->dev;
|
pdev->dev.parent = &pdev->dev;
|
||||||
|
|
||||||
|
if (!platform_device_list) { platform_device_list = pdev;
|
||||||
|
} else {
|
||||||
|
for (struct platform_device * pd = platform_device_list;
|
||||||
|
pd; pd = pd->next) {
|
||||||
|
if (!pd->next) { pd->next = pdev; break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pdev->next = nullptr;
|
||||||
|
|
||||||
device_add(&pdev->dev);
|
device_add(&pdev->dev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1008,6 +1018,8 @@ int device_property_read_string(struct device *dev, const char *propname, const
|
|||||||
|
|
||||||
const void *of_get_property(const struct device_node *node, const char *name, int *lenp)
|
const void *of_get_property(const struct device_node *node, const char *name, int *lenp)
|
||||||
{
|
{
|
||||||
|
if (Genode::strcmp(name, "fsl,anatop") == 0) { return (const void*) 0xdeaddead; }
|
||||||
|
|
||||||
for (property * p = node ? node->properties : nullptr; p; p = p->next)
|
for (property * p = node ? node->properties : nullptr; p; p = p->next)
|
||||||
if (Genode::strcmp(name, p->name) == 0) return p->value;
|
if (Genode::strcmp(name, p->name) == 0) return p->value;
|
||||||
|
|
||||||
@ -1035,9 +1047,12 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
|||||||
const struct device *dev)
|
const struct device *dev)
|
||||||
{
|
{
|
||||||
const char * compatible = (const char*) of_get_property(dev->of_node, "compatible", 0);
|
const char * compatible = (const char*) of_get_property(dev->of_node, "compatible", 0);
|
||||||
for (; matches && matches->compatible[0]; matches++)
|
if (!compatible) return nullptr;
|
||||||
|
|
||||||
|
for (; matches && matches->compatible[0]; matches++) {
|
||||||
if (Genode::strcmp(matches->compatible, compatible) == 0)
|
if (Genode::strcmp(matches->compatible, compatible) == 0)
|
||||||
return matches;
|
return matches;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,10 +1062,17 @@ int of_parse_phandle_with_args(struct device_node *np,
|
|||||||
const char *cells_name,
|
const char *cells_name,
|
||||||
int index, struct of_phandle_args *out_args)
|
int index, struct of_phandle_args *out_args)
|
||||||
{
|
{
|
||||||
out_args->np = (device_node*) of_get_property(np, "fsl,usbmisc", 0);
|
if (Genode::strcmp(list_name, "fsl,usbmisc") == 0) {
|
||||||
out_args->args[0] = 1;
|
for (struct platform_device * pd = platform_device_list; pd; pd = pd->next) {
|
||||||
|
if (Genode::strcmp(pd->name, "usbmisc_imx") == 0) {
|
||||||
|
out_args->np = pd->dev.of_node;
|
||||||
|
out_args->args[0] = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -921,6 +921,7 @@ struct platform_device {
|
|||||||
struct device dev;
|
struct device dev;
|
||||||
u32 num_resources;
|
u32 num_resources;
|
||||||
struct resource *resource;
|
struct resource *resource;
|
||||||
|
struct platform_device * next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct platform_device *platform_device_alloc(const char *name, int id);
|
struct platform_device *platform_device_alloc(const char *name, int id);
|
||||||
@ -1581,7 +1582,7 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, c
|
|||||||
extern struct platform_device *of_find_device_by_node(struct device_node *np);
|
extern struct platform_device *of_find_device_by_node(struct device_node *np);
|
||||||
struct property *of_find_property(const struct device_node *np, const char *name, int *lenp);
|
struct property *of_find_property(const struct device_node *np, const char *name, int *lenp);
|
||||||
|
|
||||||
#define of_match_ptr(ptr) NULL
|
#define of_match_ptr(ptr) (ptr)
|
||||||
#define for_each_available_child_of_node(parent, child) while (0)
|
#define for_each_available_child_of_node(parent, child) while (0)
|
||||||
|
|
||||||
const void *of_device_get_match_data(const struct device *dev);
|
const void *of_device_get_match_data(const struct device *dev);
|
||||||
@ -1820,6 +1821,7 @@ static inline void trace_xhci_dbg_address(struct va_format *v) {}
|
|||||||
#define trace_dwc3_writel(v0, v1, v2)
|
#define trace_dwc3_writel(v0, v1, v2)
|
||||||
|
|
||||||
void lx_backtrace(void);
|
void lx_backtrace(void);
|
||||||
|
void lx_platform_device_init(void);
|
||||||
|
|
||||||
#include <lx_emul/extern_c_end.h>
|
#include <lx_emul/extern_c_end.h>
|
||||||
|
|
||||||
|
@ -1,71 +1,187 @@
|
|||||||
/*
|
/*
|
||||||
* \brief ARM specific implemenations used on all SOCs
|
* \brief ARM specific implemenations used on all SOCs
|
||||||
* \author Sebastian Sumpf
|
* \author Stefan Kalkowski
|
||||||
* \date 2016-04-25
|
* \date 2020-08-18
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
* Copyright (C) 2020 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is distributed under the terms of the GNU General Public License
|
* This file is distributed under the terms of the GNU General Public License
|
||||||
* version 2.
|
* version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/attached_io_mem_dataspace.h>
|
#include <platform_session/connection.h>
|
||||||
#include <irq_session/connection.h>
|
#include <platform.h>
|
||||||
#include <base/env.h>
|
|
||||||
|
|
||||||
#include <lx_emul.h>
|
#include <lx_emul.h>
|
||||||
|
|
||||||
#include <lx_kit/backend_alloc.h>
|
#include <lx_kit/backend_alloc.h>
|
||||||
#include <lx_kit/env.h>
|
|
||||||
#include <lx_kit/irq.h>
|
#include <lx_kit/irq.h>
|
||||||
#include <lx_kit/malloc.h>
|
#include <lx_kit/malloc.h>
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
struct Io_mem : List<Io_mem>::Element
|
||||||
|
{
|
||||||
|
static addr_t io_mem_start;
|
||||||
|
|
||||||
|
Io_mem_dataspace_capability cap;
|
||||||
|
addr_t start;
|
||||||
|
size_t size;
|
||||||
|
Constructible<Attached_dataspace> ds {};
|
||||||
|
|
||||||
|
Io_mem(Io_mem_dataspace_capability cap,
|
||||||
|
addr_t off,
|
||||||
|
size_t size,
|
||||||
|
List<Io_mem> & list)
|
||||||
|
: cap(cap), start(io_mem_start+off), size(size)
|
||||||
|
{
|
||||||
|
io_mem_start += align_addr(off+size+PAGE_SIZE, PAGE_SHIFT);
|
||||||
|
list.insert(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Irq : List<Irq>::Element
|
||||||
|
{
|
||||||
|
static unsigned irq_start;
|
||||||
|
|
||||||
|
Irq_session_capability cap;
|
||||||
|
unsigned nr { irq_start++ };
|
||||||
|
|
||||||
|
Irq(Irq_session_capability cap, List<Irq> & list)
|
||||||
|
: cap(cap) { list.insert(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Resource_env
|
||||||
|
{
|
||||||
|
Platform::Connection platform;
|
||||||
|
List<Io_mem> io_mem_list;
|
||||||
|
List<Irq> irq_list;
|
||||||
|
|
||||||
|
Resource_env(Env & env) : platform(env) { };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MAX_RESOURCES = 64,
|
||||||
|
IO_MEM_START = 0xf0000,
|
||||||
|
IRQ_START = 32,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
addr_t Io_mem::io_mem_start = IO_MEM_START;
|
||||||
|
unsigned Irq::irq_start = IRQ_START;
|
||||||
|
|
||||||
|
|
||||||
|
static Resource_env & resource_env(Genode::Env * env = nullptr)
|
||||||
|
{
|
||||||
|
static Resource_env r_env { *env };
|
||||||
|
return r_env;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void lx_platform_device_init()
|
||||||
|
{
|
||||||
|
using String = String<64>;
|
||||||
|
using Device = Platform::Device;
|
||||||
|
|
||||||
|
unsigned p_id = 0;
|
||||||
|
|
||||||
|
resource_env().platform.with_xml([&] (Xml_node & xml)
|
||||||
|
{
|
||||||
|
xml.for_each_sub_node("device", [&] (Xml_node node)
|
||||||
|
{
|
||||||
|
Device::Name name = node.attribute_value("name", Device::Name());
|
||||||
|
Platform::Device_client device {
|
||||||
|
resource_env().platform.acquire_device(name.string()) };
|
||||||
|
|
||||||
|
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
||||||
|
pdev->name = (char *)kzalloc(64,0);
|
||||||
|
copy_cstring((char*)pdev->name, name.string(), 64);
|
||||||
|
pdev->id = p_id++;
|
||||||
|
|
||||||
|
unsigned res_count = 0;
|
||||||
|
pdev->resource = (resource*) kzalloc(MAX_RESOURCES*sizeof(resource), 0);
|
||||||
|
|
||||||
|
node.for_each_sub_node("io_mem", [&] (Xml_node node)
|
||||||
|
{
|
||||||
|
if (res_count >= MAX_RESOURCES) { return; }
|
||||||
|
|
||||||
|
unsigned id = node.attribute_value("id", res_count);
|
||||||
|
size_t sz = node.attribute_value("size", (size_t)0);
|
||||||
|
addr_t p_off = node.attribute_value("page_offset", (addr_t)0);
|
||||||
|
Io_mem & iom = *new (Lx_kit::env().heap())
|
||||||
|
Io_mem(device.io_mem_dataspace(id), p_off, sz, resource_env().io_mem_list);
|
||||||
|
pdev->resource[res_count++] = { iom.start, iom.start+iom.size-1,
|
||||||
|
"io_mem", IORESOURCE_MEM };
|
||||||
|
});
|
||||||
|
|
||||||
|
pdev->num_resources = res_count;
|
||||||
|
res_count = 0;
|
||||||
|
|
||||||
|
node.for_each_sub_node("irq", [&] (Xml_node node)
|
||||||
|
{
|
||||||
|
if (res_count+pdev->num_resources >= MAX_RESOURCES) { return; }
|
||||||
|
|
||||||
|
unsigned id = node.attribute_value("id", res_count);
|
||||||
|
Irq & irq = *new (Lx_kit::env().heap())
|
||||||
|
Irq(device.irq(id), resource_env().irq_list);
|
||||||
|
pdev->resource[pdev->num_resources+res_count++] =
|
||||||
|
{ irq.nr, irq.nr, "irq", IORESOURCE_IRQ };
|
||||||
|
});
|
||||||
|
|
||||||
|
pdev->num_resources += res_count;
|
||||||
|
|
||||||
|
pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
||||||
|
pdev->dev.of_node->dev = &pdev->dev;
|
||||||
|
property ** prop = &pdev->dev.of_node->properties;
|
||||||
|
|
||||||
|
node.for_each_sub_node("property", [&] (Xml_node node) {
|
||||||
|
*prop = (property*) kzalloc(sizeof(property), 0);
|
||||||
|
(*prop)->name = (char*)kzalloc(64,0);
|
||||||
|
(*prop)->value = kzalloc(64,0);
|
||||||
|
copy_cstring((char*)(*prop)->name, node.attribute_value("name", String()).string(), 64);
|
||||||
|
copy_cstring((char*)(*prop)->value, node.attribute_value("value", String()).string(), 64);
|
||||||
|
prop = &(*prop)->next;
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
resource_env().platform.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
** lx_kit/backend_alloc.h **
|
** lx_kit/backend_alloc.h **
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
void backend_alloc_init(Genode::Env&, Genode::Ram_allocator&,
|
void backend_alloc_init(Env & env, Ram_allocator&, Allocator&)
|
||||||
Genode::Allocator&)
|
|
||||||
{
|
{
|
||||||
/* intentionally left blank */
|
resource_env(&env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Genode::Ram_dataspace_capability
|
Ram_dataspace_capability
|
||||||
Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached) {
|
Lx::backend_alloc(addr_t size, Cache_attribute)
|
||||||
return Lx_kit::env().env().ram().alloc(size, cached); }
|
|
||||||
|
|
||||||
|
|
||||||
void Lx::backend_free(Genode::Ram_dataspace_capability cap) {
|
|
||||||
return Lx_kit::env().env().ram().free(cap); }
|
|
||||||
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
** linux/interrupt.h **
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
extern "C" int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
|
|
||||||
const char *name, void *dev)
|
|
||||||
{
|
{
|
||||||
Genode::Irq_connection * irq_con =
|
return resource_env().platform.alloc_dma_buffer(size);
|
||||||
new(Lx::Malloc::mem())
|
|
||||||
Genode::Irq_connection(Lx_kit::env().env(), irq);
|
|
||||||
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id)
|
void Lx::backend_free(Ram_dataspace_capability cap)
|
||||||
{
|
{
|
||||||
Genode::Irq_connection * irq_con =
|
return resource_env().platform.free_dma_buffer(cap);
|
||||||
new(Lx::Malloc::mem())
|
|
||||||
Genode::Irq_connection(Lx_kit::env().env(), irq);
|
|
||||||
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -73,17 +189,19 @@ int devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler
|
|||||||
** asm-generic/io.h **
|
** asm-generic/io.h **
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
void *_ioremap(phys_addr_t phys_addr, unsigned long size, int wc)
|
void * _ioremap(phys_addr_t phys_addr, unsigned long size, int)
|
||||||
{
|
{
|
||||||
try {
|
for (Io_mem * iom = resource_env().io_mem_list.first(); iom; iom = iom->next()) {
|
||||||
Genode::Attached_io_mem_dataspace *ds =
|
if (iom->start <= phys_addr && iom->start+iom->size >= phys_addr+size) {
|
||||||
new(Lx::Malloc::mem())
|
iom->ds.construct(Lx_kit::env().env().rm(), iom->cap);
|
||||||
Genode::Attached_io_mem_dataspace(Lx_kit::env().env(), phys_addr, size, !!wc);
|
addr_t off = phys_addr - iom->start;
|
||||||
return ds->local_addr<void>();
|
off += iom->start & (addr_t)(PAGE_SIZE-1);
|
||||||
} catch (...) {
|
return (void*)((addr_t)iom->ds->local_addr<void>() + off);
|
||||||
panic("Failed to request I/O memory: [%lx,%lx)", phys_addr, phys_addr + size);
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
warning("did not found physical resource ", (void*)phys_addr);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,3 +211,23 @@ void *ioremap(phys_addr_t offset, unsigned long size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
** linux/interrupt.h **
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
extern "C" int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
|
||||||
|
const char *name, void *dev)
|
||||||
|
{
|
||||||
|
for (Irq * i = resource_env().irq_list.first(); i; i = i->next()) {
|
||||||
|
if (i->nr != irq) { continue; }
|
||||||
|
Lx::Irq::irq().request_irq(i->cap, irq, handler, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id)
|
||||||
|
{
|
||||||
|
return request_irq(irq, handler, irqflags, devname, dev_id);
|
||||||
|
}
|
||||||
|
@ -30,87 +30,7 @@ void platform_hcd_init(Genode::Env &, Services *services)
|
|||||||
module_usbmisc_imx_driver_init();
|
module_usbmisc_imx_driver_init();
|
||||||
module_ci_hdrc_imx_driver_init();
|
module_ci_hdrc_imx_driver_init();
|
||||||
|
|
||||||
/* USB PHY initialization */
|
lx_platform_device_init();
|
||||||
{
|
|
||||||
static resource usbphy_res[] =
|
|
||||||
{
|
|
||||||
{ 0x020ca000, 0x020cafff, "usbphy", IORESOURCE_MEM },
|
|
||||||
{ 77, 77, "usbphy-irq", IORESOURCE_IRQ },
|
|
||||||
};
|
|
||||||
|
|
||||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
|
||||||
pdev->name = (char *)"mxs_phy";
|
|
||||||
pdev->id = 0;
|
|
||||||
pdev->num_resources = 2;
|
|
||||||
pdev->resource = usbphy_res;
|
|
||||||
|
|
||||||
pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
|
||||||
pdev->dev.of_node->properties = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->name = "compatible";
|
|
||||||
pdev->dev.of_node->properties->value = (void*)"fsl,imx6q-usbphy";
|
|
||||||
pdev->dev.of_node->properties->next = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->next->name = "fsl,anatop";
|
|
||||||
pdev->dev.of_node->properties->next->value = (void*)0xdeaddead;
|
|
||||||
|
|
||||||
platform_device_register(pdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
device_node * usbmisc_of_node = nullptr;
|
|
||||||
|
|
||||||
/* USB MISC initialization */
|
|
||||||
{
|
|
||||||
static resource usbmisc_res[] = { { 0x02184800, 0x021849ff, "usbmisc", IORESOURCE_MEM }, };
|
|
||||||
|
|
||||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
|
||||||
pdev->name = (char *)"usbmisc_imx";
|
|
||||||
pdev->id = 1;
|
|
||||||
pdev->num_resources = 1;
|
|
||||||
pdev->resource = usbmisc_res;
|
|
||||||
|
|
||||||
pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
|
||||||
pdev->dev.of_node->properties = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->name = "compatible";
|
|
||||||
pdev->dev.of_node->properties->value = (void*)"fsl,imx6q-usbmisc";
|
|
||||||
pdev->dev.of_node->dev = &pdev->dev;
|
|
||||||
usbmisc_of_node = pdev->dev.of_node;
|
|
||||||
|
|
||||||
platform_device_register(pdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup EHCI-controller platform device */
|
|
||||||
{
|
|
||||||
static resource ehci_res[] =
|
|
||||||
{
|
|
||||||
{ 0x02184200, 0x021843ff, "imx_usb", IORESOURCE_MEM },
|
|
||||||
{ 72, 72, "imx_usb-irq", IORESOURCE_IRQ },
|
|
||||||
};
|
|
||||||
|
|
||||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
|
||||||
pdev->name = (char *)"imx_usb";
|
|
||||||
pdev->id = 2;
|
|
||||||
pdev->num_resources = 2;
|
|
||||||
pdev->resource = ehci_res;
|
|
||||||
|
|
||||||
pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
|
||||||
pdev->dev.of_node->properties = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->name = "compatible";
|
|
||||||
pdev->dev.of_node->properties->value = (void*)"fsl,imx6q-usb";
|
|
||||||
pdev->dev.of_node->properties->next = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->next->name = "fsl,usbmisc";
|
|
||||||
pdev->dev.of_node->properties->next->value = (void*)usbmisc_of_node;
|
|
||||||
pdev->dev.of_node->properties->next->next = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->next->next->name = "dr_mode";
|
|
||||||
pdev->dev.of_node->properties->next->next->value = (void*)"host";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int devm_extcon_register_notifier(struct device *dev, struct extcon_dev *edev, unsigned int id, struct notifier_block *nb)
|
extern "C" int devm_extcon_register_notifier(struct device *dev, struct extcon_dev *edev, unsigned int id, struct notifier_block *nb)
|
||||||
|
@ -21,40 +21,9 @@
|
|||||||
extern "C" void module_dwc3_driver_init();
|
extern "C" void module_dwc3_driver_init();
|
||||||
extern "C" void module_xhci_plat_init();
|
extern "C" void module_xhci_plat_init();
|
||||||
|
|
||||||
void platform_hcd_init(Genode::Env &, Services *services)
|
void platform_hcd_init(Genode::Env &, Services *)
|
||||||
{
|
{
|
||||||
module_dwc3_driver_init();
|
module_dwc3_driver_init();
|
||||||
module_xhci_plat_init();
|
module_xhci_plat_init();
|
||||||
|
lx_platform_device_init();
|
||||||
/* setup XHCI-controller platform device */
|
|
||||||
{
|
|
||||||
static resource xhci_res[] =
|
|
||||||
{
|
|
||||||
{ 0x38200000ul, 0x38200000ul + 0x10000 - 1, "dwc3", IORESOURCE_MEM },
|
|
||||||
{ 41 + 32, 41 + 32, "dwc3-irq", IORESOURCE_IRQ },
|
|
||||||
};
|
|
||||||
|
|
||||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
|
||||||
pdev->name = (char *)"dwc3";
|
|
||||||
pdev->id = 2;
|
|
||||||
pdev->num_resources = 2;
|
|
||||||
pdev->resource = xhci_res;
|
|
||||||
|
|
||||||
pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
|
||||||
pdev->dev.of_node->properties = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->name = "compatible";
|
|
||||||
pdev->dev.of_node->properties->value = (void*)"fsl,imx8mq-dwc3";
|
|
||||||
pdev->dev.of_node->properties->next = (property*)kzalloc(sizeof(property), 0);
|
|
||||||
pdev->dev.of_node->properties->next->name = "dr_mode";
|
|
||||||
pdev->dev.of_node->properties->next->value = (void*)"host";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,6 @@
|
|||||||
* version 2.
|
* version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <io_mem_session/connection.h>
|
|
||||||
#include <util/mmio.h>
|
|
||||||
#include <platform_session/connection.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* emulation */
|
/* emulation */
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <lx_emul.h>
|
#include <lx_emul.h>
|
||||||
@ -29,17 +23,6 @@
|
|||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
|
||||||
** Resource info passed to the dwc_otg driver **
|
|
||||||
************************************************/
|
|
||||||
|
|
||||||
enum {
|
|
||||||
DWC_BASE = 0x20980000,
|
|
||||||
DWC_SIZE = 0x20000,
|
|
||||||
DWC_IRQ = 9,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
** Init function **
|
** Init function **
|
||||||
*******************/
|
*******************/
|
||||||
@ -49,33 +32,10 @@ extern bool fiq_enable, fiq_fsm_enable;
|
|||||||
|
|
||||||
void platform_hcd_init(Genode::Env &env, Services *services)
|
void platform_hcd_init(Genode::Env &env, Services *services)
|
||||||
{
|
{
|
||||||
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 }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* enable USB power */
|
|
||||||
Platform::Connection platform(services->env);
|
|
||||||
platform.power_state(Platform::Session::POWER_USB_HCD, true);
|
|
||||||
|
|
||||||
/* disable fiq optimization */
|
/* disable fiq optimization */
|
||||||
fiq_enable = false;
|
fiq_enable = false;
|
||||||
fiq_fsm_enable = false;
|
fiq_fsm_enable = false;
|
||||||
|
|
||||||
module_dwc_otg_driver_init();
|
module_dwc_otg_driver_init();
|
||||||
|
lx_platform_device_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);
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ REQUIRES = arm_v6
|
|||||||
|
|
||||||
INC_DIR += $(REP_DIR)/src/drivers/usb_host/spec/arm
|
INC_DIR += $(REP_DIR)/src/drivers/usb_host/spec/arm
|
||||||
INC_DIR += $(REP_DIR)/src/include/spec/arm
|
INC_DIR += $(REP_DIR)/src/include/spec/arm
|
||||||
INC_DIR += $(call select_from_repositories,include/spec/rpi)
|
|
||||||
|
|
||||||
SRC_CC += spec/arm/platform.cc
|
SRC_CC += spec/arm/platform.cc
|
||||||
SRC_CC += spec/rpi/platform.cc
|
SRC_CC += spec/rpi/platform.cc
|
||||||
|
@ -45,6 +45,7 @@ SRC_C += lib/find_bit.c
|
|||||||
|
|
||||||
CC_OPT += -U__linux__
|
CC_OPT += -U__linux__
|
||||||
CC_OPT += -D__KERNEL__
|
CC_OPT += -D__KERNEL__
|
||||||
|
CC_OPT += -DCONFIG_OF=1
|
||||||
CC_OPT += -DCONFIG_USB_DEVICEFS=1
|
CC_OPT += -DCONFIG_USB_DEVICEFS=1
|
||||||
CC_OPT += -DCONFIG_HOTPLUG=1
|
CC_OPT += -DCONFIG_HOTPLUG=1
|
||||||
CC_OPT += -DCONFIG_USB_PHY=1
|
CC_OPT += -DCONFIG_USB_PHY=1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user