]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/video/fsl_diu_fb.c
Merge branch 'master' of git://git.denx.de/u-boot-video
[karo-tx-uboot.git] / drivers / video / fsl_diu_fb.c
index 0709849048fafd399787231b95aec1fdcc8270e4..a98cb67e47a1edf212baa0b9c2dd44a79e4ec17f 100644 (file)
 #include "videomodes.h"
 #include <video_fb.h>
 #include <fsl_diu_fb.h>
-
-struct fb_var_screeninfo {
-       unsigned int xres;              /* visible resolution           */
-       unsigned int yres;
-
-       unsigned int bits_per_pixel;    /* guess what                   */
-
-       /* Timing: All values in pixclocks, except pixclock (of course) */
-       unsigned int pixclock;          /* pixel clock in ps (pico seconds) */
-       unsigned int left_margin;       /* time from sync to picture    */
-       unsigned int right_margin;      /* time from picture to sync    */
-       unsigned int upper_margin;      /* time from sync to picture    */
-       unsigned int lower_margin;
-       unsigned int hsync_len;         /* length of horizontal sync    */
-       unsigned int vsync_len;         /* length of vertical sync      */
-       unsigned int sync;              /* see FB_SYNC_*                */
-       unsigned int vmode;             /* see FB_VMODE_*               */
-       unsigned int rotate;            /* angle we rotate counter clockwise */
-};
-
-struct fb_info {
-       struct fb_var_screeninfo var;   /* Current var */
-       unsigned int smem_len;          /* Length of frame buffer mem */
-       unsigned int type;              /* see FB_TYPE_*                */
-       unsigned int line_length;       /* length of a line in bytes    */
-
-       void *screen_base;
-       unsigned long screen_size;
-};
-
-struct fb_videomode {
-       const char *name;       /* optional */
-       unsigned int refresh;           /* optional */
-       unsigned int xres;
-       unsigned int yres;
-       unsigned int pixclock;
-       unsigned int left_margin;
-       unsigned int right_margin;
-       unsigned int upper_margin;
-       unsigned int lower_margin;
-       unsigned int hsync_len;
-       unsigned int vsync_len;
-       unsigned int sync;
-       unsigned int vmode;
-       unsigned int flag;
-};
-
-#define FB_SYNC_VERT_HIGH_ACT  2       /* vertical sync high active    */
-#define FB_SYNC_COMP_HIGH_ACT  8       /* composite sync high active   */
-#define FB_VMODE_NONINTERLACED  0      /* non interlaced */
+#include <linux/list.h>
+#include <linux/fb.h>
 
 /* This setting is used for the ifm pdm360ng with PRIMEVIEW PM070WL3 */
-static struct fb_videomode fsl_diu_mode_800 = {
-       .name           = "800x600-60",
+static struct fb_videomode fsl_diu_mode_800_480 = {
+       .name           = "800x480-60",
        .refresh        = 60,
        .xres           = 800,
        .yres           = 480,
@@ -99,13 +51,30 @@ static struct fb_videomode fsl_diu_mode_800 = {
        .vmode          = FB_VMODE_NONINTERLACED
 };
 
+/* For the SHARP LQ084S3LG01, used on the P1022DS board */
+static struct fb_videomode fsl_diu_mode_800_600 = {
+       .name           = "800x600-60",
+       .refresh        = 60,
+       .xres           = 800,
+       .yres           = 600,
+       .pixclock       = 25000,
+       .left_margin    = 88,
+       .right_margin   = 40,
+       .upper_margin   = 23,
+       .lower_margin   = 1,
+       .hsync_len      = 128,
+       .vsync_len      = 4,
+       .sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+       .vmode          = FB_VMODE_NONINTERLACED
+};
+
 /*
  * These parameters give default parameters
  * for video output 1024x768,
  * FIXME - change timing to proper amounts
  * hsync 31.5kHz, vsync 60Hz
  */
-static struct fb_videomode fsl_diu_mode_1024 = {
+static struct fb_videomode fsl_diu_mode_1024_768 = {
        .name           = "1024x768-60",
        .refresh        = 60,
        .xres           = 1024,
@@ -121,7 +90,7 @@ static struct fb_videomode fsl_diu_mode_1024 = {
        .vmode          = FB_VMODE_NONINTERLACED
 };
 
-static struct fb_videomode fsl_diu_mode_1280 = {
+static struct fb_videomode fsl_diu_mode_1280_1024 = {
        .name           = "1280x1024-60",
        .refresh        = 60,
        .xres           = 1280,
@@ -137,6 +106,38 @@ static struct fb_videomode fsl_diu_mode_1280 = {
        .vmode          = FB_VMODE_NONINTERLACED
 };
 
+static struct fb_videomode fsl_diu_mode_1280_720 = {
+       .name           = "1280x720-60",
+       .refresh        = 60,
+       .xres           = 1280,
+       .yres           = 720,
+       .pixclock       = 13426,
+       .left_margin    = 192,
+       .right_margin   = 64,
+       .upper_margin   = 22,
+       .lower_margin   = 1,
+       .hsync_len      = 136,
+       .vsync_len      = 3,
+       .sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+       .vmode          = FB_VMODE_NONINTERLACED
+};
+
+static struct fb_videomode fsl_diu_mode_1920_1080 = {
+       .name           = "1920x1080-60",
+       .refresh        = 60,
+       .xres           = 1920,
+       .yres           = 1080,
+       .pixclock       = 5787,
+       .left_margin    = 328,
+       .right_margin   = 120,
+       .upper_margin   = 34,
+       .lower_margin   = 1,
+       .hsync_len      = 208,
+       .vsync_len      = 3,
+       .sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+       .vmode          = FB_VMODE_NONINTERLACED
+};
+
 /*
  * These are the fields of area descriptor(in DDR memory) for every plane
  */
@@ -235,7 +236,7 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
  * point to the framebuffer memory. Memory is aligned as needed.
  */
 static struct diu_ad *allocate_fb(unsigned int xres, unsigned int yres,
-                                 unsigned int depth, void **fb)
+                                 unsigned int depth, char **fb)
 {
        unsigned long size = xres * yres * depth;
        struct diu_addr addr;
@@ -263,35 +264,42 @@ static struct diu_ad *allocate_fb(unsigned int xres, unsigned int yres,
        return ad;
 }
 
-int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix)
+int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix)
 {
        struct fb_videomode *fsl_diu_mode_db;
        struct diu_ad *ad;
        struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR;
        u8 *gamma_table_base;
        unsigned int i, j;
-       struct diu_ad *dummy_ad;
        struct diu_addr gamma;
        struct diu_addr cursor;
 
-       switch (xres) {
-       case 800:
-               fsl_diu_mode_db = &fsl_diu_mode_800;
+/* Convert the X,Y resolution pair into a single number */
+#define RESOLUTION(x, y) (((u32)(x) << 16) | (y))
+
+       switch (RESOLUTION(xres, yres)) {
+       case RESOLUTION(800, 480):
+               fsl_diu_mode_db = &fsl_diu_mode_800_480;
+               break;
+       case RESOLUTION(800, 600):
+               fsl_diu_mode_db = &fsl_diu_mode_800_600;
+               break;
+       case RESOLUTION(1024, 768):
+               fsl_diu_mode_db = &fsl_diu_mode_1024_768;
+               break;
+       case RESOLUTION(1280, 1024):
+               fsl_diu_mode_db = &fsl_diu_mode_1280_1024;
                break;
-       case 1280:
-               fsl_diu_mode_db = &fsl_diu_mode_1280;
+       case RESOLUTION(1280, 720):
+               fsl_diu_mode_db = &fsl_diu_mode_1280_720;
+               break;
+       case RESOLUTION(1920, 1080):
+               fsl_diu_mode_db = &fsl_diu_mode_1920_1080;
                break;
        default:
-               fsl_diu_mode_db = &fsl_diu_mode_1024;
-       }
-
-       /* The AD struct for the dummy framebuffer and the FB itself */
-       dummy_ad = allocate_fb(2, 4, 4, NULL);
-       if (!dummy_ad) {
-               printf("DIU:   Out of memory\n");
+               printf("DIU:   Unsupported resolution %ux%u\n", xres, yres);
                return -1;
        }
-       dummy_ad->pix_fmt = 0x88883316;
 
        /* read mode info */
        info.var.xres = fsl_diu_mode_db->xres;
@@ -306,10 +314,10 @@ int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix)
        info.var.vsync_len = fsl_diu_mode_db->vsync_len;
        info.var.sync = fsl_diu_mode_db->sync;
        info.var.vmode = fsl_diu_mode_db->vmode;
-       info.line_length = info.var.xres * info.var.bits_per_pixel / 8;
+       info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8;
 
        /* Memory allocation for framebuffer */
-       info.smem_len =
+       info.screen_size =
                info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
        ad = allocate_fb(info.var.xres, info.var.yres,
                         info.var.bits_per_pixel / 8, &info.screen_base);
@@ -359,10 +367,7 @@ int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix)
        out_be32(&hw->gamma, gamma.paddr);
        out_be32(&hw->cursor, cursor.paddr);
        out_be32(&hw->bgnd, 0x007F7F7F);
-       out_be32(&hw->bgnd_wb, 0);
        out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres);
-       out_be32(&hw->wb_size, 0);
-       out_be32(&hw->wb_mem_addr, 0);
        out_be32(&hw->hsyn_para, info.var.left_margin << 22 |
                        info.var.hsync_len << 11 |
                        info.var.right_margin);
@@ -371,18 +376,13 @@ int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix)
                        info.var.vsync_len << 11 |
                        info.var.lower_margin);
 
-       out_be32(&hw->syn_pol, 0);
-       out_be32(&hw->thresholds, 0x00037800);
-       out_be32(&hw->int_status, 0);
-       out_be32(&hw->int_mask, 0);
-       out_be32(&hw->plut, 0x01F5F666);
        /* Pixel Clock configuration */
        diu_set_pixel_clock(info.var.pixclock);
 
        /* Set the frame buffers */
        out_be32(&hw->desc[0], virt_to_phys(ad));
-       out_be32(&hw->desc[1], virt_to_phys(dummy_ad));
-       out_be32(&hw->desc[2], virt_to_phys(dummy_ad));
+       out_be32(&hw->desc[1], 0);
+       out_be32(&hw->desc[2], 0);
 
        /* Enable the DIU, set display to all three planes */
        out_be32(&hw->diu_mode, 1);