patch-2.1.30 linux/drivers/sbus/char/cgthree.c
Next file: linux/drivers/sbus/char/fb.h
Previous file: linux/drivers/sbus/char/bwtwo.c
Back to the patch index
Back to the overall index
- Lines: 175
- Date:
Thu Mar 20 17:11:52 1997
- Orig file:
v2.1.29/linux/drivers/sbus/char/cgthree.c
- Orig date:
Mon Dec 30 02:00:04 1996
diff -u --recursive --new-file v2.1.29/linux/drivers/sbus/char/cgthree.c linux/drivers/sbus/char/cgthree.c
@@ -1,7 +1,9 @@
-/* $Id: cgthree.c,v 1.10 1996/12/23 10:16:07 ecd Exp $
+/* $Id: cgthree.c,v 1.12 1997/03/11 23:44:24 ecd Exp $
* cgtree.c: cg3 frame buffer driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
*
* Support for cgRDI added, Nov/96, jj.
*/
@@ -22,22 +24,55 @@
#include "fb.h"
#include "cg_common.h"
+
+#define CG3_SR_RES_MASK 0x70
+#define CG3_SR_1152_900_76_A 0x40
+#define CG3_SR_1152_900_76_B 0x60
+#define CG3_SR_ID_MASK 0x0f
+#define CG3_SR_ID_COLOR 0x01
+#define CG3_SR_ID_MONO 0x02
+#define CG3_SR_ID_MONO_ECL 0x03
+
+
+enum cg3_type {
+ CG3_AT_66HZ = 0,
+ CG3_AT_76HZ,
+ CG3_RDI
+};
+
+
+struct cg3_regs {
+ struct bt_regs cmap;
+ volatile u8 control;
+ volatile u8 status;
+ volatile u8 cursor_start;
+ volatile u8 cursor_end;
+ volatile u8 h_blank_start;
+ volatile u8 h_blank_end;
+ volatile u8 h_sync_start;
+ volatile u8 h_sync_end;
+ volatile u8 comp_sync_end;
+ volatile u8 v_blank_start_high;
+ volatile u8 v_blank_start_low;
+ volatile u8 v_blank_end;
+ volatile u8 v_sync_start;
+ volatile u8 v_sync_end;
+ volatile u8 xfer_holdoff_start;
+ volatile u8 xfer_holdoff_end;
+};
+
/* The cg3 palette is loaded with 4 color values at each time */
/* so you end up with: (rgb)(r), (gb)(rg), (b)(rgb), and so on */
static void
cg3_loadcmap (fbinfo_t *fb, int index, int count)
{
- struct bt_regs *bt = fb->info.cg3.bt;
+ struct bt_regs *bt = &fb->info.cg3.regs->cmap;
int *i, steps;
i = (((int *)fb->color_map) + D4M3(index));
steps = D4M3(index+count-1) - D4M3(index)+3;
-#if 0
- if (fb->info.cg3.cgrdi) {
- *(volatile u8 *)bt->addr = (u8)(D4M4(index));
- } else
-#endif
- bt->addr = D4M4(index);
+
+ *(volatile u8 *)&bt->addr = (u8)D4M4(index);
while (steps--)
bt->color_map = *i++;
}
@@ -90,7 +125,38 @@
return 0;
}
-__initfunc(void cg3_setup (fbinfo_t *fb, int slot, uint cg3, int cg3_io, struct linux_sbus_device *sbdp))
+static u8 cg3regvals_66hz[] __initdata = { /* 1152 x 900, 66 Hz */
+ 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14,
+ 0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24,
+ 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x20, 0
+};
+
+static u8 cg3regvals_76hz[] __initdata = { /* 1152 x 900, 76 Hz */
+ 0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f,
+ 0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a,
+ 0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x24, 0
+};
+
+static u8 cg3regvals_rdi[] __initdata = { /* 640 x 480, cgRDI */
+ 0x14, 0x70, 0x15, 0x20, 0x16, 0x08, 0x17, 0x10,
+ 0x18, 0x06, 0x19, 0x02, 0x1a, 0x31, 0x1b, 0x51,
+ 0x1c, 0x06, 0x1d, 0x0c, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x22, 0
+};
+
+static u8 *cg3_regvals[] __initdata = {
+ cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
+};
+
+static u_char cg3_dacvals[] __initdata = {
+ 4, 0xff, 5, 0x00, 6, 0x70, 7, 0x00, 0
+};
+
+
+__initfunc(void cg3_setup (fbinfo_t *fb, int slot, uint cg3, int cg3_io,
+ struct linux_sbus_device *sbdp))
{
struct cg3_info *cg3info = (struct cg3_info *) &fb->info.cg3;
@@ -99,7 +165,8 @@
char *p;
int w, h;
- prom_getstring (sbdp->prom_node, "params", buffer, sizeof(buffer));
+ prom_getstring (sbdp->prom_node, "params",
+ buffer, sizeof(buffer));
if (*buffer) {
w = simple_strtoul (buffer, &p, 10);
if (w && *p == 'x') {
@@ -126,11 +193,45 @@
fb->reset = 0;
/* Map the card registers */
- cg3info->bt = sparc_alloc_io ((void *) cg3+CG3_REGS, 0,
- sizeof (struct bt_regs),"cg3_bt", cg3_io, 0);
- /* cgRDI actually has 32 bytes of regs, but I don't understand
- those bitfields yet (guess it is some interrupt stuff etc. */
-
+ cg3info->regs = sparc_alloc_io ((void *) cg3+CG3_REGS, 0,
+ sizeof (struct cg3_regs),"cg3_regs", cg3_io, 0);
+
+ if (!prom_getbool(sbdp->prom_node, "width")) {
+ /* Ugh, broken PROM didn't initialize us.
+ * Let's deal with this ourselves.
+ */
+ u8 status, mon;
+ enum cg3_type type;
+ u8 *p;
+
+ if (cg3info->cgrdi) {
+ type = CG3_RDI;
+ } else {
+ status = cg3info->regs->status;
+ if ((status & CG3_SR_ID_MASK) == CG3_SR_ID_COLOR) {
+ mon = status & CG3_SR_RES_MASK;
+ if (mon == CG3_SR_1152_900_76_A ||
+ mon == CG3_SR_1152_900_76_B)
+ type = CG3_AT_76HZ;
+ else
+ type = CG3_AT_66HZ;
+ } else {
+ prom_printf("cgthree: can't handle SR %02x\n",
+ status);
+ prom_halt();
+ return; /* fool gcc. */
+ }
+ }
+
+ for (p = cg3_regvals[type]; *p; p += 2)
+ ((u8 *)cg3info->regs)[p[0]] = p[1];
+
+ for (p = cg3_dacvals; *p; p += 2) {
+ *(volatile u8 *)&cg3info->regs->cmap.addr = p[0];
+ *(volatile u8 *)&cg3info->regs->cmap.control = p[1];
+ }
+ }
+
if (!fb->base){
fb->base=(uint) sparc_alloc_io ((void*) cg3+CG3_RAM, 0,
fb->type.fb_size, "cg3_ram", cg3_io, 0);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov