162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2015 MediaTek Inc. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <drm/drm_blend.h> 762306a36Sopenharmony_ci#include <drm/drm_fourcc.h> 862306a36Sopenharmony_ci#include <drm/drm_framebuffer.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/clk.h> 1162306a36Sopenharmony_ci#include <linux/component.h> 1262306a36Sopenharmony_ci#include <linux/module.h> 1362306a36Sopenharmony_ci#include <linux/of.h> 1462306a36Sopenharmony_ci#include <linux/platform_device.h> 1562306a36Sopenharmony_ci#include <linux/pm_runtime.h> 1662306a36Sopenharmony_ci#include <linux/soc/mediatek/mtk-cmdq.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "mtk_disp_drv.h" 1962306a36Sopenharmony_ci#include "mtk_drm_crtc.h" 2062306a36Sopenharmony_ci#include "mtk_drm_ddp_comp.h" 2162306a36Sopenharmony_ci#include "mtk_drm_drv.h" 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define DISP_REG_OVL_INTEN 0x0004 2462306a36Sopenharmony_ci#define OVL_FME_CPL_INT BIT(1) 2562306a36Sopenharmony_ci#define DISP_REG_OVL_INTSTA 0x0008 2662306a36Sopenharmony_ci#define DISP_REG_OVL_EN 0x000c 2762306a36Sopenharmony_ci#define DISP_REG_OVL_RST 0x0014 2862306a36Sopenharmony_ci#define DISP_REG_OVL_ROI_SIZE 0x0020 2962306a36Sopenharmony_ci#define DISP_REG_OVL_DATAPATH_CON 0x0024 3062306a36Sopenharmony_ci#define OVL_LAYER_SMI_ID_EN BIT(0) 3162306a36Sopenharmony_ci#define OVL_BGCLR_SEL_IN BIT(2) 3262306a36Sopenharmony_ci#define OVL_LAYER_AFBC_EN(n) BIT(4+n) 3362306a36Sopenharmony_ci#define DISP_REG_OVL_ROI_BGCLR 0x0028 3462306a36Sopenharmony_ci#define DISP_REG_OVL_SRC_CON 0x002c 3562306a36Sopenharmony_ci#define DISP_REG_OVL_CON(n) (0x0030 + 0x20 * (n)) 3662306a36Sopenharmony_ci#define DISP_REG_OVL_SRC_SIZE(n) (0x0038 + 0x20 * (n)) 3762306a36Sopenharmony_ci#define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n)) 3862306a36Sopenharmony_ci#define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) 3962306a36Sopenharmony_ci#define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) 4062306a36Sopenharmony_ci#define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) 4162306a36Sopenharmony_ci#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) 4262306a36Sopenharmony_ci#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) 4362306a36Sopenharmony_ci#define DISP_REG_OVL_ADDR_MT2701 0x0040 4462306a36Sopenharmony_ci#define DISP_REG_OVL_CLRFMT_EXT 0x02D0 4562306a36Sopenharmony_ci#define DISP_REG_OVL_ADDR_MT8173 0x0f40 4662306a36Sopenharmony_ci#define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) 4762306a36Sopenharmony_ci#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) 4862306a36Sopenharmony_ci#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x08) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define GMC_THRESHOLD_BITS 16 5162306a36Sopenharmony_ci#define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) 5262306a36Sopenharmony_ci#define GMC_THRESHOLD_LOW ((1 << GMC_THRESHOLD_BITS) / 8) 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#define OVL_CON_BYTE_SWAP BIT(24) 5562306a36Sopenharmony_ci#define OVL_CON_MTX_YUV_TO_RGB (6 << 16) 5662306a36Sopenharmony_ci#define OVL_CON_CLRFMT_RGB (1 << 12) 5762306a36Sopenharmony_ci#define OVL_CON_CLRFMT_RGBA8888 (2 << 12) 5862306a36Sopenharmony_ci#define OVL_CON_CLRFMT_ARGB8888 (3 << 12) 5962306a36Sopenharmony_ci#define OVL_CON_CLRFMT_UYVY (4 << 12) 6062306a36Sopenharmony_ci#define OVL_CON_CLRFMT_YUYV (5 << 12) 6162306a36Sopenharmony_ci#define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ 6262306a36Sopenharmony_ci 0 : OVL_CON_CLRFMT_RGB) 6362306a36Sopenharmony_ci#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ 6462306a36Sopenharmony_ci OVL_CON_CLRFMT_RGB : 0) 6562306a36Sopenharmony_ci#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) 6662306a36Sopenharmony_ci#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) 6762306a36Sopenharmony_ci#define OVL_CON_CLRFMT_8_BIT 0x00 6862306a36Sopenharmony_ci#define OVL_CON_CLRFMT_10_BIT 0x01 6962306a36Sopenharmony_ci#define OVL_CON_AEN BIT(8) 7062306a36Sopenharmony_ci#define OVL_CON_ALPHA 0xff 7162306a36Sopenharmony_ci#define OVL_CON_VIRT_FLIP BIT(9) 7262306a36Sopenharmony_ci#define OVL_CON_HORZ_FLIP BIT(10) 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic const u32 mt8173_formats[] = { 7562306a36Sopenharmony_ci DRM_FORMAT_XRGB8888, 7662306a36Sopenharmony_ci DRM_FORMAT_ARGB8888, 7762306a36Sopenharmony_ci DRM_FORMAT_BGRX8888, 7862306a36Sopenharmony_ci DRM_FORMAT_BGRA8888, 7962306a36Sopenharmony_ci DRM_FORMAT_ABGR8888, 8062306a36Sopenharmony_ci DRM_FORMAT_XBGR8888, 8162306a36Sopenharmony_ci DRM_FORMAT_RGB888, 8262306a36Sopenharmony_ci DRM_FORMAT_BGR888, 8362306a36Sopenharmony_ci DRM_FORMAT_RGB565, 8462306a36Sopenharmony_ci DRM_FORMAT_UYVY, 8562306a36Sopenharmony_ci DRM_FORMAT_YUYV, 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic const u32 mt8195_formats[] = { 8962306a36Sopenharmony_ci DRM_FORMAT_XRGB8888, 9062306a36Sopenharmony_ci DRM_FORMAT_ARGB8888, 9162306a36Sopenharmony_ci DRM_FORMAT_ARGB2101010, 9262306a36Sopenharmony_ci DRM_FORMAT_BGRX8888, 9362306a36Sopenharmony_ci DRM_FORMAT_BGRA8888, 9462306a36Sopenharmony_ci DRM_FORMAT_BGRA1010102, 9562306a36Sopenharmony_ci DRM_FORMAT_ABGR8888, 9662306a36Sopenharmony_ci DRM_FORMAT_XBGR8888, 9762306a36Sopenharmony_ci DRM_FORMAT_RGB888, 9862306a36Sopenharmony_ci DRM_FORMAT_BGR888, 9962306a36Sopenharmony_ci DRM_FORMAT_RGB565, 10062306a36Sopenharmony_ci DRM_FORMAT_UYVY, 10162306a36Sopenharmony_ci DRM_FORMAT_YUYV, 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistruct mtk_disp_ovl_data { 10562306a36Sopenharmony_ci unsigned int addr; 10662306a36Sopenharmony_ci unsigned int gmc_bits; 10762306a36Sopenharmony_ci unsigned int layer_nr; 10862306a36Sopenharmony_ci bool fmt_rgb565_is_0; 10962306a36Sopenharmony_ci bool smi_id_en; 11062306a36Sopenharmony_ci bool supports_afbc; 11162306a36Sopenharmony_ci const u32 *formats; 11262306a36Sopenharmony_ci size_t num_formats; 11362306a36Sopenharmony_ci bool supports_clrfmt_ext; 11462306a36Sopenharmony_ci}; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci/* 11762306a36Sopenharmony_ci * struct mtk_disp_ovl - DISP_OVL driver structure 11862306a36Sopenharmony_ci * @crtc: associated crtc to report vblank events to 11962306a36Sopenharmony_ci * @data: platform data 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_cistruct mtk_disp_ovl { 12262306a36Sopenharmony_ci struct drm_crtc *crtc; 12362306a36Sopenharmony_ci struct clk *clk; 12462306a36Sopenharmony_ci void __iomem *regs; 12562306a36Sopenharmony_ci struct cmdq_client_reg cmdq_reg; 12662306a36Sopenharmony_ci const struct mtk_disp_ovl_data *data; 12762306a36Sopenharmony_ci void (*vblank_cb)(void *data); 12862306a36Sopenharmony_ci void *vblank_cb_data; 12962306a36Sopenharmony_ci}; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci struct mtk_disp_ovl *priv = dev_id; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci /* Clear frame completion interrupt */ 13662306a36Sopenharmony_ci writel(0x0, priv->regs + DISP_REG_OVL_INTSTA); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci if (!priv->vblank_cb) 13962306a36Sopenharmony_ci return IRQ_NONE; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci priv->vblank_cb(priv->vblank_cb_data); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci return IRQ_HANDLED; 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_civoid mtk_ovl_register_vblank_cb(struct device *dev, 14762306a36Sopenharmony_ci void (*vblank_cb)(void *), 14862306a36Sopenharmony_ci void *vblank_cb_data) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci ovl->vblank_cb = vblank_cb; 15362306a36Sopenharmony_ci ovl->vblank_cb_data = vblank_cb_data; 15462306a36Sopenharmony_ci} 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_civoid mtk_ovl_unregister_vblank_cb(struct device *dev) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci ovl->vblank_cb = NULL; 16162306a36Sopenharmony_ci ovl->vblank_cb_data = NULL; 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_civoid mtk_ovl_enable_vblank(struct device *dev) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); 16962306a36Sopenharmony_ci writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN); 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_civoid mtk_ovl_disable_vblank(struct device *dev) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ciconst u32 *mtk_ovl_get_formats(struct device *dev) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci return ovl->data->formats; 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cisize_t mtk_ovl_get_num_formats(struct device *dev) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci return ovl->data->num_formats; 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ciint mtk_ovl_clk_enable(struct device *dev) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci return clk_prepare_enable(ovl->clk); 19862306a36Sopenharmony_ci} 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_civoid mtk_ovl_clk_disable(struct device *dev) 20162306a36Sopenharmony_ci{ 20262306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci clk_disable_unprepare(ovl->clk); 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_civoid mtk_ovl_start(struct device *dev) 20862306a36Sopenharmony_ci{ 20962306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci if (ovl->data->smi_id_en) { 21262306a36Sopenharmony_ci unsigned int reg; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); 21562306a36Sopenharmony_ci reg = reg | OVL_LAYER_SMI_ID_EN; 21662306a36Sopenharmony_ci writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN); 21962306a36Sopenharmony_ci} 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_civoid mtk_ovl_stop(struct device *dev) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN); 22662306a36Sopenharmony_ci if (ovl->data->smi_id_en) { 22762306a36Sopenharmony_ci unsigned int reg; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); 23062306a36Sopenharmony_ci reg = reg & ~OVL_LAYER_SMI_ID_EN; 23162306a36Sopenharmony_ci writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); 23262306a36Sopenharmony_ci } 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt, 23662306a36Sopenharmony_ci int idx, bool enabled) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci mtk_ddp_write_mask(cmdq_pkt, enabled ? OVL_LAYER_AFBC_EN(idx) : 0, 23962306a36Sopenharmony_ci &ovl->cmdq_reg, ovl->regs, 24062306a36Sopenharmony_ci DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx)); 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_cistatic void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, 24462306a36Sopenharmony_ci struct cmdq_pkt *cmdq_pkt) 24562306a36Sopenharmony_ci{ 24662306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 24762306a36Sopenharmony_ci unsigned int reg; 24862306a36Sopenharmony_ci unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci if (!ovl->data->supports_clrfmt_ext) 25162306a36Sopenharmony_ci return; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); 25462306a36Sopenharmony_ci reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if (format == DRM_FORMAT_RGBA1010102 || 25762306a36Sopenharmony_ci format == DRM_FORMAT_BGRA1010102 || 25862306a36Sopenharmony_ci format == DRM_FORMAT_ARGB2101010) 25962306a36Sopenharmony_ci bit_depth = OVL_CON_CLRFMT_10_BIT; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, 26462306a36Sopenharmony_ci ovl->regs, DISP_REG_OVL_CLRFMT_EXT); 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_civoid mtk_ovl_config(struct device *dev, unsigned int w, 26862306a36Sopenharmony_ci unsigned int h, unsigned int vrefresh, 26962306a36Sopenharmony_ci unsigned int bpc, struct cmdq_pkt *cmdq_pkt) 27062306a36Sopenharmony_ci{ 27162306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci if (w != 0 && h != 0) 27462306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs, 27562306a36Sopenharmony_ci DISP_REG_OVL_ROI_SIZE); 27662306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST); 27962306a36Sopenharmony_ci mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST); 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ciunsigned int mtk_ovl_layer_nr(struct device *dev) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci return ovl->data->layer_nr; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ciunsigned int mtk_ovl_supported_rotations(struct device *dev) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 29262306a36Sopenharmony_ci DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ciint mtk_ovl_layer_check(struct device *dev, unsigned int idx, 29662306a36Sopenharmony_ci struct mtk_plane_state *mtk_state) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci struct drm_plane_state *state = &mtk_state->base; 29962306a36Sopenharmony_ci unsigned int rotation = 0; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci rotation = drm_rotation_simplify(state->rotation, 30262306a36Sopenharmony_ci DRM_MODE_ROTATE_0 | 30362306a36Sopenharmony_ci DRM_MODE_REFLECT_X | 30462306a36Sopenharmony_ci DRM_MODE_REFLECT_Y); 30562306a36Sopenharmony_ci rotation &= ~DRM_MODE_ROTATE_0; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci /* We can only do reflection, not rotation */ 30862306a36Sopenharmony_ci if ((rotation & DRM_MODE_ROTATE_MASK) != 0) 30962306a36Sopenharmony_ci return -EINVAL; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci /* 31262306a36Sopenharmony_ci * TODO: Rotating/reflecting YUV buffers is not supported at this time. 31362306a36Sopenharmony_ci * Only RGB[AX] variants are supported. 31462306a36Sopenharmony_ci */ 31562306a36Sopenharmony_ci if (state->fb->format->is_yuv && rotation != 0) 31662306a36Sopenharmony_ci return -EINVAL; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci state->rotation = rotation; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci return 0; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_civoid mtk_ovl_layer_on(struct device *dev, unsigned int idx, 32462306a36Sopenharmony_ci struct cmdq_pkt *cmdq_pkt) 32562306a36Sopenharmony_ci{ 32662306a36Sopenharmony_ci unsigned int gmc_thrshd_l; 32762306a36Sopenharmony_ci unsigned int gmc_thrshd_h; 32862306a36Sopenharmony_ci unsigned int gmc_value; 32962306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, 33262306a36Sopenharmony_ci DISP_REG_OVL_RDMA_CTRL(idx)); 33362306a36Sopenharmony_ci gmc_thrshd_l = GMC_THRESHOLD_LOW >> 33462306a36Sopenharmony_ci (GMC_THRESHOLD_BITS - ovl->data->gmc_bits); 33562306a36Sopenharmony_ci gmc_thrshd_h = GMC_THRESHOLD_HIGH >> 33662306a36Sopenharmony_ci (GMC_THRESHOLD_BITS - ovl->data->gmc_bits); 33762306a36Sopenharmony_ci if (ovl->data->gmc_bits == 10) 33862306a36Sopenharmony_ci gmc_value = gmc_thrshd_h | gmc_thrshd_h << 16; 33962306a36Sopenharmony_ci else 34062306a36Sopenharmony_ci gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 | 34162306a36Sopenharmony_ci gmc_thrshd_h << 16 | gmc_thrshd_h << 24; 34262306a36Sopenharmony_ci mtk_ddp_write(cmdq_pkt, gmc_value, 34362306a36Sopenharmony_ci &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RDMA_GMC(idx)); 34462306a36Sopenharmony_ci mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg, ovl->regs, 34562306a36Sopenharmony_ci DISP_REG_OVL_SRC_CON, BIT(idx)); 34662306a36Sopenharmony_ci} 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_civoid mtk_ovl_layer_off(struct device *dev, unsigned int idx, 34962306a36Sopenharmony_ci struct cmdq_pkt *cmdq_pkt) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci mtk_ddp_write_mask(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs, 35462306a36Sopenharmony_ci DISP_REG_OVL_SRC_CON, BIT(idx)); 35562306a36Sopenharmony_ci mtk_ddp_write(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs, 35662306a36Sopenharmony_ci DISP_REG_OVL_RDMA_CTRL(idx)); 35762306a36Sopenharmony_ci} 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_cistatic unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) 36062306a36Sopenharmony_ci{ 36162306a36Sopenharmony_ci /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" 36262306a36Sopenharmony_ci * is defined in mediatek HW data sheet. 36362306a36Sopenharmony_ci * The alphabet order in XXX is no relation to data 36462306a36Sopenharmony_ci * arrangement in memory. 36562306a36Sopenharmony_ci */ 36662306a36Sopenharmony_ci switch (fmt) { 36762306a36Sopenharmony_ci default: 36862306a36Sopenharmony_ci case DRM_FORMAT_RGB565: 36962306a36Sopenharmony_ci return OVL_CON_CLRFMT_RGB565(ovl); 37062306a36Sopenharmony_ci case DRM_FORMAT_BGR565: 37162306a36Sopenharmony_ci return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP; 37262306a36Sopenharmony_ci case DRM_FORMAT_RGB888: 37362306a36Sopenharmony_ci return OVL_CON_CLRFMT_RGB888(ovl); 37462306a36Sopenharmony_ci case DRM_FORMAT_BGR888: 37562306a36Sopenharmony_ci return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP; 37662306a36Sopenharmony_ci case DRM_FORMAT_RGBX8888: 37762306a36Sopenharmony_ci case DRM_FORMAT_RGBA8888: 37862306a36Sopenharmony_ci return OVL_CON_CLRFMT_ARGB8888; 37962306a36Sopenharmony_ci case DRM_FORMAT_BGRX8888: 38062306a36Sopenharmony_ci case DRM_FORMAT_BGRA8888: 38162306a36Sopenharmony_ci case DRM_FORMAT_BGRA1010102: 38262306a36Sopenharmony_ci return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP; 38362306a36Sopenharmony_ci case DRM_FORMAT_XRGB8888: 38462306a36Sopenharmony_ci case DRM_FORMAT_ARGB8888: 38562306a36Sopenharmony_ci case DRM_FORMAT_ARGB2101010: 38662306a36Sopenharmony_ci return OVL_CON_CLRFMT_RGBA8888; 38762306a36Sopenharmony_ci case DRM_FORMAT_XBGR8888: 38862306a36Sopenharmony_ci case DRM_FORMAT_ABGR8888: 38962306a36Sopenharmony_ci return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP; 39062306a36Sopenharmony_ci case DRM_FORMAT_UYVY: 39162306a36Sopenharmony_ci return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB; 39262306a36Sopenharmony_ci case DRM_FORMAT_YUYV: 39362306a36Sopenharmony_ci return OVL_CON_CLRFMT_YUYV | OVL_CON_MTX_YUV_TO_RGB; 39462306a36Sopenharmony_ci } 39562306a36Sopenharmony_ci} 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_civoid mtk_ovl_layer_config(struct device *dev, unsigned int idx, 39862306a36Sopenharmony_ci struct mtk_plane_state *state, 39962306a36Sopenharmony_ci struct cmdq_pkt *cmdq_pkt) 40062306a36Sopenharmony_ci{ 40162306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 40262306a36Sopenharmony_ci struct mtk_plane_pending_state *pending = &state->pending; 40362306a36Sopenharmony_ci unsigned int addr = pending->addr; 40462306a36Sopenharmony_ci unsigned int hdr_addr = pending->hdr_addr; 40562306a36Sopenharmony_ci unsigned int pitch = pending->pitch; 40662306a36Sopenharmony_ci unsigned int hdr_pitch = pending->hdr_pitch; 40762306a36Sopenharmony_ci unsigned int fmt = pending->format; 40862306a36Sopenharmony_ci unsigned int offset = (pending->y << 16) | pending->x; 40962306a36Sopenharmony_ci unsigned int src_size = (pending->height << 16) | pending->width; 41062306a36Sopenharmony_ci unsigned int con; 41162306a36Sopenharmony_ci bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR; 41262306a36Sopenharmony_ci union overlay_pitch { 41362306a36Sopenharmony_ci struct split_pitch { 41462306a36Sopenharmony_ci u16 lsb; 41562306a36Sopenharmony_ci u16 msb; 41662306a36Sopenharmony_ci } split_pitch; 41762306a36Sopenharmony_ci u32 pitch; 41862306a36Sopenharmony_ci } overlay_pitch; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci overlay_pitch.pitch = pitch; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci if (!pending->enable) { 42362306a36Sopenharmony_ci mtk_ovl_layer_off(dev, idx, cmdq_pkt); 42462306a36Sopenharmony_ci return; 42562306a36Sopenharmony_ci } 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci con = ovl_fmt_convert(ovl, fmt); 42862306a36Sopenharmony_ci if (state->base.fb && state->base.fb->format->has_alpha) 42962306a36Sopenharmony_ci con |= OVL_CON_AEN | OVL_CON_ALPHA; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci if (pending->rotation & DRM_MODE_REFLECT_Y) { 43262306a36Sopenharmony_ci con |= OVL_CON_VIRT_FLIP; 43362306a36Sopenharmony_ci addr += (pending->height - 1) * pending->pitch; 43462306a36Sopenharmony_ci } 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci if (pending->rotation & DRM_MODE_REFLECT_X) { 43762306a36Sopenharmony_ci con |= OVL_CON_HORZ_FLIP; 43862306a36Sopenharmony_ci addr += pending->pitch - 1; 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci if (ovl->data->supports_afbc) 44262306a36Sopenharmony_ci mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc); 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs, 44562306a36Sopenharmony_ci DISP_REG_OVL_CON(idx)); 44662306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs, 44762306a36Sopenharmony_ci DISP_REG_OVL_PITCH(idx)); 44862306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs, 44962306a36Sopenharmony_ci DISP_REG_OVL_SRC_SIZE(idx)); 45062306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs, 45162306a36Sopenharmony_ci DISP_REG_OVL_OFFSET(idx)); 45262306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs, 45362306a36Sopenharmony_ci DISP_REG_OVL_ADDR(ovl, idx)); 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci if (is_afbc) { 45662306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs, 45762306a36Sopenharmony_ci DISP_REG_OVL_HDR_ADDR(ovl, idx)); 45862306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, 45962306a36Sopenharmony_ci OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb, 46062306a36Sopenharmony_ci &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); 46162306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs, 46262306a36Sopenharmony_ci DISP_REG_OVL_HDR_PITCH(ovl, idx)); 46362306a36Sopenharmony_ci } else { 46462306a36Sopenharmony_ci mtk_ddp_write_relaxed(cmdq_pkt, 46562306a36Sopenharmony_ci overlay_pitch.split_pitch.msb, 46662306a36Sopenharmony_ci &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); 46762306a36Sopenharmony_ci } 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); 47062306a36Sopenharmony_ci mtk_ovl_layer_on(dev, idx, cmdq_pkt); 47162306a36Sopenharmony_ci} 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_civoid mtk_ovl_bgclr_in_on(struct device *dev) 47462306a36Sopenharmony_ci{ 47562306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 47662306a36Sopenharmony_ci unsigned int reg; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); 47962306a36Sopenharmony_ci reg = reg | OVL_BGCLR_SEL_IN; 48062306a36Sopenharmony_ci writel(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); 48162306a36Sopenharmony_ci} 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_civoid mtk_ovl_bgclr_in_off(struct device *dev) 48462306a36Sopenharmony_ci{ 48562306a36Sopenharmony_ci struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); 48662306a36Sopenharmony_ci unsigned int reg; 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON); 48962306a36Sopenharmony_ci reg = reg & ~OVL_BGCLR_SEL_IN; 49062306a36Sopenharmony_ci writel(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON); 49162306a36Sopenharmony_ci} 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_cistatic int mtk_disp_ovl_bind(struct device *dev, struct device *master, 49462306a36Sopenharmony_ci void *data) 49562306a36Sopenharmony_ci{ 49662306a36Sopenharmony_ci return 0; 49762306a36Sopenharmony_ci} 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_cistatic void mtk_disp_ovl_unbind(struct device *dev, struct device *master, 50062306a36Sopenharmony_ci void *data) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic const struct component_ops mtk_disp_ovl_component_ops = { 50562306a36Sopenharmony_ci .bind = mtk_disp_ovl_bind, 50662306a36Sopenharmony_ci .unbind = mtk_disp_ovl_unbind, 50762306a36Sopenharmony_ci}; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_cistatic int mtk_disp_ovl_probe(struct platform_device *pdev) 51062306a36Sopenharmony_ci{ 51162306a36Sopenharmony_ci struct device *dev = &pdev->dev; 51262306a36Sopenharmony_ci struct mtk_disp_ovl *priv; 51362306a36Sopenharmony_ci struct resource *res; 51462306a36Sopenharmony_ci int irq; 51562306a36Sopenharmony_ci int ret; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 51862306a36Sopenharmony_ci if (!priv) 51962306a36Sopenharmony_ci return -ENOMEM; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci irq = platform_get_irq(pdev, 0); 52262306a36Sopenharmony_ci if (irq < 0) 52362306a36Sopenharmony_ci return irq; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci priv->clk = devm_clk_get(dev, NULL); 52662306a36Sopenharmony_ci if (IS_ERR(priv->clk)) { 52762306a36Sopenharmony_ci dev_err(dev, "failed to get ovl clk\n"); 52862306a36Sopenharmony_ci return PTR_ERR(priv->clk); 52962306a36Sopenharmony_ci } 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 53262306a36Sopenharmony_ci priv->regs = devm_ioremap_resource(dev, res); 53362306a36Sopenharmony_ci if (IS_ERR(priv->regs)) { 53462306a36Sopenharmony_ci dev_err(dev, "failed to ioremap ovl\n"); 53562306a36Sopenharmony_ci return PTR_ERR(priv->regs); 53662306a36Sopenharmony_ci } 53762306a36Sopenharmony_ci#if IS_REACHABLE(CONFIG_MTK_CMDQ) 53862306a36Sopenharmony_ci ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); 53962306a36Sopenharmony_ci if (ret) 54062306a36Sopenharmony_ci dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); 54162306a36Sopenharmony_ci#endif 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci priv->data = of_device_get_match_data(dev); 54462306a36Sopenharmony_ci platform_set_drvdata(pdev, priv); 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler, 54762306a36Sopenharmony_ci IRQF_TRIGGER_NONE, dev_name(dev), priv); 54862306a36Sopenharmony_ci if (ret < 0) { 54962306a36Sopenharmony_ci dev_err(dev, "Failed to request irq %d: %d\n", irq, ret); 55062306a36Sopenharmony_ci return ret; 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci pm_runtime_enable(dev); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci ret = component_add(dev, &mtk_disp_ovl_component_ops); 55662306a36Sopenharmony_ci if (ret) { 55762306a36Sopenharmony_ci pm_runtime_disable(dev); 55862306a36Sopenharmony_ci dev_err(dev, "Failed to add component: %d\n", ret); 55962306a36Sopenharmony_ci } 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci return ret; 56262306a36Sopenharmony_ci} 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_cistatic void mtk_disp_ovl_remove(struct platform_device *pdev) 56562306a36Sopenharmony_ci{ 56662306a36Sopenharmony_ci component_del(&pdev->dev, &mtk_disp_ovl_component_ops); 56762306a36Sopenharmony_ci pm_runtime_disable(&pdev->dev); 56862306a36Sopenharmony_ci} 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_cistatic const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { 57162306a36Sopenharmony_ci .addr = DISP_REG_OVL_ADDR_MT2701, 57262306a36Sopenharmony_ci .gmc_bits = 8, 57362306a36Sopenharmony_ci .layer_nr = 4, 57462306a36Sopenharmony_ci .fmt_rgb565_is_0 = false, 57562306a36Sopenharmony_ci .formats = mt8173_formats, 57662306a36Sopenharmony_ci .num_formats = ARRAY_SIZE(mt8173_formats), 57762306a36Sopenharmony_ci}; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_cistatic const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { 58062306a36Sopenharmony_ci .addr = DISP_REG_OVL_ADDR_MT8173, 58162306a36Sopenharmony_ci .gmc_bits = 8, 58262306a36Sopenharmony_ci .layer_nr = 4, 58362306a36Sopenharmony_ci .fmt_rgb565_is_0 = true, 58462306a36Sopenharmony_ci .formats = mt8173_formats, 58562306a36Sopenharmony_ci .num_formats = ARRAY_SIZE(mt8173_formats), 58662306a36Sopenharmony_ci}; 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_cistatic const struct mtk_disp_ovl_data mt8183_ovl_driver_data = { 58962306a36Sopenharmony_ci .addr = DISP_REG_OVL_ADDR_MT8173, 59062306a36Sopenharmony_ci .gmc_bits = 10, 59162306a36Sopenharmony_ci .layer_nr = 4, 59262306a36Sopenharmony_ci .fmt_rgb565_is_0 = true, 59362306a36Sopenharmony_ci .formats = mt8173_formats, 59462306a36Sopenharmony_ci .num_formats = ARRAY_SIZE(mt8173_formats), 59562306a36Sopenharmony_ci}; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_cistatic const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = { 59862306a36Sopenharmony_ci .addr = DISP_REG_OVL_ADDR_MT8173, 59962306a36Sopenharmony_ci .gmc_bits = 10, 60062306a36Sopenharmony_ci .layer_nr = 2, 60162306a36Sopenharmony_ci .fmt_rgb565_is_0 = true, 60262306a36Sopenharmony_ci .formats = mt8173_formats, 60362306a36Sopenharmony_ci .num_formats = ARRAY_SIZE(mt8173_formats), 60462306a36Sopenharmony_ci}; 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_cistatic const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { 60762306a36Sopenharmony_ci .addr = DISP_REG_OVL_ADDR_MT8173, 60862306a36Sopenharmony_ci .gmc_bits = 10, 60962306a36Sopenharmony_ci .layer_nr = 4, 61062306a36Sopenharmony_ci .fmt_rgb565_is_0 = true, 61162306a36Sopenharmony_ci .smi_id_en = true, 61262306a36Sopenharmony_ci .formats = mt8173_formats, 61362306a36Sopenharmony_ci .num_formats = ARRAY_SIZE(mt8173_formats), 61462306a36Sopenharmony_ci}; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = { 61762306a36Sopenharmony_ci .addr = DISP_REG_OVL_ADDR_MT8173, 61862306a36Sopenharmony_ci .gmc_bits = 10, 61962306a36Sopenharmony_ci .layer_nr = 2, 62062306a36Sopenharmony_ci .fmt_rgb565_is_0 = true, 62162306a36Sopenharmony_ci .smi_id_en = true, 62262306a36Sopenharmony_ci .formats = mt8173_formats, 62362306a36Sopenharmony_ci .num_formats = ARRAY_SIZE(mt8173_formats), 62462306a36Sopenharmony_ci}; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_cistatic const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { 62762306a36Sopenharmony_ci .addr = DISP_REG_OVL_ADDR_MT8173, 62862306a36Sopenharmony_ci .gmc_bits = 10, 62962306a36Sopenharmony_ci .layer_nr = 4, 63062306a36Sopenharmony_ci .fmt_rgb565_is_0 = true, 63162306a36Sopenharmony_ci .smi_id_en = true, 63262306a36Sopenharmony_ci .supports_afbc = true, 63362306a36Sopenharmony_ci .formats = mt8195_formats, 63462306a36Sopenharmony_ci .num_formats = ARRAY_SIZE(mt8195_formats), 63562306a36Sopenharmony_ci .supports_clrfmt_ext = true, 63662306a36Sopenharmony_ci}; 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_cistatic const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { 63962306a36Sopenharmony_ci { .compatible = "mediatek,mt2701-disp-ovl", 64062306a36Sopenharmony_ci .data = &mt2701_ovl_driver_data}, 64162306a36Sopenharmony_ci { .compatible = "mediatek,mt8173-disp-ovl", 64262306a36Sopenharmony_ci .data = &mt8173_ovl_driver_data}, 64362306a36Sopenharmony_ci { .compatible = "mediatek,mt8183-disp-ovl", 64462306a36Sopenharmony_ci .data = &mt8183_ovl_driver_data}, 64562306a36Sopenharmony_ci { .compatible = "mediatek,mt8183-disp-ovl-2l", 64662306a36Sopenharmony_ci .data = &mt8183_ovl_2l_driver_data}, 64762306a36Sopenharmony_ci { .compatible = "mediatek,mt8192-disp-ovl", 64862306a36Sopenharmony_ci .data = &mt8192_ovl_driver_data}, 64962306a36Sopenharmony_ci { .compatible = "mediatek,mt8192-disp-ovl-2l", 65062306a36Sopenharmony_ci .data = &mt8192_ovl_2l_driver_data}, 65162306a36Sopenharmony_ci { .compatible = "mediatek,mt8195-disp-ovl", 65262306a36Sopenharmony_ci .data = &mt8195_ovl_driver_data}, 65362306a36Sopenharmony_ci {}, 65462306a36Sopenharmony_ci}; 65562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match); 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_cistruct platform_driver mtk_disp_ovl_driver = { 65862306a36Sopenharmony_ci .probe = mtk_disp_ovl_probe, 65962306a36Sopenharmony_ci .remove_new = mtk_disp_ovl_remove, 66062306a36Sopenharmony_ci .driver = { 66162306a36Sopenharmony_ci .name = "mediatek-disp-ovl", 66262306a36Sopenharmony_ci .owner = THIS_MODULE, 66362306a36Sopenharmony_ci .of_match_table = mtk_disp_ovl_driver_dt_match, 66462306a36Sopenharmony_ci }, 66562306a36Sopenharmony_ci}; 666