// SPDX-License-Identifier: GPL-2.0
/*
 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
 * Author: James.Qian.Wang <james.qian.wang@arm.com>
 *
 */

#include <drm/drm_print.h>
#include "d71_dev.h"
#include "malidp_io.h"

static u64 get_lpu_event(struct d71_pipeline *d71_pipeline)
{
	u32 __iomem *reg = d71_pipeline->lpu_addr;
	u32 status, raw_status;
	u64 evts = 0ULL;

	raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
	if (raw_status & LPU_IRQ_IBSY)
		evts |= KOMEDA_EVENT_IBSY;
	if (raw_status & LPU_IRQ_EOW)
		evts |= KOMEDA_EVENT_EOW;
	if (raw_status & LPU_IRQ_OVR)
		evts |= KOMEDA_EVENT_OVR;

	if (raw_status & (LPU_IRQ_ERR | LPU_IRQ_IBSY | LPU_IRQ_OVR)) {
		u32 restore = 0, tbu_status;
		/* Check error of LPU status */
		status = malidp_read32(reg, BLK_STATUS);
		if (status & LPU_STATUS_AXIE) {
			restore |= LPU_STATUS_AXIE;
			evts |= KOMEDA_ERR_AXIE;
		}
		if (status & LPU_STATUS_ACE0) {
			restore |= LPU_STATUS_ACE0;
			evts |= KOMEDA_ERR_ACE0;
		}
		if (status & LPU_STATUS_ACE1) {
			restore |= LPU_STATUS_ACE1;
			evts |= KOMEDA_ERR_ACE1;
		}
		if (status & LPU_STATUS_ACE2) {
			restore |= LPU_STATUS_ACE2;
			evts |= KOMEDA_ERR_ACE2;
		}
		if (status & LPU_STATUS_ACE3) {
			restore |= LPU_STATUS_ACE3;
			evts |= KOMEDA_ERR_ACE3;
		}
		if (status & LPU_STATUS_FEMPTY) {
			restore |= LPU_STATUS_FEMPTY;
			evts |= KOMEDA_EVENT_EMPTY;
		}
		if (status & LPU_STATUS_FFULL) {
			restore |= LPU_STATUS_FFULL;
			evts |= KOMEDA_EVENT_FULL;
		}

		if (restore != 0)
			malidp_write32_mask(reg, BLK_STATUS, restore, 0);

		restore = 0;
		/* Check errors of TBU status */
		tbu_status = malidp_read32(reg, LPU_TBU_STATUS);
		if (tbu_status & LPU_TBU_STATUS_TCF) {
			restore |= LPU_TBU_STATUS_TCF;
			evts |= KOMEDA_ERR_TCF;
		}
		if (tbu_status & LPU_TBU_STATUS_TTNG) {
			restore |= LPU_TBU_STATUS_TTNG;
			evts |= KOMEDA_ERR_TTNG;
		}
		if (tbu_status & LPU_TBU_STATUS_TITR) {
			restore |= LPU_TBU_STATUS_TITR;
			evts |= KOMEDA_ERR_TITR;
		}
		if (tbu_status & LPU_TBU_STATUS_TEMR) {
			restore |= LPU_TBU_STATUS_TEMR;
			evts |= KOMEDA_ERR_TEMR;
		}
		if (tbu_status & LPU_TBU_STATUS_TTF) {
			restore |= LPU_TBU_STATUS_TTF;
			evts |= KOMEDA_ERR_TTF;
		}
		if (restore != 0)
			malidp_write32_mask(reg, LPU_TBU_STATUS, restore, 0);
	}

	malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
	return evts;
}

static u64 get_cu_event(struct d71_pipeline *d71_pipeline)
{
	u32 __iomem *reg = d71_pipeline->cu_addr;
	u32 status, raw_status;
	u64 evts = 0ULL;

	raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
	if (raw_status & CU_IRQ_OVR)
		evts |= KOMEDA_EVENT_OVR;

	if (raw_status & (CU_IRQ_ERR | CU_IRQ_OVR)) {
		status = malidp_read32(reg, BLK_STATUS) & 0x7FFFFFFF;
		if (status & CU_STATUS_CPE)
			evts |= KOMEDA_ERR_CPE;
		if (status & CU_STATUS_ZME)
			evts |= KOMEDA_ERR_ZME;
		if (status & CU_STATUS_CFGE)
			evts |= KOMEDA_ERR_CFGE;
		if (status)
			malidp_write32_mask(reg, BLK_STATUS, status, 0);
	}

	malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);

	return evts;
}

static u64 get_dou_event(struct d71_pipeline *d71_pipeline)
{
	u32 __iomem *reg = d71_pipeline->dou_addr;
	u32 status, raw_status;
	u64 evts = 0ULL;

	raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
	if (raw_status & DOU_IRQ_PL0)
		evts |= KOMEDA_EVENT_VSYNC;
	if (raw_status & DOU_IRQ_UND)
		evts |= KOMEDA_EVENT_URUN;

	if (raw_status & (DOU_IRQ_ERR | DOU_IRQ_UND)) {
		u32 restore  = 0;

		status = malidp_read32(reg, BLK_STATUS);
		if (status & DOU_STATUS_DRIFTTO) {
			restore |= DOU_STATUS_DRIFTTO;
			evts |= KOMEDA_ERR_DRIFTTO;
		}
		if (status & DOU_STATUS_FRAMETO) {
			restore |= DOU_STATUS_FRAMETO;
			evts |= KOMEDA_ERR_FRAMETO;
		}
		if (status & DOU_STATUS_TETO) {
			restore |= DOU_STATUS_TETO;
			evts |= KOMEDA_ERR_TETO;
		}
		if (status & DOU_STATUS_CSCE) {
			restore |= DOU_STATUS_CSCE;
			evts |= KOMEDA_ERR_CSCE;
		}

		if (restore != 0)
			malidp_write32_mask(reg, BLK_STATUS, restore, 0);
	}

	malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
	return evts;
}

static u64 get_pipeline_event(struct d71_pipeline *d71_pipeline, u32 gcu_status)
{
	u32 evts = 0ULL;

	if (gcu_status & (GLB_IRQ_STATUS_LPU0 | GLB_IRQ_STATUS_LPU1))
		evts |= get_lpu_event(d71_pipeline);

	if (gcu_status & (GLB_IRQ_STATUS_CU0 | GLB_IRQ_STATUS_CU1))
		evts |= get_cu_event(d71_pipeline);

	if (gcu_status & (GLB_IRQ_STATUS_DOU0 | GLB_IRQ_STATUS_DOU1))
		evts |= get_dou_event(d71_pipeline);

	return evts;
}

static irqreturn_t
d71_irq_handler(struct komeda_dev *mdev, struct komeda_events *evts)
{
	struct d71_dev *d71 = mdev->chip_data;
	u32 status, gcu_status, raw_status;

	gcu_status = malidp_read32(d71->gcu_addr, GLB_IRQ_STATUS);

	if (gcu_status & GLB_IRQ_STATUS_GCU) {
		raw_status = malidp_read32(d71->gcu_addr, BLK_IRQ_RAW_STATUS);
		if (raw_status & GCU_IRQ_CVAL0)
			evts->pipes[0] |= KOMEDA_EVENT_FLIP;
		if (raw_status & GCU_IRQ_CVAL1)
			evts->pipes[1] |= KOMEDA_EVENT_FLIP;
		if (raw_status & GCU_IRQ_ERR) {
			status = malidp_read32(d71->gcu_addr, BLK_STATUS);
			if (status & GCU_STATUS_MERR) {
				evts->global |= KOMEDA_ERR_MERR;
				malidp_write32_mask(d71->gcu_addr, BLK_STATUS,
						    GCU_STATUS_MERR, 0);
			}
		}

		malidp_write32(d71->gcu_addr, BLK_IRQ_CLEAR, raw_status);
	}

	if (gcu_status & GLB_IRQ_STATUS_PIPE0)
		evts->pipes[0] |= get_pipeline_event(d71->pipes[0], gcu_status);

	if (gcu_status & GLB_IRQ_STATUS_PIPE1)
		evts->pipes[1] |= get_pipeline_event(d71->pipes[1], gcu_status);

	return IRQ_RETVAL(gcu_status);
}

#define ENABLED_GCU_IRQS	(GCU_IRQ_CVAL0 | GCU_IRQ_CVAL1 | \
				 GCU_IRQ_MODE | GCU_IRQ_ERR)
#define ENABLED_LPU_IRQS	(LPU_IRQ_IBSY | LPU_IRQ_ERR | LPU_IRQ_EOW)
#define ENABLED_CU_IRQS		(CU_IRQ_OVR | CU_IRQ_ERR)
#define ENABLED_DOU_IRQS	(DOU_IRQ_UND | DOU_IRQ_ERR)

static int d71_enable_irq(struct komeda_dev *mdev)
{
	struct d71_dev *d71 = mdev->chip_data;
	struct d71_pipeline *pipe;
	u32 i;

	malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK,
			    ENABLED_GCU_IRQS, ENABLED_GCU_IRQS);
	for (i = 0; i < d71->num_pipelines; i++) {
		pipe = d71->pipes[i];
		malidp_write32_mask(pipe->cu_addr,  BLK_IRQ_MASK,
				    ENABLED_CU_IRQS, ENABLED_CU_IRQS);
		malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK,
				    ENABLED_LPU_IRQS, ENABLED_LPU_IRQS);
		malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
				    ENABLED_DOU_IRQS, ENABLED_DOU_IRQS);
	}
	return 0;
}

static int d71_disable_irq(struct komeda_dev *mdev)
{
	struct d71_dev *d71 = mdev->chip_data;
	struct d71_pipeline *pipe;
	u32 i;

	malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK, ENABLED_GCU_IRQS, 0);
	for (i = 0; i < d71->num_pipelines; i++) {
		pipe = d71->pipes[i];
		malidp_write32_mask(pipe->cu_addr,  BLK_IRQ_MASK,
				    ENABLED_CU_IRQS, 0);
		malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK,
				    ENABLED_LPU_IRQS, 0);
		malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
				    ENABLED_DOU_IRQS, 0);
	}
	return 0;
}

static void d71_on_off_vblank(struct komeda_dev *mdev, int master_pipe, bool on)
{
	struct d71_dev *d71 = mdev->chip_data;
	struct d71_pipeline *pipe = d71->pipes[master_pipe];

	malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
			    DOU_IRQ_PL0, on ? DOU_IRQ_PL0 : 0);
}

static int to_d71_opmode(int core_mode)
{
	switch (core_mode) {
	case KOMEDA_MODE_DISP0:
		return DO0_ACTIVE_MODE;
	case KOMEDA_MODE_DISP1:
		return DO1_ACTIVE_MODE;
	case KOMEDA_MODE_DUAL_DISP:
		return DO01_ACTIVE_MODE;
	case KOMEDA_MODE_INACTIVE:
		return INACTIVE_MODE;
	default:
		WARN(1, "Unknown operation mode");
		return INACTIVE_MODE;
	}
}

static int d71_change_opmode(struct komeda_dev *mdev, int new_mode)
{
	struct d71_dev *d71 = mdev->chip_data;
	u32 opmode = to_d71_opmode(new_mode);
	int ret;

	malidp_write32_mask(d71->gcu_addr, BLK_CONTROL, 0x7, opmode);

	ret = dp_wait_cond(((malidp_read32(d71->gcu_addr, BLK_CONTROL) & 0x7) == opmode),
			   100, 1000, 10000);

	return ret;
}

