diff options
Diffstat (limited to 'meta-agl-bsp/meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi/dsi/0003-drm-vc4-Set-up-the-DSI-host-at-pdev-probe-time-not-c.patch')
-rw-r--r-- | meta-agl-bsp/meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi/dsi/0003-drm-vc4-Set-up-the-DSI-host-at-pdev-probe-time-not-c.patch | 217 |
1 files changed, 0 insertions, 217 deletions
diff --git a/meta-agl-bsp/meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi/dsi/0003-drm-vc4-Set-up-the-DSI-host-at-pdev-probe-time-not-c.patch b/meta-agl-bsp/meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi/dsi/0003-drm-vc4-Set-up-the-DSI-host-at-pdev-probe-time-not-c.patch deleted file mode 100644 index 0e6e068fe..000000000 --- a/meta-agl-bsp/meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi/dsi/0003-drm-vc4-Set-up-the-DSI-host-at-pdev-probe-time-not-c.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 2ccd080392adfb1f077f2f4d289651b6b15e0951 Mon Sep 17 00:00:00 2001 -From: Kevin Quigley <kevin@kquigley.co.uk> -Date: Mon, 24 Sep 2018 18:09:52 +0000 -Subject: [PATCH 3/4] drm/vc4: Set up the DSI host at pdev probe time, not - component bind. bring https://patchwork.kernel.org/patch/9902623/ to Linux - 4.14.y - -We need the following things to happen in sequence: - -DSI host creation -DSI device creation in the panel driver (needs DSI host) -DSI device attach from panel to host. -DSI drm_panel_add() -DSI encoder creation -DSI encoder's DRM panel/bridge attach - -Unless we allow device creation while the host isn't up yet, we need -to break the -EPROBE_DEFER deadlock between the panel driver looking -up the host and the host driver looking up the panel. We can do so by -moving the DSI host creation outside of the component bind loop, and -the panel/bridge lookup/attach into the component bind process. ---- - drivers/gpu/drm/vc4/vc4_dsi.c | 93 ++++++++++++++++++++--------------- - 1 file changed, 53 insertions(+), 40 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c -index 3fa2db18d70f..faf38f17ec26 100644 ---- a/drivers/gpu/drm/vc4/vc4_dsi.c -+++ b/drivers/gpu/drm/vc4/vc4_dsi.c -@@ -33,6 +33,7 @@ - #include <drm/drm_crtc_helper.h> - #include <drm/drm_edid.h> - #include <drm/drm_mipi_dsi.h> -+#include <drm/drm_of.h> - #include <drm/drm_panel.h> - #include <linux/clk.h> - #include <linux/clk-provider.h> -@@ -504,7 +505,6 @@ struct vc4_dsi { - struct mipi_dsi_host dsi_host; - struct drm_encoder *encoder; - struct drm_bridge *bridge; -- bool is_panel_bridge; - - void __iomem *regs; - -@@ -1300,7 +1300,6 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host, - struct mipi_dsi_device *device) - { - struct vc4_dsi *dsi = host_to_dsi(host); -- int ret = 0; - - dsi->lanes = device->lanes; - dsi->channel = device->channel; -@@ -1335,33 +1334,12 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host, - return 0; - } - -- dsi->bridge = of_drm_find_bridge(device->dev.of_node); -- if (!dsi->bridge) { -- struct drm_panel *panel = -- of_drm_find_panel(device->dev.of_node); -- -- dsi->bridge = drm_panel_bridge_add(panel, -- DRM_MODE_CONNECTOR_DSI); -- if (IS_ERR(dsi->bridge)) { -- ret = PTR_ERR(dsi->bridge); -- dsi->bridge = NULL; -- return ret; -- } -- dsi->is_panel_bridge = true; -- } -- -- return drm_bridge_attach(dsi->encoder, dsi->bridge, NULL); -+ return 0; - } - - static int vc4_dsi_host_detach(struct mipi_dsi_host *host, - struct mipi_dsi_device *device) - { -- struct vc4_dsi *dsi = host_to_dsi(host); -- -- if (dsi->is_panel_bridge) { -- drm_panel_bridge_remove(dsi->bridge); -- dsi->bridge = NULL; -- } - - return 0; - } -@@ -1525,16 +1503,13 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) - struct platform_device *pdev = to_platform_device(dev); - struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = to_vc4_dev(drm); -- struct vc4_dsi *dsi; -+ struct vc4_dsi *dsi = dev_get_drvdata(dev); - struct vc4_dsi_encoder *vc4_dsi_encoder; -+ struct drm_panel *panel; - const struct of_device_id *match; - dma_cap_mask_t dma_mask; - int ret; - -- dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); -- if (!dsi) -- return -ENOMEM; -- - match = of_match_device(vc4_dsi_dt_match, dev); - if (!match) - return -ENODEV; -@@ -1549,7 +1524,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) - vc4_dsi_encoder->dsi = dsi; - dsi->encoder = &vc4_dsi_encoder->base.base; - -- dsi->pdev = pdev; - dsi->regs = vc4_ioremap_regs(pdev, 0); - if (IS_ERR(dsi->regs)) - return PTR_ERR(dsi->regs); -@@ -1637,6 +1611,18 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) - return ret; - } - -+ ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, -+ &panel, &dsi->bridge); -+ if (ret) -+ return ret; -+ -+ if (panel) { -+ dsi->bridge = devm_drm_panel_bridge_add(dev, panel, -+ DRM_MODE_CONNECTOR_DSI); -+ if (IS_ERR(dsi->bridge)) -+ return PTR_ERR(dsi->bridge); -+ } -+ - /* The esc clock rate is supposed to always be 100Mhz. */ - ret = clk_set_rate(dsi->escape_clock, 100 * 1000000); - if (ret) { -@@ -1655,13 +1641,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) - DRM_MODE_ENCODER_DSI, NULL); - drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs); - -- dsi->dsi_host.ops = &vc4_dsi_host_ops; -- dsi->dsi_host.dev = dev; -- -- mipi_dsi_host_register(&dsi->dsi_host); -- -- dev_set_drvdata(dev, dsi); -- - ret = drm_bridge_attach(dsi->encoder, dsi->bridge, NULL); - if (ret) { - dev_err(dev, "bridge attach failed: %d\n", ret); -@@ -1672,6 +1651,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) - * from our driver, since we need to sequence them within the - * encoder's enable/disable paths. - */ -+ - dsi->encoder->bridge = NULL; - - pm_runtime_enable(dev); -@@ -1690,8 +1670,6 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master, - - vc4_dsi_encoder_destroy(dsi->encoder); - -- mipi_dsi_host_unregister(&dsi->dsi_host); -- - if (dsi->port == 1) - vc4->dsi1 = NULL; - } -@@ -1703,12 +1681,47 @@ static const struct component_ops vc4_dsi_ops = { - - static int vc4_dsi_dev_probe(struct platform_device *pdev) - { -- return component_add(&pdev->dev, &vc4_dsi_ops); -+ struct device *dev = &pdev->dev; -+ struct vc4_dsi *dsi; -+ int ret; -+ -+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); -+ if (!dsi) -+ return -ENOMEM; -+ dev_set_drvdata(dev, dsi); -+ -+ dsi->pdev = pdev; -+ -+ /* Note, the initialization sequence for DSI and panels is -+ * tricky. The component bind above won't get past its -+ * -EPROBE_DEFER until the panel/bridge probes. The -+ * panel/bridge will return -EPROBE_DEFER until it has a -+ * mipi_dsi_host to register its device to. So, we register -+ * the host during pdev probe time, so vc4 as a whole can then -+ * -EPROBE_DEFER its component bind process until the panel -+ * successfully attaches. -+ */ -+ dsi->dsi_host.ops = &vc4_dsi_host_ops; -+ dsi->dsi_host.dev = dev; -+ mipi_dsi_host_register(&dsi->dsi_host); -+ -+ ret = component_add(&pdev->dev, &vc4_dsi_ops); -+ if (ret) { -+ mipi_dsi_host_unregister(&dsi->dsi_host); -+ return ret; -+ } -+ -+ return 0; - } - - static int vc4_dsi_dev_remove(struct platform_device *pdev) - { -+ struct device *dev = &pdev->dev; -+ struct vc4_dsi *dsi = dev_get_drvdata(dev); -+ - component_del(&pdev->dev, &vc4_dsi_ops); -+ mipi_dsi_host_unregister(&dsi->dsi_host); -+ - return 0; - } - --- -2.21.0 - |