dss.c revision a0b38cc4d35e095f14ab0f486135f8a619ebfc14
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>
26559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/io.h>
27559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/err.h>
28559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/delay.h>
29559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/seq_file.h>
30559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include <linux/clk.h>
31559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
32a0b38cc4d35e095f14ab0f486135f8a619ebfc14Tomi Valkeinen#include <video/omapdss.h>
338b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#include <plat/clock.h>
34559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#include "dss.h"
356ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen#include "dss_features.h"
36559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
37559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SZ_REGS			SZ_512
38559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
39559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstruct dss_reg {
40559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	u16 idx;
41559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen};
42559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
43559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_REG(idx)			((const struct dss_reg) { idx })
44559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
45559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_REVISION			DSS_REG(0x0000)
46559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SYSCONFIG			DSS_REG(0x0010)
47559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SYSSTATUS			DSS_REG(0x0014)
48559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_IRQSTATUS			DSS_REG(0x0018)
49559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_CONTROL			DSS_REG(0x0040)
50559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SDI_CONTROL			DSS_REG(0x0044)
51559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_PLL_CONTROL			DSS_REG(0x0048)
52559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DSS_SDI_STATUS			DSS_REG(0x005C)
53559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
54559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define REG_GET(idx, start, end) \
55559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	FLD_GET(dss_read_reg(idx), start, end)
56559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
57559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define REG_FLD_MOD(idx, val, start, end) \
58559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
59559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
60559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic struct {
6196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	struct platform_device *pdev;
62559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	void __iomem    *base;
638b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	int             ctx_id;
64559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
65559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	struct clk	*dpll4_m4_ck;
668b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	struct clk	*dss_ick;
67c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	struct clk	*dss_fck;
68c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	struct clk	*dss_sys_clk;
69c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	struct clk	*dss_tv_fck;
70c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	struct clk	*dss_video_fck;
718b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	unsigned	num_clks_enabled;
72559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
73559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long	cache_req_pck;
74559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long	cache_prate;
75559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	struct dss_clock_info cache_dss_cinfo;
76559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	struct dispc_clock_info cache_dispc_cinfo;
77559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
782f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	enum dss_clk_source dsi_clk_source;
792f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	enum dss_clk_source dispc_clk_source;
80ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
812f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
82559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
83559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen} dss;
84559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
85235e7dba0264d4c6e56ee217fc7ef6d80da5eb67Archit Tanejastatic const char * const dss_generic_clk_source_names[] = {
86235e7dba0264d4c6e56ee217fc7ef6d80da5eb67Archit Taneja	[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]	= "DSI_PLL_HSDIV_DISPC",
87235e7dba0264d4c6e56ee217fc7ef6d80da5eb67Archit Taneja	[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]		= "DSI_PLL_HSDIV_DSI",
88235e7dba0264d4c6e56ee217fc7ef6d80da5eb67Archit Taneja	[DSS_CLK_SRC_FCK]			= "DSS_FCK",
89067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja};
90067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja
918b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_enable_all_no_ctx(void);
928b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_disable_all_no_ctx(void);
938b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_enable_no_ctx(enum dss_clock clks);
948b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_disable_no_ctx(enum dss_clock clks);
958b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
96559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic int _omap_dss_wait_reset(void);
97559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
98559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic inline void dss_write_reg(const struct dss_reg idx, u32 val)
99559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
100559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	__raw_writel(val, dss.base + idx.idx);
101559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
102559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
103559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic inline u32 dss_read_reg(const struct dss_reg idx)
104559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
105559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return __raw_readl(dss.base + idx.idx);
106559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
107559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
108559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define SR(reg) \
109559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
110559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define RR(reg) \
111559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
112559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
113559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_save_context(void)
114559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
115559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (cpu_is_omap24xx())
116559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		return;
117559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
118559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	SR(SYSCONFIG);
119559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	SR(CONTROL);
120559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
1216ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
1226ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen			OMAP_DISPLAY_TYPE_SDI) {
1236ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		SR(SDI_CONTROL);
1246ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		SR(PLL_CONTROL);
1256ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	}
126559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
127559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
128559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_restore_context(void)
129559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
130559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (_omap_dss_wait_reset())
131559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		DSSERR("DSS not coming out of reset after sleep\n");
132559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
133559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	RR(SYSCONFIG);
134559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	RR(CONTROL);
135559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
1366ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
1376ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen			OMAP_DISPLAY_TYPE_SDI) {
1386ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		RR(SDI_CONTROL);
1396ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		RR(PLL_CONTROL);
1406ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	}
141559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
142559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
143559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#undef SR
144559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#undef RR
145559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
146559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_sdi_init(u8 datapairs)
147559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
148559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	u32 l;
149559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
150559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	BUG_ON(datapairs > 3 || datapairs < 1);
151559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
152559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = dss_read_reg(DSS_SDI_CONTROL);
153559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0xf, 19, 15);		/* SDI_PDIV */
154559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, datapairs-1, 3, 2);	/* SDI_PRSEL */
155559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 2, 1, 0);		/* SDI_BWSEL */
156559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(DSS_SDI_CONTROL, l);
157559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
158559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = dss_read_reg(DSS_PLL_CONTROL);
159559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0x7, 25, 22);	/* SDI_PLL_FREQSEL */
160559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0xb, 16, 11);	/* SDI_PLL_REGN */
161559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	l = FLD_MOD(l, 0xb4, 10, 1);	/* SDI_PLL_REGM */
162559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_write_reg(DSS_PLL_CONTROL, l);
163559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
164559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
165559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenint dss_sdi_enable(void)
166559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
167559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long timeout;
168559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
169559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_pck_free_enable(1);
170559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
171559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Reset SDI PLL */
172559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
173559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	udelay(1);	/* wait 2x PCLK */
174559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
175559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Lock SDI PLL */
176559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
177559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
178559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Waiting for PLL lock request to complete */
179559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	timeout = jiffies + msecs_to_jiffies(500);
180559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
181559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (time_after_eq(jiffies, timeout)) {
182559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("PLL lock request timed out\n");
183559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			goto err1;
184559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
185559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
186559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
187559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Clearing PLL_GO bit */
188559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
189559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
190559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Waiting for PLL to lock */
191559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	timeout = jiffies + msecs_to_jiffies(500);
192559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
193559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (time_after_eq(jiffies, timeout)) {
194559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("PLL lock timed out\n");
195559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			goto err1;
196559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
197559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
198559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
199559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_lcd_enable_signal(1);
200559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
201559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Waiting for SDI reset to complete */
202559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	timeout = jiffies + msecs_to_jiffies(500);
203559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
204559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (time_after_eq(jiffies, timeout)) {
205559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("SDI reset timed out\n");
206559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			goto err2;
207559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
208559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
209559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
210559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
211559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
212559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen err2:
213559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_lcd_enable_signal(0);
214559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen err1:
215559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Reset SDI PLL */
216559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
217559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
218559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_pck_free_enable(0);
219559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
220559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return -ETIMEDOUT;
221559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
222559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
223559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_sdi_disable(void)
224559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
225559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_lcd_enable_signal(0);
226559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
227559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dispc_pck_free_enable(0);
228559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
229559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Reset SDI PLL */
230559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
231559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
232559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
233067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Tanejaconst char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src)
234067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja{
235235e7dba0264d4c6e56ee217fc7ef6d80da5eb67Archit Taneja	return dss_generic_clk_source_names[clk_src];
236067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja}
237067a57e48e302863eb2d5ac0900ae9ae65dbc8c3Archit Taneja
238559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_dump_clocks(struct seq_file *s)
239559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
240559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long dpll4_ck_rate;
241559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long dpll4_m4_ck_rate;
2420acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	const char *fclk_name, *fclk_real_name;
2430acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	unsigned long fclk_rate;
244559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2456af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
246559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
247559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	seq_printf(s, "- DSS -\n");
248559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2490acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK);
2500acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK);
2510acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
252559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2530acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	if (dss.dpll4_m4_ck) {
2540acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
2550acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
2560acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen
2570acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
2580acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen
2592de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		if (cpu_is_omap3630() || cpu_is_omap44xx())
2600acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
2610acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					fclk_name, fclk_real_name,
2620acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					dpll4_ck_rate,
2630acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					dpll4_ck_rate / dpll4_m4_ck_rate,
2640acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					fclk_rate);
2650acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		else
2660acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
2670acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					fclk_name, fclk_real_name,
2680acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					dpll4_ck_rate,
2690acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					dpll4_ck_rate / dpll4_m4_ck_rate,
2700acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen					fclk_rate);
2710acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	} else {
2720acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		seq_printf(s, "%s (%s) = %lu\n",
2730acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen				fclk_name, fclk_real_name,
2740acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen				fclk_rate);
2750acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	}
276559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2776af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
278559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
279559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
280559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_dump_regs(struct seq_file *s)
281559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
282559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
283559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2846af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
285559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
286559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_REVISION);
287559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_SYSCONFIG);
288559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_SYSSTATUS);
289559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_IRQSTATUS);
290559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DUMPREG(DSS_CONTROL);
2916ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen
2926ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
2936ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen			OMAP_DISPLAY_TYPE_SDI) {
2946ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		DUMPREG(DSS_SDI_CONTROL);
2956ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		DUMPREG(DSS_PLL_CONTROL);
2966ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen		DUMPREG(DSS_SDI_STATUS);
2976ec549e50b192105ede7bb289a31da6f6e1a61e9Tomi Valkeinen	}
298559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
2996af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
300559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#undef DUMPREG
301559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
302559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
3032f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinenvoid dss_select_dispc_clk_source(enum dss_clk_source clk_src)
3042f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen{
3052f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	int b;
306ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	u8 start, end;
3072f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
30866534e8e936a0b926863df90054dc59826d70528Archit Taneja	switch (clk_src) {
30966534e8e936a0b926863df90054dc59826d70528Archit Taneja	case DSS_CLK_SRC_FCK:
31066534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 0;
31166534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
31266534e8e936a0b926863df90054dc59826d70528Archit Taneja	case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
31366534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 1;
3141bb478350670fadf708d3cbd6137c32dfbe3fd5fArchit Taneja		dsi_wait_pll_hsdiv_dispc_active();
31566534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
31666534e8e936a0b926863df90054dc59826d70528Archit Taneja	default:
31766534e8e936a0b926863df90054dc59826d70528Archit Taneja		BUG();
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
3272f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinenvoid dss_select_dsi_clk_source(enum dss_clk_source clk_src)
328559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
3292f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	int b;
3302f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
33166534e8e936a0b926863df90054dc59826d70528Archit Taneja	switch (clk_src) {
33266534e8e936a0b926863df90054dc59826d70528Archit Taneja	case DSS_CLK_SRC_FCK:
33366534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 0;
33466534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
33566534e8e936a0b926863df90054dc59826d70528Archit Taneja	case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
33666534e8e936a0b926863df90054dc59826d70528Archit Taneja		b = 1;
3371bb478350670fadf708d3cbd6137c32dfbe3fd5fArchit Taneja		dsi_wait_pll_hsdiv_dsi_active();
33866534e8e936a0b926863df90054dc59826d70528Archit Taneja		break;
33966534e8e936a0b926863df90054dc59826d70528Archit Taneja	default:
34066534e8e936a0b926863df90054dc59826d70528Archit Taneja		BUG();
34166534e8e936a0b926863df90054dc59826d70528Archit Taneja	}
342e406f9079b993f4d5d7b5a3452b11df81ff2aef0Tomi Valkeinen
3432f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, b, 1, 1);	/* DSI_CLK_SWITCH */
3442f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen
3452f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	dss.dsi_clk_source = clk_src;
346559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
347559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
348ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Tanejavoid dss_select_lcd_clk_source(enum omap_channel channel,
349ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		enum dss_clk_source clk_src)
350ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja{
351ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	int b, ix, pos;
352ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
353ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	if (!dss_has_feature(FEAT_LCD_CLK_SRC))
354ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		return;
355ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
356ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	switch (clk_src) {
357ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	case DSS_CLK_SRC_FCK:
358ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		b = 0;
359ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		break;
360ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
361ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
362ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		b = 1;
363ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		dsi_wait_pll_hsdiv_dispc_active();
364ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		break;
365ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	default:
366ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja		BUG();
367ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	}
368ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
369ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
370ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	REG_FLD_MOD(DSS_CONTROL, b, pos, pos);	/* LCDx_CLK_SWITCH */
371ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
372ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
373ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	dss.lcd_clk_source[ix] = clk_src;
374ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja}
375ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
3762f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinenenum dss_clk_source dss_get_dispc_clk_source(void)
377559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
3782f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	return dss.dispc_clk_source;
379559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
380559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
3812f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinenenum dss_clk_source dss_get_dsi_clk_source(void)
382559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
3832f18c4d89861fc1abdfa2531ba76017acb78edc5Tomi Valkeinen	return dss.dsi_clk_source;
384559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
385559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
386ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Tanejaenum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
387ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja{
388ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
389ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	return dss.lcd_clk_source[ix];
390ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja}
391ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja
392559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen/* calculate clock rates using dividers in cinfo */
393559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenint dss_calc_clock_rates(struct dss_clock_info *cinfo)
394559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
3950acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	if (dss.dpll4_m4_ck) {
3960acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		unsigned long prate;
3972de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		u16 fck_div_max = 16;
398559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
3992de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		if (cpu_is_omap3630() || cpu_is_omap44xx())
4002de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer			fck_div_max = 32;
4012de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer
4022de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
4030acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen			return -EINVAL;
404559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
4050acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
406559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
4070acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		cinfo->fck = prate / cinfo->fck_div;
4080acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	} else {
4090acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		if (cinfo->fck_div != 0)
4100acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen			return -EINVAL;
4110acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
4120acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	}
413559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
414559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
415559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
416559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
417559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenint dss_set_clock_div(struct dss_clock_info *cinfo)
418559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
4190acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	if (dss.dpll4_m4_ck) {
4200acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		unsigned long prate;
4210acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		int r;
422559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
423559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
424559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		DSSDBG("dpll4_m4 = %ld\n", prate);
425559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
426559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
427559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (r)
428559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			return r;
4290acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	} else {
4300acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		if (cinfo->fck_div != 0)
4310acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen			return -EINVAL;
432559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
433559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
434559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
435559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
436559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
437559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
438559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
439559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenint dss_get_clock_div(struct dss_clock_info *cinfo)
440559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
4416af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
442559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
4430acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	if (dss.dpll4_m4_ck) {
444559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		unsigned long prate;
4450acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen
446559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
4470acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen
4482de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		if (cpu_is_omap3630() || cpu_is_omap44xx())
449ac01bb7ea06a02c8dc9084b4ed59cb59efeceb39Kishore Y			cinfo->fck_div = prate / (cinfo->fck);
450ac01bb7ea06a02c8dc9084b4ed59cb59efeceb39Kishore Y		else
451ac01bb7ea06a02c8dc9084b4ed59cb59efeceb39Kishore Y			cinfo->fck_div = prate / (cinfo->fck / 2);
452559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	} else {
453559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		cinfo->fck_div = 0;
454559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
455559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
456559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
457559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
458559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
459559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenunsigned long dss_get_dpll4_rate(void)
460559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
4610acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	if (dss.dpll4_m4_ck)
462559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
463559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	else
464559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		return 0;
465559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
466559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
467559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenint dss_calc_clock_div(bool is_tft, unsigned long req_pck,
468559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		struct dss_clock_info *dss_cinfo,
469559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		struct dispc_clock_info *dispc_cinfo)
470559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
471559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	unsigned long prate;
472559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	struct dss_clock_info best_dss;
473559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	struct dispc_clock_info best_dispc;
474559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
475819d807c59af10cce1dcbb13539c2fb100953fcdArchit Taneja	unsigned long fck, max_dss_fck;
476559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
4772de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer	u16 fck_div, fck_div_max = 16;
478559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
479559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	int match = 0;
480559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	int min_fck_per_pck;
481559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
482559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	prate = dss_get_dpll4_rate();
483559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
48431ef82377f1e0f1bc7d308ae4312e6cc5a431885Archit Taneja	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
485819d807c59af10cce1dcbb13539c2fb100953fcdArchit Taneja
4866af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	fck = dss_clk_get_rate(DSS_CLK_FCK);
487559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (req_pck == dss.cache_req_pck &&
488559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
489559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			 dss.cache_dss_cinfo.fck == fck)) {
490559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		DSSDBG("dispc clock info found from cache.\n");
491559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		*dss_cinfo = dss.cache_dss_cinfo;
492559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		*dispc_cinfo = dss.cache_dispc_cinfo;
493559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		return 0;
494559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
495559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
496559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
497559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
498559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (min_fck_per_pck &&
499819d807c59af10cce1dcbb13539c2fb100953fcdArchit Taneja		req_pck * min_fck_per_pck > max_dss_fck) {
500559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		DSSERR("Requested pixel clock not possible with the current "
501559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				"OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
502559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				"the constraint off.\n");
503559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		min_fck_per_pck = 0;
504559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
505559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
506559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenretry:
507559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	memset(&best_dss, 0, sizeof(best_dss));
508559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	memset(&best_dispc, 0, sizeof(best_dispc));
509559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
5102de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer	if (dss.dpll4_m4_ck == NULL) {
511559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		struct dispc_clock_info cur_dispc;
512559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		/* XXX can we change the clock on omap2? */
5136af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja		fck = dss_clk_get_rate(DSS_CLK_FCK);
514559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		fck_div = 1;
515559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
516559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
517559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		match = 1;
518559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
519559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		best_dss.fck = fck;
520559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		best_dss.fck_div = fck_div;
521559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
522559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		best_dispc = cur_dispc;
523559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
524559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		goto found;
5252de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer	} else {
5262de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		if (cpu_is_omap3630() || cpu_is_omap44xx())
5272de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer			fck_div_max = 32;
5282de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer
5292de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
530559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			struct dispc_clock_info cur_dispc;
531559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
5322de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer			if (fck_div_max == 32)
533ac01bb7ea06a02c8dc9084b4ed59cb59efeceb39Kishore Y				fck = prate / fck_div;
534ac01bb7ea06a02c8dc9084b4ed59cb59efeceb39Kishore Y			else
535ac01bb7ea06a02c8dc9084b4ed59cb59efeceb39Kishore Y				fck = prate / fck_div * 2;
536559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
537819d807c59af10cce1dcbb13539c2fb100953fcdArchit Taneja			if (fck > max_dss_fck)
538559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				continue;
539559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
540559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			if (min_fck_per_pck &&
541559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen					fck < req_pck * min_fck_per_pck)
542559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				continue;
543559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
544559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			match = 1;
545559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
546559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
547559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
548559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			if (abs(cur_dispc.pck - req_pck) <
549559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen					abs(best_dispc.pck - req_pck)) {
550559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
551559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				best_dss.fck = fck;
552559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				best_dss.fck_div = fck_div;
553559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
554559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				best_dispc = cur_dispc;
555559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
556559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen				if (cur_dispc.pck == req_pck)
557559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen					goto found;
558559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			}
559559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
560559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
561559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
562559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenfound:
563559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (!match) {
564559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		if (min_fck_per_pck) {
565559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("Could not find suitable clock settings.\n"
566559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen					"Turning FCK/PCK constraint off and"
567559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen					"trying again.\n");
568559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			min_fck_per_pck = 0;
569559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			goto retry;
570559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
571559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
572559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		DSSERR("Could not find suitable clock settings.\n");
573559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
574559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		return -EINVAL;
575559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
576559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
577559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (dss_cinfo)
578559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		*dss_cinfo = best_dss;
579559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (dispc_cinfo)
580559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		*dispc_cinfo = best_dispc;
581559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
582559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss.cache_req_pck = req_pck;
583559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss.cache_prate = prate;
584559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss.cache_dss_cinfo = best_dss;
585559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss.cache_dispc_cinfo = best_dispc;
586559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
587559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
588559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
589559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
590559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic int _omap_dss_wait_reset(void)
591559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
59224be78b32f0a6e14aead3eac89d768a361b091b3Tomi Valkeinen	int t = 0;
593559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
594559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
59524be78b32f0a6e14aead3eac89d768a361b091b3Tomi Valkeinen		if (++t > 1000) {
596559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("soft reset failed\n");
597559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			return -ENODEV;
598559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
59924be78b32f0a6e14aead3eac89d768a361b091b3Tomi Valkeinen		udelay(1);
600559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
601559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
602559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
603559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
604559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
605559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenstatic int _omap_dss_reset(void)
606559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
607559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Soft reset */
608559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1);
609559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return _omap_dss_wait_reset();
610559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
611559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
612559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_set_venc_output(enum omap_dss_venc_type type)
613559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
614559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	int l = 0;
615559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
616559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
617559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		l = 0;
618559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
619559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		l = 1;
620559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	else
621559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		BUG();
622559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
623559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* venc out selection. 0 = comp, 1 = svideo */
624559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
625559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
626559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
627559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenvoid dss_set_dac_pwrdn_bgz(bool enable)
628559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
629559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);	/* DAC Power-Down Control */
630559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
631559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
6327ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P Kvoid dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
6337ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P K{
6347ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P K	REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15);	/* VENC_HDMI_SWITCH */
6357ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P K}
6367ed024aa280cb38c8aa5c188d2d2c98f5daede10Mythri P K
63742c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinenstatic int dss_init(void)
638559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
639559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	int r;
640559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	u32 rev;
641ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy	struct resource *dss_mem;
6420acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	struct clk *dpll4_m4_ck;
643559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
644ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
645ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy	if (!dss_mem) {
646ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy		DSSERR("can't get IORESOURCE_MEM DSS\n");
647ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy		r = -EINVAL;
648ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy		goto fail0;
649ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy	}
650ea9da36a304eed585fc5ef89c0f1c460eca61b48Senthilvadivu Guruswamy	dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
651559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (!dss.base) {
652559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		DSSERR("can't ioremap DSS\n");
653559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		r = -ENOMEM;
654559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		goto fail0;
655559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
656559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
65742c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	/* disable LCD and DIGIT output. This seems to fix the synclost
65842c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	 * problem that we get, if the bootloader starts the DSS and
65942c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	 * the kernel resets it */
66042c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
66142c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen
66242c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	/* We need to wait here a bit, otherwise we sometimes start to
66342c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	 * get synclost errors, and after that only power cycle will
66442c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	 * restore DSS functionality. I have no idea why this happens.
66542c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	 * And we have to wait _before_ resetting the DSS, but after
66642c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	 * enabling clocks.
66742c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	 */
66842c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	msleep(50);
66942c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen
67042c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	_omap_dss_reset();
671559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
672559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* autoidle */
673559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
674559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
675559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	/* Select DPLL */
676559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
677559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
678559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_VENC
679559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);	/* venc dac demen */
680559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);	/* venc clock 4x enable */
681559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);	/* venc clock mode = normal */
682559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen#endif
683559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	if (cpu_is_omap34xx()) {
6840acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
6850acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		if (IS_ERR(dpll4_m4_ck)) {
686559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			DSSERR("Failed to get dpll4_m4_ck\n");
6870acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen			r = PTR_ERR(dpll4_m4_ck);
688affe360d13e54b415cde2f11cee02369b4ed54bdArchit Taneja			goto fail1;
689559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		}
6902de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer	} else if (cpu_is_omap44xx()) {
6912de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
6922de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		if (IS_ERR(dpll4_m4_ck)) {
6932de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer			DSSERR("Failed to get dpll4_m4_ck\n");
6942de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer			r = PTR_ERR(dpll4_m4_ck);
6952de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer			goto fail1;
6962de110868f455b74e91111801ce63a3c9d06f091Murthy, Raghuveer		}
6970acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	} else { /* omap24xx */
6980acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen		dpll4_m4_ck = NULL;
699559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	}
700559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
7010acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	dss.dpll4_m4_ck = dpll4_m4_ck;
7020acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen
70388134fa138b90518819b750891ffecc13f5f4886Archit Taneja	dss.dsi_clk_source = DSS_CLK_SRC_FCK;
70488134fa138b90518819b750891ffecc13f5f4886Archit Taneja	dss.dispc_clk_source = DSS_CLK_SRC_FCK;
705ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
706ea75159ee6f00bd809f57a58e5505dc362382cc8Archit Taneja	dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
707ce619e1fb86d68f125e0e6d10a5484f67a6d97b3Tomi Valkeinen
708559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	dss_save_context();
709559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
710559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	rev = dss_read_reg(DSS_REVISION);
711559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	printk(KERN_INFO "OMAP DSS rev %d.%d\n",
712559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
713559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
714559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return 0;
715559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
716559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenfail1:
717559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	iounmap(dss.base);
718559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinenfail0:
719559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	return r;
720559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
721559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
72296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamystatic void dss_exit(void)
723559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen{
7240acf659f1469725fb6e39d53af970f36c5f69a41Tomi Valkeinen	if (dss.dpll4_m4_ck)
725559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen		clk_put(dss.dpll4_m4_ck);
726559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
727559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen	iounmap(dss.base);
728559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen}
729559d67018950ced65c73358cd69c4bdd2b0c5dd6Tomi Valkeinen
7308b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy/* CONTEXT */
7318b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic int dss_get_ctx_id(void)
7328b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
7338b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
7348b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	int r;
7358b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7368b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (!pdata->board_data->get_last_off_on_transaction_id)
7378b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		return 0;
7388b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
7398b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (r < 0) {
7408b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		dev_err(&dss.pdev->dev, "getting transaction ID failed, "
7418b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy				"will force context restore\n");
7428b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		r = -1;
7438b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	}
7448b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return r;
7458b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
7468b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7478b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyint dss_need_ctx_restore(void)
7488b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
7498b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	int id = dss_get_ctx_id();
7508b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7518b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (id < 0 || id != dss.ctx_id) {
7528b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		DSSDBG("ctx id %d -> id %d\n",
7538b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy				dss.ctx_id, id);
7548b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		dss.ctx_id = id;
7558b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		return 1;
7568b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	} else {
7578b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		return 0;
7588b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	}
7598b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
7608b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7618b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void save_all_ctx(void)
7628b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
7638b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	DSSDBG("save context\n");
7648b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7656af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
7668b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7678b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_save_context();
7688b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dispc_save_context();
7698b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#ifdef CONFIG_OMAP2_DSS_DSI
7708b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dsi_save_context();
7718b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#endif
7728b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7736af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
7748b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
7758b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7768b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void restore_all_ctx(void)
7778b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
7788b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	DSSDBG("restore context\n");
7798b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7808b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_enable_all_no_ctx();
7818b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7828b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_restore_context();
7838b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dispc_restore_context();
7848b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#ifdef CONFIG_OMAP2_DSS_DSI
7858b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dsi_restore_context();
7868b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#endif
7878b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7888b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_disable_all_no_ctx();
7898b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
7908b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7918b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic int dss_get_clock(struct clk **clock, const char *clk_name)
7928b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
7938b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	struct clk *clk;
7948b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7958b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	clk = clk_get(&dss.pdev->dev, clk_name);
7968b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
7978b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (IS_ERR(clk)) {
7988b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		DSSERR("can't get clock %s", clk_name);
7998b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		return PTR_ERR(clk);
8008b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	}
8018b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8028b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	*clock = clk;
8038b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8048b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
8058b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8068b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return 0;
8078b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
8088b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8098b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic int dss_get_clocks(void)
8108b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
8118b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	int r;
812a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
8138b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8148b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss.dss_ick = NULL;
815c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	dss.dss_fck = NULL;
816c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	dss.dss_sys_clk = NULL;
817c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	dss.dss_tv_fck = NULL;
818c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	dss.dss_video_fck = NULL;
8198b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8208b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	r = dss_get_clock(&dss.dss_ick, "ick");
8218b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (r)
8228b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		goto err;
8238b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
824c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	r = dss_get_clock(&dss.dss_fck, "fck");
8258b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (r)
8268b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		goto err;
8278b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
828a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if (!pdata->opt_clock_available) {
829a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		r = -ENODEV;
8308b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		goto err;
831a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	}
8328b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
833a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if (pdata->opt_clock_available("sys_clk")) {
834a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
835a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		if (r)
836a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal			goto err;
837a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	}
8388b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
839a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if (pdata->opt_clock_available("tv_clk")) {
840a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
841a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		if (r)
842a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal			goto err;
843a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	}
844a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal
845a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if (pdata->opt_clock_available("video_clk")) {
846a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		r = dss_get_clock(&dss.dss_video_fck, "video_clk");
847a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		if (r)
848a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal			goto err;
849a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	}
8508b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8518b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return 0;
8528b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8538b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyerr:
8548b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (dss.dss_ick)
8558b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		clk_put(dss.dss_ick);
856c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	if (dss.dss_fck)
857c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_put(dss.dss_fck);
858c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	if (dss.dss_sys_clk)
859c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_put(dss.dss_sys_clk);
860c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	if (dss.dss_tv_fck)
861c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_put(dss.dss_tv_fck);
862c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	if (dss.dss_video_fck)
863c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_put(dss.dss_video_fck);
8648b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8658b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return r;
8668b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
8678b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8688b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_put_clocks(void)
8698b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
870c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	if (dss.dss_video_fck)
871c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_put(dss.dss_video_fck);
872a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if (dss.dss_tv_fck)
873a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		clk_put(dss.dss_tv_fck);
874a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if (dss.dss_sys_clk)
875a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal		clk_put(dss.dss_sys_clk);
876c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja	clk_put(dss.dss_fck);
8778b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	clk_put(dss.dss_ick);
8788b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
8798b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8808b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyunsigned long dss_clk_get_rate(enum dss_clock clk)
8818b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
8828b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	switch (clk) {
8838b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	case DSS_CLK_ICK:
8848b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		return clk_get_rate(dss.dss_ick);
8856af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	case DSS_CLK_FCK:
886c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		return clk_get_rate(dss.dss_fck);
8876af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	case DSS_CLK_SYSCK:
888c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		return clk_get_rate(dss.dss_sys_clk);
8896af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	case DSS_CLK_TVFCK:
890c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		return clk_get_rate(dss.dss_tv_fck);
8916af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	case DSS_CLK_VIDFCK:
892c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		return clk_get_rate(dss.dss_video_fck);
8938b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	}
8948b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8958b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	BUG();
8968b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return 0;
8978b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
8988b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
8998b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic unsigned count_clk_bits(enum dss_clock clks)
9008b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
9018b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	unsigned num_clks = 0;
9028b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9038b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (clks & DSS_CLK_ICK)
9048b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		++num_clks;
9056af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	if (clks & DSS_CLK_FCK)
9068b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		++num_clks;
9076af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	if (clks & DSS_CLK_SYSCK)
9088b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		++num_clks;
9096af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	if (clks & DSS_CLK_TVFCK)
9108b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		++num_clks;
9116af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	if (clks & DSS_CLK_VIDFCK)
9128b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		++num_clks;
9138b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9148b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return num_clks;
9158b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
9168b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9178b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_enable_no_ctx(enum dss_clock clks)
9188b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
9198b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	unsigned num_clks = count_clk_bits(clks);
9208b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9218b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (clks & DSS_CLK_ICK)
9228b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		clk_enable(dss.dss_ick);
9236af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	if (clks & DSS_CLK_FCK)
924c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_enable(dss.dss_fck);
925a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
926c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_enable(dss.dss_sys_clk);
927a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
928c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_enable(dss.dss_tv_fck);
929a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
930c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_enable(dss.dss_video_fck);
9318b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9328b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss.num_clks_enabled += num_clks;
9338b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
9348b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9358b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyvoid dss_clk_enable(enum dss_clock clks)
9368b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
9378b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	bool check_ctx = dss.num_clks_enabled == 0;
9388b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9398b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_enable_no_ctx(clks);
9408b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
94185604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen	/*
94285604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen	 * HACK: On omap4 the registers may not be accessible right after
94385604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen	 * enabling the clocks. At some point this will be handled by
94485604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen	 * pm_runtime, but for the time begin this should make things work.
94585604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen	 */
94685604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen	if (cpu_is_omap44xx() && check_ctx)
94785604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen		udelay(10);
94885604b0a247615157cedfec46b9cbfde2884f80fTomi Valkeinen
9498b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
9508b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		restore_all_ctx();
9518b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
9528b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9538b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_disable_no_ctx(enum dss_clock clks)
9548b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
9558b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	unsigned num_clks = count_clk_bits(clks);
9568b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9578b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (clks & DSS_CLK_ICK)
9588b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		clk_disable(dss.dss_ick);
9596af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	if (clks & DSS_CLK_FCK)
960c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_disable(dss.dss_fck);
961a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
962c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_disable(dss.dss_sys_clk);
963a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
964c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_disable(dss.dss_tv_fck);
965a1a0dccaea9e036200dc0b1070af1bfae06690fbSumit Semwal	if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
966c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		clk_disable(dss.dss_video_fck);
9678b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9688b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss.num_clks_enabled -= num_clks;
9698b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
9708b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9718b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyvoid dss_clk_disable(enum dss_clock clks)
9728b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
9738b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (cpu_is_omap34xx()) {
9748b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		unsigned num_clks = count_clk_bits(clks);
9758b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9768b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		BUG_ON(dss.num_clks_enabled < num_clks);
9778b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9788b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		if (dss.num_clks_enabled == num_clks)
9798b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy			save_all_ctx();
9808b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	}
9818b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9828b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_disable_no_ctx(clks);
9838b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
9848b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9858b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_enable_all_no_ctx(void)
9868b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
9878b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	enum dss_clock clks;
9888b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9896af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
9908b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (cpu_is_omap34xx())
9916af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja		clks |= DSS_CLK_VIDFCK;
9928b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_enable_no_ctx(clks);
9938b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
9948b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9958b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void dss_clk_disable_all_no_ctx(void)
9968b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
9978b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	enum dss_clock clks;
9988b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
9996af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja	clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
10008b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (cpu_is_omap34xx())
10016af9cd1431db952a7f9f8931497c9989a48b07dfArchit Taneja		clks |= DSS_CLK_VIDFCK;
10028b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_disable_no_ctx(clks);
10038b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
10048b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10058b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
10068b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy/* CLOCKS */
10078b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamystatic void core_dump_clocks(struct seq_file *s)
10088b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
10098b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	int i;
10108b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	struct clk *clocks[5] = {
10118b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		dss.dss_ick,
1012c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		dss.dss_fck,
1013c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		dss.dss_sys_clk,
1014c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		dss.dss_tv_fck,
1015c7642f67e5bd71f91d165620f601f00c7c9802c9Archit Taneja		dss.dss_video_fck
10168b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	};
10178b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10188b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	seq_printf(s, "- CORE -\n");
10198b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10208b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
10218b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10228b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	for (i = 0; i < 5; i++) {
10238b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		if (!clocks[i])
10248b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy			continue;
10258b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		seq_printf(s, "%-15s\t%lu\t%d\n",
10268b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy				clocks[i]->name,
10278b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy				clk_get_rate(clocks[i]),
10288b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy				clocks[i]->usecount);
10298b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	}
10308b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
10318b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
10328b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10338b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy/* DEBUGFS */
10348b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
10358b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyvoid dss_debug_dump_clocks(struct seq_file *s)
10368b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy{
10378b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	core_dump_clocks(s);
10388b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_dump_clocks(s);
10398b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dispc_dump_clocks(s);
10408b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#ifdef CONFIG_OMAP2_DSS_DSI
10418b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dsi_dump_clocks(s);
10428b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#endif
10438b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy}
10448b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy#endif
10458b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10468b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
104796c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy/* DSS HW IP initialisation */
104896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamystatic int omap_dsshw_probe(struct platform_device *pdev)
104996c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
105096c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	int r;
105196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
105296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	dss.pdev = pdev;
105396c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
10548b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	r = dss_get_clocks();
10558b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	if (r)
10568b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy		goto err_clocks;
10578b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10588b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_enable_all_no_ctx();
10598b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
10608b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss.ctx_id = dss_get_ctx_id();
10618b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	DSSDBG("initial ctx id %u\n", dss.ctx_id);
10628b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
106342c9dee82129d965bc8ca02170150817317c0135Tomi Valkeinen	r = dss_init();
106496c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	if (r) {
106596c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy		DSSERR("Failed to initialize DSS\n");
106696c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy		goto err_dss;
106796c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	}
106896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
1069587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	r = dpi_init();
1070587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	if (r) {
1071587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen		DSSERR("Failed to initialize DPI\n");
1072587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen		goto err_dpi;
1073587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	}
1074587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen
1075587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	r = sdi_init();
1076587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	if (r) {
1077587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen		DSSERR("Failed to initialize SDI\n");
1078587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen		goto err_sdi;
1079587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	}
1080587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen
10818b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_disable_all_no_ctx();
10828b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	return 0;
1083587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinenerr_sdi:
1084587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	dpi_exit();
1085587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinenerr_dpi:
1086587b5e8269fab583e4e9d2d6bbdc77b289ac78a7Tomi Valkeinen	dss_exit();
10878b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyerr_dss:
10888b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_clk_disable_all_no_ctx();
10898b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_put_clocks();
10908b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamyerr_clocks:
109196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	return r;
109296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
109396c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
109496c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamystatic int omap_dsshw_remove(struct platform_device *pdev)
109596c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
10968b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
109796c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	dss_exit();
109896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
10998b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	/*
11008b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	 * As part of hwmod changes, DSS is not the only controller of dss
11018b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	 * clocks; hwmod framework itself will also enable clocks during hwmod
11028b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
11038b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	 * need to disable clocks if their usecounts > 1.
11048b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	 */
11058b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	WARN_ON(dss.num_clks_enabled > 0);
11068b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy
11078b9cb3a8f39d0864c925c5cd5c2c54cfd85ad551Senthilvadivu Guruswamy	dss_put_clocks();
110896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	return 0;
110996c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
111096c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
111196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamystatic struct platform_driver omap_dsshw_driver = {
111296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	.probe          = omap_dsshw_probe,
111396c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	.remove         = omap_dsshw_remove,
111496c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	.driver         = {
111596c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy		.name   = "omapdss_dss",
111696c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy		.owner  = THIS_MODULE,
111796c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	},
111896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy};
111996c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
112096c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamyint dss_init_platform_driver(void)
112196c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
112296c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	return platform_driver_register(&omap_dsshw_driver);
112396c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
112496c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy
112596c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamyvoid dss_uninit_platform_driver(void)
112696c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy{
112796c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy	return platform_driver_unregister(&omap_dsshw_driver);
112896c401bcb83a182a4f332f2f64ee6530ba35511aSenthilvadivu Guruswamy}
1129