Root/drivers/video/jz4740_slcd_fb.c

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

Archive Download this file



interactive