// 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)
{
	int i;

	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_plane_state *state)
{
	struct drm_framebuffer *fb;
	int ret;
	struct drm_crtc_state *crtc_state;
	bool can_position;

	fb = state->fb;
	if (!fb || !state->crtc)
		return 0;

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

	if (state->crtc_w > KMB_MAX_WIDTH || state->crtc_h > KMB_MAX_HEIGHT)
		return -EINVAL;
	if (state->crtc_w < KMB_MIN_WIDTH || state->crtc_h < KMB_MIN_HEIGHT)
		return -EINVAL;
	can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
	crtc_state =
		drm_atomic_get_existing_crtc_state(state->state, state->crtc);
	return drm_atomic_helper_check_plane_state(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_plane_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_atomic_update(struct drm_plane *plane,
				    struct drm_plane_state *state)
{
	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];

	if (!plane || !plane->state || !state)
		return;

	fb = plane->state->fb;
	if (!fb)
		return;
	num_planes = fb->format->num_planes;
	kmb_plane = to_kmb_plane(plane);
	plane_id = kmb_plane->id;

	kmb = to_kmb(plane->dev);

	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);

	src_w = (plane->state->src_w >> 16);
	src_h = plane->state->src_h >> 16;
	crtc_x = plane->state->crtc_x;
	crtc_y = 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, 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, 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,
								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_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);

	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_set_bitmask_lcd(kmb, LCD_CONTROL, ctrl);

	/* 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);
	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;

	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_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;
	}

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