// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright © 2018-2020 Intel Corporation
 */

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_plane_helper.h>

#include "kmb_drv.h"
#include "kmb_plane.h"
#include "kmb_regs.h"

const u32 layer_irqs[] = {
	LCD_INT_VL0,
	LCD_INT_VL1,
	LCD_INT_GL0,
	LCD_INT_GL1
};

/* Conversion (yuv->rgb) matrix from myriadx */
static const u32 csc_coef_lcd[] = {
	1024, 0, 1436,
	1024, -352, -731,
	1024, 1814, 0,
	-179, 125, -226
};

/* Graphics layer (layers 2 & 3) formats, only packed formats  are supported */
static const u32 kmb_formats_g[] = {
	DRM_FORMAT_RGB332,
	DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444,
	DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444,
	DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555,
	DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555,
	DRM_FORMAT_RGB565, DRM_FORMAT_BGR565,
	DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
	DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
	DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
};

/* Video layer ( 0 & 1) formats, packed and planar formats are supported */
static const u32 kmb_formats_v[] = {
	/* packed formats */
	DRM_FORMAT_RGB332,
	DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444,
	DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444,
	DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555,
	DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555,
	DRM_FORMAT_RGB565, DRM_FORMAT_BGR565,
	DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
	DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
	DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
	/*planar formats */
	DRM_FORMAT_YUV420, DRM_FORMAT_YVU420,
	DRM_FORMAT_YUV422, DRM_FORMAT_YVU422,
	DRM_FORMAT_YUV444, DRM_FORMAT_YVU444,
	DRM_FORMAT_NV12, DRM_FORMAT_NV21,
};

static unsigned int check_pixel_format(struct drm_plane *plane, u32 format)
{
	struct kmb_drm_private *kmb;
	struct kmb_plane *kmb_plane = to_kmb_plane(plane);
	int i;
	int plane_id = kmb_plane->id;
	struct disp_cfg init_disp_cfg;

	kmb = to_kmb(plane->dev);
	init_disp_cfg = kmb->init_disp_cfg[plane_id];
	/* Due to HW limitations, changing pixel format after initial
	 * plane configuration is not supported.
	 */
	if (init_disp_cfg.format && init_disp_cfg.format != format) {
		drm_dbg(&kmb->drm, "Cannot change format after initial plane configuration");
		return -EINVAL;
	}
	for (i = 0; i < plane->format_count; i++) {
		if (plane->format_types[i] == format)
			return 0;
	}
	return -EINVAL;
}

static int kmb_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 kmb_drm_private *kmb;
	struct kmb_plane *kmb_plane = to_kmb_plane(plane);
	int plane_id = kmb_plane->id;
	struct disp_cfg init_disp_cfg;
	struct drm_framebuffer *fb;
	int ret;
	struct drm_crtc_state *crtc_state;
	bool can_position;

	kmb = to_kmb(plane->dev);
	init_disp_cfg = kmb->init_disp_cfg[plane_id];
	fb = new_plane_state->fb;
	if (!fb || !new_plane_state->crtc)
		return 0;

	ret = check_pixel_format(plane, fb->format->format);
	if (ret)
		return ret;

	if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH ||
	    new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT ||
	    new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
	    new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
		return -EINVAL;

	/* Due to HW limitations, changing plane height or width after
	 * initial plane configuration is not supported.
	 */
	if ((init_disp_cfg.width && init_disp_cfg.height) &&
	    (init_disp_cfg.width != fb->width ||
	    init_disp_cfg.height != fb->height)) {
		drm_dbg(&kmb->drm, "Cannot change plane height or width after initial configuration");
		return -EINVAL;
	}
	can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
	crtc_state =
		drm_atomic_get_existing_crtc_state(state,
						   new_plane_state->crtc);
	return drm_atomic_helper_check_plane_state(new_plane_state,
						   crtc_state,
						   DRM_PLANE_HELPER_NO_SCALING,
						   DRM_PLANE_HELPER_NO_SCALING,
						   can_position, true);
}

static void kmb_plane_atomic_disable(struct drm_plane *plane,
				     struct drm_atomic_state *state)
{
	struct kmb_plane *kmb_plane = to_kmb_plane(plane);
	int plane_id = kmb_plane->id;
	struct kmb_drm_private *kmb;

