rewrite rd
[safe/jmp/linux-2.6] / drivers / video / pxafb.c
index bbb0710..10f912d 100644 (file)
 #include <linux/cpufreq.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/err.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/uaccess.h>
 #include <asm/div64.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/bitfield.h>
 #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP|LCCR3_VSP|LCCR3_PCD|LCCR3_BPP)
 
 static void (*pxafb_backlight_power)(int);
-static void (*pxafb_lcd_power)(int);
+static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 
 static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *);
 static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
 
 #ifdef CONFIG_FB_PXA_PARAMETERS
 #define PXAFB_OPTIONS_SIZE 256
-static char g_options[PXAFB_OPTIONS_SIZE] __initdata = "";
+static char g_options[PXAFB_OPTIONS_SIZE] __devinitdata = "";
 #endif
 
 static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state)
@@ -106,20 +107,38 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
                       u_int trans, struct fb_info *info)
 {
        struct pxafb_info *fbi = (struct pxafb_info *)info;
-       u_int val, ret = 1;
+       u_int val;
 
-       if (regno < fbi->palette_size) {
-               if (fbi->fb.var.grayscale) {
-                       val = ((blue >> 8) & 0x00ff);
-               } else {
-                       val  = ((red   >>  0) & 0xf800);
-                       val |= ((green >>  5) & 0x07e0);
-                       val |= ((blue  >> 11) & 0x001f);
-               }
+       if (regno >= fbi->palette_size)
+               return 1;
+
+       if (fbi->fb.var.grayscale) {
+               fbi->palette_cpu[regno] = ((blue >> 8) & 0x00ff);
+               return 0;
+       }
+
+       switch (fbi->lccr4 & LCCR4_PAL_FOR_MASK) {
+       case LCCR4_PAL_FOR_0:
+               val  = ((red   >>  0) & 0xf800);
+               val |= ((green >>  5) & 0x07e0);
+               val |= ((blue  >> 11) & 0x001f);
                fbi->palette_cpu[regno] = val;
-               ret = 0;
+               break;
+       case LCCR4_PAL_FOR_1:
+               val  = ((red   << 8) & 0x00f80000);
+               val |= ((green >> 0) & 0x0000fc00);
+               val |= ((blue  >> 8) & 0x000000f8);
+               ((u32*)(fbi->palette_cpu))[regno] = val;
+               break;
+       case LCCR4_PAL_FOR_2:
+               val  = ((red   << 8) & 0x00fc0000);
+               val |= ((green >> 0) & 0x0000fc00);
+               val |= ((blue  >> 8) & 0x000000fc);
+               ((u32*)(fbi->palette_cpu))[regno] = val;
+               break;
        }
-       return ret;
+
+       return 0;
 }
 
 static int
@@ -214,6 +233,48 @@ extern unsigned int get_clk_frequency_khz(int info);
 #endif
 
 /*
+ * Select the smallest mode that allows the desired resolution to be
+ * displayed. If desired parameters can be rounded up.
+ */
+static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struct fb_var_screeninfo *var)
+{
+       struct pxafb_mode_info *mode = NULL;
+       struct pxafb_mode_info *modelist = mach->modes;
+       unsigned int best_x = 0xffffffff, best_y = 0xffffffff;
+       unsigned int i;
+
+       for (i = 0 ; i < mach->num_modes ; i++) {
+               if (modelist[i].xres >= var->xres && modelist[i].yres >= var->yres &&
+                               modelist[i].xres < best_x && modelist[i].yres < best_y &&
+                               modelist[i].bpp >= var->bits_per_pixel ) {
+                       best_x = modelist[i].xres;
+                       best_y = modelist[i].yres;
+                       mode = &modelist[i];
+               }
+       }
+
+       return mode;
+}
+
+static void pxafb_setmode(struct fb_var_screeninfo *var, struct pxafb_mode_info *mode)
+{
+       var->xres               = mode->xres;
+       var->yres               = mode->yres;
+       var->bits_per_pixel     = mode->bpp;
+       var->pixclock           = mode->pixclock;
+       var->hsync_len          = mode->hsync_len;
+       var->left_margin        = mode->left_margin;
+       var->right_margin       = mode->right_margin;
+       var->vsync_len          = mode->vsync_len;
+       var->upper_margin       = mode->upper_margin;
+       var->lower_margin       = mode->lower_margin;
+       var->sync               = mode->sync;
+       var->grayscale          = mode->cmap_greyscale;
+       var->xres_virtual       = var->xres;
+       var->yres_virtual       = var->yres;
+}
+
+/*
  *  pxafb_check_var():
  *    Get the video params out of 'var'. If a value doesn't fit, round it up,
  *    if it's too big, return -EINVAL.
@@ -225,15 +286,29 @@ extern unsigned int get_clk_frequency_khz(int info);
 static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct pxafb_info *fbi = (struct pxafb_info *)info;
+       struct pxafb_mach_info *inf = fbi->dev->platform_data;
 
        if (var->xres < MIN_XRES)
                var->xres = MIN_XRES;
        if (var->yres < MIN_YRES)
                var->yres = MIN_YRES;
-       if (var->xres > fbi->max_xres)
-               return -EINVAL;
-       if (var->yres > fbi->max_yres)
-               return -EINVAL;
+
+       if (inf->fixed_modes) {
+               struct pxafb_mode_info *mode;
+
+               mode = pxafb_getmode(inf, var);
+               if (!mode)
+                       return -EINVAL;
+               pxafb_setmode(var, mode);
+       } else {
+               if (var->xres > inf->modes->xres)
+                       return -EINVAL;
+               if (var->yres > inf->modes->yres)
+                       return -EINVAL;
+               if (var->bits_per_pixel > inf->modes->bpp)
+                       return -EINVAL;
+       }
+
        var->xres_virtual =
                max(var->xres_virtual, var->xres);
        var->yres_virtual =
@@ -305,7 +380,10 @@ static int pxafb_set_par(struct fb_info *info)
        else
                fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
 
-       palette_mem_size = fbi->palette_size * sizeof(u16);
+       if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+               palette_mem_size = fbi->palette_size * sizeof(u16);
+       else
+               palette_mem_size = fbi->palette_size * sizeof(u32);
 
        pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
 
@@ -450,15 +528,15 @@ static struct fb_ops pxafb_ops = {
  *
  * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below.
  */
