171d7fec4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1400.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */
271d7fec4Smrg/*-----------------------------------------------------------------------------
371d7fec4Smrg * VID_1400.C
471d7fec4Smrg *
571d7fec4Smrg * Version 2.0 - February 21, 2000
671d7fec4Smrg *
771d7fec4Smrg * This file contains routines to control the SC1400 video overlay hardware.
871d7fec4Smrg *
971d7fec4Smrg * History:
1071d7fec4Smrg *    Versions 0.1 through 2.0 by Brian Falardeau.
1171d7fec4Smrg *
1271d7fec4Smrg * Copyright (c) 1999-2000 National Semiconductor.
1371d7fec4Smrg *-----------------------------------------------------------------------------
1471d7fec4Smrg */
1571d7fec4Smrg
1671d7fec4Smrg/*----------------------------------------------------------------------------
1771d7fec4Smrg * SC1400 PLL TABLE
1871d7fec4Smrg *----------------------------------------------------------------------------
1971d7fec4Smrg */
2071d7fec4Smrg
2171d7fec4Smrgtypedef struct tagSC1400PLL
2271d7fec4Smrg{
2371d7fec4Smrg   long frequency;			/* 16.16 fixed point frequency */
2471d7fec4Smrg   unsigned long clock_select;		/* clock select register (0x2C) */
2571d7fec4Smrg}
2671d7fec4SmrgSC1400PLL;
2771d7fec4Smrg
2871d7fec4SmrgSC1400PLL gfx_sc1400_clock_table[] = {
2971d7fec4Smrg   {0x00192CCC, 0x00000000},		/*  25.1750 */
3071d7fec4Smrg   {0x001C526E, 0x00010000},		/*  28.3220 */
3171d7fec4Smrg   {0x001F8000, 0x00020000},		/*  31.5000 */
3271d7fec4Smrg   {0x00240000, 0x000E0000},		/*  36.0000 */
3371d7fec4Smrg   {0x00258000, 0x0010110C},		/*  37.5000 */
3471d7fec4Smrg   {0x00280000, 0x00040000},		/*  40.0000 */
3571d7fec4Smrg   {0x002CE666, 0x00090000},		/*  44.9000 */
3671d7fec4Smrg   {0x00320000, 0x00100C06},		/*  50.0000 */
3771d7fec4Smrg   {0x00325999, 0x0050600C},		/*  50.3500 */
3871d7fec4Smrg   {0x00360000, 0x00100100},		/*  54.0000 */
3971d7fec4Smrg   {0x0038643F, 0x0010160A},		/*  56.3916 */
4071d7fec4Smrg   {0x0038A3D7, 0x00506C0C},		/*  56.6440 */
4171d7fec4Smrg   {0x003B0000, 0x0010170A},		/*  59.6583 */
4271d7fec4Smrg   {0x003BA886, 0x00100A04},		/*  59.6583 */
4371d7fec4Smrg   {0x003F0000, 0x00100602},		/*  63.0000 */
4471d7fec4Smrg   {0x00410000, 0x00060000},		/*  65.0000 */
4571d7fec4Smrg   {0x00438000, 0x00100401},		/*  67.5000 */
4671d7fec4Smrg   {0x0046CCCC, 0x00101407},		/*  70.8000 */
4771d7fec4Smrg   {0x00480000, 0x00100702},		/*  72.0000 */
4871d7fec4Smrg   {0x004B0000, 0x00070000},		/*  75.0000 */
4971d7fec4Smrg   {0x004EC000, 0x0010220B},		/*  78.7500 */
5071d7fec4Smrg   {0x00500000, 0x00304C0C},		/*  80.0000 */
5171d7fec4Smrg   {0x00510000, 0x00100200},		/*  81.0000 */
5271d7fec4Smrg   {0x00550000, 0x00080000},		/*  85.0000 */
5371d7fec4Smrg   {0x0059CCCC, 0x00100902},		/*  89.8000 */
5471d7fec4Smrg   {0x00630000, 0x00100A02},		/*  99.0000 */
5571d7fec4Smrg   {0x00640000, 0x00102409},		/* 100.0000 */
5671d7fec4Smrg   {0x006C0000, 0x00100300},		/* 108.0000 */
5771d7fec4Smrg   {0x00870000, 0x00050000},		/* 135.0000 */
5871d7fec4Smrg   {0x009D8000, 0x00102205},		/* 157.5000 */
5971d7fec4Smrg   {0x00A20000, 0x00100500},		/* 162.0000 */
6071d7fec4Smrg   {0x00AA0000, 0x000B0000},		/* 170.0000 */
6171d7fec4Smrg   {0x00AF0000, 0x00100C01},		/* 175.0000 */
6271d7fec4Smrg   {0x00BD0000, 0x00100600},		/* 189.0000 */
6371d7fec4Smrg   {0x00CA0000, 0x00100E01},		/* 202.0000 */
6471d7fec4Smrg   {0x00E80000, 0x00102A04},		/* 232.0000 */
6571d7fec4Smrg};
6671d7fec4Smrg
6771d7fec4Smrg#define NUM_SC1400_FREQUENCIES sizeof(gfx_sc1400_clock_table)/sizeof(SC1400PLL)
6871d7fec4Smrg
6971d7fec4Smrg/*---------------------------------------------------------------------------
7071d7fec4Smrg * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API)
7171d7fec4Smrg *
7271d7fec4Smrg * This routine is used to disable all components of video overlay before
7371d7fec4Smrg * performing a mode switch.
7471d7fec4Smrg *---------------------------------------------------------------------------
7571d7fec4Smrg */
7671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
7771d7fec4Smrgvoid
7871d7fec4Smrgsc1400_reset_video(void)
7971d7fec4Smrg#else
8071d7fec4Smrgvoid
8171d7fec4Smrggfx_reset_video(void)
8271d7fec4Smrg#endif
8371d7fec4Smrg{
8471d7fec4Smrg   gfx_set_video_enable(0);
8571d7fec4Smrg}
8671d7fec4Smrg
8771d7fec4Smrg/*---------------------------------------------------------------------------
8871d7fec4Smrg * gfx_set_clock_frequency
8971d7fec4Smrg *
9071d7fec4Smrg * This routine sets the clock frequency, specified as a 16.16 fixed point
9171d7fec4Smrg * value (0x00318000 = 49.5 MHz).  It will set the closest frequency found
9271d7fec4Smrg * in the lookup table.
9371d7fec4Smrg *---------------------------------------------------------------------------
9471d7fec4Smrg */
9571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
9671d7fec4Smrgvoid
9771d7fec4Smrgsc1400_set_clock_frequency(unsigned long frequency)
9871d7fec4Smrg#else
9971d7fec4Smrgvoid
10071d7fec4Smrggfx_set_clock_frequency(unsigned long frequency)
10171d7fec4Smrg#endif
10271d7fec4Smrg{
10371d7fec4Smrg   int index;
10471d7fec4Smrg   unsigned long value;
10571d7fec4Smrg   long min, diff;
10671d7fec4Smrg
10771d7fec4Smrg   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
10871d7fec4Smrg   /* Search the table for the closest frequency (16.16 format). */
10971d7fec4Smrg
11071d7fec4Smrg   value = gfx_sc1400_clock_table[0].clock_select;
11171d7fec4Smrg   min = (long)gfx_sc1400_clock_table[0].frequency - frequency;
11271d7fec4Smrg   if (min < 0L)
11371d7fec4Smrg      min = -min;
11471d7fec4Smrg   for (index = 1; index < NUM_SC1400_FREQUENCIES; index++) {
11571d7fec4Smrg      diff = (long)gfx_sc1400_clock_table[index].frequency - frequency;
11671d7fec4Smrg      if (diff < 0L)
11771d7fec4Smrg	 diff = -diff;
11871d7fec4Smrg      if (diff < min) {
11971d7fec4Smrg	 min = diff;
12071d7fec4Smrg	 value = gfx_sc1400_clock_table[index].clock_select;
12171d7fec4Smrg      }
12271d7fec4Smrg   }
12371d7fec4Smrg
12471d7fec4Smrg   /* SET THE DOT CLOCK REGISTER */
12571d7fec4Smrg
12671d7fec4Smrg   WRITE_VID32(SC1400_VID_MISC, 0x00001000);
12771d7fec4Smrg   WRITE_VID32(SC1400_VID_CLOCK_SELECT, value);
12871d7fec4Smrg   return;
12971d7fec4Smrg}
13071d7fec4Smrg
13171d7fec4Smrg/*-----------------------------------------------------------------------------
13271d7fec4Smrg * gfx_set_video_enable
13371d7fec4Smrg *
13471d7fec4Smrg * This routine enables or disables the video overlay functionality.
13571d7fec4Smrg *-----------------------------------------------------------------------------
13671d7fec4Smrg */
13771d7fec4Smrg#if GFX_VIDEO_DYNAMIC
13871d7fec4Smrgint
13971d7fec4Smrgsc1400_set_video_enable(int enable)
14071d7fec4Smrg#else
14171d7fec4Smrgint
14271d7fec4Smrggfx_set_video_enable(int enable)
14371d7fec4Smrg#endif
14471d7fec4Smrg{
14571d7fec4Smrg   unsigned long vcfg;
14671d7fec4Smrg
14771d7fec4Smrg   /* WAIT FOR VERTICAL BLANK TO START */
14871d7fec4Smrg   /* Otherwise a glitch can be observed. */
14971d7fec4Smrg
15071d7fec4Smrg   if (gfx_test_timing_active()) {
15171d7fec4Smrg      if (!gfx_test_vertical_active()) {
15271d7fec4Smrg	 while (!gfx_test_vertical_active()) ;
15371d7fec4Smrg      }
15471d7fec4Smrg      while (gfx_test_vertical_active()) ;
15571d7fec4Smrg   }
15671d7fec4Smrg   vcfg = READ_VID32(SC1400_VIDEO_CONFIG);
15771d7fec4Smrg   if (enable) {
15871d7fec4Smrg      /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
15971d7fec4Smrg      /* Use private routine to abstract the display controller. */
16071d7fec4Smrg
16171d7fec4Smrg      gfx_set_display_video_enable(1);
16271d7fec4Smrg
16371d7fec4Smrg      /* SET SC1400 BUS CONTROL PARAMETERS */
16471d7fec4Smrg      /* Currently always high speed, 8-bit interface. */
16571d7fec4Smrg
16671d7fec4Smrg      vcfg |= SC1400_VCFG_HIGH_SPD_INT;
16771d7fec4Smrg      vcfg &= ~(SC1400_VCFG_EARLY_VID_RDY | SC1400_VCFG_16_BIT_EN);
16871d7fec4Smrg
16971d7fec4Smrg      /* ENABLE SC1400 VIDEO OVERLAY */
17071d7fec4Smrg
17171d7fec4Smrg      vcfg |= SC1400_VCFG_VID_EN;
17271d7fec4Smrg      WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg);
17371d7fec4Smrg   } else {
17471d7fec4Smrg      /* DISABLE SC1400 VIDEO OVERLAY */
17571d7fec4Smrg
17671d7fec4Smrg      vcfg &= ~SC1400_VCFG_VID_EN;
17771d7fec4Smrg      WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg);
17871d7fec4Smrg
17971d7fec4Smrg      /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
18071d7fec4Smrg      /* Use private routine to abstract the display controller. */
18171d7fec4Smrg
18271d7fec4Smrg      gfx_set_display_video_enable(0);
18371d7fec4Smrg   }
18471d7fec4Smrg   return (0);
18571d7fec4Smrg}
18671d7fec4Smrg
18771d7fec4Smrg/*-----------------------------------------------------------------------------
18871d7fec4Smrg * gfx_set_video_format
18971d7fec4Smrg *
19071d7fec4Smrg * Currently only sets 4:2:0 format, Y1 V Y0 U.
19171d7fec4Smrg *-----------------------------------------------------------------------------
19271d7fec4Smrg */
19371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
19471d7fec4Smrgint
19571d7fec4Smrgsc1400_set_video_format(unsigned long format)
19671d7fec4Smrg#else
19771d7fec4Smrgint
19871d7fec4Smrggfx_set_video_format(unsigned long format)
19971d7fec4Smrg#endif
20071d7fec4Smrg{
20171d7fec4Smrg   unsigned long vcfg = 0;
20271d7fec4Smrg
20371d7fec4Smrg   /* SET THE SC1400 VIDEO INPUT FORMAT */
20471d7fec4Smrg
20571d7fec4Smrg   vcfg = READ_VID32(SC1400_VIDEO_CONFIG);
20671d7fec4Smrg   vcfg &= ~(SC1400_VCFG_VID_INP_FORMAT | SC1400_VCFG_4_2_0_MODE);
20771d7fec4Smrg   vcfg &= ~(SC1400_VCFG_CSC_BYPASS);
20871d7fec4Smrg   if (format < 4)
20971d7fec4Smrg      vcfg |= (format << 2);
21071d7fec4Smrg   else
21171d7fec4Smrg      vcfg |= SC1400_VCFG_CSC_BYPASS;
21271d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg);
21371d7fec4Smrg   return (0);
21471d7fec4Smrg}
21571d7fec4Smrg
21671d7fec4Smrg/*-----------------------------------------------------------------------------
21771d7fec4Smrg * gfx_set_video_size
21871d7fec4Smrg *
21971d7fec4Smrg * This routine specifies the size of the source data.  It is used only
22071d7fec4Smrg * to determine how much data to transfer per frame, and is not used to
22171d7fec4Smrg * calculate the scaling value (that is handled by a separate routine).
22271d7fec4Smrg *-----------------------------------------------------------------------------
22371d7fec4Smrg */
22471d7fec4Smrg#if GFX_VIDEO_DYNAMIC
22571d7fec4Smrgint
22671d7fec4Smrgsc1400_set_video_size(unsigned short width, unsigned short height)
22771d7fec4Smrg#else
22871d7fec4Smrgint
22971d7fec4Smrggfx_set_video_size(unsigned short width, unsigned short height)
23071d7fec4Smrg#endif
23171d7fec4Smrg{
23271d7fec4Smrg   unsigned long size, vcfg;
23371d7fec4Smrg
23471d7fec4Smrg   /* SET THE SC1400 VIDEO LINE SIZE */
23571d7fec4Smrg
23671d7fec4Smrg   vcfg = READ_VID32(SC1400_VIDEO_CONFIG);
23771d7fec4Smrg   vcfg &= ~(SC1400_VCFG_LINE_SIZE_LOWER_MASK | SC1400_VCFG_LINE_SIZE_UPPER);
23871d7fec4Smrg   size = (width >> 1);
23971d7fec4Smrg   vcfg |= (size & 0x00FF) << 8;
24071d7fec4Smrg   if (size & 0x0100)
24171d7fec4Smrg      vcfg |= SC1400_VCFG_LINE_SIZE_UPPER;
24271d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg);
24371d7fec4Smrg
24471d7fec4Smrg   /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */
24571d7fec4Smrg   /* Use private routine to abstract the display controller. */
24671d7fec4Smrg
24771d7fec4Smrg   gfx_set_display_video_size(width, height);
24871d7fec4Smrg   return (0);
24971d7fec4Smrg}
25071d7fec4Smrg
25171d7fec4Smrg/*-----------------------------------------------------------------------------
25271d7fec4Smrg * gfx_set_video_offset
25371d7fec4Smrg *
25471d7fec4Smrg * This routine sets the starting offset for the video buffer when only
25571d7fec4Smrg * one offset needs to be specified.
25671d7fec4Smrg *-----------------------------------------------------------------------------
25771d7fec4Smrg */
25871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
25971d7fec4Smrgint
26071d7fec4Smrgsc1400_set_video_offset(unsigned long offset)
26171d7fec4Smrg#else
26271d7fec4Smrgint
26371d7fec4Smrggfx_set_video_offset(unsigned long offset)
26471d7fec4Smrg#endif
26571d7fec4Smrg{
26671d7fec4Smrg   /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
26771d7fec4Smrg
26871d7fec4Smrg   gfx_vid_offset = offset;
26971d7fec4Smrg
27071d7fec4Smrg   /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
27171d7fec4Smrg   /* Use private routine to abstract the display controller. */
27271d7fec4Smrg
27371d7fec4Smrg   gfx_set_display_video_offset(offset);
27471d7fec4Smrg   return (0);
27571d7fec4Smrg}
27671d7fec4Smrg
27771d7fec4Smrg/*---------------------------------------------------------------------------
27871d7fec4Smrg * gfx_set_video_scale
27971d7fec4Smrg *
28071d7fec4Smrg * This routine sets the scale factor for the video overlay window.  The
28171d7fec4Smrg * size of the source and destination regions are specified in pixels.
28271d7fec4Smrg *---------------------------------------------------------------------------
28371d7fec4Smrg */
28471d7fec4Smrg#if GFX_VIDEO_DYNAMIC
28571d7fec4Smrgint
28671d7fec4Smrgsc1400_set_video_scale(unsigned short srcw, unsigned short srch,
28771d7fec4Smrg		       unsigned short dstw, unsigned short dsth)
28871d7fec4Smrg#else
28971d7fec4Smrgint
29071d7fec4Smrggfx_set_video_scale(unsigned short srcw, unsigned short srch,
29171d7fec4Smrg		    unsigned short dstw, unsigned short dsth)
29271d7fec4Smrg#endif
29371d7fec4Smrg{
29471d7fec4Smrg   unsigned long xscale, yscale;
29571d7fec4Smrg
29671d7fec4Smrg   /* SAVE PARAMETERS */
29771d7fec4Smrg   /* These are needed for clipping the video window later. */
29871d7fec4Smrg
29971d7fec4Smrg   gfx_vid_srcw = srcw;
30071d7fec4Smrg   gfx_vid_srch = srch;
30171d7fec4Smrg   gfx_vid_dstw = dstw;
30271d7fec4Smrg   gfx_vid_dsth = dsth;
30371d7fec4Smrg
30471d7fec4Smrg   /* CALCULATE SC1400 SCALE FACTORS */
30571d7fec4Smrg   /* No downscaling in SC1400 so force to 1x if attempted. */
30671d7fec4Smrg
30771d7fec4Smrg   if (srcw < dstw)
30871d7fec4Smrg      xscale = (0x2000 * (srcw - 1)) / (dstw - 1);
30971d7fec4Smrg   else
31071d7fec4Smrg      xscale = 0x1FFF;
31171d7fec4Smrg   if (srch < dsth)
31271d7fec4Smrg      yscale = (0x2000 * (srch - 1)) / (dsth - 1);
31371d7fec4Smrg   else
31471d7fec4Smrg      yscale = 0x1FFF;
31571d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_SCALE, (yscale << 16) | xscale);
31671d7fec4Smrg
31771d7fec4Smrg   /* CALL ROUTINE TO UPDATE WINDOW POSITION */
31871d7fec4Smrg   /* This is required because the scale values effect the number of */
31971d7fec4Smrg   /* source data pixels that need to be clipped, as well as the */
32071d7fec4Smrg   /* amount of data that needs to be transferred. */
32171d7fec4Smrg
32271d7fec4Smrg   gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width,
32371d7fec4Smrg			gfx_vid_height);
32471d7fec4Smrg   return (0);
32571d7fec4Smrg}
32671d7fec4Smrg
32771d7fec4Smrg/*---------------------------------------------------------------------------
32871d7fec4Smrg * gfx_set_video_window
32971d7fec4Smrg *
33071d7fec4Smrg * This routine sets the position and size of the video overlay window.  The
33171d7fec4Smrg * position is specified in screen relative coordinates, and may be negative.
33271d7fec4Smrg * The size of destination region is specified in pixels.  The line size
33371d7fec4Smrg * indicates the number of bytes of source data per scanline.
33471d7fec4Smrg *---------------------------------------------------------------------------
33571d7fec4Smrg */
33671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
33771d7fec4Smrgint
33871d7fec4Smrgsc1400_set_video_window(short x, short y, unsigned short w, unsigned short h)
33971d7fec4Smrg#else
34071d7fec4Smrgint
34171d7fec4Smrggfx_set_video_window(short x, short y, unsigned short w, unsigned short h)
34271d7fec4Smrg#endif
34371d7fec4Smrg{
34471d7fec4Smrg   unsigned long vcfg = 0;
34571d7fec4Smrg   unsigned long hadjust, vadjust;
34671d7fec4Smrg   unsigned long initread;
34771d7fec4Smrg   unsigned long xstart, ystart, xend, yend;
34871d7fec4Smrg   unsigned long offset, line_size;
34971d7fec4Smrg
35071d7fec4Smrg   /* SAVE PARAMETERS */
35171d7fec4Smrg   /* These are needed to call this routine if the scale value changes. */
35271d7fec4Smrg
35371d7fec4Smrg   gfx_vid_xpos = x;
35471d7fec4Smrg   gfx_vid_ypos = y;
35571d7fec4Smrg   gfx_vid_width = w;
35671d7fec4Smrg   gfx_vid_height = h;
35771d7fec4Smrg
35871d7fec4Smrg   /* GET ADJUSTMENT VALUES */
35971d7fec4Smrg   /* Use routines to abstract version of display controller. */
36071d7fec4Smrg
36171d7fec4Smrg   hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13;
36271d7fec4Smrg   vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1;
36371d7fec4Smrg
36471d7fec4Smrg   if (x > 0) {
36571d7fec4Smrg      /* NO CLIPPING ON LEFT */
36671d7fec4Smrg
36771d7fec4Smrg      xstart = x + hadjust;
36871d7fec4Smrg      initread = 0;
36971d7fec4Smrg   } else {
37071d7fec4Smrg      /* CLIPPING ON LEFT */
37171d7fec4Smrg      /* Adjust initial read for scale, checking for divide by zero */
37271d7fec4Smrg
37371d7fec4Smrg      xstart = hadjust;
37471d7fec4Smrg      initread = -x;
37571d7fec4Smrg      if (gfx_vid_dstw)
37671d7fec4Smrg	 initread = ((-x) * gfx_vid_srcw) / gfx_vid_dstw;
37771d7fec4Smrg      else
37871d7fec4Smrg	 initread = 0;
37971d7fec4Smrg   }
38071d7fec4Smrg
38171d7fec4Smrg   /* CLIPPING ON RIGHT */
38271d7fec4Smrg
38371d7fec4Smrg   xend = x + w;
38471d7fec4Smrg   if (xend > gfx_get_hactive())
38571d7fec4Smrg      xend = gfx_get_hactive();
38671d7fec4Smrg   xend += hadjust;
38771d7fec4Smrg
38871d7fec4Smrg   /* CLIPPING ON TOP */
38971d7fec4Smrg
39071d7fec4Smrg   offset = gfx_vid_offset;
39171d7fec4Smrg   if (y >= 0) {
39271d7fec4Smrg      ystart = y + vadjust;
39371d7fec4Smrg   } else {
39471d7fec4Smrg      ystart = vadjust;
39571d7fec4Smrg      line_size = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE;
39671d7fec4Smrg      if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER)
39771d7fec4Smrg	 line_size += 512;
39871d7fec4Smrg      if (gfx_vid_dsth)
39971d7fec4Smrg	 offset = gfx_vid_offset + (line_size << 1) *
40071d7fec4Smrg	       (((-y) * gfx_vid_srch) / gfx_vid_dsth);
40171d7fec4Smrg   }
40271d7fec4Smrg
40371d7fec4Smrg   /* CLIPPING ON BOTTOM */
40471d7fec4Smrg
40571d7fec4Smrg   yend = y + h;
40671d7fec4Smrg   if (yend >= gfx_get_vactive())
40771d7fec4Smrg      yend = gfx_get_vactive();
40871d7fec4Smrg   yend += vadjust;
40971d7fec4Smrg
41071d7fec4Smrg   /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
41171d7fec4Smrg   /* Use private routine to abstract the display controller. */
41271d7fec4Smrg
41371d7fec4Smrg   gfx_set_display_video_offset(offset);
41471d7fec4Smrg
41571d7fec4Smrg   /* DISABLE REGISTER UPDATES */
41671d7fec4Smrg
41771d7fec4Smrg   vcfg = READ_VID32(SC1400_VIDEO_CONFIG);
41871d7fec4Smrg   vcfg &= ~SC1400_VCFG_VID_REG_UPDATE;
41971d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg);
42071d7fec4Smrg
42171d7fec4Smrg   /* SET VIDEO POSITION */
42271d7fec4Smrg
42371d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_X_POS, (xend << 16) | xstart);
42471d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_Y_POS, (yend << 16) | ystart);
42571d7fec4Smrg
42671d7fec4Smrg   /* SET INITIAL READ ADDRESS AND ENABLE REGISTER UPDATES */
42771d7fec4Smrg
42871d7fec4Smrg   vcfg &= ~SC1400_VCFG_INIT_READ_MASK;
42971d7fec4Smrg   vcfg |= (initread << 15) & SC1400_VCFG_INIT_READ_MASK;
43071d7fec4Smrg   vcfg |= SC1400_VCFG_VID_REG_UPDATE;
43171d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg);
43271d7fec4Smrg   return (0);
43371d7fec4Smrg}
43471d7fec4Smrg
43571d7fec4Smrg/*---------------------------------------------------------------------------
43671d7fec4Smrg * gfx_set_video_color_key
43771d7fec4Smrg *
43871d7fec4Smrg * This routine specifies the color key value and mask for the video overlay
43971d7fec4Smrg * hardware.  To disable color key, the color and mask should both be set to
44071d7fec4Smrg * zero.  The hardware uses the color key in the following equation:
44171d7fec4Smrg *
44271d7fec4Smrg * ((source data) & (color key mask)) == ((color key) & (color key mask))
44371d7fec4Smrg *
44471d7fec4Smrg * The source data can be either graphics data or video data.  The bluescreen
44571d7fec4Smrg * parameter is set to have the hardware compare video data and clear to
44671d7fec4Smrg * comapare graphics data.
44771d7fec4Smrg *---------------------------------------------------------------------------
44871d7fec4Smrg */
44971d7fec4Smrg#if GFX_VIDEO_DYNAMIC
45071d7fec4Smrgint
45171d7fec4Smrgsc1400_set_video_color_key(unsigned long key, unsigned long mask,
45271d7fec4Smrg			   int graphics)
45371d7fec4Smrg#else
45471d7fec4Smrgint
45571d7fec4Smrggfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics)
45671d7fec4Smrg#endif
45771d7fec4Smrg{
45871d7fec4Smrg   unsigned long dcfg = 0;
45971d7fec4Smrg
46071d7fec4Smrg   /* SET SC1400 COLOR KEY VALUE */
46171d7fec4Smrg
46271d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_COLOR_KEY, key);
46371d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_COLOR_MASK, mask);
46471d7fec4Smrg
46571d7fec4Smrg   /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */
46671d7fec4Smrg
46771d7fec4Smrg   dcfg = READ_VID32(SC1400_DISPLAY_CONFIG);
46871d7fec4Smrg   if (graphics & 0x01)
46971d7fec4Smrg      dcfg &= ~SC1400_DCFG_VG_CK;
47071d7fec4Smrg   else
47171d7fec4Smrg      dcfg |= SC1400_DCFG_VG_CK;
47271d7fec4Smrg   WRITE_VID32(SC1400_DISPLAY_CONFIG, dcfg);
47371d7fec4Smrg   return (0);
47471d7fec4Smrg}
47571d7fec4Smrg
47671d7fec4Smrg/*---------------------------------------------------------------------------
47771d7fec4Smrg * gfx_set_video_filter
47871d7fec4Smrg *
47971d7fec4Smrg * This routine enables or disables the video overlay filters.
48071d7fec4Smrg *---------------------------------------------------------------------------
48171d7fec4Smrg */
48271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
48371d7fec4Smrgint
48471d7fec4Smrgsc1400_set_video_filter(int xfilter, int yfilter)
48571d7fec4Smrg#else
48671d7fec4Smrgint
48771d7fec4Smrggfx_set_video_filter(int xfilter, int yfilter)
48871d7fec4Smrg#endif
48971d7fec4Smrg{
49071d7fec4Smrg   unsigned long vcfg = 0;
49171d7fec4Smrg
49271d7fec4Smrg   /* ENABLE OR DISABLE SC1400 VIDEO OVERLAY FILTERS */
49371d7fec4Smrg
49471d7fec4Smrg   vcfg = READ_VID32(SC1400_VIDEO_CONFIG);
49571d7fec4Smrg   vcfg &= ~(SC1400_VCFG_X_FILTER_EN | SC1400_VCFG_Y_FILTER_EN);
49671d7fec4Smrg   if (xfilter)
49771d7fec4Smrg      vcfg |= SC1400_VCFG_X_FILTER_EN;
49871d7fec4Smrg   if (yfilter)
49971d7fec4Smrg      vcfg |= SC1400_VCFG_Y_FILTER_EN;
50071d7fec4Smrg   WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg);
50171d7fec4Smrg   return (0);
50271d7fec4Smrg}
50371d7fec4Smrg
50471d7fec4Smrg/*---------------------------------------------------------------------------
50571d7fec4Smrg * gfx_set_video_palette
50671d7fec4Smrg *
50771d7fec4Smrg * This routine loads the video hardware palette.  If a NULL pointer is
50871d7fec4Smrg * specified, the palette is bypassed (for SC1400, this means loading the
50971d7fec4Smrg * palette with identity values).
51071d7fec4Smrg *---------------------------------------------------------------------------
51171d7fec4Smrg */
51271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
51371d7fec4Smrgint
51471d7fec4Smrgsc1400_set_video_palette(unsigned long *palette)
51571d7fec4Smrg#else
51671d7fec4Smrgint
51771d7fec4Smrggfx_set_video_palette(unsigned long *palette)
51871d7fec4Smrg#endif
51971d7fec4Smrg{
52071d7fec4Smrg   unsigned long i, entry;
52171d7fec4Smrg
52271d7fec4Smrg   /* LOAD SC1400 VIDEO PALETTE */
52371d7fec4Smrg
52471d7fec4Smrg   WRITE_VID32(SC1400_PALETTE_ADDRESS, 0);
52571d7fec4Smrg   for (i = 0; i < 256; i++) {
52671d7fec4Smrg      if (palette)
52771d7fec4Smrg	 entry = palette[i];
52871d7fec4Smrg      else
52971d7fec4Smrg	 entry = i | (i << 8) | (i << 16);
53071d7fec4Smrg      WRITE_VID32(SC1400_PALETTE_DATA, entry);
53171d7fec4Smrg   }
53271d7fec4Smrg   return (0);
53371d7fec4Smrg}
53471d7fec4Smrg
53571d7fec4Smrg/*************************************************************/
53671d7fec4Smrg/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
53771d7fec4Smrg/*************************************************************/
53871d7fec4Smrg
53971d7fec4Smrg#if GFX_READ_ROUTINES
54071d7fec4Smrg
54171d7fec4Smrg/*---------------------------------------------------------------------------
54271d7fec4Smrg * gfx_get_sync_polarities
54371d7fec4Smrg *
54471d7fec4Smrg * This routine returns the polarities of the sync pulses:
54571d7fec4Smrg *     Bit 0: Set if negative horizontal polarity.
54671d7fec4Smrg *     Bit 1: Set if negative vertical polarity.
54771d7fec4Smrg *---------------------------------------------------------------------------
54871d7fec4Smrg */
54971d7fec4Smrg#if GFX_VIDEO_DYNAMIC
55071d7fec4Smrgint
55171d7fec4Smrgsc1400_get_sync_polarities(void)
55271d7fec4Smrg#else
55371d7fec4Smrgint
55471d7fec4Smrggfx_get_sync_polarities(void)
55571d7fec4Smrg#endif
55671d7fec4Smrg{
55771d7fec4Smrg   int polarities = 0;
55871d7fec4Smrg
55971d7fec4Smrg   if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000100)
56071d7fec4Smrg      polarities |= 1;
56171d7fec4Smrg   if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000200)
56271d7fec4Smrg      polarities |= 2;
56371d7fec4Smrg   return (polarities);
56471d7fec4Smrg}
56571d7fec4Smrg
56671d7fec4Smrg/*-----------------------------------------------------------------------------
56771d7fec4Smrg * gfx_get_video_enable
56871d7fec4Smrg *
56971d7fec4Smrg * This routine returns the value "one" if video overlay is currently enabled,
57071d7fec4Smrg * otherwise it returns the value "zero".
57171d7fec4Smrg *-----------------------------------------------------------------------------
57271d7fec4Smrg */
57371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
57471d7fec4Smrgint
57571d7fec4Smrgsc1400_get_video_enable(void)
57671d7fec4Smrg#else
57771d7fec4Smrgint
57871d7fec4Smrggfx_get_video_enable(void)
57971d7fec4Smrg#endif
58071d7fec4Smrg{
58171d7fec4Smrg   if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_VID_EN)
58271d7fec4Smrg      return (1);
58371d7fec4Smrg   return (0);
58471d7fec4Smrg}
58571d7fec4Smrg
58671d7fec4Smrg/*-----------------------------------------------------------------------------
58771d7fec4Smrg * gfx_get_video_format
58871d7fec4Smrg *
58971d7fec4Smrg * This routine returns the current video overlay format.
59071d7fec4Smrg *-----------------------------------------------------------------------------
59171d7fec4Smrg */
59271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
59371d7fec4Smrgint
59471d7fec4Smrgsc1400_get_video_format(void)
59571d7fec4Smrg#else
59671d7fec4Smrgint
59771d7fec4Smrggfx_get_video_format(void)
59871d7fec4Smrg#endif
59971d7fec4Smrg{
60071d7fec4Smrg   unsigned long vcfg;
60171d7fec4Smrg
60271d7fec4Smrg   vcfg = READ_VID32(SC1400_VIDEO_CONFIG);
60371d7fec4Smrg   if (vcfg & SC1400_VCFG_CSC_BYPASS)
60471d7fec4Smrg      return (4);
60571d7fec4Smrg   else
60671d7fec4Smrg      return ((vcfg >> 2) & 3);
60771d7fec4Smrg}
60871d7fec4Smrg
60971d7fec4Smrg/*-----------------------------------------------------------------------------
61071d7fec4Smrg * gfx_get_video_src_size
61171d7fec4Smrg *
61271d7fec4Smrg * This routine returns the size of the source video overlay buffer.  The
61371d7fec4Smrg * return value is (height << 16) | width.
61471d7fec4Smrg *-----------------------------------------------------------------------------
61571d7fec4Smrg */
61671d7fec4Smrg#if GFX_VIDEO_DYNAMIC
61771d7fec4Smrgunsigned long
61871d7fec4Smrgsc1400_get_video_src_size(void)
61971d7fec4Smrg#else
62071d7fec4Smrgunsigned long
62171d7fec4Smrggfx_get_video_src_size(void)
62271d7fec4Smrg#endif
62371d7fec4Smrg{
62471d7fec4Smrg   unsigned long width = 0, height = 0;
62571d7fec4Smrg
62671d7fec4Smrg   /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */
62771d7fec4Smrg
62871d7fec4Smrg   width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE;
62971d7fec4Smrg   if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER)
63071d7fec4Smrg      width += 512;
63171d7fec4Smrg
63271d7fec4Smrg   if (width) {
63371d7fec4Smrg      /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */
63471d7fec4Smrg      /* Get total size from display controller - abtracted. */
63571d7fec4Smrg
63671d7fec4Smrg      height = gfx_get_display_video_size() / (width << 1);
63771d7fec4Smrg   }
63871d7fec4Smrg   return ((height << 16) | width);
63971d7fec4Smrg}
64071d7fec4Smrg
64171d7fec4Smrg/*-----------------------------------------------------------------------------
64271d7fec4Smrg * gfx_get_video_line_size
64371d7fec4Smrg *
64471d7fec4Smrg * This routine returns the line size of the source video overlay buffer, in
64571d7fec4Smrg * pixels.
64671d7fec4Smrg *-----------------------------------------------------------------------------
64771d7fec4Smrg */
64871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
64971d7fec4Smrgunsigned long
65071d7fec4Smrgsc1400_get_video_line_size(void)
65171d7fec4Smrg#else
65271d7fec4Smrgunsigned long
65371d7fec4Smrggfx_get_video_line_size(void)
65471d7fec4Smrg#endif
65571d7fec4Smrg{
65671d7fec4Smrg   unsigned long width = 0;
65771d7fec4Smrg
65871d7fec4Smrg   /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */
65971d7fec4Smrg
66071d7fec4Smrg   width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE;
66171d7fec4Smrg   if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER)
66271d7fec4Smrg      width += 512;
66371d7fec4Smrg   return (width);
66471d7fec4Smrg}
66571d7fec4Smrg
66671d7fec4Smrg/*-----------------------------------------------------------------------------
66771d7fec4Smrg * gfx_get_video_xclip
66871d7fec4Smrg *
66971d7fec4Smrg * This routine returns the number of bytes clipped on the left side of a
67071d7fec4Smrg * video overlay line (skipped at beginning).
67171d7fec4Smrg *-----------------------------------------------------------------------------
67271d7fec4Smrg */
67371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
67471d7fec4Smrgunsigned long
67571d7fec4Smrgsc1400_get_video_xclip(void)
67671d7fec4Smrg#else
67771d7fec4Smrgunsigned long
67871d7fec4Smrggfx_get_video_xclip(void)
67971d7fec4Smrg#endif
68071d7fec4Smrg{
68171d7fec4Smrg   unsigned long clip = 0;
68271d7fec4Smrg
68371d7fec4Smrg   /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */
68471d7fec4Smrg
68571d7fec4Smrg   clip = (READ_VID32(SC1400_VIDEO_CONFIG) >> 14) & 0x000007FC;
68671d7fec4Smrg   return (clip);
68771d7fec4Smrg}
68871d7fec4Smrg
68971d7fec4Smrg/*-----------------------------------------------------------------------------
69071d7fec4Smrg * gfx_get_video_offset
69171d7fec4Smrg *
69271d7fec4Smrg * This routine returns the current offset for the video overlay buffer.
69371d7fec4Smrg *-----------------------------------------------------------------------------
69471d7fec4Smrg */
69571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
69671d7fec4Smrgunsigned long
69771d7fec4Smrgsc1400_get_video_offset(void)
69871d7fec4Smrg#else
69971d7fec4Smrgunsigned long
70071d7fec4Smrggfx_get_video_offset(void)
70171d7fec4Smrg#endif
70271d7fec4Smrg{
70371d7fec4Smrg   return (gfx_get_display_video_offset());
70471d7fec4Smrg}
70571d7fec4Smrg
70671d7fec4Smrg/*---------------------------------------------------------------------------
70771d7fec4Smrg * gfx_get_video_scale
70871d7fec4Smrg *
70971d7fec4Smrg * This routine returns the scale factor for the video overlay window.
71071d7fec4Smrg *---------------------------------------------------------------------------
71171d7fec4Smrg */
71271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
71371d7fec4Smrgunsigned long
71471d7fec4Smrgsc1400_get_video_scale(void)
71571d7fec4Smrg#else
71671d7fec4Smrgunsigned long
71771d7fec4Smrggfx_get_video_scale(void)
71871d7fec4Smrg#endif
71971d7fec4Smrg{
72071d7fec4Smrg   return (READ_VID32(SC1400_VIDEO_SCALE));
72171d7fec4Smrg}
72271d7fec4Smrg
72371d7fec4Smrg/*---------------------------------------------------------------------------
72471d7fec4Smrg * gfx_get_video_dst_size
72571d7fec4Smrg *
72671d7fec4Smrg * This routine returns the size of the displayed video overlay window.
72771d7fec4Smrg *---------------------------------------------------------------------------
72871d7fec4Smrg */
72971d7fec4Smrg#if GFX_VIDEO_DYNAMIC
73071d7fec4Smrgunsigned long
73171d7fec4Smrgsc1400_get_video_dst_size(void)
73271d7fec4Smrg#else
73371d7fec4Smrgunsigned long
73471d7fec4Smrggfx_get_video_dst_size(void)
73571d7fec4Smrg#endif
73671d7fec4Smrg{
73771d7fec4Smrg   unsigned long xsize, ysize;
73871d7fec4Smrg
73971d7fec4Smrg   xsize = READ_VID32(SC1400_VIDEO_X_POS);
74071d7fec4Smrg   xsize = ((xsize >> 16) & 0x3FF) - (xsize & 0x03FF);
74171d7fec4Smrg   ysize = READ_VID32(SC1400_VIDEO_Y_POS);
74271d7fec4Smrg   ysize = ((ysize >> 16) & 0x3FF) - (ysize & 0x03FF);
74371d7fec4Smrg   return ((ysize << 16) | xsize);
74471d7fec4Smrg}
74571d7fec4Smrg
74671d7fec4Smrg/*---------------------------------------------------------------------------
74771d7fec4Smrg * gfx_get_video_position
74871d7fec4Smrg *
74971d7fec4Smrg * This routine returns the position of the video overlay window.  The
75071d7fec4Smrg * return value is (ypos << 16) | xpos.
75171d7fec4Smrg *---------------------------------------------------------------------------
75271d7fec4Smrg */
75371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
75471d7fec4Smrgunsigned long
75571d7fec4Smrgsc1400_get_video_position(void)
75671d7fec4Smrg#else
75771d7fec4Smrgunsigned long
75871d7fec4Smrggfx_get_video_position(void)
75971d7fec4Smrg#endif
76071d7fec4Smrg{
76171d7fec4Smrg   unsigned long hadjust, vadjust;
76271d7fec4Smrg   unsigned long xpos, ypos;
76371d7fec4Smrg
76471d7fec4Smrg   /* READ HARDWARE POSITION */
76571d7fec4Smrg
76671d7fec4Smrg   xpos = READ_VID32(SC1400_VIDEO_X_POS) & 0x000003FF;
76771d7fec4Smrg   ypos = READ_VID32(SC1400_VIDEO_Y_POS) & 0x000003FF;
76871d7fec4Smrg
76971d7fec4Smrg   /* GET ADJUSTMENT VALUES */
77071d7fec4Smrg   /* Use routines to abstract version of display controller. */
77171d7fec4Smrg
77271d7fec4Smrg   hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13;
77371d7fec4Smrg   vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1;
77471d7fec4Smrg   xpos -= hadjust;
77571d7fec4Smrg   ypos -= vadjust;
77671d7fec4Smrg   return ((ypos << 16) | (xpos & 0x0000FFFF));
77771d7fec4Smrg}
77871d7fec4Smrg
77971d7fec4Smrg/*---------------------------------------------------------------------------
78071d7fec4Smrg * gfx_get_video_color_key
78171d7fec4Smrg *
78271d7fec4Smrg * This routine returns the current video color key value.
78371d7fec4Smrg *---------------------------------------------------------------------------
78471d7fec4Smrg */
78571d7fec4Smrg#if GFX_VIDEO_DYNAMIC
78671d7fec4Smrgunsigned long
78771d7fec4Smrgsc1400_get_video_color_key(void)
78871d7fec4Smrg#else
78971d7fec4Smrgunsigned long
79071d7fec4Smrggfx_get_video_color_key(void)
79171d7fec4Smrg#endif
79271d7fec4Smrg{
79371d7fec4Smrg   return (READ_VID32(SC1400_VIDEO_COLOR_KEY));
79471d7fec4Smrg}
79571d7fec4Smrg
79671d7fec4Smrg/*---------------------------------------------------------------------------
79771d7fec4Smrg * gfx_get_video_color_key_mask
79871d7fec4Smrg *
79971d7fec4Smrg * This routine returns the current video color mask value.
80071d7fec4Smrg *---------------------------------------------------------------------------
80171d7fec4Smrg */
80271d7fec4Smrg#if GFX_VIDEO_DYNAMIC
80371d7fec4Smrgunsigned long
80471d7fec4Smrgsc1400_get_video_color_key_mask(void)
80571d7fec4Smrg#else
80671d7fec4Smrgunsigned long
80771d7fec4Smrggfx_get_video_color_key_mask(void)
80871d7fec4Smrg#endif
80971d7fec4Smrg{
81071d7fec4Smrg   return (READ_VID32(SC1400_VIDEO_COLOR_MASK));
81171d7fec4Smrg}
81271d7fec4Smrg
81371d7fec4Smrg/*---------------------------------------------------------------------------
81471d7fec4Smrg * gfx_get_video_color_key_src
81571d7fec4Smrg *
81671d7fec4Smrg * This routine returns 0 for video data compare, 1 for graphics data.
81771d7fec4Smrg *---------------------------------------------------------------------------
81871d7fec4Smrg */
81971d7fec4Smrg#if GFX_VIDEO_DYNAMIC
82071d7fec4Smrgint
82171d7fec4Smrgsc1400_get_video_color_key_src(void)
82271d7fec4Smrg#else
82371d7fec4Smrgint
82471d7fec4Smrggfx_get_video_color_key_src(void)
82571d7fec4Smrg#endif
82671d7fec4Smrg{
82771d7fec4Smrg   if (READ_VID32(SC1400_DISPLAY_CONFIG) & SC1400_DCFG_VG_CK)
82871d7fec4Smrg      return (0);
82971d7fec4Smrg   return (1);
83071d7fec4Smrg}
83171d7fec4Smrg
83271d7fec4Smrg/*---------------------------------------------------------------------------
83371d7fec4Smrg * gfx_get_video_filter
83471d7fec4Smrg *
83571d7fec4Smrg * This routine returns if the filters are currently enabled.
83671d7fec4Smrg *---------------------------------------------------------------------------
83771d7fec4Smrg */
83871d7fec4Smrg#if GFX_VIDEO_DYNAMIC
83971d7fec4Smrgint
84071d7fec4Smrgsc1400_get_video_filter(void)
84171d7fec4Smrg#else
84271d7fec4Smrgint
84371d7fec4Smrggfx_get_video_filter(void)
84471d7fec4Smrg#endif
84571d7fec4Smrg{
84671d7fec4Smrg   int retval = 0;
84771d7fec4Smrg
84871d7fec4Smrg   if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_X_FILTER_EN)
84971d7fec4Smrg      retval |= 1;
85071d7fec4Smrg   if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_Y_FILTER_EN)
85171d7fec4Smrg      retval |= 2;
85271d7fec4Smrg   return (retval);
85371d7fec4Smrg}
85471d7fec4Smrg
85571d7fec4Smrg/*---------------------------------------------------------------------------
85671d7fec4Smrg * gfx_get_clock_frequency
85771d7fec4Smrg *
85871d7fec4Smrg * This routine returns the current clock frequency in 16.16 format.
85971d7fec4Smrg * It reads the current register value and finds the match in the table.
86071d7fec4Smrg * If no match is found, this routine returns 0.
86171d7fec4Smrg *---------------------------------------------------------------------------
86271d7fec4Smrg */
86371d7fec4Smrg#if GFX_VIDEO_DYNAMIC
86471d7fec4Smrgunsigned long
86571d7fec4Smrgsc1400_get_clock_frequency(void)
86671d7fec4Smrg#else
86771d7fec4Smrgunsigned long
86871d7fec4Smrggfx_get_clock_frequency(void)
86971d7fec4Smrg#endif
87071d7fec4Smrg{
87171d7fec4Smrg   int index;
87271d7fec4Smrg   unsigned long value, mask;
87371d7fec4Smrg
87471d7fec4Smrg   mask = 0x007FFF0F;
87571d7fec4Smrg   value = READ_VID32(SC1400_VID_CLOCK_SELECT) & mask;
87671d7fec4Smrg   for (index = 0; index < NUM_SC1400_FREQUENCIES; index++) {
87771d7fec4Smrg      if ((gfx_sc1400_clock_table[index].clock_select & mask) == value)
87871d7fec4Smrg	 return (gfx_sc1400_clock_table[index].frequency);
87971d7fec4Smrg   }
88071d7fec4Smrg   return (0);
88171d7fec4Smrg}
88271d7fec4Smrg
88371d7fec4Smrg/*---------------------------------------------------------------------------
88471d7fec4Smrg * gfx_read_crc
88571d7fec4Smrg *
88671d7fec4Smrg * This routine returns the hardware CRC value, which is used for automated
88771d7fec4Smrg * testing.  The value is like a checksum, but will change if pixels move
88871d7fec4Smrg * locations.
88971d7fec4Smrg *---------------------------------------------------------------------------
89071d7fec4Smrg */
89171d7fec4Smrg#if GFX_VIDEO_DYNAMIC
89271d7fec4Smrgunsigned long
89371d7fec4Smrgsc1400_read_crc(void)
89471d7fec4Smrg#else
89571d7fec4Smrgunsigned long
89671d7fec4Smrggfx_read_crc(void)
89771d7fec4Smrg#endif
89871d7fec4Smrg{
89971d7fec4Smrg   unsigned long crc = 0xFFFFFFFF;
90071d7fec4Smrg
90171d7fec4Smrg   if (gfx_test_timing_active()) {
90271d7fec4Smrg      // WAIT UNTIL ACTIVE DISPLAY
90371d7fec4Smrg
90471d7fec4Smrg      while (!gfx_test_vertical_active()) ;
90571d7fec4Smrg
90671d7fec4Smrg      // RESET CRC DURING ACTIVE DISPLAY
90771d7fec4Smrg
90871d7fec4Smrg      WRITE_VID32(SC1400_VID_CRC, 0);
90971d7fec4Smrg      WRITE_VID32(SC1400_VID_CRC, 1);
91071d7fec4Smrg
91171d7fec4Smrg      // WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE
91271d7fec4Smrg
91371d7fec4Smrg      while (gfx_test_vertical_active()) ;
91471d7fec4Smrg      while (!gfx_test_vertical_active()) ;
91571d7fec4Smrg      while (gfx_test_vertical_active()) ;
91671d7fec4Smrg      while (!gfx_test_vertical_active()) ;
91771d7fec4Smrg      crc = READ_VID32(SC1400_VID_CRC) >> 8;
91871d7fec4Smrg   }
91971d7fec4Smrg   return (crc);
92071d7fec4Smrg}
92171d7fec4Smrg
92271d7fec4Smrg#endif /* GFX_READ_ROUTINES */
92371d7fec4Smrg
92471d7fec4Smrg/* END OF FILE */
925