aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2010-08-10 21:02:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-11 11:59:10 -0400
commitc4bb6ffa7754e8d0f8b24decd91de259b549fda1 (patch)
treeb3fa52dc17e77e9541d525d2ac42d8d206daa151 /drivers/video
parent50a5503a9208420e6c59d24504a5e9913d603cf7 (diff)
s3c-fb: udpate to support s3c2416/s3c2443 style hardware
Update the variant and window variant structures with the necessary changes to support the older style of hardware where these are not in the same place. Add the support for the s3c2443/s3c2416 hardware by using the platform-device s3c2443 to cover both, and add the initialisation data for these. Also change to including just the v4 header files for the moment until the last of the merging of these is sorted out. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Pawel Osciak <p.osciak@samsung.com> Cc: InKi Dae <inki.dae@samsung.com> Cc: KyungMin Park <kyungmin.park.samsung.com> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/s3c-fb.c162
1 files changed, 131 insertions, 31 deletions
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index e700cfd50023..5c7ac01ab61d 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software FoundatIon.
13*/ 13*/
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
@@ -23,7 +23,7 @@
23#include <linux/io.h> 23#include <linux/io.h>
24 24
25#include <mach/map.h> 25#include <mach/map.h>
26#include <mach/regs-fb.h> 26#include <plat/regs-fb-v4.h>
27#include <plat/fb.h> 27#include <plat/fb.h>
28 28
29/* This driver will export a number of framebuffer interfaces depending 29/* This driver will export a number of framebuffer interfaces depending
@@ -52,13 +52,38 @@ struct s3c_fb;
52 52
53#define VALID_BPP(x) (1 << ((x) - 1)) 53#define VALID_BPP(x) (1 << ((x) - 1))
54 54
55#define OSD_BASE(win, variant) ((variant).osd + ((win) * (variant).osd_stride))
56#define VIDOSD_A(win, variant) (OSD_BASE(win, variant) + 0x00)
57#define VIDOSD_B(win, variant) (OSD_BASE(win, variant) + 0x04)
58#define VIDOSD_C(win, variant) (OSD_BASE(win, variant) + 0x08)
59#define VIDOSD_D(win, variant) (OSD_BASE(win, variant) + 0x0C)
60
55/** 61/**
56 * struct s3c_fb_variant - fb variant information 62 * struct s3c_fb_variant - fb variant information
63 * @is_2443: Set if S3C2443/S3C2416 style hardware.
57 * @nr_windows: The number of windows. 64 * @nr_windows: The number of windows.
65 * @vidtcon: The base for the VIDTCONx registers
66 * @wincon: The base for the WINxCON registers.
67 * @winmap: The base for the WINxMAP registers.
68 * @keycon: The abse for the WxKEYCON registers.
69 * @buf_start: Offset of buffer start registers.
70 * @buf_size: Offset of buffer size registers.
71 * @buf_end: Offset of buffer end registers.
72 * @osd: The base for the OSD registers.
58 * @palette: Address of palette memory, or 0 if none. 73 * @palette: Address of palette memory, or 0 if none.
59 */ 74 */
60struct s3c_fb_variant { 75struct s3c_fb_variant {
76 unsigned int is_2443:1;
61 unsigned short nr_windows; 77 unsigned short nr_windows;
78 unsigned short vidtcon;
79 unsigned short wincon;
80 unsigned short winmap;
81 unsigned short keycon;
82 unsigned short buf_start;
83 unsigned short buf_end;
84 unsigned short buf_size;
85 unsigned short osd;
86 unsigned short osd_stride;
62 unsigned short palette[S3C_FB_MAX_WIN]; 87 unsigned short palette[S3C_FB_MAX_WIN];
63}; 88};
64 89
@@ -308,6 +333,7 @@ static int s3c_fb_set_par(struct fb_info *info)
308 struct s3c_fb_win *win = info->par; 333 struct s3c_fb_win *win = info->par;
309 struct s3c_fb *sfb = win->parent; 334 struct s3c_fb *sfb = win->parent;
310 void __iomem *regs = sfb->regs; 335 void __iomem *regs = sfb->regs;
336 void __iomem *buf = regs;
311 int win_no = win->index; 337 int win_no = win->index;
312 u32 osdc_data = 0; 338 u32 osdc_data = 0;
313 u32 data; 339 u32 data;
@@ -357,6 +383,9 @@ static int s3c_fb_set_par(struct fb_info *info)
357 383
358 /* write the timing data to the panel */ 384 /* write the timing data to the panel */
359 385
386 if (sfb->variant.is_2443)
387 data |= (1 << 5);
388
360 data |= VIDCON0_ENVID | VIDCON0_ENVID_F; 389 data |= VIDCON0_ENVID | VIDCON0_ENVID_F;
361 writel(data, regs + VIDCON0); 390 writel(data, regs + VIDCON0);
362 391
@@ -364,41 +393,45 @@ static int s3c_fb_set_par(struct fb_info *info)
364 VIDTCON0_VFPD(var->lower_margin - 1) | 393 VIDTCON0_VFPD(var->lower_margin - 1) |
365 VIDTCON0_VSPW(var->vsync_len - 1); 394 VIDTCON0_VSPW(var->vsync_len - 1);
366 395
367 writel(data, regs + VIDTCON0); 396 writel(data, regs + sfb->variant.vidtcon);
368 397
369 data = VIDTCON1_HBPD(var->left_margin - 1) | 398 data = VIDTCON1_HBPD(var->left_margin - 1) |
370 VIDTCON1_HFPD(var->right_margin - 1) | 399 VIDTCON1_HFPD(var->right_margin - 1) |
371 VIDTCON1_HSPW(var->hsync_len - 1); 400 VIDTCON1_HSPW(var->hsync_len - 1);
372 401
373 writel(data, regs + VIDTCON1); 402 /* VIDTCON1 */
403 writel(data, regs + sfb->variant.vidtcon + 4);
374 404
375 data = VIDTCON2_LINEVAL(var->yres - 1) | 405 data = VIDTCON2_LINEVAL(var->yres - 1) |
376 VIDTCON2_HOZVAL(var->xres - 1); 406 VIDTCON2_HOZVAL(var->xres - 1);
377 writel(data, regs + VIDTCON2); 407 writel(data, regs +sfb->variant.vidtcon + 8 );
378 } 408 }
379 409
380 /* write the buffer address */ 410 /* write the buffer address */
381 411
382 writel(info->fix.smem_start, regs + VIDW_BUF_START(win_no)); 412 /* start and end registers stride is 8 */
413 buf = regs + win_no * 8;
414
415 writel(info->fix.smem_start, buf + sfb->variant.buf_start);
383 416
384 data = info->fix.smem_start + info->fix.line_length * var->yres; 417 data = info->fix.smem_start + info->fix.line_length * var->yres;
385 writel(data, regs + VIDW_BUF_END(win_no)); 418 writel(data, buf + sfb->variant.buf_end);
386 419
387 pagewidth = (var->xres * var->bits_per_pixel) >> 3; 420 pagewidth = (var->xres * var->bits_per_pixel) >> 3;
388 data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | 421 data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) |
389 VIDW_BUF_SIZE_PAGEWIDTH(pagewidth); 422 VIDW_BUF_SIZE_PAGEWIDTH(pagewidth);
390 writel(data, regs + VIDW_BUF_SIZE(win_no)); 423 writel(data, regs + sfb->variant.buf_size + (win_no * 4));
391 424
392 /* write 'OSD' registers to control position of framebuffer */ 425 /* write 'OSD' registers to control position of framebuffer */
393 426
394 data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0); 427 data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0);
395 writel(data, regs + VIDOSD_A(win_no)); 428 writel(data, regs + VIDOSD_A(win_no, sfb->variant));
396 429
397 data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, 430 data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel,
398 var->xres - 1)) | 431 var->xres - 1)) |
399 VIDOSDxB_BOTRIGHT_Y(var->yres - 1); 432 VIDOSDxB_BOTRIGHT_Y(var->yres - 1);
400 433
401 writel(data, regs + VIDOSD_B(win_no)); 434 writel(data, regs + VIDOSD_B(win_no, sfb->variant));
402 435
403 data = var->xres * var->yres; 436 data = var->xres * var->yres;
404 437
@@ -407,10 +440,10 @@ static int s3c_fb_set_par(struct fb_info *info)
407 VIDISD14C_ALPHA1_B(0xf); 440 VIDISD14C_ALPHA1_B(0xf);
408 441
409 if (win->variant.has_osd_d) { 442 if (win->variant.has_osd_d) {
410 writel(data, regs + VIDOSD_D(win_no)); 443 writel(data, regs + VIDOSD_D(win_no, sfb->variant));
411 writel(osdc_data, regs + VIDOSD_C(win_no)); 444 writel(osdc_data, regs + VIDOSD_C(win_no, sfb->variant));
412 } else 445 } else
413 writel(data, regs + VIDOSD_C(win_no)); 446 writel(data, regs + VIDOSD_C(win_no, sfb->variant));
414 447
415 data = WINCONx_ENWIN; 448 data = WINCONx_ENWIN;
416 449
@@ -471,9 +504,10 @@ static int s3c_fb_set_par(struct fb_info *info)
471 break; 504 break;
472 } 505 }
473 506
474 /* It has no color key control register for window0 */ 507 /* Enable the colour keying for the window below this one */
475 if (win_no > 0) { 508 if (win_no > 0) {
476 u32 keycon0_data = 0, keycon1_data = 0; 509 u32 keycon0_data = 0, keycon1_data = 0;
510 void __iomem *keycon = regs + sfb->variant.keycon;
477 511
478 keycon0_data = ~(WxKEYCON0_KEYBL_EN | 512 keycon0_data = ~(WxKEYCON0_KEYBL_EN |
479 WxKEYCON0_KEYEN_F | 513 WxKEYCON0_KEYEN_F |
@@ -481,12 +515,14 @@ static int s3c_fb_set_par(struct fb_info *info)
481 515
482 keycon1_data = WxKEYCON1_COLVAL(0xffffff); 516 keycon1_data = WxKEYCON1_COLVAL(0xffffff);
483 517
484 writel(keycon0_data, regs + WxKEYCONy(win_no-1, 0)); 518 keycon += (win_no - 1) * 8;
485 writel(keycon1_data, regs + WxKEYCONy(win_no-1, 1)); 519
520 writel(keycon0_data, keycon + WKEYCON0);
521 writel(keycon1_data, keycon + WKEYCON1);
486 } 522 }
487 523
488 writel(data, regs + WINCON(win_no)); 524 writel(data, regs + sfb->variant.wincon + (win_no * 4));
489 writel(0x0, regs + WINxMAP(win_no)); 525 writel(0x0, regs + sfb->variant.winmap + (win_no * 4));
490 526
491 return 0; 527 return 0;
492} 528}
@@ -634,7 +670,7 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
634 670
635 dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); 671 dev_dbg(sfb->dev, "blank mode %d\n", blank_mode);
636 672
637 wincon = readl(sfb->regs + WINCON(index)); 673 wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4));
638 674
639 switch (blank_mode) { 675 switch (blank_mode) {
640 case FB_BLANK_POWERDOWN: 676 case FB_BLANK_POWERDOWN:
@@ -645,11 +681,11 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
645 case FB_BLANK_NORMAL: 681 case FB_BLANK_NORMAL:
646 /* disable the DMA and display 0x0 (black) */ 682 /* disable the DMA and display 0x0 (black) */
647 writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), 683 writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0),
648 sfb->regs + WINxMAP(index)); 684 sfb->regs + sfb->variant.winmap + (index * 4));
649 break; 685 break;
650 686
651 case FB_BLANK_UNBLANK: 687 case FB_BLANK_UNBLANK:
652 writel(0x0, sfb->regs + WINxMAP(index)); 688 writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4));
653 wincon |= WINCONx_ENWIN; 689 wincon |= WINCONx_ENWIN;
654 sfb->enabled |= (1 << index); 690 sfb->enabled |= (1 << index);
655 break; 691 break;
@@ -660,7 +696,7 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
660 return 1; 696 return 1;
661 } 697 }
662 698
663 writel(wincon, sfb->regs + WINCON(index)); 699 writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4));
664 700
665 /* Check the enabled state to see if we need to be running the 701 /* Check the enabled state to see if we need to be running the
666 * main LCD interface, as if there are no active windows then 702 * main LCD interface, as if there are no active windows then
@@ -796,7 +832,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
796 int palette_size; 832 int palette_size;
797 int ret; 833 int ret;
798 834
799 dev_dbg(sfb->dev, "probing window %d\n", win_no); 835 dev_dbg(sfb->dev, "probing window %d, variant %p\n", win_no, variant);
800 836
801 palette_size = variant->palette_sz * 4; 837 palette_size = variant->palette_sz * 4;
802 838
@@ -889,10 +925,10 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
889{ 925{
890 void __iomem *regs = sfb->regs; 926 void __iomem *regs = sfb->regs;
891 927
892 writel(0, regs + WINCON(win)); 928 writel(0, regs + sfb->variant.wincon + (win * 4));
893 writel(0, regs + VIDOSD_A(win)); 929 writel(0, regs + VIDOSD_A(win, sfb->variant));
894 writel(0, regs + VIDOSD_B(win)); 930 writel(0, regs + VIDOSD_B(win, sfb->variant));
895 writel(0, regs + VIDOSD_C(win)); 931 writel(0, regs + VIDOSD_C(win, sfb->variant));
896} 932}
897 933
898static int __devinit s3c_fb_probe(struct platform_device *pdev) 934static int __devinit s3c_fb_probe(struct platform_device *pdev)
@@ -924,6 +960,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
924 return -ENOMEM; 960 return -ENOMEM;
925 } 961 }
926 962
963 dev_dbg(dev, "allocate new framebuffer %p\n", sfb);
964
927 sfb->dev = dev; 965 sfb->dev = dev;
928 sfb->pdata = pd; 966 sfb->pdata = pd;
929 sfb->variant = fbdrv->variant; 967 sfb->variant = fbdrv->variant;
@@ -973,8 +1011,11 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
973 1011
974 /* initialise colour key controls */ 1012 /* initialise colour key controls */
975 for (win = 0; win < (fbdrv->variant.nr_windows - 1); win++) { 1013 for (win = 0; win < (fbdrv->variant.nr_windows - 1); win++) {
976 writel(0xffffff, sfb->regs + WxKEYCONy(win, 0)); 1014 void __iomem *regs = sfb->regs + sfb->variant.keycon;
977 writel(0xffffff, sfb->regs + WxKEYCONy(win, 1)); 1015
1016 regs += (win * 8);
1017 writel(0xffffff, regs + WKEYCON0);
1018 writel(0xffffff, regs + WKEYCON1);
978 } 1019 }
979 1020
980 /* we have the register setup, start allocating framebuffers */ 1021 /* we have the register setup, start allocating framebuffers */
@@ -1079,8 +1120,11 @@ static int s3c_fb_resume(struct platform_device *pdev)
1079 s3c_fb_clear_win(sfb, win_no); 1120 s3c_fb_clear_win(sfb, win_no);
1080 1121
1081 for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) { 1122 for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) {
1082 writel(0xffffff, sfb->regs + WxKEYCONy(win_no, 1)); 1123 void __iomem *regs = sfb->regs + sfb->variant.keycon;
1083 writel(0xffffff, sfb->regs + WxKEYCONy(win_no, 1)); 1124
1125 regs += (win_no * 8);
1126 writel(0xffffff, regs + WKEYCON0);
1127 writel(0xffffff, regs + WKEYCON1);
1084 } 1128 }
1085 1129
1086 /* restore framebuffers */ 1130 /* restore framebuffers */
@@ -1149,6 +1193,15 @@ static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] __devinitdata = {
1149static struct s3c_fb_driverdata s3c_fb_data_64xx __devinitdata = { 1193static struct s3c_fb_driverdata s3c_fb_data_64xx __devinitdata = {
1150 .variant = { 1194 .variant = {
1151 .nr_windows = 5, 1195 .nr_windows = 5,
1196 .vidtcon = VIDTCON0,
1197 .wincon = WINCON(0),
1198 .winmap = WINxMAP(0),
1199 .keycon = WKEYCON,
1200 .osd = VIDOSD_BASE,
1201 .osd_stride = 16,
1202 .buf_start = VIDW_BUF_START(0),
1203 .buf_size = VIDW_BUF_SIZE(0),
1204 .buf_end = VIDW_BUF_END(0),
1152 1205
1153 .palette = { 1206 .palette = {
1154 [0] = 0x400, 1207 [0] = 0x400,
@@ -1168,6 +1221,15 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx __devinitdata = {
1168static struct s3c_fb_driverdata s3c_fb_data_s5p __devinitdata = { 1221static struct s3c_fb_driverdata s3c_fb_data_s5p __devinitdata = {
1169 .variant = { 1222 .variant = {
1170 .nr_windows = 5, 1223 .nr_windows = 5,
1224 .vidtcon = VIDTCON0,
1225 .wincon = WINCON(0),
1226 .winmap = WINxMAP(0),
1227 .keycon = WKEYCON,
1228 .osd = VIDOSD_BASE,
1229 .osd_stride = 16,
1230 .buf_start = VIDW_BUF_START(0),
1231 .buf_size = VIDW_BUF_SIZE(0),
1232 .buf_end = VIDW_BUF_END(0),
1171 1233
1172 .palette = { 1234 .palette = {
1173 [0] = 0x2400, 1235 [0] = 0x2400,
@@ -1184,6 +1246,41 @@ static struct s3c_fb_driverdata s3c_fb_data_s5p __devinitdata = {
1184 .win[4] = &s3c_fb_data_64xx_wins[4], 1246 .win[4] = &s3c_fb_data_64xx_wins[4],
1185}; 1247};
1186 1248
1249/* S3C2443/S3C2416 style hardware */
1250static struct s3c_fb_driverdata s3c_fb_data_s3c2443 __devinitdata = {
1251 .variant = {
1252 .nr_windows = 2,
1253 .is_2443 = 1,
1254
1255 .vidtcon = 0x08,
1256 .wincon = 0x14,
1257 .winmap = 0xd0,
1258 .keycon = 0xb0,
1259 .osd = 0x28,
1260 .osd_stride = 12,
1261 .buf_start = 0x64,
1262 .buf_size = 0x94,
1263 .buf_end = 0x7c,
1264
1265 .palette = {
1266 [0] = 0x400,
1267 [1] = 0x800,
1268 },
1269 },
1270 .win[0] = &(struct s3c_fb_win_variant) {
1271 .palette_sz = 256,
1272 .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24),
1273 },
1274 .win[1] = &(struct s3c_fb_win_variant) {
1275 .has_osd_c = 1,
1276 .palette_sz = 256,
1277 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) |
1278 VALID_BPP(18) | VALID_BPP(19) |
1279 VALID_BPP(24) | VALID_BPP(25) |
1280 VALID_BPP(28)),
1281 },
1282};
1283
1187static struct platform_device_id s3c_fb_driver_ids[] = { 1284static struct platform_device_id s3c_fb_driver_ids[] = {
1188 { 1285 {
1189 .name = "s3c-fb", 1286 .name = "s3c-fb",
@@ -1191,6 +1288,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
1191 }, { 1288 }, {
1192 .name = "s5p-fb", 1289 .name = "s5p-fb",
1193 .driver_data = (unsigned long)&s3c_fb_data_s5p, 1290 .driver_data = (unsigned long)&s3c_fb_data_s5p,
1291 }, {
1292 .name = "s3c2443-fb",
1293 .driver_data = (unsigned long)&s3c_fb_data_s3c2443,
1194 }, 1294 },
1195 {}, 1295 {},
1196}; 1296};