public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Louis Chauvet <louis.chauvet@bootlin.com>
To: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Chun-Kuang Hu" <chunkuang.hu@kernel.org>,
	"Philipp Zabel" <p.zabel@pengutronix.de>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>
Cc: Alex Hung <alex.hung@amd.com>,
	wayland-devel@lists.freedesktop.org, harry.wentland@amd.com,
	leo.liu@amd.com, ville.syrjala@linux.intel.com,
	pekka.paalanen@collabora.com, contact@emersion.fr,
	mwen@igalia.com, jadahl@redhat.com, sebastian.wick@redhat.com,
	shashank.sharma@amd.com, agoins@nvidia.com, joshua@froggi.es,
	mdaenzer@redhat.com, aleixpol@kde.org, xaver.hugl@gmail.com,
	victoria@system76.com, uma.shankar@intel.com,
	quic_naseer@quicinc.com, quic_cbraga@quicinc.com,
	quic_abhinavk@quicinc.com, marcan@marcan.st, Liviu.Dudau@arm.com,
	sashamcintosh@google.com, chaitanya.kumar.borah@intel.com,
	mcanal@igalia.com, kernel@collabora.com, daniels@collabora.com,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	linux-mediatek@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	Simona Vetter <simona.vetter@ffwll.ch>
Subject: Re: [PATCH RFC 3/5] drm/mediatek: Support post-blend colorops for gamma and ctm
Date: Fri, 5 Sep 2025 19:55:52 +0200	[thread overview]
Message-ID: <22a8894a-6eb9-4f7a-b485-6259c3abc300@bootlin.com> (raw)
In-Reply-To: <20250822-mtk-post-blend-color-pipeline-v1-3-a9446d4aca82@collabora.com>



Le 22/08/2025 à 20:36, Nícolas F. R. A. Prado a écrit :
> Allow configuring the gamma and ccorr blocks through the post-blend
> color pipeline API instead of the GAMMA_LUT and CTM properties.
> 
> In order to achieve this, initialize the color pipeline property and
> colorops on the CRTC based on the DDP components available in the CRTC
> path. Then introduce a struct mtk_drm_colorop that extends drm_colorop
> and tracks the mtk_ddp_comp that implements it in hardware, and include
> new ddp_comp helper functions for setting gamma and ctm through the new
> API. These helpers will then be called during commit flush for every
> updated colorop if the DRM client supports the post-blend color pipeline
> API.
> 
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_crtc.c     | 211 +++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/mediatek/mtk_ddp_comp.h |   2 +
>   2 files changed, 208 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
> index bc7527542fdc6fb89fc36794cee7d6dc26f7dcce..80ed061de1af31916d814f29f9111973cffd10dd 100644
> --- a/drivers/gpu/drm/mediatek/mtk_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
> @@ -82,6 +82,12 @@ struct mtk_crtc_state {
>   	unsigned int			pending_vrefresh;
>   };
>   
> +struct mtk_drm_colorop {
> +	struct drm_colorop colorop;
> +	struct mtk_ddp_comp *comp;
> +	uint32_t data_id;
> +};
> +

@Alex: This is exactly a case where I think the current 
drm_colorop_pipeline_destroy will break.

