/*
 * linux/drivers/video/omap2/dss/dss.c
 *
 * Copyright (C) 2009 Nokia Corporation
 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
 *
 * Some code and ideas taken from drivers/video/omap/ driver
 * by Imre Deak.
 *
 * 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.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#define DSS_SUBSYS_NAME "DSS"

#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/gfp.h>
#include <linux/sizes.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
#include <linux/component.h>
#include <linux/sys_soc.h>

#include "omapdss.h"
#include "dss.h"

#define DSS_SZ_REGS			SZ_512

struct dss_reg {
	u16 idx;
};

#define DSS_REG(idx)			((const struct dss_reg) { idx })

#define DSS_REVISION			DSS_REG(0x0000)
#define DSS_SYSCONFIG			DSS_REG(0x0010)
#define DSS_SYSSTATUS			DSS_REG(0x0014)
#define DSS_CONTROL			DSS_REG(0x0040)
#define DSS_SDI_CONTROL			DSS_REG(0x0044)
#define DSS_PLL_CONTROL			DSS_REG(0x0048)
#define DSS_SDI_STATUS			DSS_REG(0x005C)

#define REG_GET(idx, start, end) \
	FLD_GET(dss_read_reg(idx), start, end)

#define REG_FLD_MOD(idx, val, start, end) \
	dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))

struct dss_ops {
	int (*dpi_select_source)(int port, enum omap_channel channel);
	int (*select_lcd_source)(enum omap_channel channel,
		enum dss_clk_source clk_src);
};

struct dss_features {
	enum dss_model model;
	u8 fck_div_max;
	unsigned int fck_freq_max;
	u8 dss_fck_multiplier;
	const char *parent_clk_name;
	const enum omap_display_type *ports;
	int num_ports;
	const enum omap_dss_output_id *outputs;
	const struct dss_ops *ops;
	struct dss_reg_field dispc_clk_switch;
	bool has_lcd_clk_src;
};

static struct {
	struct platform_device *pdev;
	void __iomem    *base;
	struct regmap	*syscon_pll_ctrl;
	u32		syscon_pll_ctrl_offset;

	struct clk	*parent_clk;
	struct clk	*dss_clk;
	unsigned long	dss_clk_rate;

	unsigned long	cache_req_pck;
	unsigned long	cache_prate;
	struct dispc_clock_info cache_dispc_cinfo;

	enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
	enum dss_clk_source dispc_clk_source;
	enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];

	bool		ctx_valid;
	u32		ctx[DSS_SZ_REGS / sizeof(u32)];

	const struct dss_features *feat;

	struct dss_pll	*video1_pll;
	struct dss_pll	*video2_pll;
} dss;

static const char * const dss_generic_clk_source_names[] = {
	[DSS_CLK_SRC_FCK]	= "FCK",
	[DSS_CLK_SRC_PLL1_1]	= "PLL1:1",
	[DSS_CLK_SRC_PLL1_2]	= "PLL1:2",
	[DSS_CLK_SRC_PLL1_3]	= "PLL1:3",
	[DSS_CLK_SRC_PLL2_1]	= "PLL2:1",
	[DSS_CLK_SRC_PLL2_2]	= "PLL2:2",
	[DSS_CLK_SRC_PLL2_3]	= "PLL2:3",
	[DSS_CLK_SRC_HDMI_PLL]	= "HDMI PLL",
};

static inline void dss_write_reg(const struct dss_reg idx, u32 val)
{
	__raw_writel(val, dss.base + idx.idx);
}

static inline u32 dss_read_reg(const struct dss_reg idx)
{
	return __raw_readl(dss.base + idx.idx);
}

#define SR(reg) \
	dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
#define RR(reg) \
	dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])

static void dss_save_context(void)
{
	DSSDBG("dss_save_context\n");

	SR(CONTROL);

	if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
		SR(SDI_CONTROL);
		SR(PLL_CONTROL);
	}

	dss.ctx_valid = true;

	DSSDBG("context saved\n");
}

static void dss_restore_context(void)
{
	DSSDBG("dss_restore_context\n");

	if (!dss.ctx_valid)
		return;

	RR(CONTROL);

	if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
		RR(SDI_CONTROL);
		RR(PLL_CONTROL);
	}

	DSSDBG("context restored\n");
}

#undef SR
#undef RR

void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
{
	unsigned shift;
	unsigned val;

	if (!dss.syscon_pll_ctrl)
		return;

	val = !enable;

	switch (pll_id) {
	case DSS_PLL_VIDEO1:
		shift = 0;
		break;
	case DSS_PLL_VIDEO2:
		shift = 1;
		break;
	case DSS_PLL_HDMI:
		shift = 2;
		break;
	default:
		DSSERR("illegal DSS PLL ID %d\n", pll_id);
		return;
	}

	regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
		1 << shift, val << shift);
}

static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
	enum omap_channel channel)
{
	unsigned shift, val;

	if (!dss.syscon_pll_ctrl)
		return -EINVAL;

	switch (channel) {
	case OMAP_DSS_CHANNEL_LCD:
		shift = 3;

		switch (clk_src) {
		case DSS_CLK_SRC_PLL1_1:
			val = 0; break;
		case DSS_CLK_SRC_HDMI_PLL:
			val = 1; break;
		default:
			DSSERR("error in PLL mux config for LCD\n");
			return -EINVAL;
		}

		break;
	case OMAP_DSS_CHANNEL_LCD2:
		shift = 5;

		switch (clk_src) {
		case DSS_CLK_SRC_PLL1_3:
			val = 0; break;
		case DSS_CLK_SRC_PLL2_3:
			val = 1; break;
		case DSS_CLK_SRC_HDMI_PLL:
			val = 2; break;
		default:
			DSSERR("error in PLL mux config for LCD2\n");
			return -EINVAL;
		}

		break;
	case OMAP_DSS_CHANNEL_LCD3:
		shift = 7;

		switch (clk_src) {
		case DSS_CLK_SRC_PLL2_1:
			val = 0; break;
		case DSS_CLK_SRC_PLL1_3:
			val = 1; break;
		case DSS_CLK_SRC_HDMI_PLL:
			val = 2; break;
		default:
			DSSERR("error in PLL mux config for LCD3\n");
			return -EINVAL;
		}

		break;
	default:
		DSSERR("error in PLL mux config\n");
		return -EINVAL;
	}

	regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
		0x3 << shift, val << shift);

	return 0;
}

void dss_sdi_init(int datapairs)
{
	u32 l;

	BUG_ON(datapairs > 3 || datapairs < 1);

	l = dss_read_reg(DSS_SDI_CONTROL);
	l = FLD_MOD(l, 0xf, 19, 15);		/* SDI_PDIV */
	l = FLD_MOD(l, datapairs-1, 3, 2);	/* SDI_PRSEL */
	l = FLD_MOD(l, 2, 1, 0);		/* SDI_BWSEL */
	dss_write_reg(DSS_SDI_CONTROL, l);

	l = dss_read_reg(DSS_PLL_CONTROL);
	l = FLD_MOD(l, 0x7, 25, 22);	/* SDI_PLL_FREQSEL */
	l = FLD_MOD(l, 0xb, 16, 11);	/* SDI_PLL_REGN */
	l = FLD_MOD(l, 0xb4, 10, 1);	/* SDI_PLL_REGM */
	dss_write_reg(DSS_PLL_CONTROL, l);
}

int dss_sdi_enable(void)
{
	unsigned long timeout;

	dispc_pck_free_enable(1);

	/* Reset SDI PLL */
	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
	udelay(1);	/* wait 2x PCLK */

	/* Lock SDI PLL */
	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */

	/* Waiting for PLL lock request to complete */
	timeout = jiffies + msecs_to_jiffies(500);
	while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
		if (time_after_eq(jiffies, timeout)) {
			DSSERR("PLL lock request timed out\n");
			goto err1;
		}
	}

	/* Clearing PLL_GO bit */
	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);

	/* Waiting for PLL to lock */
	timeout = jiffies + msecs_to_jiffies(500);
	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
		if (time_after_eq(jiffies, timeout)) {
			DSSERR("PLL lock timed out\n");
			goto err1;
		}
	}

	dispc_lcd_enable_signal(1);

	/* Waiting for SDI reset to complete */
	timeout = jiffies + msecs_to_jiffies(500);
	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
		if (time_after_eq(jiffies, timeout)) {
			DSSERR("SDI reset timed out\n");
			goto err2;
		}
	}

	return 0;

 err2:
	dispc_lcd_enable_signal(0);
 err1:
	/* Reset SDI PLL */
	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */

	dispc_pck_free_enable(0);

	return -ETIMEDOUT;
}

void dss_sdi_disable(void)
{
	dispc_lcd_enable_signal(0);

	dispc_pck_free_enable(0);

	/* Reset SDI PLL */
	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
}

const char *dss_get_clk_source_name(enum dss_clk_source clk_src)
{
	return dss_generic_clk_source_names[clk_src];
}

void dss_dump_clocks(struct seq_file *s)
{
	const char *fclk_name;
	unsigned long fclk_rate;

	if (dss_runtime_get())
		return;

	seq_printf(s, "- DSS -\n");

	fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK);
	fclk_rate = clk_get_rate(dss.dss_clk);

	seq_printf(s, "%s = %lu\n",
			fclk_name,
			fclk_rate);

	dss_runtime_put();
}

static void dss_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))

	if (dss_runtime_get())
		return;

	DUMPREG(DSS_REVISION);
	DUMPREG(DSS_SYSCONFIG);
	DUMPREG(DSS_SYSSTATUS);
	DUMPREG(DSS_CONTROL);

	if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
		DUMPREG(DSS_SDI_CONTROL);
		DUMPREG(DSS_PLL_CONTROL);
		DUMPREG(DSS_SDI_STATUS);
	}

	dss_runtime_put();
#undef DUMPREG
}

