diff options
-rw-r--r-- | arch/arm/mach-s3c64xx/include/mach/regs-fb.h | 20 | ||||
-rw-r--r-- | arch/arm/mach-s5pc100/include/mach/regs-fb.h | 34 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/regs-fb-v4.h | 36 | ||||
-rw-r--r-- | drivers/video/s3c-fb.c | 208 |
4 files changed, 180 insertions, 118 deletions
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-fb.h b/arch/arm/mach-s3c64xx/include/mach/regs-fb.h index f56611526c63..a06ee0af9a4b 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-fb.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-fb.h | |||
@@ -18,24 +18,4 @@ | |||
18 | 18 | ||
19 | #include <plat/regs-fb-v4.h> | 19 | #include <plat/regs-fb-v4.h> |
20 | 20 | ||
21 | /* Palette registers */ | ||
22 | #define WIN2_PAL(_entry) (0x300 + ((_entry) * 2)) | ||
23 | #define WIN3_PAL(_entry) (0x320 + ((_entry) * 2)) | ||
24 | #define WIN4_PAL(_entry) (0x340 + ((_entry) * 2)) | ||
25 | #define WIN0_PAL(_entry) (0x400 + ((_entry) * 4)) | ||
26 | #define WIN1_PAL(_entry) (0x800 + ((_entry) * 4)) | ||
27 | |||
28 | static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg) | ||
29 | { | ||
30 | switch (window) { | ||
31 | case 0: return WIN0_PAL(reg); | ||
32 | case 1: return WIN1_PAL(reg); | ||
33 | case 2: return WIN2_PAL(reg); | ||
34 | case 3: return WIN3_PAL(reg); | ||
35 | case 4: return WIN4_PAL(reg); | ||
36 | } | ||
37 | |||
38 | BUG(); | ||
39 | } | ||
40 | |||
41 | #endif /* __ASM_ARCH_MACH_REGS_FB_H */ | 21 | #endif /* __ASM_ARCH_MACH_REGS_FB_H */ |
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h index 1732cd28c765..4be4cc9abf75 100644 --- a/arch/arm/mach-s5pc100/include/mach/regs-fb.h +++ b/arch/arm/mach-s5pc100/include/mach/regs-fb.h | |||
@@ -100,40 +100,6 @@ | |||
100 | #define BLENDCON (0x260) | 100 | #define BLENDCON (0x260) |
101 | #define BLENDCON_8BIT_ALPHA (1 << 0) | 101 | #define BLENDCON_8BIT_ALPHA (1 << 0) |
102 | 102 | ||
103 | /* Per-window palette base addresses (start of palette memory). | ||
104 | * Each window palette area consists of 256 32-bit entries. | ||
105 | * START is the first address (entry 0th), END is the address of 255th entry. | ||
106 | */ | ||
107 | #define WIN0_PAL_BASE (0x2400) | ||
108 | #define WIN0_PAL_END (0x27fc) | ||
109 | #define WIN1_PAL_BASE (0x2800) | ||
110 | #define WIN1_PAL_END (0x2bfc) | ||
111 | #define WIN2_PAL_BASE (0x2c00) | ||
112 | #define WIN2_PAL_END (0x2ffc) | ||
113 | #define WIN3_PAL_BASE (0x3000) | ||
114 | #define WIN3_PAL_END (0x33fc) | ||
115 | #define WIN4_PAL_BASE (0x3400) | ||
116 | #define WIN4_PAL_END (0x37fc) | ||
117 | |||
118 | #define WIN0_PAL(_entry) (WIN0_PAL_BASE + ((_entry) * 4)) | ||
119 | #define WIN1_PAL(_entry) (WIN1_PAL_BASE + ((_entry) * 4)) | ||
120 | #define WIN2_PAL(_entry) (WIN2_PAL_BASE + ((_entry) * 4)) | ||
121 | #define WIN3_PAL(_entry) (WIN3_PAL_BASE + ((_entry) * 4)) | ||
122 | #define WIN4_PAL(_entry) (WIN4_PAL_BASE + ((_entry) * 4)) | ||
123 | |||
124 | static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg) | ||
125 | { | ||
126 | switch (window) { | ||
127 | case 0: return WIN0_PAL(reg); | ||
128 | case 1: return WIN1_PAL(reg); | ||
129 | case 2: return WIN2_PAL(reg); | ||
130 | case 3: return WIN3_PAL(reg); | ||
131 | case 4: return WIN4_PAL(reg); | ||
132 | } | ||
133 | |||
134 | BUG(); | ||
135 | } | ||
136 | |||
137 | 103 | ||
138 | #endif /* __ASM_ARCH_REGS_FB_H */ | 104 | #endif /* __ASM_ARCH_REGS_FB_H */ |
139 | 105 | ||
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h index 0f43599248ad..0477e8aaf3dd 100644 --- a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h +++ b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h | |||
@@ -148,42 +148,6 @@ | |||
148 | * compiled. | 148 | * compiled. |
149 | */ | 149 | */ |
150 | 150 | ||
151 | /* return true if window _win has OSD register D */ | ||
152 | #define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0) | ||
153 | |||
154 | static inline unsigned int s3c_fb_win_pal_size(unsigned int win) | ||
155 | { | ||
156 | if (win < 2) | ||
157 | return 256; | ||
158 | if (win < 4) | ||
159 | return 16; | ||
160 | if (win == 4) | ||
161 | return 4; | ||
162 | |||
163 | BUG(); /* shouldn't get here */ | ||
164 | } | ||
165 | |||
166 | static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp) | ||
167 | { | ||
168 | /* all windows can do 1/2 bpp */ | ||
169 | |||
170 | if ((bpp == 25 || bpp == 19) && win == 0) | ||
171 | return 0; /* win 0 does not have 19 or 25bpp modes */ | ||
172 | |||
173 | if (bpp == 4 && win == 4) | ||
174 | return 0; | ||
175 | |||
176 | if (bpp == 8 && (win >= 3)) | ||
177 | return 0; /* win 3/4 cannot do 8bpp in any mode */ | ||
178 | |||
179 | return 1; | ||
180 | } | ||
181 | |||
182 | static inline int s3c_fb_pal_is16(unsigned int window) | ||
183 | { | ||
184 | return window > 1; | ||
185 | } | ||
186 | |||
187 | struct s3c_fb_palette { | 151 | struct s3c_fb_palette { |
188 | struct fb_bitfield r; | 152 | struct fb_bitfield r; |
189 | struct fb_bitfield g; | 153 | struct fb_bitfield g; |
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index f9d0170b2413..e700cfd50023 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* linux/drivers/video/s3c-fb.c | 1 | /* linux/drivers/video/s3c-fb.c |
2 | * | 2 | * |
3 | * Copyright 2008 Openmoko Inc. | 3 | * Copyright 2008 Openmoko Inc. |
4 | * Copyright 2008 Simtec Electronics | 4 | * Copyright 2008-2010 Simtec Electronics |
5 | * Ben Dooks <ben@simtec.co.uk> | 5 | * Ben Dooks <ben@simtec.co.uk> |
6 | * http://armlinux.simtec.co.uk/ | 6 | * http://armlinux.simtec.co.uk/ |
7 | * | 7 | * |
@@ -36,9 +36,9 @@ | |||
36 | * output timings and as the control for the output power-down state. | 36 | * output timings and as the control for the output power-down state. |
37 | */ | 37 | */ |
38 | 38 | ||
39 | /* note, some of the functions that get called are derived from including | 39 | /* note, the previous use of <mach/regs-fb.h> to get platform specific data |
40 | * <mach/regs-fb.h> as they are specific to the architecture that the code | 40 | * has been replaced by using the platform device name to pick the correct |
41 | * is being built for. | 41 | * configuration data for the system. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #ifdef CONFIG_FB_S3C_DEBUG_REGWRITE | 44 | #ifdef CONFIG_FB_S3C_DEBUG_REGWRITE |
@@ -50,11 +50,52 @@ | |||
50 | 50 | ||
51 | struct s3c_fb; | 51 | struct s3c_fb; |
52 | 52 | ||
53 | #define VALID_BPP(x) (1 << ((x) - 1)) | ||
54 | |||
55 | /** | ||
56 | * struct s3c_fb_variant - fb variant information | ||
57 | * @nr_windows: The number of windows. | ||
58 | * @palette: Address of palette memory, or 0 if none. | ||
59 | */ | ||
60 | struct s3c_fb_variant { | ||
61 | unsigned short nr_windows; | ||
62 | unsigned short palette[S3C_FB_MAX_WIN]; | ||
63 | }; | ||
64 | |||
65 | /** | ||
66 | * struct s3c_fb_win_variant | ||
67 | * @has_osd_c: Set if has OSD C register. | ||
68 | * @has_osd_d: Set if has OSD D register. | ||
69 | * @palette_sz: Size of palette in entries. | ||
70 | * @palette_16bpp: Set if palette is 16bits wide. | ||
71 | * @valid_bpp: 1 bit per BPP setting to show valid bits-per-pixel. | ||
72 | * | ||
73 | * valid_bpp bit x is set if (x+1)BPP is supported. | ||
74 | */ | ||
75 | struct s3c_fb_win_variant { | ||
76 | unsigned int has_osd_c:1; | ||
77 | unsigned int has_osd_d:1; | ||
78 | unsigned int palette_16bpp:1; | ||
79 | unsigned short palette_sz; | ||
80 | u32 valid_bpp; | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * struct s3c_fb_driverdata - per-device type driver data for init time. | ||
85 | * @variant: The variant information for this driver. | ||
86 | * @win: The window information for each window. | ||
87 | */ | ||
88 | struct s3c_fb_driverdata { | ||
89 | struct s3c_fb_variant variant; | ||
90 | struct s3c_fb_win_variant *win[S3C_FB_MAX_WIN]; | ||
91 | }; | ||
92 | |||
53 | /** | 93 | /** |
54 | * struct s3c_fb_win - per window private data for each framebuffer. | 94 | * struct s3c_fb_win - per window private data for each framebuffer. |
55 | * @windata: The platform data supplied for the window configuration. | 95 | * @windata: The platform data supplied for the window configuration. |
56 | * @parent: The hardware that this window is part of. | 96 | * @parent: The hardware that this window is part of. |
57 | * @fbinfo: Pointer pack to the framebuffer info for this window. | 97 | * @fbinfo: Pointer pack to the framebuffer info for this window. |
98 | * @varint: The variant information for this window. | ||
58 | * @palette_buffer: Buffer/cache to hold palette entries. | 99 | * @palette_buffer: Buffer/cache to hold palette entries. |
59 | * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/ | 100 | * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/ |
60 | * @index: The window number of this window. | 101 | * @index: The window number of this window. |
@@ -65,6 +106,7 @@ struct s3c_fb_win { | |||
65 | struct s3c_fb *parent; | 106 | struct s3c_fb *parent; |
66 | struct fb_info *fbinfo; | 107 | struct fb_info *fbinfo; |
67 | struct s3c_fb_palette palette; | 108 | struct s3c_fb_palette palette; |
109 | struct s3c_fb_win_variant variant; | ||
68 | 110 | ||
69 | u32 *palette_buffer; | 111 | u32 *palette_buffer; |
70 | u32 pseudo_palette[16]; | 112 | u32 pseudo_palette[16]; |
@@ -77,6 +119,7 @@ struct s3c_fb_win { | |||
77 | * @regs_res: The resource we claimed for the IO registers. | 119 | * @regs_res: The resource we claimed for the IO registers. |
78 | * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. | 120 | * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. |
79 | * @regs: The mapped hardware registers. | 121 | * @regs: The mapped hardware registers. |
122 | * @variant: Variant information for this hardware. | ||
80 | * @enabled: A bitmask of enabled hardware windows. | 123 | * @enabled: A bitmask of enabled hardware windows. |
81 | * @pdata: The platform configuration data passed with the device. | 124 | * @pdata: The platform configuration data passed with the device. |
82 | * @windows: The hardware windows that have been claimed. | 125 | * @windows: The hardware windows that have been claimed. |
@@ -86,6 +129,7 @@ struct s3c_fb { | |||
86 | struct resource *regs_res; | 129 | struct resource *regs_res; |
87 | struct clk *bus_clk; | 130 | struct clk *bus_clk; |
88 | void __iomem *regs; | 131 | void __iomem *regs; |
132 | struct s3c_fb_variant variant; | ||
89 | 133 | ||
90 | unsigned char enabled; | 134 | unsigned char enabled; |
91 | 135 | ||
@@ -94,15 +138,13 @@ struct s3c_fb { | |||
94 | }; | 138 | }; |
95 | 139 | ||
96 | /** | 140 | /** |
97 | * s3c_fb_win_has_palette() - determine if a mode has a palette | 141 | * s3c_fb_validate_win_bpp - validate the bits-per-pixel for this mode. |
98 | * @win: The window number being queried. | 142 | * @win: The device window. |
99 | * @bpp: The number of bits per pixel to test. | 143 | * @bpp: The bit depth. |
100 | * | ||
101 | * Work out if the given window supports palletised data at the specified bpp. | ||
102 | */ | 144 | */ |
103 | static int s3c_fb_win_has_palette(unsigned int win, unsigned int bpp) | 145 | static bool s3c_fb_validate_win_bpp(struct s3c_fb_win *win, unsigned int bpp) |
104 | { | 146 | { |
105 | return s3c_fb_win_pal_size(win) <= (1 << bpp); | 147 | return win->variant.valid_bpp & VALID_BPP(bpp); |
106 | } | 148 | } |
107 | 149 | ||
108 | /** | 150 | /** |
@@ -125,7 +167,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, | |||
125 | var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres); | 167 | var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres); |
126 | var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres); | 168 | var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres); |
127 | 169 | ||
128 | if (!s3c_fb_validate_win_bpp(win->index, var->bits_per_pixel)) { | 170 | if (!s3c_fb_validate_win_bpp(win, var->bits_per_pixel)) { |
129 | dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", | 171 | dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", |
130 | win->index, var->bits_per_pixel); | 172 | win->index, var->bits_per_pixel); |
131 | return -EINVAL; | 173 | return -EINVAL; |
@@ -140,7 +182,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, | |||
140 | case 2: | 182 | case 2: |
141 | case 4: | 183 | case 4: |
142 | case 8: | 184 | case 8: |
143 | if (!s3c_fb_win_has_palette(win->index, var->bits_per_pixel)) { | 185 | if (sfb->variant.palette[win->index] != 0) { |
144 | /* non palletised, A:1,R:2,G:3,B:2 mode */ | 186 | /* non palletised, A:1,R:2,G:3,B:2 mode */ |
145 | var->red.offset = 4; | 187 | var->red.offset = 4; |
146 | var->green.offset = 2; | 188 | var->green.offset = 2; |
@@ -282,7 +324,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
282 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 324 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
283 | break; | 325 | break; |
284 | case 8: | 326 | case 8: |
285 | if (s3c_fb_win_has_palette(win_no, 8)) | 327 | if (win->variant.palette_sz >= 256) |
286 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | 328 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; |
287 | else | 329 | else |
288 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 330 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
@@ -364,7 +406,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
364 | VIDISD14C_ALPHA1_G(0xf) | | 406 | VIDISD14C_ALPHA1_G(0xf) | |
365 | VIDISD14C_ALPHA1_B(0xf); | 407 | VIDISD14C_ALPHA1_B(0xf); |
366 | 408 | ||
367 | if (s3c_fb_has_osd_d(win_no)) { | 409 | if (win->variant.has_osd_d) { |
368 | writel(data, regs + VIDOSD_D(win_no)); | 410 | writel(data, regs + VIDOSD_D(win_no)); |
369 | writel(osdc_data, regs + VIDOSD_C(win_no)); | 411 | writel(osdc_data, regs + VIDOSD_C(win_no)); |
370 | } else | 412 | } else |
@@ -471,7 +513,7 @@ static void s3c_fb_update_palette(struct s3c_fb *sfb, | |||
471 | void __iomem *palreg; | 513 | void __iomem *palreg; |
472 | u32 palcon; | 514 | u32 palcon; |
473 | 515 | ||
474 | palreg = sfb->regs + s3c_fb_pal_reg(win->index, reg); | 516 | palreg = sfb->regs + sfb->variant.palette[win->index]; |
475 | 517 | ||
476 | dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n", | 518 | dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n", |
477 | __func__, win->index, reg, palreg, value); | 519 | __func__, win->index, reg, palreg, value); |
@@ -481,10 +523,10 @@ static void s3c_fb_update_palette(struct s3c_fb *sfb, | |||
481 | palcon = readl(sfb->regs + WPALCON); | 523 | palcon = readl(sfb->regs + WPALCON); |
482 | writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON); | 524 | writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON); |
483 | 525 | ||
484 | if (s3c_fb_pal_is16(win->index)) | 526 | if (win->variant.palette_16bpp) |
485 | writew(value, palreg); | 527 | writew(value, palreg + (reg * 2)); |
486 | else | 528 | else |
487 | writel(value, palreg); | 529 | writel(value, palreg + (reg * 4)); |
488 | 530 | ||
489 | writel(palcon, sfb->regs + WPALCON); | 531 | writel(palcon, sfb->regs + WPALCON); |
490 | } | 532 | } |
@@ -533,7 +575,7 @@ static int s3c_fb_setcolreg(unsigned regno, | |||
533 | break; | 575 | break; |
534 | 576 | ||
535 | case FB_VISUAL_PSEUDOCOLOR: | 577 | case FB_VISUAL_PSEUDOCOLOR: |
536 | if (regno < s3c_fb_win_pal_size(win->index)) { | 578 | if (regno < win->variant.palette_sz) { |
537 | val = chan_to_field(red, &win->palette.r); | 579 | val = chan_to_field(red, &win->palette.r); |
538 | val |= chan_to_field(green, &win->palette.g); | 580 | val |= chan_to_field(green, &win->palette.g); |
539 | val |= chan_to_field(blue, &win->palette.b); | 581 | val |= chan_to_field(blue, &win->palette.b); |
@@ -736,12 +778,14 @@ static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) | |||
736 | /** | 778 | /** |
737 | * s3c_fb_probe_win() - register an hardware window | 779 | * s3c_fb_probe_win() - register an hardware window |
738 | * @sfb: The base resources for the hardware | 780 | * @sfb: The base resources for the hardware |
781 | * @variant: The variant information for this window. | ||
739 | * @res: Pointer to where to place the resultant window. | 782 | * @res: Pointer to where to place the resultant window. |
740 | * | 783 | * |
741 | * Allocate and do the basic initialisation for one of the hardware's graphics | 784 | * Allocate and do the basic initialisation for one of the hardware's graphics |
742 | * windows. | 785 | * windows. |
743 | */ | 786 | */ |
744 | static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, | 787 | static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, |
788 | struct s3c_fb_win_variant *variant, | ||
745 | struct s3c_fb_win **res) | 789 | struct s3c_fb_win **res) |
746 | { | 790 | { |
747 | struct fb_var_screeninfo *var; | 791 | struct fb_var_screeninfo *var; |
@@ -754,7 +798,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, | |||
754 | 798 | ||
755 | dev_dbg(sfb->dev, "probing window %d\n", win_no); | 799 | dev_dbg(sfb->dev, "probing window %d\n", win_no); |
756 | 800 | ||
757 | palette_size = s3c_fb_win_pal_size(win_no); | 801 | palette_size = variant->palette_sz * 4; |
758 | 802 | ||
759 | fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + | 803 | fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + |
760 | palette_size * sizeof(u32), sfb->dev); | 804 | palette_size * sizeof(u32), sfb->dev); |
@@ -772,6 +816,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, | |||
772 | 816 | ||
773 | win = fbinfo->par; | 817 | win = fbinfo->par; |
774 | var = &fbinfo->var; | 818 | var = &fbinfo->var; |
819 | win->variant = *variant; | ||
775 | win->fbinfo = fbinfo; | 820 | win->fbinfo = fbinfo; |
776 | win->parent = sfb; | 821 | win->parent = sfb; |
777 | win->windata = windata; | 822 | win->windata = windata; |
@@ -809,7 +854,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, | |||
809 | 854 | ||
810 | /* create initial colour map */ | 855 | /* create initial colour map */ |
811 | 856 | ||
812 | ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1); | 857 | ret = fb_alloc_cmap(&fbinfo->cmap, win->variant.palette_sz, 1); |
813 | if (ret == 0) | 858 | if (ret == 0) |
814 | fb_set_cmap(&fbinfo->cmap, fbinfo); | 859 | fb_set_cmap(&fbinfo->cmap, fbinfo); |
815 | else | 860 | else |
@@ -852,6 +897,7 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win) | |||
852 | 897 | ||
853 | static int __devinit s3c_fb_probe(struct platform_device *pdev) | 898 | static int __devinit s3c_fb_probe(struct platform_device *pdev) |
854 | { | 899 | { |
900 | struct s3c_fb_driverdata *fbdrv; | ||
855 | struct device *dev = &pdev->dev; | 901 | struct device *dev = &pdev->dev; |
856 | struct s3c_fb_platdata *pd; | 902 | struct s3c_fb_platdata *pd; |
857 | struct s3c_fb *sfb; | 903 | struct s3c_fb *sfb; |
@@ -859,6 +905,13 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
859 | int win; | 905 | int win; |
860 | int ret = 0; | 906 | int ret = 0; |
861 | 907 | ||
908 | fbdrv = (struct s3c_fb_driverdata *)platform_get_device_id(pdev)->driver_data; | ||
909 | |||
910 | if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) { | ||
911 | dev_err(dev, "too many windows, cannot attach\n"); | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | |||
862 | pd = pdev->dev.platform_data; | 915 | pd = pdev->dev.platform_data; |
863 | if (!pd) { | 916 | if (!pd) { |
864 | dev_err(dev, "no platform data specified\n"); | 917 | dev_err(dev, "no platform data specified\n"); |
@@ -873,6 +926,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
873 | 926 | ||
874 | sfb->dev = dev; | 927 | sfb->dev = dev; |
875 | sfb->pdata = pd; | 928 | sfb->pdata = pd; |
929 | sfb->variant = fbdrv->variant; | ||
876 | 930 | ||
877 | sfb->bus_clk = clk_get(dev, "lcd"); | 931 | sfb->bus_clk = clk_get(dev, "lcd"); |
878 | if (IS_ERR(sfb->bus_clk)) { | 932 | if (IS_ERR(sfb->bus_clk)) { |
@@ -914,22 +968,23 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
914 | 968 | ||
915 | /* zero all windows before we do anything */ | 969 | /* zero all windows before we do anything */ |
916 | 970 | ||
917 | for (win = 0; win < S3C_FB_MAX_WIN; win++) | 971 | for (win = 0; win < fbdrv->variant.nr_windows; win++) |
918 | s3c_fb_clear_win(sfb, win); | 972 | s3c_fb_clear_win(sfb, win); |
919 | 973 | ||
920 | /* initialise colour key controls */ | 974 | /* initialise colour key controls */ |
921 | for (win = 0; win < (S3C_FB_MAX_WIN - 1); win++) { | 975 | for (win = 0; win < (fbdrv->variant.nr_windows - 1); win++) { |
922 | writel(0xffffff, sfb->regs + WxKEYCONy(win, 0)); | 976 | writel(0xffffff, sfb->regs + WxKEYCONy(win, 0)); |
923 | writel(0xffffff, sfb->regs + WxKEYCONy(win, 1)); | 977 | writel(0xffffff, sfb->regs + WxKEYCONy(win, 1)); |
924 | } | 978 | } |
925 | 979 | ||
926 | /* we have the register setup, start allocating framebuffers */ | 980 | /* we have the register setup, start allocating framebuffers */ |
927 | 981 | ||
928 | for (win = 0; win < S3C_FB_MAX_WIN; win++) { | 982 | for (win = 0; win < fbdrv->variant.nr_windows; win++) { |
929 | if (!pd->win[win]) | 983 | if (!pd->win[win]) |
930 | continue; | 984 | continue; |
931 | 985 | ||
932 | ret = s3c_fb_probe_win(sfb, win, &sfb->windows[win]); | 986 | ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win], |
987 | &sfb->windows[win]); | ||
933 | if (ret < 0) { | 988 | if (ret < 0) { |
934 | dev_err(dev, "failed to create window %d\n", win); | 989 | dev_err(dev, "failed to create window %d\n", win); |
935 | for (; win >= 0; win--) | 990 | for (; win >= 0; win--) |
@@ -1020,10 +1075,10 @@ static int s3c_fb_resume(struct platform_device *pdev) | |||
1020 | writel(pd->vidcon1, sfb->regs + VIDCON1); | 1075 | writel(pd->vidcon1, sfb->regs + VIDCON1); |
1021 | 1076 | ||
1022 | /* zero all windows before we do anything */ | 1077 | /* zero all windows before we do anything */ |
1023 | for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) | 1078 | for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++) |
1024 | s3c_fb_clear_win(sfb, win_no); | 1079 | s3c_fb_clear_win(sfb, win_no); |
1025 | 1080 | ||
1026 | for (win_no = 0; win_no < S3C_FB_MAX_WIN - 1; win_no++) { | 1081 | for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) { |
1027 | writel(0xffffff, sfb->regs + WxKEYCONy(win_no, 1)); | 1082 | writel(0xffffff, sfb->regs + WxKEYCONy(win_no, 1)); |
1028 | writel(0xffffff, sfb->regs + WxKEYCONy(win_no, 1)); | 1083 | writel(0xffffff, sfb->regs + WxKEYCONy(win_no, 1)); |
1029 | } | 1084 | } |
@@ -1045,11 +1100,108 @@ static int s3c_fb_resume(struct platform_device *pdev) | |||
1045 | #define s3c_fb_resume NULL | 1100 | #define s3c_fb_resume NULL |
1046 | #endif | 1101 | #endif |
1047 | 1102 | ||
1103 | |||
1104 | #define VALID_BPP124 (VALID_BPP(1) | VALID_BPP(2) | VALID_BPP(4)) | ||
1105 | #define VALID_BPP1248 (VALID_BPP124 | VALID_BPP(8)) | ||
1106 | |||
1107 | static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] __devinitdata = { | ||
1108 | [0] = { | ||
1109 | .has_osd_c = 1, | ||
1110 | .palette_sz = 256, | ||
1111 | .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24), | ||
1112 | }, | ||
1113 | [1] = { | ||
1114 | .has_osd_c = 1, | ||
1115 | .has_osd_d = 1, | ||
1116 | .palette_sz = 256, | ||
1117 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | | ||
1118 | VALID_BPP(18) | VALID_BPP(19) | | ||
1119 | VALID_BPP(24) | VALID_BPP(25)), | ||
1120 | }, | ||
1121 | [2] = { | ||
1122 | .has_osd_c = 1, | ||
1123 | .has_osd_d = 1, | ||
1124 | .palette_sz = 16, | ||
1125 | .palette_16bpp = 1, | ||
1126 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | | ||
1127 | VALID_BPP(18) | VALID_BPP(19) | | ||
1128 | VALID_BPP(24) | VALID_BPP(25)), | ||
1129 | }, | ||
1130 | [3] = { | ||
1131 | .has_osd_c = 1, | ||
1132 | .has_osd_d = 1, | ||
1133 | .palette_sz = 16, | ||
1134 | .palette_16bpp = 1, | ||
1135 | .valid_bpp = (VALID_BPP124 | VALID_BPP(16) | | ||
1136 | VALID_BPP(18) | VALID_BPP(19) | | ||
1137 | VALID_BPP(24) | VALID_BPP(25)), | ||
1138 | }, | ||
1139 | [4] = { | ||
1140 | .has_osd_c = 1, | ||
1141 | .palette_sz = 4, | ||
1142 | .palette_16bpp = 1, | ||
1143 | .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) | | ||
1144 | VALID_BPP(16) | VALID_BPP(18) | | ||
1145 | VALID_BPP(24) | VALID_BPP(25)), | ||
1146 | }, | ||
1147 | }; | ||
1148 | |||
1149 | static struct s3c_fb_driverdata s3c_fb_data_64xx __devinitdata = { | ||
1150 | .variant = { | ||
1151 | .nr_windows = 5, | ||
1152 | |||
1153 | .palette = { | ||
1154 | [0] = 0x400, | ||
1155 | [1] = 0x800, | ||
1156 | [2] = 0x300, | ||
1157 | [3] = 0x320, | ||
1158 | [4] = 0x340, | ||
1159 | }, | ||
1160 | }, | ||
1161 | .win[0] = &s3c_fb_data_64xx_wins[0], | ||
1162 | .win[1] = &s3c_fb_data_64xx_wins[1], | ||
1163 | .win[2] = &s3c_fb_data_64xx_wins[2], | ||
1164 | .win[3] = &s3c_fb_data_64xx_wins[3], | ||
1165 | .win[4] = &s3c_fb_data_64xx_wins[4], | ||
1166 | }; | ||
1167 | |||
1168 | static struct s3c_fb_driverdata s3c_fb_data_s5p __devinitdata = { | ||
1169 | .variant = { | ||
1170 | .nr_windows = 5, | ||
1171 | |||
1172 | .palette = { | ||
1173 | [0] = 0x2400, | ||
1174 | [1] = 0x2800, | ||
1175 | [2] = 0x2c00, | ||
1176 | [3] = 0x3000, | ||
1177 | [4] = 0x3400, | ||
1178 | }, | ||
1179 | }, | ||
1180 | .win[0] = &s3c_fb_data_64xx_wins[0], | ||
1181 | .win[1] = &s3c_fb_data_64xx_wins[1], | ||
1182 | .win[2] = &s3c_fb_data_64xx_wins[2], | ||
1183 | .win[3] = &s3c_fb_data_64xx_wins[3], | ||
1184 | .win[4] = &s3c_fb_data_64xx_wins[4], | ||
1185 | }; | ||
1186 | |||
1187 | static struct platform_device_id s3c_fb_driver_ids[] = { | ||
1188 | { | ||
1189 | .name = "s3c-fb", | ||
1190 | .driver_data = (unsigned long)&s3c_fb_data_64xx, | ||
1191 | }, { | ||
1192 | .name = "s5p-fb", | ||
1193 | .driver_data = (unsigned long)&s3c_fb_data_s5p, | ||
1194 | }, | ||
1195 | {}, | ||
1196 | }; | ||
1197 | MODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids); | ||
1198 | |||
1048 | static struct platform_driver s3c_fb_driver = { | 1199 | static struct platform_driver s3c_fb_driver = { |
1049 | .probe = s3c_fb_probe, | 1200 | .probe = s3c_fb_probe, |
1050 | .remove = __devexit_p(s3c_fb_remove), | 1201 | .remove = __devexit_p(s3c_fb_remove), |
1051 | .suspend = s3c_fb_suspend, | 1202 | .suspend = s3c_fb_suspend, |
1052 | .resume = s3c_fb_resume, | 1203 | .resume = s3c_fb_resume, |
1204 | .id_table = s3c_fb_driver_ids, | ||
1053 | .driver = { | 1205 | .driver = { |
1054 | .name = "s3c-fb", | 1206 | .name = "s3c-fb", |
1055 | .owner = THIS_MODULE, | 1207 | .owner = THIS_MODULE, |