aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-04-07 15:49:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-04-07 15:49:17 -0400
commit132452ee2368cf775ccbef9746b51e3d2ba58b85 (patch)
tree68652e7a5d11776184e7b05c04dfc94baa429f2a /drivers
parent174457391a83d70215d441cb3bc0aa7d7443b63e (diff)
parent97fb85076c2d3adcc559dee577e0a3bf7215d48e (diff)
Merge branch 'fbdev-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
* 'fbdev-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6: efifb: Add override for 11" Macbook Air 3,1 efifb: Support overriding fields FW tells us with the DMI data. fb: Reduce priority of resource conflict message savagefb: Remove obsolete else clause in savage_setup_i2c_bus savagefb: Set up I2C based on chip family instead of card id savagefb: Replace magic register address with define drivers/video/bfin-lq035q1-fb.c: introduce missing kfree video: s3c-fb: fix checkpatch errors and warning efifb: support AMD Radeon HD 6490 s3fb: fix Virge/GX2 fbcon: Remove unused 'display *p' variable from fb_flashcursor() fbdev: sh_mobile_lcdcfb: fix module lock acquisition fbdev: sh_mobile_lcdcfb: add blanking support viafb: initialize margins correct viafb: refresh rate bug collection sh: mach-ap325rxa: move backlight control code sh: mach-ecovec24: support for main lcd backlight
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/bfin-lq035q1-fb.c4
-rw-r--r--drivers/video/console/fbcon.c2
-rw-r--r--drivers/video/efifb.c154
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/s3c-fb.c8
-rw-r--r--drivers/video/s3fb.c48
-rw-r--r--drivers/video/savage/savagefb-i2c.c14
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c52
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h1
-rw-r--r--drivers/video/via/chip.h1
-rw-r--r--drivers/video/via/hw.c17
-rw-r--r--drivers/video/via/hw.h3
-rw-r--r--drivers/video/via/viafbdev.c74
13 files changed, 238 insertions, 142 deletions
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index c8e1f04941b..23b6c4b62c7 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -154,8 +154,10 @@ static int __devinit lq035q1_spidev_probe(struct spi_device *spi)
154 154
155 ret = lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON); 155 ret = lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON);
156 ret |= lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode); 156 ret |= lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode);
157 if (ret) 157 if (ret) {
158 kfree(ctl);
158 return ret; 159 return ret;
160 }
159 161
160 spi_set_drvdata(spi, ctl); 162 spi_set_drvdata(spi, ctl);
161 163
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index c58393402da..8745637e4b7 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -370,7 +370,6 @@ static void fb_flashcursor(struct work_struct *work)
370{ 370{
371 struct fb_info *info = container_of(work, struct fb_info, queue); 371 struct fb_info *info = container_of(work, struct fb_info, queue);
372 struct fbcon_ops *ops = info->fbcon_par; 372 struct fbcon_ops *ops = info->fbcon_par;
373 struct display *p;
374 struct vc_data *vc = NULL; 373 struct vc_data *vc = NULL;
375 int c; 374 int c;
376 int mode; 375 int mode;
@@ -386,7 +385,6 @@ static void fb_flashcursor(struct work_struct *work)
386 return; 385 return;
387 } 386 }
388 387
389 p = &fb_display[vc->vc_num];
390 c = scr_readw((u16 *) vc->vc_pos); 388 c = scr_readw((u16 *) vc->vc_pos);
391 mode = (!ops->cursor_flash || ops->cursor_state.enable) ? 389 mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
392 CM_ERASE : CM_DRAW; 390 CM_ERASE : CM_DRAW;
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 70477c2e4b6..4eb38db36e4 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -53,6 +53,7 @@ enum {
53 M_MB_7_1, /* MacBook, 7th rev. */ 53 M_MB_7_1, /* MacBook, 7th rev. */
54 M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ 54 M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
55 M_MBA, /* MacBook Air */ 55 M_MBA, /* MacBook Air */
56 M_MBA_3, /* Macbook Air, 3rd rev */
56 M_MBP, /* MacBook Pro */ 57 M_MBP, /* MacBook Pro */
57 M_MBP_2, /* MacBook Pro 2nd gen */ 58 M_MBP_2, /* MacBook Pro 2nd gen */
58 M_MBP_2_2, /* MacBook Pro 2,2nd gen */ 59 M_MBP_2_2, /* MacBook Pro 2,2nd gen */
@@ -64,43 +65,54 @@ enum {
64 M_MBP_6_1, /* MacBook Pro, 6,1th gen */ 65 M_MBP_6_1, /* MacBook Pro, 6,1th gen */
65 M_MBP_6_2, /* MacBook Pro, 6,2th gen */ 66 M_MBP_6_2, /* MacBook Pro, 6,2th gen */
66 M_MBP_7_1, /* MacBook Pro, 7,1th gen */ 67 M_MBP_7_1, /* MacBook Pro, 7,1th gen */
68 M_MBP_8_2, /* MacBook Pro, 8,2nd gen */
67 M_UNKNOWN /* placeholder */ 69 M_UNKNOWN /* placeholder */
68}; 70};
69 71
72#define OVERRIDE_NONE 0x0
73#define OVERRIDE_BASE 0x1
74#define OVERRIDE_STRIDE 0x2
75#define OVERRIDE_HEIGHT 0x4
76#define OVERRIDE_WIDTH 0x8
77
70static struct efifb_dmi_info { 78static struct efifb_dmi_info {
71 char *optname; 79 char *optname;
72 unsigned long base; 80 unsigned long base;
73 int stride; 81 int stride;
74 int width; 82 int width;
75 int height; 83 int height;
84 int flags;
76} dmi_list[] __initdata = { 85} dmi_list[] __initdata = {
77 [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 }, 86 [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
78 [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ 87 [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */
79 [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, 88 [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE },
80 [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ 89 [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */
81 [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 }, 90 [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
82 [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 }, 91 [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE },
83 [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 }, 92 [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE },
84 [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, 93 [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE },
85 [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 }, 94 [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE },
86 [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 }, 95 [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
87 [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, 96 [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
88 [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 }, 97 [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
89 [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 }, 98 [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
90 [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 }, 99 [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
91 [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, 100 [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
92 [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, 101 /* 11" Macbook Air 3,1 passes the wrong stride */
93 [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ 102 [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE },
94 [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 }, 103 [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
95 [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, 104 [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */
96 [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, 105 [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
97 [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 }, 106 [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
98 [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 }, 107 [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
99 [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 }, 108 [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
100 [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 }, 109 [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
101 [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 }, 110 [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
102 [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 }, 111 [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
103 [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } 112 [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE },
113 [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
114 [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
115 [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE }
104}; 116};
105 117
106static int set_system(const struct dmi_system_id *id); 118static int set_system(const struct dmi_system_id *id);
@@ -138,6 +150,7 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
138 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), 150 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
139 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), 151 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
140 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), 152 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
153 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3),
141 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), 154 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
142 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), 155 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
143 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), 156 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
@@ -151,19 +164,26 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
151 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), 164 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1),
152 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), 165 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2),
153 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), 166 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1),
167 EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2),
154 {}, 168 {},
155}; 169};
156 170
171#define choose_value(dmivalue, fwvalue, field, flags) ({ \
172 typeof(fwvalue) _ret_ = fwvalue; \
173 if ((flags) & (field)) \
174 _ret_ = dmivalue; \
175 else if ((fwvalue) == 0) \
176 _ret_ = dmivalue; \
177 _ret_; \
178 })
179
157static int set_system(const struct dmi_system_id *id) 180static int set_system(const struct dmi_system_id *id)
158{ 181{
159 struct efifb_dmi_info *info = id->driver_data; 182 struct efifb_dmi_info *info = id->driver_data;
160 if (info->base == 0)
161 return 0;
162 183
163 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " 184 if (info->base == 0 && info->height == 0 && info->width == 0
164 "(%dx%d, stride %d)\n", id->ident, 185 && info->stride == 0)
165 (void *)info->base, info->width, info->height, 186 return 0;
166 info->stride);
167 187
168 /* Trust the bootloader over the DMI tables */ 188 /* Trust the bootloader over the DMI tables */
169 if (screen_info.lfb_base == 0) { 189 if (screen_info.lfb_base == 0) {
@@ -171,40 +191,47 @@ static int set_system(const struct dmi_system_id *id)
171 struct pci_dev *dev = NULL; 191 struct pci_dev *dev = NULL;
172 int found_bar = 0; 192 int found_bar = 0;
173#endif 193#endif
174 screen_info.lfb_base = info->base; 194 if (info->base) {
195 screen_info.lfb_base = choose_value(info->base,
196 screen_info.lfb_base, OVERRIDE_BASE,
197 info->flags);
175 198
176#if defined(CONFIG_PCI) 199#if defined(CONFIG_PCI)
177 /* make sure that the address in the table is actually on a 200 /* make sure that the address in the table is actually
178 * VGA device's PCI BAR */ 201 * on a VGA device's PCI BAR */
179 202
180 for_each_pci_dev(dev) { 203 for_each_pci_dev(dev) {
181 int i; 204 int i;
182 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) 205 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
183 continue; 206 continue;
184 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 207 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
185 resource_size_t start, end; 208 resource_size_t start, end;
186 209
187 start = pci_resource_start(dev, i); 210 start = pci_resource_start(dev, i);
188 if (start == 0) 211 if (start == 0)
189 break; 212 break;
190 end = pci_resource_end(dev, i); 213 end = pci_resource_end(dev, i);
191 if (screen_info.lfb_base >= start && 214 if (screen_info.lfb_base >= start &&
192 screen_info.lfb_base < end) { 215 screen_info.lfb_base < end) {
193 found_bar = 1; 216 found_bar = 1;
217 }
194 } 218 }
195 } 219 }
196 } 220 if (!found_bar)
197 if (!found_bar) 221 screen_info.lfb_base = 0;
198 screen_info.lfb_base = 0;
199#endif 222#endif
223 }
200 } 224 }
201 if (screen_info.lfb_base) { 225 if (screen_info.lfb_base) {
202 if (screen_info.lfb_linelength == 0) 226 screen_info.lfb_linelength = choose_value(info->stride,
203 screen_info.lfb_linelength = info->stride; 227 screen_info.lfb_linelength, OVERRIDE_STRIDE,
204 if (screen_info.lfb_width == 0) 228 info->flags);
205 screen_info.lfb_width = info->width; 229 screen_info.lfb_width = choose_value(info->width,
206 if (screen_info.lfb_height == 0) 230 screen_info.lfb_width, OVERRIDE_WIDTH,
207 screen_info.lfb_height = info->height; 231 info->flags);
232 screen_info.lfb_height = choose_value(info->height,
233 screen_info.lfb_height, OVERRIDE_HEIGHT,
234 info->flags);
208 if (screen_info.orig_video_isVGA == 0) 235 if (screen_info.orig_video_isVGA == 0)
209 screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; 236 screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
210 } else { 237 } else {
@@ -214,6 +241,13 @@ static int set_system(const struct dmi_system_id *id)
214 screen_info.orig_video_isVGA = 0; 241 screen_info.orig_video_isVGA = 0;
215 return 0; 242 return 0;
216 } 243 }
244
245 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
246 "(%dx%d, stride %d)\n", id->ident,
247 (void *)screen_info.lfb_base, screen_info.lfb_width,
248 screen_info.lfb_height, screen_info.lfb_linelength);
249
250
217 return 1; 251 return 1;
218} 252}
219 253
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e2bf95370e4..e0c2284924b 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1507,7 +1507,7 @@ void remove_conflicting_framebuffers(struct apertures_struct *a,
1507 (primary && gen_aper && gen_aper->count && 1507 (primary && gen_aper && gen_aper->count &&
1508 gen_aper->ranges[0].base == VGA_FB_PHYS)) { 1508 gen_aper->ranges[0].base == VGA_FB_PHYS)) {
1509 1509
1510 printk(KERN_ERR "fb: conflicting fb hw usage " 1510 printk(KERN_INFO "fb: conflicting fb hw usage "
1511 "%s vs %s - removing generic driver\n", 1511 "%s vs %s - removing generic driver\n",
1512 name, registered_fb[i]->fix.id); 1512 name, registered_fb[i]->fix.id);
1513 unregister_framebuffer(registered_fb[i]); 1513 unregister_framebuffer(registered_fb[i]);
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 6817d187d46..3b6cdcac8f1 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -48,7 +48,7 @@
48#undef writel 48#undef writel
49#define writel(v, r) do { \ 49#define writel(v, r) do { \
50 printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \ 50 printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
51 __raw_writel(v, r); } while(0) 51 __raw_writel(v, r); } while (0)
52#endif /* FB_S3C_DEBUG_REGWRITE */ 52#endif /* FB_S3C_DEBUG_REGWRITE */
53 53
54/* irq_flags bits */ 54/* irq_flags bits */
@@ -518,7 +518,7 @@ static int s3c_fb_set_par(struct fb_info *info)
518 518
519 data = VIDTCON2_LINEVAL(var->yres - 1) | 519 data = VIDTCON2_LINEVAL(var->yres - 1) |
520 VIDTCON2_HOZVAL(var->xres - 1); 520 VIDTCON2_HOZVAL(var->xres - 1);
521 writel(data, regs +sfb->variant.vidtcon + 8 ); 521 writel(data, regs + sfb->variant.vidtcon + 8);
522 } 522 }
523 523
524 /* write the buffer address */ 524 /* write the buffer address */
@@ -1304,6 +1304,7 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
1304 1304
1305static int __devinit s3c_fb_probe(struct platform_device *pdev) 1305static int __devinit s3c_fb_probe(struct platform_device *pdev)
1306{ 1306{
1307 const struct platform_device_id *platid;
1307 struct s3c_fb_driverdata *fbdrv; 1308 struct s3c_fb_driverdata *fbdrv;
1308 struct device *dev = &pdev->dev; 1309 struct device *dev = &pdev->dev;
1309 struct s3c_fb_platdata *pd; 1310 struct s3c_fb_platdata *pd;
@@ -1312,7 +1313,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1312 int win; 1313 int win;
1313 int ret = 0; 1314 int ret = 0;
1314 1315
1315 fbdrv = (struct s3c_fb_driverdata *)platform_get_device_id(pdev)->driver_data; 1316 platid = platform_get_device_id(pdev);
1317 fbdrv = (struct s3c_fb_driverdata *)platid->driver_data;
1316 1318
1317 if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) { 1319 if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) {
1318 dev_err(dev, "too many windows, cannot attach\n"); 1320 dev_err(dev, "too many windows, cannot attach\n");
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index ddedad9cd06..c4482f2e579 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -71,9 +71,9 @@ static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
71 71
72static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+", 72static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+",
73 "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX", 73 "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX",
74 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", 74 "S3 Plato/PX", "S3 Aurora64V+", "S3 Virge",
75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
76 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P", 76 "S3 Virge/GX2", "S3 Virge/GX2+", "",
77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X", 77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
78 "S3 Trio3D"}; 78 "S3 Trio3D"};
79 79
@@ -90,9 +90,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
90#define CHIP_988_VIRGE_VX 0x0A 90#define CHIP_988_VIRGE_VX 0x0A
91#define CHIP_375_VIRGE_DX 0x0B 91#define CHIP_375_VIRGE_DX 0x0B
92#define CHIP_385_VIRGE_GX 0x0C 92#define CHIP_385_VIRGE_GX 0x0C
93#define CHIP_356_VIRGE_GX2 0x0D 93#define CHIP_357_VIRGE_GX2 0x0D
94#define CHIP_357_VIRGE_GX2P 0x0E 94#define CHIP_359_VIRGE_GX2P 0x0E
95#define CHIP_359_VIRGE_GX2P 0x0F
96#define CHIP_360_TRIO3D_1X 0x10 95#define CHIP_360_TRIO3D_1X 0x10
97#define CHIP_362_TRIO3D_2X 0x11 96#define CHIP_362_TRIO3D_2X 0x11
98#define CHIP_368_TRIO3D_2X 0x12 97#define CHIP_368_TRIO3D_2X 0x12
@@ -359,7 +358,9 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
359 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 358 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
360 359
361 /* Set S3 clock registers */ 360 /* Set S3 clock registers */
362 if (par->chip == CHIP_360_TRIO3D_1X || 361 if (par->chip == CHIP_357_VIRGE_GX2 ||
362 par->chip == CHIP_359_VIRGE_GX2P ||
363 par->chip == CHIP_360_TRIO3D_1X ||
363 par->chip == CHIP_362_TRIO3D_2X || 364 par->chip == CHIP_362_TRIO3D_2X ||
364 par->chip == CHIP_368_TRIO3D_2X) { 365 par->chip == CHIP_368_TRIO3D_2X) {
365 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 366 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
@@ -560,7 +561,9 @@ static int s3fb_set_par(struct fb_info *info)
560 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 561 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
561 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value); 562 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);
562 563
563 if (par->chip != CHIP_360_TRIO3D_1X && 564 if (par->chip != CHIP_357_VIRGE_GX2 &&
565 par->chip != CHIP_359_VIRGE_GX2P &&
566 par->chip != CHIP_360_TRIO3D_1X &&
564 par->chip != CHIP_362_TRIO3D_2X && 567 par->chip != CHIP_362_TRIO3D_2X &&
565 par->chip != CHIP_368_TRIO3D_2X) { 568 par->chip != CHIP_368_TRIO3D_2X) {
566 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ 569 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
@@ -604,7 +607,9 @@ static int s3fb_set_par(struct fb_info *info)
604 vga_wcrt(par->state.vgabase, 0x66, 0x90); 607 vga_wcrt(par->state.vgabase, 0x66, 0x90);
605 } 608 }
606 609
607 if (par->chip == CHIP_360_TRIO3D_1X || 610 if (par->chip == CHIP_357_VIRGE_GX2 ||
611 par->chip == CHIP_359_VIRGE_GX2P ||
612 par->chip == CHIP_360_TRIO3D_1X ||
608 par->chip == CHIP_362_TRIO3D_2X || 613 par->chip == CHIP_362_TRIO3D_2X ||
609 par->chip == CHIP_368_TRIO3D_2X || 614 par->chip == CHIP_368_TRIO3D_2X ||
610 par->chip == CHIP_365_TRIO3D || 615 par->chip == CHIP_365_TRIO3D ||
@@ -617,8 +622,7 @@ static int s3fb_set_par(struct fb_info *info)
617 vga_wcrt(par->state.vgabase, 0x66, 0x81); 622 vga_wcrt(par->state.vgabase, 0x66, 0x81);
618 } 623 }
619 624
620 if (par->chip == CHIP_356_VIRGE_GX2 || 625 if (par->chip == CHIP_357_VIRGE_GX2 ||
621 par->chip == CHIP_357_VIRGE_GX2P ||
622 par->chip == CHIP_359_VIRGE_GX2P || 626 par->chip == CHIP_359_VIRGE_GX2P ||
623 par->chip == CHIP_360_TRIO3D_1X || 627 par->chip == CHIP_360_TRIO3D_1X ||
624 par->chip == CHIP_362_TRIO3D_2X || 628 par->chip == CHIP_362_TRIO3D_2X ||
@@ -674,6 +678,8 @@ static int s3fb_set_par(struct fb_info *info)
674 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 678 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
675 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 679 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
676 if (info->var.pixclock > 20000 || 680 if (info->var.pixclock > 20000 ||
681 par->chip == CHIP_357_VIRGE_GX2 ||
682 par->chip == CHIP_359_VIRGE_GX2P ||
677 par->chip == CHIP_360_TRIO3D_1X || 683 par->chip == CHIP_360_TRIO3D_1X ||
678 par->chip == CHIP_362_TRIO3D_2X || 684 par->chip == CHIP_362_TRIO3D_2X ||
679 par->chip == CHIP_368_TRIO3D_2X) 685 par->chip == CHIP_368_TRIO3D_2X)
@@ -702,7 +708,9 @@ static int s3fb_set_par(struct fb_info *info)
702 } else { 708 } else {
703 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 709 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
704 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); 710 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
705 if (par->chip != CHIP_360_TRIO3D_1X && 711 if (par->chip != CHIP_357_VIRGE_GX2 &&
712 par->chip != CHIP_359_VIRGE_GX2P &&
713 par->chip != CHIP_360_TRIO3D_1X &&
706 par->chip != CHIP_362_TRIO3D_2X && 714 par->chip != CHIP_362_TRIO3D_2X &&
707 par->chip != CHIP_368_TRIO3D_2X) 715 par->chip != CHIP_368_TRIO3D_2X)
708 hmul = 2; 716 hmul = 2;
@@ -727,7 +735,9 @@ static int s3fb_set_par(struct fb_info *info)
727 } else { 735 } else {
728 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 736 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
729 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); 737 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
730 if (par->chip != CHIP_360_TRIO3D_1X && 738 if (par->chip != CHIP_357_VIRGE_GX2 &&
739 par->chip != CHIP_359_VIRGE_GX2P &&
740 par->chip != CHIP_360_TRIO3D_1X &&
731 par->chip != CHIP_362_TRIO3D_2X && 741 par->chip != CHIP_362_TRIO3D_2X &&
732 par->chip != CHIP_368_TRIO3D_2X) 742 par->chip != CHIP_368_TRIO3D_2X)
733 hmul = 2; 743 hmul = 2;
@@ -1069,6 +1079,16 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1069 info->screen_size = 2 << 20; 1079 info->screen_size = 2 << 20;
1070 break; 1080 break;
1071 } 1081 }
1082 } else if (par->chip == CHIP_357_VIRGE_GX2 ||
1083 par->chip == CHIP_359_VIRGE_GX2P) {
1084 switch ((regval & 0xC0) >> 6) {
1085 case 1: /* 4MB */
1086 info->screen_size = 4 << 20;
1087 break;
1088 case 3: /* 2MB */
1089 info->screen_size = 2 << 20;
1090 break;
1091 }
1072 } else 1092 } else
1073 info->screen_size = s3_memsizes[regval >> 5] << 10; 1093 info->screen_size = s3_memsizes[regval >> 5] << 10;
1074 info->fix.smem_len = info->screen_size; 1094 info->fix.smem_len = info->screen_size;
@@ -1268,8 +1288,8 @@ static struct pci_device_id s3_devices[] __devinitdata = {
1268 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE}, 1288 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE},
1269 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX}, 1289 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX},
1270 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX}, 1290 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX},
1271 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_356_VIRGE_GX2}, 1291 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_357_VIRGE_GX2},
1272 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, 1292 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_359_VIRGE_GX2P},
1273 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1293 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
1274 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1294 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
1275 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D}, 1295 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index b16e6138fdd..bb71fea0728 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -159,8 +159,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
159 else 159 else
160 dev_warn(&chan->par->pcidev->dev, 160 dev_warn(&chan->par->pcidev->dev,
161 "Failed to register I2C bus %s.\n", name); 161 "Failed to register I2C bus %s.\n", name);
162 } else 162 }
163 chan->par = NULL;
164 163
165 return rc; 164 return rc;
166} 165}
@@ -170,9 +169,8 @@ void savagefb_create_i2c_busses(struct fb_info *info)
170 struct savagefb_par *par = info->par; 169 struct savagefb_par *par = info->par;
171 par->chan.par = par; 170 par->chan.par = par;
172 171
173 switch(info->fix.accel) { 172 switch (par->chip) {
174 case FB_ACCEL_PROSAVAGE_DDRK: 173 case S3_PROSAVAGE:
175 case FB_ACCEL_PROSAVAGE_PM:
176 par->chan.reg = CR_SERIAL2; 174 par->chan.reg = CR_SERIAL2;
177 par->chan.ioaddr = par->mmio.vbase; 175 par->chan.ioaddr = par->mmio.vbase;
178 par->chan.algo.setsda = prosavage_gpio_setsda; 176 par->chan.algo.setsda = prosavage_gpio_setsda;
@@ -180,7 +178,7 @@ void savagefb_create_i2c_busses(struct fb_info *info)
180 par->chan.algo.getsda = prosavage_gpio_getsda; 178 par->chan.algo.getsda = prosavage_gpio_getsda;
181 par->chan.algo.getscl = prosavage_gpio_getscl; 179 par->chan.algo.getscl = prosavage_gpio_getscl;
182 break; 180 break;
183 case FB_ACCEL_SAVAGE4: 181 case S3_SAVAGE4:
184 par->chan.reg = CR_SERIAL1; 182 par->chan.reg = CR_SERIAL1;
185 if (par->pcidev->revision > 1 && !(VGArCR(0xa6, par) & 0x40)) 183 if (par->pcidev->revision > 1 && !(VGArCR(0xa6, par) & 0x40))
186 par->chan.reg = CR_SERIAL2; 184 par->chan.reg = CR_SERIAL2;
@@ -190,8 +188,8 @@ void savagefb_create_i2c_busses(struct fb_info *info)
190 par->chan.algo.getsda = prosavage_gpio_getsda; 188 par->chan.algo.getsda = prosavage_gpio_getsda;
191 par->chan.algo.getscl = prosavage_gpio_getscl; 189 par->chan.algo.getscl = prosavage_gpio_getscl;
192 break; 190 break;
193 case FB_ACCEL_SAVAGE2000: 191 case S3_SAVAGE2000:
194 par->chan.reg = 0xff20; 192 par->chan.reg = MM_SERIAL1;
195 par->chan.ioaddr = par->mmio.vbase; 193 par->chan.ioaddr = par->mmio.vbase;
196 par->chan.algo.setsda = savage4_gpio_setsda; 194 par->chan.algo.setsda = savage4_gpio_setsda;
197 par->chan.algo.setscl = savage4_gpio_setscl; 195 par->chan.algo.setscl = savage4_gpio_setscl;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 757665bc500..9bcc61b4ef1 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -643,7 +643,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
643 continue; 643 continue;
644 644
645 board_cfg = &ch->cfg.board_cfg; 645 board_cfg = &ch->cfg.board_cfg;
646 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 646 if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
647 board_cfg->display_on(board_cfg->board_data, ch->info); 647 board_cfg->display_on(board_cfg->board_data, ch->info);
648 module_put(board_cfg->owner); 648 module_put(board_cfg->owner);
649 } 649 }
@@ -688,7 +688,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
688 } 688 }
689 689
690 board_cfg = &ch->cfg.board_cfg; 690 board_cfg = &ch->cfg.board_cfg;
691 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 691 if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
692 board_cfg->display_off(board_cfg->board_data); 692 board_cfg->display_off(board_cfg->board_data);
693 module_put(board_cfg->owner); 693 module_put(board_cfg->owner);
694 } 694 }
@@ -1032,6 +1032,49 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1032 return 0; 1032 return 0;
1033} 1033}
1034 1034
1035/*
1036 * Screen blanking. Behavior is as follows:
1037 * FB_BLANK_UNBLANK: screen unblanked, clocks enabled
1038 * FB_BLANK_NORMAL: screen blanked, clocks enabled
1039 * FB_BLANK_VSYNC,
1040 * FB_BLANK_HSYNC,
1041 * FB_BLANK_POWEROFF: screen blanked, clocks disabled
1042 */
1043static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
1044{
1045 struct sh_mobile_lcdc_chan *ch = info->par;
1046 struct sh_mobile_lcdc_priv *p = ch->lcdc;
1047
1048 /* blank the screen? */
1049 if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) {
1050 struct fb_fillrect rect = {
1051 .width = info->var.xres,
1052 .height = info->var.yres,
1053 };
1054 sh_mobile_lcdc_fillrect(info, &rect);
1055 }
1056 /* turn clocks on? */
1057 if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) {
1058 sh_mobile_lcdc_clk_on(p);
1059 }
1060 /* turn clocks off? */
1061 if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) {
1062 /* make sure the screen is updated with the black fill before
1063 * switching the clocks off. one vsync is not enough since
1064 * blanking may occur in the middle of a refresh. deferred io
1065 * mode will reenable the clocks and update the screen in time,
1066 * so it does not need this. */
1067 if (!info->fbdefio) {
1068 sh_mobile_wait_for_vsync(info);
1069 sh_mobile_wait_for_vsync(info);
1070 }
1071 sh_mobile_lcdc_clk_off(p);
1072 }
1073
1074 ch->blank_status = blank;
1075 return 0;
1076}
1077
1035static struct fb_ops sh_mobile_lcdc_ops = { 1078static struct fb_ops sh_mobile_lcdc_ops = {
1036 .owner = THIS_MODULE, 1079 .owner = THIS_MODULE,
1037 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 1080 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -1040,6 +1083,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
1040 .fb_fillrect = sh_mobile_lcdc_fillrect, 1083 .fb_fillrect = sh_mobile_lcdc_fillrect,
1041 .fb_copyarea = sh_mobile_lcdc_copyarea, 1084 .fb_copyarea = sh_mobile_lcdc_copyarea,
1042 .fb_imageblit = sh_mobile_lcdc_imageblit, 1085 .fb_imageblit = sh_mobile_lcdc_imageblit,
1086 .fb_blank = sh_mobile_lcdc_blank,
1043 .fb_pan_display = sh_mobile_fb_pan_display, 1087 .fb_pan_display = sh_mobile_fb_pan_display,
1044 .fb_ioctl = sh_mobile_ioctl, 1088 .fb_ioctl = sh_mobile_ioctl,
1045 .fb_open = sh_mobile_open, 1089 .fb_open = sh_mobile_open,
@@ -1254,7 +1298,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1254 1298
1255 switch(action) { 1299 switch(action) {
1256 case FB_EVENT_SUSPEND: 1300 case FB_EVENT_SUSPEND:
1257 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 1301 if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
1258 board_cfg->display_off(board_cfg->board_data); 1302 board_cfg->display_off(board_cfg->board_data);
1259 module_put(board_cfg->owner); 1303 module_put(board_cfg->owner);
1260 } 1304 }
@@ -1267,7 +1311,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1267 mutex_unlock(&ch->open_lock); 1311 mutex_unlock(&ch->open_lock);
1268 1312
1269 /* HDMI must be enabled before LCDC configuration */ 1313 /* HDMI must be enabled before LCDC configuration */
1270 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 1314 if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
1271 board_cfg->display_on(board_cfg->board_data, info); 1315 board_cfg->display_on(board_cfg->board_data, info);
1272 module_put(board_cfg->owner); 1316 module_put(board_cfg->owner);
1273 } 1317 }
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 4635eed63ee..f16cb5645a1 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -37,6 +37,7 @@ struct sh_mobile_lcdc_chan {
37 struct completion vsync_completion; 37 struct completion vsync_completion;
38 struct fb_var_screeninfo display_var; 38 struct fb_var_screeninfo display_var;
39 int use_count; 39 int use_count;
40 int blank_status;
40 struct mutex open_lock; /* protects the use counter */ 41 struct mutex open_lock; /* protects the use counter */
41}; 42};
42 43
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index 781f3aa66b4..29d70244a21 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -139,7 +139,6 @@ struct chip_information {
139 139
140struct crt_setting_information { 140struct crt_setting_information {
141 int iga_path; 141 int iga_path;
142 int refresh_rate;
143}; 142};
144 143
145struct tmds_setting_information { 144struct tmds_setting_information {
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 5728fd76bc1..dc4c778877c 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -2002,13 +2002,15 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2002 int i; 2002 int i;
2003 int index = 0; 2003 int index = 0;
2004 int h_addr, v_addr; 2004 int h_addr, v_addr;
2005 u32 pll_D_N, clock; 2005 u32 pll_D_N, clock, refresh = viafb_refresh;
2006
2007 if (viafb_SAMM_ON && set_iga == IGA2)
2008 refresh = viafb_refresh1;
2006 2009
2007 for (i = 0; i < video_mode->mode_array; i++) { 2010 for (i = 0; i < video_mode->mode_array; i++) {
2008 index = i; 2011 index = i;
2009 2012
2010 if (crt_table[i].refresh_rate == viaparinfo-> 2013 if (crt_table[i].refresh_rate == refresh)
2011 crt_setting_info->refresh_rate)
2012 break; 2014 break;
2013 } 2015 }
2014 2016
@@ -2019,7 +2021,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2019 if ((viafb_LCD_ON | viafb_DVI_ON) 2021 if ((viafb_LCD_ON | viafb_DVI_ON)
2020 && video_mode->crtc[0].crtc.hor_addr == 640 2022 && video_mode->crtc[0].crtc.hor_addr == 640
2021 && video_mode->crtc[0].crtc.ver_addr == 480 2023 && video_mode->crtc[0].crtc.ver_addr == 480
2022 && viaparinfo->crt_setting_info->refresh_rate == 60) { 2024 && refresh == 60) {
2023 /* The border is 8 pixels. */ 2025 /* The border is 8 pixels. */
2024 crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8; 2026 crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
2025 2027
@@ -2070,7 +2072,6 @@ void __devinit viafb_init_chip_info(int chip_type)
2070 init_lvds_chip_info(); 2072 init_lvds_chip_info();
2071 2073
2072 viaparinfo->crt_setting_info->iga_path = IGA1; 2074 viaparinfo->crt_setting_info->iga_path = IGA1;
2073 viaparinfo->crt_setting_info->refresh_rate = viafb_refresh;
2074 2075
2075 /*Set IGA path for each device */ 2076 /*Set IGA path for each device */
2076 viafb_set_iga_path(); 2077 viafb_set_iga_path();
@@ -2083,13 +2084,9 @@ void __devinit viafb_init_chip_info(int chip_type)
2083 viaparinfo->lvds_setting_info->lcd_mode; 2084 viaparinfo->lvds_setting_info->lcd_mode;
2084} 2085}
2085 2086
2086void viafb_update_device_setting(int hres, int vres, 2087void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
2087 int bpp, int vmode_refresh, int flag)
2088{ 2088{
2089 if (flag == 0) { 2089 if (flag == 0) {
2090 viaparinfo->crt_setting_info->refresh_rate =
2091 vmode_refresh;
2092
2093 viaparinfo->tmds_setting_info->h_active = hres; 2090 viaparinfo->tmds_setting_info->h_active = hres;
2094 viaparinfo->tmds_setting_info->v_active = vres; 2091 viaparinfo->tmds_setting_info->v_active = vres;
2095 2092
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 7295263299f..8858593405a 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -949,8 +949,7 @@ void __devinit viafb_init_chip_info(int chip_type);
949void __devinit viafb_init_dac(int set_iga); 949void __devinit viafb_init_dac(int set_iga);
950int viafb_get_pixclock(int hres, int vres, int vmode_refresh); 950int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
951int viafb_get_refresh(int hres, int vres, u32 float_refresh); 951int viafb_get_refresh(int hres, int vres, u32 float_refresh);
952void viafb_update_device_setting(int hres, int vres, int bpp, 952void viafb_update_device_setting(int hres, int vres, int bpp, int flag);
953 int vmode_refresh, int flag);
954 953
955void viafb_set_iga_path(void); 954void viafb_set_iga_path(void);
956void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue); 955void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue);
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index b64818953aa..a542bed086e 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -182,13 +182,24 @@ static int viafb_release(struct fb_info *info, int user)
182 return 0; 182 return 0;
183} 183}
184 184
185static inline int get_var_refresh(struct fb_var_screeninfo *var)
186{
187 u32 htotal, vtotal;
188
189 htotal = var->left_margin + var->xres + var->right_margin
190 + var->hsync_len;
191 vtotal = var->upper_margin + var->yres + var->lower_margin
192 + var->vsync_len;
193 return PICOS2KHZ(var->pixclock) * 1000 / (htotal * vtotal);
194}
195
185static int viafb_check_var(struct fb_var_screeninfo *var, 196static int viafb_check_var(struct fb_var_screeninfo *var,
186 struct fb_info *info) 197 struct fb_info *info)
187{ 198{
188 int htotal, vtotal, depth; 199 int depth, refresh;
189 struct VideoModeTable *vmode_entry; 200 struct VideoModeTable *vmode_entry;
190 struct viafb_par *ppar = info->par; 201 struct viafb_par *ppar = info->par;
191 u32 long_refresh, line; 202 u32 line;
192 203
193 DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); 204 DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
194 /* Sanity check */ 205 /* Sanity check */
@@ -231,17 +242,11 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
231 /* Based on var passed in to calculate the refresh, 242 /* Based on var passed in to calculate the refresh,
232 * because our driver use some modes special. 243 * because our driver use some modes special.
233 */ 244 */
234 htotal = var->xres + var->left_margin + 245 refresh = viafb_get_refresh(var->xres, var->yres,
235 var->right_margin + var->hsync_len; 246 get_var_refresh(var));
236 vtotal = var->yres + var->upper_margin +
237 var->lower_margin + var->vsync_len;
238 long_refresh = 1000000000UL / var->pixclock * 1000;
239 long_refresh /= (htotal * vtotal);
240
241 viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);
242 247
243 /* Adjust var according to our driver's own table */ 248 /* Adjust var according to our driver's own table */
244 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); 249 viafb_fill_var_timing_info(var, refresh, vmode_entry);
245 if (var->accel_flags & FB_ACCELF_TEXT && 250 if (var->accel_flags & FB_ACCELF_TEXT &&
246 !ppar->shared->vdev->engine_mmio) 251 !ppar->shared->vdev->engine_mmio)
247 var->accel_flags = 0; 252 var->accel_flags = 0;
@@ -253,12 +258,13 @@ static int viafb_set_par(struct fb_info *info)
253{ 258{
254 struct viafb_par *viapar = info->par; 259 struct viafb_par *viapar = info->par;
255 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL; 260 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
261 int refresh;
256 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 262 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
257 263
258 viafb_update_fix(info); 264 viafb_update_fix(info);
259 viapar->depth = fb_get_color_depth(&info->var, &info->fix); 265 viapar->depth = fb_get_color_depth(&info->var, &info->fix);
260 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, 266 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
261 viafbinfo->var.bits_per_pixel, viafb_refresh, 0); 267 viafbinfo->var.bits_per_pixel, 0);
262 268
263 vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres); 269 vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres);
264 if (viafb_dual_fb) { 270 if (viafb_dual_fb) {
@@ -266,7 +272,7 @@ static int viafb_set_par(struct fb_info *info)
266 viafbinfo1->var.yres); 272 viafbinfo1->var.yres);
267 viafb_update_device_setting(viafbinfo1->var.xres, 273 viafb_update_device_setting(viafbinfo1->var.xres,
268 viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel, 274 viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel,
269 viafb_refresh1, 1); 275 1);
270 } else if (viafb_SAMM_ON == 1) { 276 } else if (viafb_SAMM_ON == 1) {
271 DEBUG_MSG(KERN_INFO 277 DEBUG_MSG(KERN_INFO
272 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", 278 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
@@ -275,14 +281,19 @@ static int viafb_set_par(struct fb_info *info)
275 viafb_second_yres); 281 viafb_second_yres);
276 282
277 viafb_update_device_setting(viafb_second_xres, 283 viafb_update_device_setting(viafb_second_xres,
278 viafb_second_yres, viafb_bpp1, viafb_refresh1, 1); 284 viafb_second_yres, viafb_bpp1, 1);
279 } 285 }
280 286
287 refresh = viafb_get_refresh(info->var.xres, info->var.yres,
288 get_var_refresh(&info->var));
281 if (vmode_entry) { 289 if (vmode_entry) {
282 if (viafb_dual_fb && viapar->iga_path == IGA2) 290 if (viafb_dual_fb && viapar->iga_path == IGA2) {
283 viafb_bpp1 = info->var.bits_per_pixel; 291 viafb_bpp1 = info->var.bits_per_pixel;
284 else 292 viafb_refresh1 = refresh;
293 } else {
285 viafb_bpp = info->var.bits_per_pixel; 294 viafb_bpp = info->var.bits_per_pixel;
295 viafb_refresh = refresh;
296 }
286 297
287 if (info->var.accel_flags & FB_ACCELF_TEXT) 298 if (info->var.accel_flags & FB_ACCELF_TEXT)
288 info->flags &= ~FBINFO_HWACCEL_DISABLED; 299 info->flags &= ~FBINFO_HWACCEL_DISABLED;
@@ -1795,14 +1806,9 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1795 default_var.xres_virtual = default_xres; 1806 default_var.xres_virtual = default_xres;
1796 default_var.yres_virtual = default_yres; 1807 default_var.yres_virtual = default_yres;
1797 default_var.bits_per_pixel = viafb_bpp; 1808 default_var.bits_per_pixel = viafb_bpp;
1798 default_var.pixclock = 1809 viafb_fill_var_timing_info(&default_var, viafb_get_refresh(
1799 viafb_get_pixclock(default_xres, default_yres, viafb_refresh); 1810 default_var.xres, default_var.yres, viafb_refresh),
1800 default_var.left_margin = (default_xres >> 3) & 0xf8; 1811 viafb_get_mode(default_var.xres, default_var.yres));
1801 default_var.right_margin = 32;
1802 default_var.upper_margin = 16;
1803 default_var.lower_margin = 4;
1804 default_var.hsync_len = default_var.left_margin;
1805 default_var.vsync_len = 4;
1806 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); 1812 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
1807 viafbinfo->var = default_var; 1813 viafbinfo->var = default_var;
1808 1814
@@ -1841,15 +1847,9 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1841 default_var.xres_virtual = viafb_second_virtual_xres; 1847 default_var.xres_virtual = viafb_second_virtual_xres;
1842 default_var.yres_virtual = viafb_second_virtual_yres; 1848 default_var.yres_virtual = viafb_second_virtual_yres;
1843 default_var.bits_per_pixel = viafb_bpp1; 1849 default_var.bits_per_pixel = viafb_bpp1;
1844 default_var.pixclock = 1850 viafb_fill_var_timing_info(&default_var, viafb_get_refresh(
1845 viafb_get_pixclock(viafb_second_xres, viafb_second_yres, 1851 default_var.xres, default_var.yres, viafb_refresh1),
1846 viafb_refresh); 1852 viafb_get_mode(default_var.xres, default_var.yres));
1847 default_var.left_margin = (viafb_second_xres >> 3) & 0xf8;
1848 default_var.right_margin = 32;
1849 default_var.upper_margin = 16;
1850 default_var.lower_margin = 4;
1851 default_var.hsync_len = default_var.left_margin;
1852 default_var.vsync_len = 4;
1853 1853
1854 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); 1854 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
1855 viafb_check_var(&default_var, viafbinfo1); 1855 viafb_check_var(&default_var, viafbinfo1);
@@ -2004,15 +2004,17 @@ static int __init viafb_setup(char *options)
2004 */ 2004 */
2005int __init viafb_init(void) 2005int __init viafb_init(void)
2006{ 2006{
2007 u32 dummy; 2007 u32 dummy_x, dummy_y;
2008#ifndef MODULE 2008#ifndef MODULE
2009 char *option = NULL; 2009 char *option = NULL;
2010 if (fb_get_options("viafb", &option)) 2010 if (fb_get_options("viafb", &option))
2011 return -ENODEV; 2011 return -ENODEV;
2012 viafb_setup(option); 2012 viafb_setup(option);
2013#endif 2013#endif
2014 if (parse_mode(viafb_mode, &dummy, &dummy) 2014 if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
2015 || parse_mode(viafb_mode1, &dummy, &dummy) 2015 || !viafb_get_mode(dummy_x, dummy_y)
2016 || parse_mode(viafb_mode1, &dummy_x, &dummy_y)
2017 || !viafb_get_mode(dummy_x, dummy_y)
2016 || viafb_bpp < 0 || viafb_bpp > 32 2018 || viafb_bpp < 0 || viafb_bpp > 32
2017 || viafb_bpp1 < 0 || viafb_bpp1 > 32 2019 || viafb_bpp1 < 0 || viafb_bpp1 > 32
2018 || parse_active_dev()) 2020 || parse_active_dev())