static int dss_get_channel_index(enum omap_channel channel)
{
	switch (channel) {
	case OMAP_DSS_CHANNEL_LCD:
		return 0;
	case OMAP_DSS_CHANNEL_LCD2:
		return 1;
	case OMAP_DSS_CHANNEL_LCD3:
		return 2;
	default:
		WARN_ON(1);
		return 0;
	}
}

static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
{
	int b;

	/*
	 * We always use PRCM clock as the DISPC func clock, except on DSS3,
	 * where we don't have separate DISPC and LCD clock sources.
	 */
	if (WARN_ON(dss.feat->has_lcd_clk_src && clk_src != DSS_CLK_SRC_FCK))
		return;

	switch (clk_src) {
	case DSS_CLK_SRC_FCK:
		b = 0;
		break;
	case DSS_CLK_SRC_PLL1_1:
		b = 1;
		break;
	case DSS_CLK_SRC_PLL2_1:
		b = 2;
		break;
	default:
		BUG();
		return;
	}

	REG_FLD_MOD(DSS_CONTROL, b,			/* DISPC_CLK_SWITCH */
		    dss.feat->dispc_clk_switch.start,
		    dss.feat->dispc_clk_switch.end);

	dss.dispc_clk_source = clk_src;
}

void dss_select_dsi_clk_source(int dsi_module,
		enum dss_clk_source clk_src)
{
	int b, pos;

	switch (clk_src) {
	case DSS_CLK_SRC_FCK:
		b = 0;
		break;
	case DSS_CLK_SRC_PLL1_2:
		BUG_ON(dsi_module != 0);
		b = 1;
		break;
	case DSS_CLK_SRC_PLL2_2:
		BUG_ON(dsi_module != 1);
		b = 1;
		break;
	default:
		BUG();
		return;
	}

	pos = dsi_module == 0 ? 1 : 10;
	REG_FLD_MOD(DSS_CONTROL, b, pos, pos);	/* DSIx_CLK_SWITCH */

	dss.dsi_clk_source[dsi_module] = clk_src;
}

static int dss_lcd_clk_mux_dra7(enum omap_channel channel,
	enum dss_clk_source clk_src)
{
	const u8 ctrl_bits[] = {
		[OMAP_DSS_CHANNEL_LCD] = 0,
		[OMAP_DSS_CHANNEL_LCD2] = 12,
		[OMAP_DSS_CHANNEL_LCD3] = 19,
	};

	u8 ctrl_bit = ctrl_bits[channel];
	int r;

	if (clk_src == DSS_CLK_SRC_FCK) {
		/* LCDx_CLK_SWITCH */
		REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
		return -EINVAL;
	}

	r = dss_ctrl_pll_set_control_mux(clk_src, channel);
	if (r)
		return r;

	REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);

	return 0;
}

static int dss_lcd_clk_mux_omap5(enum omap_channel channel,
	enum dss_clk_source clk_src)
{
	const u8 ctrl_bits[] = {
		[OMAP_DSS_CHANNEL_LCD] = 0,
		[OMAP_DSS_CHANNEL_LCD2] = 12,
		[OMAP_DSS_CHANNEL_LCD3] = 19,
	};
	const enum dss_clk_source allowed_plls[] = {
		[OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
		[OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_FCK,
		[OMAP_DSS_CHANNEL_LCD3] = DSS_CLK_SRC_PLL2_1,
	};

	u8 ctrl_bit = ctrl_bits[channel];

	if (clk_src == DSS_CLK_SRC_FCK) {
		/* LCDx_CLK_SWITCH */
		REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
		return -EINVAL;
	}

	if (WARN_ON(allowed_plls[channel] != clk_src))
		return -EINVAL;

	REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);

	return 0;
}

static int dss_lcd_clk_mux_omap4(enum omap_channel channel,
	enum dss_clk_source clk_src)
{
	const u8 ctrl_bits[] = {
		[OMAP_DSS_CHANNEL_LCD] = 0,
		[OMAP_DSS_CHANNEL_LCD2] = 12,
	};
	const enum dss_clk_source allowed_plls[] = {
		[OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
		[OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_PLL2_1,
	};

	u8 ctrl_bit = ctrl_bits[channel];

	if (clk_src == DSS_CLK_SRC_FCK) {
		/* LCDx_CLK_SWITCH */
		REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
		return 0;
	}

	if (WARN_ON(allowed_plls[channel] != clk_src))
		return -EINVAL;

	REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);

	return 0;
}

void dss_select_lcd_clk_source(enum omap_channel channel,
		enum dss_clk_source clk_src)
{
	int idx = dss_get_channel_index(channel);
	int r;

	if (!dss.feat->has_lcd_clk_src) {
		dss_select_dispc_clk_source(clk_src);
		dss.lcd_clk_source[idx] = clk_src;
		return;
	}

	r = dss.feat->ops->select_lcd_source(channel, clk_src);
	if (r)
		return;

