aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2007-10-16 04:28:56 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:16 -0400
commit09fe75f6f934597f765748342ca6fb378ee7ecdb (patch)
tree55a3ab7bf52400be136ec533cd5ebda4336fcd07
parent110c1fa75463c4f327e9fc491e9a27e938800d96 (diff)
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: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c49
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c177
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c26
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c252
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c38
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c41
-rw-r--r--drivers/video/s3c2410fb.c83
-rw-r--r--drivers/video/s3c2410fb.h2
-rw-r--r--include/asm-arm/arch-s3c2410/fb.h33
9 files changed, 396 insertions, 305 deletions
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 43bb5e106302..19469340af04 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -168,13 +168,32 @@ static void __init amlm5900_map_io(void)
168} 168}
169 169
170#ifdef CONFIG_FB_S3C2410 170#ifdef CONFIG_FB_S3C2410
171static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { 171static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
172 .width = 160, 172 .width = 160,
173 .height = 160, 173 .height = 160,
174 174
175/* commented out until stn patch is submitted 175/* commented out until stn patch is submitted
176* .type = S3C2410_LCDCON1_STN4, 176* .type = S3C2410_LCDCON1_STN4,
177*/ 177*/
178 .xres = 160,
179 .yres = 160,
180 .bpp = 4,
181
182 .regs = {
183 .lcdcon1 = 0x00008225,
184 .lcdcon2 = 0x0027c000,
185 .lcdcon3 = 0x00182708,
186 .lcdcon4 = 0x00000002,
187 .lcdcon5 = 0x00000001,
188 }
189};
190
191static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = {
192
193 .displays = &amlm5900_lcd_info,
194 .num_displays = 1,
195 .default_display = 0,
196
178 .gpccon = 0xaaaaaaaa, 197 .gpccon = 0xaaaaaaaa,
179 .gpccon_mask = 0xffffffff, 198 .gpccon_mask = 0xffffffff,
180 .gpcup = 0x0000ffff, 199 .gpcup = 0x0000ffff,
@@ -184,32 +203,6 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
184 .gpdcon_mask = 0xffffffff, 203 .gpdcon_mask = 0xffffffff,
185 .gpdup = 0x0000ffff, 204 .gpdup = 0x0000ffff,
186 .gpdup_mask = 0xffffffff, 205 .gpdup_mask = 0xffffffff,
187
188 .xres = {
189 .min = 160,
190 .max = 160,
191 .defval = 160,
192 },
193
194 .yres = {
195 .min = 160,
196 .max = 160,
197 .defval = 160,
198 },
199
200 .bpp = {
201 .min = 4,
202 .max = 4,
203 .defval = 4,
204 },
205
206 .regs = {
207 .lcdcon1 = 0x00008225,
208 .lcdcon2 = 0x0027c000,
209 .lcdcon3 = 0x00182708,
210 .lcdcon4 = 0x00000002,
211 .lcdcon5 = 0x00000001,
212 }
213}; 206};
214#endif 207#endif
215 208
@@ -239,7 +232,7 @@ static void __init amlm5900_init(void)
239{ 232{
240 amlm5900_init_pm(); 233 amlm5900_init_pm();
241#ifdef CONFIG_FB_S3C2410 234#ifdef CONFIG_FB_S3C2410
242 s3c24xx_fb_set_platdata(&amlm5900_lcd_info); 235 s3c24xx_fb_set_platdata(&amlm5900_fb_info);
243#endif 236#endif
244 platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); 237 platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
245} 238}
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index bc926992b4e4..be50201809a1 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -467,35 +467,160 @@ static struct platform_device bast_device_axpp = {
467 467
468/* LCD/VGA controller */ 468/* LCD/VGA controller */
469 469
470static struct s3c2410fb_mach_info __initdata bast_lcd_info = { 470static struct s3c2410fb_display __initdata bast_lcd_info[] = {
471 .width = 640, 471 {
472 .height = 480, 472 .width = 640,
473 473 .height = 480,
474 .xres = { 474 .xres = 320,
475 .min = 320, 475 .yres = 240,
476 .max = 1024, 476
477 .defval = 640, 477 .bpp = 4,
478
479 .regs = {
480 .lcdcon1 = 0x00000176,
481 .lcdcon2 = 0x1d77c7c2,
482 .lcdcon3 = 0x013a7f13,
483 .lcdcon4 = 0x00000057,
484 .lcdcon5 = 0x00014b02,
485 }
478 }, 486 },
479 487 {
480 .yres = { 488 .width = 640,
481 .min = 240, 489 .height = 480,
482 .max = 600, 490
483 .defval = 480, 491 .xres = 640,
492 .yres = 480,
493 .bpp = 4,
494
495 .regs = {
496 .lcdcon1 = 0x00000176,
497 .lcdcon2 = 0x1d77c7c2,
498 .lcdcon3 = 0x013a7f13,
499 .lcdcon4 = 0x00000057,
500 .lcdcon5 = 0x00014b02,
501 }
484 }, 502 },
485 503 {
486 .bpp = { 504 .width = 640,
487 .min = 4, 505 .height = 480,
488 .max = 16, 506
489 .defval = 8, 507 .xres = 800,
508 .yres = 600,
509 .bpp = 4,
510
511 .regs = {
512 .lcdcon1 = 0x00000176,
513 .lcdcon2 = 0x1d77c7c2,
514 .lcdcon3 = 0x013a7f13,
515 .lcdcon4 = 0x00000057,
516 .lcdcon5 = 0x00014b02,
517 }
518 },
519 {
520 .width = 640,
521 .height = 480,
522
523 .xres = 320,
524 .yres = 240,
525 .bpp = 8,
526
527 .regs = {
528 .lcdcon1 = 0x00000176,
529 .lcdcon2 = 0x1d77c7c2,
530 .lcdcon3 = 0x013a7f13,
531 .lcdcon4 = 0x00000057,
532 .lcdcon5 = 0x00014b02,
533 }
534 },
535 {
536 .width = 640,
537 .height = 480,
538
539 .xres = 640,
540 .yres = 480,
541 .bpp = 8,
542
543 .regs = {
544 .lcdcon1 = 0x00000176,
545 .lcdcon2 = 0x1d77c7c2,
546 .lcdcon3 = 0x013a7f13,
547 .lcdcon4 = 0x00000057,
548 .lcdcon5 = 0x00014b02,
549 }
550 },
551 {
552 .width = 640,
553 .height = 480,
554
555 .xres = 800,
556 .yres = 600,
557 .bpp = 8,
558
559 .regs = {
560 .lcdcon1 = 0x00000176,
561 .lcdcon2 = 0x1d77c7c2,
562 .lcdcon3 = 0x013a7f13,
563 .lcdcon4 = 0x00000057,
564 .lcdcon5 = 0x00014b02,
565 }
566 },
567 {
568 .width = 640,
569 .height = 480,
570
571 .xres = 320,
572 .yres = 240,
573 .bpp = 16,
574
575 .regs = {
576 .lcdcon1 = 0x00000176,
577 .lcdcon2 = 0x1d77c7c2,
578 .lcdcon3 = 0x013a7f13,
579 .lcdcon4 = 0x00000057,
580 .lcdcon5 = 0x00014b02,
581 }
582 },
583 {
584 .width = 640,
585 .height = 480,
586
587 .xres = 640,
588 .yres = 480,
589 .bpp = 16,
590
591 .regs = {
592 .lcdcon1 = 0x00000176,
593 .lcdcon2 = 0x1d77c7c2,
594 .lcdcon3 = 0x013a7f13,
595 .lcdcon4 = 0x00000057,
596 .lcdcon5 = 0x00014b02,
597 }
490 }, 598 },
599 {
600 .width = 640,
601 .height = 480,
602
603 .xres = 800,
604 .yres = 600,
605 .bpp = 16,
606
607 .regs = {
608 .lcdcon1 = 0x00000176,
609 .lcdcon2 = 0x1d77c7c2,
610 .lcdcon3 = 0x013a7f13,
611 .lcdcon4 = 0x00000057,
612 .lcdcon5 = 0x00014b02,
613 }
614 },
615};
491 616
492 .regs = { 617/* LCD/VGA controller */
493 .lcdcon1 = 0x00000176, 618
494 .lcdcon2 = 0x1d77c7c2, 619static struct s3c2410fb_mach_info __initdata bast_fb_info = {
495 .lcdcon3 = 0x013a7f13, 620
496 .lcdcon4 = 0x00000057, 621 .displays = bast_lcd_info,
497 .lcdcon5 = 0x00014b02, 622 .num_displays = ARRAY_SIZE(bast_lcd_info),
498 } 623 .default_display = 4,
499}; 624};
500 625
501/* Standard BAST devices */ 626/* Standard BAST devices */
@@ -552,7 +677,7 @@ static void __init bast_map_io(void)
552 677
553static void __init bast_init(void) 678static void __init bast_init(void)
554{ 679{
555 s3c24xx_fb_set_platdata(&bast_lcd_info); 680 s3c24xx_fb_set_platdata(&bast_fb_info);
556 platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); 681 platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
557} 682}
558 683
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 9a172b4ad720..ab04b2961d6c 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -133,8 +133,7 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
133/** 133/**
134 * Set lcd on or off 134 * Set lcd on or off
135 **/ 135 **/
136static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = { 136static struct s3c2410fb_display h1940_lcd __initdata = {
137 .fixed_syncs= 1,
138 .regs={ 137 .regs={
139 .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \ 138 .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \
140 S3C2410_LCDCON1_TFT | \ 139 S3C2410_LCDCON1_TFT | \
@@ -156,6 +155,21 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
156 S3C2410_LCDCON5_INVVLINE | \ 155 S3C2410_LCDCON5_INVVLINE | \
157 S3C2410_LCDCON5_HWSWP, 156 S3C2410_LCDCON5_HWSWP,
158 }, 157 },
158
159 .width = 240,
160 .height = 320,
161 .xres = 240,
162 .yres = 320,
163 .bpp = 16,
164};
165
166static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
167 .fixed_syncs = 1,
168
169 .displays = &h1940_lcd,
170 .num_displays = 1,
171 .default_display = 0,
172
159 .lpcsel= 0x02, 173 .lpcsel= 0x02,
160 .gpccon= 0xaa940659, 174 .gpccon= 0xaa940659,
161 .gpccon_mask= 0xffffffff, 175 .gpccon_mask= 0xffffffff,
@@ -165,12 +179,6 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
165 .gpdcon_mask= 0xffffffff, 179 .gpdcon_mask= 0xffffffff,
166 .gpdup= 0x0000faff, 180 .gpdup= 0x0000faff,
167 .gpdup_mask= 0xffffffff, 181 .gpdup_mask= 0xffffffff,
168
169 .width= 240,
170 .height= 320,
171 .xres= {240,240,240},
172 .yres= {320,320,320},
173 .bpp= {16,16,16},
174}; 182};
175 183
176static struct platform_device s3c_device_leds = { 184static struct platform_device s3c_device_leds = {
@@ -217,7 +225,7 @@ static void __init h1940_init(void)
217{ 225{
218 u32 tmp; 226 u32 tmp;
219 227
220 s3c24xx_fb_set_platdata(&h1940_lcdcfg); 228 s3c24xx_fb_set_platdata(&h1940_fb_info);
221 s3c24xx_udc_set_platdata(&h1940_udc_cfg); 229 s3c24xx_udc_set_platdata(&h1940_udc_cfg);
222 230
223 /* Turn off suspend on both USB ports, and switch the 231 /* Turn off suspend on both USB ports, and switch the
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index e670b1e1631b..03ea5d7b2a17 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -95,157 +95,116 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
95 95
96/* LCD driver info */ 96/* LCD driver info */
97 97
98/* Configuration for 640x480 SHARP LQ080V3DG01 */ 98static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
99static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = { 99 {
100 .regs = { 100 /* Configuration for 640x480 SHARP LQ080V3DG01 */
101 101 .regs = {
102 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | 102
103 S3C2410_LCDCON1_TFT | 103 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
104 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */ 104 S3C2410_LCDCON1_TFT |
105 105 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
106 .lcdcon2 = S3C2410_LCDCON2_VBPD(18) | /* 19 */ 106
107 S3C2410_LCDCON2_LINEVAL(479) | 107 .lcdcon2 = S3C2410_LCDCON2_VBPD(18) | /* 19 */
108 S3C2410_LCDCON2_VFPD(10) | /* 11 */ 108 S3C2410_LCDCON2_LINEVAL(479) |
109 S3C2410_LCDCON2_VSPW(14), /* 15 */ 109 S3C2410_LCDCON2_VFPD(10) | /* 11 */
110 110 S3C2410_LCDCON2_VSPW(14), /* 15 */
111 .lcdcon3 = S3C2410_LCDCON3_HBPD(43) | /* 44 */ 111
112 S3C2410_LCDCON3_HOZVAL(639) | /* 640 */ 112 .lcdcon3 = S3C2410_LCDCON3_HBPD(43) | /* 44 */
113 S3C2410_LCDCON3_HFPD(115), /* 116 */ 113 S3C2410_LCDCON3_HOZVAL(639) | /* 640 */
114 114 S3C2410_LCDCON3_HFPD(115), /* 116 */
115 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | 115
116 S3C2410_LCDCON4_HSPW(95), /* 96 */ 116 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
117 117 S3C2410_LCDCON4_HSPW(95), /* 96 */
118 .lcdcon5 = S3C2410_LCDCON5_FRM565 | 118
119 S3C2410_LCDCON5_INVVLINE | 119 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
120 S3C2410_LCDCON5_INVVFRAME | 120 S3C2410_LCDCON5_INVVLINE |
121 S3C2410_LCDCON5_PWREN | 121 S3C2410_LCDCON5_INVVFRAME |
122 S3C2410_LCDCON5_HWSWP, 122 S3C2410_LCDCON5_PWREN |
123 S3C2410_LCDCON5_HWSWP,
124 },
125
126 .width = 640,
127 .height = 480,
128
129 .xres = 640,
130 .yres = 480,
131 .bpp = 16,
123 }, 132 },
124 133 {
125 .lpcsel = ((0xCE6) & ~7) | 1<<4, 134 /* Configuration for 480x640 toppoly TD028TTEC1 */
126 135 .regs = {
127 .width = 640, 136
128 .height = 480, 137 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
129 138 S3C2410_LCDCON1_TFT |
130 .xres = { 139 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
131 .min = 640, 140
132 .max = 640, 141 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | /* 2 */
133 .defval = 640, 142 S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
134 }, 143 S3C2410_LCDCON2_VFPD(3) | /* 4 */
135 144 S3C2410_LCDCON2_VSPW(1), /* 2 */
136 .yres = { 145
137 .min = 480, 146 .lcdcon3 = S3C2410_LCDCON3_HBPD(7) | /* 8 */
138 .max = 480, 147 S3C2410_LCDCON3_HOZVAL(479) | /* 479 */
139 .defval = 480, 148 S3C2410_LCDCON3_HFPD(23), /* 24 */
140 }, 149
141 150 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
142 .bpp = { 151 S3C2410_LCDCON4_HSPW(7), /* 8 */
143 .min = 16, 152
144 .max = 16, 153 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
145 .defval = 16, 154 S3C2410_LCDCON5_INVVLINE |
146 }, 155 S3C2410_LCDCON5_INVVFRAME |
147}; 156 S3C2410_LCDCON5_PWREN |
148 157 S3C2410_LCDCON5_HWSWP,
149/* Configuration for 480x640 toppoly TD028TTEC1 */ 158 },
150static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = { 159
151 .regs = { 160 .width = 480,
152 161 .height = 640,
153 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | 162 .xres = 480,
154 S3C2410_LCDCON1_TFT | 163 .yres = 640,
155 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */ 164 .bpp = 16,
156
157 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | /* 2 */
158 S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
159 S3C2410_LCDCON2_VFPD(3) | /* 4 */
160 S3C2410_LCDCON2_VSPW(1), /* 2 */
161
162 .lcdcon3 = S3C2410_LCDCON3_HBPD(7) | /* 8 */
163 S3C2410_LCDCON3_HOZVAL(479) | /* 479 */
164 S3C2410_LCDCON3_HFPD(23), /* 24 */
165
166 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
167 S3C2410_LCDCON4_HSPW(7), /* 8 */
168
169 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
170 S3C2410_LCDCON5_INVVLINE |
171 S3C2410_LCDCON5_INVVFRAME |
172 S3C2410_LCDCON5_PWREN |
173 S3C2410_LCDCON5_HWSWP,
174 },
175
176 .lpcsel = ((0xCE6) & ~7) | 1<<4,
177
178 .width = 480,
179 .height = 640,
180
181 .xres = {
182 .min = 480,
183 .max = 480,
184 .defval = 480,
185 }, 165 },
186 166 {
187 .yres = { 167 /* Config for 240x320 LCD */
188 .min = 640, 168 .regs = {
189 .max = 640, 169
190 .defval = 640, 170 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
191 }, 171 S3C2410_LCDCON1_TFT |
192 172 S3C2410_LCDCON1_CLKVAL(0x04),
193 .bpp = { 173
194 .min = 16, 174 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) |
195 .max = 16, 175 S3C2410_LCDCON2_LINEVAL(319) |
196 .defval = 16, 176 S3C2410_LCDCON2_VFPD(6) |
177 S3C2410_LCDCON2_VSPW(3),
178
179 .lcdcon3 = S3C2410_LCDCON3_HBPD(12) |
180 S3C2410_LCDCON3_HOZVAL(239) |
181 S3C2410_LCDCON3_HFPD(7),
182
183 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
184 S3C2410_LCDCON4_HSPW(3),
185
186 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
187 S3C2410_LCDCON5_INVVLINE |
188 S3C2410_LCDCON5_INVVFRAME |
189 S3C2410_LCDCON5_PWREN |
190 S3C2410_LCDCON5_HWSWP,
191 },
192
193 .width = 240,
194 .height = 320,
195 .xres = 240,
196 .yres = 320,
197 .bpp = 16,
197 }, 198 },
198}; 199};
199 200
200/* Config for 240x320 LCD */
201static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
202 .regs = {
203
204 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
205 S3C2410_LCDCON1_TFT |
206 S3C2410_LCDCON1_CLKVAL(0x04),
207
208 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) |
209 S3C2410_LCDCON2_LINEVAL(319) |
210 S3C2410_LCDCON2_VFPD(6) |
211 S3C2410_LCDCON2_VSPW(3),
212
213 .lcdcon3 = S3C2410_LCDCON3_HBPD(12) |
214 S3C2410_LCDCON3_HOZVAL(239) |
215 S3C2410_LCDCON3_HFPD(7),
216 201
217 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | 202static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
218 S3C2410_LCDCON4_HSPW(3), 203 .displays = qt2410_lcd_cfg,
219 204 .num_displays = ARRAY_SIZE(qt2410_lcd_cfg),
220 .lcdcon5 = S3C2410_LCDCON5_FRM565 | 205 .default_display = 0,
221 S3C2410_LCDCON5_INVVLINE |
222 S3C2410_LCDCON5_INVVFRAME |
223 S3C2410_LCDCON5_PWREN |
224 S3C2410_LCDCON5_HWSWP,
225 },
226 206
227 .lpcsel = ((0xCE6) & ~7) | 1<<4, 207 .lpcsel = ((0xCE6) & ~7) | 1<<4,
228
229 .width = 240,
230 .height = 320,
231
232 .xres = {
233 .min = 240,
234 .max = 240,
235 .defval = 240,
236 },
237
238 .yres = {
239 .min = 320,
240 .max = 320,
241 .defval = 320,
242 },
243
244 .bpp = {
245 .min = 16,
246 .max = 16,
247 .defval = 16,
248 },
249}; 208};
250 209
251/* CS8900 */ 210/* CS8900 */
@@ -408,16 +367,17 @@ static void __init qt2410_machine_init(void)
408 367
409 switch (tft_type) { 368 switch (tft_type) {
410 case 'p': /* production */ 369 case 'p': /* production */
411 s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg); 370 qt2410_fb_info.default_display = 1;
412 break; 371 break;
413 case 'b': /* big */ 372 case 'b': /* big */
414 s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg); 373 qt2410_fb_info.default_display = 0;
415 break; 374 break;
416 case 's': /* small */ 375 case 's': /* small */
417 default: 376 default:
418 s3c24xx_fb_set_platdata(&qt2410_lcd_cfg); 377 qt2410_fb_info.default_display = 2;
419 break; 378 break;
420 } 379 }
380 s3c24xx_fb_set_platdata(&qt2410_fb_info);
421 381
422 s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT); 382 s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
423 s3c2410_gpio_setpin(S3C2410_GPB0, 1); 383 s3c2410_gpio_setpin(S3C2410_GPB0, 1);
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index b59e6d39f2f2..c83078878497 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -110,7 +110,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
110 110
111/* framebuffer lcd controller information */ 111/* framebuffer lcd controller information */
112 112
113static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { 113static struct s3c2410fb_display rx3715_lcdcfg __initdata = {
114 .regs = { 114 .regs = {
115 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \ 115 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \
116 S3C2410_LCDCON1_TFT | \ 116 S3C2410_LCDCON1_TFT | \
@@ -133,6 +133,20 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
133 S3C2410_LCDCON5_HWSWP, 133 S3C2410_LCDCON5_HWSWP,
134 }, 134 },
135 135
136 .width = 240,
137 .height = 320,
138
139 .xres = 240,
140 .yres = 320,
141 .bpp = 16,
142};
143
144static struct s3c2410fb_mach_info rx3715_fb_info __initdata = {
145
146 .displays = &rx3715_lcdcfg,
147 .num_displays = 1,
148 .default_display = 0,
149
136 .lpcsel = 0xf82, 150 .lpcsel = 0xf82,
137 151
138 .gpccon = 0xaa955699, 152 .gpccon = 0xaa955699,
@@ -146,26 +160,6 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
146 .gpdup_mask = 0xffffffff, 160 .gpdup_mask = 0xffffffff,
147 161
148 .fixed_syncs = 1, 162 .fixed_syncs = 1,
149 .width = 240,
150 .height = 320,
151
152 .xres = {
153 .min = 240,
154 .max = 240,
155 .defval = 240,
156 },
157
158 .yres = {
159 .max = 320,
160 .min = 320,
161 .defval = 320,
162 },
163
164 .bpp = {
165 .min = 16,
166 .max = 16,
167 .defval = 16,
168 },
169}; 163};
170 164
171static struct mtd_partition rx3715_nand_part[] = { 165static struct mtd_partition rx3715_nand_part[] = {
@@ -224,7 +218,7 @@ static void __init rx3715_init_machine(void)
224#endif 218#endif
225 s3c2410_pm_init(); 219 s3c2410_pm_init();
226 220
227 s3c24xx_fb_set_platdata(&rx3715_lcdcfg); 221 s3c24xx_fb_set_platdata(&rx3715_fb_info);
228 platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); 222 platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
229} 223}
230 224
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index 670115b8a12e..f7dac7d54064 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -103,7 +103,7 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
103 103
104/* LCD driver info */ 104/* LCD driver info */
105 105
106static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { 106static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
107 .regs = { 107 .regs = {
108 108
109 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | 109 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
@@ -129,6 +129,21 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
129 S3C2410_LCDCON5_HWSWP, 129 S3C2410_LCDCON5_HWSWP,
130 }, 130 },
131 131
132 .type = S3C2410_LCDCON1_TFT16BPP,
133
134 .width = 240,
135 .height = 320,
136
137 .xres = 240,
138 .yres = 320,
139 .bpp = 16,
140};
141
142static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
143 .displays = &smdk2440_lcd_cfg,
144 .num_displays = 1,
145 .default_display = 0,
146
132#if 0 147#if 0
133 /* currently setup by downloader */ 148 /* currently setup by downloader */
134 .gpccon = 0xaa940659, 149 .gpccon = 0xaa940659,
@@ -142,28 +157,6 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
142#endif 157#endif
143 158
144 .lpcsel = ((0xCE6) & ~7) | 1<<4, 159 .lpcsel = ((0xCE6) & ~7) | 1<<4,
145 .type = S3C2410_LCDCON1_TFT16BPP,
146
147 .width = 240,
148 .height = 320,
149
150 .xres = {
151 .min = 240,
152 .max = 240,
153 .defval = 240,
154 },
155
156 .yres = {
157 .min = 320,
158 .max = 320,
159 .defval = 320,
160 },
161
162 .bpp = {
163 .min = 16,
164 .max = 16,
165 .defval = 16,
166 },
167}; 160};
168 161
169static struct platform_device *smdk2440_devices[] __initdata = { 162static struct platform_device *smdk2440_devices[] __initdata = {
@@ -183,7 +176,7 @@ static void __init smdk2440_map_io(void)
183 176
184static void __init smdk2440_machine_init(void) 177static void __init smdk2440_machine_init(void)
185{ 178{
186 s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); 179 s3c24xx_fb_set_platdata(&smdk2440_fb_info);
187 180
188 platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); 181 platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
189 smdk_machine_init(); 182 smdk_machine_init();
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index f7a026fa5079..e52ec2283161 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -174,27 +174,28 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
174 struct fb_info *info) 174 struct fb_info *info)
175{ 175{
176 struct s3c2410fb_info *fbi = info->par; 176 struct s3c2410fb_info *fbi = info->par;
177 struct s3c2410fb_mach_info *mach_info = fbi->mach_info;
178 struct s3c2410fb_display *display = NULL;
179 unsigned i;
177 180
178 dprintk("check_var(var=%p, info=%p)\n", var, info); 181 dprintk("check_var(var=%p, info=%p)\n", var, info);
179 182
180 /* validate x/y resolution */ 183 /* validate x/y resolution */
181 184
182 if (var->yres > fbi->mach_info->yres.max) 185 for (i = 0; i < mach_info->num_displays; i++)
183 var->yres = fbi->mach_info->yres.max; 186 if (var->yres == mach_info->displays[i].yres &&
184 else if (var->yres < fbi->mach_info->yres.min) 187 var->xres == mach_info->displays[i].xres &&
185 var->yres = fbi->mach_info->yres.min; 188 var->bits_per_pixel == mach_info->displays[i].bpp) {
186 189 display = mach_info->displays + i;
187 if (var->xres > fbi->mach_info->xres.max) 190 fbi->current_display = i;
188 var->yres = fbi->mach_info->xres.max; 191 break;
189 else if (var->xres < fbi->mach_info->xres.min) 192 }
190 var->xres = fbi->mach_info->xres.min;
191
192 /* validate bpp */
193 193
194 if (var->bits_per_pixel > fbi->mach_info->bpp.max) 194 if (!display) {
195 var->bits_per_pixel = fbi->mach_info->bpp.max; 195 dprintk("wrong resolution or depth %dx%d at %d bpp\n",
196 else if (var->bits_per_pixel < fbi->mach_info->bpp.min) 196 var->xres, var->yres, var->bits_per_pixel);
197 var->bits_per_pixel = fbi->mach_info->bpp.min; 197 return -EINVAL;
198 }
198 199
199 var->transp.offset = 0; 200 var->transp.offset = 0;
200 var->transp.length = 0; 201 var->transp.length = 0;
@@ -209,7 +210,7 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
209 var->blue = var->red; 210 var->blue = var->red;
210 break; 211 break;
211 case 8: 212 case 8:
212 if (fbi->mach_info->type != S3C2410_LCDCON1_TFT) { 213 if (display->type != S3C2410_LCDCON1_TFT) {
213 /* 8 bpp 332 */ 214 /* 8 bpp 332 */
214 var->red.length = 3; 215 var->red.length = 3;
215 var->red.offset = 5; 216 var->red.offset = 5;
@@ -236,7 +237,7 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
236 237
237 default: 238 default:
238 case 16: 239 case 16:
239 if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565) { 240 if (display->regs.lcdcon5 & S3C2410_LCDCON5_FRM565) {
240 /* 16 bpp, 565 format */ 241 /* 16 bpp, 565 format */
241 var->red.offset = 11; 242 var->red.offset = 11;
242 var->green.offset = 5; 243 var->green.offset = 5;
@@ -278,6 +279,9 @@ static void s3c2410fb_activate_var(struct fb_info *info,
278 struct fb_var_screeninfo *var) 279 struct fb_var_screeninfo *var)
279{ 280{
280 struct s3c2410fb_info *fbi = info->par; 281 struct s3c2410fb_info *fbi = info->par;
282 struct s3c2410fb_mach_info *mach_info = fbi->mach_info;
283 struct s3c2410fb_display *display = mach_info->displays +
284 fbi->current_display;
281 int hs; 285 int hs;
282 286
283 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK; 287 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
@@ -287,9 +291,9 @@ static void s3c2410fb_activate_var(struct fb_info *info,
287 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres); 291 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
288 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel); 292 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
289 293
290 fbi->regs.lcdcon1 |= fbi->mach_info->type; 294 fbi->regs.lcdcon1 |= display->type;
291 295
292 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) 296 if (display->type == S3C2410_LCDCON1_TFT)
293 switch (var->bits_per_pixel) { 297 switch (var->bits_per_pixel) {
294 case 1: 298 case 1:
295 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP; 299 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
@@ -338,7 +342,7 @@ static void s3c2410fb_activate_var(struct fb_info *info,
338 342
339 /* check to see if we need to update sync/borders */ 343 /* check to see if we need to update sync/borders */
340 344
341 if (!fbi->mach_info->fixed_syncs) { 345 if (!mach_info->fixed_syncs) {
342 dprintk("setting vert: up=%d, low=%d, sync=%d\n", 346 dprintk("setting vert: up=%d, low=%d, sync=%d\n",
343 var->upper_margin, var->lower_margin, var->vsync_len); 347 var->upper_margin, var->lower_margin, var->vsync_len);
344 348
@@ -363,7 +367,7 @@ static void s3c2410fb_activate_var(struct fb_info *info,
363 fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff); 367 fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
364 fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1); 368 fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
365 369
366 switch (fbi->mach_info->type) { 370 switch (display->type) {
367 case S3C2410_LCDCON1_DSCAN4: 371 case S3C2410_LCDCON1_DSCAN4:
368 case S3C2410_LCDCON1_STN8: 372 case S3C2410_LCDCON1_STN8:
369 hs = var->xres / 8; 373 hs = var->xres / 8;
@@ -388,7 +392,7 @@ static void s3c2410fb_activate_var(struct fb_info *info,
388 if (var->pixclock > 0) { 392 if (var->pixclock > 0) {
389 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); 393 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
390 394
391 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) { 395 if (display->type == S3C2410_LCDCON1_TFT) {
392 clkdiv = (clkdiv / 2) - 1; 396 clkdiv = (clkdiv / 2) - 1;
393 if (clkdiv < 0) 397 if (clkdiv < 0)
394 clkdiv = 0; 398 clkdiv = 0;
@@ -750,6 +754,7 @@ static char driver_name[] = "s3c2410fb";
750static int __init s3c2410fb_probe(struct platform_device *pdev) 754static int __init s3c2410fb_probe(struct platform_device *pdev)
751{ 755{
752 struct s3c2410fb_info *info; 756 struct s3c2410fb_info *info;
757 struct s3c2410fb_display *display;
753 struct fb_info *fbinfo; 758 struct fb_info *fbinfo;
754 struct s3c2410fb_hw *mregs; 759 struct s3c2410fb_hw *mregs;
755 struct resource *res; 760 struct resource *res;
@@ -766,7 +771,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
766 return -EINVAL; 771 return -EINVAL;
767 } 772 }
768 773
769 mregs = &mach_info->regs; 774 display = mach_info->displays + mach_info->default_display;
775 mregs = &display->regs;
770 776
771 irq = platform_get_irq(pdev, 0); 777 irq = platform_get_irq(pdev, 0);
772 if (irq < 0) { 778 if (irq < 0) {
@@ -809,7 +815,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
809 815
810 strcpy(fbinfo->fix.id, driver_name); 816 strcpy(fbinfo->fix.id, driver_name);
811 817
812 memcpy(&info->regs, &mach_info->regs, sizeof(info->regs)); 818 memcpy(&info->regs, &display->regs, sizeof(info->regs));
813 819
814 /* Stop the video and unset ENVID if set */ 820 /* Stop the video and unset ENVID if set */
815 info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; 821 info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
@@ -817,6 +823,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
817 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1); 823 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);
818 824
819 info->mach_info = pdev->dev.platform_data; 825 info->mach_info = pdev->dev.platform_data;
826 info->current_display = mach_info->default_display;
820 827
821 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; 828 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
822 fbinfo->fix.type_aux = 0; 829 fbinfo->fix.type_aux = 0;
@@ -827,8 +834,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
827 834
828 fbinfo->var.nonstd = 0; 835 fbinfo->var.nonstd = 0;
829 fbinfo->var.activate = FB_ACTIVATE_NOW; 836 fbinfo->var.activate = FB_ACTIVATE_NOW;
830 fbinfo->var.height = mach_info->height; 837 fbinfo->var.height = display->height;
831 fbinfo->var.width = mach_info->width; 838 fbinfo->var.width = display->width;
832 fbinfo->var.accel_flags = 0; 839 fbinfo->var.accel_flags = 0;
833 fbinfo->var.vmode = FB_VMODE_NONINTERLACED; 840 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
834 841
@@ -836,11 +843,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
836 fbinfo->flags = FBINFO_FLAG_DEFAULT; 843 fbinfo->flags = FBINFO_FLAG_DEFAULT;
837 fbinfo->pseudo_palette = &info->pseudo_pal; 844 fbinfo->pseudo_palette = &info->pseudo_pal;
838 845
839 fbinfo->var.xres = mach_info->xres.defval; 846 fbinfo->var.xres = display->xres;
840 fbinfo->var.xres_virtual = mach_info->xres.defval; 847 fbinfo->var.xres_virtual = display->xres;
841 fbinfo->var.yres = mach_info->yres.defval; 848 fbinfo->var.yres = display->yres;
842 fbinfo->var.yres_virtual = mach_info->yres.defval; 849 fbinfo->var.yres_virtual = display->yres;
843 fbinfo->var.bits_per_pixel = mach_info->bpp.defval; 850 fbinfo->var.bits_per_pixel = display->bpp;
844 851
845 fbinfo->var.upper_margin = 852 fbinfo->var.upper_margin =
846 S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1; 853 S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
@@ -864,9 +871,17 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
864 fbinfo->var.green.length = 6; 871 fbinfo->var.green.length = 6;
865 fbinfo->var.blue.length = 5; 872 fbinfo->var.blue.length = 5;
866 fbinfo->var.transp.length = 0; 873 fbinfo->var.transp.length = 0;
867 fbinfo->fix.smem_len = mach_info->xres.max * 874
868 mach_info->yres.max * 875 /* find maximum required memory size for display */
869 mach_info->bpp.max / 8; 876 for (i = 0; i < mach_info->num_displays; i++) {
877 unsigned long smem_len = mach_info->displays[i].xres;
878
879 smem_len *= mach_info->displays[i].yres;
880 smem_len *= mach_info->displays[i].bpp;
881 smem_len >>= 3;
882 if (fbinfo->fix.smem_len < smem_len)
883 fbinfo->fix.smem_len = smem_len;
884 }
870 885
871 for (i = 0; i < 256; i++) 886 for (i = 0; i < 256; i++)
872 info->palette_buffer[i] = PALETTE_BUFF_CLEAR; 887 info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index eec77080f2c5..9e86fffccb32 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -34,6 +34,8 @@ struct s3c2410fb_info {
34 34
35 struct s3c2410fb_mach_info *mach_info; 35 struct s3c2410fb_mach_info *mach_info;
36 36
37 unsigned current_display;
38
37 /* raw memory addresses */ 39 /* raw memory addresses */
38 dma_addr_t map_dma; /* physical */ 40 dma_addr_t map_dma; /* physical */
39 u_char * map_cpu; /* virtual */ 41 u_char * map_cpu; /* virtual */
diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
index 93a58e7862b0..c0e18b2c2d4a 100644
--- a/include/asm-arm/arch-s3c2410/fb.h
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -14,12 +14,6 @@
14 14
15#include <asm/arch/regs-lcd.h> 15#include <asm/arch/regs-lcd.h>
16 16
17struct s3c2410fb_val {
18 unsigned int defval;
19 unsigned int min;
20 unsigned int max;
21};
22
23struct s3c2410fb_hw { 17struct s3c2410fb_hw {
24 unsigned long lcdcon1; 18 unsigned long lcdcon1;
25 unsigned long lcdcon2; 19 unsigned long lcdcon2;
@@ -28,23 +22,30 @@ struct s3c2410fb_hw {
28 unsigned long lcdcon5; 22 unsigned long lcdcon5;
29}; 23};
30 24
31struct s3c2410fb_mach_info { 25/* LCD description */
32 unsigned char fixed_syncs; /* do not update sync/border */ 26struct s3c2410fb_display {
33 27 /* LCD type */
34 /* LCD types */ 28 unsigned type;
35 int type;
36 29
37 /* Screen size */ 30 /* Screen size */
38 int width; 31 unsigned short width;
39 int height; 32 unsigned short height;
40 33
41 /* Screen info */ 34 /* Screen info */
42 struct s3c2410fb_val xres; 35 unsigned short xres;
43 struct s3c2410fb_val yres; 36 unsigned short yres;
44 struct s3c2410fb_val bpp; 37 unsigned short bpp;
45 38
46 /* lcd configuration registers */ 39 /* lcd configuration registers */
47 struct s3c2410fb_hw regs; 40 struct s3c2410fb_hw regs;
41};
42
43struct s3c2410fb_mach_info {
44 unsigned char fixed_syncs; /* do not update sync/border */
45
46 struct s3c2410fb_display *displays; /* attached diplays info */
47 unsigned num_displays; /* number of defined displays */
48 unsigned default_display;
48 49
49 /* GPIOs */ 50 /* GPIOs */
50 51