static void d71_flush(struct komeda_dev *mdev,
		      int master_pipe, u32 active_pipes)
{
	struct d71_dev *d71 = mdev->chip_data;
	u32 reg_offset = (master_pipe == 0) ?
			 GCU_CONFIG_VALID0 : GCU_CONFIG_VALID1;

	malidp_write32(d71->gcu_addr, reg_offset, GCU_CONFIG_CVAL);
}

static int d71_reset(struct d71_dev *d71)
{
	u32 __iomem *gcu = d71->gcu_addr;
	int ret;

	malidp_write32_mask(gcu, BLK_CONTROL,
			    GCU_CONTROL_SRST, GCU_CONTROL_SRST);

	ret = dp_wait_cond(!(malidp_read32(gcu, BLK_CONTROL) & GCU_CONTROL_SRST),
			   100, 1000, 10000);

	return ret;
}

void d71_read_block_header(u32 __iomem *reg, struct block_header *blk)
{
	int i;

	blk->block_info = malidp_read32(reg, BLK_BLOCK_INFO);
	if (BLOCK_INFO_BLK_TYPE(blk->block_info) == D71_BLK_TYPE_RESERVED)
		return;

	blk->pipeline_info = malidp_read32(reg, BLK_PIPELINE_INFO);

	/* get valid input and output ids */
	for (i = 0; i < PIPELINE_INFO_N_VALID_INPUTS(blk->pipeline_info); i++)
		blk->input_ids[i] = malidp_read32(reg + i, BLK_VALID_INPUT_ID0);
	for (i = 0; i < PIPELINE_INFO_N_OUTPUTS(blk->pipeline_info); i++)
		blk->output_ids[i] = malidp_read32(reg + i, BLK_OUTPUT_ID0);
}

static void d71_cleanup(struct komeda_dev *mdev)
{
	struct d71_dev *d71 = mdev->chip_data;

	if (!d71)
		return;

	devm_kfree(mdev->dev, d71);
	mdev->chip_data = NULL;
}

