2 * linux/drivers/video/omap2/dss/dss.c
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
7 * Some code and ideas taken from drivers/video/omap/ driver
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
23 #define DSS_SUBSYS_NAME "DSS"
25 #include <linux/kernel.h>
27 #include <linux/err.h>
28 #include <linux/delay.h>
29 #include <linux/interrupt.h>
30 #include <linux/seq_file.h>
32 #include <mach/display.h>
35 #define DSS_BASE 0x48050000
37 #define DSS_SZ_REGS SZ_512
43 #define DSS_REG(idx) ((const struct dss_reg) { idx })
45 #define DSS_REVISION DSS_REG(0x0000)
46 #define DSS_SYSCONFIG DSS_REG(0x0010)
47 #define DSS_SYSSTATUS DSS_REG(0x0014)
48 #define DSS_IRQSTATUS DSS_REG(0x0018)
49 #define DSS_CONTROL DSS_REG(0x0040)
50 #define DSS_SDI_CONTROL DSS_REG(0x0044)
51 #define DSS_PLL_CONTROL DSS_REG(0x0048)
52 #define DSS_SDI_STATUS DSS_REG(0x005C)
54 #define REG_GET(idx, start, end) \
55 FLD_GET(dss_read_reg(idx), start, end)
57 #define REG_FLD_MOD(idx, val, start, end) \
58 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
63 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
66 static int _omap_dss_wait_reset(void);
68 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
70 __raw_writel(val, dss.base + idx.idx);
73 static inline u32 dss_read_reg(const struct dss_reg idx)
75 return __raw_readl(dss.base + idx.idx);
79 dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
81 dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
83 void dss_save_context(void)
85 if (cpu_is_omap24xx())
91 #ifdef CONFIG_OMAP2_DSS_SDI
97 void dss_restore_context(void)
99 if (_omap_dss_wait_reset())
100 DSSERR("DSS not coming out of reset after sleep\n");
105 #ifdef CONFIG_OMAP2_DSS_SDI
114 void dss_sdi_init(u8 datapairs)
118 BUG_ON(datapairs > 3 || datapairs < 1);
120 l = dss_read_reg(DSS_SDI_CONTROL);
121 l = FLD_MOD(l, 0xf, 19, 15); /* SDI_PDIV */
122 l = FLD_MOD(l, datapairs-1, 3, 2); /* SDI_PRSEL */
123 l = FLD_MOD(l, 2, 1, 0); /* SDI_BWSEL */
124 dss_write_reg(DSS_SDI_CONTROL, l);
126 l = dss_read_reg(DSS_PLL_CONTROL);
127 l = FLD_MOD(l, 0x7, 25, 22); /* SDI_PLL_FREQSEL */
128 l = FLD_MOD(l, 0xb, 16, 11); /* SDI_PLL_REGN */
129 l = FLD_MOD(l, 0xb4, 10, 1); /* SDI_PLL_REGM */
130 dss_write_reg(DSS_PLL_CONTROL, l);
133 void dss_sdi_enable(void)
135 dispc_pck_free_enable(1);
138 REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
139 udelay(1); /* wait 2x PCLK */
142 REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
144 /* Waiting for PLL lock request to complete */
145 while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6))
148 /* Clearing PLL_GO bit */
149 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
151 /* Waiting for PLL to lock */
152 while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5)))
155 dispc_lcd_enable_signal(1);
157 /* Waiting for SDI reset to complete */
158 while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2)))
162 void dss_sdi_disable(void)
164 dispc_lcd_enable_signal(0);
166 dispc_pck_free_enable(0);
169 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
172 void dss_dump_regs(struct seq_file *s)
174 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
178 DUMPREG(DSS_REVISION);
179 DUMPREG(DSS_SYSCONFIG);
180 DUMPREG(DSS_SYSSTATUS);
181 DUMPREG(DSS_IRQSTATUS);
182 DUMPREG(DSS_CONTROL);
183 DUMPREG(DSS_SDI_CONTROL);
184 DUMPREG(DSS_PLL_CONTROL);
185 DUMPREG(DSS_SDI_STATUS);
187 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
191 void dss_select_clk_source(bool dsi, bool dispc)
194 r = dss_read_reg(DSS_CONTROL);
195 r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */
196 r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */
197 dss_write_reg(DSS_CONTROL, r);
200 int dss_get_dsi_clk_source(void)
202 return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1);
205 int dss_get_dispc_clk_source(void)
207 return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0);
210 static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
217 static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
221 irqstatus = dss_read_reg(DSS_IRQSTATUS);
223 if (irqstatus & (1<<0)) /* DISPC_IRQ */
225 #ifdef CONFIG_OMAP2_DSS_DSI
226 if (irqstatus & (1<<1)) /* DSI_IRQ */
233 static int _omap_dss_wait_reset(void)
235 unsigned timeout = 1000;
237 while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
240 DSSERR("soft reset failed\n");
248 static int _omap_dss_reset(void)
251 REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1);
252 return _omap_dss_wait_reset();
255 void dss_set_venc_output(enum omap_dss_venc_type type)
259 if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
261 else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
266 /* venc out selection. 0 = comp, 1 = svideo */
267 REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
270 void dss_set_dac_pwrdn_bgz(bool enable)
272 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
275 int dss_init(bool skip_init)
280 dss.base = ioremap(DSS_BASE, DSS_SZ_REGS);
282 DSSERR("can't ioremap DSS\n");
288 /* We need to wait here a bit, otherwise we sometimes start to
289 * get synclost errors, and after that only power cycle will
290 * restore DSS functionality. I have no idea why this happens.
291 * And we have to wait _before_ resetting the DSS, but after
300 printk("DSS SKIP RESET\n");
303 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
306 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
308 #ifdef CONFIG_OMAP2_DSS_VENC
309 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
310 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
311 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
314 r = request_irq(INT_24XX_DSS_IRQ,
316 ? dss_irq_handler_omap2
317 : dss_irq_handler_omap3,
318 0, "OMAP DSS", NULL);
321 DSSERR("omap2 dss: request_irq failed\n");
327 rev = dss_read_reg(DSS_REVISION);
328 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
329 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
341 free_irq(INT_24XX_DSS_IRQ, NULL);