diff options
Diffstat (limited to 'drivers/sgi/char')
-rw-r--r-- | drivers/sgi/char/newport.c | 64 | ||||
-rw-r--r-- | drivers/sgi/char/newport.h | 109 |
2 files changed, 170 insertions, 3 deletions
diff --git a/drivers/sgi/char/newport.c b/drivers/sgi/char/newport.c index e0c7a2d83..756aec709 100644 --- a/drivers/sgi/char/newport.c +++ b/drivers/sgi/char/newport.c @@ -1,9 +1,15 @@ /* - * newport.c: context switching the newport graphics card + * newport.c: context switching the newport graphics card and + * newport graphics support. * * Author: Miguel de Icaza */ - +#include <linux/errno.h> +#include <linux/sched.h> +#include <asm/types.h> +#include <asm/gfx.h> +#include <asm/ng1.h> +#include <asm/uaccess.h> #include "newport.h" /* Kernel routines for supporting graphics context switching */ @@ -155,3 +161,57 @@ void newport_restore (void *y) /* FIXME: restore dcb thingies */ } + +int +newport_ioctl (int card, int cmd, unsigned long arg) +{ + switch (cmd){ + case NG1_SETDISPLAYMODE: { + int i; + struct ng1_setdisplaymode_args request; + + if (copy_from_user (&request, (void *) arg, sizeof (request))) + return -EFAULT; + + newport_wait (); + newport_bfwait (); + npregs->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL | + DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL; + xmap9FIFOWait (npregs); + + /* FIXME: timing is wrong, just be extracted from + * the per-board timing table. I still have to figure + * out where this comes from + * + * This is used to select the protocol used to talk to + * the xmap9. For now I am using 60, selecting the + * WSLOW_DCB_XMAP9_PROTOCOL. + * + * Robert Tray comments on this issue: + * + * cfreq refers to the frequency of the monitor + * (ie. the refresh rate). Our monitors run typically + * between 60 Hz and 76 Hz. But it will be as low as + * 50 Hz if you're displaying NTSC/PAL and as high as + * 120 Hz if you are runining in stereo mode. You + * might want to try the WSLOW values. + */ + xmap9SetModeReg (npregs, request.wid, request.mode, 60); + return 0; + } + case NG1_SET_CURSOR_HOTSPOT: { + struct ng1_set_cursor_hotspot request; + + if (copy_from_user (&request, (void *) arg, sizeof (request))) + return -EFAULT; + /* FIXME: make request.xhot, request.yhot the hot spot */ + return 0; + } + + case NG1_SETGAMMARAMP0: + /* FIXME: load the gamma ramps :-) */ + return 0; + + } + return -EINVAL; +} diff --git a/drivers/sgi/char/newport.h b/drivers/sgi/char/newport.h index 21a624d28..2f9f044cb 100644 --- a/drivers/sgi/char/newport.h +++ b/drivers/sgi/char/newport.h @@ -1,4 +1,4 @@ -/* $Id: newport.h,v 1.3 1997/07/16 02:50:39 miguel Exp $ +/* $Id: newport.h,v 1.4 1997/08/28 01:45:17 miguel Exp $ * newport.h: Defines and register layout for NEWPORT graphics * hardware. * @@ -470,9 +470,116 @@ static inline int newport_bfwait(void) return 0; } +/* newport.c and cons_newport.c routines */ extern struct graphics_ops *newport_probe (int, const char **); void newport_save (void *); void newport_restore (void *); +void newport_reset (void); +int newport_ioctl (int card, int cmd, unsigned long arg); + +/* + * DCBMODE register defines: + */ + +/* Widht of the data being transfered for each DCBDATA[01] word */ +#define DCB_DATAWIDTH_4 0x0 +#define DCB_DATAWIDTH_1 0x1 +#define DCB_DATAWIDTH_2 0x2 +#define DCB_DATAWIDTH_3 0x3 + +/* If set, all of DCBDATA will be moved, otherwise only DATAWIDTH bytes */ +#define DCB_ENDATAPACK (1 << 2) + +/* Enables DCBCRS auto increment after each DCB transfer */ +#define DCB_ENCRSINC (1 << 3) + +/* shift for accessing the control register select address (DBCCRS, 3 bits) */ +#define DCB_CRS_SHIFT 4 + +/* DCBADDR (4 bits): display bus slave address */ +#define DCB_ADDR_SHIFT 7 +#define DCB_VC2 (0 << DCB_ADDR_SHIFT) +#define DCB_CMAP_ALL (1 << DCB_ADDR_SHIFT) +#define DCB_CMAP0 (2 << DCB_ADDR_SHIFT) +#define DCB_CMAP1 (3 << DCB_ADDR_SHIFT) +#define DCB_XMAP_ALL (4 << DCB_ADDR_SHIFT) +#define DCB_XMAP0 (5 << DCB_ADDR_SHIFT) +#define DCB_XMAP1 (6 << DCB_ADDR_SHIFT) +#define DCB_BT445 (7 << DCB_ADDR_SHIFT) +#define DCB_VCC1 (8 << DCB_ADDR_SHIFT) +#define DCB_VAB1 (9 << DCB_ADDR_SHIFT) +#define DCB_LG3_BDVERS0 (10 << DCB_ADDR_SHIFT) +#define DCB_LG3_ICS1562 (11 << DCB_ADDR_SHIFT) +#define DCB_RESERVED (15 << DCB_ADDR_SHIFT) + +/* DCB protocol ack types */ +#define DCB_ENSYNCACK (1 << 11) +#define DCB_ENASYNCACK (1 << 12) + +#define DCB_CSWIDTH_SHIFT 13 +#define DCB_CSHOLD_SHIFT 18 +#define DCB_CSSETUP_SHIFT 23 + +/* XMAP9 specific defines */ +/* XMAP9 -- registers as seen on the DCBMODE register*/ +# define XM9_CRS_CONFIG (0 << DCB_CRS_SHIFT) +# define XM9_PUPMODE (1 << 0) +# define XM9_ODD_PIXEL (1 << 1) +# define XM9_8_BITPLANES (1 << 2) +# define XM9_SLOW_DCB (1 << 3) +# define XM9_VIDEO_RGBMAP_MASK (3 << 4) +# define XM9_EXPRESS_VIDEO (1 << 6) +# define XM9_VIDEO_OPTION (1 << 7) +# define XM9_CRS_REVISION (1 << DCB_CRS_SHIFT) +# define XM9_CRS_FIFO_AVAIL (2 << DCB_CRS_SHIFT) +# define XM9_FIFO_0_AVAIL 0 +# define XM9_FIFO_1_AVAIL 1 +# define XM9_FIFO_2_AVAIL 3 +# define XM9_FIFO_3_AVAIL 2 +# define XM9_FIFO_FULL XM9_FIFO_0_AVAIL +# define XM9_FIFO_EMPTY XM9_FIFO_3_AVAIL +# define XM9_CRS_CURS_CMAP_MSB (3 << DCB_CRS_SHIFT) +# define XM9_CRS_PUP_CMAP_MSB (4 << DCB_CRS_SHIFT) +# define XM9_CRS_MODE_REG_DATA (5 << DCB_CRS_SHIFT) +# define XM9_CRS_MODE_REG_INDEX (7 << DCB_CRS_SHIFT) + + +#define DCB_CYCLES(setup,hold,width) \ + ((hold << DCB_CSHOLD_SHIFT) | \ + (setup << DCB_CSSETUP_SHIFT)| \ + (width << DCB_CSWIDTH_SHIFT)) + +#define W_DCB_XMAP9_PROTOCOL DCB_CYCLES (2, 1, 0) +#define WSLOW_DCB_XMAP9_PROTOCOL DCB_CYCLES (5, 5, 0) +#define WAYSLOW_DCB_XMAP9_PROTOCOL DCB_CYCLES (12, 12, 0) +#define R_DCB_XMAP9_PROTOCOL DCB_CYCLES (2, 1, 3) + +static inline void +xmap9FIFOWait (struct newport_regs *rex) +{ + rex->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL | + DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL; + newport_bfwait (); + + while ((rex->set.dcbdata0.bytes.b3 & 3) != XM9_FIFO_EMPTY) + ; +} + +static inline void +xmap9SetModeReg (struct newport_regs *rex, unsigned int modereg, unsigned int data24, int cfreq) +{ + if (cfreq > 119) + rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA | + DCB_DATAWIDTH_4 | W_DCB_XMAP9_PROTOCOL; + else if (cfreq > 59) + rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA | + DCB_DATAWIDTH_4 | WSLOW_DCB_XMAP9_PROTOCOL; + else + rex->set.dcbmode = DCB_XMAP_ALL | XM9_CRS_MODE_REG_DATA | + DCB_DATAWIDTH_4 | WAYSLOW_DCB_XMAP9_PROTOCOL; + rex->set.dcbdata0.all = ((modereg) << 24) | (data24 & 0xffffff); +} #endif /* !(_SGI_NEWPORT_H) */ + |