From c9f0b0b0a076923a136aea4b948aee8737c35189 Mon Sep 17 00:00:00 2001 From: Doug Brown Date: Tue, 30 Aug 2022 21:34:34 -0700 Subject: [PATCH] drm/armada: fix DT support to work with panels Add the necessary setup to create a simple encoder and connect it to a bridge (which may be automatically created to hook up to a panel). This also required removing the "armada_add_endpoints" call, because it would never find the panel so binding would never occur. Signed-off-by: Doug Brown --- drivers/gpu/drm/armada/armada_crtc.c | 36 ++++++++++++++++++++++++---- drivers/gpu/drm/armada/armada_crtc.h | 2 ++ drivers/gpu/drm/armada/armada_drv.c | 7 ------ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 46372e2fc47c76..daff098127c56f 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "armada_crtc.h" #include "armada_drm.h" @@ -913,6 +915,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, struct armada_private *priv = drm_to_armada_dev(drm); struct armada_crtc *dcrtc; struct drm_plane *primary; + struct drm_bridge *bridge; void __iomem *base; int ret; @@ -929,6 +932,28 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, if (dev != drm->dev) dev_set_drvdata(dev, dcrtc); + /* Create a simple encoder for this CRTC to use */ + ret = drm_simple_encoder_init(drm, &dcrtc->encoder, DRM_MODE_ENCODER_NONE); + if (ret < 0) { + DRM_ERROR("failed to create Armada encoder\n"); + goto err_crtc; + } + dcrtc->encoder.possible_crtcs = 0x1; + + /* Find a bridge to connect */ + bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0); + if (IS_ERR(bridge) && (PTR_ERR(bridge) != -ENODEV)) { + ret = PTR_ERR(bridge); + goto err_encoder; + } + + /* Attach the bridge to the encoder */ + ret = drm_bridge_attach(&dcrtc->encoder, bridge, NULL, 0); + if (ret < 0) { + DRM_ERROR("failed to attach Armada bridge\n"); + goto err_encoder; + } + dcrtc->variant = variant; dcrtc->base = base; dcrtc->num = drm->mode_config.num_crtc; @@ -954,12 +979,12 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", dcrtc); if (ret < 0) - goto err_crtc; + goto err_encoder; if (dcrtc->variant->init) { ret = dcrtc->variant->init(dcrtc, dev); if (ret) - goto err_crtc; + goto err_encoder; } /* Ensure AXI pipeline is enabled */ @@ -972,13 +997,13 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, primary = kzalloc(sizeof(*primary), GFP_KERNEL); if (!primary) { ret = -ENOMEM; - goto err_crtc; + goto err_encoder; } ret = armada_drm_primary_plane_init(drm, primary); if (ret) { kfree(primary); - goto err_crtc; + goto err_encoder; } ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, primary, NULL, @@ -998,6 +1023,8 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, err_crtc_init: primary->funcs->destroy(primary); +err_encoder: + drm_encoder_cleanup(&dcrtc->encoder); err_crtc: kfree(dcrtc); @@ -1043,6 +1070,7 @@ armada_lcd_unbind(struct device *dev, struct device *master, void *data) { struct armada_crtc *dcrtc = dev_get_drvdata(dev); + drm_encoder_cleanup(&dcrtc->encoder); armada_drm_crtc_destroy(&dcrtc->crtc); } diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h index b21267d1745f14..80f3e94e253482 100644 --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h @@ -6,6 +6,7 @@ #define ARMADA_CRTC_H #include +#include struct armada_gem_object; @@ -35,6 +36,7 @@ struct armada_variant; struct armada_crtc { struct drm_crtc crtc; + struct drm_encoder encoder; const struct armada_variant *variant; void *variant_data; unsigned num; diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index f3f52fbeae9025..532de779b8d200 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -265,13 +265,6 @@ static int armada_drm_probe(struct platform_device *pdev) drm_of_component_match_add(dev, &match, component_compare_of, np); } - - for_each_compatible_node(np, NULL, "marvell,armada-lcdc") { - if (!of_device_is_available(np)) - continue; - - armada_add_endpoints(dev, &match, np); - } } return component_master_add_with_match(&pdev->dev, &armada_master_ops,