	kmb = to_kmb(plane->dev);

	if (WARN_ON(plane_id >= KMB_MAX_PLANES))
		return;

	switch (plane_id) {
	case LAYER_0:
		kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL1_ENABLE;
		break;
	case LAYER_1:
		kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL2_ENABLE;
		break;
	case LAYER_2:
		kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL1_ENABLE;
		break;
	case LAYER_3:
		kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL2_ENABLE;
		break;
	}

	kmb->plane_status[plane_id].disable = true;
}

static unsigned int get_pixel_format(u32 format)
{
	unsigned int val = 0;

	switch (format) {
		/* planar formats */
	case DRM_FORMAT_YUV444:
		val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE;
		break;
	case DRM_FORMAT_YVU444:
		val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE
		    | LCD_LAYER_CRCB_ORDER;
		break;
	case DRM_FORMAT_YUV422:
		val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE;
		break;
	case DRM_FORMAT_YVU422:
		val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE
		    | LCD_LAYER_CRCB_ORDER;
		break;
	case DRM_FORMAT_YUV420:
		val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE;
		break;
	case DRM_FORMAT_YVU420:
		val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE
		    | LCD_LAYER_CRCB_ORDER;
		break;
	case DRM_FORMAT_NV12:
		val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE;
		break;
	case DRM_FORMAT_NV21:
		val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE
		    | LCD_LAYER_CRCB_ORDER;
		break;
		/* packed formats */
		/* looks hw requires B & G to be swapped when RGB */
	case DRM_FORMAT_RGB332:
		val = LCD_LAYER_FORMAT_RGB332 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_XBGR4444:
		val = LCD_LAYER_FORMAT_RGBX4444;
		break;
	case DRM_FORMAT_ARGB4444:
		val = LCD_LAYER_FORMAT_RGBA4444 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_ABGR4444:
		val = LCD_LAYER_FORMAT_RGBA4444;
		break;
	case DRM_FORMAT_XRGB1555:
		val = LCD_LAYER_FORMAT_XRGB1555 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_XBGR1555:
		val = LCD_LAYER_FORMAT_XRGB1555;
		break;
	case DRM_FORMAT_ARGB1555:
		val = LCD_LAYER_FORMAT_RGBA1555 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_ABGR1555:
		val = LCD_LAYER_FORMAT_RGBA1555;
		break;
	case DRM_FORMAT_RGB565:
		val = LCD_LAYER_FORMAT_RGB565 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_BGR565:
		val = LCD_LAYER_FORMAT_RGB565;
		break;
	case DRM_FORMAT_RGB888:
		val = LCD_LAYER_FORMAT_RGB888 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_BGR888:
		val = LCD_LAYER_FORMAT_RGB888;
		break;
	case DRM_FORMAT_XRGB8888:
		val = LCD_LAYER_FORMAT_RGBX8888 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_XBGR8888:
		val = LCD_LAYER_FORMAT_RGBX8888;
		break;
	case DRM_FORMAT_ARGB8888:
		val = LCD_LAYER_FORMAT_RGBA8888 | LCD_LAYER_BGR_ORDER;
		break;
	case DRM_FORMAT_ABGR8888:
		val = LCD_LAYER_FORMAT_RGBA8888;
		break;
	}
	DRM_INFO_ONCE("%s : %d format=0x%x val=0x%x\n",
		      __func__, __LINE__, format, val);
	return val;
}

static unsigned int get_bits_per_pixel(const struct drm_format_info *format)
{
	u32 bpp = 0;
	unsigned int val = 0;

	if (format->num_planes > 1) {
		val = LCD_LAYER_8BPP;
		return val;
	}

	bpp += 8 * format->cpp[0];

	switch (bpp) {
	case 8:
		val = LCD_LAYER_8BPP;
		break;
	case 16:
		val = LCD_LAYER_16BPP;
		break;
	case 24:
		val = LCD_LAYER_24BPP;
		break;
	case 32:
		val = LCD_LAYER_32BPP;
		break;
	}

	DRM_DEBUG("bpp=%d val=0x%x\n", bpp, val);
	return val;
}

