/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017-2019 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 <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <soc/imx8/sc/sci.h>
#include <video/dpu.h>
#include "dpu-prv.h"

#define FGSTCTRL		0x8
#define FGSYNCMODE_MASK		0x6
#define HTCFG1			0xC
#define HTOTAL(n)		((((n) - 1) & 0x3FFF) << 16)
#define HACT(n)			((n) & 0x3FFF)
#define HTCFG2			0x10
#define HSEN			BIT(31)
#define HSBP(n)			((((n) - 1) & 0x3FFF) << 16)
#define HSYNC(n)		(((n) - 1) & 0x3FFF)
#define VTCFG1			0x14
#define VTOTAL(n)		((((n) - 1) & 0x3FFF) << 16)
#define VACT(n)			((n) & 0x3FFF)
#define VTCFG2			0x18
#define VSEN			BIT(31)
#define VSBP(n)			((((n) - 1) & 0x3FFF) << 16)
#define VSYNC(n)		(((n) - 1) & 0x3FFF)
#define INTCONFIG(n)		(0x1C + 4 * (n))
#define EN			BIT(31)
#define ROW(n)			(((n) & 0x3FFF) << 16)
#define COL(n)			((n) & 0x3FFF)
#define PKICKCONFIG		0x2C
#define SKICKCONFIG		0x30
#define SECSTATCONFIG		0x34
#define FGSRCR1			0x38
#define FGSRCR2			0x3C
#define FGSRCR3			0x40
#define FGSRCR4			0x44
#define FGSRCR5			0x48
#define FGSRCR6			0x4C
#define FGKSDR			0x50
#define PACFG			0x54
#define STARTX(n)		(((n) + 1) & 0x3FFF)
#define STARTY(n)		(((((n) + 1) & 0x3FFF)) << 16)
#define SACFG			0x58
#define FGINCTRL		0x5C
#define FGDM_MASK		0x7
#define ENPRIMALPHA		BIT(3)
#define ENSECALPHA		BIT(4)
#define FGINCTRLPANIC		0x60
#define FGCCR			0x64
#define CCALPHA(a)		(((a) & 0x1) << 30)
#define CCRED(r)		(((r) & 0x3FF) << 20)
#define CCGREEN(g)		(((g) & 0x3FF) << 10)
#define CCBLUE(b)		((b) & 0x3FF)
#define FGENABLE		0x68
#define FGEN			BIT(0)
#define FGSLR			0x6C
#define FGENSTS			0x70
#define ENSTS			BIT(0)
#define FGTIMESTAMP		0x74
#define LINEINDEX_MASK		0x3FFF
#define LINEINDEX_SHIFT		0
#define FRAMEINDEX_MASK		0xFFFFC000
#define FRAMEINDEX_SHIFT	14
#define FGCHSTAT		0x78
#define SECSYNCSTAT		BIT(24)
#define SFIFOEMPTY		BIT(16)
#define FGCHSTATCLR		0x7C
#define CLRSECSTAT		BIT(16)
#define FGSKEWMON		0x80
#define FGSFIFOMIN		0x84
#define FGSFIFOMAX		0x88
#define FGSFIFOFILLCLR		0x8C
#define FGSREPD			0x90
#define FGSRFTD			0x94

#define KHZ			1000
#define PLL_MIN_FREQ_HZ		648000000

struct dpu_framegen {
	void __iomem *base;
	struct clk *clk_pll;
	struct clk *clk_bypass;
	struct clk *clk_disp_sel;
	struct clk *clk_disp;
	struct mutex mutex;
	int id;
	bool inuse;
	bool use_bypass_clk;
	bool encoder_type_has_lvds;
	bool side_by_side;
	struct dpu_soc *dpu;
};

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

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

/* FIXME: enable pixel link in a proper manner */
static void dpu_pixel_link_enable(int dpu_id, int stream_id)
{
	sc_err_t sciErr;
	sc_ipc_t ipcHndl = 0;
	u32 mu_id;

	sciErr = sc_ipc_getMuID(&mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("Cannot obtain MU ID\n");
		return;
	}

	sciErr = sc_ipc_open(&ipcHndl, mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
		return;
	}

	if (dpu_id == 0) {
		sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
			stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 1);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
	} else if (dpu_id == 1) {
		sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
			stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 1);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
	}

	sc_ipc_close(mu_id);
}

/* FIXME: disable pixel link in a proper manner */
static void dpu_pixel_link_disable(int dpu_id, int stream_id)
{
	sc_err_t sciErr;
	sc_ipc_t ipcHndl = 0;
	u32 mu_id;

	sciErr = sc_ipc_getMuID(&mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("Cannot obtain MU ID\n");
		return;
	}

	sciErr = sc_ipc_open(&ipcHndl, mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
		return;
	}

	if (dpu_id == 0) {
		sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0,
			stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 0);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
	} else if (dpu_id == 1) {
		sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1,
			stream_id ? SC_C_PXL_LINK_MST2_ENB : SC_C_PXL_LINK_MST1_ENB, 0);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ENB sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
	}

	sc_ipc_close(mu_id);
}

/* FIXME: set MST address for pixel link in a proper manner */
static void dpu_pixel_link_set_mst_addr(int dpu_id, int stream_id, int mst_addr)
{
	sc_err_t sciErr;
	sc_ipc_t ipcHndl = 0;
	u32 mu_id;

	sciErr = sc_ipc_getMuID(&mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("Cannot obtain MU ID\n");
		return;
	}

	sciErr = sc_ipc_open(&ipcHndl, mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
		return;
	}

	if (dpu_id == 0) {
		sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_0, stream_id ?
			SC_C_PXL_LINK_MST2_ADDR : SC_C_PXL_LINK_MST1_ADDR,
								mst_addr);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_0:SC_C_PXL_LINK_MST%d_ADDR sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
	} else if (dpu_id == 1) {
		sciErr = sc_misc_set_control(ipcHndl, SC_R_DC_1, stream_id ?
			SC_C_PXL_LINK_MST2_ADDR : SC_C_PXL_LINK_MST1_ADDR,
								mst_addr);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_1:SC_C_PXL_LINK_MST%d_ADDR sc_misc_set_control failed! (sciError = %d)\n", stream_id + 1, sciErr);
	}

	sc_ipc_close(mu_id);
}

/* FIXME: set dc sync mode for pixel link in a proper manner */
static void dpu_pixel_link_set_dc_sync_mode(int dpu_id, bool enable)
{
	sc_err_t sciErr;
	sc_ipc_t ipcHndl = 0;
	u32 mu_id;

	sciErr = sc_ipc_getMuID(&mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("Cannot obtain MU ID\n");
		return;
	}

	sciErr = sc_ipc_open(&ipcHndl, mu_id);
	if (sciErr != SC_ERR_NONE) {
		pr_err("sc_ipc_open failed! (sciError = %d)\n", sciErr);
		return;
	}

	if (dpu_id == 0) {
		sciErr = sc_misc_set_control(ipcHndl,
						SC_R_DC_0, SC_C_MODE, enable);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_0:SC_C_MODE sc_misc_set_control failed! (sciError = %d)\n", sciErr);
	} else if (dpu_id == 1) {
		sciErr = sc_misc_set_control(ipcHndl,
						SC_R_DC_1, SC_C_MODE, enable);
		if (sciErr != SC_ERR_NONE)
			pr_err("SC_R_DC_1:SC_C_MODE sc_misc_set_control failed! (sciError = %d)\n", sciErr);
	}

	sc_ipc_close(mu_id);
}

void framegen_enable(struct dpu_framegen *fg)
{
	struct dpu_soc *dpu = fg->dpu;
	const struct dpu_devtype *devtype = dpu->devtype;

	mutex_lock(&fg->mutex);
	dpu_fg_write(fg, FGEN, FGENABLE);
	mutex_unlock(&fg->mutex);

	if (!(devtype->has_dual_ldb && fg->encoder_type_has_lvds))
		dpu_pixel_link_enable(dpu->id, fg->id);
}
EXPORT_SYMBOL_GPL(framegen_enable);

void framegen_disable(struct dpu_framegen *fg)
{
	struct dpu_soc *dpu = fg->dpu;
	const struct dpu_devtype *devtype = dpu->devtype;

	if (!(devtype->has_dual_ldb && fg->encoder_type_has_lvds))
		dpu_pixel_link_disable(dpu->id, fg->id);

	mutex_lock(&fg->mutex);
	dpu_fg_write(fg, 0, FGENABLE);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_disable);

void framegen_shdtokgen(struct dpu_framegen *fg)
{
	mutex_lock(&fg->mutex);
	dpu_fg_write(fg, SHDTOKGEN, FGSLR);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_shdtokgen);

void framegen_syncmode(struct dpu_framegen *fg, fgsyncmode_t mode)
{
	struct dpu_soc *dpu = fg->dpu;
	u32 val;

	mutex_lock(&fg->mutex);
	val = dpu_fg_read(fg, FGSTCTRL);
	val &= ~FGSYNCMODE_MASK;
	val |= mode;
	dpu_fg_write(fg, val, FGSTCTRL);
	mutex_unlock(&fg->mutex);

	dpu_pixel_link_set_dc_sync_mode(dpu->id, mode != FGSYNCMODE__OFF);
}
EXPORT_SYMBOL_GPL(framegen_syncmode);

void
framegen_cfg_videomode(struct dpu_framegen *fg,
		       struct drm_display_mode *m, bool side_by_side,
		       bool encoder_type_has_tmds, bool encoder_type_has_lvds)
{
	struct dpu_soc *dpu = fg->dpu;
	const struct dpu_devtype *devtype = dpu->devtype;
	u32 hact, htotal, hsync, hsbp;
	u32 vact, vtotal, vsync, vsbp;
	u32 kick_row, kick_col;
	u32 val;
	unsigned long disp_clock_rate, pll_clock_rate = 0;
	int div = 0;

	fg->side_by_side = side_by_side;
	fg->encoder_type_has_lvds = encoder_type_has_lvds;

	hact = m->crtc_hdisplay;
	htotal = m->crtc_htotal;
	hsync = m->crtc_hsync_end - m->crtc_hsync_start;
	hsbp = m->crtc_htotal - m->crtc_hsync_start;

	if (side_by_side) {
		hact /= 2;
		htotal /= 2;
		hsync /= 2;
		hsbp /= 2;
	}

	vact = m->crtc_vdisplay;
	vtotal = m->crtc_vtotal;
	vsync = m->crtc_vsync_end - m->crtc_vsync_start;
	vsbp = m->crtc_vtotal - m->crtc_vsync_start;

	mutex_lock(&fg->mutex);
	/* video mode */
	dpu_fg_write(fg, HACT(hact) | HTOTAL(htotal), HTCFG1);
	dpu_fg_write(fg, HSYNC(hsync) | HSBP(hsbp) | HSEN, HTCFG2);
	dpu_fg_write(fg, VACT(vact) | VTOTAL(vtotal), VTCFG1);
	dpu_fg_write(fg, VSYNC(vsync) | VSBP(vsbp) | VSEN, VTCFG2);

	kick_col = hact + 1;
	kick_row = vact;
	/*
	 * FrameGen as slave needs to be kicked later for
	 * one line comparing to the master.
	 */
	if (side_by_side && framegen_is_slave(fg) &&
	    devtype->has_syncmode_fixup)
		kick_row++;

	/* pkickconfig */
	dpu_fg_write(fg, COL(kick_col) | ROW(kick_row) | EN, PKICKCONFIG);

	/* skikconfig */
	dpu_fg_write(fg, COL(kick_col) | ROW(kick_row) | EN, SKICKCONFIG);

	/* primary position config */
	dpu_fg_write(fg, STARTX(0) | STARTY(0), PACFG);

	/* alpha */
	val = dpu_fg_read(fg, FGINCTRL);
	val &= ~(ENPRIMALPHA | ENSECALPHA);
	dpu_fg_write(fg, val, FGINCTRL);

	val = dpu_fg_read(fg, FGINCTRLPANIC);
	val &= ~(ENPRIMALPHA | ENSECALPHA);
	dpu_fg_write(fg, val, FGINCTRLPANIC);

	/* constant color */
	dpu_fg_write(fg, 0, FGCCR);
	mutex_unlock(&fg->mutex);

	disp_clock_rate = m->clock * 1000;

	/*
	 * To workaround setting clock rate failure issue
	 * when the system resumes back from PM sleep mode,
	 * we need to get the clock rates before setting
	 * their rates, otherwise, setting the clock rates
	 * will fail.
	 */
	if (devtype->has_disp_sel_clk && encoder_type_has_tmds) {
		if (side_by_side)
			dpu_pixel_link_set_mst_addr(dpu->id, fg->id,
							fg->id ? 2 : 1);
		else
			dpu_pixel_link_set_mst_addr(dpu->id, fg->id, 1);

		clk_set_parent(fg->clk_disp_sel, fg->clk_bypass);

		fg->use_bypass_clk = true;
	} else {
		dpu_pixel_link_set_mst_addr(dpu->id, fg->id, 0);

		/* find an even divisor for PLL */
		do {
			div += 2;
			pll_clock_rate = disp_clock_rate * div;
		} while (pll_clock_rate < PLL_MIN_FREQ_HZ);

		if (devtype->has_disp_sel_clk)
			clk_set_parent(fg->clk_disp_sel, fg->clk_pll);

		clk_get_rate(fg->clk_pll);
		clk_get_rate(fg->clk_disp);
		clk_set_rate(fg->clk_pll, pll_clock_rate);
		clk_set_rate(fg->clk_disp, disp_clock_rate);

		fg->use_bypass_clk = false;
	}
}
EXPORT_SYMBOL_GPL(framegen_cfg_videomode);

void framegen_pkickconfig(struct dpu_framegen *fg, bool enable)
{
	u32 val;

	mutex_lock(&fg->mutex);
	val = dpu_fg_read(fg, PKICKCONFIG);
	if (enable)
		val |= EN;
	else
		val &= ~EN;
	dpu_fg_write(fg, val, PKICKCONFIG);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_pkickconfig);

void framegen_syncmode_fixup(struct dpu_framegen *fg, bool enable)
{
	struct dpu_soc *dpu = fg->dpu;
	u32 val;

	if (!dpu->devtype->has_syncmode_fixup)
		return;

	mutex_lock(&fg->mutex);
	val = dpu_fg_read(fg, SECSTATCONFIG);
	if (enable)
		val |= BIT(7);
	else
		val &= ~BIT(7);
	dpu_fg_write(fg, val, SECSTATCONFIG);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_syncmode_fixup);

void framegen_sacfg(struct dpu_framegen *fg, unsigned int x, unsigned int y)
{
	mutex_lock(&fg->mutex);
	dpu_fg_write(fg, STARTX(x) | STARTY(y), SACFG);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_sacfg);

void framegen_displaymode(struct dpu_framegen *fg, fgdm_t mode)
{
	u32 val;

	mutex_lock(&fg->mutex);
	val = dpu_fg_read(fg, FGINCTRL);
	val &= ~FGDM_MASK;
	val |= mode;
	dpu_fg_write(fg, val, FGINCTRL);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_displaymode);

void framegen_panic_displaymode(struct dpu_framegen *fg, fgdm_t mode)
{
	u32 val;

	mutex_lock(&fg->mutex);
	val = dpu_fg_read(fg, FGINCTRLPANIC);
	val &= ~FGDM_MASK;
	val |= mode;
	dpu_fg_write(fg, val, FGINCTRLPANIC);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_panic_displaymode);

void framegen_wait_done(struct dpu_framegen *fg, struct drm_display_mode *m)
{
	unsigned long timeout, pending_framedur_jiffies;
	int frame_size = m->crtc_htotal * m->crtc_vtotal;
	int dotclock, pending_framedur_ns;
	u32 val;

	dotclock = clk_get_rate(fg->clk_disp) / KHZ;
	if (dotclock == 0) {
		/* fall back to display mode's clock */
		dotclock = m->crtc_clock;

		if (!(fg->side_by_side && fg->id == 1))
			dev_warn(fg->dpu->dev,
				"pixel clock for FrameGen%d is zero\n", fg->id);
	}

	/*
	 * The SoC designer indicates that there are two pending frames
	 * to complete in the worst case.
	 * So, three pending frames are enough for sure.
	 */
	pending_framedur_ns = div_u64((u64) 3 * frame_size * 1000000, dotclock);
	pending_framedur_jiffies = nsecs_to_jiffies(pending_framedur_ns);
	if (pending_framedur_jiffies > (3 * HZ)) {
		pending_framedur_jiffies = 3 * HZ;

		dev_warn(fg->dpu->dev,
			 "truncate FrameGen%d pending frame duration to 3sec\n",
			 fg->id);
	}
	timeout = jiffies + pending_framedur_jiffies;

	mutex_lock(&fg->mutex);
	do {
		val = dpu_fg_read(fg, FGENSTS);
	} while ((val & ENSTS) && time_before(jiffies, timeout));
	mutex_unlock(&fg->mutex);

	dev_dbg(fg->dpu->dev, "FrameGen%d pending frame duration is %ums\n",
			 fg->id, jiffies_to_msecs(pending_framedur_jiffies));

	if (val & ENSTS)
		dev_err(fg->dpu->dev, "failed to wait for FrameGen%d done\n",
			fg->id);
}
EXPORT_SYMBOL_GPL(framegen_wait_done);

static inline u32 framegen_frame_index(u32 stamp)
{
	return (stamp & FRAMEINDEX_MASK) >> FRAMEINDEX_SHIFT;
}

static inline u32 framegen_line_index(u32 stamp)
{
	return (stamp & LINEINDEX_MASK) >> LINEINDEX_SHIFT;
}

void framegen_read_timestamp(struct dpu_framegen *fg,
			     u32 *frame_index, u32 *line_index)
{
	u32 stamp;

	mutex_lock(&fg->mutex);
	stamp = dpu_fg_read(fg, FGTIMESTAMP);
	*frame_index = framegen_frame_index(stamp);
	*line_index = framegen_line_index(stamp);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_read_timestamp);

void framegen_wait_for_frame_counter_moving(struct dpu_framegen *fg)
{
	u32 frame_index, line_index, last_frame_index;
	unsigned long timeout = jiffies + msecs_to_jiffies(50);

	framegen_read_timestamp(fg, &frame_index, &line_index);
	do {
		last_frame_index = frame_index;
		framegen_read_timestamp(fg, &frame_index, &line_index);
	} while (last_frame_index == frame_index &&
						time_before(jiffies, timeout));

	if (last_frame_index == frame_index)
		dev_err(fg->dpu->dev,
			"failed to wait for FrameGen%d frame counter moving\n",
			fg->id);
	else
		dev_dbg(fg->dpu->dev,
			"FrameGen%d frame counter moves - last %u, curr %d\n",
			fg->id, last_frame_index, frame_index);
}
EXPORT_SYMBOL_GPL(framegen_wait_for_frame_counter_moving);

bool framegen_secondary_requests_to_read_empty_fifo(struct dpu_framegen *fg)
{
	u32 val;
	bool empty;

	mutex_lock(&fg->mutex);
	val = dpu_fg_read(fg, FGCHSTAT);
	mutex_unlock(&fg->mutex);

	empty = !!(val & SFIFOEMPTY);

	if (empty)
		dev_dbg(fg->dpu->dev,
			"FrameGen%d secondary requests to read empty FIFO\n",
			fg->id);

	return empty;
}
EXPORT_SYMBOL_GPL(framegen_secondary_requests_to_read_empty_fifo);

void framegen_secondary_clear_channel_status(struct dpu_framegen *fg)
{
	mutex_lock(&fg->mutex);
	dpu_fg_write(fg, CLRSECSTAT, FGCHSTATCLR);
	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(framegen_secondary_clear_channel_status);

bool framegen_secondary_is_syncup(struct dpu_framegen *fg)
{
	u32 val;

	mutex_lock(&fg->mutex);
	val = dpu_fg_read(fg, FGCHSTAT);
	mutex_unlock(&fg->mutex);

	return val & SECSYNCSTAT;
}
EXPORT_SYMBOL_GPL(framegen_secondary_is_syncup);

void framegen_wait_for_secondary_syncup(struct dpu_framegen *fg)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(100);
	bool syncup;

	do {
		syncup = framegen_secondary_is_syncup(fg);
	} while (!syncup && time_before(jiffies, timeout));

	if (syncup)
		dev_dbg(fg->dpu->dev, "FrameGen%d secondary syncup\n", fg->id);
	else
		dev_err(fg->dpu->dev,
			"failed to wait for FrameGen%d secondary syncup\n",
			fg->id);
}
EXPORT_SYMBOL_GPL(framegen_wait_for_secondary_syncup);

void framegen_enable_clock(struct dpu_framegen *fg)
{
	if (!fg->use_bypass_clk)
		clk_prepare_enable(fg->clk_pll);
	clk_prepare_enable(fg->clk_disp);
}
EXPORT_SYMBOL_GPL(framegen_enable_clock);

void framegen_disable_clock(struct dpu_framegen *fg)
{
	if (!fg->use_bypass_clk)
		clk_disable_unprepare(fg->clk_pll);
	clk_disable_unprepare(fg->clk_disp);
}
EXPORT_SYMBOL_GPL(framegen_disable_clock);

bool framegen_is_master(struct dpu_framegen *fg)
{
	const struct dpu_devtype *devtype = fg->dpu->devtype;

	return fg->id == devtype->master_stream_id;
}
EXPORT_SYMBOL_GPL(framegen_is_master);

bool framegen_is_slave(struct dpu_framegen *fg)
{
	return !framegen_is_master(fg);
}
EXPORT_SYMBOL_GPL(framegen_is_slave);

struct dpu_framegen *dpu_fg_get(struct dpu_soc *dpu, int id)
{
	struct dpu_framegen *fg;
	int i;

	for (i = 0; i < ARRAY_SIZE(fg_ids); i++)
		if (fg_ids[i] == id)
			break;

	if (i == ARRAY_SIZE(fg_ids))
		return ERR_PTR(-EINVAL);

	fg = dpu->fg_priv[i];

	mutex_lock(&fg->mutex);

	if (fg->inuse) {
		mutex_unlock(&fg->mutex);
		return ERR_PTR(-EBUSY);
	}

	fg->inuse = true;

	mutex_unlock(&fg->mutex);

	return fg;
}
EXPORT_SYMBOL_GPL(dpu_fg_get);

void dpu_fg_put(struct dpu_framegen *fg)
{
	mutex_lock(&fg->mutex);

	fg->inuse = false;

	mutex_unlock(&fg->mutex);
}
EXPORT_SYMBOL_GPL(dpu_fg_put);

struct dpu_framegen *dpu_aux_fg_peek(struct dpu_framegen *fg)
{
	return fg->dpu->fg_priv[fg->id ^ 1];
}
EXPORT_SYMBOL_GPL(dpu_aux_fg_peek);

void _dpu_fg_init(struct dpu_soc *dpu, unsigned int id)
{
	struct dpu_framegen *fg;
	int i;

	for (i = 0; i < ARRAY_SIZE(fg_ids); i++)
		if (fg_ids[i] == id)
			break;

	if (WARN_ON(i == ARRAY_SIZE(fg_ids)))
		return;

	fg = dpu->fg_priv[i];

	framegen_syncmode(fg, FGSYNCMODE__OFF);
}

int dpu_fg_init(struct dpu_soc *dpu, unsigned int id,
		unsigned long unused, unsigned long base)
{
	struct dpu_framegen *fg;

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

	dpu->fg_priv[id] = fg;

	fg->base = devm_ioremap(dpu->dev, base, SZ_256);
	if (!fg->base)
		return -ENOMEM;

	fg->clk_pll = devm_clk_get(dpu->dev, id ? "pll1" : "pll0");
	if (IS_ERR(fg->clk_pll))
		return PTR_ERR(fg->clk_pll);

	if (dpu->devtype->has_disp_sel_clk) {
		fg->clk_bypass = devm_clk_get(dpu->dev, "bypass0");
		if (IS_ERR(fg->clk_bypass))
			return PTR_ERR(fg->clk_bypass);

		fg->clk_disp_sel = devm_clk_get(dpu->dev,
					id ? "disp1_sel" : "disp0_sel");
			if (IS_ERR(fg->clk_disp_sel))
				return PTR_ERR(fg->clk_disp_sel);
	}

	fg->clk_disp = devm_clk_get(dpu->dev, id ? "disp1" : "disp0");
	if (IS_ERR(fg->clk_disp))
		return PTR_ERR(fg->clk_disp);

	fg->dpu = dpu;
	fg->id = id;
	mutex_init(&fg->mutex);

	_dpu_fg_init(dpu, id);

	return 0;
}