	dss.lcd_clk_source[idx] = clk_src;
}

enum dss_clk_source dss_get_dispc_clk_source(void)
{
	return dss.dispc_clk_source;
}

enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
{
	return dss.dsi_clk_source[dsi_module];
}

enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
{
	if (dss.feat->has_lcd_clk_src) {
		int idx = dss_get_channel_index(channel);
		return dss.lcd_clk_source[idx];
	} else {
		/* LCD_CLK source is the same as DISPC_FCLK source for
		 * OMAP2 and OMAP3 */
		return dss.dispc_clk_source;
	}
}

bool dss_div_calc(unsigned long pck, unsigned long fck_min,
		dss_div_calc_func func, void *data)
{
	int fckd, fckd_start, fckd_stop;
	unsigned long fck;
	unsigned long fck_hw_max;
	unsigned long fckd_hw_max;
	unsigned long prate;
	unsigned m;

	fck_hw_max = dss.feat->fck_freq_max;

	if (dss.parent_clk == NULL) {
		unsigned pckd;

		pckd = fck_hw_max / pck;

		fck = pck * pckd;

		fck = clk_round_rate(dss.dss_clk, fck);

		return func(fck, data);
	}

	fckd_hw_max = dss.feat->fck_div_max;

	m = dss.feat->dss_fck_multiplier;
	prate = clk_get_rate(dss.parent_clk);

	fck_min = fck_min ? fck_min : 1;

	fckd_start = min(prate * m / fck_min, fckd_hw_max);
	fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);

	for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
		fck = DIV_ROUND_UP(prate, fckd) * m;

		if (func(fck, data))
			return true;
	}

	return false;
}

int dss_set_fck_rate(unsigned long rate)
{
	int r;

	DSSDBG("set fck to %lu\n", rate);

	r = clk_set_rate(dss.dss_clk, rate);
	if (r)
		return r;

	dss.dss_clk_rate = clk_get_rate(dss.dss_clk);

	WARN_ONCE(dss.dss_clk_rate != rate,
			"clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
			rate);

	return 0;
}

unsigned long dss_get_dispc_clk_rate(void)
{
	return dss.dss_clk_rate;
}

unsigned long dss_get_max_fck_rate(void)
{
	return dss.feat->fck_freq_max;
}

enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel)
{
	return dss.feat->outputs[channel];
}

static int dss_setup_default_clock(void)
{
	unsigned long max_dss_fck, prate;
	unsigned long fck;
	unsigned fck_div;
	int r;

	max_dss_fck = dss.feat->fck_freq_max;

	if (dss.parent_clk == NULL) {
		fck = clk_round_rate(dss.dss_clk, max_dss_fck);
	} else {
		prate = clk_get_rate(dss.parent_clk);

		fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
				max_dss_fck);
		fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
	}

	r = dss_set_fck_rate(fck);
	if (r)
		return r;

	return 0;
}

void dss_set_venc_output(enum omap_dss_venc_type type)
{
	int l = 0;

	if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
		l = 0;
	else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
		l = 1;
	else
		BUG();

	/* venc out selection. 0 = comp, 1 = svideo */
	REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
}

void dss_set_dac_pwrdn_bgz(bool enable)
{
	REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);	/* DAC Power-Down Control */
}

void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
{
	enum omap_dss_output_id outputs;

	outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];

	/* Complain about invalid selections */
	WARN_ON((src == DSS_VENC_TV_CLK) && !(outputs & OMAP_DSS_OUTPUT_VENC));
	WARN_ON((src == DSS_HDMI_M_PCLK) && !(outputs & OMAP_DSS_OUTPUT_HDMI));

	/* Select only if we have options */
	if ((outputs & OMAP_DSS_OUTPUT_VENC) &&
	    (outputs & OMAP_DSS_OUTPUT_HDMI))
		REG_FLD_MOD(DSS_CONTROL, src, 15, 15);	/* VENC_HDMI_SWITCH */
}

enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
{
	enum omap_dss_output_id outputs;

	outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
	if ((outputs & OMAP_DSS_OUTPUT_HDMI) == 0)
		return DSS_VENC_TV_CLK;

	if ((outputs & OMAP_DSS_OUTPUT_VENC) == 0)
		return DSS_HDMI_M_PCLK;

	return REG_GET(DSS_CONTROL, 15, 15);
}

static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel)
{
	if (channel != OMAP_DSS_CHANNEL_LCD)
		return -EINVAL;

	return 0;
}

static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
{
	int val;

	switch (channel) {
	case OMAP_DSS_CHANNEL_LCD2:
		val = 0;
		break;
	case OMAP_DSS_CHANNEL_DIGIT:
		val = 1;
		break;
	default:
		return -EINVAL;
	}

	REG_FLD_MOD(DSS_CONTROL, val, 17, 17);

	return 0;
}

static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
{
	int val;

	switch (channel) {
	case OMAP_DSS_CHANNEL_LCD:
		val = 1;
		break;
	case OMAP_DSS_CHANNEL_LCD2:
		val = 2;
		break;
	case OMAP_DSS_CHANNEL_LCD3:
		val = 3;
		break;
	case OMAP_DSS_CHANNEL_DIGIT:
		val = 0;
		break;
	default:
		return -EINVAL;
	}

	REG_FLD_MOD(DSS_CONTROL, val, 17, 16);

	return 0;
}

static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
{
	switch (port) {
	case 0:
		return dss_dpi_select_source_omap5(port, channel);
	case 1:
		if (channel != OMAP_DSS_CHANNEL_LCD2)
			return -EINVAL;
		break;
	case 2:
		if (channel != OMAP_DSS_CHANNEL_LCD3)
			return -EINVAL;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

int dss_dpi_select_source(int port, enum omap_channel channel)
{
	return dss.feat->ops->dpi_select_source(port, channel);
}

static int dss_get_clocks(void)
{
	struct clk *clk;

	clk = devm_clk_get(&dss.pdev->dev, "fck");
	if (IS_ERR(clk)) {
		DSSERR("can't get clock fck\n");
		return PTR_ERR(clk);
	}

	dss.dss_clk = clk;

	if (dss.feat->parent_clk_name) {
		clk = clk_get(NULL, dss.feat->parent_clk_name);
		if (IS_ERR(clk)) {
			DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
			return PTR_ERR(clk);
		}
	} else {
		clk = NULL;
	}

	dss.parent_clk = clk;

	return 0;
}

static void dss_put_clocks(void)
{
	if (dss.parent_clk)
		clk_put(dss.parent_clk);
}

int dss_runtime_get(void)
{
	int r;

	DSSDBG("dss_runtime_get\n");

	r = pm_runtime_get_sync(&dss.pdev->dev);
	WARN_ON(r < 0);
	return r < 0 ? r : 0;
}

void dss_runtime_put(void)
{
	int r;

	DSSDBG("dss_runtime_put\n");

	r = pm_runtime_put_sync(&dss.pdev->dev);
	WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
}

/* DEBUGFS */
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
static void dss_debug_dump_clocks(struct seq_file *s)
{
	dss_dump_clocks(s);
	dispc_dump_clocks(s);
#ifdef CONFIG_OMAP2_DSS_DSI
	dsi_dump_clocks(s);
#endif
}

static int dss_debug_show(struct seq_file *s, void *unused)
{
	void (*func)(struct seq_file *) = s->private;

	func(s);
	return 0;
}

static int dss_debug_open(struct inode *inode, struct file *file)
{
	return single_open(file, dss_debug_show, inode->i_private);
}

static const struct file_operations dss_debug_fops = {
	.open           = dss_debug_open,
	.read           = seq_read,
	.llseek         = seq_lseek,
	.release        = single_release,
};

static struct dentry *dss_debugfs_dir;

static int dss_initialize_debugfs(void)
{
	dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
	if (IS_ERR(dss_debugfs_dir)) {
		int err = PTR_ERR(dss_debugfs_dir);

		dss_debugfs_dir = NULL;
		return err;
	}

	debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
			&dss_debug_dump_clocks, &dss_debug_fops);

	return 0;
}

static void dss_uninitialize_debugfs(void)
{
	if (dss_debugfs_dir)
		debugfs_remove_recursive(dss_debugfs_dir);
}

int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
{
	struct dentry *d;

	d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
			write, &dss_debug_fops);

	return PTR_ERR_OR_ZERO(d);
}
#else /* CONFIG_OMAP2_DSS_DEBUGFS */
static inline int dss_initialize_debugfs(void)
{
	return 0;
}
static inline void dss_uninitialize_debugfs(void)
{
}
#endif /* CONFIG_OMAP2_DSS_DEBUGFS */

static const struct dss_ops dss_ops_omap2_omap3 = {
	.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
};

static const struct dss_ops dss_ops_omap4 = {
	.dpi_select_source = &dss_dpi_select_source_omap4,
	.select_lcd_source = &dss_lcd_clk_mux_omap4,
};

static const struct dss_ops dss_ops_omap5 = {
	.dpi_select_source = &dss_dpi_select_source_omap5,
	.select_lcd_source = &dss_lcd_clk_mux_omap5,
};

static const struct dss_ops dss_ops_dra7 = {
	.dpi_select_source = &dss_dpi_select_source_dra7xx,
	.select_lcd_source = &dss_lcd_clk_mux_dra7,
};

static const enum omap_display_type omap2plus_ports[] = {
	OMAP_DISPLAY_TYPE_DPI,
};

static const enum omap_display_type omap34xx_ports[] = {
	OMAP_DISPLAY_TYPE_DPI,
	OMAP_DISPLAY_TYPE_SDI,
};

static const enum omap_display_type dra7xx_ports[] = {
	OMAP_DISPLAY_TYPE_DPI,
	OMAP_DISPLAY_TYPE_DPI,
	OMAP_DISPLAY_TYPE_DPI,
};

static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
	/* OMAP_DSS_CHANNEL_LCD */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,

	/* OMAP_DSS_CHANNEL_DIGIT */
	OMAP_DSS_OUTPUT_VENC,
};

static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
	/* OMAP_DSS_CHANNEL_LCD */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
	OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,

	/* OMAP_DSS_CHANNEL_DIGIT */
	OMAP_DSS_OUTPUT_VENC,
};

static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
	/* OMAP_DSS_CHANNEL_LCD */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
	OMAP_DSS_OUTPUT_DSI1,

	/* OMAP_DSS_CHANNEL_DIGIT */
	OMAP_DSS_OUTPUT_VENC,
};

static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = {
	/* OMAP_DSS_CHANNEL_LCD */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
};

static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
	/* OMAP_DSS_CHANNEL_LCD */
	OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1,

	/* OMAP_DSS_CHANNEL_DIGIT */
	OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI,

	/* OMAP_DSS_CHANNEL_LCD2 */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
	OMAP_DSS_OUTPUT_DSI2,
};

static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
	/* OMAP_DSS_CHANNEL_LCD */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
	OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,

	/* OMAP_DSS_CHANNEL_DIGIT */
	OMAP_DSS_OUTPUT_HDMI,

	/* OMAP_DSS_CHANNEL_LCD2 */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
	OMAP_DSS_OUTPUT_DSI1,

	/* OMAP_DSS_CHANNEL_LCD3 */
	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
	OMAP_DSS_OUTPUT_DSI2,
};

static const struct dss_features omap24xx_dss_feats = {
	.model			=	DSS_MODEL_OMAP2,
	/*
	 * fck div max is really 16, but the divider range has gaps. The range
	 * from 1 to 6 has no gaps, so let's use that as a max.
	 */
	.fck_div_max		=	6,
	.fck_freq_max		=	133000000,
	.dss_fck_multiplier	=	2,
	.parent_clk_name	=	"core_ck",
	.ports			=	omap2plus_ports,
	.num_ports		=	ARRAY_SIZE(omap2plus_ports),
	.outputs		=	omap2_dss_supported_outputs,
	.ops			=	&dss_ops_omap2_omap3,
	.dispc_clk_switch	=	{ 0, 0 },
	.has_lcd_clk_src	=	false,
};

static const struct dss_features omap34xx_dss_feats = {
	.model			=	DSS_MODEL_OMAP3,
	.fck_div_max		=	16,
	.fck_freq_max		=	173000000,
	.dss_fck_multiplier	=	2,
	.parent_clk_name	=	"dpll4_ck",
	.ports			=	omap34xx_ports,
	.outputs		=	omap3430_dss_supported_outputs,
	.num_ports		=	ARRAY_SIZE(omap34xx_ports),
	.ops			=	&dss_ops_omap2_omap3,
	.dispc_clk_switch	=	{ 0, 0 },
	.has_lcd_clk_src	=	false,
};

static const struct dss_features omap3630_dss_feats = {
	.model			=	DSS_MODEL_OMAP3,
	.fck_div_max		=	32,
	.fck_freq_max		=	173000000,
	.dss_fck_multiplier	=	1,
	.parent_clk_name	=	"dpll4_ck",
	.ports			=	omap2plus_ports,
	.num_ports		=	ARRAY_SIZE(omap2plus_ports),
	.outputs		=	omap3630_dss_supported_outputs,
	.ops			=	&dss_ops_omap2_omap3,
	.dispc_clk_switch	=	{ 0, 0 },
	.has_lcd_clk_src	=	false,
};

static const struct dss_features omap44xx_dss_feats = {
	.model			=	DSS_MODEL_OMAP4,
	.fck_div_max		=	32,
	.fck_freq_max		=	186000000,
	.dss_fck_multiplier	=	1,
	.parent_clk_name	=	"dpll_per_x2_ck",
	.ports			=	omap2plus_ports,
	.num_ports		=	ARRAY_SIZE(omap2plus_ports),
	.outputs		=	omap4_dss_supported_outputs,
	.ops			=	&dss_ops_omap4,
	.dispc_clk_switch	=	{ 9, 8 },
	.has_lcd_clk_src	=	true,
};

static const struct dss_features omap54xx_dss_feats = {
	.model			=	DSS_MODEL_OMAP5,
	.fck_div_max		=	64,
	.fck_freq_max		=	209250000,
	.dss_fck_multiplier	=	1,
	.parent_clk_name	=	"dpll_per_x2_ck",
	.ports			=	omap2plus_ports,
	.num_ports		=	ARRAY_SIZE(omap2plus_ports),
	.outputs		=	omap5_dss_supported_outputs,
	.ops			=	&dss_ops_omap5,
	.dispc_clk_switch	=	{ 9, 7 },
	.has_lcd_clk_src	=	true,
};

static const struct dss_features am43xx_dss_feats = {
	.model			=	DSS_MODEL_OMAP3,
	.fck_div_max		=	0,
	.fck_freq_max		=	200000000,
	.dss_fck_multiplier	=	0,
	.parent_clk_name	=	NULL,
	.ports			=	omap2plus_ports,
	.num_ports		=	ARRAY_SIZE(omap2plus_ports),
	.outputs		=	am43xx_dss_supported_outputs,
	.ops			=	&dss_ops_omap2_omap3,
	.dispc_clk_switch	=	{ 0, 0 },
	.has_lcd_clk_src	=	true,
};

static const struct dss_features dra7xx_dss_feats = {
	.model			=	DSS_MODEL_DRA7,
	.fck_div_max		=	64,
	.fck_freq_max		=	209250000,
	.dss_fck_multiplier	=	1,
	.parent_clk_name	=	"dpll_per_x2_ck",
	.ports			=	dra7xx_ports,
	.num_ports		=	ARRAY_SIZE(dra7xx_ports),
	.outputs		=	omap5_dss_supported_outputs,
	.ops			=	&dss_ops_dra7,
	.dispc_clk_switch	=	{ 9, 7 },
	.has_lcd_clk_src	=	true,
};

static int dss_init_ports(struct platform_device *pdev)
{
	struct device_node *parent = pdev->dev.of_node;
	struct device_node *port;
	int i;

	for (i = 0; i < dss.feat->num_ports; i++) {
		port = of_graph_get_port_by_id(parent, i);
		if (!port)
			continue;

		switch (dss.feat->ports[i]) {
		case OMAP_DISPLAY_TYPE_DPI:
			dpi_init_port(pdev, port, dss.feat->model);
			break;
		case OMAP_DISPLAY_TYPE_SDI:
			sdi_init_port(pdev, port);
			break;
		default:
			break;
		}
	}

	return 0;
}

static void dss_uninit_ports(struct platform_device *pdev)
{
	struct device_node *parent = pdev->dev.of_node;
	struct device_node *port;
	int i;

	for (i = 0; i < dss.feat->num_ports; i++) {
		port = of_graph_get_port_by_id(parent, i);
		if (!port)
			continue;

		switch (dss.feat->ports[i]) {
		case OMAP_DISPLAY_TYPE_DPI:
			dpi_uninit_port(port);
			break;
		case OMAP_DISPLAY_TYPE_SDI:
			sdi_uninit_port(port);
			break;
		default:
			break;
		}
	}
}

static int dss_video_pll_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct regulator *pll_regulator;
	int r;

	if (!np)
		return 0;

	if (of_property_read_bool(np, "syscon-pll-ctrl")) {
		dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
			"syscon-pll-ctrl");
		if (IS_ERR(dss.syscon_pll_ctrl)) {
			dev_err(&pdev->dev,
				"failed to get syscon-pll-ctrl regmap\n");
			return PTR_ERR(dss.syscon_pll_ctrl);
		}

		if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
				&dss.syscon_pll_ctrl_offset)) {
			dev_err(&pdev->dev,
				"failed to get syscon-pll-ctrl offset\n");
			return -EINVAL;
		}
	}

	pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
	if (IS_ERR(pll_regulator)) {
		r = PTR_ERR(pll_regulator);

		switch (r) {
		case -ENOENT:
			pll_regulator = NULL;
			break;

		case -EPROBE_DEFER:
			return -EPROBE_DEFER;

		default:
			DSSERR("can't get DPLL VDDA regulator\n");
			return r;
		}
	}

	if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
		dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
		if (IS_ERR(dss.video1_pll))
			return PTR_ERR(dss.video1_pll);
	}

	if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
		dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
		if (IS_ERR(dss.video2_pll)) {
			dss_video_pll_uninit(dss.video1_pll);
			return PTR_ERR(dss.video2_pll);
		}
	}

	return 0;
}

/* DSS HW IP initialisation */
static const struct of_device_id dss_of_match[] = {
	{ .compatible = "ti,omap2-dss", .data = &omap24xx_dss_feats },
	{ .compatible = "ti,omap3-dss", .data = &omap3630_dss_feats },
	{ .compatible = "ti,omap4-dss", .data = &omap44xx_dss_feats },
	{ .compatible = "ti,omap5-dss", .data = &omap54xx_dss_feats },
	{ .compatible = "ti,dra7-dss",  .data = &dra7xx_dss_feats },
	{},
};
MODULE_DEVICE_TABLE(of, dss_of_match);

static const struct soc_device_attribute dss_soc_devices[] = {
	{ .machine = "OMAP3430/3530", .data = &omap34xx_dss_feats },
	{ .machine = "AM35??",        .data = &omap34xx_dss_feats },
	{ .family  = "AM43xx",        .data = &am43xx_dss_feats },
	{ /* sentinel */ }
};

static int dss_bind(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct resource *dss_mem;
	u32 rev;
	int r;

	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
	dss.base = devm_ioremap_resource(&pdev->dev, dss_mem);
	if (IS_ERR(dss.base))
		return PTR_ERR(dss.base);

	r = dss_get_clocks();
	if (r)
		return r;

	r = dss_setup_default_clock();
	if (r)
		goto err_setup_clocks;

	r = dss_video_pll_probe(pdev);
	if (r)
		goto err_pll_init;

	r = dss_init_ports(pdev);
	if (r)
		goto err_init_ports;

	pm_runtime_enable(&pdev->dev);

	r = dss_runtime_get();
	if (r)
		goto err_runtime_get;

	dss.dss_clk_rate = clk_get_rate(dss.dss_clk);

	/* Select DPLL */
	REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);

	dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);

