// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2016 BayLibre, SAS
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 * Copyright (C) 2014 Endless Mobile
 *
 * Written by:
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 */

#include <linux/bitfield.h>

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_device.h>
#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>

#include "meson_plane.h"
#include "meson_registers.h"
#include "meson_viu.h"
#include "meson_osd_afbcd.h"

/* OSD_SCI_WH_M1 */
#define SCI_WH_M1_W(w)			FIELD_PREP(GENMASK(28, 16), w)
#define SCI_WH_M1_H(h)			FIELD_PREP(GENMASK(12, 0), h)

/* OSD_SCO_H_START_END */
/* OSD_SCO_V_START_END */
#define SCO_HV_START(start)		FIELD_PREP(GENMASK(27, 16), start)
#define SCO_HV_END(end)			FIELD_PREP(GENMASK(11, 0), end)

/* OSD_SC_CTRL0 */
#define SC_CTRL0_PATH_EN		BIT(3)
#define SC_CTRL0_SEL_OSD1		BIT(2)

/* OSD_VSC_CTRL0 */
#define VSC_BANK_LEN(value)		FIELD_PREP(GENMASK(2, 0), value)
#define VSC_TOP_INI_RCV_NUM(value)	FIELD_PREP(GENMASK(6, 3), value)
#define VSC_TOP_RPT_L0_NUM(value)	FIELD_PREP(GENMASK(9, 8), value)
#define VSC_BOT_INI_RCV_NUM(value)	FIELD_PREP(GENMASK(14, 11), value)
#define VSC_BOT_RPT_L0_NUM(value)	FIELD_PREP(GENMASK(17, 16), value)
#define VSC_PROG_INTERLACE		BIT(23)
#define VSC_VERTICAL_SCALER_EN		BIT(24)

/* OSD_VSC_INI_PHASE */
#define VSC_INI_PHASE_BOT(bottom)	FIELD_PREP(GENMASK(31, 16), bottom)
#define VSC_INI_PHASE_TOP(top)		FIELD_PREP(GENMASK(15, 0), top)

/* OSD_HSC_CTRL0 */
#define HSC_BANK_LENGTH(value)		FIELD_PREP(GENMASK(2, 0), value)
#define HSC_INI_RCV_NUM0(value)		FIELD_PREP(GENMASK(6, 3), value)
#define HSC_RPT_P0_NUM0(value)		FIELD_PREP(GENMASK(9, 8), value)
#define HSC_HORIZ_SCALER_EN		BIT(22)

/* VPP_OSD_VSC_PHASE_STEP */
/* VPP_OSD_HSC_PHASE_STEP */
#define SC_PHASE_STEP(value)		FIELD_PREP(GENMASK(27, 0), value)

struct meson_plane {
	struct drm_plane base;
	struct meson_drm *priv;
	bool enabled;
};
#define to_meson_plane(x) container_of(x, struct meson_plane, base)

#define FRAC_16_16(mult, div)    (((mult) << 16) / (div))

static int meson_plane_atomic_check(struct drm_plane *plane,
				    struct drm_atomic_state *state)
{
	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
										 plane);
	struct drm_crtc_state *crtc_state;

	if (!new_plane_state->crtc)
		return 0;

	crtc_state = drm_atomic_get_crtc_state(state,
					       new_plane_state->crtc);
	if (IS_ERR(crtc_state))
		return PTR_ERR(crtc_state);

	/*
	 * Only allow :
	 * - Upscaling up to 5x, vertical and horizontal
	 * - Final coordinates must match crtc size
	 */
	return drm_atomic_helper_check_plane_state(new_plane_state,
						   crtc_state,
						   FRAC_16_16(1, 5),
						   DRM_PLANE_NO_SCALING,
						   false, true);
}

#define MESON_MOD_AFBC_VALID_BITS (AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |	\
				   AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |	\
				   AFBC_FORMAT_MOD_YTR |		\
				   AFBC_FORMAT_MOD_SPARSE |		\
				   AFBC_FORMAT_MOD_SPLIT)

/* Takes a fixed 16.16 number and converts it to integer. */
static inline int64_t fixed16_to_int(int64_t value)
{
	return value >> 16;
}

