/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1400.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ /*----------------------------------------------------------------------------- * VID_1400.C * * Version 2.0 - February 21, 2000 * * This file contains routines to control the SC1400 video overlay hardware. * * History: * Versions 0.1 through 2.0 by Brian Falardeau. * * Copyright (c) 1999-2000 National Semiconductor. *----------------------------------------------------------------------------- */ /*---------------------------------------------------------------------------- * SC1400 PLL TABLE *---------------------------------------------------------------------------- */ typedef struct tagSC1400PLL { long frequency; /* 16.16 fixed point frequency */ unsigned long clock_select; /* clock select register (0x2C) */ } SC1400PLL; SC1400PLL gfx_sc1400_clock_table[] = { {0x00192CCC, 0x00000000}, /* 25.1750 */ {0x001C526E, 0x00010000}, /* 28.3220 */ {0x001F8000, 0x00020000}, /* 31.5000 */ {0x00240000, 0x000E0000}, /* 36.0000 */ {0x00258000, 0x0010110C}, /* 37.5000 */ {0x00280000, 0x00040000}, /* 40.0000 */ {0x002CE666, 0x00090000}, /* 44.9000 */ {0x00320000, 0x00100C06}, /* 50.0000 */ {0x00325999, 0x0050600C}, /* 50.3500 */ {0x00360000, 0x00100100}, /* 54.0000 */ {0x0038643F, 0x0010160A}, /* 56.3916 */ {0x0038A3D7, 0x00506C0C}, /* 56.6440 */ {0x003B0000, 0x0010170A}, /* 59.6583 */ {0x003BA886, 0x00100A04}, /* 59.6583 */ {0x003F0000, 0x00100602}, /* 63.0000 */ {0x00410000, 0x00060000}, /* 65.0000 */ {0x00438000, 0x00100401}, /* 67.5000 */ {0x0046CCCC, 0x00101407}, /* 70.8000 */ {0x00480000, 0x00100702}, /* 72.0000 */ {0x004B0000, 0x00070000}, /* 75.0000 */ {0x004EC000, 0x0010220B}, /* 78.7500 */ {0x00500000, 0x00304C0C}, /* 80.0000 */ {0x00510000, 0x00100200}, /* 81.0000 */ {0x00550000, 0x00080000}, /* 85.0000 */ {0x0059CCCC, 0x00100902}, /* 89.8000 */ {0x00630000, 0x00100A02}, /* 99.0000 */ {0x00640000, 0x00102409}, /* 100.0000 */ {0x006C0000, 0x00100300}, /* 108.0000 */ {0x00870000, 0x00050000}, /* 135.0000 */ {0x009D8000, 0x00102205}, /* 157.5000 */ {0x00A20000, 0x00100500}, /* 162.0000 */ {0x00AA0000, 0x000B0000}, /* 170.0000 */ {0x00AF0000, 0x00100C01}, /* 175.0000 */ {0x00BD0000, 0x00100600}, /* 189.0000 */ {0x00CA0000, 0x00100E01}, /* 202.0000 */ {0x00E80000, 0x00102A04}, /* 232.0000 */ }; #define NUM_SC1400_FREQUENCIES sizeof(gfx_sc1400_clock_table)/sizeof(SC1400PLL) /*--------------------------------------------------------------------------- * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) * * This routine is used to disable all components of video overlay before * performing a mode switch. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC void sc1400_reset_video(void) #else void gfx_reset_video(void) #endif { gfx_set_video_enable(0); } /*--------------------------------------------------------------------------- * gfx_set_clock_frequency * * This routine sets the clock frequency, specified as a 16.16 fixed point * value (0x00318000 = 49.5 MHz). It will set the closest frequency found * in the lookup table. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC void sc1400_set_clock_frequency(unsigned long frequency) #else void gfx_set_clock_frequency(unsigned long frequency) #endif { int index; unsigned long value; long min, diff; /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ /* Search the table for the closest frequency (16.16 format). */ value = gfx_sc1400_clock_table[0].clock_select; min = (long)gfx_sc1400_clock_table[0].frequency - frequency; if (min < 0L) min = -min; for (index = 1; index < NUM_SC1400_FREQUENCIES; index++) { diff = (long)gfx_sc1400_clock_table[index].frequency - frequency; if (diff < 0L) diff = -diff; if (diff < min) { min = diff; value = gfx_sc1400_clock_table[index].clock_select; } } /* SET THE DOT CLOCK REGISTER */ WRITE_VID32(SC1400_VID_MISC, 0x00001000); WRITE_VID32(SC1400_VID_CLOCK_SELECT, value); return; } /*----------------------------------------------------------------------------- * gfx_set_video_enable * * This routine enables or disables the video overlay functionality. *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_enable(int enable) #else int gfx_set_video_enable(int enable) #endif { unsigned long vcfg; /* WAIT FOR VERTICAL BLANK TO START */ /* Otherwise a glitch can be observed. */ if (gfx_test_timing_active()) { if (!gfx_test_vertical_active()) { while (!gfx_test_vertical_active()) ; } while (gfx_test_vertical_active()) ; } vcfg = READ_VID32(SC1400_VIDEO_CONFIG); if (enable) { /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ /* Use private routine to abstract the display controller. */ gfx_set_display_video_enable(1); /* SET SC1400 BUS CONTROL PARAMETERS */ /* Currently always high speed, 8-bit interface. */ vcfg |= SC1400_VCFG_HIGH_SPD_INT; vcfg &= ~(SC1400_VCFG_EARLY_VID_RDY | SC1400_VCFG_16_BIT_EN); /* ENABLE SC1400 VIDEO OVERLAY */ vcfg |= SC1400_VCFG_VID_EN; WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); } else { /* DISABLE SC1400 VIDEO OVERLAY */ vcfg &= ~SC1400_VCFG_VID_EN; WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ /* Use private routine to abstract the display controller. */ gfx_set_display_video_enable(0); } return (0); } /*----------------------------------------------------------------------------- * gfx_set_video_format * * Currently only sets 4:2:0 format, Y1 V Y0 U. *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_format(unsigned long format) #else int gfx_set_video_format(unsigned long format) #endif { unsigned long vcfg = 0; /* SET THE SC1400 VIDEO INPUT FORMAT */ vcfg = READ_VID32(SC1400_VIDEO_CONFIG); vcfg &= ~(SC1400_VCFG_VID_INP_FORMAT | SC1400_VCFG_4_2_0_MODE); vcfg &= ~(SC1400_VCFG_CSC_BYPASS); if (format < 4) vcfg |= (format << 2); else vcfg |= SC1400_VCFG_CSC_BYPASS; WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); return (0); } /*----------------------------------------------------------------------------- * gfx_set_video_size * * This routine specifies the size of the source data. It is used only * to determine how much data to transfer per frame, and is not used to * calculate the scaling value (that is handled by a separate routine). *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_size(unsigned short width, unsigned short height) #else int gfx_set_video_size(unsigned short width, unsigned short height) #endif { unsigned long size, vcfg; /* SET THE SC1400 VIDEO LINE SIZE */ vcfg = READ_VID32(SC1400_VIDEO_CONFIG); vcfg &= ~(SC1400_VCFG_LINE_SIZE_LOWER_MASK | SC1400_VCFG_LINE_SIZE_UPPER); size = (width >> 1); vcfg |= (size & 0x00FF) << 8; if (size & 0x0100) vcfg |= SC1400_VCFG_LINE_SIZE_UPPER; WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */ /* Use private routine to abstract the display controller. */ gfx_set_display_video_size(width, height); return (0); } /*----------------------------------------------------------------------------- * gfx_set_video_offset * * This routine sets the starting offset for the video buffer when only * one offset needs to be specified. *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_offset(unsigned long offset) #else int gfx_set_video_offset(unsigned long offset) #endif { /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ gfx_vid_offset = offset; /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ /* Use private routine to abstract the display controller. */ gfx_set_display_video_offset(offset); return (0); } /*--------------------------------------------------------------------------- * gfx_set_video_scale * * This routine sets the scale factor for the video overlay window. The * size of the source and destination regions are specified in pixels. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_scale(unsigned short srcw, unsigned short srch, unsigned short dstw, unsigned short dsth) #else int gfx_set_video_scale(unsigned short srcw, unsigned short srch, unsigned short dstw, unsigned short dsth) #endif { unsigned long xscale, yscale; /* SAVE PARAMETERS */ /* These are needed for clipping the video window later. */ gfx_vid_srcw = srcw; gfx_vid_srch = srch; gfx_vid_dstw = dstw; gfx_vid_dsth = dsth; /* CALCULATE SC1400 SCALE FACTORS */ /* No downscaling in SC1400 so force to 1x if attempted. */ if (srcw < dstw) xscale = (0x2000 * (srcw - 1)) / (dstw - 1); else xscale = 0x1FFF; if (srch < dsth) yscale = (0x2000 * (srch - 1)) / (dsth - 1); else yscale = 0x1FFF; WRITE_VID32(SC1400_VIDEO_SCALE, (yscale << 16) | xscale); /* CALL ROUTINE TO UPDATE WINDOW POSITION */ /* This is required because the scale values effect the number of */ /* source data pixels that need to be clipped, as well as the */ /* amount of data that needs to be transferred. */ gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, gfx_vid_height); return (0); } /*--------------------------------------------------------------------------- * gfx_set_video_window * * This routine sets the position and size of the video overlay window. The * position is specified in screen relative coordinates, and may be negative. * The size of destination region is specified in pixels. The line size * indicates the number of bytes of source data per scanline. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_window(short x, short y, unsigned short w, unsigned short h) #else int gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) #endif { unsigned long vcfg = 0; unsigned long hadjust, vadjust; unsigned long initread; unsigned long xstart, ystart, xend, yend; unsigned long offset, line_size; /* SAVE PARAMETERS */ /* These are needed to call this routine if the scale value changes. */ gfx_vid_xpos = x; gfx_vid_ypos = y; gfx_vid_width = w; gfx_vid_height = h; /* GET ADJUSTMENT VALUES */ /* Use routines to abstract version of display controller. */ hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13; vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1; if (x > 0) { /* NO CLIPPING ON LEFT */ xstart = x + hadjust; initread = 0; } else { /* CLIPPING ON LEFT */ /* Adjust initial read for scale, checking for divide by zero */ xstart = hadjust; initread = -x; if (gfx_vid_dstw) initread = ((-x) * gfx_vid_srcw) / gfx_vid_dstw; else initread = 0; } /* CLIPPING ON RIGHT */ xend = x + w; if (xend > gfx_get_hactive()) xend = gfx_get_hactive(); xend += hadjust; /* CLIPPING ON TOP */ offset = gfx_vid_offset; if (y >= 0) { ystart = y + vadjust; } else { ystart = vadjust; line_size = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) line_size += 512; if (gfx_vid_dsth) offset = gfx_vid_offset + (line_size << 1) * (((-y) * gfx_vid_srch) / gfx_vid_dsth); } /* CLIPPING ON BOTTOM */ yend = y + h; if (yend >= gfx_get_vactive()) yend = gfx_get_vactive(); yend += vadjust; /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ /* Use private routine to abstract the display controller. */ gfx_set_display_video_offset(offset); /* DISABLE REGISTER UPDATES */ vcfg = READ_VID32(SC1400_VIDEO_CONFIG); vcfg &= ~SC1400_VCFG_VID_REG_UPDATE; WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); /* SET VIDEO POSITION */ WRITE_VID32(SC1400_VIDEO_X_POS, (xend << 16) | xstart); WRITE_VID32(SC1400_VIDEO_Y_POS, (yend << 16) | ystart); /* SET INITIAL READ ADDRESS AND ENABLE REGISTER UPDATES */ vcfg &= ~SC1400_VCFG_INIT_READ_MASK; vcfg |= (initread << 15) & SC1400_VCFG_INIT_READ_MASK; vcfg |= SC1400_VCFG_VID_REG_UPDATE; WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); return (0); } /*--------------------------------------------------------------------------- * gfx_set_video_color_key * * This routine specifies the color key value and mask for the video overlay * hardware. To disable color key, the color and mask should both be set to * zero. The hardware uses the color key in the following equation: * * ((source data) & (color key mask)) == ((color key) & (color key mask)) * * The source data can be either graphics data or video data. The bluescreen * parameter is set to have the hardware compare video data and clear to * comapare graphics data. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_color_key(unsigned long key, unsigned long mask, int graphics) #else int gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) #endif { unsigned long dcfg = 0; /* SET SC1400 COLOR KEY VALUE */ WRITE_VID32(SC1400_VIDEO_COLOR_KEY, key); WRITE_VID32(SC1400_VIDEO_COLOR_MASK, mask); /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ dcfg = READ_VID32(SC1400_DISPLAY_CONFIG); if (graphics & 0x01) dcfg &= ~SC1400_DCFG_VG_CK; else dcfg |= SC1400_DCFG_VG_CK; WRITE_VID32(SC1400_DISPLAY_CONFIG, dcfg); return (0); } /*--------------------------------------------------------------------------- * gfx_set_video_filter * * This routine enables or disables the video overlay filters. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_filter(int xfilter, int yfilter) #else int gfx_set_video_filter(int xfilter, int yfilter) #endif { unsigned long vcfg = 0; /* ENABLE OR DISABLE SC1400 VIDEO OVERLAY FILTERS */ vcfg = READ_VID32(SC1400_VIDEO_CONFIG); vcfg &= ~(SC1400_VCFG_X_FILTER_EN | SC1400_VCFG_Y_FILTER_EN); if (xfilter) vcfg |= SC1400_VCFG_X_FILTER_EN; if (yfilter) vcfg |= SC1400_VCFG_Y_FILTER_EN; WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); return (0); } /*--------------------------------------------------------------------------- * gfx_set_video_palette * * This routine loads the video hardware palette. If a NULL pointer is * specified, the palette is bypassed (for SC1400, this means loading the * palette with identity values). *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_set_video_palette(unsigned long *palette) #else int gfx_set_video_palette(unsigned long *palette) #endif { unsigned long i, entry; /* LOAD SC1400 VIDEO PALETTE */ WRITE_VID32(SC1400_PALETTE_ADDRESS, 0); for (i = 0; i < 256; i++) { if (palette) entry = palette[i]; else entry = i | (i << 8) | (i << 16); WRITE_VID32(SC1400_PALETTE_DATA, entry); } return (0); } /*************************************************************/ /* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ /*************************************************************/ #if GFX_READ_ROUTINES /*--------------------------------------------------------------------------- * gfx_get_sync_polarities * * This routine returns the polarities of the sync pulses: * Bit 0: Set if negative horizontal polarity. * Bit 1: Set if negative vertical polarity. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_get_sync_polarities(void) #else int gfx_get_sync_polarities(void) #endif { int polarities = 0; if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000100) polarities |= 1; if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000200) polarities |= 2; return (polarities); } /*----------------------------------------------------------------------------- * gfx_get_video_enable * * This routine returns the value "one" if video overlay is currently enabled, * otherwise it returns the value "zero". *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_get_video_enable(void) #else int gfx_get_video_enable(void) #endif { if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_VID_EN) return (1); return (0); } /*----------------------------------------------------------------------------- * gfx_get_video_format * * This routine returns the current video overlay format. *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_get_video_format(void) #else int gfx_get_video_format(void) #endif { unsigned long vcfg; vcfg = READ_VID32(SC1400_VIDEO_CONFIG); if (vcfg & SC1400_VCFG_CSC_BYPASS) return (4); else return ((vcfg >> 2) & 3); } /*----------------------------------------------------------------------------- * gfx_get_video_src_size * * This routine returns the size of the source video overlay buffer. The * return value is (height << 16) | width. *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_src_size(void) #else unsigned long gfx_get_video_src_size(void) #endif { unsigned long width = 0, height = 0; /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) width += 512; if (width) { /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */ /* Get total size from display controller - abtracted. */ height = gfx_get_display_video_size() / (width << 1); } return ((height << 16) | width); } /*----------------------------------------------------------------------------- * gfx_get_video_line_size * * This routine returns the line size of the source video overlay buffer, in * pixels. *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_line_size(void) #else unsigned long gfx_get_video_line_size(void) #endif { unsigned long width = 0; /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) width += 512; return (width); } /*----------------------------------------------------------------------------- * gfx_get_video_xclip * * This routine returns the number of bytes clipped on the left side of a * video overlay line (skipped at beginning). *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_xclip(void) #else unsigned long gfx_get_video_xclip(void) #endif { unsigned long clip = 0; /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ clip = (READ_VID32(SC1400_VIDEO_CONFIG) >> 14) & 0x000007FC; return (clip); } /*----------------------------------------------------------------------------- * gfx_get_video_offset * * This routine returns the current offset for the video overlay buffer. *----------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_offset(void) #else unsigned long gfx_get_video_offset(void) #endif { return (gfx_get_display_video_offset()); } /*--------------------------------------------------------------------------- * gfx_get_video_scale * * This routine returns the scale factor for the video overlay window. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_scale(void) #else unsigned long gfx_get_video_scale(void) #endif { return (READ_VID32(SC1400_VIDEO_SCALE)); } /*--------------------------------------------------------------------------- * gfx_get_video_dst_size * * This routine returns the size of the displayed video overlay window. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_dst_size(void) #else unsigned long gfx_get_video_dst_size(void) #endif { unsigned long xsize, ysize; xsize = READ_VID32(SC1400_VIDEO_X_POS); xsize = ((xsize >> 16) & 0x3FF) - (xsize & 0x03FF); ysize = READ_VID32(SC1400_VIDEO_Y_POS); ysize = ((ysize >> 16) & 0x3FF) - (ysize & 0x03FF); return ((ysize << 16) | xsize); } /*--------------------------------------------------------------------------- * gfx_get_video_position * * This routine returns the position of the video overlay window. The * return value is (ypos << 16) | xpos. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_position(void) #else unsigned long gfx_get_video_position(void) #endif { unsigned long hadjust, vadjust; unsigned long xpos, ypos; /* READ HARDWARE POSITION */ xpos = READ_VID32(SC1400_VIDEO_X_POS) & 0x000003FF; ypos = READ_VID32(SC1400_VIDEO_Y_POS) & 0x000003FF; /* GET ADJUSTMENT VALUES */ /* Use routines to abstract version of display controller. */ hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13; vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1; xpos -= hadjust; ypos -= vadjust; return ((ypos << 16) | (xpos & 0x0000FFFF)); } /*--------------------------------------------------------------------------- * gfx_get_video_color_key * * This routine returns the current video color key value. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_color_key(void) #else unsigned long gfx_get_video_color_key(void) #endif { return (READ_VID32(SC1400_VIDEO_COLOR_KEY)); } /*--------------------------------------------------------------------------- * gfx_get_video_color_key_mask * * This routine returns the current video color mask value. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_video_color_key_mask(void) #else unsigned long gfx_get_video_color_key_mask(void) #endif { return (READ_VID32(SC1400_VIDEO_COLOR_MASK)); } /*--------------------------------------------------------------------------- * gfx_get_video_color_key_src * * This routine returns 0 for video data compare, 1 for graphics data. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_get_video_color_key_src(void) #else int gfx_get_video_color_key_src(void) #endif { if (READ_VID32(SC1400_DISPLAY_CONFIG) & SC1400_DCFG_VG_CK) return (0); return (1); } /*--------------------------------------------------------------------------- * gfx_get_video_filter * * This routine returns if the filters are currently enabled. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC int sc1400_get_video_filter(void) #else int gfx_get_video_filter(void) #endif { int retval = 0; if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_X_FILTER_EN) retval |= 1; if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_Y_FILTER_EN) retval |= 2; return (retval); } /*--------------------------------------------------------------------------- * gfx_get_clock_frequency * * This routine returns the current clock frequency in 16.16 format. * It reads the current register value and finds the match in the table. * If no match is found, this routine returns 0. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_get_clock_frequency(void) #else unsigned long gfx_get_clock_frequency(void) #endif { int index; unsigned long value, mask; mask = 0x007FFF0F; value = READ_VID32(SC1400_VID_CLOCK_SELECT) & mask; for (index = 0; index < NUM_SC1400_FREQUENCIES; index++) { if ((gfx_sc1400_clock_table[index].clock_select & mask) == value) return (gfx_sc1400_clock_table[index].frequency); } return (0); } /*--------------------------------------------------------------------------- * gfx_read_crc * * This routine returns the hardware CRC value, which is used for automated * testing. The value is like a checksum, but will change if pixels move * locations. *--------------------------------------------------------------------------- */ #if GFX_VIDEO_DYNAMIC unsigned long sc1400_read_crc(void) #else unsigned long gfx_read_crc(void) #endif { unsigned long crc = 0xFFFFFFFF; if (gfx_test_timing_active()) { // WAIT UNTIL ACTIVE DISPLAY while (!gfx_test_vertical_active()) ; // RESET CRC DURING ACTIVE DISPLAY WRITE_VID32(SC1400_VID_CRC, 0); WRITE_VID32(SC1400_VID_CRC, 1); // WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE while (gfx_test_vertical_active()) ; while (!gfx_test_vertical_active()) ; while (gfx_test_vertical_active()) ; while (!gfx_test_vertical_active()) ; crc = READ_VID32(SC1400_VID_CRC) >> 8; } return (crc); } #endif /* GFX_READ_ROUTINES */ /* END OF FILE */