drivers/video/da8xx-fb.c: fix error return
[safe/jmp/linux-2.6] / drivers / video / da8xx-fb.c
1 /*
2  * Copyright (C) 2008-2009 MontaVista Software Inc.
3  * Copyright (C) 2008-2009 Texas Instruments Inc
4  *
5  * Based on the LCD driver for TI Avalanche processors written by
6  * Ajay Singh and Shalom Hai.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option)any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/fb.h>
25 #include <linux/dma-mapping.h>
26 #include <linux/device.h>
27 #include <linux/platform_device.h>
28 #include <linux/uaccess.h>
29 #include <linux/interrupt.h>
30 #include <linux/clk.h>
31 #include <video/da8xx-fb.h>
32
33 #define DRIVER_NAME "da8xx_lcdc"
34
35 /* LCD Status Register */
36 #define LCD_END_OF_FRAME0               BIT(8)
37 #define LCD_FIFO_UNDERFLOW              BIT(5)
38 #define LCD_SYNC_LOST                   BIT(2)
39
40 /* LCD DMA Control Register */
41 #define LCD_DMA_BURST_SIZE(x)           ((x) << 4)
42 #define LCD_DMA_BURST_1                 0x0
43 #define LCD_DMA_BURST_2                 0x1
44 #define LCD_DMA_BURST_4                 0x2
45 #define LCD_DMA_BURST_8                 0x3
46 #define LCD_DMA_BURST_16                0x4
47 #define LCD_END_OF_FRAME_INT_ENA        BIT(2)
48 #define LCD_DUAL_FRAME_BUFFER_ENABLE    BIT(0)
49
50 /* LCD Control Register */
51 #define LCD_CLK_DIVISOR(x)              ((x) << 8)
52 #define LCD_RASTER_MODE                 0x01
53
54 /* LCD Raster Control Register */
55 #define LCD_PALETTE_LOAD_MODE(x)        ((x) << 20)
56 #define PALETTE_AND_DATA                0x00
57 #define PALETTE_ONLY                    0x01
58
59 #define LCD_MONO_8BIT_MODE              BIT(9)
60 #define LCD_RASTER_ORDER                BIT(8)
61 #define LCD_TFT_MODE                    BIT(7)
62 #define LCD_UNDERFLOW_INT_ENA           BIT(6)
63 #define LCD_MONOCHROME_MODE             BIT(1)
64 #define LCD_RASTER_ENABLE               BIT(0)
65 #define LCD_TFT_ALT_ENABLE              BIT(23)
66 #define LCD_STN_565_ENABLE              BIT(24)
67
68 /* LCD Raster Timing 2 Register */
69 #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)      ((x) << 16)
70 #define LCD_AC_BIAS_FREQUENCY(x)                ((x) << 8)
71 #define LCD_SYNC_CTRL                           BIT(25)
72 #define LCD_SYNC_EDGE                           BIT(24)
73 #define LCD_INVERT_PIXEL_CLOCK                  BIT(22)
74 #define LCD_INVERT_LINE_CLOCK                   BIT(21)
75 #define LCD_INVERT_FRAME_CLOCK                  BIT(20)
76
77 /* LCD Block */
78 #define  LCD_CTRL_REG                           0x4
79 #define  LCD_STAT_REG                           0x8
80 #define  LCD_RASTER_CTRL_REG                    0x28
81 #define  LCD_RASTER_TIMING_0_REG                0x2C
82 #define  LCD_RASTER_TIMING_1_REG                0x30
83 #define  LCD_RASTER_TIMING_2_REG                0x34
84 #define  LCD_DMA_CTRL_REG                       0x40
85 #define  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG        0x44
86 #define  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG     0x48
87
88 #define WSI_TIMEOUT     50
89 #define PALETTE_SIZE    256
90 #define LEFT_MARGIN     64
91 #define RIGHT_MARGIN    64
92 #define UPPER_MARGIN    32
93 #define LOWER_MARGIN    32
94
95 static resource_size_t da8xx_fb_reg_base;
96 static struct resource *lcdc_regs;
97
98 static inline unsigned int lcdc_read(unsigned int addr)
99 {
100         return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
101 }
102
103 static inline void lcdc_write(unsigned int val, unsigned int addr)
104 {
105         __raw_writel(val, da8xx_fb_reg_base + (addr));
106 }
107
108 struct da8xx_fb_par {
109         resource_size_t p_palette_base;
110         unsigned char *v_palette_base;
111         struct clk *lcdc_clk;
112         int irq;
113         unsigned short pseudo_palette[16];
114         unsigned int databuf_sz;
115         unsigned int palette_sz;
116 };
117
118 /* Variable Screen Information */
119 static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
120         .xoffset = 0,
121         .yoffset = 0,
122         .transp = {0, 0, 0},
123         .nonstd = 0,
124         .activate = 0,
125         .height = -1,
126         .width = -1,
127         .pixclock = 46666,      /* 46us - AUO display */
128         .accel_flags = 0,
129         .left_margin = LEFT_MARGIN,
130         .right_margin = RIGHT_MARGIN,
131         .upper_margin = UPPER_MARGIN,
132         .lower_margin = LOWER_MARGIN,
133         .sync = 0,
134         .vmode = FB_VMODE_NONINTERLACED
135 };
136
137 static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
138         .id = "DA8xx FB Drv",
139         .type = FB_TYPE_PACKED_PIXELS,
140         .type_aux = 0,
141         .visual = FB_VISUAL_PSEUDOCOLOR,
142         .xpanstep = 1,
143         .ypanstep = 1,
144         .ywrapstep = 1,
145         .accel = FB_ACCEL_NONE
146 };
147
148 struct da8xx_panel {
149         const char      name[25];       /* Full name <vendor>_<model> */
150         unsigned short  width;
151         unsigned short  height;
152         int             hfp;            /* Horizontal front porch */
153         int             hbp;            /* Horizontal back porch */
154         int             hsw;            /* Horizontal Sync Pulse Width */
155         int             vfp;            /* Vertical front porch */
156         int             vbp;            /* Vertical back porch */
157         int             vsw;            /* Vertical Sync Pulse Width */
158         int             pxl_clk;        /* Pixel clock */
159         unsigned char   invert_pxl_clk; /* Invert Pixel clock */
160 };
161
162 static struct da8xx_panel known_lcd_panels[] = {
163         /* Sharp LCD035Q3DG01 */
164         [0] = {
165                 .name = "Sharp_LCD035Q3DG01",
166                 .width = 320,
167                 .height = 240,
168                 .hfp = 8,
169                 .hbp = 6,
170                 .hsw = 0,
171                 .vfp = 2,
172                 .vbp = 2,
173                 .vsw = 0,
174                 .pxl_clk = 0x10,
175                 .invert_pxl_clk = 1,
176         },
177         /* Sharp LK043T1DG01 */
178         [1] = {
179                 .name = "Sharp_LK043T1DG01",
180                 .width = 480,
181                 .height = 272,
182                 .hfp = 2,
183                 .hbp = 2,
184                 .hsw = 41,
185                 .vfp = 2,
186                 .vbp = 2,
187                 .vsw = 10,
188                 .pxl_clk = 0x12,
189                 .invert_pxl_clk = 0,
190         },
191 };
192
193 /* Disable the Raster Engine of the LCD Controller */
194 static void lcd_disable_raster(struct da8xx_fb_par *par)
195 {
196         u32 reg;
197
198         reg = lcdc_read(LCD_RASTER_CTRL_REG);
199         if (reg & LCD_RASTER_ENABLE)
200                 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
201 }
202
203 static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
204 {
205         u32 tmp = par->p_palette_base + par->databuf_sz - 4;
206         u32 reg;
207
208         /* Update the databuf in the hw. */
209         lcdc_write(par->p_palette_base, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
210         lcdc_write(tmp, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
211
212         /* Start the DMA. */
213         reg = lcdc_read(LCD_RASTER_CTRL_REG);
214         reg &= ~(3 << 20);
215         if (load_mode == LOAD_DATA)
216                 reg |= LCD_PALETTE_LOAD_MODE(PALETTE_AND_DATA);
217         else if (load_mode == LOAD_PALETTE)
218                 reg |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
219
220         lcdc_write(reg, LCD_RASTER_CTRL_REG);
221 }
222
223 /* Configure the Burst Size of DMA */
224 static int lcd_cfg_dma(int burst_size)
225 {
226         u32 reg;
227
228         reg = lcdc_read(LCD_DMA_CTRL_REG) & 0x00000001;
229         switch (burst_size) {
230         case 1:
231                 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1);
232                 break;
233         case 2:
234                 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2);
235                 break;
236         case 4:
237                 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4);
238                 break;
239         case 8:
240                 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
241                 break;
242         case 16:
243                 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
244                 break;
245         default:
246                 return -EINVAL;
247         }
248         lcdc_write(reg, LCD_DMA_CTRL_REG);
249
250         return 0;
251 }
252
253 static void lcd_cfg_ac_bias(int period, int transitions_per_int)
254 {
255         u32 reg;
256
257         /* Set the AC Bias Period and Number of Transisitons per Interrupt */
258         reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & 0xFFF00000;
259         reg |= LCD_AC_BIAS_FREQUENCY(period) |
260                 LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int);
261         lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
262 }
263
264 static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width,
265                 int front_porch)
266 {
267         u32 reg;
268
269         reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf;
270         reg |= ((back_porch & 0xff) << 24)
271             | ((front_porch & 0xff) << 16)
272             | ((pulse_width & 0x3f) << 10);
273         lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
274 }
275
276 static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
277                 int front_porch)
278 {
279         u32 reg;
280
281         reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff;
282         reg |= ((back_porch & 0xff) << 24)
283             | ((front_porch & 0xff) << 16)
284             | ((pulse_width & 0x3f) << 10);
285         lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
286 }
287
288 static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
289 {
290         u32 reg;
291
292         reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
293                                                 LCD_MONO_8BIT_MODE |
294                                                 LCD_MONOCHROME_MODE);
295
296         switch (cfg->p_disp_panel->panel_shade) {
297         case MONOCHROME:
298                 reg |= LCD_MONOCHROME_MODE;
299                 if (cfg->mono_8bit_mode)
300                         reg |= LCD_MONO_8BIT_MODE;
301                 break;
302         case COLOR_ACTIVE:
303                 reg |= LCD_TFT_MODE;
304                 if (cfg->tft_alt_mode)
305                         reg |= LCD_TFT_ALT_ENABLE;
306                 break;
307
308         case COLOR_PASSIVE:
309                 if (cfg->stn_565_mode)
310                         reg |= LCD_STN_565_ENABLE;
311                 break;
312
313         default:
314                 return -EINVAL;
315         }
316
317         /* enable additional interrupts here */
318         reg |= LCD_UNDERFLOW_INT_ENA;
319
320         lcdc_write(reg, LCD_RASTER_CTRL_REG);
321
322         reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
323
324         if (cfg->sync_ctrl)
325                 reg |= LCD_SYNC_CTRL;
326         else
327                 reg &= ~LCD_SYNC_CTRL;
328
329         if (cfg->sync_edge)
330                 reg |= LCD_SYNC_EDGE;
331         else
332                 reg &= ~LCD_SYNC_EDGE;
333
334         if (cfg->invert_line_clock)
335                 reg |= LCD_INVERT_LINE_CLOCK;
336         else
337                 reg &= ~LCD_INVERT_LINE_CLOCK;
338
339         if (cfg->invert_frm_clock)
340                 reg |= LCD_INVERT_FRAME_CLOCK;
341         else
342                 reg &= ~LCD_INVERT_FRAME_CLOCK;
343
344         lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
345
346         return 0;
347 }
348
349 static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
350                 u32 bpp, u32 raster_order)
351 {
352         u32 bpl, reg;
353
354         /* Disable Dual Frame Buffer. */
355         reg = lcdc_read(LCD_DMA_CTRL_REG);
356         lcdc_write(reg & ~LCD_DUAL_FRAME_BUFFER_ENABLE,
357                                                 LCD_DMA_CTRL_REG);
358         /* Set the Panel Width */
359         /* Pixels per line = (PPL + 1)*16 */
360         /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
361         width &= 0x3f0;
362         reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
363         reg &= 0xfffffc00;
364         reg |= ((width >> 4) - 1) << 4;
365         lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
366
367         /* Set the Panel Height */
368         reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
369         reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
370         lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
371
372         /* Set the Raster Order of the Frame Buffer */
373         reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
374         if (raster_order)
375                 reg |= LCD_RASTER_ORDER;
376         lcdc_write(reg, LCD_RASTER_CTRL_REG);
377
378         switch (bpp) {
379         case 1:
380         case 2:
381         case 4:
382         case 16:
383                 par->palette_sz = 16 * 2;
384                 break;
385
386         case 8:
387                 par->palette_sz = 256 * 2;
388                 break;
389
390         default:
391                 return -EINVAL;
392         }
393
394         bpl = width * bpp / 8;
395         par->databuf_sz = height * bpl + par->palette_sz;
396
397         return 0;
398 }
399
400 static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
401                               unsigned blue, unsigned transp,
402                               struct fb_info *info)
403 {
404         struct da8xx_fb_par *par = info->par;
405         unsigned short *palette = (unsigned short *)par->v_palette_base;
406         u_short pal;
407
408         if (regno > 255)
409                 return 1;
410
411         if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
412                 return 1;
413
414         if (info->var.bits_per_pixel == 8) {
415                 red >>= 4;
416                 green >>= 8;
417                 blue >>= 12;
418
419                 pal = (red & 0x0f00);
420                 pal |= (green & 0x00f0);
421                 pal |= (blue & 0x000f);
422
423                 palette[regno] = pal;
424
425         } else if ((info->var.bits_per_pixel == 16) && regno < 16) {
426                 red >>= (16 - info->var.red.length);
427                 red <<= info->var.red.offset;
428
429                 green >>= (16 - info->var.green.length);
430                 green <<= info->var.green.offset;
431
432                 blue >>= (16 - info->var.blue.length);
433                 blue <<= info->var.blue.offset;
434
435                 par->pseudo_palette[regno] = red | green | blue;
436
437                 palette[0] = 0x4000;
438         }
439
440         return 0;
441 }
442
443 static void lcd_reset(struct da8xx_fb_par *par)
444 {
445         /* Disable the Raster if previously Enabled */
446         if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE)
447                 lcd_disable_raster(par);
448
449         /* DMA has to be disabled */
450         lcdc_write(0, LCD_DMA_CTRL_REG);
451         lcdc_write(0, LCD_RASTER_CTRL_REG);
452 }
453
454 static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
455                 struct da8xx_panel *panel)
456 {
457         u32 bpp;
458         int ret = 0;
459
460         lcd_reset(par);
461
462         /* Configure the LCD clock divisor. */
463         lcdc_write(LCD_CLK_DIVISOR(panel->pxl_clk) |
464                         (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
465
466         if (panel->invert_pxl_clk)
467                 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
468                         LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
469         else
470                 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) &
471                         ~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
472
473         /* Configure the DMA burst size. */
474         ret = lcd_cfg_dma(cfg->dma_burst_sz);
475         if (ret < 0)
476                 return ret;
477
478         /* Configure the AC bias properties. */
479         lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
480
481         /* Configure the vertical and horizontal sync properties. */
482         lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp);
483         lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp);
484
485         /* Configure for disply */
486         ret = lcd_cfg_display(cfg);
487         if (ret < 0)
488                 return ret;
489
490         if (QVGA != cfg->p_disp_panel->panel_type)
491                 return -EINVAL;
492
493         if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
494             cfg->bpp >= cfg->p_disp_panel->min_bpp)
495                 bpp = cfg->bpp;
496         else
497                 bpp = cfg->p_disp_panel->max_bpp;
498         if (bpp == 12)
499                 bpp = 16;
500         ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width,
501                                 (unsigned int)panel->height, bpp,
502                                 cfg->raster_order);
503         if (ret < 0)
504                 return ret;
505
506         /* Configure FDD */
507         lcdc_write((lcdc_read(LCD_RASTER_CTRL_REG) & 0xfff00fff) |
508                        (cfg->fdd << 12), LCD_RASTER_CTRL_REG);
509
510         return 0;
511 }
512
513 static irqreturn_t lcdc_irq_handler(int irq, void *arg)
514 {
515         u32 stat = lcdc_read(LCD_STAT_REG);
516         u32 reg;
517
518         if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
519                 reg = lcdc_read(LCD_RASTER_CTRL_REG);
520                 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
521                 lcdc_write(stat, LCD_STAT_REG);
522                 lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
523         } else
524                 lcdc_write(stat, LCD_STAT_REG);
525
526         return IRQ_HANDLED;
527 }
528
529 static int fb_check_var(struct fb_var_screeninfo *var,
530                         struct fb_info *info)
531 {
532         int err = 0;
533
534         switch (var->bits_per_pixel) {
535         case 1:
536         case 8:
537                 var->red.offset = 0;
538                 var->red.length = 8;
539                 var->green.offset = 0;
540                 var->green.length = 8;
541                 var->blue.offset = 0;
542                 var->blue.length = 8;
543                 var->transp.offset = 0;
544                 var->transp.length = 0;
545                 break;
546         case 4:
547                 var->red.offset = 0;
548                 var->red.length = 4;
549                 var->green.offset = 0;
550                 var->green.length = 4;
551                 var->blue.offset = 0;
552                 var->blue.length = 4;
553                 var->transp.offset = 0;
554                 var->transp.length = 0;
555                 break;
556         case 16:                /* RGB 565 */
557                 var->red.offset = 0;
558                 var->red.length = 5;
559                 var->green.offset = 5;
560                 var->green.length = 6;
561                 var->blue.offset = 11;
562                 var->blue.length = 5;
563                 var->transp.offset = 0;
564                 var->transp.length = 0;
565                 break;
566         default:
567                 err = -EINVAL;
568         }
569
570         var->red.msb_right = 0;
571         var->green.msb_right = 0;
572         var->blue.msb_right = 0;
573         var->transp.msb_right = 0;
574         return err;
575 }
576
577 static int __devexit fb_remove(struct platform_device *dev)
578 {
579         struct fb_info *info = dev_get_drvdata(&dev->dev);
580
581         if (info) {
582                 struct da8xx_fb_par *par = info->par;
583
584                 if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE)
585                         lcd_disable_raster(par);
586                 lcdc_write(0, LCD_RASTER_CTRL_REG);
587
588                 /* disable DMA  */
589                 lcdc_write(0, LCD_DMA_CTRL_REG);
590
591                 unregister_framebuffer(info);
592                 fb_dealloc_cmap(&info->cmap);
593                 dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
594                                         info->screen_base,
595                                         info->fix.smem_start);
596                 free_irq(par->irq, par);
597                 clk_disable(par->lcdc_clk);
598                 clk_put(par->lcdc_clk);
599                 framebuffer_release(info);
600                 iounmap((void __iomem *)da8xx_fb_reg_base);
601                 release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
602
603         }
604         return 0;
605 }
606
607 static int fb_ioctl(struct fb_info *info, unsigned int cmd,
608                           unsigned long arg)
609 {
610         struct lcd_sync_arg sync_arg;
611
612         switch (cmd) {
613         case FBIOGET_CONTRAST:
614         case FBIOPUT_CONTRAST:
615         case FBIGET_BRIGHTNESS:
616         case FBIPUT_BRIGHTNESS:
617         case FBIGET_COLOR:
618         case FBIPUT_COLOR:
619                 return -ENOTTY;
620         case FBIPUT_HSYNC:
621                 if (copy_from_user(&sync_arg, (char *)arg,
622                                 sizeof(struct lcd_sync_arg)))
623                         return -EFAULT;
624                 lcd_cfg_horizontal_sync(sync_arg.back_porch,
625                                         sync_arg.pulse_width,
626                                         sync_arg.front_porch);
627                 break;
628         case FBIPUT_VSYNC:
629                 if (copy_from_user(&sync_arg, (char *)arg,
630                                 sizeof(struct lcd_sync_arg)))
631                         return -EFAULT;
632                 lcd_cfg_vertical_sync(sync_arg.back_porch,
633                                         sync_arg.pulse_width,
634                                         sync_arg.front_porch);
635                 break;
636         default:
637                 return -EINVAL;
638         }
639         return 0;
640 }
641
642 static struct fb_ops da8xx_fb_ops = {
643         .owner = THIS_MODULE,
644         .fb_check_var = fb_check_var,
645         .fb_setcolreg = fb_setcolreg,
646         .fb_ioctl = fb_ioctl,
647         .fb_fillrect = cfb_fillrect,
648         .fb_copyarea = cfb_copyarea,
649         .fb_imageblit = cfb_imageblit,
650 };
651
652 static int __init fb_probe(struct platform_device *device)
653 {
654         struct da8xx_lcdc_platform_data *fb_pdata =
655                                                 device->dev.platform_data;
656         struct lcd_ctrl_config *lcd_cfg;
657         struct da8xx_panel *lcdc_info;
658         struct fb_info *da8xx_fb_info;
659         struct clk *fb_clk = NULL;
660         struct da8xx_fb_par *par;
661         resource_size_t len;
662         int ret, i;
663
664         if (fb_pdata == NULL) {
665                 dev_err(&device->dev, "Can not get platform data\n");
666                 return -ENOENT;
667         }
668
669         lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
670         if (!lcdc_regs) {
671                 dev_err(&device->dev,
672                         "Can not get memory resource for LCD controller\n");
673                 return -ENOENT;
674         }
675
676         len = resource_size(lcdc_regs);
677
678         lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);
679         if (!lcdc_regs)
680                 return -EBUSY;
681
682         da8xx_fb_reg_base = (resource_size_t)ioremap(lcdc_regs->start, len);
683         if (!da8xx_fb_reg_base) {
684                 ret = -EBUSY;
685                 goto err_request_mem;
686         }
687
688         fb_clk = clk_get(&device->dev, NULL);
689         if (IS_ERR(fb_clk)) {
690                 dev_err(&device->dev, "Can not get device clock\n");
691                 ret = -ENODEV;
692                 goto err_ioremap;
693         }
694         ret = clk_enable(fb_clk);
695         if (ret)
696                 goto err_clk_put;
697
698         for (i = 0, lcdc_info = known_lcd_panels;
699                 i < ARRAY_SIZE(known_lcd_panels);
700                 i++, lcdc_info++) {
701                 if (strcmp(fb_pdata->type, lcdc_info->name) == 0)
702                         break;
703         }
704
705         if (i == ARRAY_SIZE(known_lcd_panels)) {
706                 dev_err(&device->dev, "GLCD: No valid panel found\n");
707                 ret = -ENODEV;
708                 goto err_clk_disable;
709         } else
710                 dev_info(&device->dev, "GLCD: Found %s panel\n",
711                                         fb_pdata->type);
712
713         lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
714
715         da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
716                                         &device->dev);
717         if (!da8xx_fb_info) {
718                 dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
719                 ret = -ENOMEM;
720                 goto err_clk_disable;
721         }
722
723         par = da8xx_fb_info->par;
724
725         if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
726                 dev_err(&device->dev, "lcd_init failed\n");
727                 ret = -EFAULT;
728                 goto err_release_fb;
729         }
730
731         /* allocate frame buffer */
732         da8xx_fb_info->screen_base = dma_alloc_coherent(NULL,
733                                         par->databuf_sz + PAGE_SIZE,
734                                         (resource_size_t *)
735                                         &da8xx_fb_info->fix.smem_start,
736                                         GFP_KERNEL | GFP_DMA);
737
738         if (!da8xx_fb_info->screen_base) {
739                 dev_err(&device->dev,
740                         "GLCD: kmalloc for frame buffer failed\n");
741                 ret = -EINVAL;
742                 goto err_release_fb;
743         }
744
745         /* move palette base pointer by (PAGE_SIZE - palette_sz) bytes */
746         par->v_palette_base = da8xx_fb_info->screen_base +
747                                 (PAGE_SIZE - par->palette_sz);
748         par->p_palette_base = da8xx_fb_info->fix.smem_start +
749                                 (PAGE_SIZE - par->palette_sz);
750
751         /* the rest of the frame buffer is pixel data */
752         da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz;
753         da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz;
754         da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;
755
756         par->lcdc_clk = fb_clk;
757
758         par->irq = platform_get_irq(device, 0);
759         if (par->irq < 0) {
760                 ret = -ENOENT;
761                 goto err_release_fb_mem;
762         }
763
764         ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
765         if (ret)
766                 goto err_release_fb_mem;
767
768         /* Initialize par */
769         da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
770
771         da8xx_fb_var.xres = lcdc_info->width;
772         da8xx_fb_var.xres_virtual = lcdc_info->width;
773
774         da8xx_fb_var.yres = lcdc_info->height;
775         da8xx_fb_var.yres_virtual = lcdc_info->height;
776
777         da8xx_fb_var.grayscale =
778             lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0;
779         da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
780
781         da8xx_fb_var.hsync_len = lcdc_info->hsw;
782         da8xx_fb_var.vsync_len = lcdc_info->vsw;
783
784         /* Initialize fbinfo */
785         da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
786         da8xx_fb_info->fix = da8xx_fb_fix;
787         da8xx_fb_info->var = da8xx_fb_var;
788         da8xx_fb_info->fbops = &da8xx_fb_ops;
789         da8xx_fb_info->pseudo_palette = par->pseudo_palette;
790
791         ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
792         if (ret)
793                 goto err_free_irq;
794
795         /* First palette_sz byte of the frame buffer is the palette */
796         da8xx_fb_info->cmap.len = par->palette_sz;
797
798         /* Flush the buffer to the screen. */
799         lcd_blit(LOAD_DATA, par);
800
801         /* initialize var_screeninfo */
802         da8xx_fb_var.activate = FB_ACTIVATE_FORCE;
803         fb_set_var(da8xx_fb_info, &da8xx_fb_var);
804
805         dev_set_drvdata(&device->dev, da8xx_fb_info);
806         /* Register the Frame Buffer  */
807         if (register_framebuffer(da8xx_fb_info) < 0) {
808                 dev_err(&device->dev,
809                         "GLCD: Frame Buffer Registration Failed!\n");
810                 ret = -EINVAL;
811                 goto err_dealloc_cmap;
812         }
813
814         /* enable raster engine */
815         lcdc_write(lcdc_read(LCD_RASTER_CTRL_REG) |
816                         LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
817
818         return 0;
819
820 err_dealloc_cmap:
821         fb_dealloc_cmap(&da8xx_fb_info->cmap);
822
823 err_free_irq:
824         free_irq(par->irq, par);
825
826 err_release_fb_mem:
827         dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
828                                 da8xx_fb_info->screen_base,
829                                 da8xx_fb_info->fix.smem_start);
830
831 err_release_fb:
832         framebuffer_release(da8xx_fb_info);
833
834 err_clk_disable:
835         clk_disable(fb_clk);
836
837 err_clk_put:
838         clk_put(fb_clk);
839
840 err_ioremap:
841         iounmap((void __iomem *)da8xx_fb_reg_base);
842
843 err_request_mem:
844         release_mem_region(lcdc_regs->start, len);
845
846         return ret;
847 }
848
849 #ifdef CONFIG_PM
850 static int fb_suspend(struct platform_device *dev, pm_message_t state)
851 {
852          return -EBUSY;
853 }
854 static int fb_resume(struct platform_device *dev)
855 {
856          return -EBUSY;
857 }
858 #else
859 #define fb_suspend NULL
860 #define fb_resume NULL
861 #endif
862
863 static struct platform_driver da8xx_fb_driver = {
864         .probe = fb_probe,
865         .remove = fb_remove,
866         .suspend = fb_suspend,
867         .resume = fb_resume,
868         .driver = {
869                    .name = DRIVER_NAME,
870                    .owner = THIS_MODULE,
871                    },
872 };
873
874 static int __init da8xx_fb_init(void)
875 {
876         return platform_driver_register(&da8xx_fb_driver);
877 }
878
879 static void __exit da8xx_fb_cleanup(void)
880 {
881         platform_driver_unregister(&da8xx_fb_driver);
882 }
883
884 module_init(da8xx_fb_init);
885 module_exit(da8xx_fb_cleanup);
886
887 MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx");
888 MODULE_AUTHOR("Texas Instruments");
889 MODULE_LICENSE("GPL");