static void config_csc(struct kmb_drm_private *kmb, int plane_id)
{
	/* YUV to RGB conversion using the fixed matrix csc_coef_lcd */
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF11(plane_id), csc_coef_lcd[0]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF12(plane_id), csc_coef_lcd[1]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF13(plane_id), csc_coef_lcd[2]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF21(plane_id), csc_coef_lcd[3]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF22(plane_id), csc_coef_lcd[4]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF23(plane_id), csc_coef_lcd[5]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF31(plane_id), csc_coef_lcd[6]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF32(plane_id), csc_coef_lcd[7]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF33(plane_id), csc_coef_lcd[8]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF1(plane_id), csc_coef_lcd[9]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF2(plane_id), csc_coef_lcd[10]);
	kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
}

static void kmb_plane_set_alpha(struct kmb_drm_private *kmb,
				const struct drm_plane_state *state,
				unsigned char plane_id,
				unsigned int *val)
{
	u16 plane_alpha = state->alpha;
	u16 pixel_blend_mode = state->pixel_blend_mode;
	int has_alpha = state->fb->format->has_alpha;

	if (plane_alpha != DRM_BLEND_ALPHA_OPAQUE)
		*val |= LCD_LAYER_ALPHA_STATIC;

	if (has_alpha) {
		switch (pixel_blend_mode) {
		case DRM_MODE_BLEND_PIXEL_NONE:
			break;
		case DRM_MODE_BLEND_PREMULTI:
			*val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT;
			break;
		case DRM_MODE_BLEND_COVERAGE:
			*val |= LCD_LAYER_ALPHA_EMBED;
			break;
		default:
			DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n",
				  __stringify(pixel_blend_mode),
				  (long)pixel_blend_mode);
			break;
		}
	}

	if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) {
		*val &= LCD_LAYER_ALPHA_DISABLED;
		return;
	}

	kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha);
}