-static inline unsigned int get_pcd(unsigned int pixclock)
+static inline unsigned int get_pcd(struct pxafb_info *fbi, unsigned int pixclock)
 {
        unsigned long long pcd;
 
        /* FIXME: Need to take into account Double Pixel Clock mode
-         * (DPC) bit? or perhaps set it based on the various clock
-         * speeds */
-
-       pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
+        * (DPC) bit? or perhaps set it based on the various clock
+        * speeds */
+       pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000);
+       pcd *= pixclock;
        do_div(pcd, 100000000 * 2);
        /* no need for this, since we should subtract 1 anyway. they cancel */
        /* pcd += 1; */ /* make up for integer math truncations */
@@ -467,19 +545,21 @@ static inline unsigned int get_pcd(unsigned int pixclock)
 
 /*
  * Some touchscreens need hsync information from the video driver to
- * function correctly. We export it here.
+ * function correctly. We export it here.  Note that 'hsync_time' and
+ * the value returned from pxafb_get_hsync_time() is the *reciprocal*
+ * of the hsync period in seconds.
  */
 static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd)
 {
-       unsigned long long htime;
+       unsigned long htime;
 
        if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
                fbi->hsync_time=0;
                return;
        }
 
-       htime = (unsigned long long)get_lcdclk_frequency_10khz() * 10000;
-       do_div(htime, pcd * fbi->fb.var.hsync_len);
+       htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len);
+
        fbi->hsync_time = htime;
 }
 
