/*
 * Copyright 2016 Linaro Ltd.
 * Copyright 2016 ZTE Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#include <linux/clk.h>
#include <linux/component.h>
#include <linux/of_address.h>
#include <video/videomode.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_gem_cma_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_plane_helper.h>
#include <drm/drmP.h>

#include "zx_drm_drv.h"
#include "zx_plane.h"
#include "zx_vou.h"
#include "zx_vou_regs.h"

#define GL_NUM	2
#define VL_NUM	3

enum vou_chn_type {
	VOU_CHN_MAIN,
	VOU_CHN_AUX,
};

struct zx_crtc_regs {
	u32 fir_active;
	u32 fir_htiming;
	u32 fir_vtiming;
	u32 sec_vtiming;
	u32 timing_shift;
	u32 timing_pi_shift;
};

static const struct zx_crtc_regs main_crtc_regs = {
	.fir_active = FIR_MAIN_ACTIVE,
	.fir_htiming = FIR_MAIN_H_TIMING,
	.fir_vtiming = FIR_MAIN_V_TIMING,
	.sec_vtiming = SEC_MAIN_V_TIMING,
	.timing_shift = TIMING_MAIN_SHIFT,
	.timing_pi_shift = TIMING_MAIN_PI_SHIFT,
};

static const struct zx_crtc_regs aux_crtc_regs = {
	.fir_active = FIR_AUX_ACTIVE,
	.fir_htiming = FIR_AUX_H_TIMING,
	.fir_vtiming = FIR_AUX_V_TIMING,
	.sec_vtiming = SEC_AUX_V_TIMING,
	.timing_shift = TIMING_AUX_SHIFT,
	.timing_pi_shift = TIMING_AUX_PI_SHIFT,
};

struct zx_crtc_bits {
	u32 polarity_mask;
	u32 polarity_shift;
	u32 int_frame_mask;
	u32 tc_enable;
	u32 sec_vactive_shift;
	u32 sec_vactive_mask;
	u32 interlace_select;
	u32 pi_enable;
	u32 div_vga_shift;
	u32 div_pic_shift;
	u32 div_tvenc_shift;
	u32 div_hdmi_pnx_shift;
	u32 div_hdmi_shift;
	u32 div_inf_shift;
	u32 div_layer_shift;
};

static const struct zx_crtc_bits main_crtc_bits = {
	.polarity_mask = MAIN_POL_MASK,
	.polarity_shift = MAIN_POL_SHIFT,
	.int_frame_mask = TIMING_INT_MAIN_FRAME,
	.tc_enable = MAIN_TC_EN,
	.sec_vactive_shift = SEC_VACT_MAIN_SHIFT,
	.sec_vactive_mask = SEC_VACT_MAIN_MASK,
	.interlace_select = MAIN_INTERLACE_SEL,
	.pi_enable = MAIN_PI_EN,
	.div_vga_shift = VGA_MAIN_DIV_SHIFT,
	.div_pic_shift = PIC_MAIN_DIV_SHIFT,
	.div_tvenc_shift = TVENC_MAIN_DIV_SHIFT,
	.div_hdmi_pnx_shift = HDMI_MAIN_PNX_DIV_SHIFT,
	.div_hdmi_shift = HDMI_MAIN_DIV_SHIFT,
	.div_inf_shift = INF_MAIN_DIV_SHIFT,
	.div_layer_shift = LAYER_MAIN_DIV_SHIFT,
};

static const struct zx_crtc_bits aux_crtc_bits = {
	.polarity_mask = AUX_POL_MASK,
	.polarity_shift = AUX_POL_SHIFT,
	.int_frame_mask = TIMING_INT_AUX_FRAME,
	.tc_enable = AUX_TC_EN,
	.sec_vactive_shift = SEC_VACT_AUX_SHIFT,
	.sec_vactive_mask = SEC_VACT_AUX_MASK,
	.interlace_select = AUX_INTERLACE_SEL,
	.pi_enable = AUX_PI_EN,
	.div_vga_shift = VGA_AUX_DIV_SHIFT,
	.div_pic_shift = PIC_AUX_DIV_SHIFT,
	.div_tvenc_shift = TVENC_AUX_DIV_SHIFT,
	.div_hdmi_pnx_shift = HDMI_AUX_PNX_DIV_SHIFT,
	.div_hdmi_shift = HDMI_AUX_DIV_SHIFT,
	.div_inf_shift = INF_AUX_DIV_SHIFT,
	.div_layer_shift = LAYER_AUX_DIV_SHIFT,
};

struct zx_crtc {
	struct drm_crtc crtc;
	struct drm_plane *primary;
	struct zx_vou_hw *vou;
	void __iomem *chnreg;
	const struct zx_crtc_regs *regs;
	const struct zx_crtc_bits *bits;
	enum vou_chn_type chn_type;
	struct clk *pixclk;
};

#define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)

struct vou_layer_bits {
	u32 enable;
	u32 chnsel;
	u32 clksel;
};

static const struct vou_layer_bits zx_gl_bits[GL_NUM] = {
	{
		.enable = OSD_CTRL0_GL0_EN,
		.chnsel = OSD_CTRL0_GL0_SEL,
		.clksel = VOU_CLK_GL0_SEL,
	}, {
		.enable = OSD_CTRL0_GL1_EN,
		.chnsel = OSD_CTRL0_GL1_SEL,
		.clksel = VOU_CLK_GL1_SEL,
	},
};

static const struct vou_layer_bits zx_vl_bits[VL_NUM] = {
	{
		.enable = OSD_CTRL0_VL0_EN,
		.chnsel = OSD_CTRL0_VL0_SEL,
		.clksel = VOU_CLK_VL0_SEL,
	}, {
		.enable = OSD_CTRL0_VL1_EN,
		.chnsel = OSD_CTRL0_VL1_SEL,
		.clksel = VOU_CLK_VL1_SEL,
	}, {
		.enable = OSD_CTRL0_VL2_EN,
		.chnsel = OSD_CTRL0_VL2_SEL,
		.clksel = VOU_CLK_VL2_SEL,
	},
};

struct zx_vou_hw {
	struct device *dev;
	void __iomem *osd;
	void __iomem *timing;
	void __iomem *vouctl;
	void __iomem *otfppu;
	void __iomem *dtrc;
	struct clk *axi_clk;
	struct clk *ppu_clk;
	struct clk *main_clk;
	struct clk *aux_clk;
	struct zx_crtc *main_crtc;
	struct zx_crtc *aux_crtc;
};

enum vou_inf_data_sel {
	VOU_YUV444	= 0,
	VOU_RGB_101010	= 1,
	VOU_RGB_888	= 2,
	VOU_RGB_666	= 3,
};

struct vou_inf {
	enum vou_inf_id id;
	enum vou_inf_data_sel data_sel;
	u32 clocks_en_bits;
	u32 clocks_sel_bits;
};

static struct vou_inf vou_infs[] = {
	[VOU_HDMI] = {
		.data_sel = VOU_YUV444,
		.clocks_en_bits = BIT(24) | BIT(18) | BIT(6),
		.clocks_sel_bits = BIT(13) | BIT(2),
	},
	[VOU_TV_ENC] = {
		.data_sel = VOU_YUV444,
		.clocks_en_bits = BIT(15),
		.clocks_sel_bits = BIT(11) | BIT(0),
	},
};

static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
{
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);

	return zcrtc->vou;
}

void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc,
			    enum vou_inf_hdmi_audio aud)
{
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
	struct zx_vou_hw *vou = zcrtc->vou;

	zx_writel_mask(vou->vouctl + VOU_INF_HDMI_CTRL, VOU_HDMI_AUD_MASK, aud);
}

void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc)
{
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
	struct zx_vou_hw *vou = zcrtc->vou;
	struct vou_inf *inf = &vou_infs[id];
	bool is_main = zcrtc->chn_type == VOU_CHN_MAIN;
	u32 data_sel_shift = id << 1;

	/* Select data format */
	zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift,
		       inf->data_sel << data_sel_shift);

	/* Select channel */
	zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << id,
		       zcrtc->chn_type << id);

	/* Select interface clocks */
	zx_writel_mask(vou->vouctl + VOU_CLK_SEL, inf->clocks_sel_bits,
		       is_main ? 0 : inf->clocks_sel_bits);

	/* Enable interface clocks */
	zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits,
		       inf->clocks_en_bits);

	/* Enable the device */
	zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 1 << id);
}

