mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
imx8_fb_drv: MIPI DSI display support
- support for Northwest Logic MIPI DSI bridge - support for Radium panel (NXP MX8_DSI_OLED1) - new 'DSI-1' connector in driver config file issue #3900
This commit is contained in:
parent
27f705bc48
commit
664b861f9d
@ -18,6 +18,7 @@ linux-x.x.x/drivers/gpu/drm/drm_gem.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_gem_cma_helper.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_gem_framebuffer_helper.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_internal.h
|
||||
linux-x.x.x/drivers/gpu/drm/drm_mipi_dsi.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_mm.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_mode_config.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_mode_object.c
|
||||
@ -31,8 +32,10 @@ linux-x.x.x/drivers/gpu/drm/drm_property.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_rect.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_vblank.c
|
||||
linux-x.x.x/drivers/gpu/drm/drm_vma_manager.c
|
||||
linux-x.x.x/drivers/gpu/drm/bridge/nwl-dsi.c
|
||||
linux-x.x.x/drivers/gpu/drm/imx/imx-drm.h
|
||||
linux-x.x.x/drivers/gpu/drm/imx/imx-drm-core.c
|
||||
linux-x.x.x/drivers/gpu/drm/imx/nwl_dsi-imx.c
|
||||
linux-x.x.x/drivers/gpu/drm/imx/dcss/dcss-crtc.c
|
||||
linux-x.x.x/drivers/gpu/drm/imx/dcss/dcss-crtc.h
|
||||
linux-x.x.x/drivers/gpu/drm/imx/dcss/dcss-kms.c
|
||||
@ -61,6 +64,7 @@ linux-x.x.x/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.c
|
||||
linux-x.x.x/drivers/gpu/drm/imx/hdp/ss28fdsoi_hdmitx_table.h
|
||||
linux-x.x.x/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.c
|
||||
linux-x.x.x/drivers/gpu/drm/imx/hdp/t28hpc_hdmitx_table.h
|
||||
linux-x.x.x/drivers/gpu/drm/panel/panel-raydium-rm67191.c
|
||||
linux-x.x.x/drivers/gpu/imx/dcss/dcss-common.c
|
||||
linux-x.x.x/drivers/gpu/imx/dcss/dcss-blkctl.c
|
||||
linux-x.x.x/drivers/gpu/imx/dcss/dcss-ctxld.c
|
||||
@ -111,6 +115,7 @@ linux-x.x.x/drivers/mxc/hdp/source_vif.h
|
||||
linux-x.x.x/drivers/mxc/hdp/util.c
|
||||
linux-x.x.x/drivers/mxc/hdp/util.h
|
||||
linux-x.x.x/drivers/mxc/hdp-cec/imx-hdp-cec.h
|
||||
linux-x.x.x/drivers/phy/phy-mixel-mipi-dsi.c
|
||||
linux-x.x.x/drivers/video/hdmi.c
|
||||
linux-x.x.x/include/asm-generic/atomic64.h
|
||||
linux-x.x.x/include/asm-generic/bitops/__ffs.h
|
||||
@ -145,6 +150,7 @@ linux-x.x.x/include/drm/drm_gem_framebuffer_helper.h
|
||||
linux-x.x.x/include/drm/drm_hashtab.h
|
||||
linux-x.x.x/include/drm/drm_hdcp.h
|
||||
linux-x.x.x/include/drm/drm_ioctl.h
|
||||
linux-x.x.x/include/drm/drm_mipi_dsi.h
|
||||
linux-x.x.x/include/drm/drm_mm.h
|
||||
linux-x.x.x/include/drm/drm_mode_config.h
|
||||
linux-x.x.x/include/drm/drm_mode_object.h
|
||||
@ -163,6 +169,7 @@ linux-x.x.x/include/drm/drm_property.h
|
||||
linux-x.x.x/include/drm/drm_rect.h
|
||||
linux-x.x.x/include/drm/drm_vblank.h
|
||||
linux-x.x.x/include/drm/drm_vma_manager.h
|
||||
linux-x.x.x/include/drm/bridge/nwl_dsi.h
|
||||
linux-x.x.x/include/linux/irqchip/chained_irq.h
|
||||
linux-x.x.x/include/linux/busfreq-imx.h
|
||||
linux-x.x.x/include/linux/component.h
|
||||
@ -183,12 +190,16 @@ linux-x.x.x/include/linux/mod_devicetable.h
|
||||
linux-x.x.x/include/linux/of_graph.h
|
||||
linux-x.x.x/include/linux/pm_runtime.h
|
||||
linux-x.x.x/include/linux/pm_wakeirq.h
|
||||
linux-x.x.x/include/linux/phy.h
|
||||
linux-x.x.x/include/linux/radix-tree.h
|
||||
linux-x.x.x/include/linux/ratelimit.h
|
||||
linux-x.x.x/include/linux/rbtree_augmented.h
|
||||
linux-x.x.x/include/linux/rbtree.h
|
||||
linux-x.x.x/include/linux/sort.h
|
||||
linux-x.x.x/include/linux/vga_switcheroo.h
|
||||
linux-x.x.x/include/linux/mfd/syscon/imx8mq-iomuxc-gpr.h
|
||||
linux-x.x.x/include/linux/phy/phy.h
|
||||
linux-x.x.x/include/linux/phy/phy-mixel-mipi-dsi.h
|
||||
linux-x.x.x/include/soc/imx8/sc/ipc.h
|
||||
linux-x.x.x/include/soc/imx8/sc/scfw.h
|
||||
linux-x.x.x/include/soc/imx8/sc/sci.h
|
||||
@ -204,6 +215,7 @@ linux-x.x.x/include/uapi/linux/i2c.h
|
||||
linux-x.x.x/include/uapi/linux/media-bus-format.h
|
||||
linux-x.x.x/include/uapi/linux/swab.h
|
||||
linux-x.x.x/include/video/display_timing.h
|
||||
linux-x.x.x/include/video/mipi_display.h
|
||||
linux-x.x.x/include/video/of_videomode.h
|
||||
linux-x.x.x/include/video/videomode.h
|
||||
linux-x.x.x/include/video/viv-metadata.h
|
||||
|
@ -8,20 +8,27 @@ SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/dma-buf/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/i2c/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/base/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/bridge/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/imx/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/imx/dcss/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/imx/hdp/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/panel/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/imx/dcss/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/irqchip/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/mxc/hdp/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/phy/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/video/*.c))
|
||||
SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/lib/*.c))
|
||||
|
||||
|
||||
CC_OPT_nwl-dsi += -DMOD_SUFFIX=_bridge
|
||||
|
||||
#
|
||||
# Linux sources are C89 with GNU extensions
|
||||
#
|
||||
CC_C_OPT += -std=gnu89
|
||||
|
||||
|
||||
#
|
||||
# Reduce build noise of compiling contrib code
|
||||
#
|
||||
@ -34,12 +41,15 @@ vpath %.c $(LX_CONTRIB_DIR)/drivers/base
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/dma-buf
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/i2c
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm/bridge
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm/imx
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm/imx/dcss
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm/imx/hdp
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm/panel
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/imx/dcss
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/irqchip
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/mxc/hdp
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/phy
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/video
|
||||
vpath %.c $(LX_CONTRIB_DIR)/lib
|
||||
|
||||
|
@ -1,23 +1,13 @@
|
||||
dcss_blkctl.patch
|
||||
|
||||
diff --git a/drivers/gpu/imx/dcss/dcss-blkctl.c b/drivers/gpu/imx/dcss/dcss-blkctl.c
|
||||
index 2f13b33..63d48bf 100644
|
||||
index 2f13b33..a4b0620 100644
|
||||
--- a/drivers/gpu/imx/dcss/dcss-blkctl.c
|
||||
+++ b/drivers/gpu/imx/dcss/dcss-blkctl.c
|
||||
@@ -115,10 +115,14 @@ int dcss_blkctl_init(struct dcss_soc *dcss, unsigned long blkctl_base)
|
||||
disp_dev = of_get_property(node, "disp-dev", &len);
|
||||
if (!disp_dev || !strncmp(disp_dev, "hdmi_disp", 9))
|
||||
blkctl->hdmi_output = true;
|
||||
-
|
||||
+#if 0
|
||||
+ /*
|
||||
+ * XXX: for some reason 'HDMI_MIPI_CLK_SEL' does not work with SOC revision
|
||||
+ * 0x20 and Genode
|
||||
+ */
|
||||
if (imx8_get_soc_revision() >= B0_SILICON_ID)
|
||||
blkctl->clk_setting = HDMI_MIPI_CLK_SEL;
|
||||
-
|
||||
+#endif
|
||||
dcss_blkctl_cfg(dcss);
|
||||
@@ -81,7 +81,7 @@ void dcss_blkctl_cfg(struct dcss_soc *dcss)
|
||||
struct dcss_blkctl_priv *blkctl = dcss->blkctl_priv;
|
||||
|
||||
return 0;
|
||||
if (blkctl->hdmi_output)
|
||||
- dcss_writel((blkctl->clk_setting ^ HDMI_MIPI_CLK_SEL),
|
||||
+ dcss_writel((blkctl->clk_setting),
|
||||
blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
|
||||
else
|
||||
dcss_writel((blkctl->clk_setting ^ HDMI_MIPI_CLK_SEL) |
|
||||
|
@ -1,7 +1,5 @@
|
||||
imx_drm_core.patch
|
||||
|
||||
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
|
||||
index 76b782c..a2c3a76 100644
|
||||
index 453100d..05ef413 100644
|
||||
--- a/drivers/gpu/drm/imx/imx-drm-core.c
|
||||
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
|
||||
@@ -43,7 +43,9 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
|
||||
@ -14,7 +12,7 @@ index 76b782c..a2c3a76 100644
|
||||
}
|
||||
|
||||
DEFINE_DRM_GEM_CMA_FOPS(imx_drm_driver_fops);
|
||||
@@ -120,6 +122,17 @@ static int compare_of(struct device *dev, void *data)
|
||||
@@ -120,6 +122,20 @@ static int compare_of(struct device *dev, void *data)
|
||||
{
|
||||
struct device_node *np = data;
|
||||
|
||||
@ -26,13 +24,16 @@ index 76b782c..a2c3a76 100644
|
||||
+ (strncmp(np->name, "hdmi", strlen(np->name)) == 0))
|
||||
+ return 1;
|
||||
+
|
||||
+ if (strcmp(dev->driver->name, "nwl_dsi-imx") == 0 && strcmp(np->name, "mipi_dsi") == 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+#if 0
|
||||
/* Special case for DI, dev->of_node may not be set yet */
|
||||
if (strcmp(dev->driver->name, "imx-ipuv3-crtc") == 0) {
|
||||
struct ipu_client_platformdata *pdata = dev->platform_data;
|
||||
@@ -161,6 +174,7 @@ static int compare_of(struct device *dev, void *data)
|
||||
@@ -161,6 +177,7 @@ static int compare_of(struct device *dev, void *data)
|
||||
}
|
||||
|
||||
return dev->of_node == np;
|
||||
@ -40,7 +41,7 @@ index 76b782c..a2c3a76 100644
|
||||
}
|
||||
|
||||
static const char *const imx_drm_dpu_comp_parents[] = {
|
||||
@@ -416,8 +430,10 @@ static void imx_drm_unbind(struct device *dev)
|
||||
@@ -416,8 +433,10 @@ static void imx_drm_unbind(struct device *dev)
|
||||
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
|
||||
|
@ -1 +1 @@
|
||||
173719007927a108a9558e727b8c9b388f3159a2
|
||||
12e42f3a812a4d84a068782f0a65936e7e7de884
|
||||
|
@ -1 +1 @@
|
||||
2020-09-16 20a4af22bc5eb3b01c66324e77645662e8801b1a
|
||||
2020-06-12 ce8ce6fad1a020458658f5bb86e582eab4758dee
|
||||
|
@ -64,18 +64,44 @@
|
||||
parent="system_pll1_clk"
|
||||
rate="400000000"
|
||||
driver_name="rtrm"/>
|
||||
<clock name="video2_pll2_clk"
|
||||
parent="27m_ref_clk"
|
||||
driver_name="pix"/>
|
||||
<clock name="video_pll1_clk"
|
||||
parent="25m_ref_clk"
|
||||
rate="1200000000" />
|
||||
<clock name="display_dtrc_clk_root"
|
||||
driver_name="dtrc"/>
|
||||
<clock name="dc_pixel_clk_root"
|
||||
parent="video_pll1_clk"
|
||||
rate="594000000"/>
|
||||
rate="120000000"
|
||||
driver_name="pix"/>
|
||||
<property name="compatible" value="nxp,imx8mq-dcss"/>
|
||||
<property name="disp-dev" value="hdmi_disp"/>
|
||||
</device>
|
||||
|
||||
<!-- CAUTION: System reset controller access is currently required by
|
||||
mipi_dsi -->
|
||||
<device name="src">
|
||||
<io_mem address="0x30390000" size="0x10000"/>
|
||||
</device>
|
||||
|
||||
<device name="mipi_dsi">
|
||||
<io_mem address="0x30a00000" size="0x1000"/>
|
||||
<irq number="66"/>
|
||||
<power-domain name="mipi"/>
|
||||
<clock name="mipi_dsi_phy_ref_clk_root"
|
||||
parent="video_pll1_clk"
|
||||
rate="24000000"
|
||||
driver_name="phy_ref"/>
|
||||
<clock name="mipi_dsi_esc_rx_clk_root"
|
||||
parent="system_pll1_div10"
|
||||
rate="80000000"
|
||||
driver_name="rx_esc"/>
|
||||
<clock name="mipi_dsi_core_clk_root"
|
||||
parent="system_pll1_div3"
|
||||
rate="266000000"
|
||||
driver_name="core"/>
|
||||
<property name="compatible" value="fsl,imx8mq-mipi-dsi_drm"/>
|
||||
</device>
|
||||
|
||||
<device name="hdmi">
|
||||
<io_mem address="0x32c00000" size="0x100000"/>
|
||||
<io_mem address="0x32e40000" size="0x40000"/>
|
||||
@ -89,6 +115,8 @@
|
||||
<policy label="fb_drv -> ">
|
||||
<device name="dcss"/>
|
||||
<device name="hdmi"/>
|
||||
<device name="mipi_dsi"/>
|
||||
<device name="src"/>
|
||||
</policy>
|
||||
</config>
|
||||
<route> <any-service> <parent/> </any-service> </route>
|
||||
@ -104,7 +132,13 @@
|
||||
</config>
|
||||
<route>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Platform"> <child name="platform_drv"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
@ -115,17 +149,21 @@
|
||||
<route>
|
||||
<service name="ROM" label="report"> <child name="report_rom"/> </service>
|
||||
<service name="Event"> <parent/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
<service name="Usb"> <child name="usb_drv"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="fb_drv" caps="250">
|
||||
<binary name="imx8_fb_drv"/>
|
||||
<resource name="RAM" quantum="80M"/>
|
||||
<resource name="RAM" quantum="40M"/>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="fb_drv.config"/> </service>
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
<service name="IRQ"> <parent/> </service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
|
@ -1,3 +1,4 @@
|
||||
<config>
|
||||
<connector name="HDMI-A-1" width="1920" height="1080" hz="60" enabled="true"/>
|
||||
<connector name="DSI-1" width="1080" height="1920" hz="60" enabled="false"/>
|
||||
</config>
|
||||
|
@ -1 +1 @@
|
||||
2020-09-16 fad4ed0507a29556deddce535fc45963241f856d
|
||||
2020-06-12 b9cbb9da87bc382d55c3345bcb5da6b845b57aec
|
||||
|
@ -121,6 +121,29 @@ void drm_dev_unregister(struct drm_device *dev)
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/drm_panel.h **
|
||||
***********************/
|
||||
|
||||
void drm_panel_init(struct drm_panel *panel)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
|
||||
void drm_panel_remove(struct drm_panel *panel)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
|
||||
int drm_panel_detach(struct drm_panel *panel)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
** drivers/gpu/drm/drm_fb_cma_helper.c **
|
||||
*****************************************/
|
||||
@ -295,12 +318,6 @@ void clk_disable_unprepare(struct clk *clk)
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int clk_prepare_enable(struct clk *clk)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
** linux/gpio.h **
|
||||
@ -373,6 +390,7 @@ bool is_of_node(const struct fwnode_handle *fwnode)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************
|
||||
** linux/pm_runtime.h **
|
||||
************************/
|
||||
@ -411,6 +429,53 @@ ktime_t ktime_get_real(void)
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/of_device.h **
|
||||
***********************/
|
||||
|
||||
int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/device.h **
|
||||
********************/
|
||||
|
||||
void device_initialize(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void device_unregister(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** video/videomode.h **
|
||||
***********************/
|
||||
|
||||
void videomode_from_timing(const struct display_timing *dt, struct videomode *vm)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/backlight.h **
|
||||
***********************/
|
||||
|
||||
int backlight_disable(struct backlight_device *bd)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** linux/dma-mapping.h **
|
||||
*************************/
|
||||
@ -434,6 +499,76 @@ int dma_mmap_wc(struct device *dev,
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** linux/phy.h **
|
||||
*****************/
|
||||
struct phy;
|
||||
struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
|
||||
struct device_node *children,
|
||||
struct module *owner,
|
||||
struct phy * (*of_xlate)(struct device *dev,
|
||||
struct of_phandle_args *args))
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args *args)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int phy_power_off(struct phy *phy)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int phy_exit(struct phy *phy)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
***********************/
|
||||
|
||||
void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
** linux/unaligned/generic.h **
|
||||
********************************/
|
||||
|
||||
u32 get_unaligned_le32(const void *p)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/regmap.h **
|
||||
********************/
|
||||
|
||||
struct regmap;
|
||||
|
||||
int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************
|
||||
** linux/pm-runtime.h **
|
||||
************************/
|
||||
@ -561,12 +696,6 @@ loff_t noop_llseek(struct file *file, loff_t offset, int whence)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int of_alias_get_id(struct device_node *np, const char *stem)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int of_irq_get(struct device_node *dev, int index)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
@ -592,8 +721,8 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
|
||||
|
||||
int PTR_ERR_OR_ZERO(__force const void *ptr)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void up_read(struct rw_semaphore *sem)
|
||||
|
@ -111,14 +111,17 @@ LX_MUTEX_INIT_DECLARE(component_mutex);
|
||||
** asm-generic/io.h **
|
||||
**********************/
|
||||
|
||||
#include <lx_emul/mmio.h>
|
||||
|
||||
|
||||
static inline u32 __raw_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(const volatile u32 __force *) addr;
|
||||
return readl(addr);
|
||||
}
|
||||
|
||||
static inline void __raw_writel(u32 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(volatile u32 __force *) addr = b;
|
||||
writel(b, addr);
|
||||
}
|
||||
|
||||
|
||||
@ -756,6 +759,13 @@ enum rpm_status {
|
||||
RPM_SUSPENDED,
|
||||
};
|
||||
|
||||
#define pm_generic_suspend NULL
|
||||
#define pm_generic_resume NULL
|
||||
#define pm_generic_freeze NULL
|
||||
#define pm_generic_thaw NULL
|
||||
#define pm_generic_poweroff NULL
|
||||
#define pm_generic_restore NULL
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/pm_domain.h **
|
||||
@ -784,6 +794,7 @@ struct bus_type
|
||||
const char *name;
|
||||
|
||||
int (*match)(struct device *dev, struct device_driver *drv);
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
int (*probe)(struct device *dev);
|
||||
int (*remove)(struct device *dev);
|
||||
void (*shutdown)(struct device *dev);
|
||||
@ -855,8 +866,12 @@ struct device_attribute {
|
||||
#define dev_printk(level, dev, format, arg...) \
|
||||
lx_printf("dev_printk: " format , ## arg)
|
||||
|
||||
#if DEBUG_DRIVER
|
||||
#define dev_dbg(dev, format, arg...) \
|
||||
lx_printf("dev_dbg: " format, ## arg)
|
||||
#else
|
||||
#define dev_dbg(dev, format, arg...)
|
||||
#endif
|
||||
|
||||
#define dev_err_ratelimited(dev, fmt, ...) \
|
||||
dev_err(dev, fmt, ##__VA_ARGS__)
|
||||
@ -869,7 +884,10 @@ struct device_driver
|
||||
const struct of_device_id *of_match_table;
|
||||
const struct acpi_device_id *acpi_match_table;
|
||||
const struct dev_pm_ops *pm;
|
||||
int (*probe) (struct device *dev);
|
||||
|
||||
int (*probe) (struct device *dev);
|
||||
int (*remove) (struct device *dev);
|
||||
void (*shutdown) (struct device *dev);
|
||||
};
|
||||
|
||||
int driver_register(struct device_driver *drv);
|
||||
@ -899,9 +917,15 @@ int device_add(struct device *dev);
|
||||
|
||||
int device_register(struct device *dev);
|
||||
void device_unregister(struct device *dev);
|
||||
void device_initialize(struct device *dev);
|
||||
|
||||
|
||||
|
||||
const char *dev_name(const struct device *dev);
|
||||
|
||||
struct device *bus_find_device(struct bus_type *bus, struct device *start, void *data,
|
||||
int (*match)(struct device *dev, void *data));
|
||||
|
||||
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
|
||||
void *data, int (*fn)(struct device_driver *, void *));
|
||||
|
||||
@ -913,6 +937,7 @@ struct acpi_device;
|
||||
|
||||
void devm_kfree(struct device *dev, void *p);
|
||||
void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
|
||||
void *devm_kcalloc(struct device *dev, size_t n, size_t size, gfp_t flags);
|
||||
|
||||
typedef void (*dr_release_t)(struct device *dev, void *res);
|
||||
typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data);
|
||||
@ -931,6 +956,9 @@ void *devres_open_group(struct device *dev, void *id, gfp_t gfp);
|
||||
int devres_release_group(struct device *dev, void *id);
|
||||
void devres_remove_group(struct device *dev, void *id);
|
||||
|
||||
void *devres_find(struct device *dev, dr_release_t release,
|
||||
dr_match_t match, void *match_data);
|
||||
|
||||
int dev_to_node(struct device *dev);
|
||||
|
||||
|
||||
@ -938,9 +966,6 @@ int dev_to_node(struct device *dev);
|
||||
** linux/io.h **
|
||||
****************/
|
||||
|
||||
#define writel(value, addr) (*(volatile uint32_t *)(addr) = (value))
|
||||
#define readl(addr) (*(volatile uint32_t *)(addr))
|
||||
|
||||
#define readl_relaxed readl
|
||||
#define writel_relaxed(v, a) writel(v, a)
|
||||
|
||||
@ -1163,6 +1188,13 @@ extern struct page *shmem_read_mapping_page( struct address_space *mapping, pgof
|
||||
struct file *shmem_file_setup(const char *, loff_t, unsigned long);
|
||||
|
||||
|
||||
/********************************
|
||||
** linux/unaligned/generic.h **
|
||||
********************************/
|
||||
|
||||
u32 get_unaligned_le32(const void *p);
|
||||
|
||||
|
||||
/*****************
|
||||
** linux/i2c.h **
|
||||
*****************/
|
||||
@ -1170,10 +1202,23 @@ struct file *shmem_file_setup(const char *, loff_t, unsigned long);
|
||||
enum i2c_slave_event { DUMMY };
|
||||
|
||||
|
||||
/***********************
|
||||
** uapi/linux/uuid.h **
|
||||
***********************/
|
||||
|
||||
typedef struct {
|
||||
__u8 b[16];
|
||||
} uuid_le;
|
||||
|
||||
|
||||
/****************
|
||||
** linux/of.h **
|
||||
****************/
|
||||
|
||||
struct of_phandle_args;
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
||||
int of_alias_get_id(struct device_node *np, const char *stem);
|
||||
struct device_node *of_node_get(struct device_node *node);
|
||||
void of_node_put(struct device_node *);
|
||||
@ -1187,6 +1232,10 @@ int of_property_read_u32_index(const struct device_node *, const char *, u32,
|
||||
for (child = of_get_next_child(parent, NULL); child != NULL; \
|
||||
child = of_get_next_child(parent, child))
|
||||
|
||||
#define for_each_available_child_of_node(parent, child) \
|
||||
for (child = of_get_next_child(parent, NULL); child != NULL; \
|
||||
child = of_get_next_child(parent, child))
|
||||
|
||||
struct property {
|
||||
const char * name;
|
||||
void * value;
|
||||
@ -1216,6 +1265,10 @@ int of_property_read_string(const struct device_node *np, const char *propname,
|
||||
const char **out_string);
|
||||
int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value);
|
||||
|
||||
struct property *of_find_property(const struct device_node *np,
|
||||
const char *name, int *lenp);
|
||||
int of_modalias_node(struct device_node *node, char *modalias, int len);
|
||||
|
||||
bool is_of_node(const struct fwnode_handle *fwnode);
|
||||
|
||||
#define to_of_node(__fwnode) \
|
||||
@ -1228,6 +1281,9 @@ bool is_of_node(const struct fwnode_handle *fwnode);
|
||||
NULL; \
|
||||
})
|
||||
|
||||
struct device_node *of_get_child_by_name(const struct device_node *node,
|
||||
const char *name);
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/of_device.h **
|
||||
@ -1238,6 +1294,28 @@ const void *of_device_get_match_data(const struct device *dev);
|
||||
const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
const struct device *dev);
|
||||
|
||||
int of_driver_match_device(struct device *dev, const struct device_driver *drv);
|
||||
|
||||
int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
|
||||
|
||||
|
||||
/**************************
|
||||
** linux/of_videomode.h **
|
||||
**************************/
|
||||
|
||||
struct videomode;
|
||||
|
||||
int of_get_videomode(struct device_node *np, struct videomode *vm, int index);
|
||||
|
||||
|
||||
/***********************
|
||||
** video/videomode.h **
|
||||
***********************/
|
||||
|
||||
struct display_timing;
|
||||
|
||||
void videomode_from_timing(const struct display_timing *dt, struct videomode *vm);
|
||||
|
||||
|
||||
/******************
|
||||
** linux/acpi.h **
|
||||
@ -1284,6 +1362,51 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
|
||||
void gpio_set_value(unsigned int gpio, int value);
|
||||
|
||||
|
||||
/***************************
|
||||
** linux/gpio/consumer.h **
|
||||
***************************/
|
||||
|
||||
#define GPIOD_FLAGS_BIT_DIR_SET BIT(0)
|
||||
#define GPIOD_FLAGS_BIT_DIR_OUT BIT(1)
|
||||
#define GPIOD_FLAGS_BIT_DIR_VAL BIT(2)
|
||||
|
||||
enum gpiod_flags {
|
||||
GPIOD_OUT_HIGH = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT |
|
||||
GPIOD_FLAGS_BIT_DIR_VAL
|
||||
};
|
||||
|
||||
struct gpio_desc
|
||||
{
|
||||
u32 pin;
|
||||
};
|
||||
|
||||
struct gpio_desc *
|
||||
devm_gpiod_get(struct device *dev, const char *con_id, enum gpiod_flags flags);
|
||||
|
||||
void gpiod_set_value(struct gpio_desc *desc, int value);
|
||||
|
||||
|
||||
/********************
|
||||
** linux/regmap.h **
|
||||
********************/
|
||||
|
||||
struct regmap
|
||||
{
|
||||
u8 *base;
|
||||
};
|
||||
|
||||
int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
|
||||
|
||||
int regmap_update_bits(struct regmap *map, unsigned reg, unsigned mask,
|
||||
unsigned val);
|
||||
|
||||
/************************
|
||||
** linux/mfd/syscon.h **
|
||||
************************/
|
||||
|
||||
struct regmap *syscon_regmap_lookup_by_phandle( struct device_node *np, const char *property);
|
||||
|
||||
|
||||
/* needed by drivers/gpu/drm/drm_modes.c */
|
||||
#include <linux/list_sort.h>
|
||||
|
||||
@ -1544,6 +1667,58 @@ int device_property_read_u32(struct device *, const char *, u32 *);
|
||||
void call_rcu(struct rcu_head *, void (*)(struct rcu_head *));
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/backlight.h **
|
||||
***********************/
|
||||
|
||||
enum backlight_type {
|
||||
BACKLIGHT_RAW = 1,
|
||||
};
|
||||
|
||||
struct backlight_properties
|
||||
{
|
||||
int brightness;
|
||||
int max_brightness;
|
||||
enum backlight_type type;
|
||||
};
|
||||
|
||||
struct backlight_ops;
|
||||
|
||||
struct backlight_device
|
||||
{
|
||||
struct backlight_properties props;
|
||||
struct backlight_ops const *ops;
|
||||
struct device dev;
|
||||
};
|
||||
|
||||
struct backlight_ops {
|
||||
int (*update_status)(struct backlight_device *);
|
||||
int (*get_brightness)(struct backlight_device *);
|
||||
};
|
||||
|
||||
int backlight_enable(struct backlight_device *bd);
|
||||
int backlight_disable(struct backlight_device *bd);
|
||||
|
||||
void *bl_get_data(struct backlight_device *bl_dev);
|
||||
|
||||
struct backlight_device *
|
||||
devm_backlight_device_register(struct device *dev, const char *name,
|
||||
struct device *parent, void *devdata,
|
||||
const struct backlight_ops *ops,
|
||||
const struct backlight_properties *props);
|
||||
|
||||
/****************************
|
||||
** drivers/phy/phy-core.c **
|
||||
****************************/
|
||||
|
||||
void devm_phy_consume(struct device *dev, void *res);
|
||||
|
||||
/***********************
|
||||
** linux/backlight.h **
|
||||
***********************/
|
||||
|
||||
struct drm_panel;
|
||||
|
||||
/************************
|
||||
** drm/drm_os_linux.h **
|
||||
************************/
|
||||
@ -1622,7 +1797,9 @@ static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
|
||||
#define CONFIG_MMU 1
|
||||
#define CONFIG_OF 1
|
||||
#define CONFIG_VIDEOMODE_HELPERS 1
|
||||
|
||||
#define CONFIG_PHY_MIXEL_MIPI_DSI 1
|
||||
#define CONFIG_GENERIC_PHY 1
|
||||
#define CONFIG_DRM_PANEL 1
|
||||
|
||||
/**************************
|
||||
** Dummy trace funtions **
|
||||
@ -1653,6 +1830,7 @@ void enable_irq(unsigned int);
|
||||
void disable_irq(unsigned int);
|
||||
int disable_irq_nosync(unsigned int);
|
||||
|
||||
void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
|
||||
|
||||
/*****************************
|
||||
** linux/platform_device.h **
|
||||
@ -1704,30 +1882,32 @@ struct platform_driver {
|
||||
int platform_driver_register(struct platform_driver *);
|
||||
void platform_driver_unregister(struct platform_driver *);
|
||||
|
||||
#ifndef MOD_SUFFIX
|
||||
#define MOD_SUFFIX
|
||||
#endif
|
||||
|
||||
#define _MOD_CONCAT(a,b,c) a##b##c
|
||||
#define MOD_CONCAT(a,b,c) _MOD_CONCAT(a,b,c)
|
||||
|
||||
#define module_driver(__driver, __register, __unregister, ...) \
|
||||
static int __init __driver##_init(void) \
|
||||
static int __init MOD_CONCAT(__driver, MOD_SUFFIX, _init)(void) \
|
||||
{ \
|
||||
return __register(&(__driver) , ##__VA_ARGS__); \
|
||||
} \
|
||||
module_init(__driver##_init); \
|
||||
static void __exit __driver##_exit(void) \
|
||||
int MOD_CONCAT(module_##__driver, MOD_SUFFIX, _init)() { \
|
||||
return MOD_CONCAT(__driver, MOD_SUFFIX, _init)(); } \
|
||||
static void __exit MOD_CONCAT(__driver, MOD_SUFFIX, _exit)(void) \
|
||||
{ \
|
||||
__unregister(&(__driver) , ##__VA_ARGS__); \
|
||||
} \
|
||||
module_exit(__driver##_exit);
|
||||
void MOD_CONCAT(module_exit_##__driver, MOD_SUFFIX, _exit)() { \
|
||||
MOD_CONCAT(__driver, MOD_SUFFIX, _exit)(); }
|
||||
|
||||
|
||||
#define module_platform_driver(__platform_driver) \
|
||||
module_driver(__platform_driver, platform_driver_register, \
|
||||
platform_driver_unregister)
|
||||
|
||||
/***********************
|
||||
** uapi/linux/uuid.h **
|
||||
***********************/
|
||||
|
||||
typedef struct {
|
||||
__u8 b[16];
|
||||
} uuid_le;
|
||||
|
||||
|
||||
/************************
|
||||
** linux/cpuhotplug.h **
|
||||
@ -1743,7 +1923,8 @@ enum cpuhp_state {
|
||||
*******************/
|
||||
|
||||
enum {
|
||||
SZ_4K = 0x00001000,
|
||||
SZ_256 = 0x00000100,
|
||||
SZ_4K = 0x00001000,
|
||||
SZ_16K = 0x00004000,
|
||||
};
|
||||
|
||||
@ -1763,11 +1944,27 @@ enum {
|
||||
IOMEM_END_HDMI_CRS = 0x33ffff,
|
||||
IOMEM_BASE_HDMI_RST = 0x340000,
|
||||
IOMEM_END_HDMI_RST = 0x34000f,
|
||||
IOMEM_BASE_MIPI_DSI = 0x400000,
|
||||
IOMEM_BASE_MIPI_DPHY = 0x400300,
|
||||
IOMEM_END_MIPI_DSI = 0x400fff,
|
||||
IRQ_IRQSTEER = 32,
|
||||
IRQ_HDMI_IN = 33,
|
||||
IRQ_HDMI_OUT = 34
|
||||
IRQ_HDMI_OUT = 34,
|
||||
IRQ_MIPI_DSI = 35,
|
||||
IOMEM_BASE_SRC = 0x410000,
|
||||
IOMEM_END_SRC = 0xf1ffff,
|
||||
};
|
||||
|
||||
|
||||
/************************************
|
||||
** drivers/gpu/drm/drm_mipi_dsi.c **
|
||||
************************************/
|
||||
|
||||
//XXX: init in startup code before drm_mipi_dsi.c
|
||||
LX_MUTEX_INIT_DECLARE(host_lock);
|
||||
|
||||
#define host_lock LX_MUTEX(host_lock)
|
||||
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#endif /* _LX_EMUL_H_ */
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#define TRACE_AND_STOP \
|
||||
do { \
|
||||
lx_printf("%s not implemented\n", __func__); \
|
||||
lx_printf("%s not implemented called from %p\n", __func__, __builtin_return_address(0)); \
|
||||
BUG(); \
|
||||
} while (0)
|
||||
|
||||
|
@ -30,9 +30,12 @@
|
||||
#include <drm/drm_gem_cma_helper.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_of.h>
|
||||
#include <drm/drm_panel.h>
|
||||
#include "drm_crtc_internal.h"
|
||||
#include "drm_internal.h"
|
||||
#include <linux/component.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <video/videomode.h>
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#include <lx_kit/scheduler.h> /* dependency of lx_emul/impl/completion.h */
|
||||
@ -52,8 +55,7 @@
|
||||
#include <lx_kit/irq.h>
|
||||
#include <lx_kit/malloc.h>
|
||||
|
||||
|
||||
enum Device_id { DCSS, HDMI, UNKNOWN };
|
||||
enum Device_id { DCSS, HDMI, MIPI, SRC, UNKNOWN };
|
||||
|
||||
namespace Lx_kit {
|
||||
Platform::Connection & platform_connection();
|
||||
@ -84,6 +86,24 @@ Platform::Device_client & Lx_kit::platform_device(Device_id id)
|
||||
return hdmi;
|
||||
}
|
||||
|
||||
if (id == MIPI) {
|
||||
static Platform::Device_client mipi {
|
||||
platform_connection().device_by_property("compatible",
|
||||
"fsl,imx8mq-mipi-dsi_drm") };
|
||||
static bool update = true;
|
||||
if (update) {
|
||||
platform_connection().update();
|
||||
update = false;
|
||||
}
|
||||
return mipi;
|
||||
}
|
||||
|
||||
if (id == SRC){
|
||||
static Platform::Device_client src {
|
||||
platform_connection().acquire_device("src") };
|
||||
return src;
|
||||
}
|
||||
|
||||
throw 1;
|
||||
}
|
||||
|
||||
@ -151,6 +171,9 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
|
||||
return r;
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error("RESOURCE: ", name, " not found");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -160,7 +183,6 @@ static int platform_match(struct device *dev, struct device_driver *drv)
|
||||
if (!dev->name)
|
||||
return 0;
|
||||
|
||||
printk("MATCH %s %s\n", dev->name, drv->name);
|
||||
return (Genode::strcmp(dev->name, drv->name) == 0);
|
||||
}
|
||||
|
||||
@ -220,7 +242,9 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
|
||||
|
||||
int platform_device_register(struct platform_device *pdev)
|
||||
{
|
||||
pdev->dev.bus = &platform_bus_type;
|
||||
if (pdev->dev.bus == nullptr)
|
||||
pdev->dev.bus = &platform_bus_type;
|
||||
|
||||
pdev->dev.name = pdev->name;
|
||||
/*Set parent to ourselfs */
|
||||
if (!pdev->dev.parent)
|
||||
@ -273,12 +297,20 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::warning(__func__, "() not implemented");
|
||||
|
||||
|
||||
if (!clk) return -1;
|
||||
clk->rate = rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int clk_prepare_enable(struct clk *clk)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
** drivers/clk/clk-devres.c **
|
||||
******************************/
|
||||
@ -291,6 +323,7 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
|
||||
const char * clock_name = id;
|
||||
if (String<32>("ipg") == id) { clock_name = "apb"; }
|
||||
if (String<32>("tx_esc") == id) { clock_name = "rx_esc"; }
|
||||
|
||||
unsigned long rate = 0;
|
||||
Lx_kit::platform_connection().with_xml([&] (Xml_node node) {
|
||||
@ -303,11 +336,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
});
|
||||
});
|
||||
|
||||
if (!rate) return nullptr;
|
||||
if (!rate) {
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, " clock not found ", id);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct clk * clock = (struct clk*) kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
clock->name = id;
|
||||
clock->rate = rate;
|
||||
|
||||
if (String<32>("tx_esc") == id)
|
||||
clock->rate /= 4;
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
@ -399,7 +440,24 @@ static struct device_node endpoint_device_node {
|
||||
|
||||
static struct device_node port_device_node {
|
||||
.name = "port",
|
||||
.full_name = "port"
|
||||
.full_name = "port",
|
||||
};
|
||||
|
||||
static struct device_node mipi_endpoint_device_node {
|
||||
.name = "mipi-endpoint",
|
||||
.full_name = "mipi-endpoint",
|
||||
.parent = &root_device_node
|
||||
};
|
||||
|
||||
static struct device_node mipi_device_node {
|
||||
.name = "mipi_dsi",
|
||||
.full_name = "mipi_dsi",
|
||||
.parent = &root_device_node
|
||||
};
|
||||
|
||||
static struct device_node mipi_panel_node {
|
||||
.name = "panel",
|
||||
.full_name = "panel"
|
||||
};
|
||||
|
||||
int of_device_is_compatible(const struct device_node *device,
|
||||
@ -418,16 +476,58 @@ struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev)
|
||||
{
|
||||
if (Genode::strcmp(node->name, "port", strlen(node->name)) == 0) {
|
||||
if (!prev)
|
||||
return &hdmi_endpoint_device_node;
|
||||
return NULL;
|
||||
if (prev)
|
||||
return NULL;
|
||||
|
||||
if (port_device_node.parent == &mipi_device_node) {
|
||||
return &port_device_node;
|
||||
}
|
||||
|
||||
return &hdmi_endpoint_device_node;
|
||||
}
|
||||
|
||||
Genode::error("of_get_next_child(): unhandled node");
|
||||
if (Genode::strcmp(node->name, "mipi_dsi_bridge") == 0) {
|
||||
if (prev) return NULL;
|
||||
/* create panel device node */
|
||||
|
||||
device_node *np = &mipi_panel_node;
|
||||
np->properties = (property *)kzalloc(6*sizeof(property), 0);
|
||||
np->properties[0].name = "panel",
|
||||
np->properties[0].value = NULL,
|
||||
np->properties[0].next = &np->properties[1];
|
||||
np->properties[1].name = "reg";
|
||||
np->properties[1].value = 0;
|
||||
np->properties[1].next = &np->properties[2];
|
||||
np->properties[2].name = "compatible";
|
||||
np->properties[2].value = (void *)"raydium,rm67191";
|
||||
np->properties[2].next = &np->properties[3];
|
||||
np->properties[3].name = "dsi-lanes";
|
||||
np->properties[3].value = (void *)4;
|
||||
np->properties[3].next = &np->properties[4];
|
||||
np->properties[4].name = "panel-width-mm";
|
||||
np->properties[4].value = (void *)68;
|
||||
np->properties[4].next = &np->properties[5];
|
||||
np->properties[5].name = "panel-height-mm";
|
||||
np->properties[5].value = (void *)121;
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error("of_get_next_child(): unhandled node");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct device_node *of_get_child_by_name(const struct device_node *node,
|
||||
const char *name)
|
||||
{
|
||||
if (Genode::strcmp(name, "display-timings") == 0)
|
||||
return (device_node *)1;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct device_node *of_get_parent(const struct device_node *node)
|
||||
{
|
||||
static device_node dcss_device_node { "dcss", "dcss" };
|
||||
@ -437,21 +537,37 @@ struct device_node *of_get_parent(const struct device_node *node)
|
||||
|
||||
if (Genode::strcmp(node->name, "port", strlen("port")) == 0)
|
||||
return &dcss_device_node;
|
||||
|
||||
Genode::error("of_get_parent(): unhandled node");
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error("of_get_parent(): unhandled node");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void *of_get_property(const struct device_node *node, const char *name, int *lenp)
|
||||
{
|
||||
for (property * p = node ? node->properties : nullptr; p; p = p->next)
|
||||
if (Genode::strcmp(name, p->name) == 0) return p->value;
|
||||
*lenp = 0;
|
||||
for (property * p = node ? node->properties : nullptr; p; p = p->next) {
|
||||
if (!p) break;
|
||||
if (Genode::strcmp(name, p->name) == 0) {
|
||||
*lenp = sizeof(void *);
|
||||
return p->value;
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER) Genode::warning("OF property ", name, " not found");
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::warning("OF property ", name, " not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
int of_alias_get_id(struct device_node *np, const char *stem)
|
||||
{
|
||||
int len = 0;
|
||||
return (long)of_get_property(np, stem, &len);
|
||||
}
|
||||
|
||||
|
||||
struct device_node *of_parse_phandle(const struct device_node *np, const char *phandle_name, int index)
|
||||
{
|
||||
/* device node information from fsl-imx8mq.dtsi */
|
||||
@ -478,6 +594,50 @@ struct device_node *of_parse_phandle(const struct device_node *np, const char *p
|
||||
}
|
||||
|
||||
|
||||
struct property *of_find_property(const struct device_node *np,
|
||||
const char *name, int *lenp)
|
||||
{
|
||||
TRACE;
|
||||
return np->properties;
|
||||
}
|
||||
|
||||
|
||||
int of_modalias_node(struct device_node *node, char *modalias, int len)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
** linux/of_videomode.h **
|
||||
**************************/
|
||||
|
||||
int of_get_videomode(struct device_node *np, struct videomode *vm, int index)
|
||||
{
|
||||
/* taken from device tree */
|
||||
if (Genode::strcmp(np->name, "panel") == 0) {
|
||||
vm->pixelclock = 0x7de2900;
|
||||
vm->hactive = 0x438;
|
||||
vm->hfront_porch = 0x14;
|
||||
vm->hback_porch = 0x22;
|
||||
vm->hsync_len = 0x2;
|
||||
|
||||
vm->vactive = 0x780;
|
||||
vm->vfront_porch = 0x1e;
|
||||
vm->vback_porch = 0x4;
|
||||
vm->vsync_len = 0x2;
|
||||
|
||||
vm->flags = (display_flags)0x1095;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************
|
||||
** drivers/of/device.c **
|
||||
*************************/
|
||||
@ -495,7 +655,8 @@ const void *of_device_get_match_data(const struct device *dev)
|
||||
const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
const struct device *dev)
|
||||
{
|
||||
const char * compatible = (const char*) of_get_property(dev->of_node, "compatible", 0);
|
||||
int len = 0;
|
||||
const char * compatible = (const char*) of_get_property(dev->of_node, "compatible", &len);
|
||||
|
||||
for (; matches && matches->compatible[0]; matches++) {
|
||||
if (Genode::strcmp(matches->compatible, compatible) == 0)
|
||||
@ -505,6 +666,15 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
}
|
||||
|
||||
|
||||
int of_driver_match_device(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
if (of_match_device(drv->of_match_table, dev))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** drivers/of/property.c **
|
||||
***************************/
|
||||
@ -520,7 +690,16 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Genode::error(__func__, "(): unhandled parent");
|
||||
if(Genode::strcmp(parent->name, "mipi_dsi", strlen(parent->name)) == 0) {
|
||||
|
||||
if (!prev)
|
||||
return &mipi_endpoint_device_node;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): unhandled parent '", parent->name, "'");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -531,7 +710,8 @@ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
|
||||
(id == 0))
|
||||
return &port_device_node;
|
||||
|
||||
Genode::error("of_graph_get_port_by_id(): unhandled parent or id\n");
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error("of_graph_get_port_by_id(): unhandled parent or id\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -541,7 +721,12 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
|
||||
if (Genode::strcmp(node->name, "endpoint", strlen(node->name)) == 0)
|
||||
return &port_device_node;
|
||||
|
||||
Genode::error("of_graph_get_remote_port(): unhandled node\n");
|
||||
if (Genode::strcmp(node->name, "mipi-endpoint", strlen(node->name)) == 0) {
|
||||
return &port_device_node;
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error("of_graph_get_remote_port(): unhandled node '", node->name, "'\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -551,7 +736,18 @@ struct device_node *of_graph_get_remote_port_parent(const struct device_node *no
|
||||
if (Genode::strcmp(node->name, "hdmi-endpoint") == 0)
|
||||
return &hdmi_device_node;
|
||||
|
||||
Genode::error("of_graph_get_remote_port_parent(): unhandled node");
|
||||
if (Genode::strcmp(node->name, "mipi-endpoint") == 0) {
|
||||
|
||||
int len;
|
||||
void const *np = of_get_property(&mipi_endpoint_device_node, "mipi_dsi_bridge_np", &len);
|
||||
return (device_node *)np;
|
||||
}
|
||||
|
||||
if (Genode::strcmp(node->name, "port") == 0)
|
||||
return &mipi_device_node;
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error("of_graph_get_remote_port_parent(): unhandled node: ", node->name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -630,7 +826,7 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
|
||||
case IRQ_IRQSTEER: id = DCSS; break;
|
||||
case IRQ_HDMI_IN: id = HDMI; break;
|
||||
case IRQ_HDMI_OUT: id = HDMI; off = 1; break;
|
||||
default: ;
|
||||
default: Genode::error(__func__, " IRQ: ", irq, " not found");
|
||||
};
|
||||
|
||||
Lx::Irq::irq().request_irq(Lx_kit::platform_device(id).irq(off),
|
||||
@ -786,7 +982,30 @@ static void *_ioremap(phys_addr_t phys_addr, unsigned long size, int wc)
|
||||
};
|
||||
};
|
||||
|
||||
panic("Failed to request I/O memory: [%lx,%lx)",
|
||||
if (phys_addr >= IOMEM_BASE_MIPI_DSI &&
|
||||
(phys_addr+size-1) <= IOMEM_END_MIPI_DSI) {
|
||||
|
||||
/*
|
||||
* Set parent of 'port' to 'mipi_dsi' in order to distinguish between HDMI
|
||||
* and MIPI
|
||||
*/
|
||||
port_device_node.parent = &mipi_device_node;
|
||||
|
||||
static Attached_dataspace ds {
|
||||
rm, Lx_kit::platform_device(MIPI).io_mem_dataspace(0) };
|
||||
addr_t off = phys_addr - IOMEM_BASE_MIPI_DSI;
|
||||
|
||||
return (void*)(((addr_t)ds.local_addr<void>()) + off);
|
||||
}
|
||||
|
||||
if (phys_addr >= IOMEM_BASE_SRC &&
|
||||
(phys_addr+size-1) <= IOMEM_END_SRC) {
|
||||
static Attached_dataspace ds {
|
||||
rm, Lx_kit::platform_device(SRC).io_mem_dataspace(0) };
|
||||
return ds.local_addr<void>();
|
||||
}
|
||||
|
||||
panic("Failed to request I/O memory: [%lx,%lx)\n",
|
||||
phys_addr, phys_addr + size);
|
||||
return nullptr;
|
||||
}
|
||||
@ -803,6 +1022,46 @@ void *devm_ioremap_resource(struct device *dev, struct resource *res)
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
** linux/mfd/syscon.h **
|
||||
************************/
|
||||
|
||||
struct regmap *syscon_regmap_lookup_by_phandle( struct device_node *np, const char *property)
|
||||
{
|
||||
bool src = strcmp(property, "src") == 0;
|
||||
|
||||
if (!src) {
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::warning(__func__, " property '", property, "' not found.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmap *map = (regmap *)kzalloc(sizeof(regmap), GFP_KERNEL);
|
||||
map->base = (u8 *)_ioremap(IOMEM_BASE_SRC, 0x10000, 0);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/regmap.h **
|
||||
********************/
|
||||
|
||||
int regmap_update_bits(struct regmap *map, unsigned reg, unsigned mask,
|
||||
unsigned val)
|
||||
{
|
||||
if (map == nullptr) return 0;
|
||||
|
||||
unsigned volatile current = *((unsigned *)(map->base + reg));
|
||||
|
||||
current &= ~mask;
|
||||
current |= val;
|
||||
*((volatile unsigned *)(map->base + reg)) = current;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************
|
||||
** lib/string.c **
|
||||
******************/
|
||||
@ -832,7 +1091,7 @@ void reinit_completion(struct completion *work)
|
||||
*/
|
||||
class Driver : public Genode::List<Driver>::Element
|
||||
{
|
||||
private:
|
||||
public:
|
||||
|
||||
struct device_driver *_drv; /* Linux driver */
|
||||
|
||||
@ -897,17 +1156,36 @@ int device_add(struct device *dev)
|
||||
return 0;
|
||||
|
||||
/* foreach driver match and probe device */
|
||||
for (Driver *driver = Driver::list()->first(); driver; driver = driver->next())
|
||||
for (Driver *driver = Driver::list()->first(); driver; driver = driver->next()) {
|
||||
if (driver->match(dev)) {
|
||||
int ret = driver->probe(dev);
|
||||
|
||||
if (!ret) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bus_type *_bus = nullptr;
|
||||
|
||||
int bus_register(struct bus_type *bus)
|
||||
{
|
||||
if (_bus) {
|
||||
Genode::error(__func__, " called twice, implement list");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
_bus = bus;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *devm_kcalloc(struct device * /* dev */, size_t n, size_t size, gfp_t flags)
|
||||
{
|
||||
return kcalloc(n, size, flags);
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** linux/dma-mapping.h **
|
||||
@ -974,7 +1252,8 @@ int devm_request_irq(struct device *dev, unsigned int irq,
|
||||
case IRQ_IRQSTEER: id = DCSS; break;
|
||||
case IRQ_HDMI_IN: id = HDMI; break;
|
||||
case IRQ_HDMI_OUT: id = HDMI; off = 1; break;
|
||||
default: ;
|
||||
case IRQ_MIPI_DSI: id = MIPI; break;
|
||||
default: Genode::error(__func__, " IRQ: ", irq, " not found");
|
||||
};
|
||||
Lx::Irq::irq().request_irq(Lx_kit::platform_device(id).irq(off),
|
||||
irq, handler, dev_id);
|
||||
@ -1008,14 +1287,41 @@ bool of_property_read_bool(const struct device_node *np, const char *propname)
|
||||
(Genode::strcmp(propname, "fsl,no_edid", strlen(np->name)) == 0))
|
||||
return false;
|
||||
|
||||
Genode::error(__func__, "(): unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): hdmi unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Genode::error(__func__, "(): unhandled device '", Genode::Cstring(np->name),
|
||||
"' (property: '", Genode::Cstring(propname), "')");
|
||||
if ((Genode::strcmp(np->name, "mipi_dsi_bridge") == 0)) {
|
||||
if (Genode::strcmp(propname, "no_clk_reset") == 0) {
|
||||
/* set np in bridge endpoint */
|
||||
mipi_endpoint_device_node.properties = (property*)kzalloc(sizeof(property), 0);
|
||||
mipi_endpoint_device_node.properties->name = "mipi_dsi_bridge_np";
|
||||
mipi_endpoint_device_node.properties->value = (void *)np;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): mipi_dsi_bridge unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Genode::strcmp(np->name, "mipi_dsi") == 0) {
|
||||
if (Genode::strcmp(propname, "no_clk_reset") == 0)
|
||||
return true;
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): mipi_dsi unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): unhandled device '", Genode::Cstring(np->name),
|
||||
"' (property: '", Genode::Cstring(propname), "')");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -1030,13 +1336,15 @@ int of_property_read_string(const struct device_node *np, const char *propname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
Genode::error(__func__, "(): unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::error(__func__, "(): unhandled device '", Genode::Cstring(np->name),
|
||||
"' (property: '", Genode::Cstring(propname), "')");
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): unhandled device '", Genode::Cstring(np->name),
|
||||
"' (property: '", Genode::Cstring(propname), "')");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1056,8 +1364,9 @@ int of_property_read_u32(const struct device_node *np, const char *propname, u32
|
||||
return 0;
|
||||
}
|
||||
|
||||
Genode::error(__func__, "(): unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
return -1;
|
||||
|
||||
} else if (Genode::strcmp(np->name, "hdmi", strlen(np->name)) == 0) {
|
||||
@ -1067,13 +1376,23 @@ int of_property_read_u32(const struct device_node *np, const char *propname, u32
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::error(__func__, "(): unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): unhandled property '", propname,
|
||||
"' of device '", Genode::Cstring(np->name), "'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::error(__func__, "(): unhandled device '", Genode::Cstring(np->name),
|
||||
"' (property: '", Genode::Cstring(propname), "')");
|
||||
int len = 0;
|
||||
void const *value = of_get_property(np, propname, &len);
|
||||
if (len > 0) {
|
||||
*out_value = (unsigned long)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (DEBUG_DRIVER)
|
||||
Genode::error(__func__, "(): unhandled device '", Genode::Cstring(np->name),
|
||||
"' (property: '", Genode::Cstring(propname), "')");
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -1310,7 +1629,6 @@ void Framebuffer::Driver::generate_report()
|
||||
xml.attribute("connected", connected);
|
||||
|
||||
if (!connected) return;
|
||||
|
||||
struct drm_display_mode *mode;
|
||||
list_for_each_entry(mode, &c->modes, head) {
|
||||
xml.node("mode", [&] ()
|
||||
@ -1722,6 +2040,172 @@ unsigned int kref_read(const struct kref *kref)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************
|
||||
** drivers/phy/phy-core.c **
|
||||
****************************/
|
||||
|
||||
void devm_phy_consume(struct device *dev, void *res)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
struct phy_ops;
|
||||
struct phy *devm_phy_create(struct device *dev,
|
||||
struct device_node *node,
|
||||
const struct phy_ops *ops)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
phy **ptr = (phy**)devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL);
|
||||
phy *p = (phy *)kzalloc(sizeof(phy), GFP_KERNEL);
|
||||
|
||||
p->dev.of_node = node;
|
||||
p->ops = ops;
|
||||
p->dev.parent = dev;
|
||||
|
||||
*ptr = p;
|
||||
devres_add(dev, ptr);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
struct phy *devm_phy_get(struct device *dev, const char *string)
|
||||
{
|
||||
int len = 0;
|
||||
void const *phy = of_get_property(dev->of_node, string, &len);
|
||||
return (struct phy *)phy;
|
||||
}
|
||||
|
||||
|
||||
int phy_init(struct phy *phy)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
if (phy && phy->ops->init) {
|
||||
|
||||
int ret = phy->ops->init(phy);
|
||||
if (ret)
|
||||
Genode::error(__func__, " failed (err: ", ret, ")");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int phy_power_on(struct phy *phy)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
if (phy && phy->ops->power_on) {
|
||||
|
||||
int ret = phy->ops->power_on(phy);
|
||||
if (ret)
|
||||
Genode::error(__func__, " failed (err: ", ret, ")");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************
|
||||
** linux/backlight.h **
|
||||
***********************/
|
||||
|
||||
|
||||
struct backlight_device *
|
||||
devm_backlight_device_register(struct device *dev, const char *name,
|
||||
struct device *parent, void *devdata,
|
||||
const struct backlight_ops *ops,
|
||||
const struct backlight_properties *props)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
backlight_device *backlight = (backlight_device *)kzalloc(sizeof(backlight_device), GFP_KERNEL);
|
||||
backlight->ops = ops;
|
||||
backlight->props = *props;
|
||||
dev_set_drvdata(&backlight->dev, devdata);
|
||||
|
||||
return backlight;
|
||||
}
|
||||
|
||||
|
||||
int backlight_enable(struct backlight_device *bd)
|
||||
{
|
||||
int ret = -ENOENT;
|
||||
|
||||
if (bd->ops && bd->ops->update_status)
|
||||
ret = bd->ops->update_status(bd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void *bl_get_data(struct backlight_device *bl_dev)
|
||||
{
|
||||
return dev_get_drvdata(&bl_dev->dev);
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** drm/drm_panel.h **
|
||||
*********************/
|
||||
|
||||
int drm_panel_add(struct drm_panel *panel)
|
||||
{
|
||||
device_node *np = &mipi_panel_node;
|
||||
|
||||
if (Genode::strcmp(np->properties[0].name, "panel") != 0) {
|
||||
Genode::error("panel property not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
np->properties[0].value = (void*)panel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
|
||||
{
|
||||
if (panel->connector)
|
||||
return -EBUSY;
|
||||
|
||||
panel->connector = connector;
|
||||
panel->drm = connector->dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct drm_panel *of_drm_find_panel(const struct device_node *np)
|
||||
{
|
||||
int len;
|
||||
return (drm_panel *)of_get_property(np, "panel", &len);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** linux/gpio/consumer.h **
|
||||
***************************/
|
||||
|
||||
struct gpio_desc *
|
||||
devm_gpiod_get(struct device *dev, const char *con_id, enum gpiod_flags flags)
|
||||
{
|
||||
TRACE;
|
||||
return (struct gpio_desc *)-EINVAL;
|
||||
}
|
||||
|
||||
void gpiod_set_value(struct gpio_desc *desc, int value)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
** Stubs for non-ported driver code **
|
||||
**************************************/
|
||||
|
@ -40,6 +40,11 @@ extern "C" int module_imx_drm_pdrv_init();
|
||||
extern "C" int module_dcss_driver_init();
|
||||
extern "C" int module_dcss_crtc_driver_init();
|
||||
extern "C" int module_imx_hdp_imx_platform_driver_init();
|
||||
extern "C" int module_mixel_mipi_phy_driver_init();
|
||||
extern "C" int module_imx_nwl_dsi_driver_bridge_init();
|
||||
extern "C" int module_imx_nwl_dsi_driver_init();
|
||||
extern "C" int module_rad_panel_driver_init();
|
||||
extern "C" void postcore_mipi_dsi_bus_init();
|
||||
|
||||
unsigned long jiffies;
|
||||
|
||||
@ -79,6 +84,32 @@ struct Framebuffer::Main
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
||||
bool _hdmi()
|
||||
{
|
||||
try {
|
||||
Xml_node config = _config.xml();
|
||||
Xml_node xn = config.sub_node();
|
||||
for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) {
|
||||
if (!xn.has_type("connector"))
|
||||
continue;
|
||||
|
||||
bool enabled = xn.attribute_value("enabled", true);
|
||||
if (!enabled)
|
||||
continue;
|
||||
|
||||
/* check first connector only */
|
||||
typedef String<64> Name;
|
||||
Name const con_policy = xn.attribute_value("name", Name());
|
||||
if (con_policy == "DSI-1")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (...) { }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
log("--- i.MX8 framebuffer driver ---");
|
||||
@ -88,6 +119,7 @@ struct Framebuffer::Main
|
||||
LX_MUTEX_INIT(bridge_lock);
|
||||
LX_MUTEX_INIT(core_lock);
|
||||
LX_MUTEX_INIT(component_mutex);
|
||||
LX_MUTEX_INIT(host_lock);
|
||||
|
||||
/* init singleton Lx::Scheduler */
|
||||
Lx::scheduler(&_env);
|
||||
@ -125,6 +157,13 @@ void Framebuffer::Main::_run_linux()
|
||||
module_dcss_crtc_driver_init();
|
||||
module_imx_hdp_imx_platform_driver_init();
|
||||
|
||||
/* MIPI DSI */
|
||||
module_mixel_mipi_phy_driver_init();
|
||||
module_imx_nwl_dsi_driver_bridge_init();
|
||||
module_imx_nwl_dsi_driver_init();
|
||||
postcore_mipi_dsi_bus_init();
|
||||
module_rad_panel_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
|
||||
@ -150,40 +189,6 @@ void Framebuffer::Main::_run_linux()
|
||||
platform_device_register(imx_irqsteer_pdev);
|
||||
|
||||
|
||||
/**
|
||||
* This device is originally created with the name '32e00000.dcss'
|
||||
* via 'of_platform_bus_create()'. Here it is called 'dcss-core' to match
|
||||
* the driver name.
|
||||
*/
|
||||
|
||||
struct platform_device *dcss_pdev =
|
||||
platform_device_alloc("dcss-core", 0);
|
||||
|
||||
static resource dcss_resources[] = {
|
||||
{ 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;
|
||||
dcss_pdev->resource = dcss_resources;
|
||||
|
||||
dcss_pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
||||
dcss_pdev->dev.of_node->name = "dcss";
|
||||
dcss_pdev->dev.of_node->full_name = "dcss";
|
||||
dcss_pdev->dev.of_node->properties = (property*)kzalloc(sizeof(property), 0);
|
||||
dcss_pdev->dev.of_node->properties->name = "disp-dev";
|
||||
dcss_pdev->dev.of_node->properties->value = (void*)"hdmi_disp";
|
||||
|
||||
platform_device_register(dcss_pdev);
|
||||
|
||||
|
||||
/**
|
||||
* This device is originally created with the name '32c00000.hdmi'
|
||||
* via 'of_platform_bus_create()'. Here it is called 'i.mx8-hdp' to match
|
||||
@ -214,9 +219,90 @@ void Framebuffer::Main::_run_linux()
|
||||
hdp_pdev->dev.of_node->properties->name = "compatible";
|
||||
hdp_pdev->dev.of_node->properties->value = (void*)"fsl,imx8mq-hdmi";
|
||||
|
||||
platform_device_register(hdp_pdev);
|
||||
bool hdmi = _hdmi();
|
||||
if (hdmi)
|
||||
platform_device_register(hdp_pdev);
|
||||
|
||||
struct platform_device *mipi_dsi_phy_pdev =
|
||||
platform_device_alloc("mixel-mipi-dsi-phy", 0);
|
||||
|
||||
static resource mipi_dsi_phy_resources[] = {
|
||||
{ IOMEM_BASE_MIPI_DPHY, IOMEM_BASE_MIPI_DPHY+0xff, "dsi_phy", IORESOURCE_MEM }
|
||||
};
|
||||
|
||||
mipi_dsi_phy_pdev->num_resources = 1;
|
||||
mipi_dsi_phy_pdev->resource = mipi_dsi_phy_resources;
|
||||
|
||||
mipi_dsi_phy_pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
||||
mipi_dsi_phy_pdev->dev.of_node->properties = (property*)kzalloc(2*sizeof(property), 0);
|
||||
mipi_dsi_phy_pdev->dev.of_node->properties[0].name = "compatible";
|
||||
mipi_dsi_phy_pdev->dev.of_node->properties[0].value = (void*)"mixel,imx8mq-mipi-dsi-phy";
|
||||
mipi_dsi_phy_pdev->dev.of_node->properties[0].next = &mipi_dsi_phy_pdev->dev.of_node->properties[1];
|
||||
mipi_dsi_phy_pdev->dev.of_node->properties[1].name = "dsi_phy";
|
||||
mipi_dsi_phy_pdev->dev.of_node->properties[1].value = (void*)0;
|
||||
|
||||
mipi_dsi_phy_pdev->dev.parent = &mipi_dsi_phy_pdev->dev;
|
||||
|
||||
if (hdmi == false) {
|
||||
platform_device_register(mipi_dsi_phy_pdev);
|
||||
}
|
||||
/**
|
||||
* This device is originally created with the name '32e00000.dcss'
|
||||
* via 'of_platform_bus_create()'. Here it is called 'dcss-core' to match
|
||||
* the driver name.
|
||||
*/
|
||||
struct platform_device *dcss_pdev =
|
||||
platform_device_alloc("dcss-core", 0);
|
||||
|
||||
static resource dcss_resources[] = {
|
||||
{ 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;
|
||||
dcss_pdev->resource = dcss_resources;
|
||||
|
||||
dcss_pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
||||
dcss_pdev->dev.of_node->name = "dcss";
|
||||
dcss_pdev->dev.of_node->full_name = "dcss";
|
||||
dcss_pdev->dev.of_node->properties = (property*)kzalloc(sizeof(property), 0);
|
||||
dcss_pdev->dev.of_node->properties->name = "disp-dev";
|
||||
dcss_pdev->dev.of_node->properties->value = hdmi ? (void*)"hdmi_disp" : (void *)"mipi_disp";
|
||||
|
||||
platform_device_register(dcss_pdev);
|
||||
|
||||
|
||||
struct platform_device *mipi_dsi_bridge_pdev =
|
||||
platform_device_alloc("nwl-mipi-dsi", 0);
|
||||
|
||||
static resource mipi_dsi_bridge_resources[] = {
|
||||
{ IOMEM_BASE_MIPI_DSI, IOMEM_END_MIPI_DSI, "mipi_dsi_bridge", IORESOURCE_MEM },
|
||||
{ IRQ_MIPI_DSI, IRQ_MIPI_DSI, "mipi_dsi", IORESOURCE_IRQ }
|
||||
};
|
||||
|
||||
mipi_dsi_bridge_pdev->num_resources = 2;
|
||||
mipi_dsi_bridge_pdev->resource = mipi_dsi_bridge_resources;
|
||||
|
||||
Genode::addr_t **phy_ptr =
|
||||
(Genode::addr_t **)devres_find(&mipi_dsi_phy_pdev->dev, devm_phy_consume, nullptr, nullptr);
|
||||
mipi_dsi_bridge_pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
||||
mipi_dsi_bridge_pdev->dev.of_node->name = "mipi_dsi_bridge";
|
||||
mipi_dsi_bridge_pdev->dev.of_node->properties = (property*)kzalloc(sizeof(property), 0);
|
||||
mipi_dsi_bridge_pdev->dev.of_node->properties[0].name = "dphy";
|
||||
mipi_dsi_bridge_pdev->dev.of_node->properties[0].value = phy_ptr ? (void*)*phy_ptr : nullptr;
|
||||
mipi_dsi_bridge_pdev->dev.of_node->properties[0].next = nullptr;
|
||||
|
||||
if (hdmi == false)
|
||||
platform_device_register(mipi_dsi_bridge_pdev);
|
||||
|
||||
/*
|
||||
* This device is originally created with the name 'display-subsystem'
|
||||
* via 'of_platform_bus_create()'. Here it is called 'imx-drm' to match
|
||||
* the driver name.
|
||||
@ -231,6 +317,20 @@ void Framebuffer::Main::_run_linux()
|
||||
|
||||
platform_device_register(display_subsystem_pdev);
|
||||
|
||||
struct platform_device *mipi_dsi_imx_pdev =
|
||||
platform_device_alloc("nwl_dsi-imx", 0);
|
||||
|
||||
mipi_dsi_imx_pdev->dev.of_node = (device_node*)kzalloc(sizeof(device_node), 0);
|
||||
mipi_dsi_imx_pdev->dev.of_node->name = "mipi_dsi";
|
||||
mipi_dsi_imx_pdev->dev.of_node->properties = (property*)kzalloc(2*sizeof(property), 0);
|
||||
mipi_dsi_imx_pdev->dev.of_node->properties[0].name = "compatible";
|
||||
mipi_dsi_imx_pdev->dev.of_node->properties[0].value = (void *)"fsl,imx8mq-mipi-dsi_drm";
|
||||
mipi_dsi_imx_pdev->dev.of_node->properties[0].next = &mipi_dsi_imx_pdev->dev.of_node->properties[1];
|
||||
mipi_dsi_imx_pdev->dev.of_node->properties[1].name = "dphy";
|
||||
mipi_dsi_imx_pdev->dev.of_node->properties[1].value = phy_ptr ? (void *)*phy_ptr : nullptr;
|
||||
|
||||
if (hdmi == false)
|
||||
platform_device_register(mipi_dsi_imx_pdev);
|
||||
|
||||
_driver.finish_initialization();
|
||||
_driver.config_sigh(_policy_change_handler);
|
||||
|
@ -78,7 +78,7 @@ static inline void panic(const char *fmt, ...)
|
||||
va_start(args, fmt);
|
||||
lx_vprintf(fmt, args);
|
||||
va_end(args);
|
||||
lx_printf("panic()");
|
||||
lx_printf("\npanic()\n");
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user