patch-2.3.35 linux/drivers/video/igafb.c
Next file: linux/drivers/video/leofb.c
Previous file: linux/drivers/video/iga.h
Back to the patch index
Back to the overall index
- Lines: 317
- Date:
Mon Dec 20 22:06:42 1999
- Orig file:
v2.3.34/linux/drivers/video/igafb.c
- Orig date:
Sun Nov 7 16:37:34 1999
diff -u --recursive --new-file v2.3.34/linux/drivers/video/igafb.c linux/drivers/video/igafb.c
@@ -23,11 +23,9 @@
Support for video modes and acceleration must be added
together with accelerated X-Windows driver implementation.
- (Anyone to help with this?)
-
Most important thing at this moment is that we have working
JavaEngine1 console & X with new console interface.
-
+
******************************************************************************/
#include <linux/module.h>
@@ -78,7 +76,7 @@
struct fb_info_iga {
struct fb_info fb_info;
unsigned long frame_buffer_phys;
- unsigned long frame_buffer;
+ char *frame_buffer;
unsigned long io_base_phys;
unsigned long io_base;
u32 total_vram;
@@ -142,23 +140,19 @@
/*
* Memory-mapped I/O functions for Sparc PCI
+ *
+ * On sparc we happen to access I/O with memory mapped functions too.
*/
-static inline unsigned char pci_inb (struct fb_info_iga *info,
- unsigned int reg)
-{
- return *(volatile unsigned char*)(info->io_base + reg);
-}
-static inline void pci_outb (struct fb_info_iga *info, unsigned char c,
- unsigned int reg)
-{
- *(volatile unsigned char*)(info->io_base + reg) = c;
-}
+#define pci_inb(info, reg) readb(info->io_base+(reg))
+#define pci_outb(info, val, reg) writeb(val, info->io_base+(reg))
+
static inline unsigned int iga_inb(struct fb_info_iga *info,
unsigned int reg, unsigned int idx )
{
pci_outb(info, idx, reg);
return pci_inb(info, reg + 1);
}
+
static inline void iga_outb(struct fb_info_iga *info, unsigned char val,
unsigned int reg, unsigned int idx )
{
@@ -176,8 +170,24 @@
{
int i;
- for (i=0; i < 3; i++)
- iga_outb(info, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
+#if 0
+ /*
+ * PROM does this for us, so keep this code as a reminder
+ * about required read from 0x3DA and writing of 0x20 in the end.
+ */
+ (void) pci_inb(info, 0x3DA); /* required for every access */
+ pci_outb(info, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
+ (void) pci_inb(info, IGA_ATTR_CTL+1);
+ pci_outb(info, 0x38, IGA_ATTR_CTL);
+ pci_outb(info, 0x20, IGA_ATTR_CTL); /* re-enable visual */
+#endif
+ /*
+ * This does not work as it was designed because the overscan
+ * color is looked up in the palette. Therefore, under X11
+ * overscan changes color.
+ */
+ for (i=0; i < 3; i++)
+ iga_outb(info, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
}
@@ -217,7 +227,7 @@
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, igafb_name);
- fix->smem_start = fb->frame_buffer;
+ fix->smem_start = (unsigned long) fb->frame_buffer;
fix->smem_len = fb->total_vram;
fix->xpanstep = 0;
fix->ypanstep = 0;
@@ -269,17 +279,17 @@
for (page = 0; page < size; ) {
map_size = 0;
for (i = 0; fb->mmap_map[i].size; i++) {
- unsigned long start = (fb->mmap_map[i].voff) >> PAGE_SHIFT;
- unsigned long end = start + (fb->mmap_map[i].size) >> PAGE_SHIFT;
- unsigned long offset = vma->vm_pgoff + (page >> PAGE_SHIFT);
+ unsigned long start = fb->mmap_map[i].voff;
+ unsigned long end = start + fb->mmap_map[i].size;
+ unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT) + page;
if (start > offset)
continue;
if (offset >= end)
continue;
- map_size = fb->mmap_map[i].size - ((offset - start) << PAGE_SHIFT);
- map_offset = fb->mmap_map[i].poff + ((offset - start) << PAGE_SHIFT);
+ map_size = fb->mmap_map[i].size - (offset - start);
+ map_offset = fb->mmap_map[i].poff + (offset - start);
break;
}
if (!map_size) {
@@ -359,13 +369,13 @@
info->palette[regno].red = red;
info->palette[regno].green = green;
info->palette[regno].blue = blue;
-
+
pci_outb(info, regno, DAC_W_INDEX);
pci_outb(info, red, DAC_DATA);
pci_outb(info, green, DAC_DATA);
pci_outb(info, blue, DAC_DATA);
- if (regno << 16)
+ if (regno < 16)
switch (default_var.bits_per_pixel) {
#ifdef FBCON_HAS_CFB16
case 16:
@@ -475,7 +485,7 @@
struct fb_fix_screeninfo fix;
struct display *display;
struct display_switch *sw;
-
+
if (con >= 0)
display = &fb_display[con];
else
@@ -484,7 +494,7 @@
igafb_get_fix(&fix, con, &info->fb_info);
memset(display, 0, sizeof(struct display));
- display->screen_base = (char*)info->frame_buffer;
+ display->screen_base = info->frame_buffer;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -506,19 +516,19 @@
case 15:
case 16:
sw = &fbcon_cfb16;
- display->dispsw_data = fbcon_cmap.cfb16;
+ display->dispsw_data = info->fbcon_cmap.cfb16;
break;
#endif
#ifdef FBCON_HAS_CFB24
case 24:
sw = &fbcon_cfb24;
- display->dispsw_data = fbcon_cmap.cfb24;
+ display->dispsw_data = info->fbcon_cmap.cfb24;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:
sw = &fbcon_cfb32;
- display->dispsw_data = fbcon_cmap.cfb32;
+ display->dispsw_data = info->fbcon_cmap.cfb32;
break;
#endif
default:
@@ -534,15 +544,15 @@
static int igafb_switch(int con, struct fb_info *fb_info)
{
struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
-
+
/* Do we have to save the colormap? */
if (fb_display[info->currcon].cmap.len)
fb_get_cmap(&fb_display[info->currcon].cmap, 1,
iga_getcolreg, fb_info);
-
- info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con, fb_info);
+
+ info->currcon = con;
+ /* Install new colormap */
+ do_install_cmap(con, fb_info);
igafb_update_var(con, fb_info);
return 1;
}
@@ -577,15 +587,17 @@
if (default_var.bits_per_pixel > 8) {
info->video_cmap_len = 16;
} else {
- int i, j;
- for(i = 0; i < 16; i++) {
- j = color_table[i];
- info->palette[i].red = default_red[j];
- info->palette[i].green = default_grn[j];
- info->palette[i].blue = default_blu[j];
- }
info->video_cmap_len = 256;
}
+ {
+ int j, k;
+ for (j = 0; j < 16; j++) {
+ k = color_table[j];
+ info->palette[j].red = default_red[k];
+ info->palette[j].green = default_grn[k];
+ info->palette[j].blue = default_blu[k];
+ }
+ }
strcpy(info->fb_info.modename, igafb_name);
info->fb_info.node = -1;
@@ -598,16 +610,6 @@
info->fb_info.blank = &igafb_blank;
info->fb_info.flags=FBINFO_FLAG_DEFAULT;
- {
- int j, k;
- for (j = 0; j < 16; j++) {
- k = color_table[j];
- info->palette[j].red = default_red[k];
- info->palette[j].green = default_grn[k];
- info->palette[j].blue = default_blu[k];
- }
- }
-
igafb_set_disp(-1, info);
if (register_framebuffer(&info->fb_info) < 0)
@@ -619,7 +621,7 @@
iga_blank_border(info);
return 1;
-}
+}
int __init igafb_init(void)
@@ -637,6 +639,10 @@
pdev = pci_find_device(PCI_VENDOR_ID_INTERG,
PCI_DEVICE_ID_INTERG_1682, 0);
if (pdev == NULL) {
+ /*
+ * XXX We tried to use cyber2000fb.c for IGS 2000.
+ * But it does not initialize the chip in JavaStation-E, alas.
+ */
pdev = pci_find_device(PCI_VENDOR_ID_INTERG,
0x2000, 0);
if(pdev == NULL)
@@ -651,35 +657,43 @@
}
memset(info, 0, sizeof(struct fb_info_iga));
- info->frame_buffer = pdev->resource[0].start;
+ info->frame_buffer = ioremap(pdev->resource[0].start, 1024*1024*2);
if (!info->frame_buffer) {
kfree(info);
return -ENXIO;
}
- pcibios_read_config_dword(0, pdev->devfn,
- PCI_BASE_ADDRESS_0,
- (unsigned int*)&addr);
+ addr = pdev->resource[0].start;
if (!addr)
return -ENXIO;
info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
#ifdef __sparc__
-
- info->io_base_phys = info->frame_buffer_phys;
-
/*
- * The right test would be to look if there is a base I/O address.
- * But it appears that IGA 1682 reuses _memory_ address as a base
- * for I/O accesses.
+ * The following is sparc specific and this is why:
+ *
+ * IGS2000 has its I/O memory mapped and we want
+ * to generate memory cycles on PCI, e.g. do ioremap(),
+ * then readb/writeb() as in Documentation/IO-mapping.txt.
+ *
+ * IGS1682 is more traditional, it responds to PCI I/O
+ * cycles, so we want to access it with inb()/outb().
+ *
+ * On sparc, PCIC converts CPU memory access within
+ * phys window 0x3000xxxx into PCI I/O cycles. Therefore
+ * we may use readb/writeb to access them with IGS1682.
+ *
+ * We do not take io_base_phys from resource[n].start
+ * on IGS1682 because that chip is BROKEN. It does not
+ * have a base register for I/O. We just "know" what its
+ * I/O addresses are.
*/
if (iga2000) {
- info->io_base = (int) sparc_alloc_io(info->frame_buffer_phys |
- 0x00800000, NULL, 0x1000, "iga", 0, 0);
+ info->io_base_phys = info->frame_buffer_phys | 0x00800000;
} else {
- /* Obtain virtual address and correct physical by PCIC shift */
- info->io_base = pcic_alloc_io(&info->io_base_phys);
+ info->io_base_phys = 0x30000000; /* XXX */
}
+ info->io_base = (int) ioremap(info->io_base_phys, 0x1000);
if (!info->io_base) {
kfree(info);
return -ENXIO;
@@ -748,6 +762,7 @@
}
#endif
+
if (!iga_init(info)) {
if (info->mmap_map)
kfree(info->mmap_map);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)