Date:2012-05-03 00:36:49 (11 years 10 months ago)
Author:Maarten ter Huurne
Commit:12646726222a1d018095415b3022dca519526f3d
Message:MIPS: JZ4740: SLCD: In TV-out mode, add a black line on top and bottom

The bottom line ensures that the border color will be black instead of
whatever color the bottom-right pixel in the framebuffer has.

The top line delays the time that the descriptor for the main display
area is read, allowing vertical panning to be changed until just before
the display is sent to the TV encoder.

Paul Cercueil wrote the first version of this patch.
Files: drivers/video/jz4740_slcd.h (2 diffs)
drivers/video/jz4740_slcd_fb.c (7 diffs)

Change Details

drivers/video/jz4740_slcd.h
7272
7373/*************************************************************************/
7474
75struct jzfb_framedesc {
76    uint32_t next;
77    uint32_t addr;
78    uint32_t id;
79    uint32_t cmd;
80} __attribute__((packed));
81
7582struct jzfb {
7683    struct fb_info *fb;
7784    struct platform_device *pdev;
...... 
8390    size_t vidmem_size;
8491    void *vidmem;
8592    dma_addr_t vidmem_phys;
86    struct jzfb_framedesc *framedesc;
93
94    size_t blackline_size;
95    void *blackline;
96    dma_addr_t blackline_phys;
97
98    struct jzfb_framedesc (*framedesc)[3];
8799    dma_addr_t framedesc_phys;
100
88101    struct jz4740_dma_chan *dma;
89102
90103    struct clk *ldclk;
drivers/video/jz4740_slcd_fb.c
3434#include "jz4740_lcd.h"
3535#include "jz4740_slcd.h"
3636
37struct jzfb_framedesc {
38    uint32_t next;
39    uint32_t addr;
40    uint32_t id;
41    uint32_t cmd;
42} __attribute__((packed));
43
4437static struct fb_fix_screeninfo jzfb_fix __devinitdata = {
4538    .id = "JZ4740 SLCD FB",
4639    .type = FB_TYPE_PACKED_PIXELS,
...... 
506499
507500    info->var.yoffset = var->yoffset;
508501    /* update frame start address for TV-out mode */
509    jzfb->framedesc->addr = jzfb->vidmem_phys
502    (*jzfb->framedesc)[1].addr = jzfb->vidmem_phys
510503                          + info->fix.line_length * var->yoffset;
511504
512505    return 0;
...... 
530523
531524static int jzfb_alloc_devmem(struct jzfb *jzfb)
532525{
533    int max_framesize = 0;
526    int max_linesize = 0, max_framesize = 0;
527    int bytes_per_pixel;
534528    struct fb_videomode *mode = jzfb->pdata->modes;
535529    void *page;
536530    int i;
537531
538532    for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
533        if (max_linesize < mode->xres)
534            max_linesize = mode->xres;
539535        if (max_framesize < mode->xres * mode->yres)
540536            max_framesize = mode->xres * mode->yres;
541537    }
542538
543    max_framesize *= jzfb_get_controller_bpp(jzfb) >> 3;
539    bytes_per_pixel = jzfb_get_controller_bpp(jzfb) >> 3;
540    max_linesize *= bytes_per_pixel;
541    max_framesize *= bytes_per_pixel;
544542
545543    jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
546544                    sizeof(*jzfb->framedesc),
547545                    &jzfb->framedesc_phys, GFP_KERNEL);
548
549546    if (!jzfb->framedesc)
550547        return -ENOMEM;
551548
549    jzfb->blackline_size = max_linesize;
550    jzfb->blackline = dma_alloc_coherent(&jzfb->pdev->dev,
551                         jzfb->blackline_size,
552                         &jzfb->blackline_phys, GFP_KERNEL);
553    if (!jzfb->blackline)
554        goto err_free_framedesc;
555
556    /* Set the black line to black... */
557    memset(jzfb->blackline, 0, jzfb->blackline_size);
558
552559    /* reserve memory for two frames to allow double buffering */
553560    jzfb->vidmem_size = PAGE_ALIGN(max_framesize * 2);
554561    jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
...... 
556563                        &jzfb->vidmem_phys, GFP_KERNEL);
557564
558565    if (!jzfb->vidmem)
559        goto err_free_framedesc;
566        goto err_free_blackline;
560567
561568    for (page = jzfb->vidmem;
562569         page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
...... 
564571        SetPageReserved(virt_to_page(page));
565572    }
566573
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;
574    for (i = 0; i < 3; i++)
575        (*jzfb->framedesc)[i].next = jzfb->framedesc_phys
576                + ((i + 1) % 3) * sizeof(struct jzfb_framedesc);
577    (*jzfb->framedesc)[0].addr = (*jzfb->framedesc)[2].addr =
578            jzfb->blackline_phys;
579    (*jzfb->framedesc)[0].id = 0xdadabeeb;
580    (*jzfb->framedesc)[2].id = 0xfadefeed;
581    (*jzfb->framedesc)[0].cmd = (*jzfb->framedesc)[2].cmd =
582            jzfb->blackline_size / 4;
583    (*jzfb->framedesc)[1].addr = jzfb->vidmem_phys;
584    (*jzfb->framedesc)[1].id = 0xdeafbead;
585    (*jzfb->framedesc)[1].cmd = max_framesize / 4;
572586
573587    return 0;
574588
589err_free_blackline:
590    dma_free_coherent(&jzfb->pdev->dev, jzfb->blackline_size,
591                jzfb->blackline, jzfb->blackline_phys);
575592err_free_framedesc:
576593    dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
577594                jzfb->framedesc, jzfb->framedesc_phys);
...... 
582599{
583600    dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
584601                jzfb->vidmem, jzfb->vidmem_phys);
602    dma_free_coherent(&jzfb->pdev->dev, jzfb->blackline_size,
603                jzfb->blackline, jzfb->blackline_phys);
585604    dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
586605                jzfb->framedesc, jzfb->framedesc_phys);
587606}
...... 
633652            /* horizontal start/end point */
634653            writel(0x02240364, jzfb->base + JZ_REG_LCD_DAH);
635654            /* vertical start/end point */
636            writel(0x001b010b, jzfb->base + JZ_REG_LCD_DAV);
655            writel(0x001a010c, jzfb->base + JZ_REG_LCD_DAV);
637656        } else {
638657            /* NTSC and PAL 60 Hz */
639658            writel(0x0000003c, jzfb->base + JZ_REG_LCD_HSYNC);
640659            writel(0x02e00110, jzfb->base + JZ_REG_LCD_VAT);
641660            writel(0x019902d9, jzfb->base + JZ_REG_LCD_DAH);
642            writel(0x001d010d, jzfb->base + JZ_REG_LCD_DAV);
661            writel(0x001c010e, jzfb->base + JZ_REG_LCD_DAV);
643662        }
644663        writel(0, jzfb->base + JZ_REG_LCD_PS);
645664        writel(0, jzfb->base + JZ_REG_LCD_CLS);

Archive Download the corresponding diff file



interactive