>   static inline struct mtk_crtc *to_mtk_crtc(struct drm_crtc *c)
>   {
>   	return container_of(c, struct mtk_crtc, base);
> @@ -92,6 +98,11 @@ static inline struct mtk_crtc_state *to_mtk_crtc_state(struct drm_crtc_state *s)
>   	return container_of(s, struct mtk_crtc_state, base);
>   }
>   
> +static inline struct mtk_drm_colorop *to_mtk_colorop(struct drm_colorop *colorop)
> +{
> +	return container_of(colorop, struct mtk_drm_colorop, colorop);
> +}
> +
>   static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
>   {
>   	struct drm_crtc *crtc = &mtk_crtc->base;
> @@ -125,6 +136,19 @@ static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
>   	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
>   }
>   
> +static void mtk_drm_colorop_pipeline_destroy(struct drm_device *dev)
> +{
> +	struct drm_mode_config *config = &dev->mode_config;
> +	struct drm_colorop *colorop, *next;
> +	struct mtk_drm_colorop *mtk_colorop;
> +
> +	list_for_each_entry_safe(colorop, next, &config->colorop_list, head) {
> +		drm_colorop_cleanup(colorop);
> +		mtk_colorop = to_mtk_colorop(colorop);
> +		kfree(mtk_colorop);
> +	}
> +}
> +
>   static void mtk_crtc_destroy(struct drm_crtc *crtc)
>   {
>   	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
> @@ -146,6 +170,8 @@ static void mtk_crtc_destroy(struct drm_crtc *crtc)
>   		mtk_ddp_comp_unregister_vblank_cb(comp);
>   	}
>   
> +	mtk_drm_colorop_pipeline_destroy(crtc->dev);
> +
>   	drm_crtc_cleanup(crtc);
>   }
>   
> @@ -854,20 +880,103 @@ static void mtk_crtc_atomic_begin(struct drm_crtc *crtc,
>   	}
>   }
>   
> +static bool colorop_data_update_flush_status(struct drm_colorop_state *colorop_state)
> +{
> +	struct drm_colorop *colorop = colorop_state->colorop;
> +	struct mtk_drm_colorop *mtk_colorop = to_mtk_colorop(colorop);
> +	struct drm_property_blob *data_blob = colorop_state->data;
> +	uint32_t data_id = colorop_state->bypass ? 0 : data_blob->base.id;
> +	bool needs_flush = mtk_colorop->data_id != data_id;
> +
> +	mtk_colorop->data_id = data_id;
> +
> +	return needs_flush;
> +}
> +
> +static void mtk_crtc_ddp_comp_apply_colorop(struct drm_colorop_state *colorop_state)
> +{
> +	struct drm_colorop *colorop = colorop_state->colorop;
> +	struct mtk_drm_colorop *mtk_colorop = to_mtk_colorop(colorop);
> +	struct drm_property_blob *data_blob = colorop_state->data;
> +	struct mtk_ddp_comp *ddp_comp = mtk_colorop->comp;
> +	struct drm_color_ctm_3x4 *ctm = NULL;
> +	struct drm_color_lut32 *lut = NULL;
> +
> +	switch (colorop->type) {
> +	case DRM_COLOROP_1D_LUT:
> +		if (!colorop_data_update_flush_status(colorop_state))
> +			return;
> +
> +		if (!colorop_state->bypass)
> +			lut = (struct drm_color_lut32 *)data_blob->data;
> +
> +		ddp_comp->funcs->gamma_set_color_pipeline(ddp_comp->dev, lut);
> +		break;
> +	case DRM_COLOROP_CTM_3X4:
> +		if (!colorop_data_update_flush_status(colorop_state))
> +			return;
> +
> +		if (!colorop_state->bypass)
> +			ctm = (struct drm_color_ctm_3x4 *)data_blob->data;
> +
> +		ddp_comp->funcs->ctm_set_color_pipeline(ddp_comp->dev, ctm);
> +		break;
> +	default:
> +		/* If this happens the driver is broken */
> +		drm_WARN(colorop->dev, 1,
> +			 "Trying to atomic flush COLOROP of type unsupported by driver: %d\n",
> +			 colorop->type);
> +		break;
> +	}
> +}
> +
>   static void mtk_crtc_atomic_flush(struct drm_crtc *crtc,
>   				  struct drm_atomic_state *state)
>   {
>   	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
> +	struct drm_colorop_state *new_colorop_state;
> +	struct drm_colorop *colorop;
>   	int i;
>   
> -	if (crtc->state->color_mgmt_changed)
> -		for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> -			mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
> -			mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state);
> -		}
> +	if (state->post_blend_color_pipeline) {
> +		for_each_new_colorop_in_state(state, colorop, new_colorop_state, i)
> +			mtk_crtc_ddp_comp_apply_colorop(new_colorop_state);
> +	} else {
> +		if (crtc->state->color_mgmt_changed)
> +			for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> +				mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
> +				mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state);
> +			}
> +	}
>   	mtk_crtc_update_config(mtk_crtc, !!mtk_crtc->event);
>   }
>   
> +static int mtk_crtc_atomic_check(struct drm_crtc *crtc,
> +				 struct drm_atomic_state *state)
> +{
> +	struct drm_colorop_state *new_colorop_state;
> +	struct drm_colorop *colorop;
> +	int i;
> +
> +	for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) {
> +		switch (colorop->type) {
> +		case DRM_COLOROP_1D_LUT:
> +		case DRM_COLOROP_CTM_3X4:
> +			if (!new_colorop_state->bypass && !new_colorop_state->data) {
> +				drm_dbg_atomic(crtc->dev,
> +					       "Missing required DATA property for COLOROP:%d\n",
> +					       colorop->base.id);
> +				return -EINVAL;
> +			}
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static const struct drm_crtc_funcs mtk_crtc_funcs = {
>   	.set_config		= drm_atomic_helper_set_config,
>   	.page_flip		= drm_atomic_helper_page_flip,
> @@ -885,6 +994,7 @@ static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
>   	.mode_valid	= mtk_crtc_mode_valid,
>   	.atomic_begin	= mtk_crtc_atomic_begin,
>   	.atomic_flush	= mtk_crtc_atomic_flush,
> +	.atomic_check   = mtk_crtc_atomic_check,
>   	.atomic_enable	= mtk_crtc_atomic_enable,
>   	.atomic_disable	= mtk_crtc_atomic_disable,
>   };
> @@ -987,6 +1097,95 @@ struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc)
>   	return mtk_crtc->dma_dev;
>   }
>   
> +#define MAX_COLOR_PIPELINE_OPS 2
> +#define MAX_COLOR_PIPELINES 1
> +
> +static int mtk_colorop_init(struct mtk_crtc *mtk_crtc,
> +			    struct mtk_drm_colorop *mtk_colorop,
> +			    struct mtk_ddp_comp *ddp_comp)
> +{
> +	struct drm_colorop *colorop = &mtk_colorop->colorop;
> +	int ret = 0;
> +
> +	if (ddp_comp->funcs->gamma_set_color_pipeline) {
> +		unsigned int lut_sz = mtk_ddp_gamma_get_lut_size(ddp_comp);
> +
> +		ret = drm_crtc_colorop_curve_1d_lut_init(mtk_crtc->base.dev, colorop,
> +							 &mtk_crtc->base,
> +							 lut_sz,
> +							 DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
> +							 DRM_COLOROP_FLAG_ALLOW_BYPASS);
> +	} else if (ddp_comp->funcs->ctm_set_color_pipeline) {
> +		ret = drm_crtc_colorop_ctm_3x4_init(mtk_crtc->base.dev,
> +						    colorop,
> +						    &mtk_crtc->base,
> +						    DRM_COLOROP_FLAG_ALLOW_BYPASS);
> +	}
> +
> +	mtk_colorop->comp = ddp_comp;
> +
> +	return ret;
> +}
> +
> +static int mtk_crtc_init_post_blend_color_pipeline(struct mtk_crtc *mtk_crtc,
> +						   unsigned int gamma_lut_size)
> +{
> +	struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES];
> +	struct drm_colorop *ops[MAX_COLOR_PIPELINE_OPS];
> +	struct mtk_drm_colorop *mtk_colorop;
> +	unsigned int num_pipelines = 0;
> +	unsigned int op_idx = 0;
> +	int ret;
> +
> +	memset(ops, 0, sizeof(ops));
> +
> +	for (unsigned int i = 0;
> +	     i < mtk_crtc->ddp_comp_nr && op_idx < MAX_COLOR_PIPELINE_OPS;
> +	     i++) {
> +		struct mtk_ddp_comp *ddp_comp = mtk_crtc->ddp_comp[i];
> +
> +		if (!(ddp_comp->funcs->gamma_set_color_pipeline ||
> +		      ddp_comp->funcs->ctm_set_color_pipeline))
> +			continue;
> +
> +		mtk_colorop = kzalloc(sizeof(struct mtk_drm_colorop), GFP_KERNEL);
> +		if (!mtk_colorop) {
> +			ret = -ENOMEM;
> +			goto cleanup;
> +		}
> +
> +		ops[op_idx] = &mtk_colorop->colorop;
> +
> +		ret = mtk_colorop_init(mtk_crtc, mtk_colorop, ddp_comp);
> +		if (ret)
> +			goto cleanup;
> +
> +		if (op_idx > 0)
> +			drm_colorop_set_next_property(ops[op_idx-1], ops[op_idx]);
> +
> +		op_idx++;
> +	}
> +
> +	if (op_idx > 0) {
> +		pipelines[0].type = ops[0]->base.id;
> +		pipelines[0].name = kasprintf(GFP_KERNEL, "Color Pipeline %d", ops[0]->base.id);
> +		num_pipelines = 1;
> +	}
> +
> +	/* Create COLOR_PIPELINE property and attach */
> +	drm_crtc_create_color_pipeline_property(&mtk_crtc->base, pipelines, num_pipelines);
> +
> +	return 0;
> +
> +cleanup:
> +	if (ret == -ENOMEM)
> +		drm_err(mtk_crtc->base.dev, "KMS: Failed to allocate colorop\n");
> +
> +	mtk_drm_colorop_pipeline_destroy(mtk_crtc->base.dev);
> +
> +	return ret;
> +}
> +
>   int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
>   		    unsigned int path_len, int priv_data_index,
>   		    const struct mtk_drm_route *conn_routes,
> @@ -1103,6 +1302,8 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
>   	if (ret < 0)
>   		return ret;
>   
> +	mtk_crtc_init_post_blend_color_pipeline(mtk_crtc, gamma_lut_size);
> +
>   	if (gamma_lut_size)
>   		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
>   	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
> diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> index 7289b3dcf22f22f344016beee0c7c144cf7b93c8..554c3cc8ad7b266b8b8eee74ceb8f7383fe2f8df 100644
> --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> @@ -75,10 +75,12 @@ struct mtk_ddp_comp_funcs {
>   	unsigned int (*gamma_get_lut_size)(struct device *dev);
>   	void (*gamma_set)(struct device *dev,
>   			  struct drm_crtc_state *state);
> +	void (*gamma_set_color_pipeline)(struct device *dev, struct drm_color_lut32 *lut);
>   	void (*bgclr_in_on)(struct device *dev);
>   	void (*bgclr_in_off)(struct device *dev);
>   	void (*ctm_set)(struct device *dev,
>   			struct drm_crtc_state *state);
> +	void (*ctm_set_color_pipeline)(struct device *dev, struct drm_color_ctm_3x4 *ctm);
>   	struct device * (*dma_dev_get)(struct device *dev);
>   	u32 (*get_blend_modes)(struct device *dev);
>   	const u32 *(*get_formats)(struct device *dev);
> 

-- 
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


  reply	other threads:[~2025-09-05 17:56 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-22 18:36 [PATCH RFC 0/5] Introduce support for post-blend color pipeline Nícolas F. R. A. Prado
2025-08-22 18:36 ` [PATCH RFC 1/5] drm: Support post-blend color pipeline API Nícolas F. R. A. Prado
2025-08-25 13:34   ` Daniel Stone
2025-08-25 18:45     ` Xaver Hugl
2025-08-26 12:25       ` Daniel Stone
2025-09-03 18:42         ` Nícolas F. R. A. Prado
2025-09-15 12:31           ` Daniel Stone
2025-09-26 13:51             ` Sebastian Wick
2025-09-29 10:33               ` Harry Wentland
     [not found]             ` <2a985767-0fe1-40fc-b45e-921bbf201e07@app.fastmail.com>
2025-09-30 12:20               ` Daniel Stone
2025-10-02  8:00                 ` Pekka Paalanen
2025-08-27 11:17   ` Sebastian Wick
2025-08-27 11:32     ` Daniel Stone
2025-09-05 17:55   ` Louis Chauvet
2025-09-09 19:31     ` Nícolas F. R. A. Prado
2025-08-22 18:36 ` [PATCH RFC 2/5] drm/colorop: Export drm_colorop_cleanup() so drivers can extend it Nícolas F. R. A. Prado
2025-09-05 17:55   ` Louis Chauvet
2025-08-22 18:36 ` [PATCH RFC 3/5] drm/mediatek: Support post-blend colorops for gamma and ctm Nícolas F. R. A. Prado
2025-09-05 17:55   ` Louis Chauvet [this message]
2025-08-22 18:36 ` [PATCH RFC 4/5] drm/mediatek: ccorr: Support post-blend color pipeline API Nícolas F. R. A. Prado
2025-08-22 18:36 ` [PATCH RFC 5/5] drm/mediatek: gamma: " Nícolas F. R. A. Prado

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=22a8894a-6eb9-4f7a-b485-6259c3abc300@bootlin.com \
    --to=louis.chauvet@bootlin.com \
    --cc=Liviu.Dudau@arm.com \
    --cc=agoins@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=aleixpol@kde.org \
    --cc=alex.hung@amd.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=chaitanya.kumar.borah@intel.com \
    --cc=chunkuang.hu@kernel.org \
    --cc=contact@emersion.fr \
    --cc=daniels@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=harry.wentland@amd.com \
    --cc=jadahl@redhat.com \
    --cc=joshua@froggi.es \
    --cc=kernel@collabora.com \
    --cc=leo.liu@amd.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=marcan@marcan.st \
    --cc=matthias.bgg@gmail.com \
    --cc=mcanal@igalia.com \
    --cc=mdaenzer@redhat.com \
    --cc=mripard@kernel.org \
    --cc=mwen@igalia.com \
    --cc=nfraprado@collabora.com \
    --cc=p.zabel@pengutronix.de \
    --cc=pekka.paalanen@collabora.com \
    --cc=quic_abhinavk@quicinc.com \
    --cc=quic_cbraga@quicinc.com \
    --cc=quic_naseer@quicinc.com \
    --cc=sashamcintosh@google.com \
    --cc=sebastian.wick@redhat.com \
    --cc=shashank.sharma@amd.com \
    --cc=simona.vetter@ffwll.ch \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    --cc=uma.shankar@intel.com \
    --cc=victoria@system76.com \
    --cc=ville.syrjala@linux.intel.com \
    --cc=wayland-devel@lists.freedesktop.org \
    --cc=xaver.hugl@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox