/*
 * Copyright 2017-2018 NXP
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */
#include <drm/drm_fourcc.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <soc/imx8/sc/sci.h>
#include <video/imx8-prefetch.h>

#define SET					0x4
#define CLR					0x8
#define TOG					0xc

#define SYSTEM_CTRL0				0x00
#define BCMD2AXI_MASTR_ID_CTRL			BIT(16)
#define SW_SHADOW_LOAD_SEL			BIT(4)
#define SHADOW_LOAD_EN				BIT(3)
#define REPEAT_EN				BIT(2)
#define SOFT_RESET				BIT(1)
#define RUN_EN					BIT(0)	/* self-clearing */

#define IRQ_MASK				0x20
#define IRQ_MASK_STATUS				0x30
#define IRQ_NONMASK_STATUS			0x40
#define DPR2RTR_FIFO_LOAD_BUF_RDY_UV_ERROR	BIT(7)
#define DPR2RTR_FIFO_LOAD_BUF_RDY_YRGB_ERROR	BIT(6)
#define DPR2RTR_UV_FIFO_OVFL			BIT(5)
#define DPR2RTR_YRGB_FIFO_OVFL			BIT(4)
#define IRQ_AXI_READ_ERROR			BIT(3)
#define IRQ_DPR_SHADOW_LOADED_MASK		BIT(2)
#define IRQ_DPR_RUN				BIT(1)
#define IRQ_DPR_CRTL_DONE			BIT(0)
#define IRQ_ERROR_MASK				0xf8
#define IRQ_CTRL_MASK				0x7

#define MODE_CTRL0				0x50
#define PIX_COMP_SEL_MASK			0x3fc00
#define A_COMP_SEL(byte)			(((byte) & 0x3) << 16)
#define R_COMP_SEL(byte)			(((byte) & 0x3) << 14)
#define G_COMP_SEL(byte)			(((byte) & 0x3) << 12)
#define B_COMP_SEL(byte)			(((byte) & 0x3) << 10)
#define PIX_UV_SWAP				BIT(9)
#define VU					BIT(9)
#define UV					0
#define PIXEL_LUMA_UV_SWAP			BIT(8)
#define UYVY					BIT(8)
#define YUYV					0
#define PIX_SIZE				0xc0
enum {
	PIX_SIZE_8BIT = (0 << 6),
	PIX_SIZE_16BIT = (1 << 6),
	PIX_SIZE_32BIT = (2 << 6),
	PIX_SIZE_RESERVED = (3 << 6),
};
#define COMP_2PLANE_EN				BIT(5)
#define YUV_EN					BIT(4)
#define TILE_TYPE				0xc
enum {
	LINEAR_TILE = (0 << 2),
	GPU_STANDARD_TILE = (1 << 2),
	GPU_SUPER_TILE = (2 << 2),
	VPU_TILE = (3 << 2),
};
#define RTR_4LINE_BUF_EN			BIT(1)
#define LINE4					BIT(1)
#define LINE8					0
#define RTR_3BUF_EN				BIT(0)
#define BUF3					BIT(0)
#define BUF2					0

#define FRAME_CTRL0				0x70
#define PITCH(n)				(((n) & 0xffff) << 16)
#define ROT_FLIP_ORDER_EN			BIT(4)
#define ROT_FIRST				BIT(4)
#define FLIP_FIRST				0
#define ROT_ENC					0xc
#define DEGREE(n)				((((n) / 90) & 0x3) << 2)
#define VFLIP_EN				BIT(1)
#define HFLIP_EN				BIT(0)

#define FRAME_1P_CTRL0				0x90
#define FRAME_2P_CTRL0				0xe0
#define MAX_BYTES_PREQ				0x7
enum {
	BYTE_64 = 0x0,
	BYTE_128 = 0x1,
	BYTE_256 = 0x2,
	BYTE_512 = 0x3,
	BYTE_1K = 0x4,
	BYTE_2K = 0x5,
	BYTE_4K = 0x6,
};

#define FRAME_1P_PIX_X_CTRL			0xa0
#define FRAME_2P_PIX_X_CTRL			0xf0
#define NUM_X_PIX_WIDE(n)			((n) & 0xffff)
#define FRAME_PIX_X_ULC_CTRL			0xf0
#define CROP_ULC_X(n)				((n) & 0xffff)

#define FRAME_1P_PIX_Y_CTRL			0xb0
#define FRAME_2P_PIX_Y_CTRL			0x100
#define NUM_Y_PIX_HIGH(n)			((n) & 0xffff)
#define FRAME_PIX_Y_ULC_CTRL			0x100
#define CROP_ULC_Y(n)				((n) & 0xffff)

#define FRAME_1P_BASE_ADDR_CTRL0		0xc0
#define FRAME_2P_BASE_ADDR_CTRL0		0x110

#define STATUS_CTRL0				0x130
#define STATUS_SRC_SEL				0x70000
enum {
	DPR_CTRL = 0x0,
	PREFETCH_1PLANE = 0x1,
	RESPONSE_1PLANE = 0x2,
	PREFETCH_2PLANE = 0x3,
	RESPONSE_2PLANE = 0x4,
};
#define STATUS_MUX_SEL				0x7

#define STATUS_CTRL1				0x140

#define RTRAM_CTRL0				0x200
#define ABORT_SEL				BIT(7)
#define ABORT					BIT(7)
#define STALL					0
#define THRES_LOW_MASK				0x70
#define THRES_LOW(n)				(((n) & 0x7) << 4)
#define THRES_HIGH_MASK				0xe
#define THRES_HIGH(n)				(((n) & 0x7) << 1)
#define NUM_ROWS_ACTIVE				BIT(0)
#define ROWS_0_6				BIT(0)
#define ROWS_0_4				0

struct dprc {
	struct device *dev;
	void __iomem *base;
	struct list_head list;
	struct clk *clk_apb;
	struct clk *clk_b;
	struct clk *clk_rtram;
	spinlock_t spin_lock;
	u32 sc_resource;
	bool is_blit_chan;

	/* The second one, if non-NULL, is auxiliary for UV buffer. */
	struct prg *prgs[2];
	bool has_aux_prg;
	bool use_aux_prg;
};

struct dprc_format_info {
	u32 format;
	u8 depth;
	u8 num_planes;
	u8 cpp[3];
	u8 hsub;
	u8 vsub;
};

static const struct dprc_format_info formats[] = {
	{
	  .format = DRM_FORMAT_RGB565,
	  .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_ARGB8888,
	  .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_XRGB8888,
	  .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_ABGR8888,
	  .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_XBGR8888,
	  .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_RGBA8888,
	  .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_RGBX8888,
	  .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_BGRA8888,
	  .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_BGRX8888,
	  .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 },
	  .hsub = 1,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_NV12,
	  .depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 },
	  .hsub = 2,   .vsub = 2,
	}, {
	  .format = DRM_FORMAT_NV21,
	  .depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 },
	  .hsub = 2,   .vsub = 2,
	}, {
	  .format = DRM_FORMAT_YUYV,
	  .depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 },
	  .hsub = 2,   .vsub = 1,
	}, {
	  .format = DRM_FORMAT_UYVY,
	  .depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 },
	  .hsub = 2,   .vsub = 1,
	}
};

static const struct dprc_format_info *dprc_format_info(u32 format)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
		if (formats[i].format == format)
			return &formats[i];
	}

	return NULL;
}

static DEFINE_MUTEX(dprc_list_mutex);
static LIST_HEAD(dprc_list);

static inline u32 dprc_read(struct dprc *dprc, unsigned int offset)
{
	return readl(dprc->base + offset);
}

static inline void dprc_write(struct dprc *dprc, u32 value, unsigned int offset)
{
	writel(value, dprc->base + offset);
}

static void dprc_reset(struct dprc *dprc)
{
	dprc_write(dprc, SOFT_RESET, SYSTEM_CTRL0 + SET);

	if (dprc->is_blit_chan)
		usleep_range(10, 20);
	else
		usleep_range(1000, 2000);

	dprc_write(dprc, SOFT_RESET, SYSTEM_CTRL0 + CLR);
}

void dprc_enable(struct dprc *dprc)
{
	if (WARN_ON(!dprc))
		return;

	prg_enable(dprc->prgs[0]);
	if (dprc->use_aux_prg)
		prg_enable(dprc->prgs[1]);
}
EXPORT_SYMBOL_GPL(dprc_enable);

void dprc_disable(struct dprc *dprc)
{
	if (WARN_ON(!dprc))
		return;

	dprc_write(dprc, SHADOW_LOAD_EN | SW_SHADOW_LOAD_SEL, SYSTEM_CTRL0);

	prg_disable(dprc->prgs[0]);
	if (dprc->has_aux_prg)
		prg_disable(dprc->prgs[1]);

	prg_reg_update(dprc->prgs[0]);
	if (dprc->has_aux_prg)
		prg_reg_update(dprc->prgs[1]);
}
EXPORT_SYMBOL_GPL(dprc_disable);

static void dprc_dpu_gpr_configure(struct dprc *dprc, unsigned int stream_id)
{
	sc_err_t sciErr;
	sc_ipc_t ipcHndl = 0;
	u32 mu_id;

	if (WARN_ON(!dprc))
		return;

	sciErr = sc_ipc_getMuID(&mu_id);
	if (sciErr != SC_ERR_NONE) {
		dev_err(dprc->dev, "cannot obtain MU ID %d\n", sciErr);
		return;
	}

	sciErr = sc_ipc_open(&ipcHndl, mu_id);
	if (sciErr != SC_ERR_NONE) {
		dev_err(dprc->dev, "sc_ipc_open failed %d\n", sciErr);
		return;
	}

	sciErr = sc_misc_set_control(ipcHndl, dprc->sc_resource,
					SC_C_KACHUNK_SEL, stream_id);
	if (sciErr != SC_ERR_NONE)
		dev_err(dprc->dev, "sc_misc_set_control failed %d\n", sciErr);

	sc_ipc_close(mu_id);
}

static void dprc_prg_sel_configure(struct dprc *dprc, u32 resource, bool enable)
{
	sc_err_t sciErr;
	sc_ipc_t ipcHndl = 0;
	u32 mu_id;

	if (WARN_ON(!dprc))
		return;

	sciErr = sc_ipc_getMuID(&mu_id);
	if (sciErr != SC_ERR_NONE) {
		dev_err(dprc->dev, "cannot obtain MU ID %d\n", sciErr);
		return;
	}

	sciErr = sc_ipc_open(&ipcHndl, mu_id);
	if (sciErr != SC_ERR_NONE) {
		dev_err(dprc->dev, "sc_ipc_open failed %d\n", sciErr);
		return;
	}

	sciErr = sc_misc_set_control(ipcHndl, resource, SC_C_SEL0, enable);
	if (sciErr != SC_ERR_NONE)
		dev_err(dprc->dev, "sc_misc_set_control failed %d\n", sciErr);

	sc_ipc_close(mu_id);
}

void dprc_configure(struct dprc *dprc, unsigned int stream_id,
		    unsigned int width, unsigned int height,
		    unsigned int x_offset, unsigned int y_offset,
		    unsigned int stride, u32 format, u64 modifier,
		    unsigned long baddr, unsigned long uv_baddr,
		    bool start, bool aux_start, bool interlace_frame)
{
	const struct dprc_format_info *info = dprc_format_info(format);
	unsigned int dprc_width = width + x_offset;
	unsigned int dprc_height;
	unsigned int p1_w, p1_h, p2_w, p2_h;
	unsigned int prg_stride = width * info->cpp[0];
	unsigned int bpp = 8 * info->cpp[0];
	unsigned int preq;
	unsigned int mt_w = 0, mt_h = 0;	/* w/h in a micro-tile */
	u32 val;

	if (WARN_ON(!dprc))
		return;

	dprc->use_aux_prg = false;

	if (start) {
		dprc_reset(dprc);

		if (!dprc->is_blit_chan)
			dprc_dpu_gpr_configure(dprc, stream_id);
	}

	if (interlace_frame) {
		height /= 2;
		y_offset /= 2;
	}

	dprc_height = height + y_offset;

	/* disable all control irqs and enable all error irqs */
	dprc_write(dprc, IRQ_CTRL_MASK, IRQ_MASK);

	if (info->num_planes > 1) {
		p1_w = round_up(dprc_width, modifier ? 8 : 64);
		p1_h = round_up(dprc_height, 8);

		p2_w = p1_w;
		if (modifier)
			p2_h = dprc_height / info->vsub;
		else
			p2_h = round_up((dprc_height / info->vsub), 8);

		preq = modifier ? BYTE_64 : BYTE_1K;

		dprc_write(dprc, preq, FRAME_2P_CTRL0);
		if (dprc->sc_resource == SC_R_DC_0_BLIT1 ||
		    dprc->sc_resource == SC_R_DC_1_BLIT1) {
			dprc_prg_sel_configure(dprc,
					dprc->sc_resource == SC_R_DC_0_BLIT1 ?
					SC_R_DC_0_BLIT0 : SC_R_DC_1_BLIT0,
					true);
			prg_set_auxiliary(dprc->prgs[1]);
			dprc->has_aux_prg = true;
		}
		dprc_write(dprc, uv_baddr, FRAME_2P_BASE_ADDR_CTRL0);
	} else {
		switch (dprc->sc_resource) {
		case SC_R_DC_0_BLIT0:
		case SC_R_DC_1_BLIT0:
			dprc_prg_sel_configure(dprc, dprc->sc_resource, false);
			prg_set_primary(dprc->prgs[0]);
			break;
		case SC_R_DC_0_BLIT1:
		case SC_R_DC_1_BLIT1:
			dprc->has_aux_prg = false;
			break;
		default:
			break;
		}

		switch (modifier) {
		case DRM_FORMAT_MOD_VIVANTE_TILED:
			p1_w = round_up(dprc_width, info->cpp[0] == 2 ? 8 : 4);
			break;
		case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
			if (dprc->is_blit_chan)
				p1_w = round_up(dprc_width,
						info->cpp[0] == 2 ? 8 : 4);
			else
				p1_w = round_up(dprc_width, 64);
			break;
		default:
			p1_w = round_up(dprc_width,
					info->cpp[0] == 2 ? 32 : 16);
			break;
		}
		p1_h = round_up(dprc_height, 4);
	}

	dprc_write(dprc, PITCH(stride), FRAME_CTRL0);
	switch (modifier) {
	case DRM_FORMAT_MOD_AMPHION_TILED:
		preq = BYTE_64;
		mt_w = 8;
		mt_h = 8;
		break;
	case DRM_FORMAT_MOD_VIVANTE_TILED:
	case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
		if (bpp == 16) {
			preq = BYTE_64;
			mt_w = 8;
		} else {
			preq = (x_offset % 8) ? BYTE_64 : BYTE_128;
			mt_w = 4;
		}
		mt_h = 4;
		break;
	default:
		preq = BYTE_1K;
		break;
	}
	dprc_write(dprc, preq, FRAME_1P_CTRL0);
	dprc_write(dprc, NUM_X_PIX_WIDE(p1_w), FRAME_1P_PIX_X_CTRL);
	dprc_write(dprc, NUM_Y_PIX_HIGH(p1_h), FRAME_1P_PIX_Y_CTRL);
	dprc_write(dprc, baddr, FRAME_1P_BASE_ADDR_CTRL0);
	if (modifier) {
		dprc_write(dprc, CROP_ULC_X(round_down(x_offset, mt_w)),
							FRAME_PIX_X_ULC_CTRL);
		dprc_write(dprc, CROP_ULC_Y(round_down(y_offset, mt_h)),
							FRAME_PIX_Y_ULC_CTRL);
	} else {
		dprc_write(dprc, CROP_ULC_X(0), FRAME_PIX_X_ULC_CTRL);
		dprc_write(dprc, CROP_ULC_Y(0), FRAME_PIX_Y_ULC_CTRL);
	}

	val = dprc_read(dprc, RTRAM_CTRL0);
	val &= ~THRES_LOW_MASK;
	val |= THRES_LOW(3);
	val &= ~THRES_HIGH_MASK;
	val |= THRES_HIGH(7);
	dprc_write(dprc, val, RTRAM_CTRL0);

	val = dprc_read(dprc, MODE_CTRL0);
	val &= ~PIX_UV_SWAP;
	val &= ~PIXEL_LUMA_UV_SWAP;
	val &= ~COMP_2PLANE_EN;
	val &= ~YUV_EN;
	val &= ~TILE_TYPE;
	switch (modifier) {
	case DRM_FORMAT_MOD_NONE:
		break;
	case DRM_FORMAT_MOD_AMPHION_TILED:
		val |= VPU_TILE;
		break;
	case DRM_FORMAT_MOD_VIVANTE_TILED:
		val |= GPU_STANDARD_TILE;
		break;
	case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
		val |= GPU_SUPER_TILE;
		break;
	default:
		dev_err(dprc->dev, "unsupported modifier 0x%016llx\n",
								modifier);
		return;
	}
	val &= ~RTR_4LINE_BUF_EN;
	val |= info->num_planes > 1 ? LINE8 : LINE4;
	val &= ~RTR_3BUF_EN;
	val |= BUF2;
	val &= ~(PIX_COMP_SEL_MASK | PIX_SIZE);
	switch (format) {
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ABGR8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_RGBA8888:
	case DRM_FORMAT_RGBX8888:
	case DRM_FORMAT_BGRA8888:
	case DRM_FORMAT_BGRX8888:
		/*
		 * It turns out pixel components are mapped directly
		 * without position change via DPR processing with
		 * the following color component configurations.
		 * Leave the pixel format to be handled by the
		 * display controllers.
		 */
		val |= A_COMP_SEL(3) | R_COMP_SEL(2) |
		       G_COMP_SEL(1) | B_COMP_SEL(0);
		val |= PIX_SIZE_32BIT;
		break;
	case DRM_FORMAT_YUYV:
	case DRM_FORMAT_UYVY:
		val |= YUV_EN;
		/* fall-through */
	case DRM_FORMAT_RGB565:
		val |= PIX_SIZE_16BIT;
		break;
	case DRM_FORMAT_NV12:
	case DRM_FORMAT_NV21:
		dprc->use_aux_prg = true;

		val |= COMP_2PLANE_EN;
		val |= YUV_EN;
		val |= PIX_SIZE_8BIT;
		break;
	default:
		dev_err(dprc->dev, "unsupported format 0x%08x\n", format);
		return;
	}
	dprc_write(dprc, val, MODE_CTRL0);

	if (dprc->is_blit_chan) {
		val = SW_SHADOW_LOAD_SEL | RUN_EN | SHADOW_LOAD_EN;
		dprc_write(dprc, val, SYSTEM_CTRL0);
	} else if (start) {
		/* software shadow load for the first frame */
		val = SW_SHADOW_LOAD_SEL | SHADOW_LOAD_EN;
		dprc_write(dprc, val, SYSTEM_CTRL0);

		/* and then, run... */
		val |= RUN_EN | REPEAT_EN;
		dprc_write(dprc, val, SYSTEM_CTRL0);
	}

	prg_configure(dprc->prgs[0], width, height, x_offset, y_offset,
			prg_stride, bpp, baddr, format, modifier, start);
	if (dprc->use_aux_prg)
		prg_configure(dprc->prgs[1], width, height, x_offset, y_offset,
			prg_stride, 8, uv_baddr, format, modifier, aux_start);

	dev_dbg(dprc->dev, "w-%u, h-%u, s-%u, fmt-0x%08x, mod-0x%016llx\n",
				width, height, stride, format, modifier);
}
EXPORT_SYMBOL_GPL(dprc_configure);