static int d71_enum_resources(struct komeda_dev *mdev)
{
	struct d71_dev *d71;
	struct komeda_pipeline *pipe;
	struct block_header blk;
	u32 __iomem *blk_base;
	u32 i, value, offset;
	int err;

	d71 = devm_kzalloc(mdev->dev, sizeof(*d71), GFP_KERNEL);
	if (!d71)
		return -ENOMEM;

	mdev->chip_data = d71;
	d71->mdev = mdev;
	d71->gcu_addr = mdev->reg_base;
	d71->periph_addr = mdev->reg_base + (D71_BLOCK_OFFSET_PERIPH >> 2);

	err = d71_reset(d71);
	if (err) {
		DRM_ERROR("Fail to reset d71 device.\n");
		goto err_cleanup;
	}

	/* probe GCU */
	value = malidp_read32(d71->gcu_addr, GLB_CORE_INFO);
	d71->num_blocks = value & 0xFF;
	d71->num_pipelines = (value >> 8) & 0x7;

	if (d71->num_pipelines > D71_MAX_PIPELINE) {
		DRM_ERROR("d71 supports %d pipelines, but got: %d.\n",
			  D71_MAX_PIPELINE, d71->num_pipelines);
		err = -EINVAL;
		goto err_cleanup;
	}

	/* Only the legacy HW has the periph block, the newer merges the periph
	 * into GCU
	 */
	value = malidp_read32(d71->periph_addr, BLK_BLOCK_INFO);
	if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH)
		d71->periph_addr = NULL;

	if (d71->periph_addr) {
		/* probe PERIPHERAL in legacy HW */
		value = malidp_read32(d71->periph_addr, PERIPH_CONFIGURATION_ID);

		d71->max_line_size	= value & PERIPH_MAX_LINE_SIZE ? 4096 : 2048;
		d71->max_vsize		= 4096;
		d71->num_rich_layers	= value & PERIPH_NUM_RICH_LAYERS ? 2 : 1;
		d71->supports_dual_link	= !!(value & PERIPH_SPLIT_EN);
		d71->integrates_tbu	= !!(value & PERIPH_TBU_EN);
	} else {
		value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID0);
		d71->max_line_size	= GCU_MAX_LINE_SIZE(value);
		d71->max_vsize		= GCU_MAX_NUM_LINES(value);

		value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID1);
		d71->num_rich_layers	= GCU_NUM_RICH_LAYERS(value);
		d71->supports_dual_link	= GCU_DISPLAY_SPLIT_EN(value);
		d71->integrates_tbu	= GCU_DISPLAY_TBU_EN(value);
	}

	for (i = 0; i < d71->num_pipelines; i++) {
		pipe = komeda_pipeline_add(mdev, sizeof(struct d71_pipeline),
					   &d71_pipeline_funcs);
		if (IS_ERR(pipe)) {
			err = PTR_ERR(pipe);
			goto err_cleanup;
		}

		/* D71 HW doesn't update shadow registers when display output
		 * is turning off, so when we disable all pipeline components
		 * together with display output disable by one flush or one
		 * operation, the disable operation updated registers will not
		 * be flush to or valid in HW, which may leads problem.
		 * To workaround this problem, introduce a two phase disable.
		 * Phase1: Disabling components with display is on to make sure
		 *	   the disable can be flushed to HW.
		 * Phase2: Only turn-off display output.
		 */
		value = KOMEDA_PIPELINE_IMPROCS |
			BIT(KOMEDA_COMPONENT_TIMING_CTRLR);

		pipe->standalone_disabled_comps = value;

		d71->pipes[i] = to_d71_pipeline(pipe);
	}

	/* loop the register blks and probe.
	 * NOTE: d71->num_blocks includes reserved blocks.
	 * d71->num_blocks = GCU + valid blocks + reserved blocks
	 */
	i = 1; /* exclude GCU */
	offset = D71_BLOCK_SIZE; /* skip GCU */
	while (i < d71->num_blocks) {
		blk_base = mdev->reg_base + (offset >> 2);

		d71_read_block_header(blk_base, &blk);
		if (BLOCK_INFO_BLK_TYPE(blk.block_info) != D71_BLK_TYPE_RESERVED) {
			err = d71_probe_block(d71, &blk, blk_base);
			if (err)
				goto err_cleanup;
		}

		i++;
		offset += D71_BLOCK_SIZE;
	}

	DRM_DEBUG("total %d (out of %d) blocks are found.\n",
		  i, d71->num_blocks);

	return 0;

err_cleanup:
	d71_cleanup(mdev);
	return err;
}

#define __HW_ID(__group, __format) \
	((((__group) & 0x7) << 3) | ((__format) & 0x7))

#define RICH		KOMEDA_FMT_RICH_LAYER
#define SIMPLE		KOMEDA_FMT_SIMPLE_LAYER
#define RICH_SIMPLE	(KOMEDA_FMT_RICH_LAYER | KOMEDA_FMT_SIMPLE_LAYER)
#define RICH_WB		(KOMEDA_FMT_RICH_LAYER | KOMEDA_FMT_WB_LAYER)
#define RICH_SIMPLE_WB	(RICH_SIMPLE | KOMEDA_FMT_WB_LAYER)

#define Rot_0		DRM_MODE_ROTATE_0
#define Flip_H_V	(DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y | Rot_0)
#define Rot_ALL_H_V	(DRM_MODE_ROTATE_MASK | Flip_H_V)

#define LYT_NM		BIT(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16)
#define LYT_WB		BIT(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8)
#define LYT_NM_WB	(LYT_NM | LYT_WB)

#define AFB_TH		AFBC(_TILED | _SPARSE)
#define AFB_TH_SC_YTR	AFBC(_TILED | _SC | _SPARSE | _YTR)
#define AFB_TH_SC_YTR_BS AFBC(_TILED | _SC | _SPARSE | _YTR | _SPLIT)