static void kmb_plane_atomic_update(struct drm_plane *plane,
				    struct drm_atomic_state *state)
{
	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state,
										 plane);
	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
										 plane);
	struct drm_framebuffer *fb;
	struct kmb_drm_private *kmb;
	unsigned int width;
	unsigned int height;
	unsigned int dma_len;
	struct kmb_plane *kmb_plane;
	unsigned int dma_cfg;
	unsigned int ctrl = 0, val = 0, out_format = 0;
	unsigned int src_w, src_h, crtc_x, crtc_y;
	unsigned char plane_id;
	int num_planes;
	static dma_addr_t addr[MAX_SUB_PLANES];
	struct disp_cfg *init_disp_cfg;

	if (!plane || !new_plane_state || !old_plane_state)
		return;

	fb = new_plane_state->fb;
	if (!fb)
		return;

	num_planes = fb->format->num_planes;
	kmb_plane = to_kmb_plane(plane);

	kmb = to_kmb(plane->dev);
	plane_id = kmb_plane->id;

	spin_lock_irq(&kmb->irq_lock);
	if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
		spin_unlock_irq(&kmb->irq_lock);
		drm_dbg(&kmb->drm, "plane_update:underflow!!!! returning");
		return;
	}
	spin_unlock_irq(&kmb->irq_lock);

	init_disp_cfg = &kmb->init_disp_cfg[plane_id];
	src_w = new_plane_state->src_w >> 16;
	src_h = new_plane_state->src_h >> 16;
	crtc_x = new_plane_state->crtc_x;
	crtc_y = new_plane_state->crtc_y;

	drm_dbg(&kmb->drm,
		"src_w=%d src_h=%d, fb->format->format=0x%x fb->flags=0x%x\n",
		  src_w, src_h, fb->format->format, fb->flags);

	width = fb->width;
	height = fb->height;
	dma_len = (width * height * fb->format->cpp[0]);
	drm_dbg(&kmb->drm, "dma_len=%d ", dma_len);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN(plane_id), dma_len);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN_SHADOW(plane_id), dma_len);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_VSTRIDE(plane_id),
		      fb->pitches[0]);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_WIDTH(plane_id),
		      (width * fb->format->cpp[0]));

	addr[Y_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state, 0);
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_START_ADDR(plane_id),
		      addr[Y_PLANE] + fb->offsets[0]);
	val = get_pixel_format(fb->format->format);
	val |= get_bits_per_pixel(fb->format);
	/* Program Cb/Cr for planar formats */
	if (num_planes > 1) {
		kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_VSTRIDE(plane_id),
			      width * fb->format->cpp[0]);
		kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_WIDTH(plane_id),
			      (width * fb->format->cpp[0]));

		addr[U_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state,
							U_PLANE);
		/* check if Cb/Cr is swapped*/
		if (num_planes == 3 && (val & LCD_LAYER_CRCB_ORDER))
			kmb_write_lcd(kmb,
				      LCD_LAYERn_DMA_START_CR_ADR(plane_id),
					addr[U_PLANE]);
		else
			kmb_write_lcd(kmb,
				      LCD_LAYERn_DMA_START_CB_ADR(plane_id),
					addr[U_PLANE]);

		if (num_planes == 3) {
			kmb_write_lcd(kmb,
				      LCD_LAYERn_DMA_CR_LINE_VSTRIDE(plane_id),
				      ((width) * fb->format->cpp[0]));

			kmb_write_lcd(kmb,
				      LCD_LAYERn_DMA_CR_LINE_WIDTH(plane_id),
				      ((width) * fb->format->cpp[0]));

			addr[V_PLANE] = drm_fb_cma_get_gem_addr(fb,
								new_plane_state,
								V_PLANE);

			/* check if Cb/Cr is swapped*/
			if (val & LCD_LAYER_CRCB_ORDER)
				kmb_write_lcd(kmb,
					      LCD_LAYERn_DMA_START_CB_ADR(plane_id),
					      addr[V_PLANE]);
			else
				kmb_write_lcd(kmb,
					      LCD_LAYERn_DMA_START_CR_ADR(plane_id),
					      addr[V_PLANE]);
		}
	}

	kmb_write_lcd(kmb, LCD_LAYERn_WIDTH(plane_id), src_w - 1);
	kmb_write_lcd(kmb, LCD_LAYERn_HEIGHT(plane_id), src_h - 1);
	kmb_write_lcd(kmb, LCD_LAYERn_COL_START(plane_id), crtc_x);
	kmb_write_lcd(kmb, LCD_LAYERn_ROW_START(plane_id), crtc_y);

	val |= LCD_LAYER_FIFO_100;

	if (val & LCD_LAYER_PLANAR_STORAGE) {
		val |= LCD_LAYER_CSC_EN;

		/* Enable CSC if input is planar and output is RGB */
		config_csc(kmb, plane_id);
	}

	kmb_plane_set_alpha(kmb, plane->state, plane_id, &val);

	kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);

	/* Configure LCD_CONTROL */
	ctrl = kmb_read_lcd(kmb, LCD_CONTROL);

	/* Set layer blending config */
	ctrl &= ~LCD_CTRL_ALPHA_ALL;
	ctrl |= LCD_CTRL_ALPHA_BOTTOM_VL1 |
		LCD_CTRL_ALPHA_BLEND_VL2;

	ctrl &= ~LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE;

	switch (plane_id) {
	case LAYER_0:
		ctrl |= LCD_CTRL_VL1_ENABLE;
		break;
	case LAYER_1:
		ctrl |= LCD_CTRL_VL2_ENABLE;
		break;
	case LAYER_2:
		ctrl |= LCD_CTRL_GL1_ENABLE;
		break;
	case LAYER_3:
		ctrl |= LCD_CTRL_GL2_ENABLE;
		break;
	}

	ctrl |= LCD_CTRL_PROGRESSIVE | LCD_CTRL_TIM_GEN_ENABLE
	    | LCD_CTRL_CONTINUOUS | LCD_CTRL_OUTPUT_ENABLED;

	/* LCD is connected to MIPI on kmb
	 * Therefore this bit is required for DSI Tx
	 */
	ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;

	kmb_write_lcd(kmb, LCD_CONTROL, ctrl);

	/* Enable pipeline AXI read transactions for the DMA
	 * after setting graphics layers. This must be done
	 * in a separate write cycle.
	 */
	kmb_set_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA);

	/* FIXME no doc on how to set output format, these values are taken
	 * from the Myriadx tests
	 */
	out_format |= LCD_OUTF_FORMAT_RGB888;

	/* Leave RGB order,conversion mode and clip mode to default */
	/* do not interleave RGB channels for mipi Tx compatibility */
	out_format |= LCD_OUTF_MIPI_RGB_MODE;
	kmb_write_lcd(kmb, LCD_OUT_FORMAT_CFG, out_format);

	dma_cfg = LCD_DMA_LAYER_ENABLE | LCD_DMA_LAYER_VSTRIDE_EN |
	    LCD_DMA_LAYER_CONT_UPDATE | LCD_DMA_LAYER_AXI_BURST_16;

	/* Enable DMA */
	kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg);

	/* Save initial display config */
	if (!init_disp_cfg->width ||
	    !init_disp_cfg->height ||
	    !init_disp_cfg->format) {
		init_disp_cfg->width = width;
		init_disp_cfg->height = height;
		init_disp_cfg->format = fb->format->format;
	}

	drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg,
		kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id)));

	kmb_set_bitmask_lcd(kmb, LCD_INT_CLEAR, LCD_INT_EOF |
			LCD_INT_DMA_ERR);
	kmb_set_bitmask_lcd(kmb, LCD_INT_ENABLE, LCD_INT_EOF |
			LCD_INT_DMA_ERR);
}

