From 933013b3c6f812335525c5b705a0908fc5be6bc3 Mon Sep 17 00:00:00 2001 From: Meng Mingming Date: Thu, 31 Aug 2017 17:17:41 +0800 Subject: [PATCH] MLK-15321-4 drm/imx: core: Add bliteng as component of imx-drm Implement Blt engine as DRM renderer. Add dpu bliteng as component of imx-drm. Signed-off-by: Adrian Negreanu Signed-off-by: Marius Vlad Signed-off-by: Meng Mingming --- drivers/gpu/drm/imx/imx-drm-core.c | 74 +++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 8938cd4b5459..7ea83622a11c 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -143,6 +143,13 @@ static int compare_of(struct device *dev, void *data) return pdata->of_node == np; } + /* This is a special case for dpu bliteng. */ + if (strcmp(dev->driver->name, "imx-drm-dpu-bliteng") == 0) { + struct dpu_client_platformdata *pdata = dev->platform_data; + + return pdata->of_node == np; + } + /* Special case for LDB, one device for two channels */ if (of_node_cmp(np->name, "lvds-channel") == 0) { np = of_get_parent(np); @@ -201,12 +208,66 @@ static inline bool has_dcss(struct device *dev) ARRAY_SIZE(imx_drm_dcss_comp_parents)); } +static void add_dpu_bliteng_components(struct device *dev, + struct component_match **matchptr) +{ + /* + * As there may be two dpu bliteng device, + * so need add something in compare data to distinguish. + * Use its parent dpu's of_node as the data here. + */ + struct device_node *port, *parent; + /* assume max dpu number is 8 */ + struct device_node *dpu[8]; + int num_dpu = 0; + int i, j; + bool found = false; + + for (i = 0; ; i++) { + port = of_parse_phandle(dev->of_node, "ports", i); + if (!port) + break; + + parent = of_get_parent(port); + + for (j = 0; j < num_dpu; j++) { + if (dpu[j] == parent) { + found = true; + break; + } + } + + if (found) { + found = false; + } else { + if (num_dpu >= ARRAY_SIZE(dpu)) { + dev_err(dev, "The number of found dpu is greater than max [%ld].\n", + ARRAY_SIZE(dpu)); + of_node_put(parent); + of_node_put(port); + break; + } + + dpu[num_dpu] = parent; + num_dpu++; + + component_match_add(dev, matchptr, compare_of, parent); + } + + of_node_put(parent); + of_node_put(port); + } +} + static int imx_drm_bind(struct device *dev) { struct drm_device *drm; struct imx_drm_device *imxdrm; int ret; + if (has_dpu(dev)) + imx_drm_driver.driver_features |= DRIVER_RENDER; + drm = drm_dev_alloc(&imx_drm_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); @@ -335,8 +396,10 @@ static void imx_drm_unbind(struct device *dev) struct drm_device *drm = dev_get_drvdata(dev); struct imx_drm_device *imxdrm = drm->dev_private; - if (has_dpu(dev)) + if (has_dpu(dev)) { flush_workqueue(imxdrm->dpu_nonblock_commit_wq); + imx_drm_driver.driver_features &= ~DRIVER_RENDER; + } if (has_dcss(dev)) flush_workqueue(imxdrm->dcss_nonblock_commit_wq); @@ -368,7 +431,14 @@ static const struct component_master_ops imx_drm_ops = { static int imx_drm_platform_probe(struct platform_device *pdev) { - int ret = drm_of_component_probe(&pdev->dev, compare_of, &imx_drm_ops); + struct component_match *match = NULL; + int ret; + + if (has_dpu(&pdev->dev)) + add_dpu_bliteng_components(&pdev->dev, &match); + + ret = drm_of_component_probe_with_match(&pdev->dev, match, compare_of, + &imx_drm_ops); if (!ret) ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); -- 2.17.1