From patchwork Wed Dec 1 20:20:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 519884 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A4DEC433F5 for ; Wed, 1 Dec 2021 20:20:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232322AbhLAUXs (ORCPT ); Wed, 1 Dec 2021 15:23:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234856AbhLAUXs (ORCPT ); Wed, 1 Dec 2021 15:23:48 -0500 Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C26B9C061574 for ; Wed, 1 Dec 2021 12:20:26 -0800 (PST) Received: by mail-lf1-x12c.google.com with SMTP id r26so65925983lfn.8 for ; Wed, 01 Dec 2021 12:20:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9eziqWmH/0sYjYUZm8mEiRFfXUO2KooRO+C0X18Kx2U=; b=I7Gf5/r15x7wY0kT0QOOWrbv2R/uZogi3dHph5lJMgaJRQOgpfJYNfLnnjxlXwbgzD Aj+LZgzXzvtkOFQjiGwkWOfmtEU2brrceVyiUhq6ahDJ6xoPbxADUmRUQQeGNZhywTS4 gY6bK5CqcSray10hbRSVBaknbt5F1Oeg3zKYlC2y6keLIgFPFWaFI3XxOsfSHlow4V9C gZdAVyT/zZZ9wotZjPgvEvc5dg7MyXGICRyEvTNNZ75z1r+iF/AyLLfdU4SjwmEO/HWO F9YDBtPRanOsu+nDZefmZbMsInXJMHTuC3Mkzpnc9H46gLicAmsUG954PIWzV/50cvQy 0szQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9eziqWmH/0sYjYUZm8mEiRFfXUO2KooRO+C0X18Kx2U=; b=jaY4l1wJi1rtDWLQRDej4XRFpVZ2wKtBcPqhjz3jca9boAeKzXF8849ZmxBjsabaJk Z2RZTk6JzJGoTFaX9El5JeDN9omliqB9a3sY/hDb1Fnq8mTICxbsMPCj8cHkWoC5IZIx EtfjDHnpbyQDo1WwadM2gKUeJ/EeCeqNNMr3Bmr/kFvherzHL/UvoThddMDgKFmpmPnm CNU54PMkuebpZkkKiZOIR+gnoNJQBOaTxgqA/uQfXne7sBdrn4GcemUeqKrN7QFVYgNr P7N+8yGbkPwn7+eTKNnbHoaz8gchd32LhDpPFo/Pc3V7Ad7KsCRlt9Ir1eTMCIKHFRZP QadQ== X-Gm-Message-State: AOAM533gBxvvqBYVuS6KgR1vPDMTgV1k/PNtJ5ENc3C9rzH4oBghmR0u rI5btiBOg0MvOKXDZo6jRZZxpjLzFKuuBw== X-Google-Smtp-Source: ABdhPJzxilRqazp2oHgj/58Sq40QysSwe1300GaIqyK8Whzos1jiaplqsQ6SUxKNEnO7lUqiIQXQKQ== X-Received: by 2002:a05:6512:3991:: with SMTP id j17mr7954368lfu.545.1638390025047; Wed, 01 Dec 2021 12:20:25 -0800 (PST) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id b4sm88538lfq.128.2021.12.01.12.20.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Dec 2021 12:20:24 -0800 (PST) From: Dmitry Baryshkov To: Bjorn Andersson , Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, AngeloGioacchino Del Regno Subject: [PATCH] drm/msm: Initialize MDSS irq domain at probe time Date: Wed, 1 Dec 2021 23:20:23 +0300 Message-Id: <20211201202023.2313971-1-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211201105210.24970-3-angelogioacchino.delregno@collabora.com> References: <20211201105210.24970-3-angelogioacchino.delregno@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Since commit 8f59ee9a570c ("drm/msm/dsi: Adjust probe order"), the DSI host gets initialized earlier, but this caused unability to probe the entire stack of components because they all depend on interrupts coming from the main `mdss` node (mdp5, or dpu1). To fix this issue, move mdss device initialization (which include irq domain setup) to msm_mdev_probe() time, as to make sure that the interrupt controller is available before dsi and/or other components try to initialize, finally satisfying the dependency. Fixes: 8f59ee9a570c ("drm/msm/dsi: Adjust probe order") Co-Developed-By: AngeloGioacchino Del Regno Signed-off-by: Dmitry Baryshkov Tested-by: AngeloGioacchino Del Regno --- When checking your patch, I noticed that IRQ domain is created before respective MDSS clocks are enabled. This does not look like causing any issues at this time, but it did not look good. So I started moving clocks parsing to early_init() callbacks. And at some point it looked like we can drop the init()/destroy() callbacks in favour of early_init() and remove(). Which promted me to move init()/destroy() in place of early_init()/remove() with few minor fixes here and there. --- drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 25 +++++----- drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c | 32 ++++++------- drivers/gpu/drm/msm/msm_drv.c | 56 ++++++++++++----------- drivers/gpu/drm/msm/msm_kms.h | 8 ++-- 4 files changed, 59 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index b466784d9822..131c1f1a869c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -111,7 +111,7 @@ static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss) struct device *dev; struct irq_domain *domain; - dev = dpu_mdss->base.dev->dev; + dev = dpu_mdss->base.dev; domain = irq_domain_add_linear(dev->of_node, 32, &dpu_mdss_irqdomain_ops, dpu_mdss); @@ -184,16 +184,15 @@ static int dpu_mdss_disable(struct msm_mdss *mdss) return ret; } -static void dpu_mdss_destroy(struct drm_device *dev) +static void dpu_mdss_destroy(struct msm_mdss *mdss) { - struct platform_device *pdev = to_platform_device(dev->dev); - struct msm_drm_private *priv = dev->dev_private; - struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss); + struct platform_device *pdev = to_platform_device(mdss->dev); + struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); struct dss_module_power *mp = &dpu_mdss->mp; int irq; - pm_runtime_suspend(dev->dev); - pm_runtime_disable(dev->dev); + pm_runtime_suspend(mdss->dev); + pm_runtime_disable(mdss->dev); _dpu_mdss_irq_domain_fini(dpu_mdss); irq = platform_get_irq(pdev, 0); irq_set_chained_handler_and_data(irq, NULL, NULL); @@ -203,7 +202,6 @@ static void dpu_mdss_destroy(struct drm_device *dev) if (dpu_mdss->mmio) devm_iounmap(&pdev->dev, dpu_mdss->mmio); dpu_mdss->mmio = NULL; - priv->mdss = NULL; } static const struct msm_mdss_funcs mdss_funcs = { @@ -212,16 +210,15 @@ static const struct msm_mdss_funcs mdss_funcs = { .destroy = dpu_mdss_destroy, }; -int dpu_mdss_init(struct drm_device *dev) +int dpu_mdss_init(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(dev->dev); - struct msm_drm_private *priv = dev->dev_private; + struct msm_drm_private *priv = platform_get_drvdata(pdev); struct dpu_mdss *dpu_mdss; struct dss_module_power *mp; int ret; int irq; - dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL); + dpu_mdss = devm_kzalloc(&pdev->dev, sizeof(*dpu_mdss), GFP_KERNEL); if (!dpu_mdss) return -ENOMEM; @@ -238,7 +235,7 @@ int dpu_mdss_init(struct drm_device *dev) goto clk_parse_err; } - dpu_mdss->base.dev = dev; + dpu_mdss->base.dev = &pdev->dev; dpu_mdss->base.funcs = &mdss_funcs; ret = _dpu_mdss_irq_domain_add(dpu_mdss); @@ -256,7 +253,7 @@ int dpu_mdss_init(struct drm_device *dev) priv->mdss = &dpu_mdss->base; - pm_runtime_enable(dev->dev); + pm_runtime_enable(&pdev->dev); return 0; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c index c34760d981b8..b3f79c2277e9 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c @@ -112,7 +112,7 @@ static const struct irq_domain_ops mdss_hw_irqdomain_ops = { static int mdss_irq_domain_init(struct mdp5_mdss *mdp5_mdss) { - struct device *dev = mdp5_mdss->base.dev->dev; + struct device *dev = mdp5_mdss->base.dev; struct irq_domain *d; d = irq_domain_add_linear(dev->of_node, 32, &mdss_hw_irqdomain_ops, @@ -155,7 +155,7 @@ static int mdp5_mdss_disable(struct msm_mdss *mdss) static int msm_mdss_get_clocks(struct mdp5_mdss *mdp5_mdss) { struct platform_device *pdev = - to_platform_device(mdp5_mdss->base.dev->dev); + to_platform_device(mdp5_mdss->base.dev); mdp5_mdss->ahb_clk = msm_clk_get(pdev, "iface"); if (IS_ERR(mdp5_mdss->ahb_clk)) @@ -172,10 +172,9 @@ static int msm_mdss_get_clocks(struct mdp5_mdss *mdp5_mdss) return 0; } -static void mdp5_mdss_destroy(struct drm_device *dev) +static void mdp5_mdss_destroy(struct msm_mdss *mdss) { - struct msm_drm_private *priv = dev->dev_private; - struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(priv->mdss); + struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(mdss); if (!mdp5_mdss) return; @@ -183,7 +182,7 @@ static void mdp5_mdss_destroy(struct drm_device *dev) irq_domain_remove(mdp5_mdss->irqcontroller.domain); mdp5_mdss->irqcontroller.domain = NULL; - pm_runtime_disable(dev->dev); + pm_runtime_disable(mdss->dev); } static const struct msm_mdss_funcs mdss_funcs = { @@ -192,25 +191,24 @@ static const struct msm_mdss_funcs mdss_funcs = { .destroy = mdp5_mdss_destroy, }; -int mdp5_mdss_init(struct drm_device *dev) +int mdp5_mdss_init(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(dev->dev); - struct msm_drm_private *priv = dev->dev_private; + struct msm_drm_private *priv = platform_get_drvdata(pdev); struct mdp5_mdss *mdp5_mdss; int ret; DBG(""); - if (!of_device_is_compatible(dev->dev->of_node, "qcom,mdss")) + if (!of_device_is_compatible(pdev->dev.of_node, "qcom,mdss")) return 0; - mdp5_mdss = devm_kzalloc(dev->dev, sizeof(*mdp5_mdss), GFP_KERNEL); + mdp5_mdss = devm_kzalloc(&pdev->dev, sizeof(*mdp5_mdss), GFP_KERNEL); if (!mdp5_mdss) { ret = -ENOMEM; goto fail; } - mdp5_mdss->base.dev = dev; + mdp5_mdss->base.dev = &pdev->dev; mdp5_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "MDSS"); if (IS_ERR(mdp5_mdss->mmio)) { @@ -226,27 +224,27 @@ int mdp5_mdss_init(struct drm_device *dev) ret = msm_mdss_get_clocks(mdp5_mdss); if (ret) { - DRM_DEV_ERROR(dev->dev, "failed to get clocks: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to get clocks: %d\n", ret); goto fail; } - ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0), + ret = devm_request_irq(&pdev->dev, platform_get_irq(pdev, 0), mdss_irq, 0, "mdss_isr", mdp5_mdss); if (ret) { - DRM_DEV_ERROR(dev->dev, "failed to init irq: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to init irq: %d\n", ret); goto fail; } ret = mdss_irq_domain_init(mdp5_mdss); if (ret) { - DRM_DEV_ERROR(dev->dev, "failed to init sub-block irqs: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to init sub-block irqs: %d\n", ret); goto fail; } mdp5_mdss->base.funcs = &mdss_funcs; priv->mdss = &mdp5_mdss->base; - pm_runtime_enable(dev->dev); + pm_runtime_enable(&pdev->dev); return 0; fail: diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index f5596efd3819..ad35a5d94053 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -342,7 +342,6 @@ static int msm_drm_uninit(struct device *dev) struct msm_drm_private *priv = platform_get_drvdata(pdev); struct drm_device *ddev = priv->dev; struct msm_kms *kms = priv->kms; - struct msm_mdss *mdss = priv->mdss; int i; /* @@ -402,9 +401,6 @@ static int msm_drm_uninit(struct device *dev) component_unbind_all(dev, ddev); - if (mdss && mdss->funcs) - mdss->funcs->destroy(ddev); - ddev->dev_private = NULL; drm_dev_put(ddev); @@ -525,20 +521,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) ddev->dev_private = priv; priv->dev = ddev; - switch (get_mdp_ver(pdev)) { - case KMS_MDP5: - ret = mdp5_mdss_init(ddev); - break; - case KMS_DPU: - ret = dpu_mdss_init(ddev); - break; - default: - ret = 0; - break; - } - if (ret) - goto err_put_drm_dev; - mdss = priv->mdss; priv->wq = alloc_ordered_workqueue("msm", 0); @@ -561,12 +543,12 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) ret = msm_init_vram(ddev); if (ret) - goto err_destroy_mdss; + return ret; /* Bind all our sub-components: */ ret = component_bind_all(dev, ddev); if (ret) - goto err_destroy_mdss; + return ret; dma_set_max_seg_size(dev, UINT_MAX); @@ -672,12 +654,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) err_msm_uninit: msm_drm_uninit(dev); return ret; -err_destroy_mdss: - if (mdss && mdss->funcs) - mdss->funcs->destroy(ddev); -err_put_drm_dev: - drm_dev_put(ddev); - return ret; } /* @@ -1386,10 +1362,26 @@ static int msm_pdev_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); + switch (get_mdp_ver(pdev)) { + case KMS_MDP5: + ret = mdp5_mdss_init(pdev); + break; + case KMS_DPU: + ret = dpu_mdss_init(pdev); + break; + default: + ret = 0; + break; + } + if (ret) { + platform_set_drvdata(pdev, NULL); + return ret; + } + if (get_mdp_ver(pdev)) { ret = add_display_components(pdev, &match); if (ret) - return ret; + goto fail; } ret = add_gpu_components(&pdev->dev, &match); @@ -1411,14 +1403,24 @@ static int msm_pdev_probe(struct platform_device *pdev) fail: of_platform_depopulate(&pdev->dev); + + if (priv->mdss && priv->mdss->funcs) + priv->mdss->funcs->destroy(priv->mdss); + return ret; } static int msm_pdev_remove(struct platform_device *pdev) { + struct msm_drm_private *priv = platform_get_drvdata(pdev); + struct msm_mdss *mdss = priv->mdss; + component_master_del(&pdev->dev, &msm_drm_ops); of_platform_depopulate(&pdev->dev); + if (mdss && mdss->funcs) + mdss->funcs->destroy(mdss); + return 0; } diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 8b132c8b1513..2a4f0526cb98 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -204,16 +204,16 @@ extern const struct of_device_id mdp5_dt_match[]; struct msm_mdss_funcs { int (*enable)(struct msm_mdss *mdss); int (*disable)(struct msm_mdss *mdss); - void (*destroy)(struct drm_device *dev); + void (*destroy)(struct msm_mdss *mdss); }; struct msm_mdss { - struct drm_device *dev; + struct device *dev; const struct msm_mdss_funcs *funcs; }; -int mdp5_mdss_init(struct drm_device *dev); -int dpu_mdss_init(struct drm_device *dev); +int mdp5_mdss_init(struct platform_device *dev); +int dpu_mdss_init(struct platform_device *dev); #define for_each_crtc_mask(dev, crtc, crtc_mask) \ drm_for_each_crtc(crtc, dev) \ From patchwork Wed Dec 1 10:52:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AngeloGioacchino Del Regno X-Patchwork-Id: 519888 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C627C433EF for ; Wed, 1 Dec 2021 10:52:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229793AbhLAKzl (ORCPT ); Wed, 1 Dec 2021 05:55:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242505AbhLAKzk (ORCPT ); Wed, 1 Dec 2021 05:55:40 -0500 Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F22F5C061574; Wed, 1 Dec 2021 02:52:19 -0800 (PST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: kholk11) with ESMTPSA id 06D9D1F45630 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=collabora.com; s=mail; t=1638355938; bh=rL9Yo0VP8rvWWbfN9374jnoFbEFvxR/1usMNsyxgNhg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GhOvmzRBH6ydmh3oDb3Ju4hTU4S7ptZWIgytadzTT3xEd1H438JXLGqOQVMRr5Lw6 NOHiJO9s7S1tI6fWuRt24Ue8mbPAuRCpmN6rVxu/znMNrG1rvrGoa8wAyl66Bi9eo+ lypT5RYbnoxyNjGG4a+ieSyBzCIu9GN76OtKWc3kt+LABz/ZnpuFpAHrifJoDgdE7z s0NbFq373f6jwQ2+d3gNuYuAtHCgP4X5YyRC4re3w5Dnvt56RB7w7VNoXaFraXZB07 vMBa9KhYI2So5VKuY7pWzm0QOQGP1XCUb9JhYeJv/UdMEs+zU6H/9lh25JdsQAkS8J CjHKA7xxSODAA== From: AngeloGioacchino Del Regno To: robdclark@gmail.com Cc: dmitry.baryshkov@linaro.org, sean@poorly.run, airlied@linux.ie, daniel@ffwll.ch, maxime@cerno.tech, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org, kernel@collabora.com, konrad.dybcio@somainline.org, marijn.suijten@somainline.org, jami.kettunen@somainline.org, martin.botka@somainline.org, AngeloGioacchino Del Regno Subject: [PATCH v3 2/2] drm/msm: Initialize MDSS irq domain at probe time Date: Wed, 1 Dec 2021 11:52:10 +0100 Message-Id: <20211201105210.24970-3-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211201105210.24970-1-angelogioacchino.delregno@collabora.com> References: <20211201105210.24970-1-angelogioacchino.delregno@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Since commit 8f59ee9a570c ("drm/msm/dsi: Adjust probe order"), the DSI host gets initialized earlier, but this caused unability to probe the entire stack of components because they all depend on interrupts coming from the main `mdss` node (mdp5, or dpu1). To fix this issue, anticipate registering the irq domain from mdp5/dpu1 at msm_mdev_probe() time, as to make sure that the interrupt controller is available before dsi and/or other components try to initialize, finally satisfying the dependency. Moreover, to balance this operation while avoiding to always check if the irq domain is registered everytime we call bind() on msm_pdev, add a new *remove function pointer to msm_mdss_funcs, used to remove the irq domain only at msm_pdev_remove() time. Fixes: 8f59ee9a570c ("drm/msm/dsi: Adjust probe order") Signed-off-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 50 ++++++++++++------- drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c | 58 +++++++++++++++-------- drivers/gpu/drm/msm/msm_drv.c | 22 ++++++++- drivers/gpu/drm/msm/msm_kms.h | 3 ++ 4 files changed, 95 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index b466784d9822..6c2569175633 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -106,13 +106,10 @@ static const struct irq_domain_ops dpu_mdss_irqdomain_ops = { .xlate = irq_domain_xlate_onecell, }; -static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss) +static int _dpu_mdss_irq_domain_add(struct device *dev, struct dpu_mdss *dpu_mdss) { - struct device *dev; struct irq_domain *domain; - dev = dpu_mdss->base.dev->dev; - domain = irq_domain_add_linear(dev->of_node, 32, &dpu_mdss_irqdomain_ops, dpu_mdss); if (!domain) { @@ -194,7 +191,6 @@ static void dpu_mdss_destroy(struct drm_device *dev) pm_runtime_suspend(dev->dev); pm_runtime_disable(dev->dev); - _dpu_mdss_irq_domain_fini(dpu_mdss); irq = platform_get_irq(pdev, 0); irq_set_chained_handler_and_data(irq, NULL, NULL); msm_dss_put_clk(mp->clk_config, mp->num_clk); @@ -203,15 +199,43 @@ static void dpu_mdss_destroy(struct drm_device *dev) if (dpu_mdss->mmio) devm_iounmap(&pdev->dev, dpu_mdss->mmio); dpu_mdss->mmio = NULL; - priv->mdss = NULL; +} + +static void dpu_mdss_remove(struct msm_mdss *mdss) +{ + _dpu_mdss_irq_domain_fini(to_dpu_mdss(mdss)); } static const struct msm_mdss_funcs mdss_funcs = { .enable = dpu_mdss_enable, .disable = dpu_mdss_disable, .destroy = dpu_mdss_destroy, + .remove = dpu_mdss_remove, }; +int dpu_mdss_early_init(struct device *dev, struct msm_drm_private *priv) +{ + struct dpu_mdss *dpu_mdss; + int ret; + + dpu_mdss = devm_kzalloc(dev, sizeof(*dpu_mdss), GFP_KERNEL); + if (!dpu_mdss) + return -ENOMEM; + + ret = _dpu_mdss_irq_domain_add(dev, dpu_mdss); + if (ret) + return ret; + + /* + * Here we have no drm_device yet, but still do the assignment + * so that we can retrieve our struct dpu_mdss from the main + * init function, since we allocate it here. + */ + priv->mdss = &dpu_mdss->base; + + return 0; +} + int dpu_mdss_init(struct drm_device *dev) { struct platform_device *pdev = to_platform_device(dev->dev); @@ -221,9 +245,9 @@ int dpu_mdss_init(struct drm_device *dev) int ret; int irq; - dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL); + dpu_mdss = to_dpu_mdss(priv->mdss); if (!dpu_mdss) - return -ENOMEM; + return -ENODATA; dpu_mdss->mmio = msm_ioremap(pdev, "mdss", "mdss"); if (IS_ERR(dpu_mdss->mmio)) @@ -241,10 +265,6 @@ int dpu_mdss_init(struct drm_device *dev) dpu_mdss->base.dev = dev; dpu_mdss->base.funcs = &mdss_funcs; - ret = _dpu_mdss_irq_domain_add(dpu_mdss); - if (ret) - goto irq_domain_error; - irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = irq; @@ -253,16 +273,10 @@ int dpu_mdss_init(struct drm_device *dev) irq_set_chained_handler_and_data(irq, dpu_mdss_irq, dpu_mdss); - - priv->mdss = &dpu_mdss->base; - pm_runtime_enable(dev->dev); - return 0; irq_error: - _dpu_mdss_irq_domain_fini(dpu_mdss); -irq_domain_error: msm_dss_put_clk(mp->clk_config, mp->num_clk); clk_parse_err: devm_kfree(&pdev->dev, mp->clk_config); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c index 0ea53420bc40..a99538ae4182 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c @@ -112,9 +112,8 @@ static const struct irq_domain_ops mdss_hw_irqdomain_ops = { }; -static int mdss_irq_domain_init(struct mdp5_mdss *mdp5_mdss) +static int mdss_irq_domain_init(struct device *dev, struct mdp5_mdss *mdp5_mdss) { - struct device *dev = mdp5_mdss->base.dev->dev; struct irq_domain *d; d = irq_domain_add_linear(dev->of_node, 32, &mdss_hw_irqdomain_ops, @@ -182,20 +181,52 @@ static void mdp5_mdss_destroy(struct drm_device *dev) if (!mdp5_mdss) return; - irq_domain_remove(mdp5_mdss->irqcontroller.domain); - mdp5_mdss->irqcontroller.domain = NULL; - regulator_disable(mdp5_mdss->vdd); pm_runtime_disable(dev->dev); } +static void mdp5_mdss_remove(struct msm_mdss *mdss) +{ + struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(mdss); + + irq_domain_remove(mdp5_mdss->irqcontroller.domain); + mdp5_mdss->irqcontroller.domain = NULL; +} + static const struct msm_mdss_funcs mdss_funcs = { .enable = mdp5_mdss_enable, .disable = mdp5_mdss_disable, .destroy = mdp5_mdss_destroy, + .remove = mdp5_mdss_remove, }; +int mdp5_mdss_early_init(struct device *dev, struct msm_drm_private *priv) +{ + struct mdp5_mdss *mdp5_mdss; + int ret; + + if (!of_device_is_compatible(dev->of_node, "qcom,mdss")) + return 0; + + mdp5_mdss = devm_kzalloc(dev, sizeof(*mdp5_mdss), GFP_KERNEL); + if (!mdp5_mdss) + return -ENOMEM; + + ret = mdss_irq_domain_init(dev, mdp5_mdss); + if (ret) + return ret; + + /* + * Here we have no drm_device yet, but still do the assignment + * so that we can retrieve our struct mdp5_mdss from the main + * init function, since we allocate it here. + */ + priv->mdss = &mdp5_mdss->base; + + return 0; +} + int mdp5_mdss_init(struct drm_device *dev) { struct platform_device *pdev = to_platform_device(dev->dev); @@ -208,11 +239,9 @@ int mdp5_mdss_init(struct drm_device *dev) if (!of_device_is_compatible(dev->dev->of_node, "qcom,mdss")) return 0; - mdp5_mdss = devm_kzalloc(dev->dev, sizeof(*mdp5_mdss), GFP_KERNEL); - if (!mdp5_mdss) { - ret = -ENOMEM; - goto fail; - } + mdp5_mdss = to_mdp5_mdss(priv->mdss); + if (!mdp5_mdss) + return -ENODATA; mdp5_mdss->base.dev = dev; @@ -255,17 +284,8 @@ int mdp5_mdss_init(struct drm_device *dev) goto fail_irq; } - ret = mdss_irq_domain_init(mdp5_mdss); - if (ret) { - DRM_DEV_ERROR(dev->dev, "failed to init sub-block irqs: %d\n", ret); - goto fail_irq; - } - mdp5_mdss->base.funcs = &mdss_funcs; - priv->mdss = &mdp5_mdss->base; - pm_runtime_enable(dev->dev); - return 0; fail_irq: regulator_disable(mdp5_mdss->vdd); diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 64230e473a34..ded4f4d6545f 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1389,6 +1389,20 @@ static int msm_pdev_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; + switch (get_mdp_ver(pdev)) { + case KMS_MDP5: + ret = mdp5_mdss_early_init(&pdev->dev, priv); + break; + case KMS_DPU: + ret = dpu_mdss_early_init(&pdev->dev, priv); + break; + default: + ret = 0; + break; + } + if (ret) + return ret; + platform_set_drvdata(pdev, priv); if (get_mdp_ver(pdev)) { @@ -1421,6 +1435,12 @@ static int msm_pdev_probe(struct platform_device *pdev) static int msm_pdev_remove(struct platform_device *pdev) { + struct msm_drm_private *priv = platform_get_drvdata(pdev); + + if (priv->mdss && priv->mdss->funcs) + priv->mdss->funcs->remove(priv->mdss); + + priv->mdss = NULL; component_master_del(&pdev->dev, &msm_drm_ops); of_platform_depopulate(&pdev->dev); @@ -1432,7 +1452,7 @@ static void msm_pdev_shutdown(struct platform_device *pdev) struct msm_drm_private *priv = platform_get_drvdata(pdev); struct drm_device *drm = priv ? priv->dev : NULL; - if (!priv || !priv->kms) + if (!priv || !priv->kms || !drm->mode_config.funcs) return; drm_atomic_helper_shutdown(drm); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 6a42b819abc4..2c539a228156 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -202,6 +202,7 @@ struct msm_mdss_funcs { int (*enable)(struct msm_mdss *mdss); int (*disable)(struct msm_mdss *mdss); void (*destroy)(struct drm_device *dev); + void (*remove)(struct msm_mdss *mdss); }; struct msm_mdss { @@ -209,7 +210,9 @@ struct msm_mdss { const struct msm_mdss_funcs *funcs; }; +int mdp5_mdss_early_init(struct device *dev, struct msm_drm_private *priv); int mdp5_mdss_init(struct drm_device *dev); +int dpu_mdss_early_init(struct device *dev, struct msm_drm_private *priv); int dpu_mdss_init(struct drm_device *dev); #define for_each_crtc_mask(dev, crtc, crtc_mask) \