Commit 09fe75f6 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Linus Torvalds

s3c2410fb: multi-display support

This patch adds a new structure to describe and handle
more than one panel (display mode) for the s3c2410 framebuffer.
This structure is added after the pxafb driver.
Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarAntonino Daplas <adaplas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 110c1fa7
...@@ -168,13 +168,32 @@ static void __init amlm5900_map_io(void) ...@@ -168,13 +168,32 @@ static void __init amlm5900_map_io(void)
} }
#ifdef CONFIG_FB_S3C2410 #ifdef CONFIG_FB_S3C2410
static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
.width = 160, .width = 160,
.height = 160, .height = 160,
/* commented out until stn patch is submitted /* commented out until stn patch is submitted
* .type = S3C2410_LCDCON1_STN4, * .type = S3C2410_LCDCON1_STN4,
*/ */
.xres = 160,
.yres = 160,
.bpp = 4,
.regs = {
.lcdcon1 = 0x00008225,
.lcdcon2 = 0x0027c000,
.lcdcon3 = 0x00182708,
.lcdcon4 = 0x00000002,
.lcdcon5 = 0x00000001,
}
};
static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = {
.displays = &amlm5900_lcd_info,
.num_displays = 1,
.default_display = 0,
.gpccon = 0xaaaaaaaa, .gpccon = 0xaaaaaaaa,
.gpccon_mask = 0xffffffff, .gpccon_mask = 0xffffffff,
.gpcup = 0x0000ffff, .gpcup = 0x0000ffff,
...@@ -184,32 +203,6 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { ...@@ -184,32 +203,6 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
.gpdcon_mask = 0xffffffff, .gpdcon_mask = 0xffffffff,
.gpdup = 0x0000ffff, .gpdup = 0x0000ffff,
.gpdup_mask = 0xffffffff, .gpdup_mask = 0xffffffff,
.xres = {
.min = 160,
.max = 160,
.defval = 160,
},
.yres = {
.min = 160,
.max = 160,
.defval = 160,
},
.bpp = {
.min = 4,
.max = 4,
.defval = 4,
},
.regs = {
.lcdcon1 = 0x00008225,
.lcdcon2 = 0x0027c000,
.lcdcon3 = 0x00182708,
.lcdcon4 = 0x00000002,
.lcdcon5 = 0x00000001,
}
}; };
#endif #endif
...@@ -239,7 +232,7 @@ static void __init amlm5900_init(void) ...@@ -239,7 +232,7 @@ static void __init amlm5900_init(void)
{ {
amlm5900_init_pm(); amlm5900_init_pm();
#ifdef CONFIG_FB_S3C2410 #ifdef CONFIG_FB_S3C2410
s3c24xx_fb_set_platdata(&amlm5900_lcd_info); s3c24xx_fb_set_platdata(&amlm5900_fb_info);
#endif #endif
platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
} }
......
...@@ -467,27 +467,142 @@ static struct platform_device bast_device_axpp = { ...@@ -467,27 +467,142 @@ static struct platform_device bast_device_axpp = {
/* LCD/VGA controller */ /* LCD/VGA controller */
static struct s3c2410fb_mach_info __initdata bast_lcd_info = { static struct s3c2410fb_display __initdata bast_lcd_info[] = {
{
.width = 640,
.height = 480,
.xres = 320,
.yres = 240,
.bpp = 4,
.regs = {
.lcdcon1 = 0x00000176,
.lcdcon2 = 0x1d77c7c2,
.lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
},
{
.width = 640,
.height = 480,
.xres = 640,
.yres = 480,
.bpp = 4,
.regs = {
.lcdcon1 = 0x00000176,
.lcdcon2 = 0x1d77c7c2,
.lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
},
{
.width = 640,
.height = 480,
.xres = 800,
.yres = 600,
.bpp = 4,
.regs = {
.lcdcon1 = 0x00000176,
.lcdcon2 = 0x1d77c7c2,
.lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
},
{
.width = 640,
.height = 480,
.xres = 320,
.yres = 240,
.bpp = 8,
.regs = {
.lcdcon1 = 0x00000176,
.lcdcon2 = 0x1d77c7c2,
.lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
},
{
.width = 640, .width = 640,
.height = 480, .height = 480,
.xres = { .xres = 640,
.min = 320, .yres = 480,
.max = 1024, .bpp = 8,
.defval = 640,
.regs = {
.lcdcon1 = 0x00000176,
.lcdcon2 = 0x1d77c7c2,
.lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
}, },
{
.width = 640,
.height = 480,
.yres = { .xres = 800,
.min = 240, .yres = 600,
.max = 600, .bpp = 8,
.defval = 480,
.regs = {
.lcdcon1 = 0x00000176,
.lcdcon2 = 0x1d77c7c2,
.lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
}, },
{
.width = 640,
.height = 480,
.xres = 320,
.yres = 240,
.bpp = 16,
.bpp = { .regs = {
.min = 4, .lcdcon1 = 0x00000176,
.max = 16, .lcdcon2 = 0x1d77c7c2,
.defval = 8, .lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
},
{
.width = 640,
.height = 480,
.xres = 640,
.yres = 480,
.bpp = 16,
.regs = {
.lcdcon1 = 0x00000176,
.lcdcon2 = 0x1d77c7c2,
.lcdcon3 = 0x013a7f13,
.lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
}
}, },
{
.width = 640,
.height = 480,
.xres = 800,
.yres = 600,
.bpp = 16,
.regs = { .regs = {
.lcdcon1 = 0x00000176, .lcdcon1 = 0x00000176,
...@@ -496,6 +611,16 @@ static struct s3c2410fb_mach_info __initdata bast_lcd_info = { ...@@ -496,6 +611,16 @@ static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
.lcdcon4 = 0x00000057, .lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02, .lcdcon5 = 0x00014b02,
} }
},
};
/* LCD/VGA controller */
static struct s3c2410fb_mach_info __initdata bast_fb_info = {
.displays = bast_lcd_info,
.num_displays = ARRAY_SIZE(bast_lcd_info),
.default_display = 4,
}; };
/* Standard BAST devices */ /* Standard BAST devices */
...@@ -552,7 +677,7 @@ static void __init bast_map_io(void) ...@@ -552,7 +677,7 @@ static void __init bast_map_io(void)
static void __init bast_init(void) static void __init bast_init(void)
{ {
s3c24xx_fb_set_platdata(&bast_lcd_info); s3c24xx_fb_set_platdata(&bast_fb_info);
platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
} }
......
...@@ -133,8 +133,7 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = { ...@@ -133,8 +133,7 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
/** /**
* Set lcd on or off * Set lcd on or off
**/ **/
static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = { static struct s3c2410fb_display h1940_lcd __initdata = {
.fixed_syncs= 1,
.regs={ .regs={
.lcdcon1= S3C2410_LCDCON1_TFT16BPP | \ .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \
S3C2410_LCDCON1_TFT | \ S3C2410_LCDCON1_TFT | \
...@@ -156,6 +155,21 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = { ...@@ -156,6 +155,21 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
S3C2410_LCDCON5_INVVLINE | \ S3C2410_LCDCON5_INVVLINE | \
S3C2410_LCDCON5_HWSWP, S3C2410_LCDCON5_HWSWP,
}, },
.width = 240,
.height = 320,
.xres = 240,
.yres = 320,
.bpp = 16,
};
static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
.fixed_syncs = 1,
.displays = &h1940_lcd,
.num_displays = 1,
.default_display = 0,
.lpcsel= 0x02, .lpcsel= 0x02,
.gpccon= 0xaa940659, .gpccon= 0xaa940659,
.gpccon_mask= 0xffffffff, .gpccon_mask= 0xffffffff,
...@@ -165,12 +179,6 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = { ...@@ -165,12 +179,6 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
.gpdcon_mask= 0xffffffff, .gpdcon_mask= 0xffffffff,
.gpdup= 0x0000faff, .gpdup= 0x0000faff,
.gpdup_mask= 0xffffffff, .gpdup_mask= 0xffffffff,
.width= 240,
.height= 320,
.xres= {240,240,240},
.yres= {320,320,320},
.bpp= {16,16,16},
}; };
static struct platform_device s3c_device_leds = { static struct platform_device s3c_device_leds = {
...@@ -217,7 +225,7 @@ static void __init h1940_init(void) ...@@ -217,7 +225,7 @@ static void __init h1940_init(void)
{ {
u32 tmp; u32 tmp;
s3c24xx_fb_set_platdata(&h1940_lcdcfg); s3c24xx_fb_set_platdata(&h1940_fb_info);
s3c24xx_udc_set_platdata(&h1940_udc_cfg); s3c24xx_udc_set_platdata(&h1940_udc_cfg);
/* Turn off suspend on both USB ports, and switch the /* Turn off suspend on both USB ports, and switch the
......
...@@ -95,8 +95,9 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = { ...@@ -95,8 +95,9 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
/* LCD driver info */ /* LCD driver info */
/* Configuration for 640x480 SHARP LQ080V3DG01 */ static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = { {
/* Configuration for 640x480 SHARP LQ080V3DG01 */
.regs = { .regs = {
.lcdcon1 = S3C2410_LCDCON1_TFT16BPP | .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
...@@ -122,32 +123,15 @@ static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = { ...@@ -122,32 +123,15 @@ static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = {
S3C2410_LCDCON5_HWSWP, S3C2410_LCDCON5_HWSWP,
}, },
.lpcsel = ((0xCE6) & ~7) | 1<<4,
.width = 640, .width = 640,
.height = 480, .height = 480,
.xres = { .xres = 640,
.min = 640, .yres = 480,
.max = 640, .bpp = 16,
.defval = 640,
},
.yres = {
.min = 480,
.max = 480,
.defval = 480,
}, },
{
.bpp = { /* Configuration for 480x640 toppoly TD028TTEC1 */
.min = 16,
.max = 16,
.defval = 16,
},
};
/* Configuration for 480x640 toppoly TD028TTEC1 */
static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
.regs = { .regs = {
.lcdcon1 = S3C2410_LCDCON1_TFT16BPP | .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
...@@ -173,32 +157,14 @@ static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = { ...@@ -173,32 +157,14 @@ static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
S3C2410_LCDCON5_HWSWP, S3C2410_LCDCON5_HWSWP,
}, },
.lpcsel = ((0xCE6) & ~7) | 1<<4,
.width = 480, .width = 480,
.height = 640, .height = 640,
.xres = 480,
.xres = { .yres = 640,
.min = 480, .bpp = 16,
.max = 480,
.defval = 480,
},
.yres = {
.min = 640,
.max = 640,
.defval = 640,
}, },
{
.bpp = { /* Config for 240x320 LCD */
.min = 16,
.max = 16,
.defval = 16,
},
};
/* Config for 240x320 LCD */
static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
.regs = { .regs = {
.lcdcon1 = S3C2410_LCDCON1_TFT16BPP | .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
...@@ -224,28 +190,21 @@ static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = { ...@@ -224,28 +190,21 @@ static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
S3C2410_LCDCON5_HWSWP, S3C2410_LCDCON5_HWSWP,
}, },
.lpcsel = ((0xCE6) & ~7) | 1<<4,
.width = 240, .width = 240,
.height = 320, .height = 320,
.xres = 240,
.xres = { .yres = 320,
.min = 240, .bpp = 16,
.max = 240,
.defval = 240,
}, },
};
.yres = {
.min = 320,
.max = 320,
.defval = 320,
},
.bpp = { static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
.min = 16, .displays = qt2410_lcd_cfg,
.max = 16, .num_displays = ARRAY_SIZE(qt2410_lcd_cfg),
.defval = 16, .default_display = 0,
},
.lpcsel = ((0xCE6) & ~7) | 1<<4,
}; };
/* CS8900 */ /* CS8900 */
...@@ -408,16 +367,17 @@ static void __init qt2410_machine_init(void) ...@@ -408,16 +367,17 @@ static void __init qt2410_machine_init(void)
switch (tft_type) { switch (tft_type) {
case 'p': /* production */ case 'p': /* production */
s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg); qt2410_fb_info.default_display = 1;
break; break;
case 'b': /* big */ case 'b': /* big */
s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg); qt2410_fb_info.default_display = 0;
break; break;
case 's': /* small */ case 's': /* small */
default: default:
s3c24xx_fb_set_platdata(&qt2410_lcd_cfg); qt2410_fb_info.default_display = 2;
break; break;
} }
s3c24xx_fb_set_platdata(&qt2410_fb_info);
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT); s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB0, 1); s3c2410_gpio_setpin(S3C2410_GPB0, 1);
......
...@@ -110,7 +110,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { ...@@ -110,7 +110,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
/* framebuffer lcd controller information */ /* framebuffer lcd controller information */
static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { static struct s3c2410fb_display rx3715_lcdcfg __initdata = {
.regs = { .regs = {
.lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \ .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \
S3C2410_LCDCON1_TFT | \ S3C2410_LCDCON1_TFT | \
...@@ -133,6 +133,20 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { ...@@ -133,6 +133,20 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
S3C2410_LCDCON5_HWSWP, S3C2410_LCDCON5_HWSWP,
}, },
.width = 240,
.height = 320,
.xres = 240,
.yres = 320,
.bpp = 16,
};
static struct s3c2410fb_mach_info rx3715_fb_info __initdata = {
.displays = &rx3715_lcdcfg,
.num_displays = 1,
.default_display = 0,
.lpcsel = 0xf82, .lpcsel = 0xf82,
.gpccon = 0xaa955699, .gpccon = 0xaa955699,
...@@ -146,26 +160,6 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { ...@@ -146,26 +160,6 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
.gpdup_mask = 0xffffffff, .gpdup_mask = 0xffffffff,
.fixed_syncs = 1, .fixed_syncs = 1,
.width = 240,
.height = 320,
.xres = {
.min = 240,
.max = 240,
.defval = 240,
},
.yres = {
.max = 320,
.min = 320,
.defval = 320,
},
.bpp = {
.min = 16,
.max = 16,
.defval = 16,
},
}; };
static struct mtd_partition rx3715_nand_part[] = { static struct mtd_partition rx3715_nand_part[] = {
...@@ -224,7 +218,7 @@ static void __init rx3715_init_machine(void) ...@@ -224,7 +218,7 @@ static void __init rx3715_init_machine(void)
#endif #endif
s3c2410_pm_init(); s3c2410_pm_init();
s3c24xx_fb_set_platdata(&rx3715_lcdcfg); s3c24xx_fb_set_platdata(&rx3715_fb_info);
platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
} }
......
...@@ -103,7 +103,7 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = { ...@@ -103,7 +103,7 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
/* LCD driver info */ /* LCD driver info */
static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
.regs = { .regs = {
.lcdcon1 = S3C2410_LCDCON1_TFT16BPP | .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
...@@ -129,6 +129,21 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { ...@@ -129,6 +129,21 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
S3C2410_LCDCON5_HWSWP, S3C2410_LCDCON5_HWSWP,
}, },
.type = S3C2410_LCDCON1_TFT16BPP,
.width = 240,
.height = 320,
.xres = 240,
.yres = 320,
.bpp = 16,
};
static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
.displays = &smdk2440_lcd_cfg,
.num_displays = 1,
.default_display = 0,
#if 0 #if 0
/* currently setup by downloader */ /* currently setup by downloader */
.gpccon = 0xaa940659, .gpccon = 0xaa940659,
...@@ -142,28 +157,6 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { ...@@ -142,28 +157,6 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
#endif #endif
.lpcsel = ((0xCE6) & ~7) | 1<<4, .lpcsel = ((0xCE6) & ~7) | 1<<4,
.type = S3C2410_LCDCON1_TFT16BPP,
.width = 240,
.height = 320,
.xres = {
.min = 240,
.max = 240,
.defval = 240,
},
.yres = {
.min = 320,
.max = 320,
.defval = 320,
},
.bpp = {
.min = 16,
.max = 16,
.defval = 16,
},
}; };
static struct platform_device *smdk2440_devices[] __initdata = { static struct platform_device *smdk2440_devices[] __initdata = {
...@@ -183,7 +176,7 @@ static void __init smdk2440_map_io(void) ...@@ -183,7 +176,7 @@ static void __init smdk2440_map_io(void)
static void __init smdk2440_machine_init(void) static void __init smdk2440_machine_init(void)
{ {
s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); s3c24xx_fb_set_platdata(&smdk2440_fb_info);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init(); smdk_machine_init();
......
...@@ -174,27 +174,28 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var, ...@@ -174,27 +174,28 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info) struct fb_info *info)
{ {
struct s3c2410fb_info *fbi = info->par; struct s3c2410fb_info *fbi = info->par;
struct s3c2410fb_mach_info *mach_info = fbi->mach_info;
struct s3c2410fb_display *display = NULL;
unsigned i;
dprintk("check_var(var=%p, info=%p)\n", var, info); dprintk("check_var(var=%p, info=%p)\n", var, info);
/* validate x/y resolution */ /* validate x/y resolution */
if (var->yres > fbi->mach_info->yres.max) for (i = 0; i < mach_info->num_displays; i++)
var->yres = fbi->mach_info->yres.max; if (var->yres == mach_info->displays[i].yres &&
else if (var->yres < fbi->mach_info->yres.min) var->xres == mach_info->displays[i].xres &&
var->yres = fbi->mach_info->yres.min; var->bits_per_pixel == mach_info->displays[i].bpp) {
display = mach_info->displays + i;
if (var->xres > fbi->mach_info->xres.max) fbi->current_display = i;
var->yres = fbi->mach_info->xres.max; break;
else if (var->xres < fbi->mach_info->xres.min) }
var->xres = fbi->mach_info->xres.min;
/* validate bpp */
if (var->bits_per_pixel > fbi->mach_info->bpp.max) if (!display) {
var->bits_per_pixel = fbi->mach_info->bpp.max; dprintk("wrong resolution or depth %dx%d at %d bpp\n",
else if (var->bits_per_pixel < fbi->mach_info->bpp.min) var->xres, var->yres, var->bits_per_pixel);
var->bits_per_pixel = fbi->mach_info->bpp.min; return -EINVAL;
}
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
...@@ -209,7 +210,7 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var, ...@@ -209,7 +210,7 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
var->blue = var->red; var->blue = var->red;
break; break;
case 8: case 8:
if (fbi->mach_info->type != S3C2410_LCDCON1_TFT) { if (display->type != S3C2410_LCDCON1_TFT) {
/* 8 bpp 332 */ /* 8 bpp 332 */
var->red.length = 3; var->red.length = 3;
var->red.offset = 5; var->red.offset = 5;
...@@ -236,7 +237,7 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var, ...@@ -236,7 +237,7 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
default: default:
case 16: case 16:
if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565) { if (display->regs.lcdcon5 & S3C2410_LCDCON5_FRM565) {
/* 16 bpp, 565 format */ /* 16 bpp, 565 format */
var->red.offset = 11; var->red.offset = 11;
var->green.offset = 5; var->green.offset = 5;
...@@ -278,6 +279,9 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -278,6 +279,9 @@ static void s3c2410fb_activate_var(struct fb_info *info,
struct fb_var_screeninfo *var) struct fb_var_screeninfo *var)
{ {
struct s3c2410fb_info *fbi = info->par; struct s3c2410fb_info *fbi = info->par;
struct s3c2410fb_mach_info *mach_info = fbi->mach_info;
struct s3c2410fb_display *display = mach_info->displays +
fbi->current_display;
int hs; int hs;
fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK; fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
...@@ -287,9 +291,9 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -287,9 +291,9 @@ static void s3c2410fb_activate_var(struct fb_info *info,
dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres); dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel); dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
fbi->regs.lcdcon1 |= fbi->mach_info->type; fbi->regs.lcdcon1 |= display->type;
if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) if (display->type == S3C2410_LCDCON1_TFT)
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
case 1: case 1:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP; fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
...@@ -338,7 +342,7 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -338,7 +342,7 @@ static void s3c2410fb_activate_var(struct fb_info *info,
/* check to see if we need to update sync/borders */ /* check to see if we need to update sync/borders */
if (!fbi->mach_info->fixed_syncs) { if (!mach_info->fixed_syncs) {
dprintk("setting vert: up=%d, low=%d, sync=%d\n", dprintk("setting vert: up=%d, low=%d, sync=%d\n",
var->upper_margin, var->lower_margin, var->vsync_len); var->upper_margin, var->lower_margin, var->vsync_len);
...@@ -363,7 +367,7 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -363,7 +367,7 @@ static void s3c2410fb_activate_var(struct fb_info *info,
fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff); fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1); fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
switch (fbi->mach_info->type) { switch (display->type) {
case S3C2410_LCDCON1_DSCAN4: case S3C2410_LCDCON1_DSCAN4:
case S3C2410_LCDCON1_STN8: case S3C2410_LCDCON1_STN8:
hs = var->xres / 8; hs = var->xres / 8;
...@@ -388,7 +392,7 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -388,7 +392,7 @@ static void s3c2410fb_activate_var(struct fb_info *info,
if (var->pixclock > 0) { if (var->pixclock > 0) {
int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) { if (display->type == S3C2410_LCDCON1_TFT) {
clkdiv = (clkdiv / 2) - 1; clkdiv = (clkdiv / 2) - 1;
if (clkdiv < 0) if (clkdiv < 0)
clkdiv = 0; clkdiv = 0;
...@@ -750,6 +754,7 @@ static char driver_name[] = "s3c2410fb"; ...@@ -750,6 +754,7 @@ static char driver_name[] = "s3c2410fb";
static int __init s3c2410fb_probe(struct platform_device *pdev) static int __init s3c2410fb_probe(struct platform_device *pdev)
{ {
struct s3c2410fb_info *info; struct s3c2410fb_info *info;
struct s3c2410fb_display *display;
struct fb_info *fbinfo; struct fb_info *fbinfo;
struct s3c2410fb_hw *mregs; struct s3c2410fb_hw *mregs;
struct resource *res; struct resource *res;
...@@ -766,7 +771,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -766,7 +771,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
mregs = &mach_info->regs; display = mach_info->displays + mach_info->default_display;
mregs = &display->regs;
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
...@@ -809,7 +815,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -809,7 +815,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
strcpy(fbinfo->fix.id, driver_name); strcpy(fbinfo->fix.id, driver_name);
memcpy(&info->regs, &mach_info->regs, sizeof(info->regs)); memcpy(&info->regs, &display->regs, sizeof(info->regs));
/* Stop the video and unset ENVID if set */ /* Stop the video and unset ENVID if set */
info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
...@@ -817,6 +823,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -817,6 +823,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1); writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);
info->mach_info = pdev->dev.platform_data; info->mach_info = pdev->dev.platform_data;
info->current_display = mach_info->default_display;
fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
fbinfo->fix.type_aux = 0; fbinfo->fix.type_aux = 0;
...@@ -827,8 +834,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -827,8 +834,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
fbinfo->var.nonstd = 0; fbinfo->var.nonstd = 0;
fbinfo->var.activate = FB_ACTIVATE_NOW; fbinfo->var.activate = FB_ACTIVATE_NOW;
fbinfo->var.height = mach_info->height; fbinfo->var.height = display->height;
fbinfo->var.width = mach_info->width; fbinfo->var.width = display->width;
fbinfo->var.accel_flags = 0; fbinfo->var.accel_flags = 0;
fbinfo->var.vmode = FB_VMODE_NONINTERLACED; fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
...@@ -836,11 +843,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -836,11 +843,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
fbinfo->flags = FBINFO_FLAG_DEFAULT; fbinfo->flags = FBINFO_FLAG_DEFAULT;
fbinfo->pseudo_palette = &info->pseudo_pal; fbinfo->pseudo_palette = &info->pseudo_pal;
fbinfo->var.xres = mach_info->xres.defval; fbinfo->var.xres = display->xres;
fbinfo->var.xres_virtual = mach_info->xres.defval; fbinfo->var.xres_virtual = display->xres;
fbinfo->var.yres = mach_info->yres.defval; fbinfo->var.yres = display->yres;
fbinfo->var.yres_virtual = mach_info->yres.defval; fbinfo->var.yres_virtual = display->yres;
fbinfo->var.bits_per_pixel = mach_info->bpp.defval; fbinfo->var.bits_per_pixel = display->bpp;
fbinfo->var.upper_margin = fbinfo->var.upper_margin =
S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1; S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
...@@ -864,9 +871,17 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -864,9 +871,17 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
fbinfo->var.green.length = 6; fbinfo->var.green.length = 6;
fbinfo->var.blue.length = 5; fbinfo->var.blue.length = 5;
fbinfo->var.transp.length = 0; fbinfo->var.transp.length = 0;
fbinfo->fix.smem_len = mach_info->xres.max *
mach_info->yres.max * /* find maximum required memory size for display */
mach_info->bpp.max / 8; for (i = 0; i < mach_info->num_displays; i++) {
unsigned long smem_len = mach_info->displays[i].xres;
smem_len *= mach_info->displays[i].yres;
smem_len *= mach_info->displays[i].bpp;
smem_len >>= 3;
if (fbinfo->fix.smem_len < smem_len)
fbinfo->fix.smem_len = smem_len;
}
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
info->palette_buffer[i] = PALETTE_BUFF_CLEAR; info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
......
...@@ -34,6 +34,8 @@ struct s3c2410fb_info { ...@@ -34,6 +34,8 @@ struct s3c2410fb_info {
struct s3c2410fb_mach_info *mach_info; struct s3c2410fb_mach_info *mach_info;
unsigned current_display;
/* raw memory addresses */ /* raw memory addresses */
dma_addr_t map_dma; /* physical */ dma_addr_t map_dma; /* physical */
u_char * map_cpu; /* virtual */ u_char * map_cpu; /* virtual */
......
...@@ -14,12 +14,6 @@ ...@@ -14,12 +14,6 @@
#include <asm/arch/regs-lcd.h> #include <asm/arch/regs-lcd.h>
struct s3c2410fb_val {
unsigned int defval;
unsigned int min;
unsigned int max;
};
struct s3c2410fb_hw { struct s3c2410fb_hw {
unsigned long lcdcon1; unsigned long lcdcon1;
unsigned long lcdcon2; unsigned long lcdcon2;
...@@ -28,23 +22,30 @@ struct s3c2410fb_hw { ...@@ -28,23 +22,30 @@ struct s3c2410fb_hw {
unsigned long lcdcon5; unsigned long lcdcon5;
}; };
struct s3c2410fb_mach_info { /* LCD description */
unsigned char fixed_syncs; /* do not update sync/border */ struct s3c2410fb_display {
/* LCD type */
/* LCD types */ unsigned type;
int type;
/* Screen size */ /* Screen size */
int width; unsigned short width;
int height; unsigned short height;
/* Screen info */ /* Screen info */
struct s3c2410fb_val xres; unsigned short xres;
struct s3c2410fb_val yres; unsigned short yres;
struct s3c2410fb_val bpp; unsigned short bpp;
/* lcd configuration registers */ /* lcd configuration registers */
struct s3c2410fb_hw regs; struct s3c2410fb_hw regs;
};
struct s3c2410fb_mach_info {
unsigned char fixed_syncs; /* do not update sync/border */
struct s3c2410fb_display *displays; /* attached diplays info */
unsigned num_displays; /* number of defined displays */
unsigned default_display;
/* GPIOs */ /* GPIOs */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment