diff options
Diffstat (limited to 'drivers/video/tridentfb.c')
-rw-r--r-- | drivers/video/tridentfb.c | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 70fb4ee2b421..919ce75db9e2 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
@@ -564,19 +564,46 @@ static inline void write3CE(int reg, unsigned char val) | |||
564 | t_outb(val, 0x3CF); | 564 | t_outb(val, 0x3CF); |
565 | } | 565 | } |
566 | 566 | ||
567 | static inline void enable_mmio(void) | 567 | static void enable_mmio(void) |
568 | { | 568 | { |
569 | unsigned char tmp; | ||
570 | |||
569 | /* Goto New Mode */ | 571 | /* Goto New Mode */ |
570 | outb(0x0B, 0x3C4); | 572 | outb(0x0B, 0x3C4); |
571 | inb(0x3C5); | 573 | inb(0x3C5); |
572 | 574 | ||
573 | /* Unprotect registers */ | 575 | /* Unprotect registers */ |
574 | outb(NewMode1, 0x3C4); | 576 | outb(NewMode1, 0x3C4); |
577 | tmp = inb(0x3C5); | ||
575 | outb(0x80, 0x3C5); | 578 | outb(0x80, 0x3C5); |
576 | 579 | ||
577 | /* Enable MMIO */ | 580 | /* Enable MMIO */ |
578 | outb(PCIReg, 0x3D4); | 581 | outb(PCIReg, 0x3D4); |
579 | outb(inb(0x3D5) | 0x01, 0x3D5); | 582 | outb(inb(0x3D5) | 0x01, 0x3D5); |
583 | |||
584 | t_outb(NewMode1, 0x3C4); | ||
585 | t_outb(tmp, 0x3C5); | ||
586 | } | ||
587 | |||
588 | static void disable_mmio(void) | ||
589 | { | ||
590 | unsigned char tmp; | ||
591 | |||
592 | /* Goto New Mode */ | ||
593 | t_outb(0x0B, 0x3C4); | ||
594 | t_inb(0x3C5); | ||
595 | |||
596 | /* Unprotect registers */ | ||
597 | t_outb(NewMode1, 0x3C4); | ||
598 | tmp = t_inb(0x3C5); | ||
599 | t_outb(0x80, 0x3C5); | ||
600 | |||
601 | /* Disable MMIO */ | ||
602 | t_outb(PCIReg, 0x3D4); | ||
603 | t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); | ||
604 | |||
605 | outb(NewMode1, 0x3C4); | ||
606 | outb(tmp, 0x3C5); | ||
580 | } | 607 | } |
581 | 608 | ||
582 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) | 609 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) |
@@ -1239,9 +1266,9 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1239 | default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1266 | default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
1240 | 1267 | ||
1241 | if (!default_par.io_virt) { | 1268 | if (!default_par.io_virt) { |
1242 | release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | ||
1243 | debug("ioremap failed\n"); | 1269 | debug("ioremap failed\n"); |
1244 | return -1; | 1270 | err = -1; |
1271 | goto out_unmap1; | ||
1245 | } | 1272 | } |
1246 | 1273 | ||
1247 | enable_mmio(); | 1274 | enable_mmio(); |
@@ -1252,25 +1279,21 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1252 | 1279 | ||
1253 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { | 1280 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { |
1254 | debug("request_mem_region failed!\n"); | 1281 | debug("request_mem_region failed!\n"); |
1282 | disable_mmio(); | ||
1255 | err = -1; | 1283 | err = -1; |
1256 | goto out_unmap; | 1284 | goto out_unmap1; |
1257 | } | 1285 | } |
1258 | 1286 | ||
1259 | fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, | 1287 | fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, |
1260 | tridentfb_fix.smem_len); | 1288 | tridentfb_fix.smem_len); |
1261 | 1289 | ||
1262 | if (!fb_info.screen_base) { | 1290 | if (!fb_info.screen_base) { |
1263 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | ||
1264 | debug("ioremap failed\n"); | 1291 | debug("ioremap failed\n"); |
1265 | err = -1; | 1292 | err = -1; |
1266 | goto out_unmap; | 1293 | goto out_unmap2; |
1267 | } | 1294 | } |
1268 | 1295 | ||
1269 | output("%s board found\n", pci_name(dev)); | 1296 | output("%s board found\n", pci_name(dev)); |
1270 | #if 0 | ||
1271 | output("Trident board found : mem = %X, io = %X, mem_v = %X, io_v = %X\n", | ||
1272 | tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt); | ||
1273 | #endif | ||
1274 | displaytype = get_displaytype(); | 1297 | displaytype = get_displaytype(); |
1275 | 1298 | ||
1276 | if (flatpanel) | 1299 | if (flatpanel) |
@@ -1288,9 +1311,12 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1288 | 1311 | ||
1289 | if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) { | 1312 | if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) { |
1290 | err = -EINVAL; | 1313 | err = -EINVAL; |
1291 | goto out_unmap; | 1314 | goto out_unmap2; |
1292 | } | 1315 | } |
1293 | fb_alloc_cmap(&fb_info.cmap, 256, 0); | 1316 | err = fb_alloc_cmap(&fb_info.cmap, 256, 0); |
1317 | if (err < 0) | ||
1318 | goto out_unmap2; | ||
1319 | |||
1294 | if (defaultaccel && acc) | 1320 | if (defaultaccel && acc) |
1295 | default_var.accel_flags |= FB_ACCELF_TEXT; | 1321 | default_var.accel_flags |= FB_ACCELF_TEXT; |
1296 | else | 1322 | else |
@@ -1300,19 +1326,24 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1300 | fb_info.device = &dev->dev; | 1326 | fb_info.device = &dev->dev; |
1301 | if (register_framebuffer(&fb_info) < 0) { | 1327 | if (register_framebuffer(&fb_info) < 0) { |
1302 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); | 1328 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); |
1329 | fb_dealloc_cmap(&fb_info.cmap); | ||
1303 | err = -EINVAL; | 1330 | err = -EINVAL; |
1304 | goto out_unmap; | 1331 | goto out_unmap2; |
1305 | } | 1332 | } |
1306 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", | 1333 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", |
1307 | fb_info.node, fb_info.fix.id, default_var.xres, | 1334 | fb_info.node, fb_info.fix.id, default_var.xres, |
1308 | default_var.yres, default_var.bits_per_pixel); | 1335 | default_var.yres, default_var.bits_per_pixel); |
1309 | return 0; | 1336 | return 0; |
1310 | 1337 | ||
1311 | out_unmap: | 1338 | out_unmap2: |
1312 | if (default_par.io_virt) | ||
1313 | iounmap(default_par.io_virt); | ||
1314 | if (fb_info.screen_base) | 1339 | if (fb_info.screen_base) |
1315 | iounmap(fb_info.screen_base); | 1340 | iounmap(fb_info.screen_base); |
1341 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | ||
1342 | disable_mmio(); | ||
1343 | out_unmap1: | ||
1344 | if (default_par.io_virt) | ||
1345 | iounmap(default_par.io_virt); | ||
1346 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | ||
1316 | return err; | 1347 | return err; |
1317 | } | 1348 | } |
1318 | 1349 | ||
@@ -1323,7 +1354,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev) | |||
1323 | iounmap(par->io_virt); | 1354 | iounmap(par->io_virt); |
1324 | iounmap(fb_info.screen_base); | 1355 | iounmap(fb_info.screen_base); |
1325 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | 1356 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); |
1326 | release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1357 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
1327 | } | 1358 | } |
1328 | 1359 | ||
1329 | /* List of boards that we are trying to support */ | 1360 | /* List of boards that we are trying to support */ |