@@ -504,7 +584,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
 {
        struct pxafb_lcd_reg new_regs;
        u_long flags;
-       u_int lines_per_panel, pcd = get_pcd(var->pixclock);
+       u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
 
        pr_debug("pxafb: Configuring PXA LCD\n");
 
@@ -620,7 +700,13 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
 
        fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma;
        fbi->dmadesc_palette_cpu->fidr  = 0;
-       fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
+       if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+               fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
+                                                       sizeof(u16);
+       else
+               fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
+                                                       sizeof(u32);
+       fbi->dmadesc_palette_cpu->ldcmd |= LDCMD_PAL;
 
        if (var->bits_per_pixel == 16) {
                /* palette shouldn't be loaded in true-color mode */
@@ -659,6 +745,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
        fbi->reg_lccr1 = new_regs.lccr1;
        fbi->reg_lccr2 = new_regs.lccr2;
        fbi->reg_lccr3 = new_regs.lccr3;
+       fbi->reg_lccr4 = LCCR4 & (~LCCR4_PAL_FOR_MASK);
+       fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
        set_hsync_time(fbi, pcd);
        local_irq_restore(flags);
 
@@ -693,7 +781,7 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
        pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff");
 
        if (pxafb_lcd_power)
-               pxafb_lcd_power(on);
+               pxafb_lcd_power(on, &fbi->fb.var);
 }
 
 static void pxafb_setup_gpio(struct pxafb_info *fbi)
@@ -747,7 +835,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
        pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
 
        /* enable LCD controller clock */
-       pxa_set_cken(CKEN16_LCD, 1);
+       clk_enable(fbi->clk);
 
        /* Sequence from 11.7.10 */
        LCCR3 = fbi->reg_lccr3;
@@ -765,6 +853,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
        pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
        pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
        pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
+       pr_debug("LCCR4 0x%08x\n", (unsigned int) LCCR4);
 }
 
 static void pxafb_disable_controller(struct pxafb_info *fbi)
@@ -784,13 +873,13 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
        remove_wait_queue(&fbi->ctrlr_wait, &wait);
 
        /* disable LCD controller clock */
-       pxa_set_cken(CKEN16_LCD, 0);
+       clk_disable(fbi->clk);
 }
 
 /*
  *  pxafb_handle_irq: Handle 'LCD DONE' interrupts.
  */
