brintos

brintos / linux-shallow public Read only

0
0
Text · 21.7 KiB · e0c0bb0 Raw
755 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2015 MediaTek Inc.4 */5 6#include <drm/drm_blend.h>7#include <drm/drm_fourcc.h>8#include <drm/drm_framebuffer.h>9 10#include <linux/clk.h>11#include <linux/component.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/platform_device.h>15#include <linux/pm_runtime.h>16#include <linux/soc/mediatek/mtk-cmdq.h>17 18#include "mtk_crtc.h"19#include "mtk_ddp_comp.h"20#include "mtk_disp_drv.h"21#include "mtk_drm_drv.h"22 23#define DISP_REG_OVL_INTEN			0x000424#define OVL_FME_CPL_INT					BIT(1)25#define DISP_REG_OVL_INTSTA			0x000826#define DISP_REG_OVL_EN				0x000c27#define DISP_REG_OVL_RST			0x001428#define DISP_REG_OVL_ROI_SIZE			0x002029#define DISP_REG_OVL_DATAPATH_CON		0x002430#define OVL_LAYER_SMI_ID_EN				BIT(0)31#define OVL_BGCLR_SEL_IN				BIT(2)32#define OVL_LAYER_AFBC_EN(n)				BIT(4+n)33#define DISP_REG_OVL_ROI_BGCLR			0x002834#define DISP_REG_OVL_SRC_CON			0x002c35#define DISP_REG_OVL_CON(n)			(0x0030 + 0x20 * (n))36#define DISP_REG_OVL_SRC_SIZE(n)		(0x0038 + 0x20 * (n))37#define DISP_REG_OVL_OFFSET(n)			(0x003c + 0x20 * (n))38#define DISP_REG_OVL_PITCH_MSB(n)		(0x0040 + 0x20 * (n))39#define OVL_PITCH_MSB_2ND_SUBBUF			BIT(16)40#define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20 * (n))41#define OVL_CONST_BLEND					BIT(28)42#define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))43#define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))44#define DISP_REG_OVL_ADDR_MT2701		0x004045#define DISP_REG_OVL_CLRFMT_EXT			0x02d046#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(n)		(GENMASK(1, 0) << (4 * (n)))47#define OVL_CON_CLRFMT_BIT_DEPTH(depth, n)		((depth) << (4 * (n)))48#define OVL_CON_CLRFMT_8_BIT				(0)49#define OVL_CON_CLRFMT_10_BIT				(1)50#define DISP_REG_OVL_ADDR_MT8173		0x0f4051#define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n))52#define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n) + 0x04)53#define DISP_REG_OVL_HDR_PITCH(ovl, n)		((ovl)->data->addr + 0x20 * (n) + 0x08)54 55#define GMC_THRESHOLD_BITS	1656#define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)57#define GMC_THRESHOLD_LOW	((1 << GMC_THRESHOLD_BITS) / 8)58 59#define OVL_CON_CLRFMT_MAN	BIT(23)60#define OVL_CON_BYTE_SWAP	BIT(24)61 62/* OVL_CON_RGB_SWAP works only if OVL_CON_CLRFMT_MAN is enabled */63#define OVL_CON_RGB_SWAP	BIT(25)64 65#define OVL_CON_CLRFMT_RGB	(1 << 12)66#define OVL_CON_CLRFMT_ARGB8888	(2 << 12)67#define OVL_CON_CLRFMT_RGBA8888	(3 << 12)68#define OVL_CON_CLRFMT_ABGR8888	(OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP)69#define OVL_CON_CLRFMT_BGRA8888	(OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP)70#define OVL_CON_CLRFMT_UYVY	(4 << 12)71#define OVL_CON_CLRFMT_YUYV	(5 << 12)72#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)73#define OVL_CON_CLRFMT_PARGB8888 ((3 << 12) | OVL_CON_CLRFMT_MAN)74#define OVL_CON_CLRFMT_PABGR8888 (OVL_CON_CLRFMT_PARGB8888 | OVL_CON_RGB_SWAP)75#define OVL_CON_CLRFMT_PBGRA8888 (OVL_CON_CLRFMT_PARGB8888 | OVL_CON_BYTE_SWAP)76#define OVL_CON_CLRFMT_PRGBA8888 (OVL_CON_CLRFMT_PABGR8888 | OVL_CON_BYTE_SWAP)77#define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \78					0 : OVL_CON_CLRFMT_RGB)79#define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \80					OVL_CON_CLRFMT_RGB : 0)81#define	OVL_CON_AEN		BIT(8)82#define	OVL_CON_ALPHA		0xff83#define	OVL_CON_VIRT_FLIP	BIT(9)84#define	OVL_CON_HORZ_FLIP	BIT(10)85 86#define OVL_COLOR_ALPHA		GENMASK(31, 24)87 88static inline bool is_10bit_rgb(u32 fmt)89{90	switch (fmt) {91	case DRM_FORMAT_XRGB2101010:92	case DRM_FORMAT_ARGB2101010:93	case DRM_FORMAT_RGBX1010102:94	case DRM_FORMAT_RGBA1010102:95	case DRM_FORMAT_XBGR2101010:96	case DRM_FORMAT_ABGR2101010:97	case DRM_FORMAT_BGRX1010102:98	case DRM_FORMAT_BGRA1010102:99		return true;100	}101	return false;102}103 104static const u32 mt8173_formats[] = {105	DRM_FORMAT_XRGB8888,106	DRM_FORMAT_ARGB8888,107	DRM_FORMAT_BGRX8888,108	DRM_FORMAT_BGRA8888,109	DRM_FORMAT_ABGR8888,110	DRM_FORMAT_XBGR8888,111	DRM_FORMAT_RGB888,112	DRM_FORMAT_BGR888,113	DRM_FORMAT_RGB565,114	DRM_FORMAT_UYVY,115	DRM_FORMAT_YUYV,116};117 118static const u32 mt8195_formats[] = {119	DRM_FORMAT_XRGB8888,120	DRM_FORMAT_ARGB8888,121	DRM_FORMAT_XRGB2101010,122	DRM_FORMAT_ARGB2101010,123	DRM_FORMAT_BGRX8888,124	DRM_FORMAT_BGRA8888,125	DRM_FORMAT_BGRX1010102,126	DRM_FORMAT_BGRA1010102,127	DRM_FORMAT_ABGR8888,128	DRM_FORMAT_XBGR8888,129	DRM_FORMAT_XBGR2101010,130	DRM_FORMAT_ABGR2101010,131	DRM_FORMAT_RGBX8888,132	DRM_FORMAT_RGBA8888,133	DRM_FORMAT_RGBX1010102,134	DRM_FORMAT_RGBA1010102,135	DRM_FORMAT_RGB888,136	DRM_FORMAT_BGR888,137	DRM_FORMAT_RGB565,138	DRM_FORMAT_UYVY,139	DRM_FORMAT_YUYV,140};141 142struct mtk_disp_ovl_data {143	unsigned int addr;144	unsigned int gmc_bits;145	unsigned int layer_nr;146	bool fmt_rgb565_is_0;147	bool smi_id_en;148	bool supports_afbc;149	const u32 blend_modes;150	const u32 *formats;151	size_t num_formats;152	bool supports_clrfmt_ext;153};154 155/*156 * struct mtk_disp_ovl - DISP_OVL driver structure157 * @crtc: associated crtc to report vblank events to158 * @data: platform data159 */160struct mtk_disp_ovl {161	struct drm_crtc			*crtc;162	struct clk			*clk;163	void __iomem			*regs;164	struct cmdq_client_reg		cmdq_reg;165	const struct mtk_disp_ovl_data	*data;166	void				(*vblank_cb)(void *data);167	void				*vblank_cb_data;168};169 170static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)171{172	struct mtk_disp_ovl *priv = dev_id;173 174	/* Clear frame completion interrupt */175	writel(0x0, priv->regs + DISP_REG_OVL_INTSTA);176 177	if (!priv->vblank_cb)178		return IRQ_NONE;179 180	priv->vblank_cb(priv->vblank_cb_data);181 182	return IRQ_HANDLED;183}184 185void mtk_ovl_register_vblank_cb(struct device *dev,186				void (*vblank_cb)(void *),187				void *vblank_cb_data)188{189	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);190 191	ovl->vblank_cb = vblank_cb;192	ovl->vblank_cb_data = vblank_cb_data;193}194 195void mtk_ovl_unregister_vblank_cb(struct device *dev)196{197	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);198 199	ovl->vblank_cb = NULL;200	ovl->vblank_cb_data = NULL;201}202 203void mtk_ovl_enable_vblank(struct device *dev)204{205	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);206 207	writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA);208	writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN);209}210 211void mtk_ovl_disable_vblank(struct device *dev)212{213	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);214 215	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);216}217 218u32 mtk_ovl_get_blend_modes(struct device *dev)219{220	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);221 222	return ovl->data->blend_modes;223}224 225const u32 *mtk_ovl_get_formats(struct device *dev)226{227	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);228 229	return ovl->data->formats;230}231 232size_t mtk_ovl_get_num_formats(struct device *dev)233{234	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);235 236	return ovl->data->num_formats;237}238 239int mtk_ovl_clk_enable(struct device *dev)240{241	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);242 243	return clk_prepare_enable(ovl->clk);244}245 246void mtk_ovl_clk_disable(struct device *dev)247{248	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);249 250	clk_disable_unprepare(ovl->clk);251}252 253void mtk_ovl_start(struct device *dev)254{255	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);256 257	if (ovl->data->smi_id_en) {258		unsigned int reg;259 260		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);261		reg = reg | OVL_LAYER_SMI_ID_EN;262		writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);263	}264	writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);265}266 267void mtk_ovl_stop(struct device *dev)268{269	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);270 271	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN);272	if (ovl->data->smi_id_en) {273		unsigned int reg;274 275		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);276		reg = reg & ~OVL_LAYER_SMI_ID_EN;277		writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);278	}279}280 281static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt,282			     int idx, bool enabled)283{284	mtk_ddp_write_mask(cmdq_pkt, enabled ? OVL_LAYER_AFBC_EN(idx) : 0,285			   &ovl->cmdq_reg, ovl->regs,286			   DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));287}288 289static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,290				  struct cmdq_pkt *cmdq_pkt)291{292	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);293	unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;294 295	if (!ovl->data->supports_clrfmt_ext)296		return;297 298	if (is_10bit_rgb(format))299		bit_depth = OVL_CON_CLRFMT_10_BIT;300 301	mtk_ddp_write_mask(cmdq_pkt, OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx),302			   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT,303			   OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx));304}305 306void mtk_ovl_config(struct device *dev, unsigned int w,307		    unsigned int h, unsigned int vrefresh,308		    unsigned int bpc, struct cmdq_pkt *cmdq_pkt)309{310	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);311 312	if (w != 0 && h != 0)313		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs,314				      DISP_REG_OVL_ROI_SIZE);315 316	/*317	 * The background color must be opaque black (ARGB),318	 * otherwise the alpha blending will have no effect319	 */320	mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg,321			      ovl->regs, DISP_REG_OVL_ROI_BGCLR);322 323	mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);324	mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);325}326 327unsigned int mtk_ovl_layer_nr(struct device *dev)328{329	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);330 331	return ovl->data->layer_nr;332}333 334unsigned int mtk_ovl_supported_rotations(struct device *dev)335{336	return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |337	       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;338}339 340int mtk_ovl_layer_check(struct device *dev, unsigned int idx,341			struct mtk_plane_state *mtk_state)342{343	struct drm_plane_state *state = &mtk_state->base;344 345	/* check if any unsupported rotation is set */346	if (state->rotation & ~mtk_ovl_supported_rotations(dev))347		return -EINVAL;348 349	/*350	 * TODO: Rotating/reflecting YUV buffers is not supported at this time.351	 *	 Only RGB[AX] variants are supported.352	 *	 Since DRM_MODE_ROTATE_0 means "no rotation", we should not353	 *	 reject layers with this property.354	 */355	if (state->fb->format->is_yuv && (state->rotation & ~DRM_MODE_ROTATE_0))356		return -EINVAL;357 358	return 0;359}360 361void mtk_ovl_layer_on(struct device *dev, unsigned int idx,362		      struct cmdq_pkt *cmdq_pkt)363{364	unsigned int gmc_thrshd_l;365	unsigned int gmc_thrshd_h;366	unsigned int gmc_value;367	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);368 369	mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs,370		      DISP_REG_OVL_RDMA_CTRL(idx));371	gmc_thrshd_l = GMC_THRESHOLD_LOW >>372		      (GMC_THRESHOLD_BITS - ovl->data->gmc_bits);373	gmc_thrshd_h = GMC_THRESHOLD_HIGH >>374		      (GMC_THRESHOLD_BITS - ovl->data->gmc_bits);375	if (ovl->data->gmc_bits == 10)376		gmc_value = gmc_thrshd_h | gmc_thrshd_h << 16;377	else378		gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 |379			    gmc_thrshd_h << 16 | gmc_thrshd_h << 24;380	mtk_ddp_write(cmdq_pkt, gmc_value,381		      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RDMA_GMC(idx));382	mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg, ovl->regs,383			   DISP_REG_OVL_SRC_CON, BIT(idx));384}385 386void mtk_ovl_layer_off(struct device *dev, unsigned int idx,387		       struct cmdq_pkt *cmdq_pkt)388{389	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);390 391	mtk_ddp_write_mask(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,392			   DISP_REG_OVL_SRC_CON, BIT(idx));393	mtk_ddp_write(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,394		      DISP_REG_OVL_RDMA_CTRL(idx));395}396 397static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl,398					struct mtk_plane_state *state)399{400	unsigned int fmt = state->pending.format;401	unsigned int blend_mode = DRM_MODE_BLEND_COVERAGE;402 403	/*404	 * For the platforms where OVL_CON_CLRFMT_MAN is defined in the hardware data sheet405	 * and supports premultiplied color formats, such as OVL_CON_CLRFMT_PARGB8888.406	 *407	 * Check blend_modes in the driver data to see if premultiplied mode is supported.408	 * If not, use coverage mode instead to set it to the supported color formats.409	 *410	 * Current DRM assumption is that alpha is default premultiplied, so the bitmask of411	 * blend_modes must include BIT(DRM_MODE_BLEND_PREMULTI). Otherwise, mtk_plane_init()412	 * will get an error return from drm_plane_create_blend_mode_property() and413	 * state->base.pixel_blend_mode should not be used.414	 */415	if (ovl->data->blend_modes & BIT(DRM_MODE_BLEND_PREMULTI))416		blend_mode = state->base.pixel_blend_mode;417 418	switch (fmt) {419	default:420	case DRM_FORMAT_RGB565:421		return OVL_CON_CLRFMT_RGB565(ovl);422	case DRM_FORMAT_BGR565:423		return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;424	case DRM_FORMAT_RGB888:425		return OVL_CON_CLRFMT_RGB888(ovl);426	case DRM_FORMAT_BGR888:427		return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;428	case DRM_FORMAT_RGBX8888:429	case DRM_FORMAT_RGBA8888:430	case DRM_FORMAT_RGBX1010102:431	case DRM_FORMAT_RGBA1010102:432		return blend_mode == DRM_MODE_BLEND_COVERAGE ?433		       OVL_CON_CLRFMT_RGBA8888 :434		       OVL_CON_CLRFMT_PRGBA8888;435	case DRM_FORMAT_BGRX8888:436	case DRM_FORMAT_BGRA8888:437	case DRM_FORMAT_BGRX1010102:438	case DRM_FORMAT_BGRA1010102:439		return blend_mode == DRM_MODE_BLEND_COVERAGE ?440		       OVL_CON_CLRFMT_BGRA8888 :441		       OVL_CON_CLRFMT_PBGRA8888;442	case DRM_FORMAT_XRGB8888:443	case DRM_FORMAT_ARGB8888:444	case DRM_FORMAT_XRGB2101010:445	case DRM_FORMAT_ARGB2101010:446		return blend_mode == DRM_MODE_BLEND_COVERAGE ?447		       OVL_CON_CLRFMT_ARGB8888 :448		       OVL_CON_CLRFMT_PARGB8888;449	case DRM_FORMAT_XBGR8888:450	case DRM_FORMAT_ABGR8888:451	case DRM_FORMAT_XBGR2101010:452	case DRM_FORMAT_ABGR2101010:453		return blend_mode == DRM_MODE_BLEND_COVERAGE ?454		       OVL_CON_CLRFMT_ABGR8888 :455		       OVL_CON_CLRFMT_PABGR8888;456	case DRM_FORMAT_UYVY:457		return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;458	case DRM_FORMAT_YUYV:459		return OVL_CON_CLRFMT_YUYV | OVL_CON_MTX_YUV_TO_RGB;460	}461}462 463void mtk_ovl_layer_config(struct device *dev, unsigned int idx,464			  struct mtk_plane_state *state,465			  struct cmdq_pkt *cmdq_pkt)466{467	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);468	struct mtk_plane_pending_state *pending = &state->pending;469	unsigned int addr = pending->addr;470	unsigned int hdr_addr = pending->hdr_addr;471	unsigned int pitch = pending->pitch;472	unsigned int hdr_pitch = pending->hdr_pitch;473	unsigned int fmt = pending->format;474	unsigned int offset = (pending->y << 16) | pending->x;475	unsigned int src_size = (pending->height << 16) | pending->width;476	unsigned int blend_mode = state->base.pixel_blend_mode;477	unsigned int ignore_pixel_alpha = 0;478	unsigned int con;479	bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;480	union overlay_pitch {481		struct split_pitch {482			u16 lsb;483			u16 msb;484		} split_pitch;485		u32 pitch;486	} overlay_pitch;487 488	overlay_pitch.pitch = pitch;489 490	if (!pending->enable) {491		mtk_ovl_layer_off(dev, idx, cmdq_pkt);492		return;493	}494 495	con = mtk_ovl_fmt_convert(ovl, state);496	if (state->base.fb) {497		con |= state->base.alpha & OVL_CON_ALPHA;498 499		/*500		 * For blend_modes supported SoCs, always enable alpha blending.501		 * For blend_modes unsupported SoCs, enable alpha blending when has_alpha is set.502		 */503		if (blend_mode || state->base.fb->format->has_alpha)504			con |= OVL_CON_AEN;505 506		/*507		 * Although the alpha channel can be ignored, CONST_BLD must be enabled508		 * for XRGB format, otherwise OVL will still read the value from memory.509		 * For RGB888 related formats, whether CONST_BLD is enabled or not won't510		 * affect the result. Therefore we use !has_alpha as the condition.511		 */512		if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE || !state->base.fb->format->has_alpha)513			ignore_pixel_alpha = OVL_CONST_BLEND;514	}515 516	if (pending->rotation & DRM_MODE_REFLECT_Y) {517		con |= OVL_CON_VIRT_FLIP;518		addr += (pending->height - 1) * pending->pitch;519	}520 521	if (pending->rotation & DRM_MODE_REFLECT_X) {522		con |= OVL_CON_HORZ_FLIP;523		addr += pending->pitch - 1;524	}525 526	if (ovl->data->supports_afbc)527		mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);528 529	mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,530			      DISP_REG_OVL_CON(idx));531	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,532			      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));533	mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,534			      DISP_REG_OVL_SRC_SIZE(idx));535	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,536			      DISP_REG_OVL_OFFSET(idx));537	mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,538			      DISP_REG_OVL_ADDR(ovl, idx));539 540	if (is_afbc) {541		mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,542				      DISP_REG_OVL_HDR_ADDR(ovl, idx));543		mtk_ddp_write_relaxed(cmdq_pkt,544				      OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,545				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));546		mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,547				      DISP_REG_OVL_HDR_PITCH(ovl, idx));548	} else {549		mtk_ddp_write_relaxed(cmdq_pkt,550				      overlay_pitch.split_pitch.msb,551				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));552	}553 554	mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);555	mtk_ovl_layer_on(dev, idx, cmdq_pkt);556}557 558void mtk_ovl_bgclr_in_on(struct device *dev)559{560	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);561	unsigned int reg;562 563	reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);564	reg = reg | OVL_BGCLR_SEL_IN;565	writel(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);566}567 568void mtk_ovl_bgclr_in_off(struct device *dev)569{570	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);571	unsigned int reg;572 573	reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);574	reg = reg & ~OVL_BGCLR_SEL_IN;575	writel(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);576}577 578static int mtk_disp_ovl_bind(struct device *dev, struct device *master,579			     void *data)580{581	return 0;582}583 584static void mtk_disp_ovl_unbind(struct device *dev, struct device *master,585				void *data)586{587}588 589static const struct component_ops mtk_disp_ovl_component_ops = {590	.bind	= mtk_disp_ovl_bind,591	.unbind = mtk_disp_ovl_unbind,592};593 594static int mtk_disp_ovl_probe(struct platform_device *pdev)595{596	struct device *dev = &pdev->dev;597	struct mtk_disp_ovl *priv;598	struct resource *res;599	int irq;600	int ret;601 602	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);603	if (!priv)604		return -ENOMEM;605 606	irq = platform_get_irq(pdev, 0);607	if (irq < 0)608		return irq;609 610	priv->clk = devm_clk_get(dev, NULL);611	if (IS_ERR(priv->clk))612		return dev_err_probe(dev, PTR_ERR(priv->clk),613				     "failed to get ovl clk\n");614 615	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);616	priv->regs = devm_ioremap_resource(dev, res);617	if (IS_ERR(priv->regs))618		return dev_err_probe(dev, PTR_ERR(priv->regs),619				     "failed to ioremap ovl\n");620#if IS_REACHABLE(CONFIG_MTK_CMDQ)621	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);622	if (ret)623		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");624#endif625 626	priv->data = of_device_get_match_data(dev);627	platform_set_drvdata(pdev, priv);628 629	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,630			       IRQF_TRIGGER_NONE, dev_name(dev), priv);631	if (ret < 0)632		return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);633 634	pm_runtime_enable(dev);635 636	ret = component_add(dev, &mtk_disp_ovl_component_ops);637	if (ret) {638		pm_runtime_disable(dev);639		return dev_err_probe(dev, ret, "Failed to add component\n");640	}641 642	return 0;643}644 645static void mtk_disp_ovl_remove(struct platform_device *pdev)646{647	component_del(&pdev->dev, &mtk_disp_ovl_component_ops);648	pm_runtime_disable(&pdev->dev);649}650 651static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {652	.addr = DISP_REG_OVL_ADDR_MT2701,653	.gmc_bits = 8,654	.layer_nr = 4,655	.fmt_rgb565_is_0 = false,656	.formats = mt8173_formats,657	.num_formats = ARRAY_SIZE(mt8173_formats),658};659 660static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {661	.addr = DISP_REG_OVL_ADDR_MT8173,662	.gmc_bits = 8,663	.layer_nr = 4,664	.fmt_rgb565_is_0 = true,665	.formats = mt8173_formats,666	.num_formats = ARRAY_SIZE(mt8173_formats),667};668 669static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {670	.addr = DISP_REG_OVL_ADDR_MT8173,671	.gmc_bits = 10,672	.layer_nr = 4,673	.fmt_rgb565_is_0 = true,674	.formats = mt8173_formats,675	.num_formats = ARRAY_SIZE(mt8173_formats),676};677 678static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {679	.addr = DISP_REG_OVL_ADDR_MT8173,680	.gmc_bits = 10,681	.layer_nr = 2,682	.fmt_rgb565_is_0 = true,683	.formats = mt8173_formats,684	.num_formats = ARRAY_SIZE(mt8173_formats),685};686 687static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {688	.addr = DISP_REG_OVL_ADDR_MT8173,689	.gmc_bits = 10,690	.layer_nr = 4,691	.fmt_rgb565_is_0 = true,692	.smi_id_en = true,693	.blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) |694		       BIT(DRM_MODE_BLEND_COVERAGE) |695		       BIT(DRM_MODE_BLEND_PIXEL_NONE),696	.formats = mt8173_formats,697	.num_formats = ARRAY_SIZE(mt8173_formats),698};699 700static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {701	.addr = DISP_REG_OVL_ADDR_MT8173,702	.gmc_bits = 10,703	.layer_nr = 2,704	.fmt_rgb565_is_0 = true,705	.smi_id_en = true,706	.blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) |707		       BIT(DRM_MODE_BLEND_COVERAGE) |708		       BIT(DRM_MODE_BLEND_PIXEL_NONE),709	.formats = mt8173_formats,710	.num_formats = ARRAY_SIZE(mt8173_formats),711};712 713static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {714	.addr = DISP_REG_OVL_ADDR_MT8173,715	.gmc_bits = 10,716	.layer_nr = 4,717	.fmt_rgb565_is_0 = true,718	.smi_id_en = true,719	.supports_afbc = true,720	.blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) |721		       BIT(DRM_MODE_BLEND_COVERAGE) |722		       BIT(DRM_MODE_BLEND_PIXEL_NONE),723	.formats = mt8195_formats,724	.num_formats = ARRAY_SIZE(mt8195_formats),725	.supports_clrfmt_ext = true,726};727 728static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {729	{ .compatible = "mediatek,mt2701-disp-ovl",730	  .data = &mt2701_ovl_driver_data},731	{ .compatible = "mediatek,mt8173-disp-ovl",732	  .data = &mt8173_ovl_driver_data},733	{ .compatible = "mediatek,mt8183-disp-ovl",734	  .data = &mt8183_ovl_driver_data},735	{ .compatible = "mediatek,mt8183-disp-ovl-2l",736	  .data = &mt8183_ovl_2l_driver_data},737	{ .compatible = "mediatek,mt8192-disp-ovl",738	  .data = &mt8192_ovl_driver_data},739	{ .compatible = "mediatek,mt8192-disp-ovl-2l",740	  .data = &mt8192_ovl_2l_driver_data},741	{ .compatible = "mediatek,mt8195-disp-ovl",742	  .data = &mt8195_ovl_driver_data},743	{},744};745MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);746 747struct platform_driver mtk_disp_ovl_driver = {748	.probe		= mtk_disp_ovl_probe,749	.remove_new	= mtk_disp_ovl_remove,750	.driver		= {751		.name	= "mediatek-disp-ovl",752		.of_match_table = mtk_disp_ovl_driver_dt_match,753	},754};755