static struct komeda_format_caps d71_format_caps_table[] = {
	/*   HW_ID    |        fourcc         |   layer_types |   rots    | afbc_layouts | afbc_features */
	/* ABGR_2101010*/
	{__HW_ID(0, 0),	DRM_FORMAT_ARGB2101010,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(0, 1),	DRM_FORMAT_ABGR2101010,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(0, 1),	DRM_FORMAT_ABGR2101010,	RICH_SIMPLE,	Rot_ALL_H_V,	LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
	{__HW_ID(0, 2),	DRM_FORMAT_RGBA1010102,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(0, 3),	DRM_FORMAT_BGRA1010102,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	/* ABGR_8888*/
	{__HW_ID(1, 0),	DRM_FORMAT_ARGB8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(1, 1),	DRM_FORMAT_ABGR8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(1, 1),	DRM_FORMAT_ABGR8888,	RICH_SIMPLE,	Rot_ALL_H_V,	LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
	{__HW_ID(1, 2),	DRM_FORMAT_RGBA8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(1, 3),	DRM_FORMAT_BGRA8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	/* XBGB_8888 */
	{__HW_ID(2, 0),	DRM_FORMAT_XRGB8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(2, 1),	DRM_FORMAT_XBGR8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(2, 2),	DRM_FORMAT_RGBX8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	{__HW_ID(2, 3),	DRM_FORMAT_BGRX8888,	RICH_SIMPLE_WB,	Flip_H_V,		0, 0},
	/* BGR_888 */ /* none-afbc RGB888 doesn't support rotation and flip */
	{__HW_ID(3, 0),	DRM_FORMAT_RGB888,	RICH_SIMPLE_WB,	Rot_0,			0, 0},
	{__HW_ID(3, 1),	DRM_FORMAT_BGR888,	RICH_SIMPLE_WB,	Rot_0,			0, 0},
	{__HW_ID(3, 1),	DRM_FORMAT_BGR888,	RICH_SIMPLE,	Rot_ALL_H_V,	LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
	/* BGR 16bpp */
	{__HW_ID(4, 0),	DRM_FORMAT_RGBA5551,	RICH_SIMPLE,	Flip_H_V,		0, 0},
	{__HW_ID(4, 1),	DRM_FORMAT_ABGR1555,	RICH_SIMPLE,	Flip_H_V,		0, 0},
	{__HW_ID(4, 1),	DRM_FORMAT_ABGR1555,	RICH_SIMPLE,	Rot_ALL_H_V,	LYT_NM_WB, AFB_TH_SC_YTR}, /* afbc */
	{__HW_ID(4, 2),	DRM_FORMAT_RGB565,	RICH_SIMPLE,	Flip_H_V,		0, 0},
	{__HW_ID(4, 3),	DRM_FORMAT_BGR565,	RICH_SIMPLE,	Flip_H_V,		0, 0},
	{__HW_ID(4, 3),	DRM_FORMAT_BGR565,	RICH_SIMPLE,	Rot_ALL_H_V,	LYT_NM_WB, AFB_TH_SC_YTR}, /* afbc */
	{__HW_ID(4, 4), DRM_FORMAT_R8,		SIMPLE,		Rot_0,			0, 0},
	/* YUV 444/422/420 8bit  */
	{__HW_ID(5, 1),	DRM_FORMAT_YUYV,	RICH,		Rot_ALL_H_V,	LYT_NM, AFB_TH}, /* afbc */
	{__HW_ID(5, 2),	DRM_FORMAT_YUYV,	RICH,		Flip_H_V,		0, 0},
	{__HW_ID(5, 3),	DRM_FORMAT_UYVY,	RICH,		Flip_H_V,		0, 0},
	{__HW_ID(5, 6),	DRM_FORMAT_NV12,	RICH,		Flip_H_V,		0, 0},
	{__HW_ID(5, 6),	DRM_FORMAT_YUV420_8BIT,	RICH,		Rot_ALL_H_V,	LYT_NM, AFB_TH}, /* afbc */
	{__HW_ID(5, 7),	DRM_FORMAT_YUV420,	RICH,		Flip_H_V,		0, 0},
	/* YUV 10bit*/
	{__HW_ID(6, 6),	DRM_FORMAT_X0L2,	RICH,		Flip_H_V,		0, 0},
	{__HW_ID(6, 7),	DRM_FORMAT_P010,	RICH,		Flip_H_V,		0, 0},
	{__HW_ID(6, 7),	DRM_FORMAT_YUV420_10BIT, RICH,		Rot_ALL_H_V,	LYT_NM, AFB_TH},
};

static bool d71_format_mod_supported(const struct komeda_format_caps *caps,
				     u32 layer_type, u64 modifier, u32 rot)
{
	uint64_t layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;

	if ((layout == AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) &&
	    drm_rotation_90_or_270(rot)) {
		DRM_DEBUG_ATOMIC("D71 doesn't support ROT90 for WB-AFBC.\n");
		return false;
	}

	return true;
}

static void d71_init_fmt_tbl(struct komeda_dev *mdev)
{
	struct komeda_format_caps_table *table = &mdev->fmt_tbl;

	table->format_caps = d71_format_caps_table;
	table->format_mod_supported = d71_format_mod_supported;
	table->n_formats = ARRAY_SIZE(d71_format_caps_table);
}

static int d71_connect_iommu(struct komeda_dev *mdev)
{
	struct d71_dev *d71 = mdev->chip_data;
	u32 __iomem *reg = d71->gcu_addr;
	u32 check_bits = (d71->num_pipelines == 2) ?
			 GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
	int i, ret;

	if (!d71->integrates_tbu)
		return -1;

	malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);

	ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
			100, 1000, 1000);
	if (ret < 0) {
		DRM_ERROR("timed out connecting to TCU!\n");
		malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
		return ret;
	}

	for (i = 0; i < d71->num_pipelines; i++)
		malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
				    LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
	return 0;
}

static int d71_disconnect_iommu(struct komeda_dev *mdev)
{
	struct d71_dev *d71 = mdev->chip_data;
	u32 __iomem *reg = d71->gcu_addr;
	u32 check_bits = (d71->num_pipelines == 2) ?
			 GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
	int ret;

	malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);

	ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
			100, 1000, 1000);
	if (ret < 0) {
		DRM_ERROR("timed out disconnecting from TCU!\n");
		malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
	}

	return ret;
}

static const struct komeda_dev_funcs d71_chip_funcs = {
	.init_format_table	= d71_init_fmt_tbl,
	.enum_resources		= d71_enum_resources,
	.cleanup		= d71_cleanup,
	.irq_handler		= d71_irq_handler,
	.enable_irq		= d71_enable_irq,
	.disable_irq		= d71_disable_irq,
	.on_off_vblank		= d71_on_off_vblank,
	.change_opmode		= d71_change_opmode,
	.flush			= d71_flush,
	.connect_iommu		= d71_connect_iommu,
	.disconnect_iommu	= d71_disconnect_iommu,
	.dump_register		= d71_dump,
};

const struct komeda_dev_funcs *
d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
{
	const struct komeda_dev_funcs *funcs;
	u32 product_id;

	chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);

	product_id = MALIDP_CORE_ID_PRODUCT_ID(chip->core_id);

	switch (product_id) {
	case MALIDP_D71_PRODUCT_ID:
	case MALIDP_D32_PRODUCT_ID:
		funcs = &d71_chip_funcs;
		break;
	default:
		DRM_ERROR("Unsupported product: 0x%x\n", product_id);
		return NULL;
	}

	chip->arch_id	= malidp_read32(reg_base, GLB_ARCH_ID);
	chip->core_info	= malidp_read32(reg_base, GLB_CORE_INFO);
	chip->bus_width	= D71_BUS_WIDTH_16_BYTES;

	return funcs;
}