void dprc_reg_update(struct dprc *dprc)
{
	if (WARN_ON(!dprc))
		return;

	prg_reg_update(dprc->prgs[0]);
	if (dprc->use_aux_prg)
		prg_reg_update(dprc->prgs[1]);
}
EXPORT_SYMBOL_GPL(dprc_reg_update);

void dprc_first_frame_handle(struct dprc *dprc)
{
	if (WARN_ON(!dprc))
		return;

	if (dprc->is_blit_chan)
		return;

	dprc_write(dprc, REPEAT_EN, SYSTEM_CTRL0);

	prg_shadow_enable(dprc->prgs[0]);
	if (dprc->use_aux_prg)
		prg_shadow_enable(dprc->prgs[1]);
}
EXPORT_SYMBOL_GPL(dprc_first_frame_handle);

void dprc_irq_handle(struct dprc *dprc)
{
	u32 mask, status;

	if (WARN_ON(!dprc))
		return;

	spin_lock(&dprc->spin_lock);

	mask = dprc_read(dprc, IRQ_MASK);
	mask = ~mask;
	status = dprc_read(dprc, IRQ_MASK_STATUS);
	status &= mask;

	/* disable irqs to be handled */
	dprc_write(dprc, status, IRQ_MASK + SET);

	/* clear status */
	dprc_write(dprc, status, IRQ_MASK_STATUS);

	if (status & DPR2RTR_FIFO_LOAD_BUF_RDY_UV_ERROR)
		dev_err(dprc->dev,
			"DPR to RTRAM FIFO load UV buffer ready error\n");

	if (status & DPR2RTR_FIFO_LOAD_BUF_RDY_YRGB_ERROR)
		dev_err(dprc->dev,
			"DPR to RTRAM FIFO load YRGB buffer ready error\n");

	if (status & DPR2RTR_UV_FIFO_OVFL)
		dev_err(dprc->dev, "DPR to RTRAM FIFO UV FIFO overflow\n");

	if (status & DPR2RTR_YRGB_FIFO_OVFL)
		dev_err(dprc->dev, "DPR to RTRAM FIFO YRGB FIFO overflow\n");

	if (status & IRQ_AXI_READ_ERROR)
		dev_err(dprc->dev, "AXI read error\n");

	if (status & IRQ_DPR_CRTL_DONE)
		dprc_first_frame_handle(dprc);

	spin_unlock(&dprc->spin_lock);
}
EXPORT_SYMBOL_GPL(dprc_irq_handle);