-static irqreturn_t pxafb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pxafb_handle_irq(int irq, void *dev_id)
 {
        struct pxafb_info *fbi = dev_id;
        unsigned int lcsr = LCSR;
@@ -869,9 +958,11 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
                 * registers.
                 */
                if (old_state == C_ENABLE) {
+                       __pxafb_lcd_power(fbi, 0);
                        pxafb_disable_controller(fbi);
                        pxafb_setup_gpio(fbi);
                        pxafb_enable_controller(fbi);
+                       __pxafb_lcd_power(fbi, 1);
                }
                break;
 
@@ -906,9 +997,10 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
  * Our LCD controller task (which is called when we blank or unblank)
  * via keventd.
  */
-static void pxafb_task(void *dummy)
+static void pxafb_task(struct work_struct *work)
 {
-       struct pxafb_info *fbi = dummy;
+       struct pxafb_info *fbi =
+               container_of(work, struct pxafb_info, task);
        u_int state = xchg(&fbi->task_state, -1);
 
        set_ctrlr_state(fbi, state);
@@ -935,7 +1027,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
                break;
 
        case CPUFREQ_POSTCHANGE:
-               pcd = get_pcd(fbi->fb.var.pixclock);
+               pcd = get_pcd(fbi, fbi->fb.var.pixclock);
                set_hsync_time(fbi, pcd);
                fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
                set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
@@ -1031,10 +1123,13 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
                 * dma_writecombine_mmap)
                 */
                fbi->fb.fix.smem_start = fbi->screen_dma;
-
                fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
 
-               palette_mem_size = fbi->palette_size * sizeof(u16);
+               if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+                       palette_mem_size = fbi->palette_size * sizeof(u16);
+               else
+                       palette_mem_size = fbi->palette_size * sizeof(u32);
+
                pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
 
                fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
@@ -1049,6 +1144,8 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        struct pxafb_info *fbi;
        void *addr;
        struct pxafb_mach_info *inf = dev->platform_data;
+       struct pxafb_mode_info *mode = inf->modes;
+       int i, smemlen;
 
        /* Alloc the pxafb_info and pseudo_palette in one step */
        fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
@@ -1058,6 +1155,12 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        memset(fbi, 0, sizeof(struct pxafb_info));
        fbi->dev = dev;
 
+       fbi->clk = clk_get(dev, "LCDCLK");
+       if (IS_ERR(fbi->clk)) {
+               kfree(fbi);
+               return NULL;
+       }
+
        strcpy(fbi->fb.fix.id, PXA_NAME);
 
        fbi->fb.fix.type        = FB_TYPE_PACKED_PIXELS;
@@ -1082,34 +1185,25 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        addr = addr + sizeof(struct pxafb_info);
        fbi->fb.pseudo_palette  = addr;
 
-       fbi->max_xres                   = inf->xres;
-       fbi->fb.var.xres                = inf->xres;
-       fbi->fb.var.xres_virtual        = inf->xres;
-       fbi->max_yres                   = inf->yres;
-       fbi->fb.var.yres                = inf->yres;
-       fbi->fb.var.yres_virtual        = inf->yres;
-       fbi->max_bpp                    = inf->bpp;
-       fbi->fb.var.bits_per_pixel      = inf->bpp;
-       fbi->fb.var.pixclock            = inf->pixclock;
-       fbi->fb.var.hsync_len           = inf->hsync_len;
-       fbi->fb.var.left_margin         = inf->left_margin;
-       fbi->fb.var.right_margin        = inf->right_margin;
-       fbi->fb.var.vsync_len           = inf->vsync_len;
-       fbi->fb.var.upper_margin        = inf->upper_margin;
-       fbi->fb.var.lower_margin        = inf->lower_margin;
-       fbi->fb.var.sync                = inf->sync;
-       fbi->fb.var.grayscale           = inf->cmap_greyscale;
+       pxafb_setmode(&fbi->fb.var, mode);
+
        fbi->cmap_inverse               = inf->cmap_inverse;
        fbi->cmap_static                = inf->cmap_static;
+
        fbi->lccr0                      = inf->lccr0;
        fbi->lccr3                      = inf->lccr3;
+       fbi->lccr4                      = inf->lccr4;
        fbi->state                      = C_STARTUP;
        fbi->task_state                 = (u_char)-1;
-       fbi->fb.fix.smem_len            = fbi->max_xres * fbi->max_yres *
-                                         fbi->max_bpp / 8;
+
+       for (i = 0; i < inf->num_modes; i++) {
+               smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8;
+               if (smemlen > fbi->fb.fix.smem_len)
+                       fbi->fb.fix.smem_len = smemlen;
+       }
 
        init_waitqueue_head(&fbi->ctrlr_wait);
-       INIT_WORK(&fbi->task, pxafb_task, fbi);
+       INIT_WORK(&fbi->task, pxafb_task);
        init_MUTEX(&fbi->ctrlr_sem);
 
        return fbi;
@@ -1152,7 +1246,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                        } else
                                                goto done;
                                        break;
-                               case '0'...'9':
+                               case '0' ... '9':
                                        break;
                                default:
                                        goto done;
@@ -1165,7 +1259,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                done:
                        if (res_specified) {
                                dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
-                               inf->xres = xres; inf->yres = yres;
+                               inf->modes[0].xres = xres; inf->modes[0].yres = yres;
                        }
                        if (bpp_specified)
                                switch (bpp) {
@@ -1174,48 +1268,48 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
                                case 4:
                                case 8:
                                case 16:
-                                       inf->bpp = bpp;
+                                       inf->modes[0].bpp = bpp;
                                        dev_info(dev, "overriding bit depth: %d\n", bpp);
                                        break;
                                default:
                                        dev_err(dev, "Depth %d is not valid\n", bpp);
                                }
                 } else if (!strncmp(this_opt, "pixclock:", 9)) {
-                        inf->pixclock = simple_strtoul(this_opt+9, NULL, 0);
-                       dev_info(dev, "override pixclock: %ld\n", inf->pixclock);
+                        inf->modes[0].pixclock = simple_strtoul(this_opt+9, NULL, 0);
+                       dev_info(dev, "override pixclock: %ld\n", inf->modes[0].pixclock);
                 } else if (!strncmp(this_opt, "left:", 5)) {
-                        inf->left_margin = simple_strtoul(this_opt+5, NULL, 0);
-                       dev_info(dev, "override left: %u\n", inf->left_margin);
+                        inf->modes[0].left_margin = simple_strtoul(this_opt+5, NULL, 0);
+                       dev_info(dev, "override left: %u\n", inf->modes[0].left_margin);
                 } else if (!strncmp(this_opt, "right:", 6)) {
-                        inf->right_margin = simple_strtoul(this_opt+6, NULL, 0);
-                       dev_info(dev, "override right: %u\n", inf->right_margin);
+                        inf->modes[0].right_margin = simple_strtoul(this_opt+6, NULL, 0);
+                       dev_info(dev, "override right: %u\n", inf->modes[0].right_margin);
                 } else if (!strncmp(this_opt, "upper:", 6)) {
-                        inf->upper_margin = simple_strtoul(this_opt+6, NULL, 0);
-                       dev_info(dev, "override upper: %u\n", inf->upper_margin);
+                        inf->modes[0].upper_margin = simple_strtoul(this_opt+6, NULL, 0);
+                       dev_info(dev, "override upper: %u\n", inf->modes[0].upper_margin);
                 } else if (!strncmp(this_opt, "lower:", 6)) {
-                        inf->lower_margin = simple_strtoul(this_opt+6, NULL, 0);
-                       dev_info(dev, "override lower: %u\n", inf->lower_margin);
+                        inf->modes[0].lower_margin = simple_strtoul(this_opt+6, NULL, 0);
+                       dev_info(dev, "override lower: %u\n", inf->modes[0].lower_margin);
                 } else if (!strncmp(this_opt, "hsynclen:", 9)) {
-                        inf->hsync_len = simple_strtoul(this_opt+9, NULL, 0);
-                       dev_info(dev, "override hsynclen: %u\n", inf->hsync_len);
+                        inf->modes[0].hsync_len = simple_strtoul(this_opt+9, NULL, 0);
+                       dev_info(dev, "override hsynclen: %u\n", inf->modes[0].hsync_len);
                 } else if (!strncmp(this_opt, "vsynclen:", 9)) {
-                        inf->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
-                       dev_info(dev, "override vsynclen: %u\n", inf->vsync_len);
+                        inf->modes[0].vsync_len = simple_strtoul(this_opt+9, NULL, 0);
+                       dev_info(dev, "override vsynclen: %u\n", inf->modes[0].vsync_len);
                 } else if (!strncmp(this_opt, "hsync:", 6)) {
                         if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
                                dev_info(dev, "override hsync: Active Low\n");
-                               inf->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+                               inf->modes[0].sync &= ~FB_SYNC_HOR_HIGH_ACT;
                        } else {
                                dev_info(dev, "override hsync: Active High\n");
-                               inf->sync |= FB_SYNC_HOR_HIGH_ACT;
+                               inf->modes[0].sync |= FB_SYNC_HOR_HIGH_ACT;
                        }
                 } else if (!strncmp(this_opt, "vsync:", 6)) {
                         if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
                                dev_info(dev, "override vsync: Active Low\n");
-                               inf->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+                               inf->modes[0].sync &= ~FB_SYNC_VERT_HIGH_ACT;
                        } else {
                                dev_info(dev, "override vsync: Active High\n");
-                               inf->sync |= FB_SYNC_VERT_HIGH_ACT;
+                               inf->modes[0].sync |= FB_SYNC_VERT_HIGH_ACT;
                        }
                 } else if (!strncmp(this_opt, "dpc:", 4)) {
                         if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
@@ -1307,12 +1401,12 @@ int __init pxafb_probe(struct platform_device *dev)
            (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                 dev_warn(&dev->dev, "Dual panel only valid in passive mode\n");
         if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
-             (inf->upper_margin || inf->lower_margin))
+             (inf->modes->upper_margin || inf->modes->lower_margin))
                 dev_warn(&dev->dev, "Upper and lower margins must be 0 in passive mode\n");
 #endif
 
-       dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->xres, inf->yres, inf->bpp);
-       if (inf->xres == 0 || inf->yres == 0 || inf->bpp == 0) {
+       dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->modes->xres, inf->modes->yres, inf->modes->bpp);
+       if (inf->modes->xres == 0 || inf->modes->yres == 0 || inf->modes->bpp == 0) {
                dev_err(&dev->dev, "Invalid resolution or bit depth\n");
                ret = -EINVAL;
                goto failed;