static u32 meson_g12a_afbcd_line_stride(struct meson_drm *priv)
{
	u32 line_stride = 0;

	switch (priv->afbcd.format) {
	case DRM_FORMAT_RGB565:
		line_stride = ((priv->viu.osd1_width << 4) + 127) >> 7;
		break;
	case DRM_FORMAT_RGB888:
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_ABGR8888:
		line_stride = ((priv->viu.osd1_width << 5) + 127) >> 7;
		break;
	}

	return ((line_stride + 1) >> 1) << 1;
}

static void meson_plane_atomic_update(struct drm_plane *plane,
				      struct drm_atomic_state *state)
{
	struct meson_plane *meson_plane = to_meson_plane(plane);
	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
									   plane);
	struct drm_rect dest = drm_plane_state_dest(new_state);
	struct meson_drm *priv = meson_plane->priv;
	struct drm_framebuffer *fb = new_state->fb;
	struct drm_gem_dma_object *gem;
	unsigned long flags;
	int vsc_ini_rcv_num, vsc_ini_rpt_p0_num;
	int vsc_bot_rcv_num, vsc_bot_rpt_p0_num;
	int hsc_ini_rcv_num, hsc_ini_rpt_p0_num;
	int hf_phase_step, vf_phase_step;
	int src_w, src_h, dst_w, dst_h;
	int bot_ini_phase;
	int hf_bank_len;
	int vf_bank_len;
	u8 canvas_id_osd1;

	/*
	 * Update Coordinates
	 * Update Formats
	 * Update Buffer
	 * Enable Plane
	 */
	spin_lock_irqsave(&priv->drm->event_lock, flags);

	/* Check if AFBC decoder is required for this buffer */
	if ((meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
	     meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) &&
	    fb->modifier & DRM_FORMAT_MOD_ARM_AFBC(MESON_MOD_AFBC_VALID_BITS))
		priv->viu.osd1_afbcd = true;
	else
		priv->viu.osd1_afbcd = false;

	/* Enable OSD and BLK0, set max global alpha */
	priv->viu.osd1_ctrl_stat = OSD_ENABLE |
				   (0x100 << OSD_GLOBAL_ALPHA_SHIFT) |
				   OSD_BLK0_ENABLE;

	priv->viu.osd1_ctrl_stat2 = readl(priv->io_base +
					  _REG(VIU_OSD1_CTRL_STAT2));

	canvas_id_osd1 = priv->canvas_id_osd1;

	/* Set up BLK0 to point to the right canvas */
	priv->viu.osd1_blk0_cfg[0] = canvas_id_osd1 << OSD_CANVAS_SEL;

	if (priv->viu.osd1_afbcd) {
		if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
			/* This is the internal decoding memory address */
			priv->viu.osd1_blk1_cfg4 = MESON_G12A_AFBCD_OUT_ADDR;
			priv->viu.osd1_blk0_cfg[0] |= OSD_ENDIANNESS_BE;
			priv->viu.osd1_ctrl_stat2 |= OSD_PENDING_STAT_CLEAN;
			priv->viu.osd1_ctrl_stat |= VIU_OSD1_CFG_SYN_EN;
		}

		if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) {
			priv->viu.osd1_blk0_cfg[0] |= OSD_ENDIANNESS_LE;
			priv->viu.osd1_ctrl_stat2 |= OSD_DPATH_MALI_AFBCD;
		}
	} else {
		priv->viu.osd1_blk0_cfg[0] |= OSD_ENDIANNESS_LE;

		if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM))
			priv->viu.osd1_ctrl_stat2 &= ~OSD_DPATH_MALI_AFBCD;
	}

	/* On GXBB, Use the old non-HDR RGB2YUV converter */
	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
		priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB;

	if (priv->viu.osd1_afbcd &&
	    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
		priv->viu.osd1_blk0_cfg[0] |= OSD_MALI_SRC_EN |
			priv->afbcd.ops->fmt_to_blk_mode(fb->modifier,
							  fb->format->format);
	} else {
		switch (fb->format->format) {
		case DRM_FORMAT_XRGB8888:
		case DRM_FORMAT_ARGB8888:
			priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
						OSD_COLOR_MATRIX_32_ARGB;
			break;
		case DRM_FORMAT_XBGR8888:
		case DRM_FORMAT_ABGR8888:
			priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
						OSD_COLOR_MATRIX_32_ABGR;
			break;
		case DRM_FORMAT_RGB888:
			priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_24 |
						OSD_COLOR_MATRIX_24_RGB;
			break;
		case DRM_FORMAT_RGB565:
			priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_16 |
						OSD_COLOR_MATRIX_16_RGB565;
			break;
		}
	}

	switch (fb->format->format) {
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_XBGR8888:
		/* For XRGB, replace the pixel's alpha by 0xFF */
		priv->viu.osd1_ctrl_stat2 |= OSD_REPLACE_EN;
		break;
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_ABGR8888:
		/* For ARGB, use the pixel's alpha */
		priv->viu.osd1_ctrl_stat2 &= ~OSD_REPLACE_EN;
		break;
	}

	/* Default scaler parameters */
	vsc_bot_rcv_num = 0;
	vsc_bot_rpt_p0_num = 0;
	hf_bank_len = 4;
	vf_bank_len = 4;

	if (new_state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
		vsc_bot_rcv_num = 6;
		vsc_bot_rpt_p0_num = 2;
	}

	hsc_ini_rcv_num = hf_bank_len;
	vsc_ini_rcv_num = vf_bank_len;
	hsc_ini_rpt_p0_num = (hf_bank_len / 2) - 1;
	vsc_ini_rpt_p0_num = (vf_bank_len / 2) - 1;

	src_w = fixed16_to_int(new_state->src_w);
	src_h = fixed16_to_int(new_state->src_h);
	dst_w = new_state->crtc_w;
	dst_h = new_state->crtc_h;

	/*
	 * When the output is interlaced, the OSD must switch between
	 * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
	 * at each vsync.
	 * But the vertical scaler can provide such funtionnality if
	 * is configured for 2:1 scaling with interlace options enabled.
	 */
	if (new_state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
		dest.y1 /= 2;
		dest.y2 /= 2;
		dst_h /= 2;
	}

	hf_phase_step = ((src_w << 18) / dst_w) << 6;
	vf_phase_step = (src_h << 20) / dst_h;

	if (new_state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
		bot_ini_phase = ((vf_phase_step / 2) >> 4);
	else
		bot_ini_phase = 0;

	vf_phase_step = (vf_phase_step << 4);

	/* In interlaced mode, scaler is always active */
	if (src_h != dst_h || src_w != dst_w) {
		priv->viu.osd_sc_i_wh_m1 = SCI_WH_M1_W(src_w - 1) |
					   SCI_WH_M1_H(src_h - 1);
		priv->viu.osd_sc_o_h_start_end = SCO_HV_START(dest.x1) |
						 SCO_HV_END(dest.x2 - 1);
		priv->viu.osd_sc_o_v_start_end = SCO_HV_START(dest.y1) |
						 SCO_HV_END(dest.y2 - 1);
		/* Enable OSD Scaler */
		priv->viu.osd_sc_ctrl0 = SC_CTRL0_PATH_EN | SC_CTRL0_SEL_OSD1;
	} else {
		priv->viu.osd_sc_i_wh_m1 = 0;
		priv->viu.osd_sc_o_h_start_end = 0;
		priv->viu.osd_sc_o_v_start_end = 0;
		priv->viu.osd_sc_ctrl0 = 0;
	}

	/* In interlaced mode, vertical scaler is always active */
	if (src_h != dst_h) {
		priv->viu.osd_sc_v_ctrl0 =
					VSC_BANK_LEN(vf_bank_len) |
					VSC_TOP_INI_RCV_NUM(vsc_ini_rcv_num) |
					VSC_TOP_RPT_L0_NUM(vsc_ini_rpt_p0_num) |
					VSC_VERTICAL_SCALER_EN;

		if (new_state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
			priv->viu.osd_sc_v_ctrl0 |=
					VSC_BOT_INI_RCV_NUM(vsc_bot_rcv_num) |
					VSC_BOT_RPT_L0_NUM(vsc_bot_rpt_p0_num) |
					VSC_PROG_INTERLACE;

		priv->viu.osd_sc_v_phase_step = SC_PHASE_STEP(vf_phase_step);
		priv->viu.osd_sc_v_ini_phase = VSC_INI_PHASE_BOT(bot_ini_phase);
	} else {
		priv->viu.osd_sc_v_ctrl0 = 0;
		priv->viu.osd_sc_v_phase_step = 0;
		priv->viu.osd_sc_v_ini_phase = 0;
	}

	/* Horizontal scaler is only used if width does not match */
	if (src_w != dst_w) {
		priv->viu.osd_sc_h_ctrl0 =
					HSC_BANK_LENGTH(hf_bank_len) |
					HSC_INI_RCV_NUM0(hsc_ini_rcv_num) |
					HSC_RPT_P0_NUM0(hsc_ini_rpt_p0_num) |
					HSC_HORIZ_SCALER_EN;
		priv->viu.osd_sc_h_phase_step = SC_PHASE_STEP(hf_phase_step);
		priv->viu.osd_sc_h_ini_phase = 0;
	} else {
		priv->viu.osd_sc_h_ctrl0 = 0;
		priv->viu.osd_sc_h_phase_step = 0;
		priv->viu.osd_sc_h_ini_phase = 0;
	}

	/*
	 * The format of these registers is (x2 << 16 | x1),
	 * where x2 is exclusive.
	 * e.g. +30x1920 would be (1919 << 16) | 30
	 */
	priv->viu.osd1_blk0_cfg[1] =
				((fixed16_to_int(new_state->src.x2) - 1) << 16) |
				fixed16_to_int(new_state->src.x1);
	priv->viu.osd1_blk0_cfg[2] =
				((fixed16_to_int(new_state->src.y2) - 1) << 16) |
				fixed16_to_int(new_state->src.y1);
	priv->viu.osd1_blk0_cfg[3] = ((dest.x2 - 1) << 16) | dest.x1;
	priv->viu.osd1_blk0_cfg[4] = ((dest.y2 - 1) << 16) | dest.y1;

	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
		priv->viu.osd_blend_din0_scope_h = ((dest.x2 - 1) << 16) | dest.x1;
		priv->viu.osd_blend_din0_scope_v = ((dest.y2 - 1) << 16) | dest.y1;
		priv->viu.osb_blend0_size = dst_h << 16 | dst_w;
		priv->viu.osb_blend1_size = dst_h << 16 | dst_w;
	}

	/* Update Canvas with buffer address */
	gem = drm_fb_dma_get_gem_obj(fb, 0);

	priv->viu.osd1_addr = gem->dma_addr;
	priv->viu.osd1_stride = fb->pitches[0];
	priv->viu.osd1_height = fb->height;
	priv->viu.osd1_width = fb->width;

	if (priv->viu.osd1_afbcd) {
		priv->afbcd.modifier = fb->modifier;
		priv->afbcd.format = fb->format->format;

		/* Calculate decoder write stride */
		if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
			priv->viu.osd1_blk2_cfg4 =
				meson_g12a_afbcd_line_stride(priv);
	}

	if (!meson_plane->enabled) {
		/* Reset OSD1 before enabling it on GXL+ SoCs */
		if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
		    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
			meson_viu_osd1_reset(priv);

		meson_plane->enabled = true;
	}

	priv->viu.osd1_enabled = true;

	spin_unlock_irqrestore(&priv->drm->event_lock, flags);
}