void dprc_enable_ctrl_done_irq(struct dprc *dprc)
{
	unsigned long lock_flags;

	if (WARN_ON(!dprc))
		return;

	spin_lock_irqsave(&dprc->spin_lock, lock_flags);
	dprc_write(dprc, IRQ_DPR_CRTL_DONE, IRQ_MASK + CLR);
	spin_unlock_irqrestore(&dprc->spin_lock, lock_flags);
}
EXPORT_SYMBOL_GPL(dprc_enable_ctrl_done_irq);

bool dprc_format_supported(struct dprc *dprc, u32 format, u64 modifier)
{
	if (WARN_ON(!dprc))
		return false;

	switch (format) {
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ABGR8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_RGBA8888:
	case DRM_FORMAT_RGBX8888:
	case DRM_FORMAT_BGRA8888:
	case DRM_FORMAT_BGRX8888:
	case DRM_FORMAT_RGB565:
		return (modifier == DRM_FORMAT_MOD_NONE ||
			modifier == DRM_FORMAT_MOD_VIVANTE_TILED ||
			modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED);
	case DRM_FORMAT_YUYV:
	case DRM_FORMAT_UYVY:
		switch (dprc->sc_resource) {
		case SC_R_DC_0_FRAC0:
		case SC_R_DC_1_FRAC0:
		case SC_R_DC_0_WARP:
		case SC_R_DC_1_WARP:
			return false;
		}
		return modifier == DRM_FORMAT_MOD_NONE;
	case DRM_FORMAT_NV12:
	case DRM_FORMAT_NV21:
		switch (dprc->sc_resource) {
		case SC_R_DC_0_FRAC0:
		case SC_R_DC_1_FRAC0:
		case SC_R_DC_0_WARP:
		case SC_R_DC_1_WARP:
			return false;
		case SC_R_DC_0_BLIT1:
		case SC_R_DC_1_BLIT1:
			return (modifier == DRM_FORMAT_MOD_NONE ||
				modifier == DRM_FORMAT_MOD_AMPHION_TILED);
		}
		return (dprc->has_aux_prg &&
			(modifier == DRM_FORMAT_MOD_NONE ||
			 modifier == DRM_FORMAT_MOD_AMPHION_TILED));
	}

	return false;
}
EXPORT_SYMBOL_GPL(dprc_format_supported);

