brintos

brintos / linux-shallow public Read only

0
0
Text · 23.2 KiB · d70616d Raw
720 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2016 BayLibre, SAS4 * Author: Neil Armstrong <narmstrong@baylibre.com>5 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.6 * Copyright (C) 2014 Endless Mobile7 *8 * Written by:9 *     Jasper St. Pierre <jstpierre@mecheye.net>10 */11 12#include <linux/bitfield.h>13#include <linux/soc/amlogic/meson-canvas.h>14 15#include <drm/drm_atomic_helper.h>16#include <drm/drm_device.h>17#include <drm/drm_print.h>18#include <drm/drm_probe_helper.h>19#include <drm/drm_vblank.h>20 21#include "meson_crtc.h"22#include "meson_plane.h"23#include "meson_registers.h"24#include "meson_venc.h"25#include "meson_viu.h"26#include "meson_rdma.h"27#include "meson_vpp.h"28#include "meson_osd_afbcd.h"29 30#define MESON_G12A_VIU_OFFSET	0x5ec031 32/* CRTC definition */33 34struct meson_crtc {35	struct drm_crtc base;36	struct drm_pending_vblank_event *event;37	struct meson_drm *priv;38	void (*enable_osd1)(struct meson_drm *priv);39	void (*enable_vd1)(struct meson_drm *priv);40	void (*enable_osd1_afbc)(struct meson_drm *priv);41	void (*disable_osd1_afbc)(struct meson_drm *priv);42	unsigned int viu_offset;43	bool vsync_forced;44	bool vsync_disabled;45};46#define to_meson_crtc(x) container_of(x, struct meson_crtc, base)47 48/* CRTC */49 50static int meson_crtc_enable_vblank(struct drm_crtc *crtc)51{52	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);53	struct meson_drm *priv = meson_crtc->priv;54 55	meson_crtc->vsync_disabled = false;56	meson_venc_enable_vsync(priv);57 58	return 0;59}60 61static void meson_crtc_disable_vblank(struct drm_crtc *crtc)62{63	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);64	struct meson_drm *priv = meson_crtc->priv;65 66	if (!meson_crtc->vsync_forced) {67		meson_crtc->vsync_disabled = true;68		meson_venc_disable_vsync(priv);69	}70}71 72static const struct drm_crtc_funcs meson_crtc_funcs = {73	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,74	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,75	.destroy		= drm_crtc_cleanup,76	.page_flip		= drm_atomic_helper_page_flip,77	.reset			= drm_atomic_helper_crtc_reset,78	.set_config             = drm_atomic_helper_set_config,79	.enable_vblank		= meson_crtc_enable_vblank,80	.disable_vblank		= meson_crtc_disable_vblank,81 82};83 84static void meson_g12a_crtc_atomic_enable(struct drm_crtc *crtc,85					  struct drm_atomic_state *state)86{87	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);88	struct drm_crtc_state *crtc_state = crtc->state;89	struct meson_drm *priv = meson_crtc->priv;90 91	DRM_DEBUG_DRIVER("\n");92 93	if (!crtc_state) {94		DRM_ERROR("Invalid crtc_state\n");95		return;96	}97 98	/* VD1 Preblend vertical start/end */99	writel(FIELD_PREP(GENMASK(11, 0), 2303),100	       priv->io_base + _REG(VPP_PREBLEND_VD1_V_START_END));101 102	/* Setup Blender */103	writel(crtc_state->mode.hdisplay |104	       crtc_state->mode.vdisplay << 16,105	       priv->io_base + _REG(VPP_POSTBLEND_H_SIZE));106 107	writel_relaxed(0 << 16 |108			(crtc_state->mode.hdisplay - 1),109			priv->io_base + _REG(VPP_OSD1_BLD_H_SCOPE));110	writel_relaxed(0 << 16 |111			(crtc_state->mode.vdisplay - 1),112			priv->io_base + _REG(VPP_OSD1_BLD_V_SCOPE));113	writel_relaxed(crtc_state->mode.hdisplay << 16 |114			crtc_state->mode.vdisplay,115			priv->io_base + _REG(VPP_OUT_H_V_SIZE));116 117	drm_crtc_vblank_on(crtc);118}119 120static void meson_crtc_atomic_enable(struct drm_crtc *crtc,121				     struct drm_atomic_state *state)122{123	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);124	struct drm_crtc_state *crtc_state = crtc->state;125	struct meson_drm *priv = meson_crtc->priv;126 127	DRM_DEBUG_DRIVER("\n");128 129	if (!crtc_state) {130		DRM_ERROR("Invalid crtc_state\n");131		return;132	}133 134	/* Enable VPP Postblend */135	writel(crtc_state->mode.hdisplay,136	       priv->io_base + _REG(VPP_POSTBLEND_H_SIZE));137 138	/* VD1 Preblend vertical start/end */139	writel(FIELD_PREP(GENMASK(11, 0), 2303),140			priv->io_base + _REG(VPP_PREBLEND_VD1_V_START_END));141 142	writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,143			    priv->io_base + _REG(VPP_MISC));144 145	drm_crtc_vblank_on(crtc);146}147 148static void meson_g12a_crtc_atomic_disable(struct drm_crtc *crtc,149					   struct drm_atomic_state *state)150{151	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);152	struct meson_drm *priv = meson_crtc->priv;153 154	DRM_DEBUG_DRIVER("\n");155 156	drm_crtc_vblank_off(crtc);157 158	priv->viu.osd1_enabled = false;159	priv->viu.osd1_commit = false;160 161	priv->viu.vd1_enabled = false;162	priv->viu.vd1_commit = false;163 164	if (crtc->state->event && !crtc->state->active) {165		spin_lock_irq(&crtc->dev->event_lock);166		drm_crtc_send_vblank_event(crtc, crtc->state->event);167		spin_unlock_irq(&crtc->dev->event_lock);168 169		crtc->state->event = NULL;170	}171}172 173static void meson_crtc_atomic_disable(struct drm_crtc *crtc,174				      struct drm_atomic_state *state)175{176	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);177	struct meson_drm *priv = meson_crtc->priv;178 179	DRM_DEBUG_DRIVER("\n");180 181	drm_crtc_vblank_off(crtc);182 183	priv->viu.osd1_enabled = false;184	priv->viu.osd1_commit = false;185 186	priv->viu.vd1_enabled = false;187	priv->viu.vd1_commit = false;188 189	/* Disable VPP Postblend */190	writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_VD1_POSTBLEND |191			    VPP_VD1_PREBLEND | VPP_POSTBLEND_ENABLE, 0,192			    priv->io_base + _REG(VPP_MISC));193 194	if (crtc->state->event && !crtc->state->active) {195		spin_lock_irq(&crtc->dev->event_lock);196		drm_crtc_send_vblank_event(crtc, crtc->state->event);197		spin_unlock_irq(&crtc->dev->event_lock);198 199		crtc->state->event = NULL;200	}201}202 203static void meson_crtc_atomic_begin(struct drm_crtc *crtc,204				    struct drm_atomic_state *state)205{206	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);207	unsigned long flags;208 209	if (crtc->state->event) {210		WARN_ON(drm_crtc_vblank_get(crtc) != 0);211 212		spin_lock_irqsave(&crtc->dev->event_lock, flags);213		meson_crtc->event = crtc->state->event;214		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);215		crtc->state->event = NULL;216	}217}218 219static void meson_crtc_atomic_flush(struct drm_crtc *crtc,220				    struct drm_atomic_state *state)221{222	struct meson_crtc *meson_crtc = to_meson_crtc(crtc);223	struct meson_drm *priv = meson_crtc->priv;224 225	priv->viu.osd1_commit = true;226	priv->viu.vd1_commit = true;227}228 229static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {230	.atomic_begin	= meson_crtc_atomic_begin,231	.atomic_flush	= meson_crtc_atomic_flush,232	.atomic_enable	= meson_crtc_atomic_enable,233	.atomic_disable	= meson_crtc_atomic_disable,234};235 236static const struct drm_crtc_helper_funcs meson_g12a_crtc_helper_funcs = {237	.atomic_begin	= meson_crtc_atomic_begin,238	.atomic_flush	= meson_crtc_atomic_flush,239	.atomic_enable	= meson_g12a_crtc_atomic_enable,240	.atomic_disable	= meson_g12a_crtc_atomic_disable,241};242 243static void meson_crtc_enable_osd1(struct meson_drm *priv)244{245	writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,246			    priv->io_base + _REG(VPP_MISC));247}248 249static void meson_crtc_g12a_enable_osd1_afbc(struct meson_drm *priv)250{251	writel_relaxed(priv->viu.osd1_blk2_cfg4,252		       priv->io_base + _REG(VIU_OSD1_BLK2_CFG_W4));253 254	writel_bits_relaxed(OSD_MEM_LINEAR_ADDR, OSD_MEM_LINEAR_ADDR,255			    priv->io_base + _REG(VIU_OSD1_CTRL_STAT));256 257	writel_relaxed(priv->viu.osd1_blk1_cfg4,258		       priv->io_base + _REG(VIU_OSD1_BLK1_CFG_W4));259 260	meson_viu_g12a_enable_osd1_afbc(priv);261 262	writel_bits_relaxed(OSD_MEM_LINEAR_ADDR, OSD_MEM_LINEAR_ADDR,263			    priv->io_base + _REG(VIU_OSD1_CTRL_STAT));264 265	writel_bits_relaxed(OSD_MALI_SRC_EN, OSD_MALI_SRC_EN,266			    priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W0));267}268 269static void meson_g12a_crtc_enable_osd1(struct meson_drm *priv)270{271	writel_relaxed(priv->viu.osd_blend_din0_scope_h,272		       priv->io_base +273		       _REG(VIU_OSD_BLEND_DIN0_SCOPE_H));274	writel_relaxed(priv->viu.osd_blend_din0_scope_v,275		       priv->io_base +276		       _REG(VIU_OSD_BLEND_DIN0_SCOPE_V));277	writel_relaxed(priv->viu.osb_blend0_size,278		       priv->io_base +279		       _REG(VIU_OSD_BLEND_BLEND0_SIZE));280	writel_relaxed(priv->viu.osb_blend1_size,281		       priv->io_base +282		       _REG(VIU_OSD_BLEND_BLEND1_SIZE));283	writel_bits_relaxed(3 << 8, 3 << 8,284			    priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));285}286 287static void meson_crtc_enable_vd1(struct meson_drm *priv)288{289	writel_bits_relaxed(VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND |290			    VPP_COLOR_MNG_ENABLE,291			    VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND |292			    VPP_COLOR_MNG_ENABLE,293			    priv->io_base + _REG(VPP_MISC));294 295	writel_bits_relaxed(VIU_CTRL0_AFBC_TO_VD1,296			    priv->viu.vd1_afbc ? VIU_CTRL0_AFBC_TO_VD1 : 0,297			    priv->io_base + _REG(VIU_MISC_CTRL0));298}299 300static void meson_g12a_crtc_enable_vd1(struct meson_drm *priv)301{302	writel_relaxed(VD_BLEND_PREBLD_SRC_VD1 |303		       VD_BLEND_PREBLD_PREMULT_EN |304		       VD_BLEND_POSTBLD_SRC_VD1 |305		       VD_BLEND_POSTBLD_PREMULT_EN,306		       priv->io_base + _REG(VD1_BLEND_SRC_CTRL));307 308	writel_relaxed(priv->viu.vd1_afbc ?309		       (VD1_AXI_SEL_AFBC | AFBC_VD1_SEL) : 0,310		       priv->io_base + _REG(VD1_AFBCD0_MISC_CTRL));311}312 313void meson_crtc_irq(struct meson_drm *priv)314{315	struct meson_crtc *meson_crtc = to_meson_crtc(priv->crtc);316	unsigned long flags;317 318	/* Update the OSD registers */319	if (priv->viu.osd1_enabled && priv->viu.osd1_commit) {320		writel_relaxed(priv->viu.osd1_ctrl_stat,321				priv->io_base + _REG(VIU_OSD1_CTRL_STAT));322		writel_relaxed(priv->viu.osd1_ctrl_stat2,323				priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));324		writel_relaxed(priv->viu.osd1_blk0_cfg[0],325				priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W0));326		writel_relaxed(priv->viu.osd1_blk0_cfg[1],327				priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W1));328		writel_relaxed(priv->viu.osd1_blk0_cfg[2],329				priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W2));330		writel_relaxed(priv->viu.osd1_blk0_cfg[3],331				priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3));332		writel_relaxed(priv->viu.osd1_blk0_cfg[4],333				priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4));334 335		if (priv->viu.osd1_afbcd) {336			if (meson_crtc->enable_osd1_afbc)337				meson_crtc->enable_osd1_afbc(priv);338		} else {339			if (meson_crtc->disable_osd1_afbc)340				meson_crtc->disable_osd1_afbc(priv);341			if (priv->afbcd.ops) {342				priv->afbcd.ops->reset(priv);343				priv->afbcd.ops->disable(priv);344			}345			meson_crtc->vsync_forced = false;346		}347 348		writel_relaxed(priv->viu.osd_sc_ctrl0,349				priv->io_base + _REG(VPP_OSD_SC_CTRL0));350		writel_relaxed(priv->viu.osd_sc_i_wh_m1,351				priv->io_base + _REG(VPP_OSD_SCI_WH_M1));352		writel_relaxed(priv->viu.osd_sc_o_h_start_end,353				priv->io_base + _REG(VPP_OSD_SCO_H_START_END));354		writel_relaxed(priv->viu.osd_sc_o_v_start_end,355				priv->io_base + _REG(VPP_OSD_SCO_V_START_END));356		writel_relaxed(priv->viu.osd_sc_v_ini_phase,357				priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));358		writel_relaxed(priv->viu.osd_sc_v_phase_step,359				priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));360		writel_relaxed(priv->viu.osd_sc_h_ini_phase,361				priv->io_base + _REG(VPP_OSD_HSC_INI_PHASE));362		writel_relaxed(priv->viu.osd_sc_h_phase_step,363				priv->io_base + _REG(VPP_OSD_HSC_PHASE_STEP));364		writel_relaxed(priv->viu.osd_sc_h_ctrl0,365				priv->io_base + _REG(VPP_OSD_HSC_CTRL0));366		writel_relaxed(priv->viu.osd_sc_v_ctrl0,367				priv->io_base + _REG(VPP_OSD_VSC_CTRL0));368 369		if (!priv->viu.osd1_afbcd)370			meson_canvas_config(priv->canvas, priv->canvas_id_osd1,371					    priv->viu.osd1_addr,372					    priv->viu.osd1_stride,373					    priv->viu.osd1_height,374					    MESON_CANVAS_WRAP_NONE,375					    MESON_CANVAS_BLKMODE_LINEAR, 0);376 377		/* Enable OSD1 */378		if (meson_crtc->enable_osd1)379			meson_crtc->enable_osd1(priv);380 381		if (priv->viu.osd1_afbcd) {382			priv->afbcd.ops->reset(priv);383			priv->afbcd.ops->setup(priv);384			priv->afbcd.ops->enable(priv);385			meson_crtc->vsync_forced = true;386		}387 388		priv->viu.osd1_commit = false;389	}390 391	/* Update the VD1 registers */392	if (priv->viu.vd1_enabled && priv->viu.vd1_commit) {393 394		if (priv->viu.vd1_afbc) {395			writel_relaxed(priv->viu.vd1_afbc_head_addr,396				       priv->io_base +397				       _REG(AFBC_HEAD_BADDR));398			writel_relaxed(priv->viu.vd1_afbc_body_addr,399				       priv->io_base +400				       _REG(AFBC_BODY_BADDR));401			writel_relaxed(priv->viu.vd1_afbc_en,402				       priv->io_base +403				       _REG(AFBC_ENABLE));404			writel_relaxed(priv->viu.vd1_afbc_mode,405				       priv->io_base +406				       _REG(AFBC_MODE));407			writel_relaxed(priv->viu.vd1_afbc_size_in,408				       priv->io_base +409				       _REG(AFBC_SIZE_IN));410			writel_relaxed(priv->viu.vd1_afbc_dec_def_color,411				       priv->io_base +412				       _REG(AFBC_DEC_DEF_COLOR));413			writel_relaxed(priv->viu.vd1_afbc_conv_ctrl,414				       priv->io_base +415				       _REG(AFBC_CONV_CTRL));416			writel_relaxed(priv->viu.vd1_afbc_size_out,417				       priv->io_base +418				       _REG(AFBC_SIZE_OUT));419			writel_relaxed(priv->viu.vd1_afbc_vd_cfmt_ctrl,420				       priv->io_base +421				       _REG(AFBC_VD_CFMT_CTRL));422			writel_relaxed(priv->viu.vd1_afbc_vd_cfmt_w,423				       priv->io_base +424				       _REG(AFBC_VD_CFMT_W));425			writel_relaxed(priv->viu.vd1_afbc_mif_hor_scope,426				       priv->io_base +427				       _REG(AFBC_MIF_HOR_SCOPE));428			writel_relaxed(priv->viu.vd1_afbc_mif_ver_scope,429				       priv->io_base +430				       _REG(AFBC_MIF_VER_SCOPE));431			writel_relaxed(priv->viu.vd1_afbc_pixel_hor_scope,432				       priv->io_base+433				       _REG(AFBC_PIXEL_HOR_SCOPE));434			writel_relaxed(priv->viu.vd1_afbc_pixel_ver_scope,435				       priv->io_base +436				       _REG(AFBC_PIXEL_VER_SCOPE));437			writel_relaxed(priv->viu.vd1_afbc_vd_cfmt_h,438				       priv->io_base +439				       _REG(AFBC_VD_CFMT_H));440		} else {441			switch (priv->viu.vd1_planes) {442			case 3:443				meson_canvas_config(priv->canvas,444						    priv->canvas_id_vd1_2,445						    priv->viu.vd1_addr2,446						    priv->viu.vd1_stride2,447						    priv->viu.vd1_height2,448						    MESON_CANVAS_WRAP_NONE,449						    MESON_CANVAS_BLKMODE_LINEAR,450						    MESON_CANVAS_ENDIAN_SWAP64);451				fallthrough;452			case 2:453				meson_canvas_config(priv->canvas,454						    priv->canvas_id_vd1_1,455						    priv->viu.vd1_addr1,456						    priv->viu.vd1_stride1,457						    priv->viu.vd1_height1,458						    MESON_CANVAS_WRAP_NONE,459						    MESON_CANVAS_BLKMODE_LINEAR,460						    MESON_CANVAS_ENDIAN_SWAP64);461				fallthrough;462			case 1:463				meson_canvas_config(priv->canvas,464						    priv->canvas_id_vd1_0,465						    priv->viu.vd1_addr0,466						    priv->viu.vd1_stride0,467						    priv->viu.vd1_height0,468						    MESON_CANVAS_WRAP_NONE,469						    MESON_CANVAS_BLKMODE_LINEAR,470						    MESON_CANVAS_ENDIAN_SWAP64);471			}472 473			writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE));474		}475 476		writel_relaxed(priv->viu.vd1_if0_gen_reg,477				priv->io_base + meson_crtc->viu_offset +478				_REG(VD1_IF0_GEN_REG));479		writel_relaxed(priv->viu.vd1_if0_gen_reg,480				priv->io_base + meson_crtc->viu_offset +481				_REG(VD2_IF0_GEN_REG));482		writel_relaxed(priv->viu.vd1_if0_gen_reg2,483				priv->io_base + meson_crtc->viu_offset +484				_REG(VD1_IF0_GEN_REG2));485		writel_relaxed(priv->viu.viu_vd1_fmt_ctrl,486				priv->io_base + meson_crtc->viu_offset +487				_REG(VIU_VD1_FMT_CTRL));488		writel_relaxed(priv->viu.viu_vd1_fmt_ctrl,489				priv->io_base + meson_crtc->viu_offset +490				_REG(VIU_VD2_FMT_CTRL));491		writel_relaxed(priv->viu.viu_vd1_fmt_w,492				priv->io_base + meson_crtc->viu_offset +493				_REG(VIU_VD1_FMT_W));494		writel_relaxed(priv->viu.viu_vd1_fmt_w,495				priv->io_base + meson_crtc->viu_offset +496				_REG(VIU_VD2_FMT_W));497		writel_relaxed(priv->viu.vd1_if0_canvas0,498				priv->io_base + meson_crtc->viu_offset +499				_REG(VD1_IF0_CANVAS0));500		writel_relaxed(priv->viu.vd1_if0_canvas0,501				priv->io_base + meson_crtc->viu_offset +502				_REG(VD1_IF0_CANVAS1));503		writel_relaxed(priv->viu.vd1_if0_canvas0,504				priv->io_base + meson_crtc->viu_offset +505				_REG(VD2_IF0_CANVAS0));506		writel_relaxed(priv->viu.vd1_if0_canvas0,507				priv->io_base + meson_crtc->viu_offset +508				_REG(VD2_IF0_CANVAS1));509		writel_relaxed(priv->viu.vd1_if0_luma_x0,510				priv->io_base + meson_crtc->viu_offset +511				_REG(VD1_IF0_LUMA_X0));512		writel_relaxed(priv->viu.vd1_if0_luma_x0,513				priv->io_base + meson_crtc->viu_offset +514				_REG(VD1_IF0_LUMA_X1));515		writel_relaxed(priv->viu.vd1_if0_luma_x0,516				priv->io_base + meson_crtc->viu_offset +517				_REG(VD2_IF0_LUMA_X0));518		writel_relaxed(priv->viu.vd1_if0_luma_x0,519				priv->io_base + meson_crtc->viu_offset +520				_REG(VD2_IF0_LUMA_X1));521		writel_relaxed(priv->viu.vd1_if0_luma_y0,522				priv->io_base + meson_crtc->viu_offset +523				_REG(VD1_IF0_LUMA_Y0));524		writel_relaxed(priv->viu.vd1_if0_luma_y0,525				priv->io_base + meson_crtc->viu_offset +526				_REG(VD1_IF0_LUMA_Y1));527		writel_relaxed(priv->viu.vd1_if0_luma_y0,528				priv->io_base + meson_crtc->viu_offset +529				_REG(VD2_IF0_LUMA_Y0));530		writel_relaxed(priv->viu.vd1_if0_luma_y0,531				priv->io_base + meson_crtc->viu_offset +532				_REG(VD2_IF0_LUMA_Y1));533		writel_relaxed(priv->viu.vd1_if0_chroma_x0,534				priv->io_base + meson_crtc->viu_offset +535				_REG(VD1_IF0_CHROMA_X0));536		writel_relaxed(priv->viu.vd1_if0_chroma_x0,537				priv->io_base + meson_crtc->viu_offset +538				_REG(VD1_IF0_CHROMA_X1));539		writel_relaxed(priv->viu.vd1_if0_chroma_x0,540				priv->io_base + meson_crtc->viu_offset +541				_REG(VD2_IF0_CHROMA_X0));542		writel_relaxed(priv->viu.vd1_if0_chroma_x0,543				priv->io_base + meson_crtc->viu_offset +544				_REG(VD2_IF0_CHROMA_X1));545		writel_relaxed(priv->viu.vd1_if0_chroma_y0,546				priv->io_base + meson_crtc->viu_offset +547				_REG(VD1_IF0_CHROMA_Y0));548		writel_relaxed(priv->viu.vd1_if0_chroma_y0,549				priv->io_base + meson_crtc->viu_offset +550				_REG(VD1_IF0_CHROMA_Y1));551		writel_relaxed(priv->viu.vd1_if0_chroma_y0,552				priv->io_base + meson_crtc->viu_offset +553				_REG(VD2_IF0_CHROMA_Y0));554		writel_relaxed(priv->viu.vd1_if0_chroma_y0,555				priv->io_base + meson_crtc->viu_offset +556				_REG(VD2_IF0_CHROMA_Y1));557		writel_relaxed(priv->viu.vd1_if0_repeat_loop,558				priv->io_base + meson_crtc->viu_offset +559				_REG(VD1_IF0_RPT_LOOP));560		writel_relaxed(priv->viu.vd1_if0_repeat_loop,561				priv->io_base + meson_crtc->viu_offset +562				_REG(VD2_IF0_RPT_LOOP));563		writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,564				priv->io_base + meson_crtc->viu_offset +565				_REG(VD1_IF0_LUMA0_RPT_PAT));566		writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,567				priv->io_base + meson_crtc->viu_offset +568				_REG(VD2_IF0_LUMA0_RPT_PAT));569		writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,570				priv->io_base + meson_crtc->viu_offset +571				_REG(VD1_IF0_LUMA1_RPT_PAT));572		writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,573				priv->io_base + meson_crtc->viu_offset +574				_REG(VD2_IF0_LUMA1_RPT_PAT));575		writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,576				priv->io_base + meson_crtc->viu_offset +577				_REG(VD1_IF0_CHROMA0_RPT_PAT));578		writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,579				priv->io_base + meson_crtc->viu_offset +580				_REG(VD2_IF0_CHROMA0_RPT_PAT));581		writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,582				priv->io_base + meson_crtc->viu_offset +583				_REG(VD1_IF0_CHROMA1_RPT_PAT));584		writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,585				priv->io_base + meson_crtc->viu_offset +586				_REG(VD2_IF0_CHROMA1_RPT_PAT));587		writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +588				_REG(VD1_IF0_LUMA_PSEL));589		writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +590				_REG(VD1_IF0_CHROMA_PSEL));591		writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +592				_REG(VD2_IF0_LUMA_PSEL));593		writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +594				_REG(VD2_IF0_CHROMA_PSEL));595		writel_relaxed(priv->viu.vd1_range_map_y,596				priv->io_base + meson_crtc->viu_offset +597				_REG(VD1_IF0_RANGE_MAP_Y));598		writel_relaxed(priv->viu.vd1_range_map_cb,599				priv->io_base + meson_crtc->viu_offset +600				_REG(VD1_IF0_RANGE_MAP_CB));601		writel_relaxed(priv->viu.vd1_range_map_cr,602				priv->io_base + meson_crtc->viu_offset +603				_REG(VD1_IF0_RANGE_MAP_CR));604		writel_relaxed(VPP_VSC_BANK_LENGTH(4) |605			       VPP_HSC_BANK_LENGTH(4) |606			       VPP_SC_VD_EN_ENABLE |607			       VPP_SC_TOP_EN_ENABLE |608			       VPP_SC_HSC_EN_ENABLE |609			       VPP_SC_VSC_EN_ENABLE,610				priv->io_base + _REG(VPP_SC_MISC));611		writel_relaxed(priv->viu.vpp_pic_in_height,612				priv->io_base + _REG(VPP_PIC_IN_HEIGHT));613		writel_relaxed(priv->viu.vpp_postblend_vd1_h_start_end,614			priv->io_base + _REG(VPP_POSTBLEND_VD1_H_START_END));615		writel_relaxed(priv->viu.vpp_blend_vd2_h_start_end,616			priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));617		writel_relaxed(priv->viu.vpp_postblend_vd1_v_start_end,618			priv->io_base + _REG(VPP_POSTBLEND_VD1_V_START_END));619		writel_relaxed(priv->viu.vpp_blend_vd2_v_start_end,620			priv->io_base + _REG(VPP_BLEND_VD2_V_START_END));621		writel_relaxed(priv->viu.vpp_hsc_region12_startp,622				priv->io_base + _REG(VPP_HSC_REGION12_STARTP));623		writel_relaxed(priv->viu.vpp_hsc_region34_startp,624				priv->io_base + _REG(VPP_HSC_REGION34_STARTP));625		writel_relaxed(priv->viu.vpp_hsc_region4_endp,626				priv->io_base + _REG(VPP_HSC_REGION4_ENDP));627		writel_relaxed(priv->viu.vpp_hsc_start_phase_step,628				priv->io_base + _REG(VPP_HSC_START_PHASE_STEP));629		writel_relaxed(priv->viu.vpp_hsc_region1_phase_slope,630			priv->io_base + _REG(VPP_HSC_REGION1_PHASE_SLOPE));631		writel_relaxed(priv->viu.vpp_hsc_region3_phase_slope,632			priv->io_base + _REG(VPP_HSC_REGION3_PHASE_SLOPE));633		writel_relaxed(priv->viu.vpp_line_in_length,634				priv->io_base + _REG(VPP_LINE_IN_LENGTH));635		writel_relaxed(priv->viu.vpp_preblend_h_size,636				priv->io_base + _REG(VPP_PREBLEND_H_SIZE));637		writel_relaxed(priv->viu.vpp_vsc_region12_startp,638				priv->io_base + _REG(VPP_VSC_REGION12_STARTP));639		writel_relaxed(priv->viu.vpp_vsc_region34_startp,640				priv->io_base + _REG(VPP_VSC_REGION34_STARTP));641		writel_relaxed(priv->viu.vpp_vsc_region4_endp,642				priv->io_base + _REG(VPP_VSC_REGION4_ENDP));643		writel_relaxed(priv->viu.vpp_vsc_start_phase_step,644				priv->io_base + _REG(VPP_VSC_START_PHASE_STEP));645		writel_relaxed(priv->viu.vpp_vsc_ini_phase,646				priv->io_base + _REG(VPP_VSC_INI_PHASE));647		writel_relaxed(priv->viu.vpp_vsc_phase_ctrl,648				priv->io_base + _REG(VPP_VSC_PHASE_CTRL));649		writel_relaxed(priv->viu.vpp_hsc_phase_ctrl,650				priv->io_base + _REG(VPP_HSC_PHASE_CTRL));651		writel_relaxed(0x42, priv->io_base + _REG(VPP_SCALE_COEF_IDX));652 653		/* Enable VD1 */654		if (meson_crtc->enable_vd1)655			meson_crtc->enable_vd1(priv);656 657		priv->viu.vd1_commit = false;658	}659 660	if (meson_crtc->vsync_disabled)661		return;662 663	drm_crtc_handle_vblank(priv->crtc);664 665	spin_lock_irqsave(&priv->drm->event_lock, flags);666	if (meson_crtc->event) {667		drm_crtc_send_vblank_event(priv->crtc, meson_crtc->event);668		drm_crtc_vblank_put(priv->crtc);669		meson_crtc->event = NULL;670	}671	spin_unlock_irqrestore(&priv->drm->event_lock, flags);672}673 674int meson_crtc_create(struct meson_drm *priv)675{676	struct meson_crtc *meson_crtc;677	struct drm_crtc *crtc;678	int ret;679 680	meson_crtc = devm_kzalloc(priv->drm->dev, sizeof(*meson_crtc),681				  GFP_KERNEL);682	if (!meson_crtc)683		return -ENOMEM;684 685	meson_crtc->priv = priv;686	crtc = &meson_crtc->base;687	ret = drm_crtc_init_with_planes(priv->drm, crtc,688					priv->primary_plane, NULL,689					&meson_crtc_funcs, "meson_crtc");690	if (ret) {691		dev_err(priv->drm->dev, "Failed to init CRTC\n");692		return ret;693	}694 695	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {696		meson_crtc->enable_osd1 = meson_g12a_crtc_enable_osd1;697		meson_crtc->enable_vd1 = meson_g12a_crtc_enable_vd1;698		meson_crtc->viu_offset = MESON_G12A_VIU_OFFSET;699		meson_crtc->enable_osd1_afbc =700					meson_crtc_g12a_enable_osd1_afbc;701		meson_crtc->disable_osd1_afbc =702					meson_viu_g12a_disable_osd1_afbc;703		drm_crtc_helper_add(crtc, &meson_g12a_crtc_helper_funcs);704	} else {705		meson_crtc->enable_osd1 = meson_crtc_enable_osd1;706		meson_crtc->enable_vd1 = meson_crtc_enable_vd1;707		if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) {708			meson_crtc->enable_osd1_afbc =709					meson_viu_gxm_enable_osd1_afbc;710			meson_crtc->disable_osd1_afbc =711					meson_viu_gxm_disable_osd1_afbc;712		}713		drm_crtc_helper_add(crtc, &meson_crtc_helper_funcs);714	}715 716	priv->crtc = crtc;717 718	return 0;719}720