Received: by 2002:ab2:1689:0:b0:1f7:5705:b850 with SMTP id d9csp233737lqa; Fri, 26 Apr 2024 23:33:20 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWxlqojDSrUFlqzriV54d8Z3AGYIHOU8S7Il3sKRAVLBzH344s63530dowAMp411TpDfDGWYTFTeIvFUgQvOWdDDg643lAbiI/8ifDxoA== X-Google-Smtp-Source: AGHT+IFvaWtpCC4M0yJuouHuZng5OYrWsC5ji1hE6uLZKQNAF6vLa8Tq/pHNOdVeWRVpMLttqZCy X-Received: by 2002:a17:906:6899:b0:a58:dcc3:f4b0 with SMTP id n25-20020a170906689900b00a58dcc3f4b0mr1398014ejr.61.1714199600054; Fri, 26 Apr 2024 23:33:20 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714199600; cv=pass; d=google.com; s=arc-20160816; b=kasAuuEGO9FWbrYBjpyjdmGvzP94nxwjWUCU21ryavcN+EbKXnsG5+Cq+soVlNNwV0 ZPflHzoczAbLlAQNJLgUA0j9183I6oEPYh0fwv+jtL1J0R6MOHFZAKQbVBdItuiUS5nY fXqtww0poYE/XK/o0Qe7HBWxTEzEo1z4E1xQQUUq4COzKrUVy05bwz+SDNal0mzYFfhT 9MbWIbrsnMEF9a7w0Vodyk4/ZjA2cljiqgqWe0aLgZscXeixcZwokhBbprN2iNrYEpHv VWNDc78LUm3iarhYZx/ypt5scJ1xmnPnbq3y8uMorQObd6WwxWIJKhRzZzis2flTBIKR EqHQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:cc :to:from:date:dkim-signature:dkim-signature; bh=ec9lAzcjCON+j70wbK+o0qqyRqRnZ6NwtKhIea0xhVE=; fh=dbDnj+Wd3nVpSPuoce60sV3QrHiPmIXuhHacVA0txnw=; b=vc86nt8iF1zyHPTPwvkn2K+i7Xu9ANCEbnupEQ+eMHLCnttT7UDUP5R25tXfMzvLGo hpTkzPIaYf98x3XnlnAid0aaX4axUjnqvBEiWD8D72AbPQoHfcIKSu7j6s5W5pwnDnIR dL97MvDqqJ/ZLsd/AHKXVCvZ5/tsTt9dlNqqxGN37RBWZKrBkOqLUcz5ZsxglkaJHYzK zN48p1si9uWzGB9w+eZ5LCpDFmHaplvoapCwG9SpHGaeYB2jJXFtHpak/h5Luv24VTow JejLm6SH3V7biGeYhcxNu3YCb6V8IQAPQRxfbkznphemAM4DfWGdvQST0Q9A6DjWOrb4 UhkA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@ravnborg.org header.s=rsa1 header.b=IewcLyW5; dkim=neutral (no key) header.i=@ravnborg.org header.s=ed1 header.b=zVDS9FE+; arc=pass (i=1 dkim=pass dkdomain=ravnborg.org); spf=pass (google.com: domain of linux-kernel+bounces-160920-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-160920-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id b19-20020a1709063f9300b00a4734b06c8csi11901266ejj.630.2024.04.26.23.33.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 23:33:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-160920-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@ravnborg.org header.s=rsa1 header.b=IewcLyW5; dkim=neutral (no key) header.i=@ravnborg.org header.s=ed1 header.b=zVDS9FE+; arc=pass (i=1 dkim=pass dkdomain=ravnborg.org); spf=pass (google.com: domain of linux-kernel+bounces-160920-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-160920-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 9D5381F22B8F for ; Sat, 27 Apr 2024 06:33:19 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1421F40841; Sat, 27 Apr 2024 06:33:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ravnborg.org header.i=@ravnborg.org header.b="IewcLyW5"; dkim=permerror (0-bit key) header.d=ravnborg.org header.i=@ravnborg.org header.b="zVDS9FE+" Received: from mailrelay6-1.pub.mailoutpod2-cph3.one.com (mailrelay6-1.pub.mailoutpod2-cph3.one.com [46.30.211.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 07E028BFA for ; Sat, 27 Apr 2024 06:33:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.30.211.181 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714199591; cv=none; b=Aw+MZ3cRIgYRM1bLawL1U7wEPw6WAwRlHHGx1HlpzvVNd8sHfvrd2nYKD1FrEPoaFWgt2JbXRz7asjE9t3z/AMuUX0XgiRX3vaqIjFANF5XTsAOGYxvH787Uvv2OYyLl0cmLfTS3UmgcEAza5/2SH+e/TVYDtyl0WQcx8NCTArQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714199591; c=relaxed/simple; bh=bkevbAcJyK2MNnWrPnc9F57yzVZwMT3LBbqqltk/oGI=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=TiuLmUwXS4KfPknEYyE9s5Mi7UZs2sYDk8tPOSNPl2UbcAvZXhJMstnRTH8oYYj0Z9oltUIiiB3uHkvTfqR7GloiehCJ78571P947vyQmOw0QVZ+2rxKV6aIj34Bspv+UAi4GAOsITBMhZhC8IvLxUbqyjMY/znWEm9jdD2ke5c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ravnborg.org; spf=none smtp.mailfrom=ravnborg.org; dkim=pass (2048-bit key) header.d=ravnborg.org header.i=@ravnborg.org header.b=IewcLyW5; dkim=permerror (0-bit key) header.d=ravnborg.org header.i=@ravnborg.org header.b=zVDS9FE+; arc=none smtp.client-ip=46.30.211.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ravnborg.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ravnborg.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ravnborg.org; s=rsa1; h=in-reply-to:content-type:mime-version:references:message-id:subject:cc:to: from:date:from; bh=ec9lAzcjCON+j70wbK+o0qqyRqRnZ6NwtKhIea0xhVE=; b=IewcLyW5OZhWJ9xBcznao1kvHf9DWJP3OaspsYfueBhsro/GXKGrSFhv4NMQU5hIj7UJ5iR8V//N6 SGjbLpxUHXf2cxoWMCP8lEQt93iKkW9rFVVC9g+Ykbch8OL23v1v20EtYYH7DXhMy2Y3VI5aIjVMcB rr/BmyLnoSESb1D6F2bsR3q5qCgSJuslnYMIdfAj7ARo5QuKOrC13q0dgZKaS0rlIJI3ev+YrTHsQB okHivnHXq7M3wYDx0BP8tBooMTP7vqsWTQ8Ze4sse2GyNAuK4+kUVZZBXXpdg78xNTm98Q4Qz0L+FR GxtNTjGhIutw2sFga942qaUxMujfbYQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ravnborg.org; s=ed1; h=in-reply-to:content-type:mime-version:references:message-id:subject:cc:to: from:date:from; bh=ec9lAzcjCON+j70wbK+o0qqyRqRnZ6NwtKhIea0xhVE=; b=zVDS9FE+iZDbPevL1q+sAfvAFGfoBi3/B542U+LWg9gWbmmYafi7m7DBbHE53Opa99mUovT8r4vCn JqdNB0zDg== X-HalOne-ID: f81909a5-045f-11ef-8438-f528319a6ef4 Received: from ravnborg.org (2-105-2-98-cable.dk.customer.tdc.net [2.105.2.98]) by mailrelay6.pub.mailoutpod2-cph3.one.com (Halon) with ESMTPSA id f81909a5-045f-11ef-8438-f528319a6ef4; Sat, 27 Apr 2024 06:32:59 +0000 (UTC) Date: Sat, 27 Apr 2024 08:32:50 +0200 From: Sam Ravnborg To: Douglas Anderson Cc: dri-devel@lists.freedesktop.org, Linus Walleij , lvzhaoxiong@huaqin.corp-partner.google.com, Jani Nikula , Hsin-Yi Wang , Javier Martinez Canillas , Neil Armstrong , Joel Selvaraj , Dmitry Baryshkov , Cong Yang , Daniel Vetter , David Airlie , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , linux-kernel@vger.kernel.org Subject: Re: [PATCH v2 4/8] drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi() Message-ID: <20240427063250.GB1137299@ravnborg.org> References: <20240426235857.3870424-1-dianders@chromium.org> <20240426165839.v2.4.Ie94246c30fe95101e0e26dd5f96e976dbeb8f242@changeid> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20240426165839.v2.4.Ie94246c30fe95101e0e26dd5f96e976dbeb8f242@changeid> Hi Douglas. On Fri, Apr 26, 2024 at 04:58:37PM -0700, Douglas Anderson wrote: > The current mipi_dsi_*_write_seq() macros are non-intutitive because > they contain a hidden "return" statement that will return out of the > _caller_ of the macro. Let's mark them as deprecated and instead > introduce some new macros that are more intuitive. > > These new macros are less optimal when an error occurs but should > behave more optimally when there is no error. Specifically these new > macros cause smaller code to get generated and the code size savings > (less to fetch from RAM, less cache space used, less RAM used) are > important. Since the error case isn't something we need to optimize > for and these new macros are easier to understand and more flexible, > they should be used. The whole ignore-and-return-early-if-an-error-occured concept is nice and make this easy to understand and use. I have a few nits in the following, but the overall concept is nice. Sam > > After converting to use these new functions, one example shows some > nice savings while also being easier to understand. > > $ scripts/bloat-o-meter \ > ...after/panel-novatek-nt36672e.ko \ > ...ctx/panel-novatek-nt36672e.ko > add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-988 (-988) > Function old new delta > nt36672e_1080x2408_60hz_init 6236 5248 -988 > Total: Before=10651, After=9663, chg -9.28% > > Signed-off-by: Douglas Anderson > --- > Right now this patch introduces two new functions in > drm_mipi_dsi.c. Alternatively we could have changed the prototype of > the "chatty" functions and made the deprecated macros adapt to the new > prototype. While this sounds nice, it bloated callers of the > deprecated functioin a bit because it caused the compiler to emit less > optimal code. It doesn't seem terrible to add two more functions, so I > went that way. The concern here is when it will be cleaned up. As a minimum please consider adding an item to todo.rst that details what should be done to get rid of the now obsolete chatty functions so someone can pick it up. > > Changes in v2: > - New > > drivers/gpu/drm/drm_mipi_dsi.c | 56 +++++++++++++++++++++++++++++++++ > include/drm/drm_mipi_dsi.h | 57 ++++++++++++++++++++++++++++++++++ > 2 files changed, 113 insertions(+) > > diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c > index 1e062eda3b88..b7c75a4396e6 100644 > --- a/drivers/gpu/drm/drm_mipi_dsi.c > +++ b/drivers/gpu/drm/drm_mipi_dsi.c > @@ -792,6 +792,34 @@ int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, > } > EXPORT_SYMBOL(mipi_dsi_generic_write_chatty); > > +/** > + * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ accum_err > + * @ctx: Context for multiple DSI transactions > + * @payload: buffer containing the payload > + * @size: size of payload buffer > + * > + * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that > + * makes it convenient to make several calls in a row. > + */ > +void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, > + const void *payload, size_t size) > +{ > + struct mipi_dsi_device *dsi = ctx->dsi; > + struct device *dev = &dsi->dev; > + ssize_t ret; > + > + if (ctx->accum_err) > + return; > + > + ret = mipi_dsi_generic_write(dsi, payload, size); > + if (ret < 0) { > + ctx->accum_err = ret; > + dev_err_ratelimited(dev, "sending generic data %*ph failed: %d\n", > + (int)size, payload, ctx->accum_err); > + } I see no point in using ratelimited and then change it in the next patch. > +} > +EXPORT_SYMBOL(mipi_dsi_generic_write_multi); > + > /** > * mipi_dsi_generic_read() - receive data using a generic read packet > * @dsi: DSI peripheral device > @@ -908,6 +936,34 @@ int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, > } > EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty); > > +/** > + * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err > + * @ctx: Context for multiple DSI transactions > + * @data: buffer containing data to be transmitted > + * @len: size of transmission buffer > + * > + * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that > + * makes it convenient to make several calls in a row. > + */ > +void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, > + const void *data, size_t len) > +{ > + struct mipi_dsi_device *dsi = ctx->dsi; > + struct device *dev = &dsi->dev; > + ssize_t ret; > + > + if (ctx->accum_err) > + return; > + > + ret = mipi_dsi_dcs_write_buffer(dsi, data, len); > + if (ret < 0) { > + ctx->accum_err = ret; > + dev_err_ratelimited(dev, "sending dcs data %*ph failed: %d\n", > + (int)len, data, ctx->accum_err); > + } > +} > +EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi); > + > /** > * mipi_dsi_dcs_write() - send DCS write command > * @dsi: DSI peripheral device > diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h > index 6d68d9927f46..379594649a42 100644 > --- a/include/drm/drm_mipi_dsi.h > +++ b/include/drm/drm_mipi_dsi.h > @@ -197,6 +197,22 @@ struct mipi_dsi_device { > struct drm_dsc_config *dsc; > }; > > +/** > + * struct mipi_dsi_multi_context - Context to call multiple MIPI DSI funcs in a row > + * @dsi: Pointer to the MIPI DSI device > + * @accum_err: Storage for the accumulated error over the multiple calls. Init > + * to 0. If a function encounters an error then the error code will be > + * stored here. If you call a function and this points to a non-zero > + * value then the function will be a noop. This allows calling a function > + * many times in a row and just checking the error at the end to see if > + * any of them failed. > + */ > + > +struct mipi_dsi_multi_context { > + struct mipi_dsi_device *dsi; > + int accum_err; > +}; Inline comments is - I think - preferred. > + > #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:" > > #define to_mipi_dsi_device(__dev) container_of_const(__dev, struct mipi_dsi_device, dev) > @@ -258,6 +274,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, > size_t size); > int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, > const void *payload, size_t size); > +void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, > + const void *payload, size_t size); > ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, > size_t num_params, void *data, size_t size); > > @@ -283,6 +301,8 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, > const void *data, size_t len); > int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, > const void *data, size_t len); > +void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, > + const void *data, size_t len); > ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, > const void *data, size_t len); > ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, > @@ -319,6 +339,9 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, > * This macro will print errors for you and will RETURN FROM THE CALLING > * FUNCTION (yes this is non-intuitive) upon error. > * > + * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED. > + * Please replace calls of it with mipi_dsi_generic_write_seq_multi(). > + * > * @dsi: DSI peripheral device > * @seq: buffer containing the payload > */ > @@ -331,12 +354,30 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, > return ret; \ > } while (0) > > +/** > + * mipi_dsi_generic_write_seq_multi - transmit data using a generic write packet > + * > + * This macro will print errors for you and error handling is optimized for > + * callers that call this multiple times in a row. > + * > + * @ctx: Context for multiple DSI transactions > + * @seq: buffer containing the payload > + */ > +#define mipi_dsi_generic_write_seq_multi(ctx, seq...) \ > + do { \ > + static const u8 d[] = { seq }; \ > + mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d)); \ > + } while (0) > + > /** > * mipi_dsi_dcs_write_seq - transmit a DCS command with payload > * > * This macro will print errors for you and will RETURN FROM THE CALLING > * FUNCTION (yes this is non-intuitive) upon error. > * > + * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED. > + * Please replace calls of it with mipi_dsi_dcs_write_seq_multi(). > + * > * @dsi: DSI peripheral device > * @cmd: Command > * @seq: buffer containing data to be transmitted > @@ -350,6 +391,22 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, > return ret; \ > } while (0) > > +/** > + * mipi_dsi_dcs_write_seq_multi - transmit a DCS command with payload > + * > + * This macro will print errors for you and error handling is optimized for > + * callers that call this multiple times in a row. > + * > + * @ctx: Context for multiple DSI transactions > + * @cmd: Command > + * @seq: buffer containing data to be transmitted > + */ > +#define mipi_dsi_dcs_write_seq_multi(ctx, cmd, seq...) \ > + do { \ > + static const u8 d[] = { cmd, seq }; \ > + mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \ > + } while (0) > + > /** > * struct mipi_dsi_driver - DSI driver > * @driver: device driver model driver > -- > 2.44.0.769.g3c40516874-goog