bool dprc_stride_supported(struct dprc *dprc,
			   unsigned int stride, unsigned int uv_stride,
			   unsigned int width, u32 format)
{
	const struct dprc_format_info *info = dprc_format_info(format);
	unsigned int prg_stride = width * info->cpp[0];

	if (WARN_ON(!dprc))
		return false;

	if (stride > 0xffff)
		return false;

	if (info->num_planes > 1 && stride != uv_stride)
		return false;

	return prg_stride_supported(dprc->prgs[0], prg_stride);
}
EXPORT_SYMBOL_GPL(dprc_stride_supported);

bool dprc_stride_double_check(struct dprc *dprc,
			      unsigned int width, unsigned int x_offset,
			      u32 format, u64 modifier,
			      dma_addr_t baddr, dma_addr_t uv_baddr)
{
	const struct dprc_format_info *info = dprc_format_info(format);
	unsigned int bpp = 8 * info->cpp[0];
	unsigned int prg_stride = width * info->cpp[0];

	if (WARN_ON(!dprc))
		return false;

	if (!prg_stride_double_check(dprc->prgs[0], width, x_offset,
				     bpp, modifier, prg_stride, baddr))
		return false;

	if (info->num_planes > 1 &&
	    !prg_stride_double_check(dprc->prgs[1], width, x_offset,
				     bpp, modifier, prg_stride, uv_baddr))
		return false;

	return true;
}
EXPORT_SYMBOL_GPL(dprc_stride_double_check);

struct dprc *
dprc_lookup_by_phandle(struct device *dev, const char *name, int index)
{
	struct device_node *dprc_node = of_parse_phandle(dev->of_node,
							 name, index);
	struct dprc *dprc;

	mutex_lock(&dprc_list_mutex);
	list_for_each_entry(dprc, &dprc_list, list) {
		if (dprc_node == dprc->dev->of_node) {
			mutex_unlock(&dprc_list_mutex);
			device_link_add(dev, dprc->dev, DL_FLAG_AUTOREMOVE);
			return dprc;
		}
	}
	mutex_unlock(&dprc_list_mutex);

	return NULL;
}
EXPORT_SYMBOL_GPL(dprc_lookup_by_phandle);

static const struct of_device_id dprc_dt_ids[] = {
	{ .compatible = "fsl,imx8qm-dpr-channel", },
	{ .compatible = "fsl,imx8qxp-dpr-channel", },
	{ /* sentinel */ },
};

