2 * File: drivers/video/omap/omap2/dispc.c
4 * OMAP2 display controller support
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Imre Deak <imre.deak@nokia.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <linux/kernel.h>
25 #include <linux/dma-mapping.h>
29 #include <asm/arch/omapfb.h>
31 #include <asm/hardware/clock.h>
35 /* #define OMAPFB_DBG 2 */
39 #define MODULE_NAME "omapfb-dispc"
41 #define DISPC_BASE 0x48050400
44 #define DISPC_REVISION 0x0000
45 #define DISPC_SYSCONFIG 0x0010
46 #define DISPC_SYSSTATUS 0x0014
47 #define DISPC_IRQSTATUS 0x0018
48 #define DISPC_IRQENABLE 0x001C
49 #define DISPC_CONTROL 0x0040
50 #define DISPC_CONFIG 0x0044
51 #define DISPC_CAPABLE 0x0048
52 #define DISPC_DEFAULT_COLOR0 0x004C
53 #define DISPC_DEFAULT_COLOR1 0x0050
54 #define DISPC_TRANS_COLOR0 0x0054
55 #define DISPC_TRANS_COLOR1 0x0058
56 #define DISPC_LINE_STATUS 0x005C
57 #define DISPC_LINE_NUMBER 0x0060
58 #define DISPC_TIMING_H 0x0064
59 #define DISPC_TIMING_V 0x0068
60 #define DISPC_POL_FREQ 0x006C
61 #define DISPC_DIVISOR 0x0070
62 #define DISPC_SIZE_DIG 0x0078
63 #define DISPC_SIZE_LCD 0x007C
65 #define DISPC_DATA_CYCLE1 0x01D4
66 #define DISPC_DATA_CYCLE2 0x01D8
67 #define DISPC_DATA_CYCLE3 0x01DC
70 #define DISPC_GFX_BA0 0x0080
71 #define DISPC_GFX_BA1 0x0084
72 #define DISPC_GFX_POSITION 0x0088
73 #define DISPC_GFX_SIZE 0x008C
74 #define DISPC_GFX_ATTRIBUTES 0x00A0
75 #define DISPC_GFX_FIFO_THRESHOLD 0x00A4
76 #define DISPC_GFX_FIFO_SIZE_STATUS 0x00A8
77 #define DISPC_GFX_ROW_INC 0x00AC
78 #define DISPC_GFX_PIXEL_INC 0x00B0
79 #define DISPC_GFX_WINDOW_SKIP 0x00B4
80 #define DISPC_GFX_TABLE_BA 0x00B8
82 /* DISPC Video plane 1/2 */
83 #define DISPC_VID1_BASE 0x00BC
84 #define DISPC_VID2_BASE 0x014C
86 /* Offsets into DISPC_VID1/2_BASE */
87 #define DISPC_VID_BA0 0x0000
88 #define DISPC_VID_BA1 0x0004
89 #define DISPC_VID_POSITION 0x0008
90 #define DISPC_VID_SIZE 0x000C
91 #define DISPC_VID_ATTRIBUTES 0x0010
92 #define DISPC_VID_FIFO_THRESHOLD 0x0014
93 #define DISPC_VID_FIFO_SIZE_STATUS 0x0018
94 #define DISPC_VID_ROW_INC 0x001C
95 #define DISPC_VID_PIXEL_INC 0x0020
96 #define DISPC_VID_FIR 0x0024
97 #define DISPC_VID_PICTURE_SIZE 0x0028
98 #define DISPC_VID_ACCU0 0x002C
99 #define DISPC_VID_ACCU1 0x0030
101 /* 8 elements in 8 byte increments */
102 #define DISPC_VID_FIR_COEF_H0 0x0034
103 /* 8 elements in 8 byte increments */
104 #define DISPC_VID_FIR_COEF_HV0 0x0038
105 /* 5 elements in 4 byte increments */
106 #define DISPC_VID_CONV_COEF0 0x0074
108 #define DISPC_IRQ_FRAMEMASK 0x0001
109 #define DISPC_IRQ_VSYNC 0x0002
110 #define DISPC_IRQ_EVSYNC_EVEN 0x0004
111 #define DISPC_IRQ_EVSYNC_ODD 0x0008
112 #define DISPC_IRQ_ACBIAS_COUNT_STAT 0x0010
113 #define DISPC_IRQ_PROG_LINE_NUM 0x0020
114 #define DISPC_IRQ_GFX_FIFO_UNDERFLOW 0x0040
115 #define DISPC_IRQ_GFX_END_WIN 0x0080
116 #define DISPC_IRQ_PAL_GAMMA_MASK 0x0100
117 #define DISPC_IRQ_OCP_ERR 0x0200
118 #define DISPC_IRQ_VID1_FIFO_UNDERFLOW 0x0400
119 #define DISPC_IRQ_VID1_END_WIN 0x0800
120 #define DISPC_IRQ_VID2_FIFO_UNDERFLOW 0x1000
121 #define DISPC_IRQ_VID2_END_WIN 0x2000
122 #define DISPC_IRQ_SYNC_LOST 0x4000
124 #define DISPC_IRQ_MASK_ALL 0x7fff
126 #define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
127 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
128 DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
131 #define MAX_PALETTE_SIZE (256 * 16)
133 #define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args)
135 #define FLD_MASK(pos, len) (((1 << len) - 1) << pos)
137 #define MOD_REG_FLD(reg, mask, val) \
138 dispc_write_reg((reg), (dispc_read_reg(reg) & ~(mask)) | (val));
143 dma_addr_t vram_phys;
148 unsigned long enabled_irqs;
149 void (*irq_callback)(void *);
150 void *irq_callback_data;
151 struct completion frame_done;
153 struct clk *dss_ick, *dss1_fck;
154 struct clk *dss_54m_fck;
156 int active_plane_mask;
158 enum omapfb_update_mode update_mode;
159 struct omapfb_device *fbdev;
162 static void inline dispc_write_reg(int idx, u32 val)
164 __raw_writel(val, dispc.base + idx);
167 static u32 inline dispc_read_reg(int idx)
169 u32 l = __raw_readl(dispc.base + idx);
173 /* Select RFBI or bypass mode */
174 static void enable_rfbi_mode(int enable)
178 l = dispc_read_reg(DISPC_CONTROL);
179 /* Enable RFBI, GPIO0/1 */
180 l &= ~((1 << 11) | (1 << 15) | (1 << 16));
181 l |= enable ? (1 << 11) : 0;
182 /* RFBI En: GPIO0/1=10 RFBI Dis: GPIO0/1=11 */
184 l |= enable ? 0 : (1 << 16);
185 dispc_write_reg(DISPC_CONTROL, l);
188 static void set_lcd_data_lines(int data_lines)
193 switch (data_lines) {
210 l = dispc_read_reg(DISPC_CONTROL);
213 dispc_write_reg(DISPC_CONTROL, l);
216 static void set_load_mode(int mode)
218 BUG_ON(mode & ~(DISPC_LOAD_CLUT_ONLY | DISPC_LOAD_FRAME_ONLY |
219 DISPC_LOAD_CLUT_ONCE_FRAME));
220 MOD_REG_FLD(DISPC_CONFIG, 0x03 << 1, mode << 1);
223 void omap_dispc_set_lcd_size(int x, int y)
225 BUG_ON((x > (1 << 11)) || (y > (1 << 11)));
226 MOD_REG_FLD(DISPC_SIZE_LCD, FLD_MASK(16, 11) | FLD_MASK(0, 11),
227 ((y - 1) << 16) | (x - 1));
229 EXPORT_SYMBOL(omap_dispc_set_lcd_size);
231 void omap_dispc_set_digit_size(int x, int y)
233 BUG_ON((x > (1 << 11)) || (y > (1 << 11)));
234 MOD_REG_FLD(DISPC_SIZE_DIG, FLD_MASK(16, 11) | FLD_MASK(0, 11),
235 ((y - 1) << 16) | (x - 1));
237 EXPORT_SYMBOL(omap_dispc_set_digit_size);
239 static void setup_plane_fifo(int plane)
241 const u32 ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
242 DISPC_VID1_BASE + DISPC_VID_FIFO_THRESHOLD,
243 DISPC_VID2_BASE + DISPC_VID_FIFO_THRESHOLD };
244 const u32 fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
245 DISPC_VID1_BASE + DISPC_VID_FIFO_SIZE_STATUS,
246 DISPC_VID2_BASE + DISPC_VID_FIFO_SIZE_STATUS };
252 l = dispc_read_reg(fsz_reg[plane]);
254 /* HIGH=3/4 LOW=1/4 */
255 MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 9) | FLD_MASK(0, 9),
256 ((l * 3 / 4) << 16) | (l / 4));
259 void omap_dispc_enable_lcd_out(int enable)
261 MOD_REG_FLD(DISPC_CONTROL, 1, enable ? 1 : 0);
263 EXPORT_SYMBOL(omap_dispc_enable_lcd_out);
265 void omap_dispc_enable_digit_out(int enable)
267 MOD_REG_FLD(DISPC_CONTROL, 1 << 1, enable ? 1 << 1 : 0);
269 EXPORT_SYMBOL(omap_dispc_enable_digit_out);
271 static int omap_dispc_setup_plane(int plane, int channel_out,
272 unsigned long offset, int screen_width,
273 int pos_x, int pos_y, int width, int height,
276 const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
277 DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
278 DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
279 const u32 ba_reg[] = { DISPC_GFX_BA0, DISPC_VID1_BASE + DISPC_VID_BA0,
280 DISPC_VID2_BASE + DISPC_VID_BA0 };
281 const u32 ps_reg[] = { DISPC_GFX_POSITION,
282 DISPC_VID1_BASE + DISPC_VID_POSITION,
283 DISPC_VID2_BASE + DISPC_VID_POSITION };
284 const u32 sz_reg[] = { DISPC_GFX_SIZE, DISPC_VID1_BASE + DISPC_VID_SIZE,
285 DISPC_VID2_BASE + DISPC_VID_SIZE };
286 const u32 ri_reg[] = { DISPC_GFX_ROW_INC,
287 DISPC_VID1_BASE + DISPC_VID_ROW_INC,
288 DISPC_VID2_BASE + DISPC_VID_ROW_INC };
289 int chout_shift, burst_shift;
298 case OMAPFB_PLANE_GFX:
302 case OMAPFB_PLANE_VID1:
303 case OMAPFB_PLANE_VID2:
311 switch (channel_out) {
312 case OMAPFB_CHANNEL_OUT_LCD:
315 case OMAPFB_CHANNEL_OUT_DIGIT:
322 switch (color_mode) {
323 case OMAPFB_COLOR_RGB565:
324 color_code = DISPC_RGB_16_BPP;
327 case OMAPFB_COLOR_YUV422:
330 color_code = DISPC_UYVY_422;
333 case OMAPFB_COLOR_YUV420:
336 color_code = DISPC_YUV2_422;
343 l = dispc_read_reg(at_reg[plane]);
346 l |= color_code << 1;
348 l &= ~(0x03 << burst_shift);
349 l |= DISPC_BURST_8x32 << burst_shift;
351 l &= ~(1 << chout_shift);
352 l |= chout_val << chout_shift;
354 dispc_write_reg(at_reg[plane], l);
357 dispc_write_reg(ba_reg[plane],
358 dispc.vram_phys + PAGE_ALIGN(MAX_PALETTE_SIZE) + offset);
360 MOD_REG_FLD(ps_reg[plane],
361 FLD_MASK(16, 11) | FLD_MASK(0, 11), (pos_y << 16) | pos_x);
363 MOD_REG_FLD(sz_reg[plane], FLD_MASK(16, 11) | FLD_MASK(0, 11),
364 ((height - 1) << 16) | (width - 1));
366 dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1);
371 static int omap_dispc_enable_plane(int plane, int enable)
373 const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
374 DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
375 DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
378 if ((unsigned int)plane > 2)
380 MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0);
385 static int omap_dispc_set_color_key(struct omapfb_color_key *ck)
390 switch (ck->channel_out) {
391 case OMAPFB_CHANNEL_OUT_LCD:
392 df_reg = DISPC_DEFAULT_COLOR0;
393 tr_reg = DISPC_TRANS_COLOR0;
396 case OMAPFB_CHANNEL_OUT_DIGIT:
397 df_reg = DISPC_DEFAULT_COLOR1;
398 tr_reg = DISPC_TRANS_COLOR1;
404 switch (ck->key_type) {
405 case OMAPFB_COLOR_KEY_DISABLED:
408 case OMAPFB_COLOR_KEY_GFX_DST:
411 case OMAPFB_COLOR_KEY_VID_SRC:
417 MOD_REG_FLD(DISPC_CONFIG, FLD_MASK(shift, 2), val << shift);
420 dispc_write_reg(tr_reg, ck->trans_key);
421 dispc_write_reg(df_reg, ck->background);
426 static void load_palette(void)
430 static int omap_dispc_set_update_mode(enum omapfb_update_mode mode)
436 if (mode != dispc.update_mode) {
438 case OMAPFB_AUTO_UPDATE:
439 omap_dispc_enable_lcd_out(1);
440 dispc.update_mode = mode;
442 case OMAPFB_UPDATE_DISABLED:
443 init_completion(&dispc.frame_done);
444 omap_dispc_enable_lcd_out(0);
445 if (!wait_for_completion_timeout(&dispc.frame_done,
446 msecs_to_jiffies(500))) {
447 pr_err("timeout waiting for FRAME DONE\n");
449 dispc.update_mode = mode;
461 static enum omapfb_update_mode omap_dispc_get_update_mode(void)
463 return dispc.update_mode;
466 static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
468 unsigned long fck, lck;
472 fck = clk_get_rate(dispc.dss1_fck);
474 *pck_div = lck / pck;
476 *pck_div = max(2, *pck_div);
478 *pck_div = max(3, *pck_div);
479 if (*pck_div > 255) {
481 lck = pck * *pck_div;
482 *lck_div = fck / lck;
483 BUG_ON(*lck_div < 1);
484 if (*lck_div > 255) {
487 MODULE_NAME ": pixclock %d kHz too low.\n",
493 static void set_lcd_timings(void)
496 int lck_div, pck_div;
497 struct lcd_panel *panel = dispc.fbdev->panel;
498 int is_tft = panel->config & OMAP_LCDC_PANEL_TFT;
503 /* TFT dither, TFT/STN */
504 l = (1 << 7) | (1 << 3);
505 MOD_REG_FLD(DISPC_CONTROL, l, is_tft ? l : 0);
507 l = dispc_read_reg(DISPC_TIMING_H);
508 l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8));
509 l |= ( max(1, (min(64, panel->hsw))) - 1 ) << 0;
510 l |= ( max(1, (min(256, panel->hfp))) - 1 ) << 8;
511 l |= ( max(1, (min(256, panel->hbp))) - 1 ) << 20;
512 dispc_write_reg(DISPC_TIMING_H, l);
514 l = dispc_read_reg(DISPC_TIMING_V);
515 l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8));
516 l |= ( max(1, (min(64, panel->vsw))) - 1 ) << 0;
517 l |= ( max(0, (min(255, panel->vfp))) - 0 ) << 8;
518 l |= ( max(0, (min(255, panel->vbp))) - 0 ) << 20;
519 dispc_write_reg(DISPC_TIMING_V, l);
521 l = dispc_read_reg(DISPC_POL_FREQ);
522 l &= ~FLD_MASK(12, 6);
523 l |= (panel->config & OMAP_LCDC_SIGNAL_MASK) << 12;
524 l |= panel->acb & 0xff;
525 dispc_write_reg(DISPC_POL_FREQ, l);
527 calc_ck_div(is_tft, panel->pixel_clock * 1000, &lck_div, &pck_div);
529 l = dispc_read_reg(DISPC_DIVISOR);
530 l &= ~(FLD_MASK(16, 8) | FLD_MASK(0, 8));
531 l |= (lck_div << 16) | (pck_div << 0);
532 dispc_write_reg(DISPC_DIVISOR, l);
534 /* update panel info with the exact clock */
535 fck = clk_get_rate(dispc.dss1_fck);
536 panel->pixel_clock = fck / lck_div / pck_div / 1000;
539 int omap_dispc_request_irq(void (*callback)(void *data), void *data)
543 BUG_ON(callback == NULL);
545 if (dispc.irq_callback)
548 dispc.irq_callback = callback;
549 dispc.irq_callback_data = data;
554 EXPORT_SYMBOL(omap_dispc_request_irq);
556 void omap_dispc_enable_irqs(int irq_mask)
558 dispc.enabled_irqs = irq_mask;
559 irq_mask |= DISPC_IRQ_MASK_ERROR;
560 MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask);
562 EXPORT_SYMBOL(omap_dispc_enable_irqs);
564 void omap_dispc_disable_irqs(int irq_mask)
566 dispc.enabled_irqs &= ~irq_mask;
567 irq_mask &= ~DISPC_IRQ_MASK_ERROR;
568 MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask);
570 EXPORT_SYMBOL(omap_dispc_disable_irqs);
572 void omap_dispc_free_irq(void)
574 omap_dispc_disable_irqs(DISPC_IRQ_MASK_ALL);
575 dispc.irq_callback = NULL;
576 dispc.irq_callback_data = NULL;
578 EXPORT_SYMBOL(omap_dispc_free_irq);
580 static irqreturn_t omap_dispc_irq_handler(int irq, void *dev, struct pt_regs *regs)
582 u32 stat = dispc_read_reg(DISPC_IRQSTATUS);
587 if (stat & DISPC_IRQ_FRAMEMASK)
588 complete(&dispc.frame_done);
590 if (stat & DISPC_IRQ_MASK_ERROR) {
592 pr_err("irq error status %04x\n", stat);
594 pr_err("disable irq\n");
595 dispc_write_reg(DISPC_IRQENABLE, 0);
599 if ((stat & dispc.enabled_irqs) && dispc.irq_callback)
600 dispc.irq_callback(dispc.irq_callback_data);
602 dispc_write_reg(DISPC_IRQSTATUS, stat);
607 static int get_dss_clocks(void)
609 if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) {
610 pr_err("can't get dss_ick");
611 return PTR_ERR(dispc.dss_ick);
614 if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) {
615 pr_err("can't get dss1_fck");
616 clk_put(dispc.dss_ick);
617 return PTR_ERR(dispc.dss1_fck);
620 if (IS_ERR((dispc.dss_54m_fck =
621 clk_get(dispc.fbdev->dev, "dss_54m_fck")))) {
622 pr_err("can't get dss_54m_fck");
623 clk_put(dispc.dss_ick);
624 clk_put(dispc.dss1_fck);
625 return PTR_ERR(dispc.dss_54m_fck);
631 static void put_dss_clocks(void)
633 clk_put(dispc.dss_54m_fck);
634 clk_put(dispc.dss1_fck);
635 clk_put(dispc.dss_ick);
638 static void enable_lcd_clocks(int enable)
641 clk_enable(dispc.dss_ick);
642 clk_enable(dispc.dss1_fck);
644 clk_disable(dispc.dss1_fck);
645 clk_disable(dispc.dss_ick);
649 static void enable_digit_clocks(int enable)
652 clk_enable(dispc.dss_54m_fck);
654 clk_disable(dispc.dss_54m_fck);
657 static void omap_dispc_suspend(void)
661 if (dispc.update_mode == OMAPFB_AUTO_UPDATE) {
662 init_completion(&dispc.frame_done);
663 omap_dispc_enable_lcd_out(0);
664 if (!wait_for_completion_timeout(&dispc.frame_done,
665 msecs_to_jiffies(500))) {
666 pr_err("timeout waiting for FRAME DONE\n");
668 enable_lcd_clocks(0);
674 static void omap_dispc_resume(void)
678 if (dispc.update_mode == OMAPFB_AUTO_UPDATE) {
679 enable_lcd_clocks(1);
682 omap_dispc_enable_lcd_out(1);
688 /* Called when used in bypass mode */
689 static int alloc_vram(int req_size)
692 struct lcd_panel *panel = dispc.fbdev->panel;
694 frame_size = PAGE_ALIGN(panel->x_res * panel->bpp / 8 * panel->y_res);
695 if (req_size > frame_size)
696 frame_size = req_size;
697 dispc.vram_size = PAGE_ALIGN(MAX_PALETTE_SIZE) + frame_size;
698 dispc.vram_virt = dma_alloc_writecombine(dispc.fbdev->dev,
699 dispc.vram_size, &dispc.vram_phys, GFP_KERNEL);
701 if (dispc.vram_virt == 0) {
702 pr_err("unable to allocate fb DMA memory\n");
709 static void free_vram(void)
711 dma_free_writecombine(dispc.fbdev->dev, dispc.vram_size,
712 dispc.vram_virt, dispc.vram_phys);
715 static void omap_dispc_get_vram_layout(unsigned long *size, void **virt,
718 *size = dispc.vram_size - PAGE_ALIGN(MAX_PALETTE_SIZE);
719 *virt = (u8 *)dispc.vram_virt + PAGE_ALIGN(MAX_PALETTE_SIZE);
720 *phys = dispc.vram_phys + PAGE_ALIGN(MAX_PALETTE_SIZE);
723 static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
728 struct lcd_panel *panel = fbdev->panel;
733 memset(&dispc, 0, sizeof(dispc));
735 dispc.base = io_p2v(DISPC_BASE);
737 dispc.ext_mode = ext_mode;
739 if ((r = get_dss_clocks()) < 0)
742 enable_lcd_clocks(1);
743 /* Reset monitoring works only w/ the 54M clk */
744 enable_digit_clocks(1);
746 l = dispc_read_reg(DISPC_REVISION);
747 pr_info(MODULE_NAME ": version %d.%d\n", l >> 4 & 0x0f, l & 0x0f);
750 MOD_REG_FLD(DISPC_SYSCONFIG, 1 << 1, 1 << 1);
752 while (!(dispc_read_reg(DISPC_SYSSTATUS) & 1)) {
754 pr_err("soft reset failed\n");
756 enable_digit_clocks(0);
761 enable_digit_clocks(0);
763 if (!ext_mode && (r = alloc_vram(req_vram_size)) < 0)
766 /* Set logic clock to the fck for now */
767 MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(16, 8), 1);
773 l = dispc_read_reg(DISPC_IRQSTATUS);
774 dispc_write_reg(l, DISPC_IRQSTATUS);
776 /* Enable those that we handle always */
777 omap_dispc_enable_irqs(DISPC_IRQ_FRAMEMASK);
779 if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler,
780 0, MODULE_NAME, NULL)) < 0) {
781 pr_err("can't get DSS IRQ\n");
785 set_lcd_data_lines(panel->data_lines);
786 set_load_mode(DISPC_LOAD_FRAME_ONLY);
789 omap_dispc_set_lcd_size(panel->x_res, panel->y_res);
792 enable_rfbi_mode(ext_mode);
800 enable_lcd_clocks(0);
807 static void omap_dispc_cleanup(void)
809 free_irq(INT_24XX_DSS_IRQ, NULL);
810 enable_lcd_clocks(0);
816 static unsigned long omap_dispc_get_caps(void)
821 struct lcd_ctrl omap2_int_ctrl = {
823 .init = omap_dispc_init,
824 .cleanup = omap_dispc_cleanup,
825 .get_vram_layout = omap_dispc_get_vram_layout,
826 .get_caps = omap_dispc_get_caps,
827 .set_update_mode = omap_dispc_set_update_mode,
828 .get_update_mode = omap_dispc_get_update_mode,
829 .update_window = NULL,
830 .suspend = omap_dispc_suspend,
831 .resume = omap_dispc_resume,
832 .setup_plane = omap_dispc_setup_plane,
833 .enable_plane = omap_dispc_enable_plane,
834 .set_color_key = omap_dispc_set_color_key,
837 MODULE_DESCRIPTION("TI OMAP LCDC controller");
838 MODULE_LICENSE("GPL");