mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
dde_linux: turn imx8_fb_drv into Platform client
* Requests its I/O resources and clock settings from the platform driver Fix #3877
This commit is contained in:
parent
5913cdae89
commit
fd161cd814
@ -50,7 +50,46 @@
|
||||
<property name="compatible" value="snps,dwc3"/>
|
||||
<property name="dr_mode" value="host"/>
|
||||
</device>
|
||||
|
||||
<device name="dcss">
|
||||
<io_mem address="0x32e00000" size="0x30000"/>
|
||||
<irq number="50"/>
|
||||
<clock name="display_apb_clk_root"
|
||||
driver_name="apb"/>
|
||||
<clock name="display_axi_clk_root"
|
||||
parent="system_pll1_clk"
|
||||
rate="800000000"
|
||||
driver_name="axi"/>
|
||||
<clock name="display_rtrm_clk_root"
|
||||
parent="system_pll1_clk"
|
||||
rate="400000000"
|
||||
driver_name="rtrm"/>
|
||||
<clock name="video2_pll2_clk"
|
||||
parent="27m_ref_clk"
|
||||
driver_name="pix"/>
|
||||
<clock name="display_dtrc_clk_root"
|
||||
driver_name="dtrc"/>
|
||||
<clock name="dc_pixel_clk_root"
|
||||
parent="video_pll1_clk"
|
||||
rate="594000000"/>
|
||||
<property name="compatible" value="nxp,imx8mq-dcss"/>
|
||||
<property name="disp-dev" value="hdmi_disp"/>
|
||||
</device>
|
||||
|
||||
<device name="hdmi">
|
||||
<io_mem address="0x32c00000" size="0x100000"/>
|
||||
<io_mem address="0x32e40000" size="0x40000"/>
|
||||
<io_mem address="0x32e2f000" size="0x10"/>
|
||||
<irq number="48"/>
|
||||
<irq number="57"/>
|
||||
<property name="compatible" value="fsl,imx8mq-hdmi"/>
|
||||
</device>
|
||||
|
||||
<policy label="usb_drv -> "> <device name="usb_host_2"/> </policy>
|
||||
<policy label="fb_drv -> ">
|
||||
<device name="dcss"/>
|
||||
<device name="hdmi"/>
|
||||
</policy>
|
||||
</config>
|
||||
<route> <any-service> <parent/> </any-service> </route>
|
||||
</start>
|
||||
@ -94,6 +133,7 @@
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Capture"> <parent/> </service>
|
||||
<service name="Platform"> <child name="platform_drv"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
|
@ -1748,6 +1748,26 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
/*****************************
|
||||
** IO resource definitions **
|
||||
*****************************/
|
||||
|
||||
enum {
|
||||
IOMEM_BASE_DCSS = 0x100000,
|
||||
IOMEM_END_DCSS = 0x1fffff,
|
||||
IOMEM_BASE_IRQSTEER = IOMEM_BASE_DCSS + 0x2d000,
|
||||
IOMEM_END_IRQSTEER = IOMEM_BASE_IRQSTEER + 0xfff,
|
||||
IOMEM_BASE_HDMI_CTRL = 0x200000,
|
||||
IOMEM_END_HDMI_CTRL = 0x2fffff,
|
||||
IOMEM_BASE_HDMI_CRS = 0x300000,
|
||||
IOMEM_END_HDMI_CRS = 0x33ffff,
|
||||
IOMEM_BASE_HDMI_RST = 0x340000,
|
||||
IOMEM_END_HDMI_RST = 0x34000f,
|
||||
IRQ_IRQSTEER = 32,
|
||||
IRQ_HDMI_IN = 33,
|
||||
IRQ_HDMI_OUT = 34
|
||||
};
|
||||
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#endif /* _LX_EMUL_H_ */
|
||||
|
@ -14,8 +14,8 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_io_mem_dataspace.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <platform_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
@ -53,6 +53,41 @@
|
||||
#include <lx_kit/malloc.h>
|
||||
|
||||
|
||||
enum Device_id { DCSS, HDMI, UNKNOWN };
|
||||
|
||||
namespace Lx_kit {
|
||||
Platform::Connection & platform_connection();
|
||||
Platform::Device_client & platform_device(Device_id);
|
||||
}
|
||||
|
||||
|
||||
Platform::Connection & Lx_kit::platform_connection()
|
||||
{
|
||||
static Platform::Connection plat { Lx_kit::env().env() };
|
||||
return plat;
|
||||
}
|
||||
|
||||
|
||||
Platform::Device_client & Lx_kit::platform_device(Device_id id)
|
||||
{
|
||||
if (id == DCSS) {
|
||||
static Platform::Device_client dcss {
|
||||
platform_connection().device_by_property("compatible",
|
||||
"nxp,imx8mq-dcss") };
|
||||
return dcss;
|
||||
}
|
||||
|
||||
if (id == HDMI) {
|
||||
static Platform::Device_client hdmi {
|
||||
platform_connection().device_by_property("compatible",
|
||||
"fsl,imx8mq-hdmi") };
|
||||
return hdmi;
|
||||
}
|
||||
|
||||
throw 1;
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
** drivers/base/dma-mapping.c **
|
||||
********************************/
|
||||
@ -252,23 +287,28 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
/* numbers from running Linux system */
|
||||
|
||||
static struct clk clocks[] {
|
||||
{ "apb", 133333334 },
|
||||
{ "axi", 800000000 },
|
||||
{ "ipg", 133333334 },
|
||||
{ "pix", 27000000 },
|
||||
{ "rtrm", 400000000 },
|
||||
{ "dtrc", 25000000 },
|
||||
};
|
||||
using namespace Genode;
|
||||
|
||||
for (unsigned i = 0; i < (sizeof(clocks) / sizeof(struct clk)); i++)
|
||||
if (Genode::strcmp(clocks[i].name, id) == 0)
|
||||
return &clocks[i];
|
||||
const char * clock_name = id;
|
||||
if (String<32>("ipg") == id) { clock_name = "apb"; }
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::warning("MISSING CLOCK: ", id);
|
||||
unsigned long rate = 0;
|
||||
Lx_kit::platform_connection().with_xml([&] (Xml_node node) {
|
||||
node.for_each_sub_node("device", [&] (Xml_node node) {
|
||||
node.for_each_sub_node("clock", [&] (Xml_node node) {
|
||||
if (node.attribute_value("name", String<64>()) != clock_name) {
|
||||
return; }
|
||||
rate = node.attribute_value<unsigned long>("rate", 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return nullptr;
|
||||
if (!rate) return nullptr;
|
||||
|
||||
struct clk * clock = (struct clk*) kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
clock->name = id;
|
||||
clock->rate = rate;
|
||||
return clock;
|
||||
}
|
||||
|
||||
|
||||
@ -565,9 +605,7 @@ void irq_set_chained_handler_and_data(unsigned int irq,
|
||||
irqsteer_irq_desc.irq_data.chip = irqsteer_chip;
|
||||
irqsteer_irq_desc.handle_irq = handle;
|
||||
|
||||
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
|
||||
Genode::Irq_connection(Lx_kit::env().env(), irq);
|
||||
Lx::Irq::irq().request_irq(irq_con->cap(), irq,
|
||||
Lx::Irq::irq().request_irq(Lx_kit::platform_device(DCSS).irq(), irq,
|
||||
irqsteer_irq_handler, nullptr, nullptr);
|
||||
}
|
||||
|
||||
@ -586,9 +624,17 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
|
||||
Genode::Irq_connection(Lx_kit::env().env(), irq);
|
||||
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id, thread_fn);
|
||||
Device_id id = UNKNOWN;
|
||||
unsigned off = 0;
|
||||
switch (irq) {
|
||||
case IRQ_IRQSTEER: id = DCSS; break;
|
||||
case IRQ_HDMI_IN: id = HDMI; break;
|
||||
case IRQ_HDMI_OUT: id = HDMI; off = 1; break;
|
||||
default: ;
|
||||
};
|
||||
|
||||
Lx::Irq::irq().request_irq(Lx_kit::platform_device(id).irq(off),
|
||||
irq, handler, dev_id, thread_fn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -703,14 +749,46 @@ int disable_irq_nosync(unsigned int irq)
|
||||
|
||||
static void *_ioremap(phys_addr_t phys_addr, unsigned long size, int wc)
|
||||
{
|
||||
try {
|
||||
Genode::Attached_io_mem_dataspace *ds = new(Lx::Malloc::mem())
|
||||
Genode::Attached_io_mem_dataspace(Lx_kit::env().env(), phys_addr, size, !!wc);
|
||||
return ds->local_addr<void>();
|
||||
} catch (...) {
|
||||
panic("Failed to request I/O memory: [%lx,%lx)", phys_addr, phys_addr + size);
|
||||
return 0;
|
||||
}
|
||||
using namespace Genode;
|
||||
|
||||
Region_map & rm = Lx_kit::env().env().rm();
|
||||
|
||||
if (phys_addr >= IOMEM_BASE_DCSS &&
|
||||
(phys_addr+size-1) <= IOMEM_END_DCSS) {
|
||||
static Attached_dataspace ds {
|
||||
rm, Lx_kit::platform_device(DCSS).io_mem_dataspace() };
|
||||
addr_t off = phys_addr - IOMEM_BASE_DCSS;
|
||||
return (void*)(((addr_t)ds.local_addr<void>()) + off);
|
||||
};
|
||||
|
||||
if (phys_addr >= IOMEM_BASE_HDMI_CTRL &&
|
||||
(phys_addr+size-1) <= IOMEM_END_HDMI_RST) {
|
||||
switch (phys_addr) {
|
||||
case IOMEM_BASE_HDMI_CTRL:
|
||||
{
|
||||
static Attached_dataspace ds {
|
||||
rm, Lx_kit::platform_device(HDMI).io_mem_dataspace(0) };
|
||||
return ds.local_addr<void>();
|
||||
}
|
||||
case IOMEM_BASE_HDMI_CRS:
|
||||
{
|
||||
static Attached_dataspace ds {
|
||||
rm, Lx_kit::platform_device(HDMI).io_mem_dataspace(1) };
|
||||
return ds.local_addr<void>();
|
||||
}
|
||||
case IOMEM_BASE_HDMI_RST:
|
||||
{
|
||||
static Attached_dataspace ds {
|
||||
rm, Lx_kit::platform_device(HDMI).io_mem_dataspace(2) };
|
||||
return ds.local_addr<void>();
|
||||
}
|
||||
default: ;
|
||||
};
|
||||
};
|
||||
|
||||
panic("Failed to request I/O memory: [%lx,%lx)",
|
||||
phys_addr, phys_addr + size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *devm_ioremap(struct device *dev, resource_size_t offset,
|
||||
@ -890,9 +968,16 @@ int devm_request_irq(struct device *dev, unsigned int irq,
|
||||
irqsteer_dev_id[irq] = dev_id;
|
||||
enable_irq(irq);
|
||||
} else {
|
||||
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
|
||||
Genode::Irq_connection(Lx_kit::env().env(), irq);
|
||||
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id);
|
||||
Device_id id = UNKNOWN;
|
||||
unsigned off = 0;
|
||||
switch (irq) {
|
||||
case IRQ_IRQSTEER: id = DCSS; break;
|
||||
case IRQ_HDMI_IN: id = HDMI; break;
|
||||
case IRQ_HDMI_OUT: id = HDMI; off = 1; break;
|
||||
default: ;
|
||||
};
|
||||
Lx::Irq::irq().request_irq(Lx_kit::platform_device(id).irq(off),
|
||||
irq, handler, dev_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_io_mem_dataspace.h>
|
||||
#include <base/log.h>
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
@ -124,7 +125,6 @@ void Framebuffer::Main::_run_linux()
|
||||
module_dcss_crtc_driver_init();
|
||||
module_imx_hdp_imx_platform_driver_init();
|
||||
|
||||
|
||||
/**
|
||||
* This device is originally created with the name '32e2d000.irqsteer'
|
||||
* via 'of_platform_bus_create()'. Here it is called 'imx-irqsteer' to match
|
||||
@ -135,8 +135,9 @@ void Framebuffer::Main::_run_linux()
|
||||
platform_device_alloc("imx-irqsteer", 0);
|
||||
|
||||
static resource imx_irqsteer_resources[] = {
|
||||
{ 0x32e2d000, 0x32e2dfff, "imx-irqsteer", IORESOURCE_MEM },
|
||||
{ 50, 50, "imx-irqsteer", IORESOURCE_IRQ },
|
||||
{ IOMEM_BASE_IRQSTEER, IOMEM_END_IRQSTEER,
|
||||
"imx-irqsteer", IORESOURCE_MEM },
|
||||
{ IRQ_IRQSTEER, IRQ_IRQSTEER, "imx-irqsteer", IORESOURCE_IRQ },
|
||||
};
|
||||
|
||||
imx_irqsteer_pdev->num_resources = 2;
|
||||
@ -159,15 +160,15 @@ void Framebuffer::Main::_run_linux()
|
||||
platform_device_alloc("dcss-core", 0);
|
||||
|
||||
static resource dcss_resources[] = {
|
||||
{ 0x32e00000, 0x32efffff, "dcss", IORESOURCE_MEM },
|
||||
{ 3, 3, "dpr_dc_ch0", IORESOURCE_IRQ },
|
||||
{ 4, 4, "dpr_dc_ch1", IORESOURCE_IRQ },
|
||||
{ 5, 5, "dpr_dc_ch2", IORESOURCE_IRQ },
|
||||
{ 6, 6, "ctx_ld", IORESOURCE_IRQ },
|
||||
{ 8, 8, "ctxld_kick", IORESOURCE_IRQ },
|
||||
{ 9, 9, "dtg_prg1", IORESOURCE_IRQ },
|
||||
{ 16, 16, "dtrc_ch1", IORESOURCE_IRQ },
|
||||
{ 17, 17, "dtrc_ch2", IORESOURCE_IRQ },
|
||||
{ IOMEM_BASE_DCSS, IOMEM_END_DCSS, "dcss", IORESOURCE_MEM },
|
||||
{ 3, 3, "dpr_dc_ch0", IORESOURCE_IRQ },
|
||||
{ 4, 4, "dpr_dc_ch1", IORESOURCE_IRQ },
|
||||
{ 5, 5, "dpr_dc_ch2", IORESOURCE_IRQ },
|
||||
{ 6, 6, "ctx_ld", IORESOURCE_IRQ },
|
||||
{ 8, 8, "ctxld_kick", IORESOURCE_IRQ },
|
||||
{ 9, 9, "dtg_prg1", IORESOURCE_IRQ },
|
||||
{ 16, 16, "dtrc_ch1", IORESOURCE_IRQ },
|
||||
{ 17, 17, "dtrc_ch2", IORESOURCE_IRQ },
|
||||
};
|
||||
|
||||
dcss_pdev->num_resources = 9;
|
||||
@ -193,11 +194,14 @@ void Framebuffer::Main::_run_linux()
|
||||
platform_device_alloc("i.mx8-hdp", 0);
|
||||
|
||||
static resource hdp_resources[] = {
|
||||
{ 0x32c00000, 0x32cfffff, "hdp_ctrl", IORESOURCE_MEM },
|
||||
{ 0x32e40000, 0x32e7ffff, "hdp_crs", IORESOURCE_MEM },
|
||||
{ 0x32e2f000, 0x32e2f00f, "hdp_reset", IORESOURCE_MEM },
|
||||
{ 48, 48, "plug_in", IORESOURCE_IRQ },
|
||||
{ 57, 57, "plug_out", IORESOURCE_IRQ },
|
||||
{ IOMEM_BASE_HDMI_CTRL, IOMEM_END_HDMI_CTRL,
|
||||
"hdp_ctrl", IORESOURCE_MEM },
|
||||
{ IOMEM_BASE_HDMI_CRS, IOMEM_END_HDMI_CRS,
|
||||
"hdp_crs", IORESOURCE_MEM },
|
||||
{ IOMEM_BASE_HDMI_RST, IOMEM_END_HDMI_RST,
|
||||
"hdp_reset", IORESOURCE_MEM },
|
||||
{ 33, 33, "plug_in", IORESOURCE_IRQ },
|
||||
{ 34, 34, "plug_out", IORESOURCE_IRQ },
|
||||
};
|
||||
|
||||
hdp_pdev->num_resources = 5;
|
||||
@ -212,7 +216,6 @@ void Framebuffer::Main::_run_linux()
|
||||
|
||||
platform_device_register(hdp_pdev);
|
||||
|
||||
|
||||
/**
|
||||
* This device is originally created with the name 'display-subsystem'
|
||||
* via 'of_platform_bus_create()'. Here it is called 'imx-drm' to match
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define _LX_KIT__IRQ_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
#include <platform_device/platform_device.h>
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user