static int dprc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct dprc *dprc;
	int ret, i;

	dprc = devm_kzalloc(dev, sizeof(*dprc), GFP_KERNEL);
	if (!dprc)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dprc->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dprc->base))
		return PTR_ERR(dprc->base);

	dprc->clk_apb = devm_clk_get(dev, "apb");
	if (IS_ERR(dprc->clk_apb))
		return PTR_ERR(dprc->clk_apb);
	clk_prepare_enable(dprc->clk_apb);

	dprc->clk_b = devm_clk_get(dev, "b");
	if (IS_ERR(dprc->clk_b))
		return PTR_ERR(dprc->clk_b);
	clk_prepare_enable(dprc->clk_b);

	dprc->clk_rtram = devm_clk_get(dev, "rtram");
	if (IS_ERR(dprc->clk_rtram))
		return PTR_ERR(dprc->clk_rtram);
	clk_prepare_enable(dprc->clk_rtram);

	ret = of_property_read_u32(pdev->dev.of_node,
					"fsl,sc-resource", &dprc->sc_resource);
	if (ret) {
		dev_err(dev, "cannot get SC resource %d\n", ret);
		return ret;
	}

	switch (dprc->sc_resource) {
	case SC_R_DC_0_BLIT1:
	case SC_R_DC_1_BLIT1:
		dprc->has_aux_prg = true;
		/* fall-through */
	case SC_R_DC_0_BLIT0:
	case SC_R_DC_1_BLIT0:
		dprc->is_blit_chan = true;
		/* fall-through */
	case SC_R_DC_0_FRAC0:
	case SC_R_DC_1_FRAC0:
		break;
	case SC_R_DC_0_VIDEO0:
	case SC_R_DC_0_VIDEO1:
	case SC_R_DC_1_VIDEO0:
	case SC_R_DC_1_VIDEO1:
	case SC_R_DC_0_WARP:
	case SC_R_DC_1_WARP:
		dprc->has_aux_prg = true;
		break;
	default:
		dev_err(dev, "wrong SC resource %u\n", dprc->sc_resource);
		return -EINVAL;
	}

	for (i = 0; i < 2; i++) {
		if (i == 1 && !dprc->has_aux_prg)
			break;

		dprc->prgs[i] = prg_lookup_by_phandle(dev, "fsl,prgs", i);
		if (!dprc->prgs[i])
			return -EPROBE_DEFER;

		if (i == 1)
			prg_set_auxiliary(dprc->prgs[i]);

		if (dprc->is_blit_chan)
			prg_set_blit(dprc->prgs[i]);
	}

	dprc->dev = dev;
	spin_lock_init(&dprc->spin_lock);
	platform_set_drvdata(pdev, dprc);
	mutex_lock(&dprc_list_mutex);
	list_add(&dprc->list, &dprc_list);
	mutex_unlock(&dprc_list_mutex);

	dprc_reset(dprc);

	return 0;
}

static int dprc_remove(struct platform_device *pdev)
{
	struct dprc *dprc = platform_get_drvdata(pdev);

	mutex_lock(&dprc_list_mutex);
	list_del(&dprc->list);
	mutex_unlock(&dprc_list_mutex);

	clk_disable_unprepare(dprc->clk_rtram);
	clk_disable_unprepare(dprc->clk_b);
	clk_disable_unprepare(dprc->clk_apb);

	return 0;
}

struct platform_driver dprc_drv = {
	.probe = dprc_probe,
	.remove = dprc_remove,
	.driver = {
		.name = "imx8-dpr-channel",
		.of_match_table = dprc_dt_ids,
	},
};
module_platform_driver(dprc_drv);

MODULE_DESCRIPTION("i.MX8 DPRC driver");
MODULE_AUTHOR("NXP Semiconductor");
MODULE_LICENSE("GPL");