#ifdef CONFIG_OMAP2_DSS_VENC
	REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);	/* venc dac demen */
	REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);	/* venc clock 4x enable */
	REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);	/* venc clock mode = normal */
#endif
	dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK;
	dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK;
	dss.dispc_clk_source = DSS_CLK_SRC_FCK;
	dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
	dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;

	rev = dss_read_reg(DSS_REVISION);
	pr_info("OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));

	dss_runtime_put();

	r = component_bind_all(&pdev->dev, NULL);
	if (r)
		goto err_component;

	dss_debugfs_create_file("dss", dss_dump_regs);

	pm_set_vt_switch(0);

	omapdss_gather_components(dev);
	omapdss_set_is_initialized(true);

	return 0;

err_component:
err_runtime_get:
	pm_runtime_disable(&pdev->dev);
	dss_uninit_ports(pdev);
err_init_ports:
	if (dss.video1_pll)
		dss_video_pll_uninit(dss.video1_pll);

	if (dss.video2_pll)
		dss_video_pll_uninit(dss.video2_pll);
err_pll_init:
err_setup_clocks:
	dss_put_clocks();
	return r;
}

static void dss_unbind(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);

	omapdss_set_is_initialized(false);

	component_unbind_all(&pdev->dev, NULL);

	if (dss.video1_pll)
		dss_video_pll_uninit(dss.video1_pll);

	if (dss.video2_pll)
		dss_video_pll_uninit(dss.video2_pll);

	dss_uninit_ports(pdev);

	pm_runtime_disable(&pdev->dev);

	dss_put_clocks();
}

static const struct component_master_ops dss_component_ops = {
	.bind = dss_bind,
	.unbind = dss_unbind,
};

static int dss_component_compare(struct device *dev, void *data)
{
	struct device *child = data;
	return dev == child;
}

static int dss_add_child_component(struct device *dev, void *data)
{
	struct component_match **match = data;

	/*
	 * HACK
	 * We don't have a working driver for rfbi, so skip it here always.
	 * Otherwise dss will never get probed successfully, as it will wait
	 * for rfbi to get probed.
	 */
	if (strstr(dev_name(dev), "rfbi"))
		return 0;

	component_match_add(dev->parent, match, dss_component_compare, dev);

	return 0;
}

static int dss_probe(struct platform_device *pdev)
{
	const struct soc_device_attribute *soc;
	struct component_match *match = NULL;
	int r;

	dss.pdev = pdev;

	/*
	 * The various OMAP3-based SoCs can't be told apart using the compatible
	 * string, use SoC device matching.
	 */
	soc = soc_device_match(dss_soc_devices);
	if (soc)
		dss.feat = soc->data;
	else
		dss.feat = of_match_device(dss_of_match, &pdev->dev)->data;

	r = dss_initialize_debugfs();
	if (r)
		return r;

	/* add all the child devices as components */
	device_for_each_child(&pdev->dev, &match, dss_add_child_component);

	r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
	if (r) {
		dss_uninitialize_debugfs();
		return r;
	}

	return 0;
}

static int dss_remove(struct platform_device *pdev)
{
	component_master_del(&pdev->dev, &dss_component_ops);

	dss_uninitialize_debugfs();

	return 0;
}

static void dss_shutdown(struct platform_device *pdev)
{
	struct omap_dss_device *dssdev = NULL;

	DSSDBG("shutdown\n");

	for_each_dss_dev(dssdev) {
		if (!dssdev->driver)
			continue;

		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
			dssdev->driver->disable(dssdev);
	}
}

static int dss_runtime_suspend(struct device *dev)
{
	dss_save_context();
	dss_set_min_bus_tput(dev, 0);

	pinctrl_pm_select_sleep_state(dev);

	return 0;
}

static int dss_runtime_resume(struct device *dev)
{
	int r;

	pinctrl_pm_select_default_state(dev);

	/*
	 * Set an arbitrarily high tput request to ensure OPP100.
	 * What we should really do is to make a request to stay in OPP100,
	 * without any tput requirements, but that is not currently possible
	 * via the PM layer.
	 */

	r = dss_set_min_bus_tput(dev, 1000000000);
	if (r)
		return r;

	dss_restore_context();
	return 0;
}

static const struct dev_pm_ops dss_pm_ops = {
	.runtime_suspend = dss_runtime_suspend,
	.runtime_resume = dss_runtime_resume,
};

static struct platform_driver omap_dsshw_driver = {
	.probe		= dss_probe,
	.remove		= dss_remove,
	.shutdown	= dss_shutdown,
	.driver         = {
		.name   = "omapdss_dss",
		.pm	= &dss_pm_ops,
		.of_match_table = dss_of_match,
		.suppress_bind_attrs = true,
	},
};

int __init dss_init_platform_driver(void)
{
	return platform_driver_register(&omap_dsshw_driver);
}

void dss_uninit_platform_driver(void)
{
	platform_driver_unregister(&omap_dsshw_driver);
}
