Root/drivers/video/jz4740_slcd_fb.c

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

Archive Download this file



interactive