pandora: reserve CMA area for c64_tools
[pandora-kernel.git] / drivers / video / atmel_lcdfb.c
1 /*
2  *  Driver for AT91/AT32 LCD Controller
3  *
4  *  Copyright (C) 2007 Atmel Corporation
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file COPYING in the main directory of this archive for
8  * more details.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/platform_device.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/interrupt.h>
15 #include <linux/clk.h>
16 #include <linux/fb.h>
17 #include <linux/init.h>
18 #include <linux/delay.h>
19 #include <linux/backlight.h>
20 #include <linux/gfp.h>
21 #include <linux/module.h>
22
23 #include <mach/board.h>
24 #include <mach/cpu.h>
25 #include <asm/gpio.h>
26
27 #include <video/atmel_lcdc.h>
28
29 #define lcdc_readl(sinfo, reg)          __raw_readl((sinfo)->mmio+(reg))
30 #define lcdc_writel(sinfo, reg, val)    __raw_writel((val), (sinfo)->mmio+(reg))
31
32 /* configurable parameters */
33 #define ATMEL_LCDC_CVAL_DEFAULT         0xc8
34 #define ATMEL_LCDC_DMA_BURST_LEN        8       /* words */
35 #define ATMEL_LCDC_FIFO_SIZE            512     /* words */
36
37 #if defined(CONFIG_ARCH_AT91)
38 #define ATMEL_LCDFB_FBINFO_DEFAULT      (FBINFO_DEFAULT \
39                                          | FBINFO_PARTIAL_PAN_OK \
40                                          | FBINFO_HWACCEL_YPAN)
41
42 static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
43                                         struct fb_var_screeninfo *var,
44                                         struct fb_info *info)
45 {
46
47 }
48 #elif defined(CONFIG_AVR32)
49 #define ATMEL_LCDFB_FBINFO_DEFAULT      (FBINFO_DEFAULT \
50                                         | FBINFO_PARTIAL_PAN_OK \
51                                         | FBINFO_HWACCEL_XPAN \
52                                         | FBINFO_HWACCEL_YPAN)
53
54 static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
55                                      struct fb_var_screeninfo *var,
56                                      struct fb_info *info)
57 {
58         u32 dma2dcfg;
59         u32 pixeloff;
60
61         pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
62
63         dma2dcfg = (info->var.xres_virtual - info->var.xres)
64                  * info->var.bits_per_pixel / 8;
65         dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
66         lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
67
68         /* Update configuration */
69         lcdc_writel(sinfo, ATMEL_LCDC_DMACON,
70                     lcdc_readl(sinfo, ATMEL_LCDC_DMACON)
71                     | ATMEL_LCDC_DMAUPDT);
72 }
73 #endif
74
75 static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
76                 | ATMEL_LCDC_POL_POSITIVE
77                 | ATMEL_LCDC_ENA_PWMENABLE;
78
79 #ifdef CONFIG_BACKLIGHT_ATMEL_LCDC
80
81 /* some bl->props field just changed */
82 static int atmel_bl_update_status(struct backlight_device *bl)
83 {
84         struct atmel_lcdfb_info *sinfo = bl_get_data(bl);
85         int                     power = sinfo->bl_power;
86         int                     brightness = bl->props.brightness;
87
88         /* REVISIT there may be a meaningful difference between
89          * fb_blank and power ... there seem to be some cases
90          * this doesn't handle correctly.
91          */
92         if (bl->props.fb_blank != sinfo->bl_power)
93                 power = bl->props.fb_blank;
94         else if (bl->props.power != sinfo->bl_power)
95                 power = bl->props.power;
96
97         if (brightness < 0 && power == FB_BLANK_UNBLANK)
98                 brightness = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
99         else if (power != FB_BLANK_UNBLANK)
100                 brightness = 0;
101
102         lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness);
103         lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR,
104                         brightness ? contrast_ctr : 0);
105
106         bl->props.fb_blank = bl->props.power = sinfo->bl_power = power;
107
108         return 0;
109 }
110
111 static int atmel_bl_get_brightness(struct backlight_device *bl)
112 {
113         struct atmel_lcdfb_info *sinfo = bl_get_data(bl);
114
115         return lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
116 }
117
118 static const struct backlight_ops atmel_lcdc_bl_ops = {
119         .update_status = atmel_bl_update_status,
120         .get_brightness = atmel_bl_get_brightness,
121 };
122
123 static void init_backlight(struct atmel_lcdfb_info *sinfo)
124 {
125         struct backlight_properties props;
126         struct backlight_device *bl;
127
128         sinfo->bl_power = FB_BLANK_UNBLANK;
129
130         if (sinfo->backlight)
131                 return;
132
133         memset(&props, 0, sizeof(struct backlight_properties));
134         props.type = BACKLIGHT_RAW;
135         props.max_brightness = 0xff;
136         bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo,
137                                        &atmel_lcdc_bl_ops, &props);
138         if (IS_ERR(bl)) {
139                 dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n",
140                                 PTR_ERR(bl));
141                 return;
142         }
143         sinfo->backlight = bl;
144
145         bl->props.power = FB_BLANK_UNBLANK;
146         bl->props.fb_blank = FB_BLANK_UNBLANK;
147         bl->props.brightness = atmel_bl_get_brightness(bl);
148 }
149
150 static void exit_backlight(struct atmel_lcdfb_info *sinfo)
151 {
152         if (sinfo->backlight)
153                 backlight_device_unregister(sinfo->backlight);
154 }
155
156 #else
157
158 static void init_backlight(struct atmel_lcdfb_info *sinfo)
159 {
160         dev_warn(&sinfo->pdev->dev, "backlight control is not available\n");
161 }
162
163 static void exit_backlight(struct atmel_lcdfb_info *sinfo)
164 {
165 }
166
167 #endif
168
169 static void init_contrast(struct atmel_lcdfb_info *sinfo)
170 {
171         /* contrast pwm can be 'inverted' */
172         if (sinfo->lcdcon_pol_negative)
173                         contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
174
175         /* have some default contrast/backlight settings */
176         lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
177         lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
178
179         if (sinfo->lcdcon_is_backlight)
180                 init_backlight(sinfo);
181 }
182
183
184 static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
185         .type           = FB_TYPE_PACKED_PIXELS,
186         .visual         = FB_VISUAL_TRUECOLOR,
187         .xpanstep       = 0,
188         .ypanstep       = 1,
189         .ywrapstep      = 0,
190         .accel          = FB_ACCEL_NONE,
191 };
192
193 static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
194 {
195         unsigned long value;
196
197         if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10()
198                 || cpu_is_at32ap7000()))
199                 return xres;
200
201         value = xres;
202         if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) {
203                 /* STN display */
204                 if ((lcdcon2 & ATMEL_LCDC_DISTYPE) == ATMEL_LCDC_DISTYPE_STNCOLOR) {
205                         value *= 3;
206                 }
207                 if ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_4
208                    || ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_8
209                       && (lcdcon2 & ATMEL_LCDC_SCANMOD) == ATMEL_LCDC_SCANMOD_DUAL ))
210                         value = DIV_ROUND_UP(value, 4);
211                 else
212                         value = DIV_ROUND_UP(value, 8);
213         }
214
215         return value;
216 }
217
218 static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
219 {
220         /* Turn off the LCD controller and the DMA controller */
221         lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
222                         sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
223
224         /* Wait for the LCDC core to become idle */
225         while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
226                 msleep(10);
227
228         lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
229 }
230
231 static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)
232 {
233         atmel_lcdfb_stop_nowait(sinfo);
234
235         /* Wait for DMA engine to become idle... */
236         while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
237                 msleep(10);
238 }
239
240 static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
241 {
242         lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
243         lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
244                 (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
245                 | ATMEL_LCDC_PWR);
246 }
247
248 static void atmel_lcdfb_update_dma(struct fb_info *info,
249                                struct fb_var_screeninfo *var)
250 {
251         struct atmel_lcdfb_info *sinfo = info->par;
252         struct fb_fix_screeninfo *fix = &info->fix;
253         unsigned long dma_addr;
254
255         dma_addr = (fix->smem_start + var->yoffset * fix->line_length
256                     + var->xoffset * info->var.bits_per_pixel / 8);
257
258         dma_addr &= ~3UL;
259
260         /* Set framebuffer DMA base address and pixel offset */
261         lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
262
263         atmel_lcdfb_update_dma2d(sinfo, var, info);
264 }
265
266 static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
267 {
268         struct fb_info *info = sinfo->info;
269
270         dma_free_writecombine(info->device, info->fix.smem_len,
271                                 info->screen_base, info->fix.smem_start);
272 }
273
274 /**
275  *      atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory
276  *      @sinfo: the frame buffer to allocate memory for
277  *      
278  *      This function is called only from the atmel_lcdfb_probe()
279  *      so no locking by fb_info->mm_lock around smem_len setting is needed.
280  */
281 static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo)
282 {
283         struct fb_info *info = sinfo->info;
284         struct fb_var_screeninfo *var = &info->var;
285         unsigned int smem_len;
286
287         smem_len = (var->xres_virtual * var->yres_virtual
288                     * ((var->bits_per_pixel + 7) / 8));
289         info->fix.smem_len = max(smem_len, sinfo->smem_len);
290
291         info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len,
292                                         (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL);
293
294         if (!info->screen_base) {
295                 return -ENOMEM;
296         }
297
298         memset(info->screen_base, 0, info->fix.smem_len);
299
300         return 0;
301 }
302
303 static const struct fb_videomode *atmel_lcdfb_choose_mode(struct fb_var_screeninfo *var,
304                                                      struct fb_info *info)
305 {
306         struct fb_videomode varfbmode;
307         const struct fb_videomode *fbmode = NULL;
308
309         fb_var_to_videomode(&varfbmode, var);
310         fbmode = fb_find_nearest_mode(&varfbmode, &info->modelist);
311         if (fbmode)
312                 fb_videomode_to_var(var, fbmode);
313         return fbmode;
314 }
315
316
317 /**
318  *      atmel_lcdfb_check_var - Validates a var passed in.
319  *      @var: frame buffer variable screen structure
320  *      @info: frame buffer structure that represents a single frame buffer
321  *
322  *      Checks to see if the hardware supports the state requested by
323  *      var passed in. This function does not alter the hardware
324  *      state!!!  This means the data stored in struct fb_info and
325  *      struct atmel_lcdfb_info do not change. This includes the var
326  *      inside of struct fb_info.  Do NOT change these. This function
327  *      can be called on its own if we intent to only test a mode and
328  *      not actually set it. The stuff in modedb.c is a example of
329  *      this. If the var passed in is slightly off by what the
330  *      hardware can support then we alter the var PASSED in to what
331  *      we can do. If the hardware doesn't support mode change a
332  *      -EINVAL will be returned by the upper layers. You don't need
333  *      to implement this function then. If you hardware doesn't
334  *      support changing the resolution then this function is not
335  *      needed. In this case the driver would just provide a var that
336  *      represents the static state the screen is in.
337  *
338  *      Returns negative errno on error, or zero on success.
339  */
340 static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
341                              struct fb_info *info)
342 {
343         struct device *dev = info->device;
344         struct atmel_lcdfb_info *sinfo = info->par;
345         unsigned long clk_value_khz;
346
347         clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
348
349         dev_dbg(dev, "%s:\n", __func__);
350
351         if (!(var->pixclock && var->bits_per_pixel)) {
352                 /* choose a suitable mode if possible */
353                 if (!atmel_lcdfb_choose_mode(var, info)) {
354                         dev_err(dev, "needed value not specified\n");
355                         return -EINVAL;
356                 }
357         }
358
359         dev_dbg(dev, "  resolution: %ux%u\n", var->xres, var->yres);
360         dev_dbg(dev, "  pixclk:     %lu KHz\n", PICOS2KHZ(var->pixclock));
361         dev_dbg(dev, "  bpp:        %u\n", var->bits_per_pixel);
362         dev_dbg(dev, "  clk:        %lu KHz\n", clk_value_khz);
363
364         if (PICOS2KHZ(var->pixclock) > clk_value_khz) {
365                 dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(var->pixclock));
366                 return -EINVAL;
367         }
368
369         /* Do not allow to have real resoulution larger than virtual */
370         if (var->xres > var->xres_virtual)
371                 var->xres_virtual = var->xres;
372
373         if (var->yres > var->yres_virtual)
374                 var->yres_virtual = var->yres;
375
376         /* Force same alignment for each line */
377         var->xres = (var->xres + 3) & ~3UL;
378         var->xres_virtual = (var->xres_virtual + 3) & ~3UL;
379
380         var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0;
381         var->transp.msb_right = 0;
382         var->transp.offset = var->transp.length = 0;
383         var->xoffset = var->yoffset = 0;
384
385         if (info->fix.smem_len) {
386                 unsigned int smem_len = (var->xres_virtual * var->yres_virtual
387                                          * ((var->bits_per_pixel + 7) / 8));
388                 if (smem_len > info->fix.smem_len)
389                         return -EINVAL;
390         }
391
392         /* Saturate vertical and horizontal timings at maximum values */
393         var->vsync_len = min_t(u32, var->vsync_len,
394                         (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1);
395         var->upper_margin = min_t(u32, var->upper_margin,
396                         ATMEL_LCDC_VBP >> ATMEL_LCDC_VBP_OFFSET);
397         var->lower_margin = min_t(u32, var->lower_margin,
398                         ATMEL_LCDC_VFP);
399         var->right_margin = min_t(u32, var->right_margin,
400                         (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1);
401         var->hsync_len = min_t(u32, var->hsync_len,
402                         (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1);
403         var->left_margin = min_t(u32, var->left_margin,
404                         ATMEL_LCDC_HBP + 1);
405
406         /* Some parameters can't be zero */
407         var->vsync_len = max_t(u32, var->vsync_len, 1);
408         var->right_margin = max_t(u32, var->right_margin, 1);
409         var->hsync_len = max_t(u32, var->hsync_len, 1);
410         var->left_margin = max_t(u32, var->left_margin, 1);
411
412         switch (var->bits_per_pixel) {
413         case 1:
414         case 2:
415         case 4:
416         case 8:
417                 var->red.offset = var->green.offset = var->blue.offset = 0;
418                 var->red.length = var->green.length = var->blue.length
419                         = var->bits_per_pixel;
420                 break;
421         case 15:
422         case 16:
423                 if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
424                         /* RGB:565 mode */
425                         var->red.offset = 11;
426                         var->blue.offset = 0;
427                         var->green.length = 6;
428                 } else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) {
429                         var->red.offset = 10;
430                         var->blue.offset = 0;
431                         var->green.length = 5;
432                 } else {
433                         /* BGR:555 mode */
434                         var->red.offset = 0;
435                         var->blue.offset = 10;
436                         var->green.length = 5;
437                 }
438                 var->green.offset = 5;
439                 var->red.length = var->blue.length = 5;
440                 break;
441         case 32:
442                 var->transp.offset = 24;
443                 var->transp.length = 8;
444                 /* fall through */
445         case 24:
446                 if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
447                         /* RGB:888 mode */
448                         var->red.offset = 16;
449                         var->blue.offset = 0;
450                 } else {
451                         /* BGR:888 mode */
452                         var->red.offset = 0;
453                         var->blue.offset = 16;
454                 }
455                 var->green.offset = 8;
456                 var->red.length = var->green.length = var->blue.length = 8;
457                 break;
458         default:
459                 dev_err(dev, "color depth %d not supported\n",
460                                         var->bits_per_pixel);
461                 return -EINVAL;
462         }
463
464         return 0;
465 }
466
467 /*
468  * LCD reset sequence
469  */
470 static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo)
471 {
472         might_sleep();
473
474         atmel_lcdfb_stop(sinfo);
475         atmel_lcdfb_start(sinfo);
476 }
477
478 /**
479  *      atmel_lcdfb_set_par - Alters the hardware state.
480  *      @info: frame buffer structure that represents a single frame buffer
481  *
482  *      Using the fb_var_screeninfo in fb_info we set the resolution
483  *      of the this particular framebuffer. This function alters the
484  *      par AND the fb_fix_screeninfo stored in fb_info. It doesn't
485  *      not alter var in fb_info since we are using that data. This
486  *      means we depend on the data in var inside fb_info to be
487  *      supported by the hardware.  atmel_lcdfb_check_var is always called
488  *      before atmel_lcdfb_set_par to ensure this.  Again if you can't
489  *      change the resolution you don't need this function.
490  *
491  */
492 static int atmel_lcdfb_set_par(struct fb_info *info)
493 {
494         struct atmel_lcdfb_info *sinfo = info->par;
495         unsigned long hozval_linesz;
496         unsigned long value;
497         unsigned long clk_value_khz;
498         unsigned long bits_per_line;
499         unsigned long pix_factor = 2;
500
501         might_sleep();
502
503         dev_dbg(info->device, "%s:\n", __func__);
504         dev_dbg(info->device, "  * resolution: %ux%u (%ux%u virtual)\n",
505                  info->var.xres, info->var.yres,
506                  info->var.xres_virtual, info->var.yres_virtual);
507
508         atmel_lcdfb_stop_nowait(sinfo);
509
510         if (info->var.bits_per_pixel == 1)
511                 info->fix.visual = FB_VISUAL_MONO01;
512         else if (info->var.bits_per_pixel <= 8)
513                 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
514         else
515                 info->fix.visual = FB_VISUAL_TRUECOLOR;
516
517         bits_per_line = info->var.xres_virtual * info->var.bits_per_pixel;
518         info->fix.line_length = DIV_ROUND_UP(bits_per_line, 8);
519
520         /* Re-initialize the DMA engine... */
521         dev_dbg(info->device, "  * update DMA engine\n");
522         atmel_lcdfb_update_dma(info, &info->var);
523
524         /* ...set frame size and burst length = 8 words (?) */
525         value = (info->var.yres * info->var.xres * info->var.bits_per_pixel) / 32;
526         value |= ((ATMEL_LCDC_DMA_BURST_LEN - 1) << ATMEL_LCDC_BLENGTH_OFFSET);
527         lcdc_writel(sinfo, ATMEL_LCDC_DMAFRMCFG, value);
528
529         /* Now, the LCDC core... */
530
531         /* Set pixel clock */
532         if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es())
533                 pix_factor = 1;
534
535         clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
536
537         value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));
538
539         if (value < pix_factor) {
540                 dev_notice(info->device, "Bypassing pixel clock divider\n");
541                 lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
542         } else {
543                 value = (value / pix_factor) - 1;
544                 dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n",
545                                 value);
546                 lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1,
547                                 value << ATMEL_LCDC_CLKVAL_OFFSET);
548                 info->var.pixclock =
549                         KHZ2PICOS(clk_value_khz / (pix_factor * (value + 1)));
550                 dev_dbg(info->device, "  updated pixclk:     %lu KHz\n",
551                                         PICOS2KHZ(info->var.pixclock));
552         }
553
554
555         /* Initialize control register 2 */
556         value = sinfo->default_lcdcon2;
557
558         if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
559                 value |= ATMEL_LCDC_INVLINE_INVERTED;
560         if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
561                 value |= ATMEL_LCDC_INVFRAME_INVERTED;
562
563         switch (info->var.bits_per_pixel) {
564                 case 1: value |= ATMEL_LCDC_PIXELSIZE_1; break;
565                 case 2: value |= ATMEL_LCDC_PIXELSIZE_2; break;
566                 case 4: value |= ATMEL_LCDC_PIXELSIZE_4; break;
567                 case 8: value |= ATMEL_LCDC_PIXELSIZE_8; break;
568                 case 15: /* fall through */
569                 case 16: value |= ATMEL_LCDC_PIXELSIZE_16; break;
570                 case 24: value |= ATMEL_LCDC_PIXELSIZE_24; break;
571                 case 32: value |= ATMEL_LCDC_PIXELSIZE_32; break;
572                 default: BUG(); break;
573         }
574         dev_dbg(info->device, "  * LCDCON2 = %08lx\n", value);
575         lcdc_writel(sinfo, ATMEL_LCDC_LCDCON2, value);
576
577         /* Vertical timing */
578         value = (info->var.vsync_len - 1) << ATMEL_LCDC_VPW_OFFSET;
579         value |= info->var.upper_margin << ATMEL_LCDC_VBP_OFFSET;
580         value |= info->var.lower_margin;
581         dev_dbg(info->device, "  * LCDTIM1 = %08lx\n", value);
582         lcdc_writel(sinfo, ATMEL_LCDC_TIM1, value);
583
584         /* Horizontal timing */
585         value = (info->var.right_margin - 1) << ATMEL_LCDC_HFP_OFFSET;
586         value |= (info->var.hsync_len - 1) << ATMEL_LCDC_HPW_OFFSET;
587         value |= (info->var.left_margin - 1);
588         dev_dbg(info->device, "  * LCDTIM2 = %08lx\n", value);
589         lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value);
590
591         /* Horizontal value (aka line size) */
592         hozval_linesz = compute_hozval(info->var.xres,
593                                         lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2));
594
595         /* Display size */
596         value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET;
597         value |= info->var.yres - 1;
598         dev_dbg(info->device, "  * LCDFRMCFG = %08lx\n", value);
599         lcdc_writel(sinfo, ATMEL_LCDC_LCDFRMCFG, value);
600
601         /* FIFO Threshold: Use formula from data sheet */
602         value = ATMEL_LCDC_FIFO_SIZE - (2 * ATMEL_LCDC_DMA_BURST_LEN + 3);
603         lcdc_writel(sinfo, ATMEL_LCDC_FIFO, value);
604
605         /* Toggle LCD_MODE every frame */
606         lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0);
607
608         /* Disable all interrupts */
609         lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
610         /* Enable FIFO & DMA errors */
611         lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
612
613         /* ...wait for DMA engine to become idle... */
614         while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
615                 msleep(10);
616
617         atmel_lcdfb_start(sinfo);
618
619         dev_dbg(info->device, "  * DONE\n");
620
621         return 0;
622 }
623
624 static inline unsigned int chan_to_field(unsigned int chan, const struct fb_bitfield *bf)
625 {
626         chan &= 0xffff;
627         chan >>= 16 - bf->length;
628         return chan << bf->offset;
629 }
630
631 /**
632  *      atmel_lcdfb_setcolreg - Optional function. Sets a color register.
633  *      @regno: Which register in the CLUT we are programming
634  *      @red: The red value which can be up to 16 bits wide
635  *      @green: The green value which can be up to 16 bits wide
636  *      @blue:  The blue value which can be up to 16 bits wide.
637  *      @transp: If supported the alpha value which can be up to 16 bits wide.
638  *      @info: frame buffer info structure
639  *
640  *      Set a single color register. The values supplied have a 16 bit
641  *      magnitude which needs to be scaled in this function for the hardware.
642  *      Things to take into consideration are how many color registers, if
643  *      any, are supported with the current color visual. With truecolor mode
644  *      no color palettes are supported. Here a pseudo palette is created
645  *      which we store the value in pseudo_palette in struct fb_info. For
646  *      pseudocolor mode we have a limited color palette. To deal with this
647  *      we can program what color is displayed for a particular pixel value.
648  *      DirectColor is similar in that we can program each color field. If
649  *      we have a static colormap we don't need to implement this function.
650  *
651  *      Returns negative errno on error, or zero on success. In an
652  *      ideal world, this would have been the case, but as it turns
653  *      out, the other drivers return 1 on failure, so that's what
654  *      we're going to do.
655  */
656 static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
657                              unsigned int green, unsigned int blue,
658                              unsigned int transp, struct fb_info *info)
659 {
660         struct atmel_lcdfb_info *sinfo = info->par;
661         unsigned int val;
662         u32 *pal;
663         int ret = 1;
664
665         if (info->var.grayscale)
666                 red = green = blue = (19595 * red + 38470 * green
667                                       + 7471 * blue) >> 16;
668
669         switch (info->fix.visual) {
670         case FB_VISUAL_TRUECOLOR:
671                 if (regno < 16) {
672                         pal = info->pseudo_palette;
673
674                         val  = chan_to_field(red, &info->var.red);
675                         val |= chan_to_field(green, &info->var.green);
676                         val |= chan_to_field(blue, &info->var.blue);
677
678                         pal[regno] = val;
679                         ret = 0;
680                 }
681                 break;
682
683         case FB_VISUAL_PSEUDOCOLOR:
684                 if (regno < 256) {
685                         val  = ((red   >> 11) & 0x001f);
686                         val |= ((green >>  6) & 0x03e0);
687                         val |= ((blue  >>  1) & 0x7c00);
688
689                         /*
690                          * TODO: intensity bit. Maybe something like
691                          *   ~(red[10] ^ green[10] ^ blue[10]) & 1
692                          */
693
694                         lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
695                         ret = 0;
696                 }
697                 break;
698
699         case FB_VISUAL_MONO01:
700                 if (regno < 2) {
701                         val = (regno == 0) ? 0x00 : 0x1F;
702                         lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
703                         ret = 0;
704                 }
705                 break;
706
707         }
708
709         return ret;
710 }
711
712 static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
713                                struct fb_info *info)
714 {
715         dev_dbg(info->device, "%s\n", __func__);
716
717         atmel_lcdfb_update_dma(info, var);
718
719         return 0;
720 }
721
722 static int atmel_lcdfb_blank(int blank_mode, struct fb_info *info)
723 {
724         struct atmel_lcdfb_info *sinfo = info->par;
725
726         switch (blank_mode) {
727         case FB_BLANK_UNBLANK:
728         case FB_BLANK_NORMAL:
729                 atmel_lcdfb_start(sinfo);
730                 break;
731         case FB_BLANK_VSYNC_SUSPEND:
732         case FB_BLANK_HSYNC_SUSPEND:
733                 break;
734         case FB_BLANK_POWERDOWN:
735                 atmel_lcdfb_stop(sinfo);
736                 break;
737         default:
738                 return -EINVAL;
739         }
740
741         /* let fbcon do a soft blank for us */
742         return ((blank_mode == FB_BLANK_NORMAL) ? 1 : 0);
743 }
744
745 static struct fb_ops atmel_lcdfb_ops = {
746         .owner          = THIS_MODULE,
747         .fb_check_var   = atmel_lcdfb_check_var,
748         .fb_set_par     = atmel_lcdfb_set_par,
749         .fb_setcolreg   = atmel_lcdfb_setcolreg,
750         .fb_blank       = atmel_lcdfb_blank,
751         .fb_pan_display = atmel_lcdfb_pan_display,
752         .fb_fillrect    = cfb_fillrect,
753         .fb_copyarea    = cfb_copyarea,
754         .fb_imageblit   = cfb_imageblit,
755 };
756
757 static irqreturn_t atmel_lcdfb_interrupt(int irq, void *dev_id)
758 {
759         struct fb_info *info = dev_id;
760         struct atmel_lcdfb_info *sinfo = info->par;
761         u32 status;
762
763         status = lcdc_readl(sinfo, ATMEL_LCDC_ISR);
764         if (status & ATMEL_LCDC_UFLWI) {
765                 dev_warn(info->device, "FIFO underflow %#x\n", status);
766                 /* reset DMA and FIFO to avoid screen shifting */
767                 schedule_work(&sinfo->task);
768         }
769         lcdc_writel(sinfo, ATMEL_LCDC_ICR, status);
770         return IRQ_HANDLED;
771 }
772
773 /*
774  * LCD controller task (to reset the LCD)
775  */
776 static void atmel_lcdfb_task(struct work_struct *work)
777 {
778         struct atmel_lcdfb_info *sinfo =
779                 container_of(work, struct atmel_lcdfb_info, task);
780
781         atmel_lcdfb_reset(sinfo);
782 }
783
784 static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo)
785 {
786         struct fb_info *info = sinfo->info;
787         int ret = 0;
788
789         info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
790
791         dev_info(info->device,
792                "%luKiB frame buffer at %08lx (mapped at %p)\n",
793                (unsigned long)info->fix.smem_len / 1024,
794                (unsigned long)info->fix.smem_start,
795                info->screen_base);
796
797         /* Allocate colormap */
798         ret = fb_alloc_cmap(&info->cmap, 256, 0);
799         if (ret < 0)
800                 dev_err(info->device, "Alloc color map failed\n");
801
802         return ret;
803 }
804
805 static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo)
806 {
807         if (sinfo->bus_clk)
808                 clk_enable(sinfo->bus_clk);
809         clk_enable(sinfo->lcdc_clk);
810 }
811
812 static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
813 {
814         if (sinfo->bus_clk)
815                 clk_disable(sinfo->bus_clk);
816         clk_disable(sinfo->lcdc_clk);
817 }
818
819
820 static int __init atmel_lcdfb_probe(struct platform_device *pdev)
821 {
822         struct device *dev = &pdev->dev;
823         struct fb_info *info;
824         struct atmel_lcdfb_info *sinfo;
825         struct atmel_lcdfb_info *pdata_sinfo;
826         struct fb_videomode fbmode;
827         struct resource *regs = NULL;
828         struct resource *map = NULL;
829         int ret;
830
831         dev_dbg(dev, "%s BEGIN\n", __func__);
832
833         ret = -ENOMEM;
834         info = framebuffer_alloc(sizeof(struct atmel_lcdfb_info), dev);
835         if (!info) {
836                 dev_err(dev, "cannot allocate memory\n");
837                 goto out;
838         }
839
840         sinfo = info->par;
841
842         if (dev->platform_data) {
843                 pdata_sinfo = (struct atmel_lcdfb_info *)dev->platform_data;
844                 sinfo->default_bpp = pdata_sinfo->default_bpp;
845                 sinfo->default_dmacon = pdata_sinfo->default_dmacon;
846                 sinfo->default_lcdcon2 = pdata_sinfo->default_lcdcon2;
847                 sinfo->default_monspecs = pdata_sinfo->default_monspecs;
848                 sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control;
849                 sinfo->guard_time = pdata_sinfo->guard_time;
850                 sinfo->smem_len = pdata_sinfo->smem_len;
851                 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
852                 sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative;
853                 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
854         } else {
855                 dev_err(dev, "cannot get default configuration\n");
856                 goto free_info;
857         }
858         sinfo->info = info;
859         sinfo->pdev = pdev;
860
861         strcpy(info->fix.id, sinfo->pdev->name);
862         info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;
863         info->pseudo_palette = sinfo->pseudo_palette;
864         info->fbops = &atmel_lcdfb_ops;
865
866         memcpy(&info->monspecs, sinfo->default_monspecs, sizeof(info->monspecs));
867         info->fix = atmel_lcdfb_fix;
868
869         /* Enable LCDC Clocks */
870         if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()
871          || cpu_is_at32ap7000()) {
872                 sinfo->bus_clk = clk_get(dev, "hck1");
873                 if (IS_ERR(sinfo->bus_clk)) {
874                         ret = PTR_ERR(sinfo->bus_clk);
875                         goto free_info;
876                 }
877         }
878         sinfo->lcdc_clk = clk_get(dev, "lcdc_clk");
879         if (IS_ERR(sinfo->lcdc_clk)) {
880                 ret = PTR_ERR(sinfo->lcdc_clk);
881                 goto put_bus_clk;
882         }
883         atmel_lcdfb_start_clock(sinfo);
884
885         ret = fb_find_mode(&info->var, info, NULL, info->monspecs.modedb,
886                         info->monspecs.modedb_len, info->monspecs.modedb,
887                         sinfo->default_bpp);
888         if (!ret) {
889                 dev_err(dev, "no suitable video mode found\n");
890                 goto stop_clk;
891         }
892
893
894         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
895         if (!regs) {
896                 dev_err(dev, "resources unusable\n");
897                 ret = -ENXIO;
898                 goto stop_clk;
899         }
900
901         sinfo->irq_base = platform_get_irq(pdev, 0);
902         if (sinfo->irq_base < 0) {
903                 dev_err(dev, "unable to get irq\n");
904                 ret = sinfo->irq_base;
905                 goto stop_clk;
906         }
907
908         /* Initialize video memory */
909         map = platform_get_resource(pdev, IORESOURCE_MEM, 1);
910         if (map) {
911                 /* use a pre-allocated memory buffer */
912                 info->fix.smem_start = map->start;
913                 info->fix.smem_len = resource_size(map);
914                 if (!request_mem_region(info->fix.smem_start,
915                                         info->fix.smem_len, pdev->name)) {
916                         ret = -EBUSY;
917                         goto stop_clk;
918                 }
919
920                 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
921                 if (!info->screen_base)
922                         goto release_intmem;
923
924                 /*
925                  * Don't clear the framebuffer -- someone may have set
926                  * up a splash image.
927                  */
928         } else {
929                 /* alocate memory buffer */
930                 ret = atmel_lcdfb_alloc_video_memory(sinfo);
931                 if (ret < 0) {
932                         dev_err(dev, "cannot allocate framebuffer: %d\n", ret);
933                         goto stop_clk;
934                 }
935         }
936
937         /* LCDC registers */
938         info->fix.mmio_start = regs->start;
939         info->fix.mmio_len = resource_size(regs);
940
941         if (!request_mem_region(info->fix.mmio_start,
942                                 info->fix.mmio_len, pdev->name)) {
943                 ret = -EBUSY;
944                 goto free_fb;
945         }
946
947         sinfo->mmio = ioremap(info->fix.mmio_start, info->fix.mmio_len);
948         if (!sinfo->mmio) {
949                 dev_err(dev, "cannot map LCDC registers\n");
950                 goto release_mem;
951         }
952
953         /* Initialize PWM for contrast or backlight ("off") */
954         init_contrast(sinfo);
955
956         /* interrupt */
957         ret = request_irq(sinfo->irq_base, atmel_lcdfb_interrupt, 0, pdev->name, info);
958         if (ret) {
959                 dev_err(dev, "request_irq failed: %d\n", ret);
960                 goto unmap_mmio;
961         }
962
963         /* Some operations on the LCDC might sleep and
964          * require a preemptible task context */
965         INIT_WORK(&sinfo->task, atmel_lcdfb_task);
966
967         ret = atmel_lcdfb_init_fbinfo(sinfo);
968         if (ret < 0) {
969                 dev_err(dev, "init fbinfo failed: %d\n", ret);
970                 goto unregister_irqs;
971         }
972
973         /*
974          * This makes sure that our colour bitfield
975          * descriptors are correctly initialised.
976          */
977         atmel_lcdfb_check_var(&info->var, info);
978
979         ret = fb_set_var(info, &info->var);
980         if (ret) {
981                 dev_warn(dev, "unable to set display parameters\n");
982                 goto free_cmap;
983         }
984
985         dev_set_drvdata(dev, info);
986
987         /*
988          * Tell the world that we're ready to go
989          */
990         ret = register_framebuffer(info);
991         if (ret < 0) {
992                 dev_err(dev, "failed to register framebuffer device: %d\n", ret);
993                 goto reset_drvdata;
994         }
995
996         /* add selected videomode to modelist */
997         fb_var_to_videomode(&fbmode, &info->var);
998         fb_add_videomode(&fbmode, &info->modelist);
999
1000         /* Power up the LCDC screen */
1001         if (sinfo->atmel_lcdfb_power_control)
1002                 sinfo->atmel_lcdfb_power_control(1);
1003
1004         dev_info(dev, "fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %d\n",
1005                        info->node, info->fix.mmio_start, sinfo->mmio, sinfo->irq_base);
1006
1007         return 0;
1008
1009 reset_drvdata:
1010         dev_set_drvdata(dev, NULL);
1011 free_cmap:
1012         fb_dealloc_cmap(&info->cmap);
1013 unregister_irqs:
1014         cancel_work_sync(&sinfo->task);
1015         free_irq(sinfo->irq_base, info);
1016 unmap_mmio:
1017         exit_backlight(sinfo);
1018         iounmap(sinfo->mmio);
1019 release_mem:
1020         release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1021 free_fb:
1022         if (map)
1023                 iounmap(info->screen_base);
1024         else
1025                 atmel_lcdfb_free_video_memory(sinfo);
1026
1027 release_intmem:
1028         if (map)
1029                 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1030 stop_clk:
1031         atmel_lcdfb_stop_clock(sinfo);
1032         clk_put(sinfo->lcdc_clk);
1033 put_bus_clk:
1034         if (sinfo->bus_clk)
1035                 clk_put(sinfo->bus_clk);
1036 free_info:
1037         framebuffer_release(info);
1038 out:
1039         dev_dbg(dev, "%s FAILED\n", __func__);
1040         return ret;
1041 }
1042
1043 static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
1044 {
1045         struct device *dev = &pdev->dev;
1046         struct fb_info *info = dev_get_drvdata(dev);
1047         struct atmel_lcdfb_info *sinfo;
1048
1049         if (!info || !info->par)
1050                 return 0;
1051         sinfo = info->par;
1052
1053         cancel_work_sync(&sinfo->task);
1054         exit_backlight(sinfo);
1055         if (sinfo->atmel_lcdfb_power_control)
1056                 sinfo->atmel_lcdfb_power_control(0);
1057         unregister_framebuffer(info);
1058         atmel_lcdfb_stop_clock(sinfo);
1059         clk_put(sinfo->lcdc_clk);
1060         if (sinfo->bus_clk)
1061                 clk_put(sinfo->bus_clk);
1062         fb_dealloc_cmap(&info->cmap);
1063         free_irq(sinfo->irq_base, info);
1064         iounmap(sinfo->mmio);
1065         release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1066         if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) {
1067                 iounmap(info->screen_base);
1068                 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1069         } else {
1070                 atmel_lcdfb_free_video_memory(sinfo);
1071         }
1072
1073         dev_set_drvdata(dev, NULL);
1074         framebuffer_release(info);
1075
1076         return 0;
1077 }
1078
1079 #ifdef CONFIG_PM
1080
1081 static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
1082 {
1083         struct fb_info *info = platform_get_drvdata(pdev);
1084         struct atmel_lcdfb_info *sinfo = info->par;
1085
1086         /*
1087          * We don't want to handle interrupts while the clock is
1088          * stopped. It may take forever.
1089          */
1090         lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
1091
1092         sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR);
1093         lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
1094         if (sinfo->atmel_lcdfb_power_control)
1095                 sinfo->atmel_lcdfb_power_control(0);
1096
1097         atmel_lcdfb_stop(sinfo);
1098         atmel_lcdfb_stop_clock(sinfo);
1099
1100         return 0;
1101 }
1102
1103 static int atmel_lcdfb_resume(struct platform_device *pdev)
1104 {
1105         struct fb_info *info = platform_get_drvdata(pdev);
1106         struct atmel_lcdfb_info *sinfo = info->par;
1107
1108         atmel_lcdfb_start_clock(sinfo);
1109         atmel_lcdfb_start(sinfo);
1110         if (sinfo->atmel_lcdfb_power_control)
1111                 sinfo->atmel_lcdfb_power_control(1);
1112         lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
1113
1114         /* Enable FIFO & DMA errors */
1115         lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI
1116                         | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
1117
1118         return 0;
1119 }
1120
1121 #else
1122 #define atmel_lcdfb_suspend     NULL
1123 #define atmel_lcdfb_resume      NULL
1124 #endif
1125
1126 static struct platform_driver atmel_lcdfb_driver = {
1127         .remove         = __exit_p(atmel_lcdfb_remove),
1128         .suspend        = atmel_lcdfb_suspend,
1129         .resume         = atmel_lcdfb_resume,
1130
1131         .driver         = {
1132                 .name   = "atmel_lcdfb",
1133                 .owner  = THIS_MODULE,
1134         },
1135 };
1136
1137 static int __init atmel_lcdfb_init(void)
1138 {
1139         return platform_driver_probe(&atmel_lcdfb_driver, atmel_lcdfb_probe);
1140 }
1141
1142 static void __exit atmel_lcdfb_exit(void)
1143 {
1144         platform_driver_unregister(&atmel_lcdfb_driver);
1145 }
1146
1147 module_init(atmel_lcdfb_init);
1148 module_exit(atmel_lcdfb_exit);
1149
1150 MODULE_DESCRIPTION("AT91/AT32 LCD Controller framebuffer driver");
1151 MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@atmel.com>");
1152 MODULE_LICENSE("GPL");