From patchwork Sun Jan 24 08:55:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 12042181 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2AE72C433E0 for ; Sun, 24 Jan 2021 08:57:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F19AB22B49 for ; Sun, 24 Jan 2021 08:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726615AbhAXI5n (ORCPT ); Sun, 24 Jan 2021 03:57:43 -0500 Received: from aposti.net ([89.234.176.197]:43646 "EHLO aposti.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726102AbhAXI5j (ORCPT ); Sun, 24 Jan 2021 03:57:39 -0500 From: Paul Cercueil To: David Airlie , Daniel Vetter Cc: Sam Ravnborg , Laurent Pinchart , od@zcrc.me, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, Paul Cercueil , stable@vger.kernel.org, Andrzej Hajda , Neil Armstrong , Jonas Karlman , Jernej Skrabec Subject: [PATCH v3 1/4] drm: bridge/panel: Cleanup connector on bridge detach Date: Sun, 24 Jan 2021 08:55:49 +0000 Message-Id: <20210124085552.29146-2-paul@crapouillou.net> In-Reply-To: <20210124085552.29146-1-paul@crapouillou.net> References: <20210124085552.29146-1-paul@crapouillou.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org If we don't call drm_connector_cleanup() manually in panel_bridge_detach(), the connector will be cleaned up with the other DRM objects in the call to drm_mode_config_cleanup(). However, since our drm_connector is devm-allocated, by the time drm_mode_config_cleanup() will be called, our connector will be long gone. Therefore, the connector must be cleaned up when the bridge is detached to avoid use-after-free conditions. v2: Cleanup connector only if it was created v3: Add FIXME Fixes: 13dfc0540a57 ("drm/bridge: Refactor out the panel wrapper from the lvds-encoder bridge.") Cc: # 4.12+ Cc: Andrzej Hajda Cc: Neil Armstrong Cc: Laurent Pinchart Cc: Jonas Karlman Cc: Jernej Skrabec Signed-off-by: Paul Cercueil Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/bridge/panel.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index 0ddc37551194..5959e8183cd0 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -87,6 +87,18 @@ static int panel_bridge_attach(struct drm_bridge *bridge, static void panel_bridge_detach(struct drm_bridge *bridge) { + struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); + struct drm_connector *connector = &panel_bridge->connector; + + /* + * Cleanup the connector if we know it was initialized. + * + * FIXME: This wouldn't be needed if the panel_bridge structure was + * allocated with drmm_kzalloc(). This might be tricky since the + * drm_device pointer can only be retrieved when the bridge is attached. + */ + if (!!panel_bridge->connector.dev) + drm_connector_cleanup(connector); } static void panel_bridge_pre_enable(struct drm_bridge *bridge) From patchwork Sun Jan 24 08:55:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 12042183 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1F481C433DB for ; Sun, 24 Jan 2021 08:58:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E4B8A22CAF for ; Sun, 24 Jan 2021 08:58:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726657AbhAXI6h (ORCPT ); Sun, 24 Jan 2021 03:58:37 -0500 Received: from aposti.net ([89.234.176.197]:43698 "EHLO aposti.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726634AbhAXI6a (ORCPT ); Sun, 24 Jan 2021 03:58:30 -0500 From: Paul Cercueil To: David Airlie , Daniel Vetter Cc: Sam Ravnborg , Laurent Pinchart , od@zcrc.me, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, Paul Cercueil Subject: [PATCH v3 2/4] drm/simple_kms_helper: Add macro drmm_plain_simple_encoder_alloc() Date: Sun, 24 Jan 2021 08:55:50 +0000 Message-Id: <20210124085552.29146-3-paul@crapouillou.net> In-Reply-To: <20210124085552.29146-1-paul@crapouillou.net> References: <20210124085552.29146-1-paul@crapouillou.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org This performs the same operation as drmm_simple_encoder_alloc(), but only allocates and returns a struct drm_encoder instance. Signed-off-by: Paul Cercueil --- include/drm/drm_simple_kms_helper.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index e6dbf3161c2f..f07e70303cfb 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -209,4 +209,21 @@ void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size, offsetof(type, member), \ encoder_type)) +/** + * drmm_plain_simple_encoder_alloc - Allocate and initialize a drm_encoder + * struct with basic functionality. + * @dev: drm device + * @encoder_type: user visible type of the encoder + * + * This performs the same operation as drmm_simple_encoder_alloc(), but + * only allocates and returns a struct drm_encoder instance. + * + * Returns: + * Pointer to the new drm_encoder struct, or ERR_PTR on failure. + */ +#define drmm_plain_simple_encoder_alloc(dev, encoder_type) \ + ((struct drm_encoder *) \ + __drmm_simple_encoder_alloc(dev, sizeof(struct drm_encoder), \ + 0, encoder_type)) + #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ From patchwork Sun Jan 24 08:55:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 12042185 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1376C433DB for ; Sun, 24 Jan 2021 08:59:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AEFD422CAF for ; Sun, 24 Jan 2021 08:59:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726551AbhAXI7c (ORCPT ); Sun, 24 Jan 2021 03:59:32 -0500 Received: from aposti.net ([89.234.176.197]:43710 "EHLO aposti.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726680AbhAXI7X (ORCPT ); Sun, 24 Jan 2021 03:59:23 -0500 From: Paul Cercueil To: David Airlie , Daniel Vetter Cc: Sam Ravnborg , Laurent Pinchart , od@zcrc.me, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, Paul Cercueil , stable@vger.kernel.org Subject: [PATCH v3 3/4] drm/ingenic: Register devm action to cleanup encoders Date: Sun, 24 Jan 2021 08:55:51 +0000 Message-Id: <20210124085552.29146-4-paul@crapouillou.net> In-Reply-To: <20210124085552.29146-1-paul@crapouillou.net> References: <20210124085552.29146-1-paul@crapouillou.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Since the encoders have been devm-allocated, they will be freed way before drm_mode_config_cleanup() is called. To avoid use-after-free conditions, we then must ensure that drm_encoder_cleanup() is called before the encoders are freed. v2: Use the new __drmm_simple_encoder_alloc() function v3: Use the new drmm_plain_simple_encoder_alloc() macro Fixes: c369cb27c267 ("drm/ingenic: Support multiple panels/bridges") Cc: # 5.8+ Signed-off-by: Paul Cercueil Reviewed-by: Laurent Pinchart --- Notes: Use the V1 of this patch to fix v5.11 and older kernels. This V3 only applies on the current drm-misc-next branch. drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 7bb31fbee29d..b23011c1c5d9 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -1014,20 +1014,17 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) bridge = devm_drm_panel_bridge_add_typed(dev, panel, DRM_MODE_CONNECTOR_DPI); - encoder = devm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); - if (!encoder) - return -ENOMEM; + encoder = drmm_plain_simple_encoder_alloc(drm, DRM_MODE_ENCODER_DPI); + if (IS_ERR(encoder)) { + ret = PTR_ERR(encoder); + dev_err(dev, "Failed to init encoder: %d\n", ret); + return ret; + } encoder->possible_crtcs = 1; drm_encoder_helper_add(encoder, &ingenic_drm_encoder_helper_funcs); - ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_DPI); - if (ret) { - dev_err(dev, "Failed to init encoder: %d\n", ret); - return ret; - } - ret = drm_bridge_attach(encoder, bridge, NULL, 0); if (ret) { dev_err(dev, "Unable to attach bridge\n"); From patchwork Sun Jan 24 08:55:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 12042187 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77BBAC433E0 for ; Sun, 24 Jan 2021 09:00:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 48B5422CAF for ; Sun, 24 Jan 2021 09:00:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726673AbhAXJAU (ORCPT ); Sun, 24 Jan 2021 04:00:20 -0500 Received: from aposti.net ([89.234.176.197]:43722 "EHLO aposti.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726456AbhAXJAR (ORCPT ); Sun, 24 Jan 2021 04:00:17 -0500 From: Paul Cercueil To: David Airlie , Daniel Vetter Cc: Sam Ravnborg , Laurent Pinchart , od@zcrc.me, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, Paul Cercueil , stable@vger.kernel.org, Daniel Vetter Subject: [PATCH v3 4/4] drm/ingenic: Fix non-OSD mode Date: Sun, 24 Jan 2021 08:55:52 +0000 Message-Id: <20210124085552.29146-5-paul@crapouillou.net> In-Reply-To: <20210124085552.29146-1-paul@crapouillou.net> References: <20210124085552.29146-1-paul@crapouillou.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Even though the JZ4740 did not have the OSD mode, it had (according to the documentation) two DMA channels, but there is absolutely no information about how to select the second DMA channel. Make the ingenic-drm driver work in non-OSD mode by using the foreground0 plane (which is bound to the DMA0 channel) as the primary plane, instead of the foreground1 plane, which is the primary plane when in OSD mode. Fixes: 3c9bea4ef32b ("drm/ingenic: Add support for OSD mode") Cc: # v5.8+ Signed-off-by: Paul Cercueil Acked-by: Daniel Vetter Tested-by: H. Nikolaus Schaller Acked-by: Laurent Pinchart --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index b23011c1c5d9..59ce43862e16 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -554,7 +554,7 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, height = state->src_h >> 16; cpp = state->fb->format->cpp[0]; - if (priv->soc_info->has_osd && plane->type == DRM_PLANE_TYPE_OVERLAY) + if (!priv->soc_info->has_osd || plane->type == DRM_PLANE_TYPE_OVERLAY) hwdesc = &priv->dma_hwdescs->hwdesc_f0; else hwdesc = &priv->dma_hwdescs->hwdesc_f1; @@ -826,6 +826,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) const struct jz_soc_info *soc_info; struct ingenic_drm *priv; struct clk *parent_clk; + struct drm_plane *primary; struct drm_bridge *bridge; struct drm_panel *panel; struct drm_encoder *encoder; @@ -940,9 +941,11 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) if (soc_info->has_osd) priv->ipu_plane = drm_plane_from_index(drm, 0); - drm_plane_helper_add(&priv->f1, &ingenic_drm_plane_helper_funcs); + primary = priv->soc_info->has_osd ? &priv->f1 : &priv->f0; - ret = drm_universal_plane_init(drm, &priv->f1, 1, + drm_plane_helper_add(primary, &ingenic_drm_plane_helper_funcs); + + ret = drm_universal_plane_init(drm, primary, 1, &ingenic_drm_primary_plane_funcs, priv->soc_info->formats_f1, priv->soc_info->num_formats_f1, @@ -954,7 +957,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs); - ret = drm_crtc_init_with_planes(drm, &priv->crtc, &priv->f1, + ret = drm_crtc_init_with_planes(drm, &priv->crtc, primary, NULL, &ingenic_drm_crtc_funcs, NULL); if (ret) { dev_err(dev, "Failed to init CRTC: %i\n", ret);