static void meson_plane_atomic_disable(struct drm_plane *plane,
				       struct drm_atomic_state *state)
{
	struct meson_plane *meson_plane = to_meson_plane(plane);
	struct meson_drm *priv = meson_plane->priv;

	if (priv->afbcd.ops) {
		priv->afbcd.ops->reset(priv);
		priv->afbcd.ops->disable(priv);
	}

	/* Disable OSD1 */
	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
		writel_bits_relaxed(VIU_OSD1_POSTBLD_SRC_OSD1, 0,
				    priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
	else
		writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
				    priv->io_base + _REG(VPP_MISC));

	meson_plane->enabled = false;
	priv->viu.osd1_enabled = false;
}

static const struct drm_plane_helper_funcs meson_plane_helper_funcs = {
	.atomic_check	= meson_plane_atomic_check,
	.atomic_disable	= meson_plane_atomic_disable,
	.atomic_update	= meson_plane_atomic_update,
};

static bool meson_plane_format_mod_supported(struct drm_plane *plane,
					     u32 format, u64 modifier)
{
	struct meson_plane *meson_plane = to_meson_plane(plane);
	struct meson_drm *priv = meson_plane->priv;
	int i;

	if (modifier == DRM_FORMAT_MOD_INVALID)
		return false;

	if (modifier == DRM_FORMAT_MOD_LINEAR)
		return true;

	if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) &&
	    !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
		return false;

	if (modifier & ~DRM_FORMAT_MOD_ARM_AFBC(MESON_MOD_AFBC_VALID_BITS))
		return false;

	for (i = 0 ; i < plane->modifier_count ; ++i)
		if (plane->modifiers[i] == modifier)
			break;

	if (i == plane->modifier_count) {
		DRM_DEBUG_KMS("Unsupported modifier\n");
		return false;
	}

	if (priv->afbcd.ops && priv->afbcd.ops->supported_fmt)
		return priv->afbcd.ops->supported_fmt(modifier, format);

	DRM_DEBUG_KMS("AFBC Unsupported\n");
	return false;
}

