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_mt8188.c | 106 +++++++++++++++++++++++++ drivers/video/mediatek/mtk_disp_merge_mt8188.h | 19 +++++ 2 files changed, 125 insertions(+) diff --git a/drivers/video/mediatek/mtk_disp_merge_mt8188.c b/drivers/video/mediatek/mtk_disp_merge_mt8188.c new file mode 100644 index 00000000000..437bf1a5533 --- /dev/null +++ b/drivers/video/mediatek/mtk_disp_merge_mt8188.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek Video Disp Merge Support + * + * Copyright (c) 2025 BayLibre, SAS. + * Author: Julien Stephan <[email protected]> + */ + +#include <dm.h> + +#include "mtk_disp_comp.h" +#include "mtk_disp_merge_mt8188.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 +#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" }, + {} +}; + +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_mt8188.h b/drivers/video/mediatek/mtk_disp_merge_mt8188.h new file mode 100644 index 00000000000..7dd960541a7 --- /dev/null +++ b/drivers/video/mediatek/mtk_disp_merge_mt8188.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Mediatek Video Disp Merge Support + * + * Copyright (c) 2025 BayLibre, SAS. + * Author: Julien Stephan <[email protected]> + */ + +#ifndef _MTK_DISP_MERGE_MT8188_H +#define _MTK_DISP_MERGE_MT8188_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 -- 2.54.0
