From nobody Mon Jun 29 17:36:49 2026 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 AFB7DC433FE for ; Sat, 5 Feb 2022 00:14:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378727AbiBEAOV (ORCPT ); Fri, 4 Feb 2022 19:14:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1378698AbiBEAOO (ORCPT ); Fri, 4 Feb 2022 19:14:14 -0500 Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28064DF8C1BD for ; Fri, 4 Feb 2022 16:14:11 -0800 (PST) Received: by mail-pg1-x52e.google.com with SMTP id 132so6310501pga.5 for ; Fri, 04 Feb 2022 16:14:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Yhbxh7kkqGGusGWBNx2mCA04d+nWExRaG4eT8COW5H4=; b=lW6XJL1GStnh11sxE6c3AEle1jPDq08bgs8pl3Qpl/pK4zYtnr+ztxBX07afHyB6nu wSLkzJT/NtirEqBGto3hq3t4fbxaHfhHfEj7wRY6raIcpc0Jpb5eG0m4HIIvOxX+Ez6v QTdow9MsyanB+ZzJUlBgqSf5f9qWQJEzMJwPE= 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=Yhbxh7kkqGGusGWBNx2mCA04d+nWExRaG4eT8COW5H4=; b=ldW7XZdC+2CjxxlsZgFSLmQRvCvHlwgzQ3OIqOXTkjx0OS8J0xq5kLqgAZBozUFoQ0 kYgdmV32ffbveg3RpUvHPU6I7V0fcf1o1KH47V3PIcby70GL2OmB5bawifV1QSUgPGt6 M37Sqo7R29DPkPHgfhgu77EtkRUHl553WDctvI/7oW0gQbCu9TQX/mbwkKqpd1643XjW +B2Zpc5jc7B5jDZwCj4uH1Zy8kH1R3xJk9m8SU8z7EVBn41rBmQh6vsGk7wq8wR2glmQ Fm9n+l63NXW25tFhoFPCU7bNWlb+PVLqy97rUaqtI4sJbkvOHh+j7C4d8d3stDlnQa0G V6DQ== X-Gm-Message-State: AOAM531JKyNUQy1hZESKNJwNqJienLx7/TV90StCVitJ3vm0GZo9N2nH ncbWGT/nczpW3O3ZNChGCU15eg== X-Google-Smtp-Source: ABdhPJwHbENOYwTwkFtmdn6y83vbJk6FTR1NFcvBdcuuTC/JSeQWcPm1Se3dFMTqcxl6aZvQHwe4dQ== X-Received: by 2002:a63:690a:: with SMTP id e10mr1171147pgc.599.1644020050659; Fri, 04 Feb 2022 16:14:10 -0800 (PST) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:d668:55ac:a465:88bf]) by smtp.gmail.com with ESMTPSA id q13sm3720231pfj.44.2022.02.04.16.14.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Feb 2022 16:14:10 -0800 (PST) From: Douglas Anderson To: dri-devel@lists.freedesktop.org Cc: Daniel Vetter , Javier Martinez Canillas , robert.foss@linaro.org, lschyi@chromium.org, Sam Ravnborg , jjsu@chromium.org, Douglas Anderson , Andrzej Hajda , David Airlie , Jernej Skrabec , Jonas Karlman , Laurent Pinchart , Neil Armstrong , linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] drm/bridge: ti-sn65dsi86: Use drm_bridge_connector Date: Fri, 4 Feb 2022 16:13:40 -0800 Message-Id: <20220204161245.v2.1.I3ab26b7f197cc56c874246a43e57913e9c2c1028@changeid> X-Mailer: git-send-email 2.35.0.263.gb82422642f-goog In-Reply-To: <20220205001342.3155839-1-dianders@chromium.org> References: <20220205001342.3155839-1-dianders@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The ti-sn65dsi86 driver shouldn't hand-roll its own bridge connector. It should use the normal drm_bridge_connector. Let's switch to do that, removing all of the custom code. NOTE: this still _doesn't_ implement DRM_BRIDGE_ATTACH_NO_CONNECTOR support for ti-sn65dsi86 and that would still be a useful thing to do in the future. It was attempted in the past [1] but put on the back burner. However, unless we instantly change ti-sn65dsi86 fully from not supporting DRM_BRIDGE_ATTACH_NO_CONNECTOR at all to _only_ supporting DRM_BRIDGE_ATTACH_NO_CONNECTOR then we'll still need a bit of time when we support both. This is a better way to support the old way where the driver hand rolls things itself. A new notes about the implementation here: * When using the drm_bridge_connector the connector should be created after all the bridges, so we change the ordering a bit. * I'm reasonably certain that we don't need to do anything to "free" the new drm_bridge_connector. If drm_bridge_connector_init() returns success then we know drm_connector_init() was called with the `drm_bridge_connector_funcs`. The `drm_bridge_connector_funcs` has a .destroy() that does all the cleanup. drm_connector_init() calls __drm_mode_object_add() with a drm_connector_free() that will call the .destroy(). * I'm also reasonably certain that I don't need to "undo" the drm_bridge_attach() if drm_bridge_connector_init() fails. The "detach" function is private and other similar code doesn't try to undo the drm_bridge_attach() in error cases. There's also a comment indicating the lack of balance at the top of drm_bridge_attach(). [1] https://lore.kernel.org/r/20210920225801.227211-4-robdclark@gmail.com Signed-off-by: Douglas Anderson --- Changes in v2: - ("ti-sn65dsi86: Use drm_bridge_connector") new for v2. drivers/gpu/drm/bridge/ti-sn65dsi86.c | 72 ++++++--------------------- 1 file changed, 14 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge= /ti-sn65dsi86.c index ba136a188be7..38616aab12ac 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -174,7 +175,7 @@ struct ti_sn65dsi86 { struct regmap *regmap; struct drm_dp_aux aux; struct drm_bridge bridge; - struct drm_connector connector; + struct drm_connector *connector; struct device_node *host_node; struct mipi_dsi_device *dsi; struct clk *refclk; @@ -646,54 +647,6 @@ static struct auxiliary_driver ti_sn_aux_driver =3D { .id_table =3D ti_sn_aux_id_table, }; =20 -/* -----------------------------------------------------------------------= ------ - * DRM Connector Operations - */ - -static struct ti_sn65dsi86 * -connector_to_ti_sn65dsi86(struct drm_connector *connector) -{ - return container_of(connector, struct ti_sn65dsi86, connector); -} - -static int ti_sn_bridge_connector_get_modes(struct drm_connector *connecto= r) -{ - struct ti_sn65dsi86 *pdata =3D connector_to_ti_sn65dsi86(connector); - - return drm_bridge_get_modes(pdata->next_bridge, connector); -} - -static struct drm_connector_helper_funcs ti_sn_bridge_connector_helper_fun= cs =3D { - .get_modes =3D ti_sn_bridge_connector_get_modes, -}; - -static const struct drm_connector_funcs ti_sn_bridge_connector_funcs =3D { - .fill_modes =3D drm_helper_probe_single_connector_modes, - .destroy =3D drm_connector_cleanup, - .reset =3D drm_atomic_helper_connector_reset, - .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, -}; - -static int ti_sn_bridge_connector_init(struct ti_sn65dsi86 *pdata) -{ - int ret; - - ret =3D drm_connector_init(pdata->bridge.dev, &pdata->connector, - &ti_sn_bridge_connector_funcs, - DRM_MODE_CONNECTOR_eDP); - if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); - return ret; - } - - drm_connector_helper_add(&pdata->connector, - &ti_sn_bridge_connector_helper_funcs); - drm_connector_attach_encoder(&pdata->connector, pdata->bridge.encoder); - - return 0; -} - /*------------------------------------------------------------------------= ------ * DRM Bridge */ @@ -757,10 +710,6 @@ static int ti_sn_bridge_attach(struct drm_bridge *brid= ge, return ret; } =20 - ret =3D ti_sn_bridge_connector_init(pdata); - if (ret < 0) - goto err_conn_init; - /* We never want the next bridge to *also* create a connector: */ flags |=3D DRM_BRIDGE_ATTACH_NO_CONNECTOR; =20 @@ -768,13 +717,20 @@ static int ti_sn_bridge_attach(struct drm_bridge *bri= dge, ret =3D drm_bridge_attach(bridge->encoder, pdata->next_bridge, &pdata->bridge, flags); if (ret < 0) - goto err_dsi_host; + goto err_initted_aux; + + pdata->connector =3D drm_bridge_connector_init(pdata->bridge.dev, + pdata->bridge.encoder); + if (IS_ERR(pdata->connector)) { + ret =3D PTR_ERR(pdata->connector); + goto err_initted_aux; + } + + drm_connector_attach_encoder(pdata->connector, pdata->bridge.encoder); =20 return 0; =20 -err_dsi_host: - drm_connector_cleanup(&pdata->connector); -err_conn_init: +err_initted_aux: drm_dp_aux_unregister(&pdata->aux); return ret; } @@ -824,7 +780,7 @@ static void ti_sn_bridge_set_dsi_rate(struct ti_sn65dsi= 86 *pdata) =20 static unsigned int ti_sn_bridge_get_bpp(struct ti_sn65dsi86 *pdata) { - if (pdata->connector.display_info.bpc <=3D 6) + if (pdata->connector->display_info.bpc <=3D 6) return 18; else return 24; --=20 2.35.0.263.gb82422642f-goog From nobody Mon Jun 29 17:36:49 2026 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 64812C433EF for ; Sat, 5 Feb 2022 00:14:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378713AbiBEAOS (ORCPT ); Fri, 4 Feb 2022 19:14:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1378699AbiBEAOO (ORCPT ); Fri, 4 Feb 2022 19:14:14 -0500 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 295A6D8399EF for ; Fri, 4 Feb 2022 16:14:13 -0800 (PST) Received: by mail-pf1-x435.google.com with SMTP id n32so6407337pfv.11 for ; Fri, 04 Feb 2022 16:14:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e1YXgPQg/QgIjJPLCBmICQvUckRJaQCi5C+VqMeIvS8=; b=Sckp/asfIozxW6+xn26hgboYzojlq2fJp0f/cWViFPP5LEVqkjJNujfGR3enGVfekg djCvSjwk9cRt3TXxY8kTZjjQ8be4dShkvIEpLPkjvoKx6c1KR4gXhXhm0cNQgCc5i3+z hgyEmOmP8sG5U4Ef8pF/jwtlX4AicnYcnoDes= 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=e1YXgPQg/QgIjJPLCBmICQvUckRJaQCi5C+VqMeIvS8=; b=Qmtz2MZIfr6Tv4ypb7oOWU7dyHTbSacsoBFY0jqXhpj8/UOdF+u2MJvTDt5K3dTs5w KgTOvu4HdPSqFr/rfxoaKtNa6wRjTIIZoKsIOtUCT5jP03lCrkjXWDmSLrLSvCsMO6Pl aeUwXULwVJJl2WCgaWuUq+93TagMFPDfYFimZePLLYENlNsGF5Qrkw46LOJAburbJjHX ojFjTQXi4bZlsxI2D7s0XyK0OjiwPTrzQtdXsM0wNtVRIaLZSdwltMf3XcXpzpTNO6xA cR1u8RBqEwtnXY1QQFXmFNWzSrYrO/mHdm1aj2Cd9/atErzVtMiBm8a7TVXQHhOMJxUz VOZg== X-Gm-Message-State: AOAM5331563WYwt55GwdPQPrhT+h7rpoI+Y3mAIg8wnv+8mI2pcsWqJo xdF3umB1jQIP+owVJXiriffmOA== X-Google-Smtp-Source: ABdhPJz+Fkk9gqDAia0auO55LEycSweXxaTCerYWw5xHDV+zLvHydudS8AzzEA9Cikmz2NxmdWE4kQ== X-Received: by 2002:a63:6b41:: with SMTP id g62mr1194976pgc.538.1644020052438; Fri, 04 Feb 2022 16:14:12 -0800 (PST) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:d668:55ac:a465:88bf]) by smtp.gmail.com with ESMTPSA id q13sm3720231pfj.44.2022.02.04.16.14.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Feb 2022 16:14:12 -0800 (PST) From: Douglas Anderson To: dri-devel@lists.freedesktop.org Cc: Daniel Vetter , Javier Martinez Canillas , robert.foss@linaro.org, lschyi@chromium.org, Sam Ravnborg , jjsu@chromium.org, Douglas Anderson , Andrzej Hajda , David Airlie , Jernej Skrabec , Jonas Karlman , Laurent Pinchart , Maarten Lankhorst , Maxime Ripard , Neil Armstrong , Thierry Reding , Thomas Zimmermann , linux-kernel@vger.kernel.org Subject: [PATCH v2 2/3] drm: Plumb debugfs_init through to panels Date: Fri, 4 Feb 2022 16:13:41 -0800 Message-Id: <20220204161245.v2.2.Ib0bd5346135cbb0b63006b69b61d4c8af6484740@changeid> X-Mailer: git-send-email 2.35.0.263.gb82422642f-goog In-Reply-To: <20220205001342.3155839-1-dianders@chromium.org> References: <20220205001342.3155839-1-dianders@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" We'd like panels to be able to add things to debugfs underneath the connector's directory. Let's plumb it through. A panel will be able to put things in a "panel" directory under the connector's directory. Note that debugfs is not ABI and so it's always possible that the location that the panel gets for its debugfs could change in the future. NOTE: this currently only works if you're using a modern architecture. Specifically the plumbing relies on _both_ drm_bridge_connector and drm_panel_bridge. If you're not using one or both of these things then things won't be plumbed through. As a side effect of this change, drm_bridges can also get callbacks to put stuff underneath the connector's debugfs directory. At the moment all bridges in the chain have their debugfs_init() called with the connector's root directory. Signed-off-by: Douglas Anderson Reviewed-by: Javier Martinez Canillas Reviewed-by: Laurent Pinchart --- Changes in v2: - ("drm: Plumb debugfs_init through to panels") new for v2. drivers/gpu/drm/bridge/panel.c | 12 ++++++++++++ drivers/gpu/drm/drm_bridge_connector.c | 15 +++++++++++++++ drivers/gpu/drm/drm_debugfs.c | 3 +++ include/drm/drm_bridge.h | 7 +++++++ include/drm/drm_connector.h | 7 +++++++ include/drm/drm_panel.h | 8 ++++++++ 6 files changed, 52 insertions(+) diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index b32295abd9e7..5be057575183 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -138,6 +138,17 @@ static int panel_bridge_get_modes(struct drm_bridge *b= ridge, return drm_panel_get_modes(panel_bridge->panel, connector); } =20 +static void panel_bridge_debugfs_init(struct drm_bridge *bridge, + struct dentry *root) +{ + struct panel_bridge *panel_bridge =3D drm_bridge_to_panel_bridge(bridge); + struct drm_panel *panel =3D panel_bridge->panel; + + root =3D debugfs_create_dir("panel", root); + if (panel->funcs->debugfs_init) + panel->funcs->debugfs_init(panel, root); +} + static const struct drm_bridge_funcs panel_bridge_bridge_funcs =3D { .attach =3D panel_bridge_attach, .detach =3D panel_bridge_detach, @@ -150,6 +161,7 @@ static const struct drm_bridge_funcs panel_bridge_bridg= e_funcs =3D { .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, .atomic_get_input_bus_fmts =3D drm_atomic_helper_bridge_propagate_bus_fmt, + .debugfs_init =3D panel_bridge_debugfs_init, }; =20 /** diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_b= ridge_connector.c index 791379816837..60923cdfe8e1 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -216,6 +216,20 @@ static void drm_bridge_connector_destroy(struct drm_co= nnector *connector) kfree(bridge_connector); } =20 +static void drm_bridge_connector_debugfs_init(struct drm_connector *connec= tor, + struct dentry *root) +{ + struct drm_bridge_connector *bridge_connector =3D + to_drm_bridge_connector(connector); + struct drm_encoder *encoder =3D bridge_connector->encoder; + struct drm_bridge *bridge; + + list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) { + if (bridge->funcs->debugfs_init) + bridge->funcs->debugfs_init(bridge, root); + } +} + static const struct drm_connector_funcs drm_bridge_connector_funcs =3D { .reset =3D drm_atomic_helper_connector_reset, .detect =3D drm_bridge_connector_detect, @@ -223,6 +237,7 @@ static const struct drm_connector_funcs drm_bridge_conn= ector_funcs =3D { .destroy =3D drm_bridge_connector_destroy, .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, + .debugfs_init =3D drm_bridge_connector_debugfs_init, }; =20 /* -----------------------------------------------------------------------= ------ diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index b0a826489488..7f1b82dbaebb 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -436,6 +436,9 @@ void drm_debugfs_connector_add(struct drm_connector *co= nnector) /* vrr range */ debugfs_create_file("vrr_range", S_IRUGO, root, connector, &vrr_range_fops); + + if (connector->funcs->debugfs_init) + connector->funcs->debugfs_init(connector, root); } =20 void drm_debugfs_connector_remove(struct drm_connector *connector) diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 061d87313fac..f27b4060faa2 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -649,6 +649,13 @@ struct drm_bridge_funcs { * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. */ void (*hpd_disable)(struct drm_bridge *bridge); + + /** + * @debugfs_init: + * + * Allows bridges to create bridge-specific debugfs files. + */ + void (*debugfs_init)(struct drm_bridge *bridge, struct dentry *root); }; =20 /** diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 64cf5f88c05b..54429dde744a 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1142,6 +1142,13 @@ struct drm_connector_funcs { * has been received from a source outside the display driver / device. */ void (*oob_hotplug_event)(struct drm_connector *connector); + + /** + * @debugfs_init: + * + * Allows connectors to create connector-specific debugfs files. + */ + void (*debugfs_init)(struct drm_connector *connector, struct dentry *root= ); }; =20 /** diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 4602f833eb51..1ba2d424a53f 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -29,6 +29,7 @@ #include =20 struct backlight_device; +struct dentry; struct device_node; struct drm_connector; struct drm_device; @@ -125,6 +126,13 @@ struct drm_panel_funcs { */ int (*get_timings)(struct drm_panel *panel, unsigned int num_timings, struct display_timing *timings); + + /** + * @debugfs_init: + * + * Allows panels to create panels-specific debugfs files. + */ + void (*debugfs_init)(struct drm_panel *panel, struct dentry *root); }; =20 /** --=20 2.35.0.263.gb82422642f-goog From nobody Mon Jun 29 17:36:49 2026 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 545DCC433EF for ; Sat, 5 Feb 2022 00:14:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378737AbiBEAOY (ORCPT ); Fri, 4 Feb 2022 19:14:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1378710AbiBEAOQ (ORCPT ); Fri, 4 Feb 2022 19:14:16 -0500 Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B3E7DF8C1BE for ; Fri, 4 Feb 2022 16:14:14 -0800 (PST) Received: by mail-pg1-x534.google.com with SMTP id d186so6294747pgc.9 for ; Fri, 04 Feb 2022 16:14:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JSn2M/yKAMsfnGZFwHB10y6iqnXx4FF2oGb2lIsnFpI=; b=lbZTKKPzut0pSDp0PGEfSw3i5JnQ5JXUOvWVZ6Bqe23XIqEF6A2W1GMcYGs4LM94eq 1tgtOTcFBq6W1UWg5oKNaKKyOSErFWPClzvAqvTWGYekDZykaMBZ7OGE6HsZzPuqH8ec VHPh6nksgC3cBqMWKW3nX7/jZgVqlYWTuHtTs= 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=JSn2M/yKAMsfnGZFwHB10y6iqnXx4FF2oGb2lIsnFpI=; b=NKkaFVvgnSCYaCTleAGEfbb8tRhye/LSel5Oxm1IxNH4K+u3ezxDBE2AJhX6blJwc9 JZfZKSz8mUSmcVSnNNw2yazGe/gmGVG0VUrZc69++pidVz9nP2R/CglbAZRyBR028O6j nbvEe9s3bCKNGFuXGnEbXmZ3xaoe7stxZZlIem6IHLzD+eksSNHK2h8BzNFWH+OtXNaj 2IKa7mVi/u2nsuSoJB+5UxLFUtP4vftfAHae1VyqKAXhHgXMIWFR0hviddQf9XcZQ20n NujHDx6r+bRHAtgYMAkP132lg8VIJa130Nza4W6kyAiCPjVL+l1eZo/cy5vMhd+771cT ltog== X-Gm-Message-State: AOAM532NWAsvAFS8WK7WVkrnypzytXmXHeR6uTdN0AtnUo/rHWWdXBTg Z3w/cFVP2Iap2oLrTOzuo36q7w== X-Google-Smtp-Source: ABdhPJxn/GCPUuG4dWCd6GKM189yB7c+AgTeBQ6yKeW1fQ/otXDa51dtaC8z5cJVw357oaP3WHq34w== X-Received: by 2002:a05:6a00:1810:: with SMTP id y16mr5530158pfa.65.1644020053748; Fri, 04 Feb 2022 16:14:13 -0800 (PST) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:d668:55ac:a465:88bf]) by smtp.gmail.com with ESMTPSA id q13sm3720231pfj.44.2022.02.04.16.14.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Feb 2022 16:14:13 -0800 (PST) From: Douglas Anderson To: dri-devel@lists.freedesktop.org Cc: Daniel Vetter , Javier Martinez Canillas , robert.foss@linaro.org, lschyi@chromium.org, Sam Ravnborg , jjsu@chromium.org, Douglas Anderson , David Airlie , Thierry Reding , linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] drm/panel-edp: Allow querying the detected panel via debugfs Date: Fri, 4 Feb 2022 16:13:42 -0800 Message-Id: <20220204161245.v2.3.I209d72bcc571e1d7d6b793db71bf15c9c0fc9292@changeid> X-Mailer: git-send-email 2.35.0.263.gb82422642f-goog In-Reply-To: <20220205001342.3155839-1-dianders@chromium.org> References: <20220205001342.3155839-1-dianders@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Recently we added generic "edp-panel"s probed by EDID. To support panels in this way we look at the panel ID in the EDID and look up the panel in a table that has power sequence timings. If we find a panel that's not in the table we will still attempt to use it but we'll use conservative timings. While it's likely that these conservative timings will work for most nearly all panels, the performance of turning the panel off and on suffers. We'd like to be able to reliably detect the case that we're using the hardcoded timings without relying on parsing dmesg. This allows us to implement tests that ensure that no devices get shipped that are relying on the conservative timings. Let's add a new debugfs entry to panel devices. It will have one of: * UNKNOWN - We tried to detect a panel but it wasn't in our table. * HARDCODED - We're not using generic "edp-panel" probed by EDID. * A panel name - This is the name of the panel from our table. Signed-off-by: Douglas Anderson Reviewed-by: Javier Martinez Canillas --- Changes in v2: - Now using debugfs, not sysfs drivers/gpu/drm/panel/panel-edp.c | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/pane= l-edp.c index a394a15dc3fb..0fda1eb7b690 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ =20 +#include #include #include #include @@ -222,6 +223,8 @@ struct panel_edp { struct gpio_desc *enable_gpio; struct gpio_desc *hpd_gpio; =20 + const struct edp_panel_entry *detected_panel; + struct edid *edid; =20 struct drm_display_mode override_mode; @@ -606,6 +609,28 @@ static int panel_edp_get_timings(struct drm_panel *pan= el, return p->desc->num_timings; } =20 +static int detected_panel_show(struct seq_file *s, void *data) +{ + struct drm_panel *panel =3D s->private; + struct panel_edp *p =3D to_panel_edp(panel); + + if (IS_ERR(p->detected_panel)) + seq_puts(s, "UNKNOWN\n"); + else if (!p->detected_panel) + seq_puts(s, "HARDCODED\n"); + else + seq_printf(s, "%s\n", p->detected_panel->name); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(detected_panel); + +static void panel_edp_debugfs_init(struct drm_panel *panel, struct dentry = *root) +{ + debugfs_create_file("detected_panel", 0600, root, panel, &detected_panel_= fops); +} + static const struct drm_panel_funcs panel_edp_funcs =3D { .disable =3D panel_edp_disable, .unprepare =3D panel_edp_unprepare, @@ -613,6 +638,7 @@ static const struct drm_panel_funcs panel_edp_funcs =3D= { .enable =3D panel_edp_enable, .get_modes =3D panel_edp_get_modes, .get_timings =3D panel_edp_get_timings, + .debugfs_init =3D panel_edp_debugfs_init, }; =20 #define PANEL_EDP_BOUNDS_CHECK(to_check, bounds, field) \ @@ -666,7 +692,6 @@ static const struct edp_panel_entry *find_edp_panel(u32= panel_id); =20 static int generic_edp_panel_probe(struct device *dev, struct panel_edp *p= anel) { - const struct edp_panel_entry *edp_panel; struct panel_desc *desc; u32 panel_id; char vend[4]; @@ -705,14 +730,14 @@ static int generic_edp_panel_probe(struct device *dev= , struct panel_edp *panel) } drm_edid_decode_panel_id(panel_id, vend, &product_id); =20 - edp_panel =3D find_edp_panel(panel_id); + panel->detected_panel =3D find_edp_panel(panel_id); =20 /* * We're using non-optimized timings and want it really obvious that * someone needs to add an entry to the table, so we'll do a WARN_ON * splat. */ - if (WARN_ON(!edp_panel)) { + if (WARN_ON(!panel->detected_panel)) { dev_warn(dev, "Unknown panel %s %#06x, using conservative timings\n", vend, product_id); @@ -734,12 +759,14 @@ static int generic_edp_panel_probe(struct device *dev= , struct panel_edp *panel) */ desc->delay.unprepare =3D 2000; desc->delay.enable =3D 200; + + panel->detected_panel =3D ERR_PTR(-EINVAL); } else { dev_info(dev, "Detected %s %s (%#06x)\n", - vend, edp_panel->name, product_id); + vend, panel->detected_panel->name, product_id); =20 /* Update the delay; everything else comes from EDID */ - desc->delay =3D *edp_panel->delay; + desc->delay =3D *panel->detected_panel->delay; } =20 ret =3D 0; --=20 2.35.0.263.gb82422642f-goog