void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc)
{
	struct zx_vou_hw *vou = crtc_to_vou(crtc);
	struct vou_inf *inf = &vou_infs[id];

	/* Disable the device */
	zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 0);

	/* Disable interface clocks */
	zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0);
}

void zx_vou_config_dividers(struct drm_crtc *crtc,
			    struct vou_div_config *configs, int num)
{
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
	struct zx_vou_hw *vou = zcrtc->vou;
	const struct zx_crtc_bits *bits = zcrtc->bits;
	int i;

	/* Clear update flag bit */
	zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0);

	for (i = 0; i < num; i++) {
		struct vou_div_config *cfg = configs + i;
		u32 reg, shift;

		switch (cfg->id) {
		case VOU_DIV_VGA:
			reg = VOU_CLK_SEL;
			shift = bits->div_vga_shift;
			break;
		case VOU_DIV_PIC:
			reg = VOU_CLK_SEL;
			shift = bits->div_pic_shift;
			break;
		case VOU_DIV_TVENC:
			reg = VOU_DIV_PARA;
			shift = bits->div_tvenc_shift;
			break;
		case VOU_DIV_HDMI_PNX:
			reg = VOU_DIV_PARA;
			shift = bits->div_hdmi_pnx_shift;
			break;
		case VOU_DIV_HDMI:
			reg = VOU_DIV_PARA;
			shift = bits->div_hdmi_shift;
			break;
		case VOU_DIV_INF:
			reg = VOU_DIV_PARA;
			shift = bits->div_inf_shift;
			break;
		case VOU_DIV_LAYER:
			reg = VOU_DIV_PARA;
			shift = bits->div_layer_shift;
			break;
		default:
			continue;
		}

		/* Each divider occupies 3 bits */
		zx_writel_mask(vou->vouctl + reg, 0x7 << shift,
			       cfg->val << shift);
	}

	/* Set update flag bit to get dividers effected */
	zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE,
		       DIV_PARA_UPDATE);
}

static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
{
	zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
}

static void zx_crtc_enable(struct drm_crtc *crtc)
{
	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
	bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
	struct zx_vou_hw *vou = zcrtc->vou;
	const struct zx_crtc_regs *regs = zcrtc->regs;
	const struct zx_crtc_bits *bits = zcrtc->bits;
	struct videomode vm;
	u32 scan_mask;
	u32 pol = 0;
	u32 val;
	int ret;

	drm_display_mode_to_videomode(mode, &vm);

	/* Set up timing parameters */
	val = V_ACTIVE((interlaced ? vm.vactive / 2 : vm.vactive) - 1);
	val |= H_ACTIVE(vm.hactive - 1);
	zx_writel(vou->timing + regs->fir_active, val);

	val = SYNC_WIDE(vm.hsync_len - 1);
	val |= BACK_PORCH(vm.hback_porch - 1);
	val |= FRONT_PORCH(vm.hfront_porch - 1);
	zx_writel(vou->timing + regs->fir_htiming, val);

	val = SYNC_WIDE(vm.vsync_len - 1);
	val |= BACK_PORCH(vm.vback_porch - 1);
	val |= FRONT_PORCH(vm.vfront_porch - 1);
	zx_writel(vou->timing + regs->fir_vtiming, val);

	if (interlaced) {
		u32 shift = bits->sec_vactive_shift;
		u32 mask = bits->sec_vactive_mask;

		val = zx_readl(vou->timing + SEC_V_ACTIVE);
		val &= ~mask;
		val |= ((vm.vactive / 2 - 1) << shift) & mask;
		zx_writel(vou->timing + SEC_V_ACTIVE, val);

		val = SYNC_WIDE(vm.vsync_len - 1);
		/*
		 * The vback_porch for the second field needs to shift one on
		 * the value for the first field.
		 */
		val |= BACK_PORCH(vm.vback_porch);
		val |= FRONT_PORCH(vm.vfront_porch - 1);
		zx_writel(vou->timing + regs->sec_vtiming, val);
	}

	/* Set up polarities */
	if (vm.flags & DISPLAY_FLAGS_VSYNC_LOW)
		pol |= 1 << POL_VSYNC_SHIFT;
	if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW)
		pol |= 1 << POL_HSYNC_SHIFT;

	zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask,
		       pol << bits->polarity_shift);

	/* Setup SHIFT register by following what ZTE BSP does */
	val = H_SHIFT_VAL;
	if (interlaced)
		val |= V_SHIFT_VAL << 16;
	zx_writel(vou->timing + regs->timing_shift, val);
	zx_writel(vou->timing + regs->timing_pi_shift, H_PI_SHIFT_VAL);

	/* Progressive or interlace scan select */
	scan_mask = bits->interlace_select | bits->pi_enable;
	zx_writel_mask(vou->timing + SCAN_CTRL, scan_mask,
		       interlaced ? scan_mask : 0);

	/* Enable TIMING_CTRL */
	zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable,
		       bits->tc_enable);

	/* Configure channel screen size */
	zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_W_MASK,
		       vm.hactive << CHN_SCREEN_W_SHIFT);
	zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_H_MASK,
		       vm.vactive << CHN_SCREEN_H_SHIFT);

	/* Configure channel interlace buffer control */
	zx_writel_mask(zcrtc->chnreg + CHN_INTERLACE_BUF_CTRL, CHN_INTERLACE_EN,
		       interlaced ? CHN_INTERLACE_EN : 0);

	/* Update channel */
	vou_chn_set_update(zcrtc);

	/* Enable channel */
	zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);

	drm_crtc_vblank_on(crtc);

	ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
	if (ret) {
		DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret);
		return;
	}

	ret = clk_prepare_enable(zcrtc->pixclk);
	if (ret)
		DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
}

static void zx_crtc_disable(struct drm_crtc *crtc)
{
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
	const struct zx_crtc_bits *bits = zcrtc->bits;
	struct zx_vou_hw *vou = zcrtc->vou;

	clk_disable_unprepare(zcrtc->pixclk);

	drm_crtc_vblank_off(crtc);

	/* Disable channel */
	zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);

	/* Disable TIMING_CTRL */
	zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0);
}

static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
				  struct drm_crtc_state *old_state)
{
	struct drm_pending_vblank_event *event = crtc->state->event;

	if (!event)
		return;

	crtc->state->event = NULL;

	spin_lock_irq(&crtc->dev->event_lock);
	if (drm_crtc_vblank_get(crtc) == 0)
		drm_crtc_arm_vblank_event(crtc, event);
	else
		drm_crtc_send_vblank_event(crtc, event);
	spin_unlock_irq(&crtc->dev->event_lock);
}

static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = {
	.enable = zx_crtc_enable,
	.disable = zx_crtc_disable,
	.atomic_flush = zx_crtc_atomic_flush,
};

static int zx_vou_enable_vblank(struct drm_crtc *crtc)
{
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
	struct zx_vou_hw *vou = crtc_to_vou(crtc);
	u32 int_frame_mask = zcrtc->bits->int_frame_mask;

	zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask,
		       int_frame_mask);

	return 0;
}

static void zx_vou_disable_vblank(struct drm_crtc *crtc)
{
	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
	struct zx_vou_hw *vou = crtc_to_vou(crtc);

	zx_writel_mask(vou->timing + TIMING_INT_CTRL,
		       zcrtc->bits->int_frame_mask, 0);
}

static const struct drm_crtc_funcs zx_crtc_funcs = {
	.destroy = drm_crtc_cleanup,
	.set_config = drm_atomic_helper_set_config,
	.page_flip = drm_atomic_helper_page_flip,
	.reset = drm_atomic_helper_crtc_reset,
	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
	.enable_vblank = zx_vou_enable_vblank,
	.disable_vblank = zx_vou_disable_vblank,
};

static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
			enum vou_chn_type chn_type)
{
	struct device *dev = vou->dev;
	struct zx_plane *zplane;
	struct zx_crtc *zcrtc;
	int ret;

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

	zcrtc->vou = vou;
	zcrtc->chn_type = chn_type;

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

	zplane->dev = dev;

	if (chn_type == VOU_CHN_MAIN) {
		zplane->layer = vou->osd + MAIN_GL_OFFSET;
		zplane->csc = vou->osd + MAIN_CSC_OFFSET;
		zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
		zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
		zplane->bits = &zx_gl_bits[0];
		zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
		zcrtc->regs = &main_crtc_regs;
		zcrtc->bits = &main_crtc_bits;
	} else {
		zplane->layer = vou->osd + AUX_GL_OFFSET;
		zplane->csc = vou->osd + AUX_CSC_OFFSET;
		zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
		zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
		zplane->bits = &zx_gl_bits[1];
		zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
		zcrtc->regs = &aux_crtc_regs;
		zcrtc->bits = &aux_crtc_bits;
	}

	zcrtc->pixclk = devm_clk_get(dev, (chn_type == VOU_CHN_MAIN) ?
					  "main_wclk" : "aux_wclk");
	if (IS_ERR(zcrtc->pixclk)) {
		ret = PTR_ERR(zcrtc->pixclk);
		DRM_DEV_ERROR(dev, "failed to get pix clk: %d\n", ret);
		return ret;
	}

	ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret);
		return ret;
	}

	zcrtc->primary = &zplane->plane;

	ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL,
					&zx_crtc_funcs, NULL);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret);
		return ret;
	}

	drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs);

	if (chn_type == VOU_CHN_MAIN)
		vou->main_crtc = zcrtc;
	else
		vou->aux_crtc = zcrtc;

	return 0;
}

void zx_vou_layer_enable(struct drm_plane *plane)
{
	struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc);
	struct zx_vou_hw *vou = zcrtc->vou;
	struct zx_plane *zplane = to_zx_plane(plane);
	const struct vou_layer_bits *bits = zplane->bits;

	if (zcrtc->chn_type == VOU_CHN_MAIN) {
		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0);
		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0);
	} else {
		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
			       bits->chnsel);
		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
			       bits->clksel);
	}

	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
}

void zx_vou_layer_disable(struct drm_plane *plane)
{
	struct zx_crtc *zcrtc = to_zx_crtc(plane->crtc);
	struct zx_vou_hw *vou = zcrtc->vou;
	struct zx_plane *zplane = to_zx_plane(plane);
	const struct vou_layer_bits *bits = zplane->bits;

	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
}

static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou)
{
	struct device *dev = vou->dev;
	struct zx_plane *zplane;
	int i;
	int ret;

	/*
	 * VL0 has some quirks on scaling support which need special handling.
	 * Let's leave it out for now.
	 */
	for (i = 1; i < VL_NUM; i++) {
		zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
		if (!zplane) {
			DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i);
			return;
		}

		zplane->layer = vou->osd + OSD_VL_OFFSET(i);
		zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i);
		zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i);
		zplane->bits = &zx_vl_bits[i];

		ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY);
		if (ret) {
			DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i);
			continue;
		}
	}
}

static inline void zx_osd_int_update(struct zx_crtc *zcrtc)
{
	struct drm_crtc *crtc = &zcrtc->crtc;
	struct drm_plane *plane;

	vou_chn_set_update(zcrtc);

	drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask)
		zx_plane_set_update(plane);
}

static irqreturn_t vou_irq_handler(int irq, void *dev_id)
{
	struct zx_vou_hw *vou = dev_id;
	u32 state;

	/* Handle TIMING_CTRL frame interrupts */
	state = zx_readl(vou->timing + TIMING_INT_STATE);
	zx_writel(vou->timing + TIMING_INT_STATE, state);

	if (state & TIMING_INT_MAIN_FRAME)
		drm_crtc_handle_vblank(&vou->main_crtc->crtc);

	if (state & TIMING_INT_AUX_FRAME)
		drm_crtc_handle_vblank(&vou->aux_crtc->crtc);

	/* Handle OSD interrupts */
	state = zx_readl(vou->osd + OSD_INT_STA);
	zx_writel(vou->osd + OSD_INT_CLRSTA, state);

	if (state & OSD_INT_MAIN_UPT)
		zx_osd_int_update(vou->main_crtc);

	if (state & OSD_INT_AUX_UPT)
		zx_osd_int_update(vou->aux_crtc);

	if (state & OSD_INT_ERROR)
		DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);

	return IRQ_HANDLED;
}

static void vou_dtrc_init(struct zx_vou_hw *vou)
{
	/* Clear bit for bypass by ID */
	zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL,
		       TILE2RASTESCAN_BYPASS_MODE, 0);

	/* Select ARIDR mode */
	zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK,
		       DETILE_ARID_IN_ARIDR);

	/* Bypass decompression for both frames */
	zx_writel_mask(vou->dtrc + DTRC_F0_CTRL, DTRC_DECOMPRESS_BYPASS,
		       DTRC_DECOMPRESS_BYPASS);
	zx_writel_mask(vou->dtrc + DTRC_F1_CTRL, DTRC_DECOMPRESS_BYPASS,
		       DTRC_DECOMPRESS_BYPASS);

	/* Set up ARID register */
	zx_writel(vou->dtrc + DTRC_ARID, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) |
		  DTRC_ARID1(0xf) | DTRC_ARID0(0xe));
}

static void vou_hw_init(struct zx_vou_hw *vou)
{
	/* Release reset for all VOU modules */
	zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);

	/* Enable clock auto-gating for all VOU modules */
	zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0);

	/* Enable all VOU module clocks */
	zx_writel(vou->vouctl + VOU_CLK_EN, ~0);

	/* Clear both OSD and TIMING_CTRL interrupt state */
	zx_writel(vou->osd + OSD_INT_CLRSTA, ~0);
	zx_writel(vou->timing + TIMING_INT_STATE, ~0);

	/* Enable OSD and TIMING_CTRL interrrupts */
	zx_writel(vou->osd + OSD_INT_MSK, OSD_INT_ENABLE);
	zx_writel(vou->timing + TIMING_INT_CTRL, TIMING_INT_ENABLE);

	/* Select GPC as input to gl/vl scaler as a sane default setting */
	zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a);

	/*
	 * Needs to reset channel and layer logic per frame when frame starts
	 * to get VOU work properly.
	 */
	zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME);

	vou_dtrc_init(vou);
}

static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct drm_device *drm = data;
	struct zx_vou_hw *vou;
	struct resource *res;
	int irq;
	int ret;

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

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd");
	vou->osd = devm_ioremap_resource(dev, res);
	if (IS_ERR(vou->osd)) {
		ret = PTR_ERR(vou->osd);
		DRM_DEV_ERROR(dev, "failed to remap osd region: %d\n", ret);
		return ret;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl");
	vou->timing = devm_ioremap_resource(dev, res);
	if (IS_ERR(vou->timing)) {
		ret = PTR_ERR(vou->timing);
		DRM_DEV_ERROR(dev, "failed to remap timing_ctrl region: %d\n",
			      ret);
		return ret;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc");
	vou->dtrc = devm_ioremap_resource(dev, res);
	if (IS_ERR(vou->dtrc)) {
		ret = PTR_ERR(vou->dtrc);
		DRM_DEV_ERROR(dev, "failed to remap dtrc region: %d\n", ret);
		return ret;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl");
	vou->vouctl = devm_ioremap_resource(dev, res);
	if (IS_ERR(vou->vouctl)) {
		ret = PTR_ERR(vou->vouctl);
		DRM_DEV_ERROR(dev, "failed to remap vou_ctrl region: %d\n",
			      ret);
		return ret;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu");
	vou->otfppu = devm_ioremap_resource(dev, res);
	if (IS_ERR(vou->otfppu)) {
		ret = PTR_ERR(vou->otfppu);
		DRM_DEV_ERROR(dev, "failed to remap otfppu region: %d\n", ret);
		return ret;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	vou->axi_clk = devm_clk_get(dev, "aclk");
	if (IS_ERR(vou->axi_clk)) {
		ret = PTR_ERR(vou->axi_clk);
		DRM_DEV_ERROR(dev, "failed to get axi_clk: %d\n", ret);
		return ret;
	}

	vou->ppu_clk = devm_clk_get(dev, "ppu_wclk");
	if (IS_ERR(vou->ppu_clk)) {
		ret = PTR_ERR(vou->ppu_clk);
		DRM_DEV_ERROR(dev, "failed to get ppu_clk: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(vou->axi_clk);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret);
		return ret;
	}

	clk_prepare_enable(vou->ppu_clk);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret);
		goto disable_axi_clk;
	}

	vou->dev = dev;
	dev_set_drvdata(dev, vou);

	vou_hw_init(vou);

	ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou);
	if (ret < 0) {
		DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret);
		goto disable_ppu_clk;
	}

	ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n",
			      ret);
		goto disable_ppu_clk;
	}

	ret = zx_crtc_init(drm, vou, VOU_CHN_AUX);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n",
			      ret);
		goto disable_ppu_clk;
	}

	zx_overlay_init(drm, vou);

	return 0;

disable_ppu_clk:
	clk_disable_unprepare(vou->ppu_clk);
disable_axi_clk:
	clk_disable_unprepare(vou->axi_clk);
	return ret;
}

static void zx_crtc_unbind(struct device *dev, struct device *master,
			   void *data)
{
	struct zx_vou_hw *vou = dev_get_drvdata(dev);

	clk_disable_unprepare(vou->axi_clk);
	clk_disable_unprepare(vou->ppu_clk);
}

static const struct component_ops zx_crtc_component_ops = {
	.bind = zx_crtc_bind,
	.unbind = zx_crtc_unbind,
};

static int zx_crtc_probe(struct platform_device *pdev)
{
	return component_add(&pdev->dev, &zx_crtc_component_ops);
}

static int zx_crtc_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &zx_crtc_component_ops);
	return 0;
}

static const struct of_device_id zx_crtc_of_match[] = {
	{ .compatible = "zte,zx296718-dpc", },
	{ /* end */ },
};
MODULE_DEVICE_TABLE(of, zx_crtc_of_match);

struct platform_driver zx_crtc_driver = {
	.probe = zx_crtc_probe,
	.remove = zx_crtc_remove,
	.driver	= {
		.name = "zx-crtc",
		.of_match_table	= zx_crtc_of_match,
	},
};