static const struct drm_plane_funcs meson_plane_funcs = {
	.update_plane		= drm_atomic_helper_update_plane,
	.disable_plane		= drm_atomic_helper_disable_plane,
	.destroy		= drm_plane_cleanup,
	.reset			= drm_atomic_helper_plane_reset,
	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
	.format_mod_supported   = meson_plane_format_mod_supported,
};

static const uint32_t supported_drm_formats[] = {
	DRM_FORMAT_ARGB8888,
	DRM_FORMAT_ABGR8888,
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_XBGR8888,
	DRM_FORMAT_RGB888,
	DRM_FORMAT_RGB565,
};

static const uint64_t format_modifiers_afbc_gxm[] = {
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
				AFBC_FORMAT_MOD_SPARSE |
				AFBC_FORMAT_MOD_YTR),
	/* SPLIT mandates SPARSE, RGB modes mandates YTR */
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
				AFBC_FORMAT_MOD_YTR |
				AFBC_FORMAT_MOD_SPARSE |
				AFBC_FORMAT_MOD_SPLIT),
	DRM_FORMAT_MOD_LINEAR,
	DRM_FORMAT_MOD_INVALID,
};

static const uint64_t format_modifiers_afbc_g12a[] = {
	/*
	 * - TOFIX Support AFBC modifiers for YUV formats (16x16 + TILED)
	 * - SPLIT is mandatory for performances reasons when in 16x16
	 *   block size
	 * - 32x8 block size + SPLIT is mandatory with 4K frame size
	 *   for performances reasons
	 */
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
				AFBC_FORMAT_MOD_SPARSE |
				AFBC_FORMAT_MOD_SPLIT),
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
				AFBC_FORMAT_MOD_YTR |
				AFBC_FORMAT_MOD_SPARSE |
				AFBC_FORMAT_MOD_SPLIT),
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
				AFBC_FORMAT_MOD_SPARSE),
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
				AFBC_FORMAT_MOD_YTR |
				AFBC_FORMAT_MOD_SPARSE),
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
				AFBC_FORMAT_MOD_SPARSE |
				AFBC_FORMAT_MOD_SPLIT),
	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
				AFBC_FORMAT_MOD_YTR |
				AFBC_FORMAT_MOD_SPARSE |
				AFBC_FORMAT_MOD_SPLIT),
	DRM_FORMAT_MOD_LINEAR,
	DRM_FORMAT_MOD_INVALID,
};

static const uint64_t format_modifiers_default[] = {
	DRM_FORMAT_MOD_LINEAR,
	DRM_FORMAT_MOD_INVALID,
};

int meson_plane_create(struct meson_drm *priv)
{
	struct meson_plane *meson_plane;
	struct drm_plane *plane;
	const uint64_t *format_modifiers = format_modifiers_default;

	meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane),
				   GFP_KERNEL);
	if (!meson_plane)
		return -ENOMEM;

	meson_plane->priv = priv;
	plane = &meson_plane->base;

	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM))
		format_modifiers = format_modifiers_afbc_gxm;
	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
		format_modifiers = format_modifiers_afbc_g12a;

	drm_universal_plane_init(priv->drm, plane, 0xFF,
				 &meson_plane_funcs,
				 supported_drm_formats,
				 ARRAY_SIZE(supported_drm_formats),
				 format_modifiers,
				 DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");

	drm_plane_helper_add(plane, &meson_plane_helper_funcs);

	/* For now, OSD Primary plane is always on the front */
	drm_plane_create_zpos_immutable_property(plane, 1);

	priv->primary_plane = plane;

	return 0;
}
