Root/drivers/video/jz4740_slcd_fb.c

Source at commit 0ff19649b347708021af975c15c64cfa04fa0078 created 8 years 6 months ago.
By Maarten ter Huurne, MIPS: JZ4740: SLCD: Add PAL-60 mode for TV-out.
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_PAL50 2
595#define FB_A320TV_PAL60 3
596#define FB_A320TV_LAST 3
597
598static int jzfb_tv_out(struct jzfb *jzfb, unsigned int mode)
599{
600    int blank = jzfb->is_enabled ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
601    struct fb_event event = {
602        .info = jzfb->fb,
603        .data = &blank,
604    };
605
606    printk("A320 TV out: %d\n", mode);
607    if (mode > FB_A320TV_LAST)
608        return -EINVAL;
609
610    if (mode != FB_A320TV_OFF) {
611        cancel_delayed_work(&jzfb->refresh_work);
612        /* Abort any DMA transfer that might be in progress and
613           allow direct writes to the panel. */
614        jzfb_disable_dma(jzfb);
615        jzfb->panel->disable(jzfb);
616
617        /* set up LCD controller for TV output */
618
619        writel(JZ_LCD_CFG_HSYNC_ACTIVE_LOW |
620               JZ_LCD_CFG_VSYNC_ACTIVE_LOW,
621               jzfb->base + JZ_REG_LCD_CFG);
622
623        /* V-Sync pulse end position */
624        writel(10, jzfb->base + JZ_REG_LCD_VSYNC);
625
626        if (mode == FB_A320TV_PAL50) {
627            /* PAL 50 Hz */
628            /* H-Sync pulse start position */
629            writel(0x0000007d, jzfb->base + JZ_REG_LCD_HSYNC);
630            /* virtual area size */
631            writel(0x036c0112, jzfb->base + JZ_REG_LCD_VAT);
632            /* horizontal start/end point */
633            writel(0x02240364, jzfb->base + JZ_REG_LCD_DAH);
634            /* vertical start/end point */
635            writel(0x001b010b, jzfb->base + JZ_REG_LCD_DAV);
636        } else {
637            /* NTSC and PAL 60 Hz */
638            writel(0x0000003c, jzfb->base + JZ_REG_LCD_HSYNC);
639            writel(0x02e00110, jzfb->base + JZ_REG_LCD_VAT);
640            writel(0x019902d9, jzfb->base + JZ_REG_LCD_DAH);
641            writel(0x001d010d, jzfb->base + JZ_REG_LCD_DAV);
642        }
643        writel(0, jzfb->base + JZ_REG_LCD_PS);
644        writel(0, jzfb->base + JZ_REG_LCD_CLS);
645        writel(0, jzfb->base + JZ_REG_LCD_SPL);
646        writel(0, jzfb->base + JZ_REG_LCD_REV);
647        /* reset status register */
648        writel(0, jzfb->base + JZ_REG_LCD_STATE);
649
650        /* tell LCDC about the frame descriptor address */
651        writel(jzfb->framedesc_phys, jzfb->base + JZ_REG_LCD_DA0);
652
653        writel(JZ_LCD_CTRL_BURST_16 | JZ_LCD_CTRL_ENABLE |
654               JZ_LCD_CTRL_BPP_15_16,
655               jzfb->base + JZ_REG_LCD_CTRL);
656    } else {
657        /* disable LCD controller and re-enable SLCD */
658        writel(JZ_LCD_CFG_SLCD, jzfb->base + JZ_REG_LCD_CFG);
659        jzfb->panel->enable(jzfb);
660        schedule_delayed_work(&jzfb->refresh_work, 0);
661    }
662
663    /* reaffirm the current blanking state, to trigger a backlight update */
664    fb_notifier_call_chain(FB_EVENT_BLANK, &event);
665    return 0;
666}
667
668static int jzfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
669{
670    struct jzfb *jzfb = info->par;
671    switch (cmd) {
672        case FBIOA320TVOUT:
673            /* No TV-out mode while sleeping. */
674            if (!jzfb->is_enabled)
675                return -EBUSY;
676
677            return jzfb_tv_out(jzfb, arg);
678        default:
679            return -EINVAL;
680    }
681    return 0;
682}
683
684static ssize_t jzfb_panel_show(struct device *dev, struct device_attribute *attr,
685            char *buf)
686{
687    struct jzfb *jzfb = dev_get_drvdata(dev);
688    return sprintf(buf, "%s\n", jzfb->panel->name);
689}
690
691static ssize_t jzfb_panel_store(struct device *dev, struct device_attribute *attr,
692            const char *buf, size_t n)
693{
694    struct jzfb *jzfb = dev_get_drvdata(dev);
695    const struct jz_slcd_panel *panel = jz_slcd_panel_from_name(buf);
696
697    if (!panel) {
698        dev_err(dev, "Unknown SLCD panel: %s\n", buf);
699        return -EINVAL;
700    }
701
702    if (panel != jzfb->panel) {
703        jzfb->panel->disable(jzfb);
704        jzfb->panel->exit(jzfb);
705        jzfb->panel = panel;
706        panel->init(jzfb);
707        panel->enable(jzfb);
708    }
709    return n;
710}
711
712static DEVICE_ATTR(panel, 0644, jzfb_panel_show, jzfb_panel_store);
713
714static struct fb_ops jzfb_ops = {
715    .owner = THIS_MODULE,
716    .fb_check_var = jzfb_check_var,
717    .fb_set_par = jzfb_set_par,
718    .fb_setcolreg = jzfb_setcolreg,
719    .fb_blank = jzfb_blank,
720    .fb_pan_display = jzfb_pan_display,
721    .fb_fillrect = sys_fillrect,
722    .fb_copyarea = sys_copyarea,
723    .fb_imageblit = sys_imageblit,
724    .fb_ioctl = jzfb_ioctl,
725    .fb_mmap = jzfb_mmap,
726};
727
728static int __devinit jzfb_probe(struct platform_device *pdev)
729{
730    int ret;
731    struct jzfb *jzfb;
732    struct fb_info *fb;
733    struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
734    struct resource *mem;
735
736    if (!pdata) {
737        dev_err(&pdev->dev, "Missing platform data\n");
738        return -ENOENT;
739    }
740
741    mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
742
743    if (!mem) {
744        dev_err(&pdev->dev, "Failed to get register memory resource\n");
745        return -ENOENT;
746    }
747
748    mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
749
750    if (!mem) {
751        dev_err(&pdev->dev, "Failed to request register memory region\n");
752        return -EBUSY;
753    }
754
755    fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
756
757    if (!fb) {
758        dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
759        ret = -ENOMEM;
760        goto err_release_mem_region;
761    }
762
763    fb->fbops = &jzfb_ops;
764    fb->flags = FBINFO_DEFAULT;
765
766    jzfb = fb->par;
767    jzfb->pdev = pdev;
768    jzfb->pdata = pdata;
769    jzfb->mem = mem;
770
771    jzfb->dma = jz4740_dma_request(&pdev->dev, dev_name(&pdev->dev), 0);
772    if (!jzfb->dma) {
773        dev_err(&pdev->dev, "Failed to get DMA channel\n");
774        ret = -EBUSY;
775        goto err_framebuffer_release;
776    }
777    jz4740_dma_configure(jzfb->dma, &jzfb_slcd_dma_config);
778    jz4740_dma_set_complete_cb(jzfb->dma, &jzfb_refresh_work_complete);
779
780    jzfb->ldclk = clk_get(&pdev->dev, "lcd");
781    if (IS_ERR(jzfb->ldclk)) {
782        ret = PTR_ERR(jzfb->ldclk);
783        dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
784        goto err_free_dma;
785    }
786
787    jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
788    if (IS_ERR(jzfb->lpclk)) {
789        ret = PTR_ERR(jzfb->lpclk);
790        dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
791        goto err_put_ldclk;
792    }
793
794    jzfb->base = ioremap(mem->start, resource_size(mem));
795
796    if (!jzfb->base) {
797        dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
798        ret = -EBUSY;
799        goto err_put_lpclk;
800    }
801
802    platform_set_drvdata(pdev, jzfb);
803
804    fb_videomode_to_modelist(pdata->modes, pdata->num_modes,
805                 &fb->modelist);
806    fb->mode = pdata->modes;
807
808    fb_videomode_to_var(&fb->var, fb->mode);
809    fb->var.bits_per_pixel = pdata->bpp;
810    jzfb_check_var(&fb->var, fb);
811
812    ret = jzfb_alloc_devmem(jzfb);
813    if (ret) {
814        dev_err(&pdev->dev, "Failed to allocate video memory\n");
815        goto err_iounmap;
816    }
817
818    fb->fix = jzfb_fix;
819    fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
820    fb->fix.mmio_start = mem->start;
821    fb->fix.mmio_len = resource_size(mem);
822    fb->fix.smem_start = jzfb->vidmem_phys;
823    fb->fix.smem_len = fb->fix.line_length * fb->var.yres_virtual;
824    fb->screen_base = jzfb->vidmem;
825    fb->pseudo_palette = jzfb->pseudo_palette;
826
827    fb_alloc_cmap(&fb->cmap, 256, 0);
828
829    mutex_init(&jzfb->lock);
830
831    clk_enable(jzfb->ldclk);
832    jzfb->is_enabled = 1;
833
834    writel(JZ_LCD_CFG_SLCD, jzfb->base + JZ_REG_LCD_CFG);
835    writeb(0, jzfb->base + JZ_REG_SLCD_CTRL);
836
837    jzfb_set_par(fb);
838
839    jz_gpio_bulk_request(jz_slcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
840    if (jzfb->pdata->lcd_type & (1 << 6)) {
841        /* serial */
842        jz_gpio_bulk_request(&jz_slcd_data_pins[15], 1);
843    } else {
844        /* parallel */
845        jz_gpio_bulk_request(jz_slcd_data_pins,
846                     jzfb_num_data_pins(jzfb));
847    }
848
849    jzfb->panel = jz_slcd_panels_probe(jzfb);
850    if (!jzfb->panel) {
851        dev_err(&pdev->dev, "Failed to find panel driver\n");
852        ret = -ENOENT;
853        goto err_free_devmem;
854    }
855    jzfb_disable_dma(jzfb);
856    jzfb->panel->init(jzfb);
857    jzfb->panel->enable(jzfb);
858
859    ret = register_framebuffer(fb);
860    if (ret) {
861        dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
862        goto err_free_panel;
863    }
864
865    jzfb->fb = fb;
866    fb_prepare_logo(jzfb->fb, 0);
867    fb_show_logo(jzfb->fb, 0);
868
869    INIT_DELAYED_WORK(&jzfb->refresh_work, jzfb_refresh_work);
870    schedule_delayed_work(&jzfb->refresh_work, 0);
871
872    ret = device_create_file(&pdev->dev, &dev_attr_panel);
873    if (!ret)
874        return 0;
875
876    cancel_delayed_work_sync(&jzfb->refresh_work);
877err_free_panel:
878    jzfb->panel->exit(jzfb);
879err_free_devmem:
880    jzfb_free_gpio_pins(jzfb);
881
882    fb_dealloc_cmap(&fb->cmap);
883    jzfb_free_devmem(jzfb);
884err_iounmap:
885    iounmap(jzfb->base);
886err_put_lpclk:
887    clk_put(jzfb->lpclk);
888err_put_ldclk:
889    clk_put(jzfb->ldclk);
890err_free_dma:
891    jz4740_dma_free(jzfb->dma);
892err_framebuffer_release:
893    framebuffer_release(fb);
894err_release_mem_region:
895    release_mem_region(mem->start, resource_size(mem));
896    return ret;
897}
898
899static int __devexit jzfb_remove(struct platform_device *pdev)
900{
901    struct jzfb *jzfb = platform_get_drvdata(pdev);
902
903    device_remove_file(&pdev->dev, &dev_attr_panel);
904    jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
905
906    /* Blanking will prevent future refreshes from behind scheduled.
907       Now wait for a possible refresh in progress to finish. */
908    cancel_delayed_work_sync(&jzfb->refresh_work);
909
910    jzfb->panel->exit(jzfb);
911
912    jzfb_free_gpio_pins(jzfb);
913
914    jz4740_dma_free(jzfb->dma);
915
916    iounmap(jzfb->base);
917    release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
918
919    fb_dealloc_cmap(&jzfb->fb->cmap);
920    jzfb_free_devmem(jzfb);
921
922    platform_set_drvdata(pdev, NULL);
923
924    clk_put(jzfb->lpclk);
925    clk_put(jzfb->ldclk);
926
927    framebuffer_release(jzfb->fb);
928
929    return 0;
930}
931
932#ifdef CONFIG_PM
933
934static int jzfb_suspend(struct device *dev)
935{
936    struct jzfb *jzfb = dev_get_drvdata(dev);
937
938    console_lock();
939    fb_set_suspend(jzfb->fb, 1);
940    console_unlock();
941
942    mutex_lock(&jzfb->lock);
943    if (jzfb->is_enabled)
944        jzfb_disable(jzfb);
945    mutex_unlock(&jzfb->lock);
946
947    return 0;
948}
949
950static int jzfb_resume(struct device *dev)
951{
952    struct jzfb *jzfb = dev_get_drvdata(dev);
953    clk_enable(jzfb->ldclk);
954
955    mutex_lock(&jzfb->lock);
956    if (jzfb->is_enabled)
957        jzfb_enable(jzfb);
958    mutex_unlock(&jzfb->lock);
959
960    console_lock();
961    fb_set_suspend(jzfb->fb, 0);
962    console_unlock();
963
964    return 0;
965}
966
967static const struct dev_pm_ops jzfb_pm_ops = {
968    .suspend = jzfb_suspend,
969    .resume = jzfb_resume,
970    .poweroff = jzfb_suspend,
971    .restore = jzfb_resume,
972};
973
974#define JZFB_PM_OPS (&jzfb_pm_ops)
975
976#else
977#define JZFB_PM_OPS NULL
978#endif
979
980static struct platform_driver jzfb_driver = {
981    .probe = jzfb_probe,
982    .remove = __devexit_p(jzfb_remove),
983    .driver = {
984        .name = "jz4740-fb",
985        .pm = JZFB_PM_OPS,
986    },
987};
988
989static int __init jzfb_init(void)
990{
991    return platform_driver_register(&jzfb_driver);
992}
993module_init(jzfb_init);
994
995static void __exit jzfb_exit(void)
996{
997    platform_driver_unregister(&jzfb_driver);
998}
999module_exit(jzfb_exit);
1000
1001MODULE_LICENSE("GPL");
1002MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>, Maarten ter Huurne <maarten@treewalker.org>");
1003MODULE_DESCRIPTION("JZ4740 SoC SLCD framebuffer driver");
1004MODULE_ALIAS("platform:jz4740-fb");
1005

Archive Download this file



interactive