static const struct drm_plane_helper_funcs kmb_plane_helper_funcs = {
	.atomic_check = kmb_plane_atomic_check,
	.atomic_update = kmb_plane_atomic_update,
	.atomic_disable = kmb_plane_atomic_disable
};

void kmb_plane_destroy(struct drm_plane *plane)
{
	struct kmb_plane *kmb_plane = to_kmb_plane(plane);

	drm_plane_cleanup(plane);
	kfree(kmb_plane);
}

static const struct drm_plane_funcs kmb_plane_funcs = {
	.update_plane = drm_atomic_helper_update_plane,
	.disable_plane = drm_atomic_helper_disable_plane,
	.destroy = kmb_plane_destroy,
	.reset = drm_atomic_helper_plane_reset,
	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
};

struct kmb_plane *kmb_plane_init(struct drm_device *drm)
{
	struct kmb_drm_private *kmb = to_kmb(drm);
	struct kmb_plane *plane = NULL;
	struct kmb_plane *primary = NULL;
	int i = 0;
	int ret = 0;
	enum drm_plane_type plane_type;
	const u32 *plane_formats;
	int num_plane_formats;
	unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
				  BIT(DRM_MODE_BLEND_PREMULTI)   |
				  BIT(DRM_MODE_BLEND_COVERAGE);

	for (i = 0; i < KMB_MAX_PLANES; i++) {
		plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);

		if (!plane) {
			drm_err(drm, "Failed to allocate plane\n");
			return ERR_PTR(-ENOMEM);
		}

		plane_type = (i == 0) ? DRM_PLANE_TYPE_PRIMARY :
		    DRM_PLANE_TYPE_OVERLAY;
		if (i < 2) {
			plane_formats = kmb_formats_v;
			num_plane_formats = ARRAY_SIZE(kmb_formats_v);
		} else {
			plane_formats = kmb_formats_g;
			num_plane_formats = ARRAY_SIZE(kmb_formats_g);
		}

		ret = drm_universal_plane_init(drm, &plane->base_plane,
					       POSSIBLE_CRTCS, &kmb_plane_funcs,
					       plane_formats, num_plane_formats,
					       NULL, plane_type, "plane %d", i);
		if (ret < 0) {
			drm_err(drm, "drm_universal_plane_init failed (ret=%d)",
				ret);
			goto cleanup;
		}
		drm_dbg(drm, "%s : %d i=%d type=%d",
			__func__, __LINE__,
			  i, plane_type);
		drm_plane_create_alpha_property(&plane->base_plane);

		drm_plane_create_blend_mode_property(&plane->base_plane,
						     blend_caps);

		drm_plane_create_zpos_immutable_property(&plane->base_plane, i);

		drm_plane_helper_add(&plane->base_plane,
				     &kmb_plane_helper_funcs);

		if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
			primary = plane;
			kmb->plane = plane;
		}
		drm_dbg(drm, "%s : %d primary=%p\n", __func__, __LINE__,
			&primary->base_plane);
		plane->id = i;
	}

	/* Disable pipeline AXI read transactions for the DMA
	 * prior to setting graphics layers
	 */
	kmb_clr_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA);

	return primary;
cleanup:
	drmm_kfree(drm, plane);
	return ERR_PTR(ret);
}
