[PATCH] drm/mipi-dsi: Introduce macros to create mipi_dsi_*_multi functions

Tejas Vipin tejasvipin76 at gmail.com
Tue Jul 16 13:31:17 UTC 2024


Introduce 2 new macros, DSI_CTX_NO_OP and MIPI_DSI_ADD_MULTI_VARIANT.

DSI_CTX_NO_OP calls a function only if the context passed to it hasn't
encountered any errors. It is a generic form of what mipi_dsi_msleep
does.

MIPI_DSI_ADD_MULTI_VARIANT defines a multi style function of any
mipi_dsi function that follows a certain style. This allows us to
greatly reduce the amount of redundant code written for each multi
function. It reduces the overhead for a developer introducing new
mipi_dsi_*_multi functions.

Signed-off-by: Tejas Vipin <tejasvipin76 at gmail.com>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 286 ++++++++++-----------------------
 1 file changed, 83 insertions(+), 203 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index a471c46f5ca6..53880b486f22 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -1430,214 +1430,94 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
 
 /**
- * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral
- * @ctx: Context for multiple DSI transactions
- * @pps: VESA DSC 1.1 Picture Parameter Set
- *
- * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
-				   const struct drm_dsc_picture_parameter_set *pps)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_picture_parameter_set(dsi, pps);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending PPS failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
-
-/**
- * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
- * @ctx: Context for multiple DSI transactions
- * @enable: Whether to enable or disable the DSC
- * @algo: Selected compression algorithm
- * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
- *
- * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
-					 bool enable,
-					 enum mipi_dsi_compression_algo algo,
-					 unsigned int pps_selector)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
-
-/**
- * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_nop() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
+ * DSI_CTX_NO_OP() - Calls a function only if no previous errors have
+ *	occurred.
+ * @func: The function call that needs to happen.
+ * @ctx: Context whose accum_err is checked to decide if the function
+ *	should run.
  */
-void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_dcs_nop(dsi);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending DCS NOP failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
+#define DSI_CTX_NO_OP(func, ctx)	\
+	do {				\
+		if (!(ctx)->accum_err)	\
+			func;		\
+	} while (0)
 
 /**
- * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE  packet
- * @ctx: Context for multiple DSI transactions
+ * MIPI_DSI_ADD_MULTI_VARIANT() - Define the multi variant of
+ *	an existing MIPI DSI function.
+ * @proto: The prototype of the desired multi variant
+ * @err: The error string used by dev_err on an error occurring.
+ * @inner_func: Identifier of the function being wrapped
+ * @...: Any arguments that need to be passed to inner_func
  *
- * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
  */
-void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
-
-/**
- * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
-
-/**
- * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_dcs_set_display_off(dsi);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
-
-/**
- * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
- * @ctx: Context for multiple DSI transactions
- *
- * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_dcs_set_display_on(dsi);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
-
-/**
- * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
- * @ctx: Context for multiple DSI transactions
- * @mode: the Tearing Effect Output Line mode
- *
- * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
- * makes it convenient to make several calls in a row.
- */
-void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
-				    enum mipi_dsi_dcs_tear_mode mode)
-{
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	struct device *dev = &dsi->dev;
-	ssize_t ret;
-
-	if (ctx->accum_err)
-		return;
-
-	ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
-	if (ret < 0) {
-		ctx->accum_err = ret;
-		dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
-			ctx->accum_err);
-	}
-}
-EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
+#define MIPI_DSI_ADD_MULTI_VARIANT(proto, err, inner_func, ...)	\
+proto {								\
+	struct mipi_dsi_device *dsi = ctx->dsi;			\
+	struct device *dev = &dsi->dev;				\
+	int ret;						\
+	\
+	if (ctx->accum_err)					\
+		return;						\
+	\
+	ret = inner_func(dsi, ##__VA_ARGS__);			\
+	if (ret < 0) {						\
+		ctx->accum_err = ret;				\
+		dev_err(dev, err, ctx->accum_err);		\
+	}							\
+}								\
+EXPORT_SYMBOL(inner_func##_multi);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_picture_parameter_set_multi(
+	struct mipi_dsi_multi_context *ctx,
+	const struct drm_dsc_picture_parameter_set *pps),
+	"sending PPS failed: %d\n",
+	mipi_dsi_picture_parameter_set, pps);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_compression_mode_ext_multi(
+	struct mipi_dsi_multi_context *ctx, bool enable,
+	enum mipi_dsi_compression_algo algo, unsigned int pps_selector),
+	"sending COMPRESSION_MODE failed: %d\n",
+	mipi_dsi_compression_mode_ext, enable, algo, pps_selector);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_dcs_nop_multi(
+	struct mipi_dsi_multi_context *ctx),
+	"sending DCS NOP failed: %d\n",
+	mipi_dsi_dcs_nop);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_dcs_enter_sleep_mode_multi(
+	struct mipi_dsi_multi_context *ctx),
+	"sending DCS ENTER_SLEEP_MODE failed: %d\n",
+	mipi_dsi_dcs_enter_sleep_mode);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_dcs_exit_sleep_mode_multi(
+	struct mipi_dsi_multi_context *ctx),
+	"sending DCS EXIT_SLEEP_MODE failed: %d\n",
+	mipi_dsi_dcs_exit_sleep_mode);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_dcs_set_display_off_multi(
+	struct mipi_dsi_multi_context *ctx),
+	"sending DCS SET_DISPLAY_OFF failed: %d\n",
+	mipi_dsi_dcs_set_display_off);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_dcs_set_display_on_multi(
+	struct mipi_dsi_multi_context *ctx),
+	"sending DCS SET_DISPLAY_ON failed: %d\n",
+	mipi_dsi_dcs_set_display_on);
+
+MIPI_DSI_ADD_MULTI_VARIANT(
+	void mipi_dsi_dcs_set_tear_on_multi(
+	struct mipi_dsi_multi_context *ctx,
+	enum mipi_dsi_dcs_tear_mode mode),
+	"sending DCS SET_TEAR_ON failed: %d\n",
+	mipi_dsi_dcs_set_tear_on, mode);
 
 static int mipi_dsi_drv_probe(struct device *dev)
 {
-- 
2.45.2



More information about the dri-devel mailing list