1559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen/*
2559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * linux/drivers/video/omap2/dss/dss.c
3559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen *
4559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * Copyright (C) 2009 Nokia Corporation
5559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen *
7559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * Some code and ideas taken from drivers/video/omap/ driver
8559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * by Imre Deak.
9559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen *
10559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * This program is free software; you can redistribute it and/or modify it
11559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * under the terms of the GNU General Public License version 2 as published by
12559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * the Free Software Foundation.
13559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen *
14559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * This program is distributed in the hope that it will be useful, but WITHOUT
15559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * more details.
18559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen *
19559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * You should have received a copy of the GNU General Public License along with
20559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen * this program.  If not, see <http://www.gnu.org/licenses/>.
21559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen */
22559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
23559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SUBSYS_NAME "DSS"
24559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
25559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/kernel.h>
262ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#include <linux/module.h>
27559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/io.h>
28a8a359318530a779c8d28d86357d492adead5b1fPaul Gortmaker#include <linux/export.h>
29559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/err.h>
30559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/delay.h>
31559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/seq_file.h>
32559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/clk.h>
3324e6289c029b0cf5b4f75e12c1b66000d441c9edTomi Valkeinen#include <linux/platform_device.h>
344fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen#include <linux/pm_runtime.h>
35185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra#include <linux/gfp.h>
3633366d0e8be06b980784c732ebace26de08e6679Tomi Valkeinen#include <linux/sizes.h>
372ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#include <linux/of.h>
38559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
39a0b38cc4d35e095f14ab0f486135f8a619ebfc14Tomi Valkeinen#include <video/omapdss.h>
402c799cef4d145af2182594a41cb5e5b42f2535c5Tony Lindgren
41559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include "dss.h"
426ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen#include "dss_features.h"
43559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
44559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SZ_REGS			SZ_512
45559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
46559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstruct dss_reg {
47559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	u16 idx;
48559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen};
49559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
50559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_REG(idx)			((const struct dss_reg) { idx })
51559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
52559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_REVISION			DSS_REG(0x0000)
53559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SYSCONFIG			DSS_REG(0x0010)
54559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SYSSTATUS			DSS_REG(0x0014)
55559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_CONTROL			DSS_REG(0x0040)
56559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SDI_CONTROL			DSS_REG(0x0044)
57559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_PLL_CONTROL			DSS_REG(0x0048)
58559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SDI_STATUS			DSS_REG(0x005C)
59559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
60559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define REG_GET(idx, start, end) \
61559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	FLD_GET(dss_read_reg(idx), start, end)
62559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
63559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define REG_FLD_MOD(idx, val, start, end) \
64559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
65559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
66852f083843af618eaa8997f7803c9aed8293fdf9Tomi Valkeinenstatic int dss_runtime_get(void);
67852f083843af618eaa8997f7803c9aed8293fdf9Tomi Valkeinenstatic void dss_runtime_put(void);
68852f083843af618eaa8997f7803c9aed8293fdf9Tomi Valkeinen
69185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatrastruct dss_features {
70185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	u8 fck_div_max;
71185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	u8 dss_fck_multiplier;
7264ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen	const char *parent_clk_name;
73de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	int (*dpi_select_source)(enum omap_channel channel);
74185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra};
75185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
76559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic struct {
7796c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	struct platform_device *pdev;
78559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	void __iomem    *base;
794fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen
8064ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen	struct clk	*parent_clk;
814fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	struct clk	*dss_clk;
825aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen	unsigned long	dss_clk_rate;
83559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
84559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long	cache_req_pck;
85559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long	cache_prate;
86559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	struct dispc_clock_info cache_dispc_cinfo;
87559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
885a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja	enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
8989a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	enum omap_dss_clk_source dispc_clk_source;
9089a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
912f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
9269f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen	bool		ctx_valid;
93559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
94185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
95185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	const struct dss_features *feat;
96559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen} dss;
97559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
98235e7dba0264d4c6e56ee217fc7ef6d80da5eb67Archit Tanejastatic const char * const dss_generic_clk_source_names[] = {
9989a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]	= "DSI_PLL_HSDIV_DISPC",
10089a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]	= "DSI_PLL_HSDIV_DSI",
10189a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCK",
102901e5fe5a47d360a8ad6b5fbbe37e107ddb11662Tomi Valkeinen	[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC]	= "DSI_PLL2_HSDIV_DISPC",
103901e5fe5a47d360a8ad6b5fbbe37e107ddb11662Tomi Valkeinen	[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]	= "DSI_PLL2_HSDIV_DSI",
104067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja};
105067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja
106559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic inline void dss_write_reg(const struct dss_reg idx, u32 val)
107559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
108559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	__raw_writel(val, dss.base + idx.idx);
109559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
110559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
111559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic inline u32 dss_read_reg(const struct dss_reg idx)
112559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
113559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return __raw_readl(dss.base + idx.idx);
114559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
115559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
116559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define SR(reg) \
117559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
118559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define RR(reg) \
119559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
120559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
1214fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic void dss_save_context(void)
122559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
1234fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	DSSDBG("dss_save_context\n");
124559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
125559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	SR(CONTROL);
126559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
1276ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
1286ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen			OMAP_DISPLAY_TYPE_SDI) {
1296ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		SR(SDI_CONTROL);
1306ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		SR(PLL_CONTROL);
1316ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	}
13269f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen
13369f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen	dss.ctx_valid = true;
13469f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen
13569f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen	DSSDBG("context saved\n");
136559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
137559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
1384fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic void dss_restore_context(void)
139559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
1404fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	DSSDBG("dss_restore_context\n");
141559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
14269f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen	if (!dss.ctx_valid)
14369f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen		return;
14469f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen
145559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	RR(CONTROL);
146559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
1476ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
1486ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen			OMAP_DISPLAY_TYPE_SDI) {
1496ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		RR(SDI_CONTROL);
1506ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		RR(PLL_CONTROL);
1516ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	}
15269f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen
15369f06054aad122b314cd64fdafdf14fc3b8e5b7cTomi Valkeinen	DSSDBG("context restored\n");
154559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
155559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
156559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#undef SR
157559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#undef RR
158559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
159889b4fd7eed2d7c155dc642e15a714f87ab2842cArchit Tanejavoid dss_sdi_init(int datapairs)
160559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
161559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	u32 l;
162559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
163559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	BUG_ON(datapairs > 3 || datapairs < 1);
164559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
165559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = dss_read_reg(DSS_SDI_CONTROL);
166559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0xf, 19, 15);		/* SDI_PDIV */
167559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, datapairs-1, 3, 2);	/* SDI_PRSEL */
168559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 2, 1, 0);		/* SDI_BWSEL */
169559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(DSS_SDI_CONTROL, l);
170559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
171559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = dss_read_reg(DSS_PLL_CONTROL);
172559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0x7, 25, 22);	/* SDI_PLL_FREQSEL */
173559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0xb, 16, 11);	/* SDI_PLL_REGN */
174559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0xb4, 10, 1);	/* SDI_PLL_REGM */
175559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(DSS_PLL_CONTROL, l);
176559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
177559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
178559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenint dss_sdi_enable(void)
179559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
180559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long timeout;
181559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
182559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_pck_free_enable(1);
183559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
184559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Reset SDI PLL */
185559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
186559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	udelay(1);	/* wait 2x PCLK */
187559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
188559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Lock SDI PLL */
189559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
190559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
191559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Waiting for PLL lock request to complete */
192559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	timeout = jiffies + msecs_to_jiffies(500);
193559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
194559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (time_after_eq(jiffies, timeout)) {
195559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("PLL lock request timed out\n");
196559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			goto err1;
197559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
198559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
199559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
200559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Clearing PLL_GO bit */
201559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
202559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
203559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Waiting for PLL to lock */
204559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	timeout = jiffies + msecs_to_jiffies(500);
205559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
206559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (time_after_eq(jiffies, timeout)) {
207559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("PLL lock timed out\n");
208559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			goto err1;
209559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
210559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
211559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
212559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_lcd_enable_signal(1);
213559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
214559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Waiting for SDI reset to complete */
215559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	timeout = jiffies + msecs_to_jiffies(500);
216559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
217559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (time_after_eq(jiffies, timeout)) {
218559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("SDI reset timed out\n");
219559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			goto err2;
220559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
221559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
222559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
223559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
224559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
225559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen err2:
226559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_lcd_enable_signal(0);
227559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen err1:
228559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Reset SDI PLL */
229559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
230559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
231559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_pck_free_enable(0);
232559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
233559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return -ETIMEDOUT;
234559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
235559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
236559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_sdi_disable(void)
237559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
238559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_lcd_enable_signal(0);
239559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
240559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_pck_free_enable(0);
241559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
242559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Reset SDI PLL */
243559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
244559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
245559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
24689a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Tanejaconst char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
247067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja{
248235e7dba0264d4c6e56ee217fc7ef6d80da5eb67Archit Taneja	return dss_generic_clk_source_names[clk_src];
249067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja}
250067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja
251559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_dump_clocks(struct seq_file *s)
252559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
2530acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	const char *fclk_name, *fclk_real_name;
2540acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	unsigned long fclk_rate;
255559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2564fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	if (dss_runtime_get())
2574fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen		return;
258559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
259559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	seq_printf(s, "- DSS -\n");
260559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
26189a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
26289a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
2634fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	fclk_rate = clk_get_rate(dss.dss_clk);
264559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2659c15d76200dbd9c0ae5b1c6bfa17cbfdfaa2e2aeTomi Valkeinen	seq_printf(s, "%s (%s) = %lu\n",
2669c15d76200dbd9c0ae5b1c6bfa17cbfdfaa2e2aeTomi Valkeinen			fclk_name, fclk_real_name,
2679c15d76200dbd9c0ae5b1c6bfa17cbfdfaa2e2aeTomi Valkeinen			fclk_rate);
268559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2694fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	dss_runtime_put();
270559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
271559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
272e40402cf182e798fd71824f4ad02fb51ce599bb2Tomi Valkeinenstatic void dss_dump_regs(struct seq_file *s)
273559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
274559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
275559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2764fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	if (dss_runtime_get())
2774fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen		return;
278559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
279559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_REVISION);
280559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_SYSCONFIG);
281559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_SYSSTATUS);
282559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_CONTROL);
2836ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen
2846ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
2856ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen			OMAP_DISPLAY_TYPE_SDI) {
2866ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		DUMPREG(DSS_SDI_CONTROL);
2876ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		DUMPREG(DSS_PLL_CONTROL);
2886ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		DUMPREG(DSS_SDI_STATUS);
2896ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	}
290559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2914fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	dss_runtime_put();
292559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#undef DUMPREG
293559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
294559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
295a5b8399fb6866be6ca065d8ab5eb7d8775d0ad26Tomi Valkeinenstatic void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
2962f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen{
297a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja	struct platform_device *dsidev;
2982f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	int b;
299ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	u8 start, end;
3002f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
30166534e8e936a0b926863df90054dc59826d70528Archit Taneja	switch (clk_src) {
30289a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	case OMAP_DSS_CLK_SRC_FCK:
30366534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 0;
30466534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
30589a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
30666534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 1;
307a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja		dsidev = dsi_get_dsidev_from_id(0);
308a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja		dsi_wait_pll_hsdiv_dispc_active(dsidev);
30966534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
3105a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
3115a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		b = 2;
3125a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		dsidev = dsi_get_dsidev_from_id(1);
3135a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		dsi_wait_pll_hsdiv_dispc_active(dsidev);
3145a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		break;
31566534e8e936a0b926863df90054dc59826d70528Archit Taneja	default:
31666534e8e936a0b926863df90054dc59826d70528Archit Taneja		BUG();
317c6eee968d40d319f0ac7a8a63dcbc633d9e6a2eaTomi Valkeinen		return;
31866534e8e936a0b926863df90054dc59826d70528Archit Taneja	}
319e406f9079b993f4d5d7b5a3452b11df81ff2aef0Tomi Valkeinen
320ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
321ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
322ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	REG_FLD_MOD(DSS_CONTROL, b, start, end);	/* DISPC_CLK_SWITCH */
3232f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
3242f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	dss.dispc_clk_source = clk_src;
3252f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen}
3262f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
3275a8b572d832772722c3b3b7578e7fb968560fcf3Archit Tanejavoid dss_select_dsi_clk_source(int dsi_module,
3285a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		enum omap_dss_clk_source clk_src)
329559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
330a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja	struct platform_device *dsidev;
331a2e5d82758a82b4848f00b1f28f8f71920e1b076Archit Taneja	int b, pos;
3322f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
33366534e8e936a0b926863df90054dc59826d70528Archit Taneja	switch (clk_src) {
33489a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	case OMAP_DSS_CLK_SRC_FCK:
33566534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 0;
33666534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
33789a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
3385a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		BUG_ON(dsi_module != 0);
33966534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 1;
340a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja		dsidev = dsi_get_dsidev_from_id(0);
341a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja		dsi_wait_pll_hsdiv_dsi_active(dsidev);
34266534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
3435a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
3445a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		BUG_ON(dsi_module != 1);
3455a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		b = 1;
3465a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		dsidev = dsi_get_dsidev_from_id(1);
3475a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		dsi_wait_pll_hsdiv_dsi_active(dsidev);
3485a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		break;
34966534e8e936a0b926863df90054dc59826d70528Archit Taneja	default:
35066534e8e936a0b926863df90054dc59826d70528Archit Taneja		BUG();
351c6eee968d40d319f0ac7a8a63dcbc633d9e6a2eaTomi Valkeinen		return;
35266534e8e936a0b926863df90054dc59826d70528Archit Taneja	}
353e406f9079b993f4d5d7b5a3452b11df81ff2aef0Tomi Valkeinen
354a2e5d82758a82b4848f00b1f28f8f71920e1b076Archit Taneja	pos = dsi_module == 0 ? 1 : 10;
355a2e5d82758a82b4848f00b1f28f8f71920e1b076Archit Taneja	REG_FLD_MOD(DSS_CONTROL, b, pos, pos);	/* DSIx_CLK_SWITCH */
3562f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
3575a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja	dss.dsi_clk_source[dsi_module] = clk_src;
358559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
359559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
360ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Tanejavoid dss_select_lcd_clk_source(enum omap_channel channel,
36189a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja		enum omap_dss_clk_source clk_src)
362ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja{
363a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja	struct platform_device *dsidev;
364ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	int b, ix, pos;
365ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
366a5b8399fb6866be6ca065d8ab5eb7d8775d0ad26Tomi Valkeinen	if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
367a5b8399fb6866be6ca065d8ab5eb7d8775d0ad26Tomi Valkeinen		dss_select_dispc_clk_source(clk_src);
368ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		return;
369a5b8399fb6866be6ca065d8ab5eb7d8775d0ad26Tomi Valkeinen	}
370ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
371ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	switch (clk_src) {
37289a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	case OMAP_DSS_CLK_SRC_FCK:
373ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		b = 0;
374ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		break;
37589a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Taneja	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
376ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
377ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		b = 1;
378a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja		dsidev = dsi_get_dsidev_from_id(0);
379a72b64b99918ee801a3a6abf5391e356752bcad0Archit Taneja		dsi_wait_pll_hsdiv_dispc_active(dsidev);
380ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		break;
3815a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
382e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra		BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
383e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra		       channel != OMAP_DSS_CHANNEL_LCD3);
3845a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		b = 1;
3855a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		dsidev = dsi_get_dsidev_from_id(1);
3865a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		dsi_wait_pll_hsdiv_dispc_active(dsidev);
3875a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja		break;
388ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	default:
389ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		BUG();
390c6eee968d40d319f0ac7a8a63dcbc633d9e6a2eaTomi Valkeinen		return;
391ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	}
392ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
393e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra	pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
394e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra	     (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
395ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	REG_FLD_MOD(DSS_CONTROL, b, pos, pos);	/* LCDx_CLK_SWITCH */
396ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
397e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra	ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
398e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra	    (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
399ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	dss.lcd_clk_source[ix] = clk_src;
400ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja}
401ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
40289a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Tanejaenum omap_dss_clk_source dss_get_dispc_clk_source(void)
403559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
4042f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	return dss.dispc_clk_source;
405559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
406559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
4075a8b572d832772722c3b3b7578e7fb968560fcf3Archit Tanejaenum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
408559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
4095a8b572d832772722c3b3b7578e7fb968560fcf3Archit Taneja	return dss.dsi_clk_source[dsi_module];
410559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
411559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
41289a35e5170fc579e4fc3a1f3444c5dc1aa36904dArchit Tanejaenum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
413ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja{
41489976f2990a97820b73a1768371ee505b0ffc176Archit Taneja	if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
415e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra		int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
416e86d456a23f3ecbb97704e63899ecfd6ec54b8d8Chandrabhanu Mahapatra			(channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
41789976f2990a97820b73a1768371ee505b0ffc176Archit Taneja		return dss.lcd_clk_source[ix];
41889976f2990a97820b73a1768371ee505b0ffc176Archit Taneja	} else {
41989976f2990a97820b73a1768371ee505b0ffc176Archit Taneja		/* LCD_CLK source is the same as DISPC_FCLK source for
42089976f2990a97820b73a1768371ee505b0ffc176Archit Taneja		 * OMAP2 and OMAP3 */
42189976f2990a97820b73a1768371ee505b0ffc176Archit Taneja		return dss.dispc_clk_source;
42289976f2990a97820b73a1768371ee505b0ffc176Archit Taneja	}
423ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja}
424ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
425688af02d22c11a077532d6437e4afc7bdc972f82Tomi Valkeinenbool dss_div_calc(unsigned long pck, unsigned long fck_min,
426688af02d22c11a077532d6437e4afc7bdc972f82Tomi Valkeinen		dss_div_calc_func func, void *data)
42743417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen{
42843417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	int fckd, fckd_start, fckd_stop;
42943417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	unsigned long fck;
43043417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	unsigned long fck_hw_max;
43143417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	unsigned long fckd_hw_max;
43243417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	unsigned long prate;
433648a55e1254117bd7500747a789f0b112c7af240Tomi Valkeinen	unsigned m;
43443417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
435fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen	fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
436fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen
43764ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen	if (dss.parent_clk == NULL) {
438fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen		unsigned pckd;
439fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen
440fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen		pckd = fck_hw_max / pck;
441fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen
442fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen		fck = pck * pckd;
443fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen
444fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen		fck = clk_round_rate(dss.dss_clk, fck);
445fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen
446d0f58bd3bba3877fb1af4664c4e33273d36f00e4Tomi Valkeinen		return func(fck, data);
44743417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	}
44843417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
44943417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	fckd_hw_max = dss.feat->fck_div_max;
45043417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
451648a55e1254117bd7500747a789f0b112c7af240Tomi Valkeinen	m = dss.feat->dss_fck_multiplier;
452ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	prate = clk_get_rate(dss.parent_clk);
45343417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
45443417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	fck_min = fck_min ? fck_min : 1;
45543417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
456648a55e1254117bd7500747a789f0b112c7af240Tomi Valkeinen	fckd_start = min(prate * m / fck_min, fckd_hw_max);
457648a55e1254117bd7500747a789f0b112c7af240Tomi Valkeinen	fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
45843417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
45943417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
460d0e224f9963b79610850b2a10622182176658022Tomi Valkeinen		fck = DIV_ROUND_UP(prate, fckd) * m;
46143417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
462d0f58bd3bba3877fb1af4664c4e33273d36f00e4Tomi Valkeinen		if (func(fck, data))
46343417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen			return true;
46443417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	}
46543417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
46643417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen	return false;
46743417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen}
46843417823fd8210edb7e714bea82ea9bd77089635Tomi Valkeinen
469d0f58bd3bba3877fb1af4664c4e33273d36f00e4Tomi Valkeinenint dss_set_fck_rate(unsigned long rate)
470559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
471ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	int r;
472559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
473ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	DSSDBG("set fck to %lu\n", rate);
474559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
475ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	r = clk_set_rate(dss.dss_clk, rate);
476ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	if (r)
477ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen		return r;
478559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
4795aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen	dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
4805aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen
481d0f58bd3bba3877fb1af4664c4e33273d36f00e4Tomi Valkeinen	WARN_ONCE(dss.dss_clk_rate != rate,
482648a55e1254117bd7500747a789f0b112c7af240Tomi Valkeinen			"clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
483d0f58bd3bba3877fb1af4664c4e33273d36f00e4Tomi Valkeinen			rate);
484559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
485559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
486559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
487559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
4885aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinenunsigned long dss_get_dispc_clk_rate(void)
4895aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen{
4905aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen	return dss.dss_clk_rate;
4915aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen}
4925aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen
49313a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinenstatic int dss_setup_default_clock(void)
49413a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen{
49513a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	unsigned long max_dss_fck, prate;
496d0f58bd3bba3877fb1af4664c4e33273d36f00e4Tomi Valkeinen	unsigned long fck;
49713a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	unsigned fck_div;
49813a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	int r;
49913a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen
50013a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
50113a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen
502fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen	if (dss.parent_clk == NULL) {
503fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen		fck = clk_round_rate(dss.dss_clk, max_dss_fck);
504fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen	} else {
505fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen		prate = clk_get_rate(dss.parent_clk);
50613a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen
507fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen		fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
508fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen				max_dss_fck);
509d0e224f9963b79610850b2a10622182176658022Tomi Valkeinen		fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
510fc1fe6e794cc85fcdb63daa9c7a977940ff49e4fTomi Valkeinen	}
51113a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen
512d0f58bd3bba3877fb1af4664c4e33273d36f00e4Tomi Valkeinen	r = dss_set_fck_rate(fck);
51313a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	if (r)
51413a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen		return r;
51513a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen
51613a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	return 0;
51713a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen}
51813a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen
519559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_set_venc_output(enum omap_dss_venc_type type)
520559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
521559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	int l = 0;
522559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
523559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
524559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		l = 0;
525559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
526559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		l = 1;
527559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	else
528559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		BUG();
529559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
530559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* venc out selection. 0 = comp, 1 = svideo */
531559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
532559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
533559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
534559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_set_dac_pwrdn_bgz(bool enable)
535559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
536559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);	/* DAC Power-Down Control */
537559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
538559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
5398aa2eed1348d615817de792cd205868348a5293dRicardo Nerivoid dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
5407ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P K{
5418aa2eed1348d615817de792cd205868348a5293dRicardo Neri	enum omap_display_type dp;
5428aa2eed1348d615817de792cd205868348a5293dRicardo Neri	dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
5438aa2eed1348d615817de792cd205868348a5293dRicardo Neri
5448aa2eed1348d615817de792cd205868348a5293dRicardo Neri	/* Complain about invalid selections */
5458aa2eed1348d615817de792cd205868348a5293dRicardo Neri	WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
5468aa2eed1348d615817de792cd205868348a5293dRicardo Neri	WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
5478aa2eed1348d615817de792cd205868348a5293dRicardo Neri
5488aa2eed1348d615817de792cd205868348a5293dRicardo Neri	/* Select only if we have options */
5498aa2eed1348d615817de792cd205868348a5293dRicardo Neri	if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
5508aa2eed1348d615817de792cd205868348a5293dRicardo Neri		REG_FLD_MOD(DSS_CONTROL, src, 15, 15);	/* VENC_HDMI_SWITCH */
5517ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P K}
5527ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P K
5534a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinenenum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
5544a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen{
5554a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen	enum omap_display_type displays;
5564a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen
5574a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen	displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
5584a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen	if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
5594a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen		return DSS_VENC_TV_CLK;
5604a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen
5618aa2eed1348d615817de792cd205868348a5293dRicardo Neri	if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
5628aa2eed1348d615817de792cd205868348a5293dRicardo Neri		return DSS_HDMI_M_PCLK;
5638aa2eed1348d615817de792cd205868348a5293dRicardo Neri
5644a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen	return REG_GET(DSS_CONTROL, 15, 15);
5654a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen}
5664a61e267c84e98caeddcab25432a871bf1a599ddTomi Valkeinen
567de09e4555592986219132b518c3f7834a28823cdTomi Valkeinenstatic int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
568de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen{
569de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	if (channel != OMAP_DSS_CHANNEL_LCD)
570de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		return -EINVAL;
571de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
572de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	return 0;
573de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen}
574de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
575de09e4555592986219132b518c3f7834a28823cdTomi Valkeinenstatic int dss_dpi_select_source_omap4(enum omap_channel channel)
576de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen{
577de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	int val;
578de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
579de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	switch (channel) {
580de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	case OMAP_DSS_CHANNEL_LCD2:
581de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		val = 0;
582de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		break;
583de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	case OMAP_DSS_CHANNEL_DIGIT:
584de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		val = 1;
585de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		break;
586de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	default:
587de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		return -EINVAL;
588de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	}
589de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
590de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
591de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
592de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	return 0;
593de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen}
594de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
595de09e4555592986219132b518c3f7834a28823cdTomi Valkeinenstatic int dss_dpi_select_source_omap5(enum omap_channel channel)
596de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen{
597de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	int val;
598de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
599de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	switch (channel) {
600de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	case OMAP_DSS_CHANNEL_LCD:
601de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		val = 1;
602de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		break;
603de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	case OMAP_DSS_CHANNEL_LCD2:
604de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		val = 2;
605de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		break;
606de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	case OMAP_DSS_CHANNEL_LCD3:
607de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		val = 3;
608de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		break;
609de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	case OMAP_DSS_CHANNEL_DIGIT:
610de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		val = 0;
611de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		break;
612de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	default:
613de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen		return -EINVAL;
614de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	}
615de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
616de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
617de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
618de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	return 0;
619de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen}
620de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
621de09e4555592986219132b518c3f7834a28823cdTomi Valkeinenint dss_dpi_select_source(enum omap_channel channel)
622de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen{
623de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	return dss.feat->dpi_select_source(channel);
624de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen}
625de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen
6268b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic int dss_get_clocks(void)
6278b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
6284fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	struct clk *clk;
6298b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
630b2c9c8ee7cec4c7d8fa90375f9de92ecf3045ebbArchit Taneja	clk = devm_clk_get(&dss.pdev->dev, "fck");
6314fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	if (IS_ERR(clk)) {
6324fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen		DSSERR("can't get clock fck\n");
633b2c9c8ee7cec4c7d8fa90375f9de92ecf3045ebbArchit Taneja		return PTR_ERR(clk);
634a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	}
6358b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
6364fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	dss.dss_clk = clk;
6378b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
63864ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen	if (dss.feat->parent_clk_name) {
63964ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen		clk = clk_get(NULL, dss.feat->parent_clk_name);
6408ad9375f8b7c709b89f7de4de413bb2644ba3c24Aaro Koskinen		if (IS_ERR(clk)) {
64164ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen			DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
642b2c9c8ee7cec4c7d8fa90375f9de92ecf3045ebbArchit Taneja			return PTR_ERR(clk);
6438ad9375f8b7c709b89f7de4de413bb2644ba3c24Aaro Koskinen		}
6448ad9375f8b7c709b89f7de4de413bb2644ba3c24Aaro Koskinen	} else {
6458ad9375f8b7c709b89f7de4de413bb2644ba3c24Aaro Koskinen		clk = NULL;
64694c042ce589b6b81e5dc0020fce2d248940412bdTomi Valkeinen	}
64794c042ce589b6b81e5dc0020fce2d248940412bdTomi Valkeinen
64864ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen	dss.parent_clk = clk;
64994c042ce589b6b81e5dc0020fce2d248940412bdTomi Valkeinen
6508b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return 0;
6518b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
6528b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
6538b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_put_clocks(void)
6548b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
65564ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen	if (dss.parent_clk)
65664ad846ffd9fe2d29ac9d2f68a4866f67ad9e3f1Tomi Valkeinen		clk_put(dss.parent_clk);
6578b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
6588b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
659852f083843af618eaa8997f7803c9aed8293fdf9Tomi Valkeinenstatic int dss_runtime_get(void)
6608b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
6614fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	int r;
6628b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
6634fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	DSSDBG("dss_runtime_get\n");
6648b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
6654fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	r = pm_runtime_get_sync(&dss.pdev->dev);
6664fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	WARN_ON(r < 0);
6674fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	return r < 0 ? r : 0;
6688b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
6698b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
670852f083843af618eaa8997f7803c9aed8293fdf9Tomi Valkeinenstatic void dss_runtime_put(void)
6718b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
6724fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	int r;
6738b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
6744fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	DSSDBG("dss_runtime_put\n");
6758b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
6760eaf9f52e94f756147dbfe1faf1f77a02378dbf9Tomi Valkeinen	r = pm_runtime_put_sync(&dss.pdev->dev);
6775be3aebd09f384fa2db8dda4fd99b73fc4be64f1Tomi Valkeinen	WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
6788b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
6798b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
6808b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy/* DEBUGFS */
6811b3bcb33fb9faeab29e5c734fa000f6c7746ea1cChandrabhanu Mahapatra#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
6828b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyvoid dss_debug_dump_clocks(struct seq_file *s)
6838b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
6848b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_dump_clocks(s);
6858b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dispc_dump_clocks(s);
6868b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#ifdef CONFIG_OMAP2_DSS_DSI
6878b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dsi_dump_clocks(s);
6888b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#endif
6898b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
6908b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#endif
6918b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
69284273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinenstatic const struct dss_features omap24xx_dss_feats __initconst = {
6936e555e2752ea284bda55b0ee477a512e1525b84aTomi Valkeinen	/*
6946e555e2752ea284bda55b0ee477a512e1525b84aTomi Valkeinen	 * fck div max is really 16, but the divider range has gaps. The range
6956e555e2752ea284bda55b0ee477a512e1525b84aTomi Valkeinen	 * from 1 to 6 has no gaps, so let's use that as a max.
6966e555e2752ea284bda55b0ee477a512e1525b84aTomi Valkeinen	 */
6976e555e2752ea284bda55b0ee477a512e1525b84aTomi Valkeinen	.fck_div_max		=	6,
69884273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.dss_fck_multiplier	=	2,
699ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	.parent_clk_name	=	"core_ck",
700de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
70184273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen};
70284273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen
70384273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinenstatic const struct dss_features omap34xx_dss_feats __initconst = {
70484273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.fck_div_max		=	16,
70584273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.dss_fck_multiplier	=	2,
706ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	.parent_clk_name	=	"dpll4_ck",
707de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
70884273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen};
70984273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen
71084273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinenstatic const struct dss_features omap3630_dss_feats __initconst = {
71184273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.fck_div_max		=	32,
71284273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.dss_fck_multiplier	=	1,
713ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	.parent_clk_name	=	"dpll4_ck",
714de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
71584273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen};
71684273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen
71784273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinenstatic const struct dss_features omap44xx_dss_feats __initconst = {
71884273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.fck_div_max		=	32,
71984273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.dss_fck_multiplier	=	1,
720ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	.parent_clk_name	=	"dpll_per_x2_ck",
721de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	.dpi_select_source	=	&dss_dpi_select_source_omap4,
72284273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen};
72384273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen
72484273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinenstatic const struct dss_features omap54xx_dss_feats __initconst = {
72584273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.fck_div_max		=	64,
72684273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen	.dss_fck_multiplier	=	1,
727ada9443ff407f83a96abc15ea44a106250dd23f2Tomi Valkeinen	.parent_clk_name	=	"dpll_per_x2_ck",
728de09e4555592986219132b518c3f7834a28823cdTomi Valkeinen	.dpi_select_source	=	&dss_dpi_select_source_omap5,
72984273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen};
73084273a9593306926af56ad5b4a69029c2886c5deTomi Valkeinen
731d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M Rstatic const struct dss_features am43xx_dss_feats __initconst = {
732d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R	.fck_div_max		=	0,
733d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R	.dss_fck_multiplier	=	0,
734d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R	.parent_clk_name	=	NULL,
735d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
736d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R};
737d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R
738bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinenstatic int __init dss_init_features(struct platform_device *pdev)
739185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra{
740185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	const struct dss_features *src;
741185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	struct dss_features *dst;
742185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
743bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
744185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	if (!dst) {
745bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen		dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
746185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra		return -ENOMEM;
747185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	}
748185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
749b2c7d54f72c1c588e8851c882f0465705f5e9e55Tomi Valkeinen	switch (omapdss_get_version()) {
750bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP24xx:
751185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra		src = &omap24xx_dss_feats;
752bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen		break;
753bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen
754bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP34xx_ES1:
755bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP34xx_ES3:
756bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_AM35xx:
757185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra		src = &omap34xx_dss_feats;
758bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen		break;
759bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen
760bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP3630:
761185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra		src = &omap3630_dss_feats;
762bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen		break;
763bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen
764bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP4430_ES1:
765bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP4430_ES2:
766bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP4:
767185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra		src = &omap44xx_dss_feats;
768bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen		break;
769bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen
770bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	case OMAPDSS_VER_OMAP5:
771233628328037c02cf3db6165cab5d3f43587c5f3Archit Taneja		src = &omap54xx_dss_feats;
772bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen		break;
773bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen
774d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R	case OMAPDSS_VER_AM43xx:
775d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R		src = &am43xx_dss_feats;
776d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R		break;
777d6279d4ae18d4248c90dfcf02fa8c579b81ce43bSathya Prakash M R
778bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	default:
779185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra		return -ENODEV;
780bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	}
781185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
782185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	memcpy(dst, src, sizeof(*dst));
783185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	dss.feat = dst;
784185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
785185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	return 0;
786185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra}
787185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
7885f0bc7a9eec7e562be82b90bffee7a5370d38517Tomi Valkeinenstatic int __init dss_init_ports(struct platform_device *pdev)
7892ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen{
7902ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	struct device_node *parent = pdev->dev.of_node;
7912ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	struct device_node *port;
7922ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	int r;
7932ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
7942ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	if (parent == NULL)
7952ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		return 0;
7962ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
7972ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	port = omapdss_of_get_next_port(parent, NULL);
7980059277276bdbbcfeaed454017ec70628414d3feArchit Taneja	if (!port)
7992ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		return 0;
8002ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
8012ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	do {
8022ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		u32 reg;
8032ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
8042ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		r = of_property_read_u32(port, "reg", &reg);
8052ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		if (r)
8062ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen			reg = 0;
8072ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
8082ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_DPI
8092ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		if (reg == 0)
8102ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen			dpi_init_port(pdev, port);
8112ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#endif
8122ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
8132ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_SDI
8142ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		if (reg == 1)
8152ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen			sdi_init_port(pdev, port);
8162ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#endif
8172ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
8182ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	} while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
8192ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
8202ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	return 0;
8212ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen}
8222ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
823a41ca72e5733097c8e54784d42b3d340d5b504adFabian Frederickstatic void __exit dss_uninit_ports(void)
8242ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen{
8252ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_DPI
8262ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	dpi_uninit_port();
8272ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#endif
8282ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
8292ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_SDI
8302ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	sdi_uninit_port();
8312ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen#endif
8322ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen}
8332ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
83496c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy/* DSS HW IP initialisation */
8356e7e8f06b2c77dbb5d28062a174e4d67aec4b924Tomi Valkeinenstatic int __init omap_dsshw_probe(struct platform_device *pdev)
83696c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
837b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	struct resource *dss_mem;
838b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	u32 rev;
83996c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	int r;
84096c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
84196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	dss.pdev = pdev;
84296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
843bd81ed0818875e233a3d400cc3c70454a0a53c08Tomi Valkeinen	r = dss_init_features(dss.pdev);
844185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra	if (r)
845185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra		return r;
846185bae1095188aa199c9be64d6030d8dbfc65e0aChandrabhanu Mahapatra
847b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
848b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	if (!dss_mem) {
849b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen		DSSERR("can't get IORESOURCE_MEM DSS\n");
850cd3b34493f9b5de1d617e0be39f6cb5c59c9889cTomi Valkeinen		return -EINVAL;
851b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	}
852cd3b34493f9b5de1d617e0be39f6cb5c59c9889cTomi Valkeinen
8536e2a14d2c59f6208310eeb6b031e9d1c22b38c6aJulia Lawall	dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
8546e2a14d2c59f6208310eeb6b031e9d1c22b38c6aJulia Lawall				resource_size(dss_mem));
855b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	if (!dss.base) {
856b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen		DSSERR("can't ioremap DSS\n");
857cd3b34493f9b5de1d617e0be39f6cb5c59c9889cTomi Valkeinen		return -ENOMEM;
858b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	}
859b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen
8608b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	r = dss_get_clocks();
8618b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (r)
862cd3b34493f9b5de1d617e0be39f6cb5c59c9889cTomi Valkeinen		return r;
8638b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
86413a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	r = dss_setup_default_clock();
86513a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen	if (r)
86613a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen		goto err_setup_clocks;
86713a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinen
8684fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	pm_runtime_enable(&pdev->dev);
869b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen
8704fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	r = dss_runtime_get();
8714fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	if (r)
8724fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen		goto err_runtime_get;
873b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen
8745aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen	dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
8755aaee69d7fe02d1ffb76b6a31a588efa5f2742e3Tomi Valkeinen
876b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	/* Select DPLL */
877b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
878b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen
879a5b8399fb6866be6ca065d8ab5eb7d8775d0ad26Tomi Valkeinen	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
880a5b8399fb6866be6ca065d8ab5eb7d8775d0ad26Tomi Valkeinen
881b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen#ifdef CONFIG_OMAP2_DSS_VENC
882b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);	/* venc dac demen */
883b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);	/* venc clock 4x enable */
884b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);	/* venc clock mode = normal */
885b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen#endif
886b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
887b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
888b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
889b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
890b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
89196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
8922ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	dss_init_ports(pdev);
8932ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
894b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	rev = dss_read_reg(DSS_REVISION);
895b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
896b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
897b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen
8984fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	dss_runtime_put();
899b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen
900e40402cf182e798fd71824f4ad02fb51ce599bb2Tomi Valkeinen	dss_debugfs_create_file("dss", dss_dump_regs);
901e40402cf182e798fd71824f4ad02fb51ce599bb2Tomi Valkeinen
9028b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return 0;
903a57dd4fe7bef557afaa1a6cdb77cd95b2cba094eTomi Valkeinen
9044fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenerr_runtime_get:
9054fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	pm_runtime_disable(&pdev->dev);
90613a1a2b2a68d00d8d81417606571e004e10f6d91Tomi Valkeinenerr_setup_clocks:
9078b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_put_clocks();
90896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	return r;
90996c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
91096c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
9116e7e8f06b2c77dbb5d28062a174e4d67aec4b924Tomi Valkeinenstatic int __exit omap_dsshw_remove(struct platform_device *pdev)
91296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
9132ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	dss_uninit_ports();
9142ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
9154fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	pm_runtime_disable(&pdev->dev);
9168b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9178b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_put_clocks();
918b98482ed73810c4a970dee3402b35241d3ce4b7eTomi Valkeinen
91996c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	return 0;
92096c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
92196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
9224fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic int dss_runtime_suspend(struct device *dev)
9234fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{
9244fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	dss_save_context();
925a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	dss_set_min_bus_tput(dev, 0);
9264fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	return 0;
9274fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen}
9284fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen
9294fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic int dss_runtime_resume(struct device *dev)
9304fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{
931a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	int r;
932a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	/*
933a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	 * Set an arbitrarily high tput request to ensure OPP100.
934a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	 * What we should really do is to make a request to stay in OPP100,
935a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	 * without any tput requirements, but that is not currently possible
936a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	 * via the PM layer.
937a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	 */
938a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen
939a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	r = dss_set_min_bus_tput(dev, 1000000000);
940a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen	if (r)
941a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen		return r;
942a8081d317978416197295df22fc2ea71e4812f50Tomi Valkeinen
94339020710e707a01d80ea6c9e55dad4de93bb4730Tomi Valkeinen	dss_restore_context();
9444fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	return 0;
9454fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen}
9464fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen
9474fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic const struct dev_pm_ops dss_pm_ops = {
9484fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	.runtime_suspend = dss_runtime_suspend,
9494fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen	.runtime_resume = dss_runtime_resume,
9504fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen};
9514fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen
9522ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinenstatic const struct of_device_id dss_of_match[] = {
9532ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	{ .compatible = "ti,omap2-dss", },
9542ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	{ .compatible = "ti,omap3-dss", },
9552ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	{ .compatible = "ti,omap4-dss", },
9562e7e6b68924b3ab48e40b197ba72d9dc6d8e4a65Tomi Valkeinen	{ .compatible = "ti,omap5-dss", },
9572ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen	{},
9582ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen};
9592ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
9602ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi ValkeinenMODULE_DEVICE_TABLE(of, dss_of_match);
9612ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen
96296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamystatic struct platform_driver omap_dsshw_driver = {
9636e7e8f06b2c77dbb5d28062a174e4d67aec4b924Tomi Valkeinen	.remove         = __exit_p(omap_dsshw_remove),
96496c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	.driver         = {
96596c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy		.name   = "omapdss_dss",
96696c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy		.owner  = THIS_MODULE,
9674fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen		.pm	= &dss_pm_ops,
9682ecef24630f434e58bf3e5adb4d9bb76e50daf78Tomi Valkeinen		.of_match_table = dss_of_match,
969422ccbd57170d18cfd9d4c0cdbdd4603929fc51bTomi Valkeinen		.suppress_bind_attrs = true,
97096c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	},
97196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy};
97296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
9736e7e8f06b2c77dbb5d28062a174e4d67aec4b924Tomi Valkeinenint __init dss_init_platform_driver(void)
97496c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
97511436e1dd2aab1a33f81a3737ec8641788ec8543Tomi Valkeinen	return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe);
97696c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
97796c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
97896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamyvoid dss_uninit_platform_driver(void)
97996c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
98004c742c3dccac296fdc52b464bd0491ffe88de23Tomi Valkeinen	platform_driver_unregister(&omap_dsshw_driver);
98196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
982