From patchwork Sat Feb 19 00:28:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 12752028 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 24174C433F5 for ; Sat, 19 Feb 2022 00:29:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0F5C610EAD0; Sat, 19 Feb 2022 00:29:29 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0FEAB10E1CE for ; Sat, 19 Feb 2022 00:29:06 +0000 (UTC) Received: from tr.lan (ip-89-176-112-137.net.upcbroadband.cz [89.176.112.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id A6E8283B93; Sat, 19 Feb 2022 01:29:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1645230544; bh=L+B1tFSSDDT9W0fLMjFIiTtoyd9xng4Xae+xdTJ9xMY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i9oD1qLDAcww9/hUQEEUfGmi97kIaf2uiwgtoLFWzL/nKPvhfggJ7dhbgvWCx4JMk NgFDoXQtCWGVkgSPZRsHWNXBu38WFgWON0gKETOPjVUDii+rQMXiPLs1F/h9mItT+u T/Sy0F7u4LkSQzG/2JEWR+hcnq0Cw1ROR2wwMJuyaZyLehrJ3b50moNIqgf9+lvCX6 cOgP8TBITyXwBe3XhT3KjdxFCM8l+DMPKHnP+sR5ijiXFI9YCIPyhxdI7VNvJT5ig+ LtJ6IBr84L1NA+yhJhbyw3zmtV1bKOHESFZauGiAHN866SvoK0IdDgP5Z4qttXWpzH 0IB76BY5BMD0w== From: Marek Vasut To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/7] drm/bridge: Pass struct drm_bus_cfg to select_bus_fmt_recursive() Date: Sat, 19 Feb 2022 01:28:38 +0100 Message-Id: <20220219002844.362157-2-marex@denx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219002844.362157-1-marex@denx.de> References: <20220219002844.362157-1-marex@denx.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Neil Armstrong , Sam Ravnborg , Laurent Pinchart , Maxime Ripard Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Pass the entire struct drm_bus_cfg {} to select_bus_fmt_recursive() instead of only u32 out_bus_fmt which contains only the pixel format. This would permit passing more bus format data around during the bridge-to-bridge format negotiation. Signed-off-by: Marek Vasut Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Neil Armstrong Cc: Sam Ravnborg --- drivers/gpu/drm/drm_bridge.c | 39 +++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebcb..f052d50106758 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -821,11 +821,13 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, struct drm_bridge *cur_bridge, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state, - u32 out_bus_fmt) + struct drm_bus_cfg *out_bus_cfg) { struct drm_bridge_state *cur_state; unsigned int num_in_bus_fmts, i; struct drm_bridge *prev_bridge; + struct drm_bus_cfg fixed_bus_cfg; + struct drm_bus_cfg *in_bus_cfgs; u32 *in_bus_fmts; int ret; @@ -841,10 +843,11 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, */ if (!cur_bridge->funcs->atomic_get_input_bus_fmts) { if (cur_bridge != first_bridge) { + fixed_bus_cfg.format = MEDIA_BUS_FMT_FIXED; ret = select_bus_fmt_recursive(first_bridge, prev_bridge, crtc_state, conn_state, - MEDIA_BUS_FMT_FIXED); + &fixed_bus_cfg); if (ret) return ret; } @@ -855,7 +858,7 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, */ if (cur_state) { cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED; - cur_state->output_bus_cfg.format = out_bus_fmt; + cur_state->output_bus_cfg.format = out_bus_cfg->format; } return 0; @@ -872,34 +875,44 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, cur_state, crtc_state, conn_state, - out_bus_fmt, + out_bus_cfg->format, &num_in_bus_fmts); if (!num_in_bus_fmts) return -ENOTSUPP; else if (!in_bus_fmts) return -ENOMEM; + /* Transcribe in_bus_fmts to in_bus_cfgs */ + in_bus_cfgs = kcalloc(num_in_bus_fmts, sizeof(*in_bus_cfgs), GFP_KERNEL); + if (!in_bus_cfgs) + return -ENOMEM; + + for (i = 0; i < num_in_bus_fmts; i++) + in_bus_cfgs[i].format = in_bus_fmts[i]; + + kfree(in_bus_fmts); + if (first_bridge == cur_bridge) { - cur_state->input_bus_cfg.format = in_bus_fmts[0]; - cur_state->output_bus_cfg.format = out_bus_fmt; - kfree(in_bus_fmts); + cur_state->input_bus_cfg.format = in_bus_cfgs[0].format; + cur_state->output_bus_cfg.format = out_bus_cfg->format; + kfree(in_bus_cfgs); return 0; } for (i = 0; i < num_in_bus_fmts; i++) { ret = select_bus_fmt_recursive(first_bridge, prev_bridge, crtc_state, conn_state, - in_bus_fmts[i]); + &(in_bus_cfgs[i])); if (ret != -ENOTSUPP) break; } if (!ret) { - cur_state->input_bus_cfg.format = in_bus_fmts[i]; - cur_state->output_bus_cfg.format = out_bus_fmt; + cur_state->input_bus_cfg.format = in_bus_cfgs[i].format; + cur_state->output_bus_cfg.format = out_bus_cfg->format; } - kfree(in_bus_fmts); + kfree(in_bus_cfgs); return ret; } @@ -947,6 +960,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, struct drm_bridge_state *last_bridge_state; unsigned int i, num_out_bus_fmts; struct drm_bridge *last_bridge; + struct drm_bus_cfg out_bus_cfg; u32 *out_bus_fmts; int ret = 0; @@ -988,8 +1002,9 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, } for (i = 0; i < num_out_bus_fmts; i++) { + out_bus_cfg.format = out_bus_fmts[i]; ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state, - conn_state, out_bus_fmts[i]); + conn_state, &out_bus_cfg); if (ret != -ENOTSUPP) break; } From patchwork Sat Feb 19 00:28:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 12752029 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5ADCDC433F5 for ; Sat, 19 Feb 2022 00:29:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 566E610EC04; Sat, 19 Feb 2022 00:29:35 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0F6B910E180 for ; Sat, 19 Feb 2022 00:29:06 +0000 (UTC) Received: from tr.lan (ip-89-176-112-137.net.upcbroadband.cz [89.176.112.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 15DBF83B9B; Sat, 19 Feb 2022 01:29:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1645230544; bh=0ESrqcar5CMMLHRigFsBSOOSdNLNe6yhKBL5yl8yX3U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YptVKqHqMJfyOsTxBdQWoS23C6WsVilLeXDy5t94ySMOyjKqDbDyw89KYNlfGV6fS nENVdtdg5dHFxZSlUerFGNVp6wKxeHvUEU+YlTG26JlQKKOCvtkMFMPz4ksCQN0kr6 mhbMdRTeA48Av3CdZkEJm7aE9VsyGqlpICX0eHLxxuhhhrqs73Ve+1XknEWPbocXFb cqQrUgD/QOgrprvg+4aCRPWumjuBoxdCpwbDrLXDcs0tai5peHfBgVky/Hh/ujdmq2 eSpLQj9IQqDchEJLgK7IwLkDitbl3RqHdPc371fQdqxVDeXgnRcYNgFo8zAvC5s5rA E+28noutAMH4w== From: Marek Vasut To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/7] drm/bridge: Add new atomic_get_input_bus_cfgs callback Date: Sat, 19 Feb 2022 01:28:39 +0100 Message-Id: <20220219002844.362157-3-marex@denx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219002844.362157-1-marex@denx.de> References: <20220219002844.362157-1-marex@denx.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Neil Armstrong , Sam Ravnborg , Laurent Pinchart , Maxime Ripard Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add new .atomic_get_input_bus_cfgs callback into struct drm_bridge_funcs {}. This is an extended version of .atomic_get_input_bus_fmts callback which only returns list of bus formats supported by a bridge and provides no way to e.g. limit clock frequency required between neighboring bridges. The new .atomic_get_input_bus_cfgs callback returns list of struct drm_bus_cfg, which currently contains format and bus flags, but can be extended with other members, like desired clock frequency, as required. The .atomic_get_input_bus_cfgs should replace the .atomic_get_input_bus_fmts once drivers get converted over. The conversion could be done using a script. Signed-off-by: Marek Vasut Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Neil Armstrong Cc: Sam Ravnborg --- drivers/gpu/drm/drm_bridge.c | 47 ++++++++++++++++++++++++------------ include/drm/drm_bridge.h | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index f052d50106758..a069c50cc7d6b 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -841,7 +841,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, * hope that it can handle this situation gracefully (by providing * appropriate default values). */ - if (!cur_bridge->funcs->atomic_get_input_bus_fmts) { + if (!cur_bridge->funcs->atomic_get_input_bus_cfgs && + !cur_bridge->funcs->atomic_get_input_bus_fmts) { if (cur_bridge != first_bridge) { fixed_bus_cfg.format = MEDIA_BUS_FMT_FIXED; ret = select_bus_fmt_recursive(first_bridge, @@ -865,32 +866,48 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, } /* - * If the driver implements ->atomic_get_input_bus_fmts() it - * should also implement the atomic state hooks. + * If the driver implements ->atomic_get_input_bus_cfgs() + * or legacy ->atomic_get_input_bus_fmts() it should also + * implement the atomic state hooks. */ if (WARN_ON(!cur_state)) return -EINVAL; - in_bus_fmts = cur_bridge->funcs->atomic_get_input_bus_fmts(cur_bridge, + if (cur_bridge->funcs->atomic_get_input_bus_cfgs) { + in_bus_cfgs = cur_bridge->funcs->atomic_get_input_bus_cfgs( + cur_bridge, + cur_state, + crtc_state, + conn_state, + out_bus_cfg, + &num_in_bus_fmts); + if (!num_in_bus_fmts) + return -ENOTSUPP; + else if (!in_bus_cfgs) + return -ENOMEM; + } else { + in_bus_fmts = cur_bridge->funcs->atomic_get_input_bus_fmts( + cur_bridge, cur_state, crtc_state, conn_state, out_bus_cfg->format, &num_in_bus_fmts); - if (!num_in_bus_fmts) - return -ENOTSUPP; - else if (!in_bus_fmts) - return -ENOMEM; + if (!num_in_bus_fmts) + return -ENOTSUPP; + else if (!in_bus_fmts) + return -ENOMEM; - /* Transcribe in_bus_fmts to in_bus_cfgs */ - in_bus_cfgs = kcalloc(num_in_bus_fmts, sizeof(*in_bus_cfgs), GFP_KERNEL); - if (!in_bus_cfgs) - return -ENOMEM; + /* Transcribe in_bus_fmts to in_bus_cfgs */ + in_bus_cfgs = kcalloc(num_in_bus_fmts, sizeof(*in_bus_cfgs), GFP_KERNEL); + if (!in_bus_cfgs) + return -ENOMEM; - for (i = 0; i < num_in_bus_fmts; i++) - in_bus_cfgs[i].format = in_bus_fmts[i]; + for (i = 0; i < num_in_bus_fmts; i++) + in_bus_cfgs[i].format = in_bus_fmts[i]; - kfree(in_bus_fmts); + kfree(in_bus_fmts); + } if (first_bridge == cur_bridge) { cur_state->input_bus_cfg.format = in_bus_cfgs[0].format; diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 061d87313fac9..b2fe0ee7294b5 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -439,6 +439,48 @@ struct drm_bridge_funcs { struct drm_connector_state *conn_state, unsigned int *num_output_fmts); + /** + * @atomic_get_input_bus_cfgs: + * + * Return the supported bus configurations on the input end of a bridge + * for a specific output bus format. + * + * The returned array must be allocated with kmalloc() and will be + * freed by the caller. If the allocation fails, NULL should be + * returned. num_output_fmts must be set to the returned array size. + * Formats listed in the returned array should be listed in decreasing + * preference order (the core will try all formats until it finds one + * that works). When the format is not supported NULL should be + * returned and num_output_fmts should be set to 0. + * + * This method is called on all elements of the bridge chain as part of + * the bus format negotiation process that happens in + * drm_atomic_bridge_chain_select_bus_fmts(). + * This method is optional. When not implemented, the core will bypass + * bus format negotiation on this element of the bridge without + * failing, and the previous element in the chain will be passed + * MEDIA_BUS_FMT_FIXED as its output bus format. + * + * Bridge drivers that need to support being linked to bridges that are + * not supporting bus format negotiation should handle the + * output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a + * sensible default value or extracting this information from somewhere + * else (FW property, &drm_display_mode, &drm_display_info, ...) + * + * Note: Even if input format selection on the first bridge has no + * impact on the negotiation process (bus format negotiation stops once + * we reach the first element of the chain), drivers are expected to + * return accurate input formats as the input format may be used to + * configure the CRTC output appropriately. + */ + struct drm_bus_cfg *(*atomic_get_input_bus_cfgs) + (struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + struct drm_bus_cfg *output_cfg, + unsigned int *num_input_cfgs); + /** * @atomic_get_input_bus_fmts: * From patchwork Sat Feb 19 00:28:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 12752024 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 91377C433F5 for ; Sat, 19 Feb 2022 00:29:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D9A6C10E180; Sat, 19 Feb 2022 00:29:10 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) by gabe.freedesktop.org (Postfix) with ESMTPS id 126E610EA7E for ; Sat, 19 Feb 2022 00:29:06 +0000 (UTC) Received: from tr.lan (ip-89-176-112-137.net.upcbroadband.cz [89.176.112.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 767D383B9F; Sat, 19 Feb 2022 01:29:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1645230544; bh=Npyt74H0xfvsIzBT3cAcKU1K4YM4l/gvVblubqCNQ2Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MF5LzCyJX3sMyjwBL3rxztmHP2lcYQQBa3UawEUHYnO3kJWhVrMKE75OhDlsyOZeJ mxciAMj+hx5mw56nQOUgT29kEwRJpKenvTbAa9FHmwAlJgvZdo2tbasIieOAEPyLoT S18mS6605u+zIwAy4IZYkTgBQVN8SI1ket+XFErRy/IX5JqqVvj9vlKcLrB3tQRzP1 F7ZgTqvej03n9mCixhvxHiHpra/Ct6pWlRXSDRq02ImlQdiq8DZCi/k9epAsf7Gqr1 PRV29PdPKa3+5ZSVmIpwOCzWTC4UiqAK9Iqc7zGa8DBY4KzKA3CeHhdaZxJ90waxYR vG3ChuBcSFnew== From: Marek Vasut To: dri-devel@lists.freedesktop.org Subject: [PATCH 3/7] drm/bridge: Extend struct drm_bus_cfg with clock field Date: Sat, 19 Feb 2022 01:28:40 +0100 Message-Id: <20220219002844.362157-4-marex@denx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219002844.362157-1-marex@denx.de> References: <20220219002844.362157-1-marex@denx.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Neil Armstrong , Sam Ravnborg , Laurent Pinchart , Maxime Ripard Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Extend struct drm_bus_cfg with a clock field. This makes it possible for an upstream bridge (further from scanout engine) to indicate to a downstream bridge which frequency it expects on a link. This is particularly useful in case of DSI bridges which derive their own internal clock from the DSI HS clock. Signed-off-by: Marek Vasut Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Neil Armstrong Cc: Sam Ravnborg --- drivers/gpu/drm/drm_bridge.c | 6 ++++++ include/drm/drm_atomic.h | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index a069c50cc7d6b..6a5981b82499a 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -859,7 +859,9 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, */ if (cur_state) { cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED; + cur_state->input_bus_cfg.clock = 0; cur_state->output_bus_cfg.format = out_bus_cfg->format; + cur_state->output_bus_cfg.clock = out_bus_cfg->clock; } return 0; @@ -911,7 +913,9 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, if (first_bridge == cur_bridge) { cur_state->input_bus_cfg.format = in_bus_cfgs[0].format; + cur_state->input_bus_cfg.clock = in_bus_cfgs[0].clock; cur_state->output_bus_cfg.format = out_bus_cfg->format; + cur_state->output_bus_cfg.clock = out_bus_cfg->clock; kfree(in_bus_cfgs); return 0; } @@ -926,7 +930,9 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, if (!ret) { cur_state->input_bus_cfg.format = in_bus_cfgs[i].format; + cur_state->input_bus_cfg.clock = in_bus_cfgs[i].clock; cur_state->output_bus_cfg.format = out_bus_cfg->format; + cur_state->output_bus_cfg.clock = out_bus_cfg->clock; } kfree(in_bus_cfgs); diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 1701c2128a5cb..32455cf28f0bc 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -1077,6 +1077,11 @@ struct drm_bus_cfg { * @flags: DRM_BUS_* flags used on this bus */ u32 flags; + + /** + * @clock: Clock frequency in kHz used on this bus + */ + u32 clock; }; /** From patchwork Sat Feb 19 00:28:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 12752027 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EDD81C433EF for ; Sat, 19 Feb 2022 00:29:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0BDF110EABB; Sat, 19 Feb 2022 00:29:28 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8260D10EA7E for ; Sat, 19 Feb 2022 00:29:06 +0000 (UTC) Received: from tr.lan (ip-89-176-112-137.net.upcbroadband.cz [89.176.112.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id D7E9683BA2; Sat, 19 Feb 2022 01:29:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1645230545; bh=omuqhxDL60Kp051Ey9wmAuH7K5IB+pkShX1jBNb3Vao=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TIYSbxV1r3DfljFY2Rt94D2wpAV0yEX5LGZF8Jyqu2y5aG92IdnCPT7CBVrtsgG2L FyKavkPO8089UbveBGZvG6O1dBKtFjHT29GfFQnTOcbuq9MZHlrMRsFqI2anciqij/ Qhu5K8PCzjr55rUYmz3f2m/lpZE8FBpjXsdA5jgaVWb/Gz41J7dWnEtXcM6JnAYyJw X/NZF0WFgXUaE1ROUmBdzZqpMhXZY28vylKNNNfdnJWlNnHrnD0mnFgNwaLXznbH+c jYNBdt71Pom6lvvAWicoBsXkqA7dBlxNo55+P7zuhmZsQZ4Mdqd5+sDEbT5ysTEBV2 /pJOL0zRKrFEg== From: Marek Vasut To: dri-devel@lists.freedesktop.org Subject: [PATCH 4/7] drm/bridge: dw-mipi-dsi: Move PLL setup into atomic_enable Date: Sat, 19 Feb 2022 01:28:41 +0100 Message-Id: <20220219002844.362157-5-marex@denx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219002844.362157-1-marex@denx.de> References: <20220219002844.362157-1-marex@denx.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Neil Armstrong , Sam Ravnborg , Laurent Pinchart , Maxime Ripard Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The bridge clock configuration should happen in atomic_enable instead of mode_set callback, since that is where the current state of the bridge is available. Move the clock configuration into atomic_enable callback. Signed-off-by: Marek Vasut Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Neil Armstrong Cc: Sam Ravnborg --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index f4a6e4da903ca..7a2ea21dc0554 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -267,6 +267,8 @@ struct dw_mipi_dsi { u32 format; unsigned long mode_flags; + struct drm_display_mode mode; + #ifdef CONFIG_DEBUG_FS struct dentry *debugfs; struct debugfs_entries *debugfs_vpg; @@ -1045,15 +1047,18 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge, { struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); - dw_mipi_dsi_mode_set(dsi, adjusted_mode); - if (dsi->slave) - dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode); + drm_mode_copy(&dsi->mode, adjusted_mode); } static void dw_mipi_dsi_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state) { struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + const struct drm_display_mode *adjusted_mode = &dsi->mode; + + dw_mipi_dsi_mode_set(dsi, adjusted_mode); + if (dsi->slave) + dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode); /* Switch to video mode for panel-bridge enable & panel enable */ dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO); From patchwork Sat Feb 19 00:28:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 12752023 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3A408C433EF for ; Sat, 19 Feb 2022 00:29:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0D6BA10EA81; Sat, 19 Feb 2022 00:29:11 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) by gabe.freedesktop.org (Postfix) with ESMTPS id 158A810E180 for ; Sat, 19 Feb 2022 00:29:07 +0000 (UTC) Received: from tr.lan (ip-89-176-112-137.net.upcbroadband.cz [89.176.112.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 435F083BA4; Sat, 19 Feb 2022 01:29:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1645230545; bh=TJrz5MRroQ1rrJuEeruRRzLmqQK9W6OltcpoMMGR1Ug=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uv3SnF0byH1Henb/3eOteBagMRCPZ6ym3sl87bnAH9PwpzsfMhvk8xhFuxHJe6euQ oEIKkIc4DSWUPNy7JaO8z/yo3r76Gmlb+4ZgKu8CHG1Edqfz5PzD7kFo47kQWCcOt1 bVN6hJfX1UTI3rB95u++zV6NiDo4Q3W5iRu0daDklOO0A1/0+YhAv5tvz4E2a8TV+k 0/EPwQtsfb7quKwncoNNyy/p5za0Fj2DYD1gyPwb3Wzszkdu+k2CuIoGSZ7M48xONM egbmX0ZYuR2TsHZBPsgX22joiucH8GP68H//9dXuVPI8Ye1fx4JAHPHY7I3eeo6QRC 8facyH28bXM+Q== From: Marek Vasut To: dri-devel@lists.freedesktop.org Subject: [PATCH 5/7] drm/bridge: dw-mipi-dsi: Pass bridge state into dw_mipi_dsi_get_lane_mbps() Date: Sat, 19 Feb 2022 01:28:42 +0100 Message-Id: <20220219002844.362157-6-marex@denx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219002844.362157-1-marex@denx.de> References: <20220219002844.362157-1-marex@denx.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Neil Armstrong , Sam Ravnborg , Laurent Pinchart , Maxime Ripard Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Pass negotiated bridge state, which now optionally contains required DSI bus clock, into dw_mipi_dsi_get_lane_mbps(). The dw_mipi_dsi_get_lane_mbps() is a misnomer, it is also responsible for configuration of the bridge PLL and thus also configuration of the clock the bridge outputs on the DSI bus. Signed-off-by: Marek Vasut Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Neil Armstrong Cc: Sam Ravnborg --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 15 ++++++++++----- drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 1 + drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 1 + include/drm/bridge/dw_mipi_dsi.h | 2 ++ 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 7a2ea21dc0554..d5f3c98cefdb5 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -996,7 +996,8 @@ static unsigned int dw_mipi_dsi_get_lanes(struct dw_mipi_dsi *dsi) } static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi, - const struct drm_display_mode *adjusted_mode) + const struct drm_display_mode *adjusted_mode, + const struct drm_bridge_state *bridge_state) { const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops; void *priv_data = dsi->plat_data->priv_data; @@ -1005,8 +1006,9 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi, clk_prepare_enable(dsi->pclk); - ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi->mode_flags, - lanes, dsi->format, &dsi->lane_mbps); + ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, bridge_state, + dsi->mode_flags, lanes, dsi->format, + &dsi->lane_mbps); if (ret) DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n"); @@ -1054,11 +1056,14 @@ static void dw_mipi_dsi_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state) { struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + struct drm_atomic_state *state = old_bridge_state->base.state; + const struct drm_bridge_state *bridge_state; const struct drm_display_mode *adjusted_mode = &dsi->mode; + bridge_state = drm_atomic_get_new_bridge_state(state, bridge); - dw_mipi_dsi_mode_set(dsi, adjusted_mode); + dw_mipi_dsi_mode_set(dsi, adjusted_mode, bridge_state); if (dsi->slave) - dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode); + dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode, bridge_state); /* Switch to video mode for panel-bridge enable & panel enable */ dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO); diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 4ed7a68681978..39965e0d16c95 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -526,6 +526,7 @@ static void dw_mipi_dsi_phy_power_off(void *priv_data) static int dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, + const struct drm_bridge_state *bridge_state, unsigned long mode_flags, u32 lanes, u32 format, unsigned int *lane_mbps) { diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c index 32cb41b2202fe..0132e576339dd 100644 --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -239,6 +239,7 @@ static void dw_mipi_dsi_phy_power_off(void *priv_data) static int dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, + const struct drm_bridge_state *bridge_state, unsigned long mode_flags, u32 lanes, u32 format, unsigned int *lane_mbps) { diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index 5286a53a1875d..f449ff36c4653 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -11,6 +11,7 @@ #include +#include #include struct drm_display_mode; @@ -32,6 +33,7 @@ struct dw_mipi_dsi_phy_ops { void (*power_off)(void *priv_data); int (*get_lane_mbps)(void *priv_data, const struct drm_display_mode *mode, + const struct drm_bridge_state *bridge_state, unsigned long mode_flags, u32 lanes, u32 format, unsigned int *lane_mbps); int (*get_timing)(void *priv_data, unsigned int lane_mbps, From patchwork Sat Feb 19 00:28:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 12752026 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4E7C8C433FE for ; Sat, 19 Feb 2022 00:29:22 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 80C7610EAA1; Sat, 19 Feb 2022 00:29:11 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4694A10EA7E for ; Sat, 19 Feb 2022 00:29:07 +0000 (UTC) Received: from tr.lan (ip-89-176-112-137.net.upcbroadband.cz [89.176.112.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id A138683BA7; Sat, 19 Feb 2022 01:29:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1645230545; bh=8G+mZS1H1Dpc2GiUJHF619u1Fp150ZofVi99t8q/8Cs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hJ7qKpA8wVBYYMuPZQT9HLs7E4tm5dueRy4rvqA/T4RyCbACumqJozwtwfuRwv/Ot VAbcG1W3GWrGE+hjGRcO9zC4TQJlBgJzo5zwIC2I9+9K2CTHBj0PfkH+Nd4dEGSIi9 FUnkTcg5i3jqrh7uFiTp6FFzb0jPChGAEb+glqi+PnRddp4nzRmlCuvuRjs8oU48HZ thFvecUvaNoQ7cfEe3o/cvz2vM1Cl8iLT+t4sF0XzSjc7h9zHdnXgwZjxUqIdCwWkJ dHuJhubWpB/RVsFIbqrij7yZ7ik7mjogxwQ9oGhMkl5utQPT+UAs48wQbRk/1Hl1wQ JyVFeH5f3861A== From: Marek Vasut To: dri-devel@lists.freedesktop.org Subject: [PATCH 6/7] drm/bridge: dw-mipi-dsi: Prefer DSI bus clock settings from bridge_state Date: Sat, 19 Feb 2022 01:28:43 +0100 Message-Id: <20220219002844.362157-7-marex@denx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219002844.362157-1-marex@denx.de> References: <20220219002844.362157-1-marex@denx.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Neil Armstrong , Sam Ravnborg , Laurent Pinchart , Maxime Ripard Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The bridge_state now contains clock frequency required by the next bridge. This information is optional, since very few drivers pass this information now. In case the required clock frequency is part of bridge state, use it for the DSI bus clock frequency, otherwise fall back to the old guesswork. Signed-off-by: Marek Vasut Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Neil Armstrong Cc: Sam Ravnborg --- drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c index 0132e576339dd..e3fea94db9bfa 100644 --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -258,13 +258,17 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000); - /* Compute requested pll out */ - bpp = mipi_dsi_pixel_format_to_bpp(format); - pll_out_khz = mode->clock * bpp / lanes; + pll_out_khz = bridge_state->output_bus_cfg.clock; - /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ - if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST) - pll_out_khz = (pll_out_khz * 12) / 10; + if (pll_out_khz == 0) { + /* Guess requested pll out */ + bpp = mipi_dsi_pixel_format_to_bpp(format); + pll_out_khz = mode->clock * bpp / lanes; + + /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ + if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST) + pll_out_khz = (pll_out_khz * 12) / 10; + } if (pll_out_khz > dsi->lane_max_kbps) { pll_out_khz = dsi->lane_max_kbps; From patchwork Sat Feb 19 00:28:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 12752025 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 05EA0C433EF for ; Sat, 19 Feb 2022 00:29:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0944F10EA7E; Sat, 19 Feb 2022 00:29:11 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) by gabe.freedesktop.org (Postfix) with ESMTPS id A459E10E180 for ; Sat, 19 Feb 2022 00:29:07 +0000 (UTC) Received: from tr.lan (ip-89-176-112-137.net.upcbroadband.cz [89.176.112.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 0864583BB0; Sat, 19 Feb 2022 01:29:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1645230546; bh=OCkQAsxoUpuY5fWMkO0fSy3ic5e8fU+Ljiosq6sOEfg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZMnNyNGo8pdo1XDaHMNTZqw0hg5ozz7zt/H/mLxWP7EaEmKGqsT2f7Zw/jI7mHOUn YCp0SSR8ze36rKTnchQHlWi4iTWb12aJfx3sI2DL9wJdrz6CoC+g8n/t91D3/sHn4p PdLnuzAnchXcND/ahCQxHWLHKY3npVQa9uZW4KnNivO/CNS40uWibpHaR2aNk8+bad ChgGJaCwRFYoH7ES4ifS9/XHngQgmBm9Yl2D0mARuU7Rn+qm2id0zdER5DyAG+UG6S kCoSFmWGfX/A7pP5Jr5rSWa+L7E0qheUR4yAoM7dr2HPtBk40JNf95VTCVpqoe5e1V yMS3IuenJzphA== From: Marek Vasut To: dri-devel@lists.freedesktop.org Subject: [PATCH 7/7] drm/bridge: tc358767: Add support for PLL clock derivation from DSI HS clock Date: Sat, 19 Feb 2022 01:28:44 +0100 Message-Id: <20220219002844.362157-8-marex@denx.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219002844.362157-1-marex@denx.de> References: <20220219002844.362157-1-marex@denx.de> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Neil Armstrong , Jonas Karlman , Laurent Pinchart , Sam Ravnborg , Maxime Ripard Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The TC358767/TC358867/TC9595 are all capable of operating without RefClk Xtal in DSI-to-DPI mode. In this mode of operation, the chip PLLs are fed with clock derived from the DSI HS clock. The SYSPLL is fed from DSI HS clock divided by 2*7 and the resulting clock must match the allowed RefClk supported by the chip, which is either of 13 MHz, 26 MHz, 19.2 MHz, 38.4 MHz and no other RefClk clock are allowed. That limits the allowed DSI HS clock as well. The PixelPLL is fed directly with DSI HS clock SDR and derives DPI pixel clock from those clock. In order to impose these very specific limitations on DSI HS clock, this patch implements .atomic_get_input_bus_cfgs callback and calculates the most suitable clock to be passed on to the DSI host bridge. Signed-off-by: Marek Vasut Cc: Jonas Karlman Cc: Laurent Pinchart Cc: Maxime Ripard Cc: Neil Armstrong Cc: Sam Ravnborg --- drivers/gpu/drm/bridge/tc358767.c | 97 +++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 2b9fceb1333fa..98ea07912f721 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -250,11 +250,13 @@ #define PLLEN BIT(0) #define PXL_PLLPARAM 0x0914 #define IN_SEL_REFCLK (0 << 14) +#define IN_SEL_DSI_HSCK (1 << 14) #define SYS_PLLPARAM 0x0918 #define REF_FREQ_38M4 (0 << 8) /* 38.4 MHz */ #define REF_FREQ_19M2 (1 << 8) /* 19.2 MHz */ #define REF_FREQ_26M (2 << 8) /* 26 MHz */ #define REF_FREQ_13M (3 << 8) /* 13 MHz */ +#define SYSCLK_SEL_DSI_HSCLK (1 << 4) #define SYSCLK_SEL_LSCLK (0 << 4) #define LSCLK_DIV_1 (0 << 0) #define LSCLK_DIV_2 (1 << 0) @@ -492,6 +494,27 @@ static u32 tc_srcctrl(struct tc_data *tc) return reg; } +static int tc_mode_to_refclk(struct tc_data *tc, struct drm_display_mode *mode) +{ + u32 clock; + + /* Minimum DSI clock lane clock. */ + clock = (mode->htotal * mode->vtotal * 24 * 60) / tc->dsi_lanes / 2; + clock /= 7; /* DSIClk/7 */ + + /* Round the DSI clock to nearest supported faster clock. */ + if (clock < 13000000) /* DSIClk / 2 / 7 = 13 MHz RefClk */ + return 13000000; + else if (clock < 19200000) /* DSIClk / 2 / 7 = 19.2 MHz RefClk */ + return 19200000; + else if (clock < 26000000) /* DSIClk / 2 / 7 = 26 MHz RefClk */ + return 26000000; + else if (clock < 38400000) /* DSIClk / 2 / 7 = 38.4 MHz RefClk */ + return 38400000; + else + return 0; +} + static int tc_pllupdate(struct tc_data *tc, unsigned int pllctrl) { int ret; @@ -508,6 +531,7 @@ static int tc_pllupdate(struct tc_data *tc, unsigned int pllctrl) static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock) { + unsigned long rate; int ret; int i_pre, best_pre = 1; int i_post, best_post = 1; @@ -596,10 +620,17 @@ static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock) pxl_pllparam = vco_hi << 24; /* For PLL VCO >= 300 MHz = 1 */ pxl_pllparam |= ext_div[best_pre] << 20; /* External Pre-divider */ pxl_pllparam |= ext_div[best_post] << 16; /* External Post-divider */ - pxl_pllparam |= IN_SEL_REFCLK; /* Use RefClk as PLL input */ pxl_pllparam |= best_div << 8; /* Divider for PLL RefClk */ pxl_pllparam |= best_mul; /* Multiplier for PLL */ + rate = clk_get_rate(tc->refclk); + + /* DSI-to-DPI mode with clock inferred from DSI HS */ + if (rate == 0 && tc->bridge.type == DRM_MODE_CONNECTOR_DPI) + pxl_pllparam |= IN_SEL_DSI_HSCK; /* Use DSI HSCK as PLL input */ + else + pxl_pllparam |= IN_SEL_REFCLK; /* Use RefClk as PLL input */ + ret = regmap_write(tc->regmap, PXL_PLLPARAM, pxl_pllparam); if (ret) return ret; @@ -637,9 +668,19 @@ static int tc_stream_clock_calc(struct tc_data *tc) static int tc_set_syspllparam(struct tc_data *tc) { unsigned long rate; - u32 pllparam = SYSCLK_SEL_LSCLK | LSCLK_DIV_2; + u32 pllparam = LSCLK_DIV_2; rate = clk_get_rate(tc->refclk); + + /* DSI-to-DPI mode with clock inferred from DSI HS */ + if (rate == 0 && tc->bridge.type == DRM_MODE_CONNECTOR_DPI) { + pllparam |= SYSCLK_SEL_DSI_HSCLK; + /* Get RefClk rate from DSI HS clock. */ + rate = tc_mode_to_refclk(tc, &tc->mode); + } else { + pllparam |= SYSCLK_SEL_LSCLK; + } + switch (rate) { case 38400000: pllparam |= REF_FREQ_38M4; @@ -1266,9 +1307,18 @@ static int tc_dpi_stream_enable(struct tc_data *tc) if (ret) return ret; + value = clk_get_rate(tc->refclk); + if (!value) { + /* + * If RefClk Xtal is not connected, it is the DSI HS clock + * SDR that is directly fed into the Pixel PLL and used as + * input clock. Hence no multiplication of this value by 2. + */ + value = 7 * tc_mode_to_refclk(tc, &tc->mode); + } + /* Pixel PLL must always be enabled for DPI mode */ - ret = tc_pxl_pll_en(tc, clk_get_rate(tc->refclk), - 1000 * tc->mode.clock); + ret = tc_pxl_pll_en(tc, value, 1000 * tc->mode.clock); if (ret) return ret; @@ -1781,30 +1831,38 @@ static void tc_edp_bridge_detach(struct drm_bridge *bridge) drm_dp_aux_unregister(&bridge_to_tc(bridge)->aux); } -#define MAX_INPUT_SEL_FORMATS 1 +#define MAX_INPUT_SEL_CONFIGS 1 -static u32 * -tc_dpi_atomic_get_input_bus_fmts(struct drm_bridge *bridge, +static struct drm_bus_cfg * +tc_dpi_atomic_get_input_bus_cfgs(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state, - u32 output_fmt, - unsigned int *num_input_fmts) + struct drm_bus_cfg *out_cfg, + unsigned int *num_input_cfgs) { - u32 *input_fmts; + struct tc_data *tc = bridge_to_tc(bridge); + struct drm_bus_cfg *input_cfgs; + u32 clock; - *num_input_fmts = 0; + /* Minimum DSI clock lane clock in kHz (DSIClk / 7 = RefClk). */ + clock = 2 * 7 * tc_mode_to_refclk(tc, &crtc_state->adjusted_mode) / 1000; + if (clock == 0) + return NULL; - input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), + *num_input_cfgs = 0; + + input_cfgs = kcalloc(MAX_INPUT_SEL_CONFIGS, sizeof(*input_cfgs), GFP_KERNEL); - if (!input_fmts) + if (!input_cfgs) return NULL; /* This is the DSI-end bus format */ - input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; - *num_input_fmts = 1; + input_cfgs[0].format = MEDIA_BUS_FMT_RGB888_1X24; + input_cfgs[0].clock = clock; /* kHz */ + *num_input_cfgs = MAX_INPUT_SEL_CONFIGS; - return input_fmts; + return input_cfgs; } static const struct drm_bridge_funcs tc_dpi_bridge_funcs = { @@ -1817,7 +1875,7 @@ static const struct drm_bridge_funcs tc_dpi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, - .atomic_get_input_bus_fmts = tc_dpi_atomic_get_input_bus_fmts, + .atomic_get_input_bus_cfgs = tc_dpi_atomic_get_input_bus_cfgs, }; static const struct drm_bridge_funcs tc_bridge_funcs = { @@ -2107,7 +2165,10 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) usleep_range(5000, 10000); } - tc->refclk = devm_clk_get(dev, "ref"); + if (tc->bridge.type == DRM_MODE_CONNECTOR_DPI) + tc->refclk = devm_clk_get_optional(dev, "ref"); + else + tc->refclk = devm_clk_get(dev, "ref"); if (IS_ERR(tc->refclk)) { ret = PTR_ERR(tc->refclk); dev_err(dev, "Failed to get refclk: %d\n", ret);