Root/drivers/video/jz4740_slcd_fb.c

Source at commit 939c3e51dd77d23649fe511311f33d3cc698ced8 created 10 years 8 days ago.
By Maarten ter Huurne, MIPS: JZ4740: Work around fbcon logo crash with SLCD
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * Copyright (C) 2010, Maarten ter Huurne <maarten@treewalker.org>
4 * JZ4720/JZ4740 SoC LCD framebuffer driver
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, write to the Free Software Foundation, Inc.,
13 * 675 Mass Ave, Cambridge, MA 02139, USA.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/mutex.h>
20#include <linux/platform_device.h>
21
22#include <linux/clk.h>
23#include <linux/delay.h>
24
25#include <linux/console.h>
26#include <linux/fb.h>
27
28#include <linux/interrupt.h>
29#include <linux/dma-mapping.h>
30
31#include <asm/mach-jz4740/dma.h>
32#include <asm/mach-jz4740/gpio.h>
33#include <asm/mach-jz4740/jz4740_fb.h>
34
35#include "jz4740_lcd.h"
36#include "jz4740_slcd.h"
37
38#define FB_A320TV_OFF 0
39#define FB_A320TV_NTSC 1
40#define FB_A320TV_PAL50 2
41#define FB_A320TV_PAL60 3
42#define FB_A320TV_PAL_M 4
43#define FB_A320TV_LAST 4
44
45static const char *jzfb_tv_out_norm[] = {
46    "off", "ntsc", "pal", "pal-60", "pal-m",
47};
48
49static struct fb_fix_screeninfo jzfb_fix = {
50    .id = "JZ4740 SLCD FB",
51    .type = FB_TYPE_PACKED_PIXELS,
52    .visual = FB_VISUAL_TRUECOLOR,
53    .xpanstep = 0,
54    .ypanstep = 1,
55    .ywrapstep = 0,
56    .accel = FB_ACCEL_NONE,
57};
58
59const static struct jz_gpio_bulk_request jz_slcd_ctrl_pins[] = {
60    JZ_GPIO_BULK_PIN(LCD_PCLK),
61    JZ_GPIO_BULK_PIN(SLCD_RS),
62    JZ_GPIO_BULK_PIN(SLCD_CS),
63};
64
65const static struct jz_gpio_bulk_request jz_slcd_data_pins[] = {
66    JZ_GPIO_BULK_PIN(LCD_DATA0),
67    JZ_GPIO_BULK_PIN(LCD_DATA1),
68    JZ_GPIO_BULK_PIN(LCD_DATA2),
69    JZ_GPIO_BULK_PIN(LCD_DATA3),
70    JZ_GPIO_BULK_PIN(LCD_DATA4),
71    JZ_GPIO_BULK_PIN(LCD_DATA5),
72    JZ_GPIO_BULK_PIN(LCD_DATA6),
73    JZ_GPIO_BULK_PIN(LCD_DATA7),
74    JZ_GPIO_BULK_PIN(LCD_DATA8),
75    JZ_GPIO_BULK_PIN(LCD_DATA9),
76    JZ_GPIO_BULK_PIN(LCD_DATA10),
77    JZ_GPIO_BULK_PIN(LCD_DATA11),
78    JZ_GPIO_BULK_PIN(LCD_DATA12),
79    JZ_GPIO_BULK_PIN(LCD_DATA13),
80    JZ_GPIO_BULK_PIN(LCD_DATA14),
81    JZ_GPIO_BULK_PIN(LCD_DATA15),
82    JZ_GPIO_BULK_PIN(LCD_DATA16),
83    JZ_GPIO_BULK_PIN(LCD_DATA17),
84};
85
86static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb)
87{
88    return ARRAY_SIZE(jz_slcd_ctrl_pins);
89}
90
91static unsigned int jzfb_num_data_pins(struct jzfb *jzfb)
92{
93    switch (jzfb->pdata->lcd_type) {
94    case JZ_LCD_TYPE_SMART_PARALLEL_8_BIT:
95        return 8;
96    case JZ_LCD_TYPE_SMART_PARALLEL_16_BIT:
97        return 16;
98    case JZ_LCD_TYPE_SMART_PARALLEL_18_BIT:
99        return 18;
100    default:
101        return 0;
102    }
103}
104
105static void jzfb_free_gpio_pins(struct jzfb *jzfb)
106{
107    jz_gpio_bulk_free(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
108    if (jzfb->pdata->lcd_type & (1 << 6)) {
109        /* serial */
110        jz_gpio_bulk_free(&jz_slcd_data_pins[15], 1);
111    } else {
112        /* parallel */
113        jz_gpio_bulk_free(jz_slcd_data_pins,
114                  jzfb_num_data_pins(jzfb));
115    }
116}
117
118static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green,
119            unsigned blue, unsigned transp, struct fb_info *fb)
120{
121    if (regno >= 16)
122        return -EINVAL;
123
124    red = (red * ((1 << fb->var.red.length ) - 1)) / ((1 << 16) - 1);
125    green = (green * ((1 << fb->var.green.length) - 1)) / ((1 << 16) - 1);
126    blue = (blue * ((1 << fb->var.blue.length ) - 1)) / ((1 << 16) - 1);
127
128    ((uint32_t *)fb->pseudo_palette)[regno] =
129        (red << fb->var.red.offset ) |
130        (green << fb->var.green.offset) |
131        (blue << fb->var.blue.offset );
132
133    return 0;
134}
135
136static int jzfb_get_controller_bpp(struct jzfb *jzfb)
137{
138    switch (jzfb->pdata->bpp) {
139    case 18:
140    case 24:
141        return 32;
142    case 15:
143        return 16;
144    default:
145        return jzfb->pdata->bpp;
146    }
147}
148
149static struct fb_videomode *jzfb_get_mode(struct jzfb *jzfb, struct fb_var_screeninfo *var)
150{
151    size_t i;
152    struct fb_videomode *mode = jzfb->pdata->modes;
153
154    for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
155        if (mode->xres == var->xres && mode->yres == var->yres)
156            return mode;
157    }
158
159    return NULL;
160}
161
162static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
163{
164    struct jzfb *jzfb = fb->par;
165    struct fb_videomode *mode;
166
167    if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
168        var->bits_per_pixel != jzfb->pdata->bpp)
169        return -EINVAL;
170
171    mode = jzfb_get_mode(jzfb, var);
172    if (mode == NULL)
173        return -EINVAL;
174
175    fb_videomode_to_var(var, mode);
176
177    /* Reserve space for double buffering. */
178    var->yres_virtual = var->yres * 2;
179
180    switch (jzfb->pdata->bpp) {
181    case 8:
182        break;
183    case 15:
184        var->red.offset = 10;
185        var->red.length = 5;
186        var->green.offset = 5;
187        var->green.length = 5;
188        var->blue.offset = 0;
189        var->blue.length = 5;
190        break;
191    case 16:
192        var->red.offset = 11;
193        var->red.length = 5;
194        var->green.offset = 5;
195        var->green.length = 6;
196        var->blue.offset = 0;
197        var->blue.length = 5;
198        break;
199    case 18:
200        var->red.offset = 16;
201        var->red.length = 6;
202        var->green.offset = 8;
203        var->green.length = 6;
204        var->blue.offset = 0;
205        var->blue.length = 6;
206        var->bits_per_pixel = 32;
207        break;
208    case 32:
209    case 24:
210        var->transp.offset = 24;
211        var->transp.length = 8;
212        var->red.offset = 16;
213        var->red.length = 8;
214        var->green.offset = 8;
215        var->green.length = 8;
216        var->blue.offset = 0;
217        var->blue.length = 8;
218        var->bits_per_pixel = 32;
219        break;
220    default:
221        break;
222    }
223
224    return 0;
225}
226
227static void jzfb_disable_dma(struct jzfb *jzfb)
228{
229    jz4740_dma_disable(jzfb->dma);
230    while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
231    writeb(readb(jzfb->base + JZ_REG_SLCD_CTRL) & ~SLCD_CTRL_DMA_EN,
232        jzfb->base + JZ_REG_SLCD_CTRL);
233}
234
235static struct jz4740_dma_config jzfb_slcd_dma_config = {
236    .src_width = JZ4740_DMA_WIDTH_32BIT,
237    .dst_width = JZ4740_DMA_WIDTH_16BIT,
238    .transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE,
239    .request_type = JZ4740_DMA_TYPE_SLCD,
240    .flags = JZ4740_DMA_SRC_AUTOINC,
241    .mode = JZ4740_DMA_MODE_BLOCK,
242};
243
244static void jzfb_upload_frame_dma(struct jzfb *jzfb)
245{
246    struct fb_info *fb = jzfb->fb;
247    struct fb_videomode *mode = fb->mode;
248    __u32 offset = fb->fix.line_length * fb->var.yoffset;
249    __u32 size = fb->fix.line_length * mode->yres;
250
251    /* Ensure that the data to be uploaded is in memory. */
252    dma_cache_sync(fb->device, jzfb->vidmem + offset, size,
253               DMA_TO_DEVICE);
254
255    jz4740_dma_set_src_addr(jzfb->dma, jzfb->vidmem_phys + offset);
256    jz4740_dma_set_dst_addr(jzfb->dma,
257                CPHYSADDR(jzfb->base + JZ_REG_SLCD_FIFO));
258    jz4740_dma_set_transfer_count(jzfb->dma, size);
259
260    while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
261    writeb(readb(jzfb->base + JZ_REG_SLCD_CTRL) | SLCD_CTRL_DMA_EN,
262        jzfb->base + JZ_REG_SLCD_CTRL);
263    jz4740_dma_enable(jzfb->dma);
264}
265
266static void jzfb_upload_frame_cpu(struct jzfb *jzfb)
267{
268    const int num_pixels = jzfb->fb->mode->xres * jzfb->fb->mode->yres;
269    uint16_t *p = jzfb->vidmem;
270    int i;
271
272    jzfb_disable_dma(jzfb);
273    for (i = 0; i < num_pixels; i++) {
274        uint16_t rgb = *p++;
275        while (readb(jzfb->base + JZ_REG_SLCD_STATE) & SLCD_STATE_BUSY);
276        writel(SLCD_DATA_RS_DATA | rgb, jzfb->base + JZ_REG_SLCD_DATA);
277    }
278}
279
280static void jzfb_refresh_work(struct work_struct *work)
281{
282    struct jzfb *jzfb = container_of(work, struct jzfb, refresh_work.work);
283
284    mutex_lock(&jzfb->lock);
285    if (jzfb->is_enabled) {
286        if (1) {
287            int interval;
288
289            if (jzfb->dma_completion.done) {
290                if (jzfb->refresh_on_pan)
291                    interval = HZ / 5;
292                else
293                    interval = HZ / 60;
294                jzfb->refresh_on_pan = 0;
295
296                INIT_COMPLETION(jzfb->dma_completion);
297                jzfb_upload_frame_dma(jzfb);
298            } else
299                interval = HZ / 250;
300
301            schedule_delayed_work(&jzfb->refresh_work, interval);
302        } else {
303            jzfb_upload_frame_cpu(jzfb);
304            schedule_delayed_work(&jzfb->refresh_work, HZ / 10);
305        }
306    }
307    mutex_unlock(&jzfb->lock);
308}
309
310static int jzfb_set_par(struct fb_info *info)
311{
312    struct jzfb *jzfb = info->par;
313    struct fb_var_screeninfo *var = &info->var;
314    struct fb_videomode *mode;
315    uint16_t slcd_cfg;
316
317    mode = jzfb_get_mode(jzfb, var);
318    if (mode == NULL)
319        return -EINVAL;
320
321    info->mode = mode;
322
323    slcd_cfg = SLCD_CFG_BURST_8_WORD;
324    /* command size */
325    slcd_cfg |= (jzfb->pdata->lcd_type & 3) << SLCD_CFG_CWIDTH_BIT;
326    /* data size */
327    if (jzfb->pdata->lcd_type & (1 << 6)) {
328        /* serial */
329        unsigned int num_bits;
330        switch (jzfb->pdata->lcd_type) {
331        case JZ_LCD_TYPE_SMART_SERIAL_8_BIT:
332            slcd_cfg |= SLCD_CFG_DWIDTH_8_x1;
333            num_bits = 8;
334            break;
335        case JZ_LCD_TYPE_SMART_SERIAL_16_BIT:
336            slcd_cfg |= SLCD_CFG_DWIDTH_16;
337            num_bits = 16;
338            break;
339        case JZ_LCD_TYPE_SMART_SERIAL_18_BIT:
340            slcd_cfg |= SLCD_CFG_DWIDTH_18;
341            num_bits = 18;
342            break;
343        default:
344            num_bits = 0;
345            break;
346        }
347        if (num_bits != jzfb->pdata->bpp) {
348            dev_err(&jzfb->pdev->dev,
349                "Data size (%d) does not match bpp (%d)\n",
350                num_bits, jzfb->pdata->bpp);
351        }
352        slcd_cfg |= SLCD_CFG_TYPE_SERIAL;
353    } else {
354        /* parallel */
355        switch (jzfb->pdata->bpp) {
356        case 8:
357            slcd_cfg |= SLCD_CFG_DWIDTH_8_x1;
358            break;
359        case 15:
360        case 16:
361            switch (jzfb->pdata->lcd_type) {
362            case JZ_LCD_TYPE_SMART_PARALLEL_8_BIT:
363                slcd_cfg |= SLCD_CFG_DWIDTH_8_x2;
364                break;
365            default:
366                slcd_cfg |= SLCD_CFG_DWIDTH_16;
367                break;
368            }
369            break;
370        case 18:
371            switch (jzfb->pdata->lcd_type) {
372            case JZ_LCD_TYPE_SMART_PARALLEL_8_BIT:
373                slcd_cfg |= SLCD_CFG_DWIDTH_8_x3;
374                break;
375            case JZ_LCD_TYPE_SMART_PARALLEL_16_BIT:
376                slcd_cfg |= SLCD_CFG_DWIDTH_9_x2;
377                break;
378            case JZ_LCD_TYPE_SMART_PARALLEL_18_BIT:
379                slcd_cfg |= SLCD_CFG_DWIDTH_18;
380                break;
381            default:
382                break;
383            }
384            break;
385        case 24:
386            slcd_cfg |= SLCD_CFG_DWIDTH_8_x3;
387            break;
388        default:
389            dev_err(&jzfb->pdev->dev,
390                "Unsupported value for bpp: %d\n",
391                jzfb->pdata->bpp);
392        }
393        slcd_cfg |= SLCD_CFG_TYPE_PARALLEL;
394    }
395    if (!jzfb->pdata->chip_select_active_low)
396        slcd_cfg |= SLCD_CFG_CS_ACTIVE_HIGH;
397    if (!jzfb->pdata->register_select_active_low)
398        slcd_cfg |= SLCD_CFG_RS_CMD_HIGH;
399    if (!jzfb->pdata->pixclk_falling_edge)
400        slcd_cfg |= SLCD_CFG_CLK_ACTIVE_RISING;
401
402#if 0
403    // TODO(MtH): Compute rate from refresh or vice versa.
404    if (mode->pixclock) {
405        rate = PICOS2KHZ(mode->pixclock) * 1000;
406        mode->refresh = rate / vt / ht;
407    } else {
408        if (jzfb->pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL)
409            rate = mode->refresh * (vt + 2 * mode->xres) * ht;
410        else
411            rate = mode->refresh * vt * ht;
412
413        mode->pixclock = KHZ2PICOS(rate / 1000);
414    }
415#endif
416
417    mutex_lock(&jzfb->lock);
418    if (!jzfb->is_enabled)
419        clk_prepare_enable(jzfb->ldclk);
420
421    // TODO(MtH): We should not change config while DMA might be running.
422    writew(slcd_cfg, jzfb->base + JZ_REG_SLCD_CFG);
423
424    if (!jzfb->is_enabled)
425        clk_disable_unprepare(jzfb->ldclk);
426    mutex_unlock(&jzfb->lock);
427
428    // TODO(MtH): Use maximum transfer speed that panel can handle.
429    // ILI9325 can do 10 MHz.
430    clk_set_rate(jzfb->lpclk, 12000000);
431    clk_set_rate(jzfb->ldclk, 42000000);
432
433    return 0;
434}
435
436static void jzfb_enable(struct jzfb *jzfb)
437{
438    uint32_t ctrl;
439
440    clk_prepare_enable(jzfb->ldclk);
441
442    jz_gpio_bulk_resume(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
443    if (jzfb->pdata->lcd_type & (1 << 6)) {
444        /* serial */
445        jz_gpio_bulk_resume(&jz_slcd_data_pins[15], 1);
446    } else {
447        /* parallel */
448        jz_gpio_bulk_resume(jz_slcd_data_pins,
449                    jzfb_num_data_pins(jzfb));
450    }
451    jzfb_disable_dma(jzfb);
452    complete_all(&jzfb->dma_completion);
453    jzfb->panel->enable(jzfb);
454
455    ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
456    ctrl |= JZ_LCD_CTRL_ENABLE;
457    ctrl &= ~JZ_LCD_CTRL_DISABLE;
458    writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
459
460    schedule_delayed_work(&jzfb->refresh_work, 0);
461}
462
463static void jzfb_disable(struct jzfb *jzfb)
464{
465    /* It is safe but wasteful to call refresh_work() while disabled. */
466    cancel_delayed_work_sync(&jzfb->refresh_work);
467
468    /* Abort any DMA transfer that might be in progress and allow direct
469       writes to the panel. */
470    jzfb_disable_dma(jzfb);
471    complete_all(&jzfb->dma_completion);
472
473    jzfb->panel->disable(jzfb);
474    jz_gpio_bulk_suspend(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
475    if (jzfb->pdata->lcd_type & (1 << 6)) {
476        /* serial */
477        jz_gpio_bulk_suspend(&jz_slcd_data_pins[15], 1);
478    } else {
479        /* parallel */
480        jz_gpio_bulk_suspend(jz_slcd_data_pins,
481                     jzfb_num_data_pins(jzfb));
482    }
483
484    clk_disable_unprepare(jzfb->ldclk);
485}
486
487static int jzfb_blank(int blank_mode, struct fb_info *info)
488{
489    struct jzfb *jzfb = info->par;
490    int ret = 0;
491    int new_enabled = (blank_mode == FB_BLANK_UNBLANK);
492
493    mutex_lock(&jzfb->lock);
494    if (new_enabled) {
495        if (!jzfb->is_enabled)
496            jzfb_enable(jzfb);
497    } else {
498        if (jzfb->is_enabled) {
499            /* No sleep in TV-out mode. */
500            if (jzfb->tv_out == FB_A320TV_OFF)
501                jzfb_disable(jzfb);
502            else
503                ret = -EBUSY;
504        }
505    }
506    if (!ret)
507        jzfb->is_enabled = new_enabled;
508    mutex_unlock(&jzfb->lock);
509
510    return ret;
511}
512
513static int jzfb_wait_for_vsync(struct fb_info *info)
514{
515    struct jzfb *jzfb = info->par;
516
517    if (jzfb->tv_out != FB_A320TV_OFF &&
518                !jzfb->tv_out_vsync)
519        return 0;
520    return wait_for_completion_interruptible(&jzfb->dma_completion);
521}
522
523static int jzfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
524{
525    struct jzfb *jzfb = info->par;
526    info->var.yoffset = var->yoffset;
527
528    /* Ensure that the data to be uploaded is in memory. */
529    dma_cache_sync(&jzfb->pdev->dev, jzfb->vidmem
530                + info->fix.line_length * var->yoffset,
531                info->fix.line_length * var->yres,
532                DMA_TO_DEVICE);
533
534    /* update frame start address for TV-out mode */
535    (*jzfb->framedesc)[1].addr = jzfb->vidmem_phys
536                          + info->fix.line_length * var->yoffset;
537
538    jzfb_wait_for_vsync(info);
539
540    jzfb->refresh_on_pan = 1;
541    flush_delayed_work(&jzfb->refresh_work);
542    return 0;
543}
544
545static int jzfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
546{
547    const unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
548    const unsigned long size = vma->vm_end - vma->vm_start;
549
550    if (offset + size > info->fix.smem_len)
551        return -EINVAL;
552
553    if (remap_pfn_range(vma, vma->vm_start,
554                (info->fix.smem_start + offset) >> PAGE_SHIFT,
555                size, vma->vm_page_prot))
556        return -EAGAIN;
557
558    return 0;
559}
560
561static int jzfb_alloc_devmem(struct jzfb *jzfb)
562{
563    int max_linesize = 0, max_framesize = 0;
564    int bytes_per_pixel;
565    struct fb_videomode *mode = jzfb->pdata->modes;
566    void *page;
567    int i;
568
569    for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
570        if (max_linesize < mode->xres)
571            max_linesize = mode->xres;
572        if (max_framesize < mode->xres * mode->yres)
573            max_framesize = mode->xres * mode->yres;
574    }
575
576    bytes_per_pixel = jzfb_get_controller_bpp(jzfb) >> 3;
577    max_linesize *= bytes_per_pixel;
578    max_framesize *= bytes_per_pixel;
579
580    jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
581                    sizeof(*jzfb->framedesc),
582                    &jzfb->framedesc_phys, GFP_KERNEL);
583    if (!jzfb->framedesc)
584        return -ENOMEM;
585
586    jzfb->blackline_size = max_linesize;
587    jzfb->blackline = dma_alloc_coherent(&jzfb->pdev->dev,
588                         jzfb->blackline_size,
589                         &jzfb->blackline_phys, GFP_KERNEL);
590    if (!jzfb->blackline)
591        goto err_free_framedesc;
592
593    /* Set the black line to black... */
594    memset(jzfb->blackline, 0, jzfb->blackline_size);
595
596    /* reserve memory for two frames to allow double buffering */
597    jzfb->vidmem_size = PAGE_ALIGN(max_framesize * 2);
598    jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
599                        jzfb->vidmem_size,
600                        &jzfb->vidmem_phys, GFP_KERNEL);
601
602    if (!jzfb->vidmem)
603        goto err_free_blackline;
604
605    for (page = jzfb->vidmem;
606         page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
607         page += PAGE_SIZE) {
608        SetPageReserved(virt_to_page(page));
609    }
610
611    for (i = 0; i < 3; i++)
612        (*jzfb->framedesc)[i].next = jzfb->framedesc_phys
613                + ((i + 1) % 3) * sizeof(struct jzfb_framedesc);
614    (*jzfb->framedesc)[0].addr = (*jzfb->framedesc)[2].addr =
615            jzfb->blackline_phys;
616    (*jzfb->framedesc)[0].id = 0xdadabeeb;
617    (*jzfb->framedesc)[2].id = 0xfadefeed;
618    (*jzfb->framedesc)[0].cmd = (*jzfb->framedesc)[2].cmd =
619            jzfb->blackline_size / 4;
620    (*jzfb->framedesc)[1].addr = jzfb->vidmem_phys;
621    (*jzfb->framedesc)[1].id = 0xdeafbead;
622    (*jzfb->framedesc)[1].cmd = (max_framesize / 4)
623            | JZ_LCD_CMD_EOF_IRQ | JZ_LCD_CMD_SOF_IRQ;
624
625    return 0;
626
627err_free_blackline:
628    dma_free_coherent(&jzfb->pdev->dev, jzfb->blackline_size,
629                jzfb->blackline, jzfb->blackline_phys);
630err_free_framedesc:
631    dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
632                jzfb->framedesc, jzfb->framedesc_phys);
633    return -ENOMEM;
634}
635
636static void jzfb_free_devmem(struct jzfb *jzfb)
637{
638    dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
639                jzfb->vidmem, jzfb->vidmem_phys);
640    dma_free_coherent(&jzfb->pdev->dev, jzfb->blackline_size,
641                jzfb->blackline, jzfb->blackline_phys);
642    dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
643                jzfb->framedesc, jzfb->framedesc_phys);
644}
645
646static int jzfb_tv_out(struct jzfb *jzfb, unsigned int mode)
647{
648    int blank = jzfb->is_enabled ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
649    struct fb_event event = {
650        .info = jzfb->fb,
651        .data = &blank,
652    };
653
654    printk("A320 TV out: %d\n", mode);
655    if (mode > FB_A320TV_LAST)
656        return -EINVAL;
657    if (mode == jzfb->tv_out)
658        return 0;
659
660    if (mode != FB_A320TV_OFF) {
661        cancel_delayed_work_sync(&jzfb->refresh_work);
662        /* Abort any DMA transfer that might be in progress and
663           allow direct writes to the panel. */
664        jzfb_disable_dma(jzfb);
665        jzfb->panel->disable(jzfb);
666        complete_all(&jzfb->dma_completion);
667
668        /* set up LCD controller for TV output */
669
670        writel(JZ_LCD_CFG_HSYNC_ACTIVE_LOW |
671               JZ_LCD_CFG_VSYNC_ACTIVE_LOW,
672               jzfb->base + JZ_REG_LCD_CFG);
673
674        /* V-Sync pulse end position */
675        writel(10, jzfb->base + JZ_REG_LCD_VSYNC);
676
677        if (mode == FB_A320TV_PAL50) {
678            /* PAL 50 Hz */
679            /* H-Sync pulse start position */
680            writel(0x0000007d, jzfb->base + JZ_REG_LCD_HSYNC);
681            /* virtual area size */
682            writel(0x036c0112, jzfb->base + JZ_REG_LCD_VAT);
683            /* horizontal start/end point */
684            writel(0x02240364, jzfb->base + JZ_REG_LCD_DAH);
685            /* vertical start/end point */
686            writel(0x001a010c, jzfb->base + JZ_REG_LCD_DAV);
687        } else {
688            /* NTSC and PAL 60 Hz */
689            writel(0x0000003c, jzfb->base + JZ_REG_LCD_HSYNC);
690            writel(0x02e00110, jzfb->base + JZ_REG_LCD_VAT);
691            writel(0x019902d9, jzfb->base + JZ_REG_LCD_DAH);
692            writel(0x001c010e, jzfb->base + JZ_REG_LCD_DAV);
693        }
694        writel(0, jzfb->base + JZ_REG_LCD_PS);
695        writel(0, jzfb->base + JZ_REG_LCD_CLS);
696        writel(0, jzfb->base + JZ_REG_LCD_SPL);
697        writel(0, jzfb->base + JZ_REG_LCD_REV);
698        /* reset status register */
699        writel(0, jzfb->base + JZ_REG_LCD_STATE);
700
701        /* tell LCDC about the frame descriptor address */
702        writel(jzfb->framedesc_phys, jzfb->base + JZ_REG_LCD_DA0);
703
704        writel(JZ_LCD_CTRL_BURST_16 | JZ_LCD_CTRL_ENABLE |
705                    JZ_LCD_CTRL_BPP_15_16 |
706                    JZ_LCD_CTRL_EOF_IRQ | JZ_LCD_CTRL_SOF_IRQ,
707                    jzfb->base + JZ_REG_LCD_CTRL);
708    } else {
709        /* disable EOF/SOF interrupts */
710        unsigned long ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
711        ctrl &= ~(JZ_LCD_CTRL_EOF_IRQ | JZ_LCD_CTRL_SOF_IRQ);
712        writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
713
714        /* disable LCD controller and re-enable SLCD */
715        writel(JZ_LCD_CFG_SLCD, jzfb->base + JZ_REG_LCD_CFG);
716        jzfb->panel->enable(jzfb);
717
718        jzfb->refresh_on_pan = 0;
719        complete_all(&jzfb->dma_completion);
720        schedule_delayed_work(&jzfb->refresh_work, 0);
721    }
722
723    /* reaffirm the current blanking state, to trigger a backlight update */
724    console_lock();
725    fb_notifier_call_chain(FB_EVENT_BLANK, &event);
726    console_unlock();
727    jzfb->tv_out = mode;
728    return 0;
729}
730
731static ssize_t jzfb_tv_out_show(struct device *dev, struct device_attribute *attr,
732            char *buf)
733{
734    struct jzfb *jzfb = dev_get_drvdata(dev);
735
736    if (jzfb->tv_out > FB_A320TV_LAST) {
737        dev_err(dev, "Unknown norm for TV-out\n");
738        return -1;
739    }
740
741    return sprintf(buf, "%s\n", jzfb_tv_out_norm[jzfb->tv_out]);
742}
743
744static ssize_t jzfb_tv_out_store(struct device *dev, struct device_attribute *attr,
745            const char *buf, size_t n)
746{
747    size_t i;
748    struct jzfb *jzfb = dev_get_drvdata(dev);
749
750    for (i = 0; i <= FB_A320TV_LAST; i++) {
751        if (sysfs_streq(jzfb_tv_out_norm[i], buf)) {
752            jzfb_tv_out(jzfb, i);
753            return n;
754        }
755    }
756    return -EINVAL;
757}
758
759static DEVICE_ATTR(tv_out, 0644, jzfb_tv_out_show, jzfb_tv_out_store);
760
761static ssize_t jzfb_vsync_show(struct device *dev, struct device_attribute *attr,
762            char *buf)
763{
764    struct jzfb *jzfb = dev_get_drvdata(dev);
765    return sprintf(buf, "%u\n", jzfb->tv_out_vsync);
766}
767
768static ssize_t jzfb_vsync_store(struct device *dev, struct device_attribute *attr,
769            const char *buf, size_t n)
770{
771    struct jzfb *jzfb = dev_get_drvdata(dev);
772    unsigned int vsync;
773
774    if (sscanf(buf, "%u", &vsync) < 1)
775        return -EINVAL;
776
777    jzfb->tv_out_vsync = vsync;
778    return n;
779}
780
781static DEVICE_ATTR(tv_out_vsync, 0644, jzfb_vsync_show, jzfb_vsync_store);
782
783static ssize_t jzfb_panel_show(struct device *dev, struct device_attribute *attr,
784            char *buf)
785{
786    struct jzfb *jzfb = dev_get_drvdata(dev);
787    return sprintf(buf, "%s\n", jzfb->panel->name);
788}
789
790static ssize_t jzfb_panel_store(struct device *dev, struct device_attribute *attr,
791            const char *buf, size_t n)
792{
793    struct jzfb *jzfb = dev_get_drvdata(dev);
794    const struct jz_slcd_panel *panel = jz_slcd_panel_from_name(buf);
795
796    if (!panel) {
797        dev_err(dev, "Unknown SLCD panel: %s\n", buf);
798        return -EINVAL;
799    }
800
801    if (panel != jzfb->panel) {
802        jzfb->panel->disable(jzfb);
803        jzfb->panel->exit(jzfb);
804        jzfb->panel = panel;
805        panel->init(jzfb);
806        panel->enable(jzfb);
807    }
808    return n;
809}
810
811static DEVICE_ATTR(panel, 0644, jzfb_panel_show, jzfb_panel_store);
812
813static struct fb_ops jzfb_ops = {
814    .owner = THIS_MODULE,
815    .fb_check_var = jzfb_check_var,
816    .fb_set_par = jzfb_set_par,
817    .fb_setcolreg = jzfb_setcolreg,
818    .fb_blank = jzfb_blank,
819    .fb_pan_display = jzfb_pan_display,
820    .fb_fillrect = sys_fillrect,
821    .fb_copyarea = sys_copyarea,
822    .fb_imageblit = sys_imageblit,
823    .fb_mmap = jzfb_mmap,
824};
825
826static irqreturn_t jz4740_lcd_irq(int irq, void *dev_id)
827{
828    struct jzfb *jzfb = dev_id;
829    unsigned long state = readl(jzfb->base + JZ_REG_LCD_STATE);
830
831    if (state & JZ_LCD_STATE_SOF) {
832        INIT_COMPLETION(jzfb->dma_completion);
833        state &= ~JZ_LCD_STATE_SOF;
834    } else {
835        complete_all(&jzfb->dma_completion);
836        state &= ~JZ_LCD_STATE_EOF;
837    }
838
839    /* Acknowledge the interrupt */
840    writel(state, jzfb->base + JZ_REG_LCD_STATE);
841    return IRQ_HANDLED;
842}
843
844static int jzfb_probe(struct platform_device *pdev)
845{
846    int ret;
847    struct jzfb *jzfb;
848    struct fb_info *fb;
849    struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
850    struct resource *mem;
851
852    if (!pdata) {
853        dev_err(&pdev->dev, "Missing platform data\n");
854        return -ENOENT;
855    }
856
857    fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
858
859    if (!fb) {
860        dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
861        return -ENOMEM;
862    }
863
864    fb->fbops = &jzfb_ops;
865    fb->flags = FBINFO_DEFAULT;
866
867    jzfb = fb->par;
868    jzfb->pdata = pdata;
869    jzfb->pdev = pdev;
870
871    mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
872    jzfb->base = devm_ioremap_resource(&pdev->dev, mem);
873    if (IS_ERR(jzfb->base)) {
874        ret = PTR_ERR(jzfb->base);
875        goto err_framebuffer_release;
876    }
877
878    jzfb->tv_out = FB_A320TV_OFF;
879    jzfb->tv_out_vsync = 1;
880    jzfb->refresh_on_pan = 0;
881    init_completion(&jzfb->dma_completion);
882    complete_all(&jzfb->dma_completion);
883
884    jzfb->dma = jz4740_dma_request(&pdev->dev, dev_name(&pdev->dev), 0);
885    if (!jzfb->dma) {
886        dev_err(&pdev->dev, "Failed to get DMA channel\n");
887        ret = -EBUSY;
888        goto err_framebuffer_release;
889    }
890    jz4740_dma_configure(jzfb->dma, &jzfb_slcd_dma_config);
891    jz4740_dma_set_complete_cb(jzfb->dma, &jzfb_refresh_work_complete);
892
893    jzfb->ldclk = clk_get(&pdev->dev, "lcd");
894    if (IS_ERR(jzfb->ldclk)) {
895        ret = PTR_ERR(jzfb->ldclk);
896        dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
897        goto err_free_dma;
898    }
899
900    jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
901    if (IS_ERR(jzfb->lpclk)) {
902        ret = PTR_ERR(jzfb->lpclk);
903        dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
904        goto err_put_ldclk;
905    }
906
907    platform_set_drvdata(pdev, jzfb);
908
909    fb_videomode_to_modelist(pdata->modes, pdata->num_modes,
910                 &fb->modelist);
911    fb->mode = pdata->modes;
912
913    fb_videomode_to_var(&fb->var, fb->mode);
914    fb->var.bits_per_pixel = pdata->bpp;
915    jzfb_check_var(&fb->var, fb);
916
917    ret = jzfb_alloc_devmem(jzfb);
918    if (ret) {
919        dev_err(&pdev->dev, "Failed to allocate video memory\n");
920        goto err_put_lpclk;
921    }
922
923    fb->fix = jzfb_fix;
924    fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
925    fb->fix.mmio_start = mem->start;
926    fb->fix.mmio_len = resource_size(mem);
927    fb->fix.smem_start = jzfb->vidmem_phys;
928    fb->fix.smem_len = fb->fix.line_length * fb->var.yres_virtual;
929    fb->screen_base = jzfb->vidmem;
930    fb->pseudo_palette = jzfb->pseudo_palette;
931
932    fb_alloc_cmap(&fb->cmap, 256, 0);
933
934    mutex_init(&jzfb->lock);
935
936    clk_prepare_enable(jzfb->ldclk);
937    jzfb->is_enabled = 1;
938
939    writel(JZ_LCD_CFG_SLCD, jzfb->base + JZ_REG_LCD_CFG);
940    writeb(0, jzfb->base + JZ_REG_SLCD_CTRL);
941
942    jzfb_set_par(fb);
943
944    jz_gpio_bulk_request(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
945    if (jzfb->pdata->lcd_type & (1 << 6)) {
946        /* serial */
947        jz_gpio_bulk_request(&jz_slcd_data_pins[15], 1);
948    } else {
949        /* parallel */
950        jz_gpio_bulk_request(jz_slcd_data_pins,
951                     jzfb_num_data_pins(jzfb));
952    }
953
954    ret = request_irq(JZ4740_IRQ_LCD, jz4740_lcd_irq, 0, "LCD", jzfb);
955    if (ret) {
956        dev_err(&pdev->dev, "Failed to request IRQ\n");
957        goto err_free_devmem;
958    }
959
960    jzfb->panel = jz_slcd_panels_probe(jzfb);
961    if (!jzfb->panel) {
962        dev_err(&pdev->dev, "Failed to find panel driver\n");
963        ret = -ENOENT;
964        goto err_free_irq;
965    }
966    jzfb_disable_dma(jzfb);
967    jzfb->panel->init(jzfb);
968
969    jzfb->panel->enable(jzfb);
970
971    ret = register_framebuffer(fb);
972    if (ret) {
973        dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
974        goto err_free_panel;
975    }
976
977    jzfb->fb = fb;
978    fb_prepare_logo(jzfb->fb, 0);
979    fb_show_logo(jzfb->fb, 0);
980
981    INIT_DELAYED_WORK(&jzfb->refresh_work, jzfb_refresh_work);
982    schedule_delayed_work(&jzfb->refresh_work, 0);
983
984    ret = device_create_file(&pdev->dev, &dev_attr_panel);
985    if (ret)
986        goto err_cancel_work;
987
988    ret = device_create_file(&pdev->dev, &dev_attr_tv_out);
989    if (ret)
990        goto err_remove_file_panel;
991
992    ret = device_create_file(&pdev->dev, &dev_attr_tv_out_vsync);
993    if (!ret)
994        return 0;
995
996    device_remove_file(&pdev->dev, &dev_attr_tv_out);
997err_remove_file_panel:
998    device_remove_file(&pdev->dev, &dev_attr_panel);
999err_cancel_work:
1000    cancel_delayed_work_sync(&jzfb->refresh_work);
1001err_free_panel:
1002    jzfb->panel->exit(jzfb);
1003err_free_irq:
1004    free_irq(JZ4740_IRQ_LCD, jzfb);
1005err_free_devmem:
1006    jzfb_free_gpio_pins(jzfb);
1007
1008    fb_dealloc_cmap(&fb->cmap);
1009    jzfb_free_devmem(jzfb);
1010err_put_lpclk:
1011    clk_put(jzfb->lpclk);
1012err_put_ldclk:
1013    clk_put(jzfb->ldclk);
1014err_free_dma:
1015    jz4740_dma_free(jzfb->dma);
1016err_framebuffer_release:
1017    framebuffer_release(fb);
1018    return ret;
1019}
1020
1021static int jzfb_remove(struct platform_device *pdev)
1022{
1023    struct jzfb *jzfb = platform_get_drvdata(pdev);
1024
1025    device_remove_file(&pdev->dev, &dev_attr_tv_out_vsync);
1026    device_remove_file(&pdev->dev, &dev_attr_tv_out);
1027    device_remove_file(&pdev->dev, &dev_attr_panel);
1028    jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
1029
1030    free_irq(JZ4740_IRQ_LCD, jzfb);
1031
1032    /* Blanking will prevent future refreshes from behind scheduled.
1033       Now wait for a possible refresh in progress to finish. */
1034    cancel_delayed_work_sync(&jzfb->refresh_work);
1035
1036    jzfb->panel->exit(jzfb);
1037
1038    jzfb_free_gpio_pins(jzfb);
1039
1040    jz4740_dma_free(jzfb->dma);
1041
1042    fb_dealloc_cmap(&jzfb->fb->cmap);
1043    jzfb_free_devmem(jzfb);
1044
1045    platform_set_drvdata(pdev, NULL);
1046
1047    clk_put(jzfb->lpclk);
1048    clk_put(jzfb->ldclk);
1049
1050    framebuffer_release(jzfb->fb);
1051
1052    return 0;
1053}
1054
1055#ifdef CONFIG_PM
1056
1057static int jzfb_suspend(struct device *dev)
1058{
1059    struct jzfb *jzfb = dev_get_drvdata(dev);
1060
1061    console_lock();
1062    fb_set_suspend(jzfb->fb, 1);
1063    console_unlock();
1064
1065    mutex_lock(&jzfb->lock);
1066    if (jzfb->is_enabled)
1067        jzfb_disable(jzfb);
1068    mutex_unlock(&jzfb->lock);
1069
1070    return 0;
1071}
1072
1073static int jzfb_resume(struct device *dev)
1074{
1075    struct jzfb *jzfb = dev_get_drvdata(dev);
1076
1077    mutex_lock(&jzfb->lock);
1078    if (jzfb->is_enabled)
1079        jzfb_enable(jzfb);
1080    mutex_unlock(&jzfb->lock);
1081
1082    console_lock();
1083    fb_set_suspend(jzfb->fb, 0);
1084    console_unlock();
1085
1086    return 0;
1087}
1088
1089static SIMPLE_DEV_PM_OPS(jzfb_pm_ops, jzfb_suspend, jzfb_resume);
1090
1091#define JZFB_PM_OPS (&jzfb_pm_ops)
1092
1093#else
1094#define JZFB_PM_OPS NULL
1095#endif
1096
1097static struct platform_driver jzfb_driver = {
1098    .probe = jzfb_probe,
1099    .remove = jzfb_remove,
1100    .driver = {
1101        .name = "jz4740-fb",
1102        .pm = JZFB_PM_OPS,
1103    },
1104};
1105module_platform_driver(jzfb_driver);
1106
1107MODULE_LICENSE("GPL");
1108MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>, Maarten ter Huurne <maarten@treewalker.org>");
1109MODULE_DESCRIPTION("JZ4740 SoC SLCD framebuffer driver");
1110MODULE_ALIAS("platform:jz4740-fb");
1111

Archive Download this file



interactive