diff options
Diffstat (limited to 'drivers/video/tridentfb.c')
-rw-r--r-- | drivers/video/tridentfb.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 70fb4ee2b421..0a4e07d43d2d 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
@@ -564,7 +564,7 @@ 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 | /* Goto New Mode */ | 569 | /* Goto New Mode */ |
570 | outb(0x0B, 0x3C4); | 570 | outb(0x0B, 0x3C4); |
@@ -579,6 +579,21 @@ static inline void enable_mmio(void) | |||
579 | outb(inb(0x3D5) | 0x01, 0x3D5); | 579 | outb(inb(0x3D5) | 0x01, 0x3D5); |
580 | } | 580 | } |
581 | 581 | ||
582 | static void disable_mmio(void) | ||
583 | { | ||
584 | /* Goto New Mode */ | ||
585 | t_outb(0x0B, 0x3C4); | ||
586 | t_inb(0x3C5); | ||
587 | |||
588 | /* Unprotect registers */ | ||
589 | t_outb(NewMode1, 0x3C4); | ||
590 | t_outb(0x80, 0x3C5); | ||
591 | |||
592 | /* Disable MMIO */ | ||
593 | t_outb(PCIReg, 0x3D4); | ||
594 | t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); | ||
595 | } | ||
596 | |||
582 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) | 597 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) |
583 | 598 | ||
584 | /* Return flat panel's maximum x resolution */ | 599 | /* Return flat panel's maximum x resolution */ |
@@ -730,7 +745,7 @@ static unsigned int __devinit get_memsize(void) | |||
730 | switch (tmp) { | 745 | switch (tmp) { |
731 | 746 | ||
732 | case 0x01: | 747 | case 0x01: |
733 | k = 512; | 748 | k = 512 * Kb; |
734 | break; | 749 | break; |
735 | case 0x02: | 750 | case 0x02: |
736 | k = 6 * Mb; /* XP */ | 751 | k = 6 * Mb; /* XP */ |
@@ -1239,9 +1254,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); | 1254 | default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
1240 | 1255 | ||
1241 | if (!default_par.io_virt) { | 1256 | if (!default_par.io_virt) { |
1242 | release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | ||
1243 | debug("ioremap failed\n"); | 1257 | debug("ioremap failed\n"); |
1244 | return -1; | 1258 | err = -1; |
1259 | goto out_unmap1; | ||
1245 | } | 1260 | } |
1246 | 1261 | ||
1247 | enable_mmio(); | 1262 | enable_mmio(); |
@@ -1252,25 +1267,21 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1252 | 1267 | ||
1253 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { | 1268 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { |
1254 | debug("request_mem_region failed!\n"); | 1269 | debug("request_mem_region failed!\n"); |
1270 | disable_mmio(); | ||
1255 | err = -1; | 1271 | err = -1; |
1256 | goto out_unmap; | 1272 | goto out_unmap1; |
1257 | } | 1273 | } |
1258 | 1274 | ||
1259 | fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, | 1275 | fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, |
1260 | tridentfb_fix.smem_len); | 1276 | tridentfb_fix.smem_len); |
1261 | 1277 | ||
1262 | if (!fb_info.screen_base) { | 1278 | if (!fb_info.screen_base) { |
1263 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | ||
1264 | debug("ioremap failed\n"); | 1279 | debug("ioremap failed\n"); |
1265 | err = -1; | 1280 | err = -1; |
1266 | goto out_unmap; | 1281 | goto out_unmap2; |
1267 | } | 1282 | } |
1268 | 1283 | ||
1269 | output("%s board found\n", pci_name(dev)); | 1284 | 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(); | 1285 | displaytype = get_displaytype(); |
1275 | 1286 | ||
1276 | if (flatpanel) | 1287 | if (flatpanel) |
@@ -1288,9 +1299,12 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1288 | 1299 | ||
1289 | if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) { | 1300 | if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) { |
1290 | err = -EINVAL; | 1301 | err = -EINVAL; |
1291 | goto out_unmap; | 1302 | goto out_unmap2; |
1292 | } | 1303 | } |
1293 | fb_alloc_cmap(&fb_info.cmap, 256, 0); | 1304 | err = fb_alloc_cmap(&fb_info.cmap, 256, 0); |
1305 | if (err < 0) | ||
1306 | goto out_unmap2; | ||
1307 | |||
1294 | if (defaultaccel && acc) | 1308 | if (defaultaccel && acc) |
1295 | default_var.accel_flags |= FB_ACCELF_TEXT; | 1309 | default_var.accel_flags |= FB_ACCELF_TEXT; |
1296 | else | 1310 | else |
@@ -1300,19 +1314,24 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1300 | fb_info.device = &dev->dev; | 1314 | fb_info.device = &dev->dev; |
1301 | if (register_framebuffer(&fb_info) < 0) { | 1315 | if (register_framebuffer(&fb_info) < 0) { |
1302 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); | 1316 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); |
1317 | fb_dealloc_cmap(&fb_info.cmap); | ||
1303 | err = -EINVAL; | 1318 | err = -EINVAL; |
1304 | goto out_unmap; | 1319 | goto out_unmap2; |
1305 | } | 1320 | } |
1306 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", | 1321 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", |
1307 | fb_info.node, fb_info.fix.id, default_var.xres, | 1322 | fb_info.node, fb_info.fix.id, default_var.xres, |
1308 | default_var.yres, default_var.bits_per_pixel); | 1323 | default_var.yres, default_var.bits_per_pixel); |
1309 | return 0; | 1324 | return 0; |
1310 | 1325 | ||
1311 | out_unmap: | 1326 | out_unmap2: |
1312 | if (default_par.io_virt) | ||
1313 | iounmap(default_par.io_virt); | ||
1314 | if (fb_info.screen_base) | 1327 | if (fb_info.screen_base) |
1315 | iounmap(fb_info.screen_base); | 1328 | iounmap(fb_info.screen_base); |
1329 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | ||
1330 | disable_mmio(); | ||
1331 | out_unmap1: | ||
1332 | if (default_par.io_virt) | ||
1333 | iounmap(default_par.io_virt); | ||
1334 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | ||
1316 | return err; | 1335 | return err; |
1317 | } | 1336 | } |
1318 | 1337 | ||
@@ -1323,7 +1342,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev) | |||
1323 | iounmap(par->io_virt); | 1342 | iounmap(par->io_virt); |
1324 | iounmap(fb_info.screen_base); | 1343 | iounmap(fb_info.screen_base); |
1325 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | 1344 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); |
1326 | release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1345 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
1327 | } | 1346 | } |
1328 | 1347 | ||
1329 | /* List of boards that we are trying to support */ | 1348 | /* List of boards that we are trying to support */ |