On 8/26/26 8:09 AM, Julien Stephan wrote:
> The merge block is one of the components of the video pipeline on
> some MediaTek SoCs, such as the MT8188. It combines two half-width
> inputs into one output.
> 
> Signed-off-by: Julien Stephan <[email protected]>
> ---
>  drivers/video/mediatek/mtk_disp_merge.c | 106 
> ++++++++++++++++++++++++++++++++
>  drivers/video/mediatek/mtk_disp_merge.h |  19 ++++++
>  2 files changed, 125 insertions(+)
> 
> diff --git a/drivers/video/mediatek/mtk_disp_merge.c 
> b/drivers/video/mediatek/mtk_disp_merge.c
> new file mode 100644
> index 00000000000..185e75231fc
> --- /dev/null
> +++ b/drivers/video/mediatek/mtk_disp_merge.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Mediatek Video Disp Merge Support
> + *
> + * Copyright (c) 2026 BayLibre, SAS.
> + * Author: Julien Stephan <[email protected]>
> + */
> +
> +#include <dm.h>
> +
> +#include "mtk_disp_comp.h"
> +#include "mtk_disp_merge.h"
> +
> +/* MERGE registers */
> +#define SUBDISP_DISP_MERGE_ENABLE    0x000
> +#define SUBDISP_DISP_MERGE_CFG_0     0x010
> +#define SUBDISP_DISP_MERGE_CFG_1     0x014
> +#define SUBDISP_DISP_MERGE_CFG_4     0x020
> +#define SUBDISP_DISP_MERGE_CFG_10    0x038
> +#define SUBDISP_DISP_MERGE_CFG_12    0x040
> +#define CFG_10_10_2PI_2PO_BUF_MODE   0x08
> +#define CFG_11_10_1PI_2PO_MERGE              0x12

nit: these CFG macros use decimal format in linux.

> +#define SUBDISP_DISP_MERGE_CFG_24    0x070
> +#define SUBDISP_DISP_MERGE_CFG_25    0x074
> +#define SUBDISP_DISP_MERGE_CFG_26    0x078
> +#define SUBDISP_DISP_MERGE_CFG_27    0x07C
> +#define SUBDISP_DISP_MERGE_CFG_30    0x088
> +#define SUBDISP_DISP_MERGE_MUTE_0    0xf00
> +
> +void mtk_disp_merge_config(struct udevice *dev,
> +                        u16 width1, u16 height1,
> +                        u16 width2, u16 height2,
> +                        u16 output_width, u16 output_height)
> +{
> +     bool dual_input = (width2 != 0 && height2 != 0);
> +
> +     /* input 1 */
> +     if (width1 != 0 && height1 != 0)
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_0,
> +                                 height1 << 16 | width1);
> +
> +     /* input 2 */
> +     if (dual_input)
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_1,
> +                                 height2 << 16 | width2);
> +
> +     /* output */
> +     mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_4,
> +                         output_height << 16 | output_width);
> +
> +     /* no pixel/channel swap */
> +     mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_10, 0x0);
> +
> +     if (dual_input)
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_12,
> +                                 CFG_11_10_1PI_2PO_MERGE);
> +     else
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_12,
> +                                 CFG_10_10_2PI_2PO_BUF_MODE);
> +
> +     /* size in sram of inputs 0 and 1 */
> +     if (width1 != 0 && height1 != 0)
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_24,
> +                                 height1 << 16 | width1);
> +
> +     if (dual_input)
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_25,
> +                                 height2 << 16 | width2);
> +     else
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_25,
> +                                 height1 << 16 | width1);
> +
> +     /* merged size of inputs 0 and 1 */
> +     if (width1 != 0 && height1 != 0)
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_26,
> +                                 height1 << 16 | width1);
> +
> +     if (dual_input)
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_27,
> +                                 height2 << 16 | width2);
> +     else
> +             mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_27,
> +                                 height1 << 16 | width1);
> +
> +     /* 12 bit lsb off */
> +     mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_CFG_30, 0x0);
> +
> +     /* unmute */
> +     mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_MUTE_0, 0x0);
> +
> +     /* enable */
> +     mtk_disp_comp_write(dev, SUBDISP_DISP_MERGE_ENABLE, 0x1);
> +}
> +
> +static const struct udevice_id mtk_disp_merge_ids[] = {
> +     { .compatible = "mediatek,mt8188-disp-merge" },

This can use the mt8195 fallback too.

> +     {}
> +};
> +
> +U_BOOT_DRIVER(mtk_disp_merge) = {
> +     .name      = "mtk_disp_merge",
> +     .id        = UCLASS_MISC,
> +     .of_match  = mtk_disp_merge_ids,
> +     .probe     = mtk_disp_comp_probe,
> +     .priv_auto = sizeof(struct mtk_disp_comp_priv),
> +};
> diff --git a/drivers/video/mediatek/mtk_disp_merge.h 
> b/drivers/video/mediatek/mtk_disp_merge.h
> new file mode 100644
> index 00000000000..cac3982c74e
> --- /dev/null
> +++ b/drivers/video/mediatek/mtk_disp_merge.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Mediatek Video Disp Merge Support
> + *
> + * Copyright (c) 2026 BayLibre, SAS.
> + * Author: Julien Stephan <[email protected]>
> + */
> +
> +#ifndef _MTK_DISP_MERGE_H
> +#define _MTK_DISP_MERGE_H
> +
> +struct udevice;
> +
> +void mtk_disp_merge_config(struct udevice *dev,
> +                        u16 width1, u16 height1,
> +                        u16 width2, u16 height2,
> +                        u16 output_width, u16 output_height);
> +
> +#endif
> 

Reply via email to