igafb.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /*
  2. * linux/drivers/video/igafb.c -- Frame buffer device for IGA 1682
  3. *
  4. * Copyright (C) 1998 Vladimir Roganov and Gleb Raiko
  5. *
  6. * This driver is partly based on the Frame buffer device for ATI Mach64
  7. * and partially on VESA-related code.
  8. *
  9. * Copyright (C) 1997-1998 Geert Uytterhoeven
  10. * Copyright (C) 1998 Bernd Harries
  11. * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
  12. *
  13. * This file is subject to the terms and conditions of the GNU General Public
  14. * License. See the file COPYING in the main directory of this archive for
  15. * more details.
  16. */
  17. /******************************************************************************
  18. TODO:
  19. Despite of IGA Card has advanced graphic acceleration,
  20. initial version is almost dummy and does not support it.
  21. Support for video modes and acceleration must be added
  22. together with accelerated X-Windows driver implementation.
  23. Most important thing at this moment is that we have working
  24. JavaEngine1 console & X with new console interface.
  25. ******************************************************************************/
  26. #include <linux/module.h>
  27. #include <linux/kernel.h>
  28. #include <linux/errno.h>
  29. #include <linux/string.h>
  30. #include <linux/mm.h>
  31. #include <linux/tty.h>
  32. #include <linux/slab.h>
  33. #include <linux/vmalloc.h>
  34. #include <linux/delay.h>
  35. #include <linux/interrupt.h>
  36. #include <linux/fb.h>
  37. #include <linux/init.h>
  38. #include <linux/pci.h>
  39. #include <linux/nvram.h>
  40. #include <asm/io.h>
  41. #ifdef __sparc__
  42. #include <asm/pbm.h>
  43. #include <asm/pcic.h>
  44. #endif
  45. #include <video/iga.h>
  46. struct pci_mmap_map {
  47. unsigned long voff;
  48. unsigned long poff;
  49. unsigned long size;
  50. unsigned long prot_flag;
  51. unsigned long prot_mask;
  52. };
  53. struct iga_par {
  54. struct pci_mmap_map *mmap_map;
  55. unsigned long frame_buffer_phys;
  56. unsigned long io_base;
  57. };
  58. struct fb_info fb_info;
  59. struct fb_fix_screeninfo igafb_fix __initdata = {
  60. .id = "IGA 1682",
  61. .type = FB_TYPE_PACKED_PIXELS,
  62. .mmio_len = 1000
  63. };
  64. struct fb_var_screeninfo default_var = {
  65. /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
  66. .xres = 640,
  67. .yres = 480,
  68. .xres_virtual = 640,
  69. .yres_virtual = 480,
  70. .bits_per_pixel = 8,
  71. .red = {0, 8, 0 },
  72. .green = {0, 8, 0 },
  73. .blue = {0, 8, 0 },
  74. .height = -1,
  75. .width = -1,
  76. .accel_flags = FB_ACCEL_NONE,
  77. .pixclock = 39722,
  78. .left_margin = 48,
  79. .right_margin = 16,
  80. .upper_margin = 33,
  81. .lower_margin = 10,
  82. .hsync_len = 96,
  83. .vsync_len = 2,
  84. .vmode = FB_VMODE_NONINTERLACED
  85. };
  86. #ifdef __sparc__
  87. struct fb_var_screeninfo default_var_1024x768 __initdata = {
  88. /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
  89. .xres = 1024,
  90. .yres = 768,
  91. .xres_virtual = 1024,
  92. .yres_virtual = 768,
  93. .bits_per_pixel = 8,
  94. .red = {0, 8, 0 },
  95. .green = {0, 8, 0 },
  96. .blue = {0, 8, 0 },
  97. .height = -1,
  98. .width = -1,
  99. .accel_flags = FB_ACCEL_NONE,
  100. .pixclock = 12699,
  101. .left_margin = 176,
  102. .right_margin = 16,
  103. .upper_margin = 28,
  104. .lower_margin = 1,
  105. .hsync_len = 96,
  106. .vsync_len = 3,
  107. .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
  108. };
  109. struct fb_var_screeninfo default_var_1152x900 __initdata = {
  110. /* 1152x900, 76 Hz, Non-Interlaced (110.0 MHz dotclock) */
  111. .xres = 1152,
  112. .yres = 900,
  113. .xres_virtual = 1152,
  114. .yres_virtual = 900,
  115. .bits_per_pixel = 8,
  116. .red = { 0, 8, 0 },
  117. .green = { 0, 8, 0 },
  118. .blue = { 0, 8, 0 },
  119. .height = -1,
  120. .width = -1,
  121. .accel_flags = FB_ACCEL_NONE,
  122. .pixclock = 9091,
  123. .left_margin = 234,
  124. .right_margin = 24,
  125. .upper_margin = 34,
  126. .lower_margin = 3,
  127. .hsync_len = 100,
  128. .vsync_len = 3,
  129. .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
  130. };
  131. struct fb_var_screeninfo default_var_1280x1024 __initdata = {
  132. /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
  133. .xres = 1280,
  134. .yres = 1024,
  135. .xres_virtual = 1280,
  136. .yres_virtual = 1024,
  137. .bits_per_pixel = 8,
  138. .red = {0, 8, 0 },
  139. .green = {0, 8, 0 },
  140. .blue = {0, 8, 0 },
  141. .height = -1,
  142. .width = -1,
  143. .accel_flags = 0,
  144. .pixclock = 7408,
  145. .left_margin = 248,
  146. .right_margin = 16,
  147. .upper_margin = 38,
  148. .lower_margin = 1,
  149. .hsync_len = 144,
  150. .vsync_len = 3,
  151. .vmode = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
  152. };
  153. /*
  154. * Memory-mapped I/O functions for Sparc PCI
  155. *
  156. * On sparc we happen to access I/O with memory mapped functions too.
  157. */
  158. #define pci_inb(par, reg) readb(par->io_base+(reg))
  159. #define pci_outb(par, val, reg) writeb(val, par->io_base+(reg))
  160. static inline unsigned int iga_inb(struct iga_par *par, unsigned int reg,
  161. unsigned int idx)
  162. {
  163. pci_outb(par, idx, reg);
  164. return pci_inb(par, reg + 1);
  165. }
  166. static inline void iga_outb(struct iga_par *par, unsigned char val,
  167. unsigned int reg, unsigned int idx )
  168. {
  169. pci_outb(par, idx, reg);
  170. pci_outb(par, val, reg+1);
  171. }
  172. #endif /* __sparc__ */
  173. /*
  174. * Very important functionality for the JavaEngine1 computer:
  175. * make screen border black (usign special IGA registers)
  176. */
  177. static void iga_blank_border(struct iga_par *par)
  178. {
  179. int i;
  180. #if 0
  181. /*
  182. * PROM does this for us, so keep this code as a reminder
  183. * about required read from 0x3DA and writing of 0x20 in the end.
  184. */
  185. (void) pci_inb(par, 0x3DA); /* required for every access */
  186. pci_outb(par, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
  187. (void) pci_inb(par, IGA_ATTR_CTL+1);
  188. pci_outb(par, 0x38, IGA_ATTR_CTL);
  189. pci_outb(par, 0x20, IGA_ATTR_CTL); /* re-enable visual */
  190. #endif
  191. /*
  192. * This does not work as it was designed because the overscan
  193. * color is looked up in the palette. Therefore, under X11
  194. * overscan changes color.
  195. */
  196. for (i=0; i < 3; i++)
  197. iga_outb(par, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
  198. }
  199. #ifdef __sparc__
  200. static int igafb_mmap(struct fb_info *info,
  201. struct vm_area_struct *vma)
  202. {
  203. struct iga_par *par = (struct iga_par *)info->par;
  204. unsigned int size, page, map_size = 0;
  205. unsigned long map_offset = 0;
  206. int i;
  207. if (!par->mmap_map)
  208. return -ENXIO;
  209. size = vma->vm_end - vma->vm_start;
  210. /* To stop the swapper from even considering these pages. */
  211. vma->vm_flags |= (VM_SHM | VM_LOCKED);
  212. /* Each page, see which map applies */
  213. for (page = 0; page < size; ) {
  214. map_size = 0;
  215. for (i = 0; par->mmap_map[i].size; i++) {
  216. unsigned long start = par->mmap_map[i].voff;
  217. unsigned long end = start + par->mmap_map[i].size;
  218. unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT) + page;
  219. if (start > offset)
  220. continue;
  221. if (offset >= end)
  222. continue;
  223. map_size = par->mmap_map[i].size - (offset - start);
  224. map_offset = par->mmap_map[i].poff + (offset - start);
  225. break;
  226. }
  227. if (!map_size) {
  228. page += PAGE_SIZE;
  229. continue;
  230. }
  231. if (page + map_size > size)
  232. map_size = size - page;
  233. pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask);
  234. pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
  235. if (remap_pfn_range(vma, vma->vm_start + page,
  236. map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
  237. return -EAGAIN;
  238. page += map_size;
  239. }
  240. if (!map_size)
  241. return -EINVAL;
  242. vma->vm_flags |= VM_IO;
  243. return 0;
  244. }
  245. #endif /* __sparc__ */
  246. static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
  247. unsigned blue, unsigned transp,
  248. struct fb_info *info)
  249. {
  250. /*
  251. * Set a single color register. The values supplied are
  252. * already rounded down to the hardware's capabilities
  253. * (according to the entries in the `var' structure). Return
  254. * != 0 for invalid regno.
  255. */
  256. struct iga_par *par = (struct iga_par *)info->par;
  257. if (regno >= info->cmap.len)
  258. return 1;
  259. pci_outb(par, regno, DAC_W_INDEX);
  260. pci_outb(par, red, DAC_DATA);
  261. pci_outb(par, green, DAC_DATA);
  262. pci_outb(par, blue, DAC_DATA);
  263. if (regno < 16) {
  264. switch (info->var.bits_per_pixel) {
  265. case 16:
  266. ((u16*)(info->pseudo_palette))[regno] =
  267. (regno << 10) | (regno << 5) | regno;
  268. break;
  269. case 24:
  270. ((u32*)(info->pseudo_palette))[regno] =
  271. (regno << 16) | (regno << 8) | regno;
  272. break;
  273. case 32:
  274. { int i;
  275. i = (regno << 8) | regno;
  276. ((u32*)(info->pseudo_palette))[regno] = (i << 16) | i;
  277. }
  278. break;
  279. }
  280. }
  281. return 0;
  282. }
  283. /*
  284. * Framebuffer option structure
  285. */
  286. static struct fb_ops igafb_ops = {
  287. .owner = THIS_MODULE,
  288. .fb_setcolreg = igafb_setcolreg,
  289. .fb_fillrect = cfb_fillrect,
  290. .fb_copyarea = cfb_copyarea,
  291. .fb_imageblit = cfb_imageblit,
  292. #ifdef __sparc__
  293. .fb_mmap = igafb_mmap,
  294. #endif
  295. };
  296. static int __init iga_init(struct fb_info *info, struct iga_par *par)
  297. {
  298. char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL)
  299. & MEM_SIZE_ALIAS;
  300. int video_cmap_len;
  301. switch (vramsz) {
  302. case MEM_SIZE_1M:
  303. info->fix.smem_len = 0x100000;
  304. break;
  305. case MEM_SIZE_2M:
  306. info->fix.smem_len = 0x200000;
  307. break;
  308. case MEM_SIZE_4M:
  309. case MEM_SIZE_RESERVED:
  310. info->fix.smem_len = 0x400000;
  311. break;
  312. }
  313. if (info->var.bits_per_pixel > 8)
  314. video_cmap_len = 16;
  315. else
  316. video_cmap_len = 256;
  317. info->fbops = &igafb_ops;
  318. info->flags = FBINFO_DEFAULT;
  319. fb_alloc_cmap(&info->cmap, video_cmap_len, 0);
  320. if (register_framebuffer(info) < 0)
  321. return 0;
  322. printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n",
  323. info->node, info->fix.id,
  324. par->frame_buffer_phys, info->fix.smem_len >> 20);
  325. iga_blank_border(par);
  326. return 1;
  327. }
  328. int __init igafb_init(void)
  329. {
  330. extern int con_is_present(void);
  331. struct fb_info *info;
  332. struct pci_dev *pdev;
  333. struct iga_par *par;
  334. unsigned long addr;
  335. int size, iga2000 = 0;
  336. if (fb_get_options("igafb", NULL))
  337. return -ENODEV;
  338. /* Do not attach when we have a serial console. */
  339. if (!con_is_present())
  340. return -ENXIO;
  341. pdev = pci_find_device(PCI_VENDOR_ID_INTERG,
  342. PCI_DEVICE_ID_INTERG_1682, 0);
  343. if (pdev == NULL) {
  344. /*
  345. * XXX We tried to use cyber2000fb.c for IGS 2000.
  346. * But it does not initialize the chip in JavaStation-E, alas.
  347. */
  348. pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
  349. if(pdev == NULL) {
  350. return -ENXIO;
  351. }
  352. iga2000 = 1;
  353. }
  354. size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16;
  355. info = kmalloc(size, GFP_ATOMIC);
  356. if (!info) {
  357. printk("igafb_init: can't alloc fb_info\n");
  358. return -ENOMEM;
  359. }
  360. memset(info, 0, size);
  361. par = (struct iga_par *) (info + 1);
  362. if ((addr = pdev->resource[0].start) == 0) {
  363. printk("igafb_init: no memory start\n");
  364. kfree(info);
  365. return -ENXIO;
  366. }
  367. if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) {
  368. printk("igafb_init: can't remap %lx[2M]\n", addr);
  369. kfree(info);
  370. return -ENXIO;
  371. }
  372. par->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
  373. #ifdef __sparc__
  374. /*
  375. * The following is sparc specific and this is why:
  376. *
  377. * IGS2000 has its I/O memory mapped and we want
  378. * to generate memory cycles on PCI, e.g. do ioremap(),
  379. * then readb/writeb() as in Documentation/IO-mapping.txt.
  380. *
  381. * IGS1682 is more traditional, it responds to PCI I/O
  382. * cycles, so we want to access it with inb()/outb().
  383. *
  384. * On sparc, PCIC converts CPU memory access within
  385. * phys window 0x3000xxxx into PCI I/O cycles. Therefore
  386. * we may use readb/writeb to access them with IGS1682.
  387. *
  388. * We do not take io_base_phys from resource[n].start
  389. * on IGS1682 because that chip is BROKEN. It does not
  390. * have a base register for I/O. We just "know" what its
  391. * I/O addresses are.
  392. */
  393. if (iga2000) {
  394. igafb_fix.mmio_start = par->frame_buffer_phys | 0x00800000;
  395. } else {
  396. igafb_fix.mmio_start = 0x30000000; /* XXX */
  397. }
  398. if ((par->io_base = (int) ioremap(igafb_fix.mmio_start, igafb_fix.smem_len)) == 0) {
  399. printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start);
  400. iounmap((void *)info->screen_base);
  401. kfree(info);
  402. return -ENXIO;
  403. }
  404. /*
  405. * Figure mmap addresses from PCI config space.
  406. * We need two regions: for video memory and for I/O ports.
  407. * Later one can add region for video coprocessor registers.
  408. * However, mmap routine loops until size != 0, so we put
  409. * one additional region with size == 0.
  410. */
  411. par->mmap_map = kmalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC);
  412. if (!par->mmap_map) {
  413. printk("igafb_init: can't alloc mmap_map\n");
  414. iounmap((void *)par->io_base);
  415. iounmap(info->screen_base);
  416. kfree(info);
  417. return -ENOMEM;
  418. }
  419. memset(par->mmap_map, 0, 4 * sizeof(*par->mmap_map));
  420. /*
  421. * Set default vmode and cmode from PROM properties.
  422. */
  423. {
  424. struct pcidev_cookie *cookie = pdev->sysdata;
  425. int node = cookie->prom_node;
  426. int width = prom_getintdefault(node, "width", 1024);
  427. int height = prom_getintdefault(node, "height", 768);
  428. int depth = prom_getintdefault(node, "depth", 8);
  429. switch (width) {
  430. case 1024:
  431. if (height == 768)
  432. default_var = default_var_1024x768;
  433. break;
  434. case 1152:
  435. if (height == 900)
  436. default_var = default_var_1152x900;
  437. break;
  438. case 1280:
  439. if (height == 1024)
  440. default_var = default_var_1280x1024;
  441. break;
  442. default:
  443. break;
  444. }
  445. switch (depth) {
  446. case 8:
  447. default_var.bits_per_pixel = 8;
  448. break;
  449. case 16:
  450. default_var.bits_per_pixel = 16;
  451. break;
  452. case 24:
  453. default_var.bits_per_pixel = 24;
  454. break;
  455. case 32:
  456. default_var.bits_per_pixel = 32;
  457. break;
  458. default:
  459. break;
  460. }
  461. }
  462. #endif
  463. igafb_fix.smem_start = (unsigned long) info->screen_base;
  464. igafb_fix.line_length = default_var.xres*(default_var.bits_per_pixel/8);
  465. igafb_fix.visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
  466. info->var = default_var;
  467. info->fix = igafb_fix;
  468. info->pseudo_palette = (void *)(par + 1);
  469. info->device = &pdev->dev;
  470. if (!iga_init(info, par)) {
  471. iounmap((void *)par->io_base);
  472. iounmap(info->screen_base);
  473. kfree(par->mmap_map);
  474. kfree(info);
  475. }
  476. #ifdef __sparc__
  477. /*
  478. * Add /dev/fb mmap values.
  479. */
  480. /* First region is for video memory */
  481. par->mmap_map[0].voff = 0x0;
  482. par->mmap_map[0].poff = par->frame_buffer_phys & PAGE_MASK;
  483. par->mmap_map[0].size = info->fix.smem_len & PAGE_MASK;
  484. par->mmap_map[0].prot_mask = SRMMU_CACHE;
  485. par->mmap_map[0].prot_flag = SRMMU_WRITE;
  486. /* Second region is for I/O ports */
  487. par->mmap_map[1].voff = par->frame_buffer_phys & PAGE_MASK;
  488. par->mmap_map[1].poff = info->fix.smem_start & PAGE_MASK;
  489. par->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
  490. par->mmap_map[1].prot_mask = SRMMU_CACHE;
  491. par->mmap_map[1].prot_flag = SRMMU_WRITE;
  492. #endif /* __sparc__ */
  493. return 0;
  494. }
  495. int __init igafb_setup(char *options)
  496. {
  497. char *this_opt;
  498. if (!options || !*options)
  499. return 0;
  500. while ((this_opt = strsep(&options, ",")) != NULL) {
  501. }
  502. return 0;
  503. }
  504. module_init(igafb_init);
  505. MODULE_LICENSE("GPL");