patch-2.2.17 linux/drivers/video/offb.c
Next file: linux/drivers/video/pm2fb.c
Previous file: linux/drivers/video/matroxfb.c
Back to the patch index
Back to the overall index
- Lines: 245
- Date:
Mon Sep 4 18:39:22 2000
- Orig file:
v2.2.16/drivers/video/offb.c
- Orig date:
Mon Sep 4 18:37:41 2000
diff -u --recursive --new-file v2.2.16/drivers/video/offb.c linux/drivers/video/offb.c
@@ -42,6 +42,15 @@
static int currcon = 0;
+/* Supported palette hacks */
+enum {
+ cmap_unknown,
+ cmap_m64, /* ATI Mach64 */
+ cmap_r128, /* ATI Rage128 */
+ cmap_M3A, /* ATI Rage Mobility M3 Head A */
+ cmap_M3B /* ATI Rage Mobility M3 Head B */
+};
+
struct fb_info_offb {
struct fb_info info;
struct fb_fix_screeninfo fix;
@@ -50,6 +59,7 @@
struct { u_char red, green, blue, pad; } palette[256];
volatile unsigned char *cmap_adr;
volatile unsigned char *cmap_data;
+ int cmap_type;
union {
#ifdef FBCON_HAS_CFB16
u16 cfb16[16];
@@ -106,7 +116,8 @@
static int offb_init_driver(struct device_node *);
static void offb_init_nodriver(struct device_node *);
static void offb_init_fb(const char *name, const char *full_name, int width,
- int height, int depth, int pitch, unsigned long address);
+ int height, int depth, int pitch, unsigned long address,
+ struct device_node *dp);
/*
* Interface to the low level console driver
@@ -293,6 +304,9 @@
#ifdef CONFIG_FB_ATY
extern void atyfb_of_init(struct device_node *dp);
#endif /* CONFIG_FB_ATY */
+#if defined(CONFIG_FB_ATY128)
+extern void aty128fb_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_ATY128 */
#ifdef CONFIG_FB_S3TRIO
extern void s3triofb_init_of(struct device_node *dp);
#endif /* CONFIG_FB_S3TRIO */
@@ -362,6 +376,20 @@
}
/*
+ * The M3 on the Pismo powerbook has no addresses
+ * on the display nodes, they are on their parent.
+ */
+ if (dp->n_addrs == 0 && device_is_compatible(dp, "ATY,RageM3p")) {
+ int na;
+ unsigned int *ap = (unsigned int *)
+ get_property(dp, "AAPL,address", &na);
+ if (ap != 0)
+ for (na /= sizeof(unsigned int); na > 0; --na, ++ap)
+ if (*ap <= addr && addr < *ap + 0x1000000)
+ goto foundit;
+ }
+
+ /*
* See if the display address is in one of the address
* ranges for this display.
*/
@@ -386,7 +414,7 @@
boot_infos->dispDeviceRect[2],
boot_infos->dispDeviceRect[3],
boot_infos->dispDeviceDepth,
- boot_infos->dispDeviceRowBytes, addr);
+ boot_infos->dispDeviceRowBytes, addr, 0);
}
}
@@ -409,6 +437,15 @@
__initfunc(static int offb_init_driver(struct device_node *dp))
{
+#ifdef CONFIG_FB_ATY128
+ if (!strncmp(dp->name, "ATY,Rage128", 11) ||
+ !strncmp(dp->name, "ATY,RageM3pA", 12)) {
+ aty128fb_of_init(dp);
+ return 1;
+ }
+ if (!strncmp(dp->name, "ATY,RageM3pB", 12))
+ return 0;
+#endif /* CONFIG_FB_ATY128*/
#ifdef CONFIG_FB_ATY
if (!strncmp(dp->name, "ATY", 3)) {
atyfb_of_init(dp);
@@ -477,9 +514,11 @@
&& len == sizeof(int))
height = *pp;
if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
- && len == sizeof(int))
+ && len == sizeof(int)) {
pitch = *pp;
- else
+ if (pitch == 1)
+ pitch = 0x1000;
+ } else
pitch = width;
if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
&& len == sizeof(unsigned))
@@ -500,13 +539,14 @@
address += 0x1000;
}
offb_init_fb(dp->name, dp->full_name, width, height, depth,
- pitch, address);
+ pitch, address, dp);
}
__initfunc(static void offb_init_fb(const char *name, const char *full_name,
int width, int height, int depth,
- int pitch, unsigned long address))
+ int pitch, unsigned long address,
+ struct device_node *dp))
{
int i;
struct fb_fix_screeninfo *fix;
@@ -543,13 +583,27 @@
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
+ info->cmap_type = cmap_unknown;
if (depth == 8)
{
/* XXX kludge for ati */
- if (strncmp(name, "ATY,", 4) == 0) {
+ if (dp && !strncmp(name, "ATY,Rage128", 11)) {
+ unsigned long regbase = dp->addrs[2].address;
+ info->cmap_adr = ioremap(regbase, 0x1FFF);
+ info->cmap_type = cmap_r128;
+ } else if (dp && !strncmp(name, "ATY,RageM3pA", 12)) {
+ unsigned long regbase = dp->parent->addrs[2].address;
+ info->cmap_adr = ioremap(regbase, 0x1FFF);
+ info->cmap_type = cmap_M3A;
+ } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
+ unsigned long regbase = dp->parent->addrs[2].address;
+ info->cmap_adr = ioremap(regbase, 0x1FFF);
+ info->cmap_type = cmap_M3B;
+ } else if (!strncmp(name, "ATY,", 4)) {
unsigned long base = address & 0xff000000UL;
info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
info->cmap_data = info->cmap_adr + 1;
+ info->cmap_type = cmap_m64;
}
fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_STATIC_PSEUDOCOLOR;
@@ -706,7 +760,7 @@
display_info.cmap_data_address = 0;
display_info.disp_reg_address = 0;
/* XXX kludge for ati */
- if (strncmp(name, "ATY,", 4) == 0) {
+ if (info->cmap_type == cmap_m64) {
unsigned long base = address & 0xff000000UL;
display_info.disp_reg_address = base + 0x7ffc00;
display_info.cmap_adr_address = base + 0x7ffcc0;
@@ -767,12 +821,33 @@
return;
if (blank)
- for (i = 0; i < 256; i++) {
- *info2->cmap_adr = i;
- mach_eieio();
- for (j = 0; j < 3; j++) {
- *info2->cmap_data = 0;
- mach_eieio();
+ for (i = 0; i < 256; i++) {
+ switch(info2->cmap_type) {
+ case cmap_m64:
+ *info2->cmap_adr = i;
+ mach_eieio();
+ for (j = 0; j < 3; j++) {
+ *info2->cmap_data = 0;
+ mach_eieio();
+ }
+ break;
+ case cmap_M3A:
+ /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+ case cmap_r128:
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, i);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+ break;
+ case cmap_M3B:
+ /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, i);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+ break;
}
}
else
@@ -823,14 +898,37 @@
info2->palette[regno].green = green;
info2->palette[regno].blue = blue;
- *info2->cmap_adr = regno;/* On some chipsets, add << 3 in 15 bits */
- mach_eieio();
- *info2->cmap_data = red;
- mach_eieio();
- *info2->cmap_data = green;
- mach_eieio();
- *info2->cmap_data = blue;
- mach_eieio();
+ switch(info2->cmap_type) {
+ case cmap_m64:
+ *info2->cmap_adr = regno;
+ mach_eieio();
+ *info2->cmap_data = red;
+ mach_eieio();
+ *info2->cmap_data = green;
+ mach_eieio();
+ *info2->cmap_data = blue;
+ mach_eieio();
+ break;
+ case cmap_M3A:
+ /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+ case cmap_r128:
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, regno);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+ (red << 16 | green << 8 | blue));
+ break;
+ case cmap_M3B:
+ /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, regno);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+ (red << 16 | green << 8 | blue));
+ break;
+ }
if (regno < 16)
switch (info2->var.bits_per_pixel) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)