summaryrefslogtreecommitdiff
path: root/src/gfx
diff options
context:
space:
mode:
authorJordan Crouse <jordan.crouse@amd.com>2006-07-06 14:56:42 -0600
committerJordan Crouse <jordan.crouse@amd.com>2006-07-06 14:56:42 -0600
commitc3ab9f1a60afe1f5e86db1cf2635acda14fae2f5 (patch)
tree00cfb19765f276220eb794553b545e9f67402688 /src/gfx
Initial commit of the xf86-video-amd tree
Diffstat (limited to 'src/gfx')
-rw-r--r--src/gfx/disp_gu1.c2532
-rw-r--r--src/gfx/disp_gu2.c2788
-rw-r--r--src/gfx/disp_gu3.c2603
-rw-r--r--src/gfx/durango.c488
-rw-r--r--src/gfx/gfx_dcdr.c499
-rw-r--r--src/gfx/gfx_defs.h348
-rw-r--r--src/gfx/gfx_disp.c2925
-rw-r--r--src/gfx/gfx_i2c.c168
-rw-r--r--src/gfx/gfx_init.c731
-rw-r--r--src/gfx/gfx_mode.h194
-rw-r--r--src/gfx/gfx_msr.c152
-rw-r--r--src/gfx/gfx_priv.h981
-rw-r--r--src/gfx/gfx_regs.h1654
-rw-r--r--src/gfx/gfx_rndr.c671
-rw-r--r--src/gfx/gfx_rtns.h604
-rw-r--r--src/gfx/gfx_tv.c836
-rw-r--r--src/gfx/gfx_type.h331
-rw-r--r--src/gfx/gfx_vga.c45
-rw-r--r--src/gfx/gfx_vid.c2319
-rw-r--r--src/gfx/gfx_vip.c531
-rw-r--r--src/gfx/history.h33
-rw-r--r--src/gfx/i2c_acc.c876
-rw-r--r--src/gfx/i2c_gpio.c639
-rw-r--r--src/gfx/init_gu1.c265
-rw-r--r--src/gfx/init_gu2.c154
-rw-r--r--src/gfx/init_gu3.c159
-rw-r--r--src/gfx/msr_rdcl.c632
-rw-r--r--src/gfx/release.txt630
-rw-r--r--src/gfx/rndr_gu1.c1584
-rw-r--r--src/gfx/rndr_gu2.c2180
-rw-r--r--src/gfx/saa7114.c916
-rw-r--r--src/gfx/tv_1200.c967
-rw-r--r--src/gfx/tv_fs450.c3261
-rw-r--r--src/gfx/tv_fs450.h206
-rw-r--r--src/gfx/vga_gu1.c680
-rw-r--r--src/gfx/vid_1200.c2849
-rw-r--r--src/gfx/vid_5530.c1354
-rw-r--r--src/gfx/vid_cstl.c2571
-rw-r--r--src/gfx/vid_rdcl.c2887
-rw-r--r--src/gfx/vip_1200.c663
40 files changed, 44906 insertions, 0 deletions
diff --git a/src/gfx/disp_gu1.c b/src/gfx/disp_gu1.c
new file mode 100644
index 0000000..58e42ee
--- /dev/null
+++ b/src/gfx/disp_gu1.c
@@ -0,0 +1,2532 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ */
+
+void gu1_enable_compression(void); /* private routine definition */
+void gu1_disable_compression(void); /* private routine definition */
+void gfx_reset_video(void); /* private routine definition */
+int gfx_set_display_control(int sync_polarities); /* private routine
+ * definition */
+int gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp);
+
+/* VIDEO BUFFER SIZE */
+
+unsigned long vid_buf_size = 0;
+int vid_enabled = 0;
+
+/*----------------------------------------------------------------------------
+ * GU1_DELAY_APPROXIMATE (PRIVATE ROUTINE - NOT PART OF DURANGO API)
+ *
+ * Delay the requested number of milliseconds by reading a register. This
+ * function generally takes longer than the requested time.
+ *----------------------------------------------------------------------------
+ */
+
+#define READS_PER_MILLISECOND 60000L
+
+void
+gu1_delay_approximate(unsigned long milliseconds)
+{
+ /* ASSUME 300 MHz, 5 CLOCKS PER READ */
+
+ unsigned long loop;
+
+ loop = milliseconds * READS_PER_MILLISECOND;
+ while (loop-- > 0) {
+ READ_REG32(DC_UNLOCK);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * GU1_DELAY_PRECISE (PRIVATE ROUTINE - NOT PART OF DURANGO API)
+ *
+ * Delay the number of milliseconds on a more precise level, varying only by
+ * 1/10 of a ms. This function should only be called if an SC1200 is present.
+ *----------------------------------------------------------------------------
+ */
+void
+gu1_delay_precise(unsigned long milliseconds)
+{
+#if GFX_VIDEO_SC1200
+
+#define LOOP 1000
+ unsigned long i, timer_start, timer_end, total_ticks, previous_ticks,
+ temp_ticks;
+
+ /* Get current time */
+ timer_start = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE);
+
+ /* Calculate expected end time */
+ if (INB(SC1200_CB_BASE_ADDR + SC1200_CB_TMCNFG) & SC1200_TMCLKSEL_27MHZ)
+ total_ticks = 27000 * milliseconds; /* timer resolution is 27 MHz */
+ else
+ total_ticks = 1000 * milliseconds; /* timer resolution is 1 MHz */
+
+ if (total_ticks > ((unsigned long)0xffffffff - timer_start))
+ /* wrap-around */
+ timer_end = total_ticks - ((unsigned long)0xffffffff - timer_start);
+ else
+ timer_end = timer_start + total_ticks;
+
+ /* in case of wrap around */
+ if (timer_end < timer_start) {
+ previous_ticks = timer_start;
+ while (1) {
+ temp_ticks = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE);
+ if (temp_ticks < previous_ticks)
+ break;
+ else
+ previous_ticks = temp_ticks;
+ for (i = 0; i < LOOP; i++)
+ READ_REG32(DC_UNLOCK);
+ }
+ }
+
+ /* now the non-wrap around part */
+ while (1) {
+ for (i = 0; i < LOOP; i++)
+ READ_REG32(DC_UNLOCK);
+ if (IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE) > timer_end)
+ break;
+ }
+#endif /* GFX_VIDEO_SC1200 */
+}
+
+/*----------------------------------------------------------------------------
+ * WARNING!!!! INACCURATE DELAY MECHANISM
+ *
+ * In an effort to keep the code self contained and operating system
+ * independent, the delay loop just performs reads of a display controller
+ * register. This time will vary for faster processors. The delay can always
+ * be longer than intended, only effecting the time of the mode switch
+ * (obviously want it to still be under a second). Problems with the hardware
+ * only arise if the delay is not long enough.
+ *
+ * For the SC1200, the high resolution timer can be used as an accurate
+ * mechanism for keeping time. However, in order to avoid a busy loop of IO
+ * reads, the timer is polled in-between busy loops, and therefore the actual
+ * delay might be longer than the requested delay by the time of one busy loop
+ * (which on a 200 MHz system took 95 us)
+ *
+ * There are thus two delay functions which are called from the main API
+ * routine.
+ * One is meant to be more precise and should only called if an SC1200 is
+ * present.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_delay_milliseconds(unsigned long milliseconds)
+#else
+void
+gfx_delay_milliseconds(unsigned long milliseconds)
+#endif
+{
+#if GFX_VIDEO_SC1200
+#if GFX_VIDEO_DYNAMIC
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) {
+#endif
+ gu1_delay_precise(milliseconds);
+ return;
+#if GFX_VIDEO_DYNAMIC
+ }
+#endif
+#endif /* GFX_VIDEO_SC1200 */
+ gu1_delay_approximate(milliseconds);
+}
+
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_delay_microseconds(unsigned long microseconds)
+#else
+void
+gfx_delay_microseconds(unsigned long microseconds)
+#endif
+{
+ /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */
+ unsigned long loop_count = microseconds * 150;
+
+ while (loop_count-- > 0) {
+ ;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_VIDEO_SHUTDOWN
+ *
+ * This routine disables the display controller output.
+ *----------------------------------------------------------------------------
+ */
+void
+gu1_video_shutdown(void)
+{
+ unsigned long unlock;
+ unsigned long gcfg, tcfg;
+
+ /* DISABLE COMPRESSION */
+ gu1_disable_compression();
+
+ /* ALSO DISABLE VIDEO */
+ /* Use private "reset video" routine to do all that is needed. */
+ /* SC1200, for example, also disables the alpha blending regions. */
+ gfx_reset_video();
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+ unlock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+
+ /* READ THE CURRENT GX VALUES */
+ gcfg = READ_REG32(DC_GENERAL_CFG);
+ tcfg = READ_REG32(DC_TIMING_CFG);
+
+ /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */
+ tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN);
+ WRITE_REG32(DC_TIMING_CFG, tcfg);
+
+ /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */
+ /* This delay is used to make sure that all pending requests to the */
+ /* memory controller have completed before disabling the FIFO load. */
+ gfx_delay_milliseconds(1);
+
+ /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */
+ gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC_UNLOCK, unlock);
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_BPP
+ *
+ * This routine programs the bpp in the display controller.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_display_bpp(unsigned short bpp)
+#else
+int
+gfx_set_display_bpp(unsigned short bpp)
+#endif
+{
+ unsigned long ocfg, lock;
+
+ lock = READ_REG32(DC_UNLOCK);
+ ocfg = READ_REG32(DC_OUTPUT_CFG) & ~(DC_OCFG_8BPP | DC_OCFG_555);
+
+ /* SET DC PIXEL FORMAT */
+ if (bpp == 8)
+ ocfg |= DC_OCFG_8BPP;
+ else if (bpp == 15)
+ ocfg |= DC_OCFG_555;
+ else if (bpp != 16)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_OUTPUT_CFG, ocfg);
+ WRITE_REG32(DC_UNLOCK, lock);
+
+ /* SET BPP IN GRAPHICS PIPELINE */
+ gfx_set_bpp(bpp);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_SPECIFIED_MODE
+ * This routine uses the parameters in the specified display mode structure
+ * to program the display controller hardware.
+ *----------------------------------------------------------------------------
+ */
+int
+gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp)
+{
+ unsigned long unlock, value;
+ unsigned long gcfg, tcfg, ocfg;
+ unsigned long size, pitch;
+ unsigned long hactive, vactive;
+
+ gbpp = bpp;
+
+ /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
+ /* Flag used for locking also overrides timing change restriction */
+ if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
+ return GFX_STATUS_ERROR;
+
+ /* SET GLOBAL FLAG */
+ if (pMode->flags & GFX_MODE_LOCK_TIMING)
+ gfx_timing_lock = 1;
+
+ /* DISABLE COMPRESSION */
+ gu1_disable_compression();
+
+ /* ALSO DISABLE VIDEO */
+ /* Use private "reset video" routine to do all that is needed. */
+ /* SC1200, for example, also disables the alpha blending regions. */
+ gfx_reset_video();
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+ unlock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+
+ /* READ THE CURRENT GX VALUES */
+ gcfg = READ_REG32(DC_GENERAL_CFG);
+ tcfg = READ_REG32(DC_TIMING_CFG);
+
+ /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */
+ tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN);
+ WRITE_REG32(DC_TIMING_CFG, tcfg);
+
+ /* DELAY: WAIT FOR PENDING MEMORY REQUESTS
+ * This delay is used to make sure that all pending requests to the
+ * memory controller have completed before disabling the FIFO load.
+ */
+ gfx_delay_milliseconds(1);
+
+ /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */
+ gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+
+ /* CLEAR THE "DCLK_MUL" FIELD */
+ gcfg &= ~(unsigned long)(DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK);
+ gcfg &= ~(unsigned long)DC_GCFG_DCLK_MASK;
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+
+ /* SET THE DOT CLOCK FREQUENCY */
+ /* Mask off the divide by two bit (bit 31) */
+ gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
+
+ /* DELAY: WAIT FOR THE PLL TO SETTLE */
+ /* This allows the dot clock frequency that was just set to settle. */
+ gfx_delay_milliseconds(1);
+
+ /* SET THE "DCLK_MUL" FIELD OF DC_GENERAL_CFG */
+ /* The GX hardware divides the dot clock, so 2x really means that the */
+ /* internal dot clock equals the external dot clock. */
+ if (pMode->frequency & 0x80000000)
+ gcfg |= 0x0040;
+ else
+ gcfg |= 0x0080;
+
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+
+ /* DELAY: WAIT FOR THE ADL TO LOCK */
+ /* This allows the clock generatation within GX to settle. This is */
+ /* needed since some of the register writes that follow require that */
+ /* clock to be present. */
+ gfx_delay_milliseconds(1);
+
+ /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
+ WRITE_REG32(DC_FB_ST_OFFSET, 0);
+ WRITE_REG32(DC_CB_ST_OFFSET, 0);
+ WRITE_REG32(DC_CURS_ST_OFFSET, 0);
+
+ /* SET LINE SIZE AND PITCH */
+ /* Flat panels use the current flat panel line size to */
+ /* calculate the pitch, but load the true line size */
+ /* for the mode into the "Frame Buffer Line Size" field */
+ /* of DC_BUF_SIZE. */
+ if (PanelEnable)
+ size = ModeWidth;
+ else
+ size = pMode->hactive;
+
+ if (bpp > 8)
+ size <<= 1;
+
+ /* ONLY PYRAMID SUPPORTS 4K LINE SIZE */
+ if (size <= 1024) {
+ pitch = 1024;
+ /* SPECIAL CASE */
+ /* Graphics acceleration in 16-bit pixel line double modes */
+ /* requires a pitch of 2048. */
+ if ((pMode->flags & GFX_MODE_LINE_DOUBLE) && bpp > 8)
+ pitch <<= 1;
+ } else {
+ if (gfx_cpu_version == GFX_CPU_PYRAMID)
+ pitch = (size <= 2048) ? 2048 : 4096;
+ else
+ pitch = 2048;
+ }
+
+ WRITE_REG32(DC_LINE_DELTA, pitch >> 2);
+
+ if (PanelEnable) {
+ size = pMode->hactive;
+ if (bpp > 8)
+ size <<= 1;
+ }
+
+ /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */
+ WRITE_REG32(DC_BUF_SIZE, (size >> 3) + 2);
+
+ /* ALWAYS ENABLE "PANEL" DATA FROM MEDIAGX */
+ /* That is really just the 18 BPP data bus to the companion chip */
+ ocfg = DC_OCFG_PCKE | DC_OCFG_PDEL | DC_OCFG_PDEH;
+
+ /* SET PIXEL FORMAT */
+ if (bpp == 8)
+ ocfg |= DC_OCFG_8BPP;
+ else if (bpp == 15)
+ ocfg |= DC_OCFG_555;
+
+ /* ENABLE TIMING GENERATOR, SYNCS, AND FP DATA */
+ tcfg = DC_TCFG_FPPE | DC_TCFG_HSYE | DC_TCFG_VSYE | DC_TCFG_BLKE |
+ DC_TCFG_TGEN;
+
+ /* SET FIFO PRIORITY, DCLK MULTIPLIER, AND FIFO ENABLE */
+ /* Default 6/5 for FIFO, 2x for DCLK multiplier. */
+ gcfg =
+ (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | DC_GCFG_DFLE;
+
+ /* INCREASE FIFO PRIORITY FOR LARGE MODES */
+ if (pMode->hactive == 1280 && pMode->vactive == 1024) {
+ if ((bpp == 8) && (pMode->flags & GFX_MODE_85HZ))
+ gcfg =
+ (8l << DC_GCFG_DFHPEL_POS) | (7l << DC_GCFG_DFHPSL_POS) |
+ DC_GCFG_DFLE;
+
+ if ((bpp > 8) && (pMode->flags & GFX_MODE_75HZ))
+ gcfg =
+ (7l << DC_GCFG_DFHPEL_POS) | (6l << DC_GCFG_DFHPSL_POS) |
+ DC_GCFG_DFLE;
+
+ if ((bpp > 8) && (pMode->flags & GFX_MODE_85HZ))
+ gcfg =
+ (9l << DC_GCFG_DFHPEL_POS) | (8l << DC_GCFG_DFHPSL_POS) |
+ DC_GCFG_DFLE;
+ }
+
+ /* SET DOT CLOCK MULTIPLIER */
+ /* Bit 31 of frequency indicates divide frequency by two */
+ if (pMode->frequency & 0x80000000)
+ gcfg |= (1l << DC_GCFG_DCLK_POS);
+ else
+ gcfg |= (2l << DC_GCFG_DCLK_POS);
+
+ /* DIVIDE VIDEO CLOCK */
+ /* CPU core frequencies above 266 MHz will divide the video */
+ /* clock by 4 to ensure that we are running below 150 MHz. */
+ if (gfx_cpu_frequency > 266)
+ gcfg |= DC_GCFG_VCLK_DIV;
+
+ /* ALWAYS ENABLE VIDEO IN THE DISPLAY CONTROLLER */
+ /* Enabling video at an inopportune momemt can corrupt the DC fetch */
+ /* engine and cause screen artifacts or system hang. */
+ gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY);
+
+ /* SET THE PIXEL AND LINE DOUBLE BITS IF NECESSARY */
+ hactive = pMode->hactive;
+ vactive = pMode->vactive;
+ gfx_line_double = 0;
+ gfx_pixel_double = 0;
+
+ if (pMode->flags & GFX_MODE_LINE_DOUBLE) {
+ gcfg |= DC_GCFG_LDBL;
+ hactive <<= 1;
+
+ /* SET GLOBAL FLAG */
+ gfx_line_double = 1;
+ }
+
+ if (pMode->flags & GFX_MODE_PIXEL_DOUBLE) {
+ tcfg |= DC_TCFG_PXDB;
+ vactive <<= 1;
+
+ /* SET GLOBAL FLAG */
+ gfx_pixel_double = 1;
+ }
+
+ /* COMBINE AND SET TIMING VALUES */
+
+ value = (unsigned long)(hactive - 1) |
+ (((unsigned long)(pMode->htotal - 1)) << 16);
+ WRITE_REG32(DC_H_TIMING_1, value);
+ value = (unsigned long)(pMode->hblankstart - 1) |
+ (((unsigned long)(pMode->hblankend - 1)) << 16);
+ WRITE_REG32(DC_H_TIMING_2, value);
+ value = (unsigned long)(pMode->hsyncstart - 1) |
+ (((unsigned long)(pMode->hsyncend - 1)) << 16);
+ WRITE_REG32(DC_H_TIMING_3, value);
+ WRITE_REG32(DC_FP_H_TIMING, value);
+ value = (unsigned long)(vactive - 1) |
+ (((unsigned long)(pMode->vtotal - 1)) << 16);
+ WRITE_REG32(DC_V_TIMING_1, value);
+ value = (unsigned long)(pMode->vblankstart - 1) |
+ (((unsigned long)(pMode->vblankend - 1)) << 16);
+ WRITE_REG32(DC_V_TIMING_2, value);
+ value = (unsigned long)(pMode->vsyncstart - 1) |
+ (((unsigned long)(pMode->vsyncend - 1)) << 16);
+ WRITE_REG32(DC_V_TIMING_3, value);
+ value = (unsigned long)(pMode->vsyncstart - 2) |
+ (((unsigned long)(pMode->vsyncend - 2)) << 16);
+ WRITE_REG32(DC_FP_V_TIMING, value);
+
+ WRITE_REG32(DC_OUTPUT_CFG, ocfg);
+ WRITE_REG32(DC_TIMING_CFG, tcfg);
+ gfx_delay_milliseconds(1); /* delay after TIMING_CFG */
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+
+ /* ENABLE FLAT PANEL CENTERING */
+ /* For 640x480 modes displayed with the 9211 within a 800x600 */
+ /* flat panel display, turn on flat panel centering. */
+ if (PanelEnable) {
+ if (ModeWidth < PanelWidth) {
+ tcfg = READ_REG32(DC_TIMING_CFG);
+ tcfg = tcfg | DC_TCFG_FCEN;
+ WRITE_REG32(DC_TIMING_CFG, tcfg);
+ gfx_delay_milliseconds(1); /* delay after TIMING_CFG */
+ }
+ }
+
+ /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+ gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
+ ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
+
+ /* RESTORE VALUE OF DC_UNLOCK */
+ WRITE_REG32(DC_UNLOCK, unlock);
+
+ /* ALSO WRITE GP_BLIT_STATUS FOR PITCH AND 8/18 BPP */
+ /* Remember, only Pyramid supports 4K line pitch */
+ value = 0;
+ if (bpp > 8)
+ value |= BC_16BPP;
+ if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048))
+ value |= BC_FB_WIDTH_4096;
+ else if (pitch > 1024)
+ value |= BC_FB_WIDTH_2048;
+
+ WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value);
+
+ return GFX_STATUS_OK;
+} /* end gfx_set_specified_mode() */
+
+/*----------------------------------------------------------------------------
+ * GFX_IS_DISPLAY_MODE_SUPPORTED
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns the index of the mode if successful and mode returned, -1 if the
+ * mode could not be found.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#else
+int
+gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#endif
+{
+ unsigned int mode = 0;
+ unsigned long hz_flag = 0, bpp_flag = 0;
+
+ /* SET FLAGS TO MATCH REFRESH RATE */
+ if (hz == 56)
+ hz_flag = GFX_MODE_56HZ;
+ else if (hz == 60)
+ hz_flag = GFX_MODE_60HZ;
+ else if (hz == 70)
+ hz_flag = GFX_MODE_70HZ;
+ else if (hz == 72)
+ hz_flag = GFX_MODE_72HZ;
+ else if (hz == 75)
+ hz_flag = GFX_MODE_75HZ;
+ else if (hz == 85)
+ hz_flag = GFX_MODE_85HZ;
+ else
+ return -1;
+
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+ if (bpp == 8)
+ bpp_flag = GFX_MODE_8BPP;
+ else if (bpp == 15)
+ bpp_flag = GFX_MODE_15BPP;
+ else if (bpp == 16)
+ bpp_flag = GFX_MODE_16BPP;
+ else
+ return -1;
+
+ /* ONLY PYRAMID SUPPORTS 4K PITCH */
+ if (gfx_cpu_version != GFX_CPU_PYRAMID && xres > 1024) {
+ if (bpp > 8)
+ return (-1); /* return with mode not found */
+ }
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) {
+ if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
+ (DisplayParams[mode].vactive == (unsigned short)yres) &&
+ (DisplayParams[mode].flags & hz_flag) &&
+ (DisplayParams[mode].flags & bpp_flag)) {
+
+ /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
+ return (mode);
+ }
+ }
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_MODE
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_display_mode(int xres, int yres, int bpp, int hz)
+#else
+int
+gfx_set_display_mode(int xres, int yres, int bpp, int hz)
+#endif
+{
+ int mode;
+
+ /* DISABLE FLAT PANEL */
+ /* Flat Panel settings are enabled by the function gfx_set_fixed_timings
+ * and disabled by gfx_set_display_mode. */
+ PanelEnable = 0;
+
+ mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
+ if (mode >= 0) {
+ if (gu1_set_specified_mode(&DisplayParams[mode],
+ bpp) == GFX_STATUS_OK)
+ return (1);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_TIMINGS
+ *
+ * This routine sets the display controller mode using the specified timing
+ * values (as opposed to using the tables internal to Durango).
+ *
+ * Returns GFX_STATUS_OK on success, GFX_STATUS_ERROR otherwise.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
+#else
+int
+gfx_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
+#endif
+{
+ /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
+
+ gfx_display_mode.flags = 0;
+ if (flags & 1)
+ gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
+ if (flags & 2)
+ gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
+ if (flags & 0x1000)
+ gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
+ gfx_display_mode.hactive = hactive;
+ gfx_display_mode.hblankstart = hblankstart;
+ gfx_display_mode.hsyncstart = hsyncstart;
+ gfx_display_mode.hsyncend = hsyncend;
+ gfx_display_mode.hblankend = hblankend;
+ gfx_display_mode.htotal = htotal;
+ gfx_display_mode.vactive = vactive;
+ gfx_display_mode.vblankstart = vblankstart;
+ gfx_display_mode.vsyncstart = vsyncstart;
+ gfx_display_mode.vsyncend = vsyncend;
+ gfx_display_mode.vblankend = vblankend;
+ gfx_display_mode.vtotal = vtotal;
+ gfx_display_mode.frequency = frequency;
+
+ /* CALL ROUTINE TO SET MODE */
+ return (gu1_set_specified_mode(&gfx_display_mode, bpp));
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_VTOTAL
+ *
+ * This routine sets the display controller vertical total to
+ * "vtotal". As a side effect it also sets vertical blank end.
+ * It should be used when only this value needs to be changed,
+ * due to speed considerations.
+ *
+ * Note: it is the caller's responsibility to make sure that
+ * a legal vtotal is used, i.e. that "vtotal" is greater than or
+ * equal to vsync end.
+ *
+ * Always returns 0.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_vtotal(unsigned short vtotal)
+#else
+int
+gfx_set_vtotal(unsigned short vtotal)
+#endif
+{
+ unsigned long unlock, tcfg, timing1, timing2;
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+ unlock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+
+ /* READ THE CURRENT GX VALUES */
+ tcfg = READ_REG32(DC_TIMING_CFG);
+ timing1 = READ_REG32(DC_V_TIMING_1);
+ timing2 = READ_REG32(DC_V_TIMING_2);
+
+ /* DISABLE THE TIMING GENERATOR */
+ WRITE_REG32(DC_TIMING_CFG, tcfg & ~(unsigned long)DC_TCFG_TGEN);
+
+ /* WRITE NEW TIMING VALUES */
+ WRITE_REG32(DC_V_TIMING_1,
+ (timing1 & 0xffff) | (unsigned long)(vtotal - 1) << 16);
+ WRITE_REG32(DC_V_TIMING_2,
+ (timing2 & 0xffff) | (unsigned long)(vtotal - 1) << 16);
+
+ /* RESTORE GX VALUES */
+ WRITE_REG32(DC_TIMING_CFG, tcfg);
+ WRITE_REG32(DC_UNLOCK, unlock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_pitch
+ *
+ * This routine sets the pitch of the frame buffer to the specified value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_display_pitch(unsigned short pitch)
+#else
+void
+gfx_set_display_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long value = 0;
+ unsigned long lock = READ_REG32(DC_UNLOCK);
+
+ value = READ_REG32(DC_LINE_DELTA) & 0xFFFFF000;
+ value |= (pitch >> 2);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_LINE_DELTA, value);
+ WRITE_REG32(DC_UNLOCK, lock);
+
+ /* ALSO UPDATE PITCH IN GRAPHICS ENGINE */
+ /* Pyramid alone supports 4K line pitch */
+ value = (unsigned long)READ_REG16(GP_BLIT_STATUS);
+ value &= ~(BC_FB_WIDTH_2048 | BC_FB_WIDTH_4096);
+
+ if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048))
+ value |= BC_FB_WIDTH_4096;
+
+ else if (pitch > 1024)
+ value |= BC_FB_WIDTH_2048;
+
+ WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value);
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_offset
+ *
+ * This routine sets the start address of the frame buffer. It is
+ * typically used to pan across a virtual desktop (frame buffer larger than
+ * the displayed screen) or to flip the display between multiple buffers.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_display_offset(unsigned long offset)
+#else
+void
+gfx_set_display_offset(unsigned long offset)
+#endif
+{
+ /* UPDATE FRAME BUFFER OFFSET */
+
+ unsigned long lock;
+
+ lock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+
+ /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
+ /* Disable compression for non-zero start addresss values. */
+ /* Enable compression if offset is zero and comression is intended to */
+ /* be enabled from a previous call to "gfx_set_compression_enable". */
+ /* Compression should be disabled BEFORE the offset is changed */
+ /* and enabled AFTER the offset is changed. */
+ if (offset == 0) {
+ WRITE_REG32(DC_FB_ST_OFFSET, offset);
+ if (gfx_compression_enabled) {
+ /* WAIT FOR THE OFFSET TO BE LATCHED */
+ gfx_wait_vertical_blank();
+ gu1_enable_compression();
+ }
+ } else {
+ /* ONLY DISABLE COMPRESSION ONCE */
+ if (gfx_compression_active)
+ gu1_disable_compression();
+
+ WRITE_REG32(DC_FB_ST_OFFSET, offset);
+ }
+
+ WRITE_REG32(DC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette_entry
+ *
+ * This routine sets an palette entry in the display controller.
+ * A 32-bit X:R:G:B value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_display_palette_entry(unsigned long index, unsigned long palette)
+#else
+int
+gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ unsigned long data;
+
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(DC_PAL_ADDRESS, index);
+ data = ((palette >> 2) & 0x0003F) |
+ ((palette >> 4) & 0x00FC0) | ((palette >> 6) & 0x3F000);
+ WRITE_REG32(DC_PAL_DATA, data);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette
+ *
+ * This routine sets the entire palette in the display controller.
+ * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
+ *
+ * Restriction:
+ * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
+ * when DCLK is active, i.e PLL is already powered up and genlock is not
+ * active.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_display_palette(unsigned long *palette)
+#else
+int
+gfx_set_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long data, i;
+
+ WRITE_REG32(DC_PAL_ADDRESS, 0);
+ if (palette) {
+ for (i = 0; i < 256; i++) {
+ /* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */
+ data = ((palette[i] >> 2) & 0x0003F) |
+ ((palette[i] >> 4) & 0x00FC0) | ((palette[i] >> 6) & 0x3F000);
+ WRITE_REG32(DC_PAL_DATA, data);
+ }
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_enable
+ *
+ * This routine enables or disables the hardware cursor.
+ *
+ * WARNING: The cusrsor start offset must be set by setting the cursor
+ * position before calling this routine to assure that memory reads do not
+ * go past the end of graphics memory (this can hang GXm).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_cursor_enable(int enable)
+#else
+void
+gfx_set_cursor_enable(int enable)
+#endif
+{
+ unsigned long unlock, gcfg;
+
+ /* SET OR CLEAR CURSOR ENABLE BIT */
+ unlock = READ_REG32(DC_UNLOCK);
+ gcfg = READ_REG32(DC_GENERAL_CFG);
+ if (enable)
+ gcfg |= DC_GCFG_CURE;
+ else
+ gcfg &= ~(DC_GCFG_CURE);
+
+ /* WRITE NEW REGISTER VALUE */
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_colors
+ *
+ * This routine sets the colors of the hardware cursor.
+ *
+ * Restriction:
+ * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
+ * when DCLK is active, i.e PLL is already powered up.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#else
+void
+gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#endif
+{
+ unsigned long value;
+
+ /* If genlock is enabled DCLK might be disabled in vertical blank. */
+ /* Due to SC1200 Issue #748 in Notes DB this would fail the cursor color settings */
+ /* So Wait for vertical blank to end */
+
+#if GFX_VIDEO_SC1200
+ if (gfx_test_timing_active())
+ while ((gfx_get_vline()) > gfx_get_vactive()) ;
+#endif
+ /* SET CURSOR COLORS */
+ WRITE_REG32(DC_PAL_ADDRESS, 0x100);
+ value = ((bkcolor & 0x000000FC) >> 2) |
+ ((bkcolor & 0x0000FC00) >> (2 + 8 - 6)) |
+ ((bkcolor & 0x00FC0000) >> (2 + 16 - 12));
+ WRITE_REG32(DC_PAL_DATA, value);
+ value = ((fgcolor & 0x000000FC) >> 2) |
+ ((fgcolor & 0x0000FC00) >> (2 + 8 - 6)) |
+ ((fgcolor & 0x00FC0000) >> (2 + 16 - 12));
+ WRITE_REG32(DC_PAL_DATA, value);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_position
+ *
+ * This routine sets the position of the hardware cusror. The starting
+ * offset of the cursor buffer must be specified so that the routine can
+ * properly clip scanlines if the cursor is off the top of the screen.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#else
+void
+gfx_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#endif
+{
+ unsigned long unlock;
+
+ short x, y;
+ short xoffset = 0;
+ short yoffset = 0;
+
+ /* SUPPORT CURSOR IN EMULATED VGA MODES */
+ /* Timings are for twice the resolution */
+ if (gfx_pixel_double)
+ xpos <<= 1;
+
+ if (gfx_line_double)
+ ypos <<= 1;
+
+ x = (short)xpos - (short)xhotspot;
+ y = (short)ypos - (short)yhotspot;
+ if (x < -31)
+ return;
+
+ if (y < -31)
+ return;
+
+ if (x < 0) {
+ xoffset = -x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ yoffset = -y;
+ y = 0;
+ }
+
+ memoffset += (unsigned long)yoffset << 3;
+
+ if (PanelEnable) {
+ if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
+ gfx_enable_panning(xpos, ypos);
+ x = x - (short)panelLeft;
+ y = y - (short)panelTop;
+ }
+ }
+
+ /* SET CURSOR POSITION */
+ unlock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_CURS_ST_OFFSET, memoffset);
+ WRITE_REG32(DC_CURSOR_X, (unsigned long)x |
+ (((unsigned long)xoffset) << 11));
+ WRITE_REG32(DC_CURSOR_Y, (unsigned long)y |
+ (((unsigned long)yoffset) << 11));
+ WRITE_REG32(DC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape32
+ *
+ * This routine loads 32x32 cursor data into the specified location in
+ * graphics memory.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#else
+void
+gfx_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+ int i;
+ unsigned long value;
+
+ for (i = 0; i < 32; i++) {
+ /* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */
+ value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16);
+ WRITE_FB32(memoffset, value);
+ memoffset += 4;
+ value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF);
+ WRITE_FB32(memoffset, value);
+ memoffset += 4;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gu1_enable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It enables display compression.
+ *---------------------------------------------------------------------------
+ */
+void
+gu1_enable_compression(void)
+{
+ int i;
+ unsigned long unlock, gcfg, offset;
+
+ /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
+ offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF;
+ if (offset != 0)
+ return;
+
+ /* DO NOT ENABLE IF WE ARE WITHIN AN EMULATED VGA MODE */
+ if (gfx_line_double || gfx_pixel_double)
+ return;
+
+ /* SET GLOBAL INDICATOR */
+ gfx_compression_active = 1;
+
+ /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
+ /* Software is required to do this before enabling compression. */
+ /* Don't want controller to think that old lines are still valid. */
+ for (i = 0; i < 1024; i++) {
+ WRITE_REG32(MC_DR_ADD, i);
+ WRITE_REG32(MC_DR_ACC, 0);
+ }
+
+ /* TURN ON COMPRESSION CONTROL BITS */
+ unlock = READ_REG32(DC_UNLOCK);
+ gcfg = READ_REG32(DC_GENERAL_CFG);
+ gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE;
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gu1_disable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It disables display compression.
+ *---------------------------------------------------------------------------
+ */
+void
+gu1_disable_compression(void)
+{
+ unsigned long unlock, gcfg;
+
+ /* SET GLOBAL INDICATOR */
+ gfx_compression_active = 0;
+
+ /* TURN OFF COMPRESSION CONTROL BITS */
+ unlock = READ_REG32(DC_UNLOCK);
+ gcfg = READ_REG32(DC_GENERAL_CFG);
+ gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_enable
+ *
+ * This routine enables or disables display compression.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_compression_enable(int enable)
+#else
+int
+gfx_set_compression_enable(int enable)
+#endif
+{
+ /* SET GLOBAL VARIABLE FOR INTENDED STATE */
+ /* Compression can only be enabled for non-zero start address values. */
+ /* Keep state to enable compression on start address changes. */
+ gfx_compression_enabled = enable;
+ if (enable)
+ gu1_enable_compression();
+ else
+ gu1_disable_compression();
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_offset
+ *
+ * This routine sets the base offset for the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_compression_offset(unsigned long offset)
+#else
+int
+gfx_set_compression_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ /* MUST BE 16-BYTE ALIGNED FOR GXLV */
+ if (offset & 0x0F)
+ return (1);
+
+ /* SET REGISTER VALUE */
+ lock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_CB_ST_OFFSET, offset);
+ WRITE_REG32(DC_UNLOCK, lock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_pitch
+ *
+ * This routine sets the pitch, in bytes, of the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_compression_pitch(unsigned short pitch)
+#else
+int
+gfx_set_compression_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long lock, line_delta;
+
+ /* SET REGISTER VALUE */
+ lock = READ_REG32(DC_UNLOCK);
+ line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF;
+ line_delta |= ((unsigned long)pitch << 10l) & 0x007FF000;
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_LINE_DELTA, line_delta);
+ WRITE_REG32(DC_UNLOCK, lock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_size
+ *
+ * This routine sets the line size of the compression buffer, which is the
+ * maximum number of bytes allowed to store a compressed line.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_compression_size(unsigned short size)
+#else
+int
+gfx_set_compression_size(unsigned short size)
+#endif
+{
+ unsigned long lock, buf_size;
+
+ /* SUBTRACT 16 FROM SIZE */
+ /* The display controller will actually write */
+ /* 2 extra QWords. So, if we assume that "size" */
+ /* refers to the allocated size, we must subtract */
+ /* 16 bytes. */
+ size -= 16;
+
+ /* SET REGISTER VALUE */
+ lock = READ_REG32(DC_UNLOCK);
+ buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF;
+ buf_size |= (((size >> 2) + 1) & 0x7F) << 9;
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ WRITE_REG32(DC_BUF_SIZE, buf_size);
+ WRITE_REG32(DC_UNLOCK, lock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine enables/disables video on GX.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_display_video_enable(int enable)
+#else
+void
+gfx_set_display_video_enable(int enable)
+#endif
+{
+ unsigned long lock, gcfg, buf_size;
+
+ lock = READ_REG32(DC_UNLOCK);
+ gcfg = READ_REG32(DC_GENERAL_CFG);
+ buf_size = READ_REG32(DC_BUF_SIZE);
+
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+
+ vid_enabled = enable;
+
+ /* SET THE BUFFER SIZE TO A NON-ZERO VALUE ONLY WHEN */
+ /* ENABLING VIDEO */
+ if (enable) {
+ gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY);
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+
+ WRITE_REG32(DC_BUF_SIZE, (buf_size & 0x0000FFFFl) | vid_buf_size);
+ }
+ /* CLEAR THE VIDEO BUFFER SIZE WHEN DISABLING VIDEO */
+ else {
+ gcfg &= ~(DC_GCFG_VIDE);
+ WRITE_REG32(DC_GENERAL_CFG, gcfg);
+
+ vid_buf_size = buf_size & 0xFFFF0000l;
+ WRITE_REG32(DC_BUF_SIZE, buf_size & 0x0000FFFFl);
+ }
+
+ WRITE_REG32(DC_UNLOCK, lock);
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_display_video_size(unsigned short width, unsigned short height)
+#else
+void
+gfx_set_display_video_size(unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long lock, size, value;
+
+ size = (unsigned long)(width << 1) * (unsigned long)height;
+
+ /* STORE THE VIDEO BUFFER SIZE AS A GLOBAL */
+ vid_buf_size = ((size + 63) >> 6) << 16;
+
+ lock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF;
+ value |= vid_buf_size;
+ WRITE_REG32(DC_BUF_SIZE, value);
+ WRITE_REG32(DC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_display_video_offset(unsigned long offset)
+#else
+void
+gfx_set_display_video_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ lock = READ_REG32(DC_UNLOCK);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ offset &= 0x003FFFFF;
+ WRITE_REG32(DC_VID_ST_OFFSET, offset);
+ WRITE_REG32(DC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_priority_high
+ *
+ * This routine controls the x-bus round robin arbitration mechanism.
+ * When enable is TRUE, graphics pipeline requests and non-critical display
+ * controller requests are arbitrated at the same priority as processor
+ * requests. When FALSE processor requests are arbitrated at a higher priority
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_set_display_priority_high(int enable)
+#else
+void
+gfx_set_display_priority_high(int enable)
+#endif
+{
+ unsigned long lock, control;
+
+ lock = READ_REG32(DC_UNLOCK);
+ control = READ_REG32(MC_MEM_CNTRL1);
+ WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
+ if (enable)
+ control |= MC_XBUSARB;
+ else
+ control &= ~(MC_XBUSARB);
+ WRITE_REG32(MC_MEM_CNTRL1, control);
+ WRITE_REG32(DC_UNLOCK, lock);
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_timing_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_test_timing_active(void)
+#else
+int
+gfx_test_timing_active(void)
+#endif
+{
+ if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN)
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_vertical_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_test_vertical_active(void)
+#else
+int
+gfx_test_vertical_active(void)
+#endif
+{
+ if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_VNA)
+ return (0);
+ else
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_wait_vertical_blank
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_wait_vertical_blank(void)
+#else
+int
+gfx_wait_vertical_blank(void)
+#endif
+{
+ if (gfx_test_timing_active()) {
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ }
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_panning
+ *
+ * This routine enables the panning when the Mode is bigger than the panel
+ * size.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_enable_panning(int x, int y)
+#else
+void
+gfx_enable_panning(int x, int y)
+#endif
+{
+ unsigned long modeBytesPerPixel;
+ unsigned long modeBytesPerScanline = 0;
+ unsigned long startAddress = 0;
+
+ modeBytesPerPixel = (gbpp + 7) / 8;
+ modeBytesPerScanline =
+ (((ModeWidth + 1023) / 1024) * 1024) * modeBytesPerPixel;
+
+ /* TEST FOR NO-WORK */
+ if (x >= DeltaX && (unsigned short)x < (PanelWidth + DeltaX) &&
+ y >= DeltaY && (unsigned short)y < (PanelHeight + DeltaY))
+ return;
+
+ /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */
+ /* Test the boundary conditions for each coordinate and update */
+ /* all variables and the starting offset accordingly. */
+ if (x < DeltaX)
+ DeltaX = x;
+ else if ((unsigned short)x >= (DeltaX + PanelWidth))
+ DeltaX = x - PanelWidth + 1;
+
+ if (y < DeltaY)
+ DeltaY = y;
+ else if ((unsigned short)y >= (DeltaY + PanelHeight))
+ DeltaY = y - PanelHeight + 1;
+
+ /* CALCULATE THE START OFFSET */
+ startAddress =
+ (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
+
+ gfx_set_display_offset(startAddress);
+
+ /* SET PANEL COORDINATES */
+ /* Panel's x position must be DWORD aligned */
+ panelTop = DeltaY;
+ panelLeft = DeltaX * modeBytesPerPixel;
+
+ if (panelLeft & 3)
+ panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
+
+ panelLeft /= modeBytesPerPixel;
+
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_fixed_timings
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#else
+int
+gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#endif
+{
+ unsigned int mode;
+
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
+ if ((FixedParams[mode].xres == width) &&
+ (FixedParams[mode].yres == height) &&
+ (FixedParams[mode].panelresx == panelResX) &&
+ (FixedParams[mode].panelresy == panelResY)) {
+
+ /* SET THE 92xx FOR THE SELECTED MODE */
+ FIXEDTIMINGS *fmode = &FixedParams[mode];
+
+ gfx_set_display_timings(bpp, 3, fmode->hactive,
+ fmode->hblankstart, fmode->hsyncstart, fmode->hsyncend,
+ fmode->hblankend, fmode->htotal, fmode->vactive,
+ fmode->vblankstart, fmode->vsyncstart, fmode->vsyncend,
+ fmode->vblankend, fmode->vtotal, fmode->frequency);
+
+ return (1);
+ } /* end if() */
+ } /* end for() */
+
+ return (-1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_panel_present
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#else
+int
+gfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#endif
+{
+ /* SET VALID BPP */
+ /* 16BPP is the default. */
+ if (bpp != 8 && bpp != 15 && bpp != 16)
+ bpp = 16;
+
+ /* RECORD PANEL PARAMETERS */
+ /* This routine does not touch any panel timings. It is used when custom
+ * panel settings are set up in advance by the BIOS or an application, but
+ * the application still requires access to other panel functionality
+ * provided by Durango (i.e. panning)
+ * */
+
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+ gbpp = bpp;
+
+ /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
+ gfx_set_display_bpp(bpp);
+
+ return (GFX_STATUS_OK);
+}
+
+/*-----------------------------------------------------------------------*
+ * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: *
+ * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal *
+ * are used by the video overlay routines. *
+ * *
+ * gfx_get_vline and gfx_vactive are used to prevent an issue for the *
+ * SC1200. *
+ * *
+ * The others are part of the Durango API. *
+ *-----------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_pitch
+ *
+ * This routine returns the current pitch of the frame buffer, in bytes.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_display_pitch(void)
+#else
+unsigned short
+gfx_get_display_pitch(void)
+#endif
+{
+ unsigned long value;
+
+ if (gfx_cpu_version == GFX_CPU_PYRAMID) {
+ /* Pyramid update for 4KB line pitch */
+ value = (READ_REG32(DC_LINE_DELTA) & 0x07FF) << 2;
+ } else {
+ value = (READ_REG32(DC_LINE_DELTA) & 0x03FF) << 2;
+ }
+
+ return ((unsigned short)value);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_DETAILS
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be get.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#else
+int
+gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#endif
+{
+ if (mode < NUM_GX_DISPLAY_MODES) {
+ if (DisplayParams[mode].flags & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
+ *hz = 85;
+
+ *xres = DisplayParams[mode].hactive;
+ *yres = DisplayParams[mode].vactive;
+
+ return (1);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_MODE_COUNT
+ *
+ * Returns number of modes supported.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_display_mode_count(void)
+#else
+int
+gfx_get_display_mode_count(void)
+#endif
+{
+ return (NUM_GX_DISPLAY_MODES);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_line_size
+ *
+ * Returns the current frame buffer line size, in bytes
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_frame_buffer_line_size(void)
+#else
+unsigned long
+gfx_get_frame_buffer_line_size(void)
+#endif
+{
+ return ((READ_REG32(DC_BUF_SIZE) & 0x1FF) << 3);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_mode_frequency_supported
+ *
+ * This routine examines if the requested mode with pixel frequency is supported.
+ *
+ * Returns >0 if successful , <0 if freq. could not be found and matched.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency)
+#else
+int
+gfx_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+
+ bpp_flag = GFX_MODE_8BPP;
+ if (bpp > 8)
+ bpp_flag = GFX_MODE_16BPP;
+
+ for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned short)xres) &&
+ (DisplayParams[index].vactive == (unsigned short)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].frequency == frequency)) {
+ int hz = 0;
+
+ value = DisplayParams[index].flags;
+
+ if (value & GFX_MODE_56HZ)
+ hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ hz = 85;
+
+ return (hz);
+ }
+ }
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_frequency
+ *
+ * This routine maps the frequency to close match refresh rate
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#else
+int
+gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch = 0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ bpp_flag = GFX_MODE_8BPP;
+ if (bpp > 8)
+ bpp_flag = GFX_MODE_16BPP;
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].htotal == (unsigned short)xres) &&
+ (DisplayParams[index].vtotal == (unsigned short)yres) &&
+ (DisplayParams[index].flags & bpp_flag)) {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < min) {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ *hz = 85;
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_mode
+ *
+ * This routine is identical to the gfx_get_refreshrate_from_frequency,
+ * except that the active timing values are compared instead of the total
+ * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#else
+int
+gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch = 0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ bpp_flag = GFX_MODE_8BPP;
+ if (bpp > 8)
+ bpp_flag = GFX_MODE_16BPP;
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned short)xres) &&
+ (DisplayParams[index].vactive == (unsigned short)yres) &&
+ (DisplayParams[index].flags & bpp_flag)) {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < min) {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ *hz = 85;
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frequency_from_refreshrate
+ *
+ * This routine maps the refresh rate to the closest matching PLL frequency.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency)
+#else
+int
+gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency)
+#endif
+{
+ unsigned int index;
+ int retval = -1;
+ unsigned long hz_flag = 0;
+ unsigned long bpp_flag = 0;
+
+ *frequency = 0;
+
+ if (hz == 56)
+ hz_flag = GFX_MODE_56HZ;
+ else if (hz == 60)
+ hz_flag = GFX_MODE_60HZ;
+ else if (hz == 70)
+ hz_flag = GFX_MODE_70HZ;
+ else if (hz == 72)
+ hz_flag = GFX_MODE_72HZ;
+ else if (hz == 75)
+ hz_flag = GFX_MODE_75HZ;
+ else if (hz == 85)
+ hz_flag = GFX_MODE_85HZ;
+
+ bpp_flag = GFX_MODE_8BPP;
+ if (bpp > 8)
+ bpp_flag = GFX_MODE_16BPP;
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+
+ for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned short)xres) &&
+ (DisplayParams[index].vactive == (unsigned short)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].flags & hz_flag)) {
+ *frequency = DisplayParams[index].frequency;
+ retval = 1;
+ }
+ }
+ return retval;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_supported_pixel_clock
+ *
+ * This routine returns the maximum recommended speed for the pixel clock. The
+ * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum
+ * floating point pixel clock speed.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_max_supported_pixel_clock(void)
+#else
+unsigned long
+gfx_get_max_supported_pixel_clock(void)
+#endif
+{
+ /* ALL CHIPS CAN HANDLE 1280X1024@85HZ - 157.5 MHz */
+ return 157500;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_mode
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns: >0 if successful and mode returned, <0 if mode could not be found.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#else
+int
+gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#endif
+{
+ unsigned int mode = 0;
+ unsigned long pll_freq = 0, bpp_flag = 0;
+
+ *xres = gfx_get_hactive();
+ *yres = gfx_get_vactive();
+ *bpp = gfx_get_display_bpp();
+ pll_freq = gfx_get_clock_frequency();
+
+ /* SUPPORT EMULATED VGA MODES */
+ if (gfx_pixel_double)
+ *xres >>= 1;
+
+ if (gfx_line_double)
+ *yres >>= 1;
+
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+ bpp_flag = GFX_MODE_8BPP;
+ if (*bpp > 8)
+ bpp_flag = GFX_MODE_16BPP;
+
+ for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) {
+ if ((DisplayParams[mode].hactive == (unsigned short)*xres) &&
+ (DisplayParams[mode].vactive == (unsigned short)*yres) &&
+ (DisplayParams[mode].frequency == pll_freq) &&
+ (DisplayParams[mode].flags & bpp_flag)) {
+
+ pll_freq = DisplayParams[mode].flags;
+
+ if (pll_freq & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (pll_freq & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (pll_freq & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (pll_freq & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (pll_freq & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (pll_freq & GFX_MODE_85HZ)
+ *hz = 85;
+
+ return (1);
+ }
+ }
+ return (-1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_hactive(void)
+#else
+unsigned short
+gfx_get_hactive(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC_H_TIMING_1) & 0x07F8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_hsync_start(void)
+#else
+unsigned short
+gfx_get_hsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC_H_TIMING_3) & 0x07F8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_hsync_end(void)
+#else
+unsigned short
+gfx_get_hsync_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC_H_TIMING_3) >> 16) & 0x07F8) +
+ 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_htotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_htotal(void)
+#else
+unsigned short
+gfx_get_htotal(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC_H_TIMING_1) >> 16) & 0x07F8) +
+ 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_vactive(void)
+#else
+unsigned short
+gfx_get_vactive(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC_V_TIMING_1) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_vsync_end(void)
+#else
+unsigned short
+gfx_get_vsync_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC_V_TIMING_3) >> 16) & 0x07FF) +
+ 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vtotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_vtotal(void)
+#else
+unsigned short
+gfx_get_vtotal(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC_V_TIMING_1) >> 16) & 0x07FF) +
+ 1));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_bpp
+ *
+ * This routine returns the current color depth of the active display.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_display_bpp(void)
+#else
+unsigned short
+gfx_get_display_bpp(void)
+#endif
+{
+ switch (READ_REG32(DC_OUTPUT_CFG) & 3) {
+ case 0:
+ return (16);
+ case 2:
+ return (15);
+ }
+ return (8);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vline
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_vline(void)
+#else
+unsigned short
+gfx_get_vline(void)
+#endif
+{
+ unsigned short current_scan_line;
+
+ /* Read similar value twice to ensure that the value is not transitioning */
+ do {
+ current_scan_line =
+ (unsigned short)READ_REG32(DC_V_LINE_CNT) & 0x07FF;
+ } while (current_scan_line !=
+ (unsigned short)(READ_REG32(DC_V_LINE_CNT) & 0x07FF));
+
+ return (current_scan_line);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_display_offset(void)
+#else
+unsigned long
+gfx_get_display_offset(void)
+#endif
+{
+ return (READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_cursor_offset(void)
+#else
+unsigned long
+gfx_get_cursor_offset(void)
+#endif
+{
+ return (READ_REG32(DC_CURS_ST_OFFSET) & 0x003FFFFF);
+}
+
+#if GFX_READ_ROUTINES
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_hblank_start(void)
+#else
+unsigned short
+gfx_get_hblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC_H_TIMING_2) & 0x07F8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_hblank_end(void)
+#else
+unsigned short
+gfx_get_hblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC_H_TIMING_2) >> 16) & 0x07F8) +
+ 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_vblank_start(void)
+#else
+unsigned short
+gfx_get_vblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC_V_TIMING_2) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_vsync_start(void)
+#else
+unsigned short
+gfx_get_vsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC_V_TIMING_3) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_vblank_end(void)
+#else
+unsigned short
+gfx_get_vblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC_V_TIMING_2) >> 16) & 0x07FF) +
+ 1));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_palette_entry
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int
+gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ unsigned long data;
+
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(DC_PAL_ADDRESS, index);
+ data = READ_REG32(DC_PAL_DATA);
+ data = ((data << 2) & 0x000000FC) |
+ ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
+
+ *palette = data;
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_palette
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu1_get_display_palette(unsigned long *palette)
+#else
+void
+gfx_get_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i, data;
+
+ WRITE_REG32(DC_PAL_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ data = READ_REG32(DC_PAL_DATA);
+ data = ((data << 2) & 0x000000FC) |
+ ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
+ palette[i] = data;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_enable
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_cursor_enable(void)
+#else
+unsigned long
+gfx_get_cursor_enable(void)
+#endif
+{
+ return (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_CURE);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_position
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_cursor_position(void)
+#else
+unsigned long
+gfx_get_cursor_position(void)
+#endif
+{
+ return ((READ_REG32(DC_CURSOR_X) & 0x07FF) |
+ ((READ_REG32(DC_CURSOR_Y) << 16) & 0x03FF0000));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_clip
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_cursor_clip(void)
+#else
+unsigned long
+gfx_get_cursor_clip(void)
+#endif
+{
+ return (((READ_REG32(DC_CURSOR_X) >> 11) & 0x01F) |
+ ((READ_REG32(DC_CURSOR_Y) << 5) & 0x1F0000));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_color
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_cursor_color(int color)
+#else
+unsigned long
+gfx_get_cursor_color(int color)
+#endif
+{
+ unsigned long data;
+
+ if (color) {
+ WRITE_REG32(DC_PAL_ADDRESS, 0x101);
+ } else {
+ WRITE_REG32(DC_PAL_ADDRESS, 0x100);
+ }
+ data = READ_REG32(DC_PAL_DATA);
+ data = ((data << 6) & 0x00FC0000) |
+ ((data << 4) & 0x0000FC00) | ((data << 2) & 0x000000FC);
+ return (data);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_enable
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_compression_enable(void)
+#else
+int
+gfx_get_compression_enable(void)
+#endif
+{
+ unsigned long gcfg;
+
+ gcfg = READ_REG32(DC_GENERAL_CFG);
+ if (gcfg & DC_GCFG_CMPE)
+ return (1);
+ else
+ return (0);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_compression_offset(void)
+#else
+unsigned long
+gfx_get_compression_offset(void)
+#endif
+{
+ unsigned long offset;
+
+ offset = READ_REG32(DC_CB_ST_OFFSET) & 0x003FFFFF;
+ return (offset);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_pitch
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_compression_pitch(void)
+#else
+unsigned short
+gfx_get_compression_pitch(void)
+#endif
+{
+ unsigned short pitch;
+
+ pitch = (unsigned short)(READ_REG32(DC_LINE_DELTA) >> 12) & 0x03FF;
+ return (pitch << 2);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_size
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu1_get_compression_size(void)
+#else
+unsigned short
+gfx_get_compression_size(void)
+#endif
+{
+ unsigned short size;
+
+ size = (unsigned short)((READ_REG32(DC_BUF_SIZE) >> 9) & 0x7F) - 1;
+ return ((size << 2) + 16);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_valid_bit
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_valid_bit(int line)
+#else
+int
+gfx_get_valid_bit(int line)
+#endif
+{
+ int valid;
+
+ WRITE_REG32(MC_DR_ADD, line);
+ valid = (int)READ_REG32(MC_DR_ACC) & 1;
+ return (valid);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_display_video_offset(void)
+#else
+unsigned long
+gfx_get_display_video_offset(void)
+#endif
+{
+ return (READ_REG32(DC_VID_ST_OFFSET) & 0x003FFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu1_get_display_video_size(void)
+#else
+unsigned long
+gfx_get_display_video_size(void)
+#endif
+{
+ /* RETURN TOTAL SIZE, IN BYTES */
+ return ((READ_REG32(DC_BUF_SIZE) >> 10) & 0x000FFFC0);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_priority_high
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu1_get_display_priority_high(void)
+#else
+int
+gfx_get_display_priority_high(void)
+#endif
+{
+ if (READ_REG32(MC_MEM_CNTRL1) & MC_XBUSARB)
+ return (1);
+ else
+ return (0);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/disp_gu2.c b/src/gfx/disp_gu2.c
new file mode 100644
index 0000000..403a72a
--- /dev/null
+++ b/src/gfx/disp_gu2.c
@@ -0,0 +1,2788 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ */
+
+/*
+ * This file contains routines for the second generation display controller.
+ * */
+
+void gu2_enable_compression(void); /* private routine definition */
+void gu2_disable_compression(void); /* private routine definition */
+int gfx_set_display_control(int sync_polarities); /* private routine
+ * definition */
+void gfx_reset_video(void);
+int gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp);
+
+ /*---------------------------------------------------------------------------
+ * WARNING!!!! INACCURATE DELAY MECHANISM
+ *
+ * In an effort to keep the code self contained and operating system
+ * independent, the delay loop just performs reads of a display controller
+ * register. This time will vary for faster processors. The delay can always
+ * be longer than intended, only effecting the time of the mode switch
+ * (obviously want it to still be under a second). Problems with the hardware
+ * only arise if the delay is not long enough.
+ *----------------------------------------------------------------------------
+ */
+#define RC_READS_PER_MILLISECOND 15000L
+
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_delay_milliseconds(unsigned long milliseconds)
+#else
+void
+gfx_delay_milliseconds(unsigned long milliseconds)
+#endif
+{
+ /* ASSUME 300 MHZ 20 CLOCKS PER READ */
+ unsigned long loop;
+
+ loop = milliseconds * RC_READS_PER_MILLISECOND;
+ while (loop-- > 0) {
+ READ_REG32(MDC_UNLOCK);
+ }
+}
+
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_delay_microseconds(unsigned long microseconds)
+#else
+void
+gfx_delay_microseconds(unsigned long microseconds)
+#endif
+{
+ /* ASSUME 400 MHz, 2 CLOCKS PER INCREMENT */
+ unsigned long loop_count = microseconds * 15;
+
+ while (loop_count-- > 0) {
+ READ_REG32(MDC_UNLOCK);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_BPP
+ *
+ * This routine programs the bpp in the display controller.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_display_bpp(unsigned short bpp)
+#else
+int
+gfx_set_display_bpp(unsigned short bpp)
+#endif
+{
+ unsigned long dcfg, lock;
+
+ dcfg =
+ READ_REG32(MDC_DISPLAY_CFG) & ~(MDC_DCFG_DISP_MODE_MASK |
+ MDC_DCFG_16BPP_MODE_MASK);
+ lock = READ_REG32(MDC_UNLOCK);
+
+ switch (bpp) {
+ case 12:
+ dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_12BPP);
+ break;
+ case 15:
+ dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_15BPP);
+ break;
+ case 16:
+ dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_16BPP);
+ break;
+ case 32:
+ dcfg |= (MDC_DCFG_DISP_MODE_24BPP);
+ break;
+ case 8:
+ dcfg |= (MDC_DCFG_DISP_MODE_8BPP);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
+ WRITE_REG32(MDC_UNLOCK, lock);
+
+ /* SET BPP IN GRAPHICS PIPELINE */
+ gfx_set_bpp(bpp);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * gu2_set_specified_mode (private routine)
+ * This routine uses the parameters in the specified display mode structure
+ * to program the display controller hardware.
+ *----------------------------------------------------------------------------
+ */
+int
+gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp)
+{
+ unsigned long unlock, value;
+ unsigned long gcfg, dcfg;
+ unsigned long size, pitch;
+ unsigned long vid_buf_size;
+ unsigned long bpp_mask, temp, dv_size;
+
+ /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
+ /* Flag used for locking also overrides timing change restriction */
+ if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
+ return GFX_STATUS_ERROR;
+
+ /* CLEAR PANNING OFFSETS */
+ DeltaX = 0;
+ DeltaY = 0;
+ panelLeft = 0;
+ panelTop = 0;
+
+ /* SET GLOBAL FLAG */
+
+ if (pMode->flags & GFX_MODE_LOCK_TIMING)
+ gfx_timing_lock = 1;
+
+ /* CHECK FOR VALID BPP */
+ /* As this function can be called directly from */
+ /* gfx_set_display_timings, we must correct any */
+ /* invalid bpp settings. */
+ switch (bpp) {
+ case 12:
+ bpp_mask = 0x00000900;
+ break;
+ case 15:
+ bpp_mask = 0x00000500;
+ break;
+ case 16:
+ bpp_mask = 0x00000100;
+ break;
+ case 32:
+ bpp_mask = 0x00000200;
+ break;
+ default:
+ bpp_mask = 0x00000000;
+ bpp = 8;
+ break;
+ }
+
+ gbpp = bpp;
+
+ /* DISABLE COMPRESSION */
+ gu2_disable_compression();
+
+ /* ALSO DISABLE VIDEO */
+ /* Use private "reset video" routine to do all that is needed. */
+ /* SC1200, for example, also disables the alpha blending regions. */
+ gfx_reset_video();
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+ unlock = READ_REG32(MDC_UNLOCK);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+
+ /* READ THE CURRENT REGISTER VALUES */
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+ dcfg = READ_REG32(MDC_DISPLAY_CFG);
+
+ /* BLANK THE DISPLAY IN THE DISPLAY FILTER */
+ gfx_set_crt_enable(0);
+
+ /* DISABLE THE TIMING GENERATOR */
+ dcfg &= ~(unsigned long)MDC_DCFG_TGEN;
+ WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
+
+ /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */
+ /* This delay is used to make sure that all pending requests to the */
+ /* memory controller have completed before disabling the FIFO load. */
+ gfx_delay_milliseconds(5);
+
+ /* DISABLE DISPLAY FIFO LOAD */
+ gcfg &= ~(unsigned long)MDC_GCFG_DFLE;
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+
+ /* PRESERVE VIDEO INFORMATION */
+ gcfg &= (unsigned long)(MDC_GCFG_YUVM | MDC_GCFG_VDSE);
+ dcfg = 0;
+
+ /* SET THE DOT CLOCK FREQUENCY */
+ /* Mask off the divide by two bit (bit 31) */
+ if (!(pMode->flags & GFX_MODE_EXCLUDE_PLL))
+ gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
+
+ /* DELAY: WAIT FOR THE PLL TO SETTLE */
+ /* This allows the dot clock frequency that was just set to settle. */
+ gfx_delay_milliseconds(10);
+
+ /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
+ WRITE_REG32(MDC_FB_ST_OFFSET, 0);
+ WRITE_REG32(MDC_CB_ST_OFFSET, 0);
+ WRITE_REG32(MDC_CURS_ST_OFFSET, 0);
+ WRITE_REG32(MDC_ICON_ST_OFFSET, 0);
+
+ /* SET LINE SIZE AND PITCH */
+ /* 1. Flat Panels must use the mode width and not */
+ /* the timing width to set the pitch. */
+ /* 2. Mode sets will use a pitch that is aligned */
+ /* on a 1K boundary to preserve legacy. The */
+ /* pitch can be overridden by a subsequent call */
+ /* to gfx_set_display_pitch. */
+ if (PanelEnable)
+ size = ModeWidth;
+ else
+ size = pMode->hactive;
+
+ if (bpp > 8)
+ size <<= 1;
+
+ if (bpp > 16)
+ size <<= 1;
+
+ pitch = 1024;
+ dv_size = MDC_DV_LINE_SIZE_1024;
+
+ if (size > 1024) {
+ pitch = 2048;
+ dv_size = MDC_DV_LINE_SIZE_2048;
+ }
+
+ if (size > 2048) {
+ pitch = 4096;
+ dv_size = MDC_DV_LINE_SIZE_4096;
+ }
+
+ if (size > 4096) {
+ pitch = 8192;
+ dv_size = MDC_DV_LINE_SIZE_8192;
+ }
+
+ WRITE_REG32(MDC_GFX_PITCH, pitch >> 3);
+
+ /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */
+ temp = READ_REG32(MDC_DV_CTL);
+ WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size);
+
+ if (PanelEnable) {
+ size = pMode->hactive;
+ if (bpp > 8)
+ size <<= 1;
+ if (bpp > 16)
+ size <<= 1;
+ }
+
+ /* SAVE PREVIOUSLY STORED VIDEO LINE SIZE */
+ vid_buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF000000;
+
+ /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */
+ WRITE_REG32(MDC_LINE_SIZE, ((size >> 3) + 2) | vid_buf_size);
+
+ /* ALWAYS ENABLE VIDEO AND GRAPHICS DATA */
+ /* These bits are relics from a previous design and */
+ /* should always be enabled. */
+ dcfg |= (unsigned long)(MDC_DCFG_VDEN | MDC_DCFG_GDEN);
+
+ /* SET PIXEL FORMAT */
+ dcfg |= bpp_mask;
+
+ /* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
+ /* AND VERT. INT. SELECT */
+ dcfg |=
+ (unsigned long)(MDC_DCFG_TGEN | MDC_DCFG_TRUP | MDC_DCFG_PALB |
+ MDC_DCFG_VISL);
+
+ /* DISABLE ADDRESS MASKS */
+ dcfg |= MDC_DCFG_A20M;
+ dcfg |= MDC_DCFG_A18M;
+
+ /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */
+ /* Set the priorities higher for high resolution modes. */
+ if (pMode->hactive > 1024 || bpp == 32)
+ gcfg |= 0x000A901;
+ else
+ gcfg |= 0x0006501;
+
+ /* ENABLE FLAT PANEL CENTERING */
+ /* For panel modes having a resolution smaller than the */
+ /* panel resolution, turn on data centering. */
+ if (PanelEnable && ModeWidth < PanelWidth)
+ dcfg |= MDC_DCFG_DCEN;
+
+ /* COMBINE AND SET TIMING VALUES */
+ value = (unsigned long)(pMode->hactive - 1) |
+ (((unsigned long)(pMode->htotal - 1)) << 16);
+ WRITE_REG32(MDC_H_ACTIVE_TIMING, value);
+ value = (unsigned long)(pMode->hblankstart - 1) |
+ (((unsigned long)(pMode->hblankend - 1)) << 16);
+ WRITE_REG32(MDC_H_BLANK_TIMING, value);
+ value = (unsigned long)(pMode->hsyncstart - 1) |
+ (((unsigned long)(pMode->hsyncend - 1)) << 16);
+ WRITE_REG32(MDC_H_SYNC_TIMING, value);
+ value = (unsigned long)(pMode->vactive - 1) |
+ (((unsigned long)(pMode->vtotal - 1)) << 16);
+ WRITE_REG32(MDC_V_ACTIVE_TIMING, value);
+ value = (unsigned long)(pMode->vblankstart - 1) |
+ (((unsigned long)(pMode->vblankend - 1)) << 16);
+ WRITE_REG32(MDC_V_BLANK_TIMING, value);
+ value = (unsigned long)(pMode->vsyncstart - 1) |
+ (((unsigned long)(pMode->vsyncend - 1)) << 16);
+ WRITE_REG32(MDC_V_SYNC_TIMING, value);
+
+ WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+
+ /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+ gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
+ ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
+
+ /* RESTORE VALUE OF MDC_UNLOCK */
+ WRITE_REG32(MDC_UNLOCK, unlock);
+
+ /* RESET THE PITCH VALUES IN THE GP */
+ gfx_reset_pitch((unsigned short)pitch);
+
+ gfx_set_bpp((unsigned short)bpp);
+
+ return GFX_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_IS_DISPLAY_MODE_SUPPORTED
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#else
+int
+gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#endif
+{
+ unsigned int mode;
+ unsigned long hz_flag = 0, bpp_flag = 0;
+
+ /* SET FLAGS TO MATCH REFRESH RATE */
+ gfx_mode_hz_conversion
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+ gfx_mode_bpp_conversion
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
+ if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
+ (DisplayParams[mode].vactive == (unsigned short)yres) &&
+ (DisplayParams[mode].flags & hz_flag) &&
+ (DisplayParams[mode].flags & bpp_flag)) {
+
+ /* REDCLOUD DOES NOT SUPPORT EMULATED VGA MODES */
+ if ((DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) ||
+ (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE))
+ continue;
+
+ /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
+ return (mode);
+ }
+ }
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_display_mode
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_display_mode(int xres, int yres, int bpp, int hz)
+#else
+int
+gfx_set_display_mode(int xres, int yres, int bpp, int hz)
+#endif
+{
+ int mode;
+
+ /* DISABLE FLAT PANEL */
+ /* Flat Panel settings are enabled by the function gfx_set_fixed_timings
+ * and disabled by gfx_set_display_mode.
+ * */
+ PanelEnable = 0;
+
+ mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
+ if (mode >= 0) {
+ if (gu2_set_specified_mode(&DisplayParams[mode],
+ bpp) == GFX_STATUS_OK)
+ return (1);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_TIMINGS
+ *
+ * This routine sets the display controller mode using the specified timing
+ * values (as opposed to using the tables internal to Durango).
+ *
+ * Returns GFX_STATUS_OK ON SUCCESS, GFX_STATUS_ERROR otherwise.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
+#else
+int
+gfx_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
+#endif
+{
+ /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
+
+ gfx_display_mode.flags = 0;
+ if (flags & 1)
+ gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
+ if (flags & 2)
+ gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
+ if (flags & 4)
+ gfx_display_mode.flags |= GFX_MODE_EXCLUDE_PLL;
+ if (flags & 0x1000)
+ gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
+ gfx_display_mode.hactive = hactive;
+ gfx_display_mode.hblankstart = hblankstart;
+ gfx_display_mode.hsyncstart = hsyncstart;
+ gfx_display_mode.hsyncend = hsyncend;
+ gfx_display_mode.hblankend = hblankend;
+ gfx_display_mode.htotal = htotal;
+ gfx_display_mode.vactive = vactive;
+ gfx_display_mode.vblankstart = vblankstart;
+ gfx_display_mode.vsyncstart = vsyncstart;
+ gfx_display_mode.vsyncend = vsyncend;
+ gfx_display_mode.vblankend = vblankend;
+ gfx_display_mode.vtotal = vtotal;
+ gfx_display_mode.frequency = frequency;
+
+ /* CALL ROUTINE TO SET MODE */
+ return (gu2_set_specified_mode(&gfx_display_mode, bpp));
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_VTOTAL
+ *
+ * This routine sets the display controller vertical total to
+ * "vtotal". As a side effect it also sets vertical blank end.
+ * It should be used when only this value needs to be changed,
+ * due to speed considerations.
+ *
+ * Note: it is the caller's responsibility to make sure that
+ * a legal vtotal is used, i.e. that "vtotal" is greater than or
+ * equal to vsync end.
+ *
+ * Always returns 0.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_vtotal(unsigned short vtotal)
+#else
+int
+gfx_set_vtotal(unsigned short vtotal)
+#endif
+{
+ unsigned long unlock, dcfg, vactive, vblank;
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+ unlock = READ_REG32(MDC_UNLOCK);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+
+ /* READ THE CURRENT RC VALUES */
+ dcfg = READ_REG32(MDC_DISPLAY_CFG);
+ vactive = READ_REG32(MDC_V_ACTIVE_TIMING);
+ vblank = READ_REG32(MDC_V_BLANK_TIMING);
+
+ /* DISABLE TIMING REGISTER UPDATES */
+ WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~(unsigned long)MDC_DCFG_TRUP);
+
+ /* WRITE NEW TIMING VALUES */
+ WRITE_REG32(MDC_V_ACTIVE_TIMING,
+ (vactive & MDC_VAT_VA_MASK) | (unsigned long)(vtotal - 1) << 16);
+ WRITE_REG32(MDC_V_BLANK_TIMING,
+ (vblank & MDC_VBT_VBS_MASK) | (unsigned long)(vtotal - 1) << 16);
+
+ /* RESTORE OLD RC VALUES */
+ WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_pitch
+ *
+ * This routine sets the pitch of the frame buffer to the specified value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_pitch(unsigned short pitch)
+#else
+void
+gfx_set_display_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long value = 0;
+ unsigned long lock = READ_REG32(MDC_UNLOCK);
+
+ value = READ_REG32(MDC_GFX_PITCH) & 0xFFFF0000;
+ value |= (pitch >> 3);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GFX_PITCH, value);
+
+ /* SET RENDERING PITCHES TO MATCH */
+ gfx_reset_pitch(pitch);
+
+ /* SET THE FRAME DIRTY MODE */
+ /* Non-standard pitches, i.e. pitches that */
+ /* are not 1K, 2K or 4K must mark the entire */
+ /* frame as dirty when writing to the frame */
+ /* buffer. */
+ value = READ_REG32(MDC_GENERAL_CFG);
+
+ if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
+ value &= ~(unsigned long)(MDC_GCFG_FDTY);
+ else
+ value |= (unsigned long)(MDC_GCFG_FDTY);
+
+ WRITE_REG32(MDC_GENERAL_CFG, value);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_offset
+ *
+ * This routine sets the start address of the frame buffer. It is
+ * typically used to pan across a virtual desktop (frame buffer larger than
+ * the displayed screen) or to flip the display between multiple buffers.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_offset(unsigned long offset)
+#else
+void
+gfx_set_display_offset(unsigned long offset)
+#endif
+{
+ /* UPDATE FRAME BUFFER OFFSET */
+ unsigned long lock;
+
+ lock = READ_REG32(MDC_UNLOCK);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+
+ /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
+ /* Disable compression for non-zero start addresss values. */
+ /* Enable compression if offset is zero and comression is intended to */
+ /* be enabled from a previous call to "gfx_set_compression_enable". */
+ /* Compression should be disabled BEFORE the offset is changed */
+ /* and enabled AFTER the offset is changed. */
+ if (offset == 0) {
+ WRITE_REG32(MDC_FB_ST_OFFSET, offset);
+ if (gfx_compression_enabled) {
+ /* WAIT FOR THE OFFSET TO BE LATCHED */
+ gfx_wait_vertical_blank();
+ gu2_enable_compression();
+ }
+ } else {
+ /* ONLY DISABLE COMPRESSION ONCE */
+ if (gfx_compression_active)
+ gu2_disable_compression();
+
+ WRITE_REG32(MDC_FB_ST_OFFSET, offset);
+ }
+
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette_entry
+ *
+ * This routine sets an palette entry in the display controller.
+ * A 32-bit X:R:G:B value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_display_palette_entry(unsigned long index, unsigned long palette)
+#else
+int
+gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ unsigned long dcfg, unlock;
+
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ unlock = READ_REG32(MDC_UNLOCK);
+ dcfg = READ_REG32(MDC_DISPLAY_CFG);
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~MDC_DCFG_PALB);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+
+ WRITE_REG32(MDC_PAL_ADDRESS, index);
+ WRITE_REG32(MDC_PAL_DATA, palette);
+
+ return GFX_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette
+ *
+ * This routine sets the entire palette in the display controller.
+ * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_display_palette(unsigned long *palette)
+#else
+int
+gfx_set_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long unlock, dcfg, i;
+
+ WRITE_REG32(MDC_PAL_ADDRESS, 0);
+
+ if (palette) {
+ unlock = READ_REG32(MDC_UNLOCK);
+ dcfg = READ_REG32(MDC_DISPLAY_CFG);
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~MDC_DCFG_PALB);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+
+ for (i = 0; i < 256; i++)
+ WRITE_REG32(MDC_PAL_DATA, palette[i]);
+
+ return GFX_STATUS_OK;
+ }
+ return GFX_STATUS_BAD_PARAMETER;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_enable
+ *
+ * This routine enables or disables the hardware cursor.
+ *
+ * WARNING: The cursor start offset must be set by setting the cursor
+ * position before calling this routine to assure that memory reads do not
+ * go past the end of graphics memory (this can hang GXm).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_cursor_enable(int enable)
+#else
+void
+gfx_set_cursor_enable(int enable)
+#endif
+{
+ unsigned long unlock, gcfg;
+
+ /* SET OR CLEAR CURSOR ENABLE BIT */
+ unlock = READ_REG32(MDC_UNLOCK);
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+ if (enable)
+ gcfg |= MDC_GCFG_CURE;
+ else
+ gcfg &= ~(MDC_GCFG_CURE);
+
+ /* WRITE NEW REGISTER VALUE */
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_colors
+ *
+ * This routine sets the colors of the hardware cursor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#else
+void
+gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#endif
+{
+ /* SET CURSOR COLORS */
+ WRITE_REG32(MDC_PAL_ADDRESS, 0x100);
+ WRITE_REG32(MDC_PAL_DATA, bkcolor);
+ WRITE_REG32(MDC_PAL_DATA, fgcolor);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_position
+ *
+ * This routine sets the position of the hardware cusror. The starting
+ * offset of the cursor buffer must be specified so that the routine can
+ * properly clip scanlines if the cursor is off the top of the screen.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#else
+void
+gfx_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#endif
+{
+ unsigned long unlock;
+
+ short x = (short)xpos - (short)xhotspot;
+ short y = (short)ypos - (short)yhotspot;
+ short xoffset = 0;
+ short yoffset = 0;
+
+ if (x < -63)
+ return;
+ if (y < -63)
+ return;
+
+ if (PanelEnable) {
+ if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
+ gfx_enable_panning(xpos, ypos);
+ x = x - (unsigned short)panelLeft;
+ y = y - (unsigned short)panelTop;
+ }
+ }
+
+ /* ADJUST OFFSETS */
+ /* Cursor movement and panning work as follows: The cursor position */
+ /* refers to where the hotspot of the cursor is located. However, for */
+ /* non-zero hotspots, the cursor buffer actually begins before the */
+ /* specified position. */
+ if (x < 0) {
+ xoffset = -x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ yoffset = -y;
+ y = 0;
+ }
+ memoffset += (unsigned long)yoffset << 4;
+
+ /* SET CURSOR POSITION */
+ unlock = READ_REG32(MDC_UNLOCK);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_CURS_ST_OFFSET, memoffset);
+ WRITE_REG32(MDC_CURSOR_X, (unsigned long)x |
+ (((unsigned long)xoffset) << 11));
+ WRITE_REG32(MDC_CURSOR_Y, (unsigned long)y |
+ (((unsigned long)yoffset) << 11));
+ WRITE_REG32(MDC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape32
+ *
+ * This routine loads 32x32 cursor data into the cursor buffer in graphics
+ * memory.
+ * As the Redcloud cursor is actually 64x64, we must pad the outside of the
+ * cursor data with transparent pixels.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#else
+void
+gfx_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+ WRITE_FB32(memoffset, 0xFFFFFFFF);
+ WRITE_FB32(memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+ WRITE_FB32(memoffset + 8, 0x00000000);
+ WRITE_FB32(memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+
+ /* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
+ for (i = 0; i < 32; i++) {
+ WRITE_FB32(memoffset, 0xFFFFFFFF);
+ WRITE_FB32(memoffset + 4, 0xFFFFFFFF);
+ WRITE_FB32(memoffset + 8, 0x00000000);
+ WRITE_FB32(memoffset + 12, 0x00000000);
+
+ memoffset += 16;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape64
+ *
+ * This routine loads 64x64 cursor data into the cursor buffer in graphics
+ * memory.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#else
+void
+gfx_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+ int i;
+
+ for (i = 0; i < 128; i += 2) {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+ /* We invert the dwords to prevent the calling */
+ /* application from having to think in terms of Qwords. */
+ /* The hardware data order is actually 63:0, or 31:0 of */
+ /* the second dword followed by 31:0 of the first dword. */
+ WRITE_FB32(memoffset, andmask[i + 1]);
+ WRITE_FB32(memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+ WRITE_FB32(memoffset + 8, xormask[i + 1]);
+ WRITE_FB32(memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_enable
+ *
+ * This routine enables or disables the hardware icon. The icon position
+ * and colors should be programmed prior to calling this routine for the
+ * first time.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_icon_enable(int enable)
+#else
+void
+gfx_set_icon_enable(int enable)
+#endif
+{
+ unsigned long unlock, gcfg;
+
+ /* SET OR CLEAR ICON ENABLE BIT */
+ unlock = READ_REG32(MDC_UNLOCK);
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+ if (enable)
+ gcfg |= MDC_GCFG_ICNE;
+ else
+ gcfg &= ~(MDC_GCFG_ICNE);
+
+ /* WRITE NEW REGISTER VALUE */
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_colors
+ *
+ * This routine sets the three icon colors.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_icon_colors(unsigned long color0, unsigned long color1,
+ unsigned long color2)
+#else
+void
+gfx_set_icon_colors(unsigned long color0, unsigned long color1,
+ unsigned long color2)
+#endif
+{
+ /* ICON COLORS LOCATED AT PALETTE INDEXES 102-104h */
+ WRITE_REG32(MDC_PAL_ADDRESS, 0x102);
+
+ WRITE_REG32(MDC_PAL_DATA, color0);
+ WRITE_REG32(MDC_PAL_DATA, color1);
+ WRITE_REG32(MDC_PAL_DATA, color2);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_position
+ *
+ * This routine sets the starting X coordinate for the hardware icon and the
+ * memory offset for the icon buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_icon_position(unsigned long memoffset, unsigned short xpos)
+#else
+void
+gfx_set_icon_position(unsigned long memoffset, unsigned short xpos)
+#endif
+{
+ unsigned long lock = READ_REG32(MDC_UNLOCK);
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+
+ /* PROGRAM THE MEMORY OFFSET */
+ WRITE_REG32(MDC_ICON_ST_OFFSET, memoffset & 0x0FFFFFFF);
+
+ /* PROGRAM THE XCOORDINATE */
+ WRITE_REG32(MDC_ICON_X, (unsigned long)(xpos & 0x07FF));
+
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_shape64
+ *
+ * This routine initializes the icon buffer according to the current mode.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned int lines)
+#else
+void
+gfx_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned int lines)
+#endif
+{
+ unsigned short i, height;
+
+ height = lines << 1;
+
+ for (i = 0; i < height; i += 2) {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+ /* Swap dwords to hide qword constraint */
+ WRITE_FB32(memoffset, andmask[i + 1]);
+ WRITE_FB32(memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+ WRITE_FB32(memoffset + 8, xormask[i + 1]);
+ WRITE_FB32(memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gu2_enable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It enables display compression.
+ *---------------------------------------------------------------------------
+ */
+void
+gu2_enable_compression(void)
+{
+ unsigned long unlock, gcfg, temp;
+
+ /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
+ if (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF)
+ return;
+
+ /* SET GLOBAL INDICATOR */
+ gfx_compression_active = 1;
+
+ /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
+ /* Software is required to do this before enabling compression. */
+ /* Don't want controller to think that old lines are still valid. */
+ /* Writing a 1 to bit 0 of the DV Control register will force the */
+ /* hardware to clear all the valid bits. */
+ temp = READ_REG32(MDC_DV_CTL);
+ WRITE_REG32(MDC_DV_CTL, temp | 0x00000001);
+
+ /* TURN ON COMPRESSION CONTROL BITS */
+ unlock = READ_REG32(MDC_UNLOCK);
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+ gcfg |= MDC_GCFG_CMPE | MDC_GCFG_DECE;
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gu2_disable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It disables display compression.
+ *---------------------------------------------------------------------------
+ */
+void
+gu2_disable_compression(void)
+{
+ unsigned long unlock, gcfg;
+
+ /* SET GLOBAL INDICATOR */
+
+ gfx_compression_active = 0;
+
+ /* TURN OFF COMPRESSION CONTROL BITS */
+
+ unlock = READ_REG32(MDC_UNLOCK);
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+ gcfg &= ~(MDC_GCFG_CMPE | MDC_GCFG_DECE);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_enable
+ *
+ * This routine enables or disables display compression.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_compression_enable(int enable)
+#else
+int
+gfx_set_compression_enable(int enable)
+#endif
+{
+ /* SET GLOBAL VARIABLE FOR INDENDED STATE */
+ /* Compression can only be enabled for non-zero start address values. */
+ /* Keep state to enable compression on start address changes. */
+
+ gfx_compression_enabled = enable;
+ if (enable)
+ gu2_enable_compression();
+ else
+ gu2_disable_compression();
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_offset
+ *
+ * This routine sets the base offset for the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_compression_offset(unsigned long offset)
+#else
+int
+gfx_set_compression_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ /* MUST BE 16-BYTE ALIGNED FOR REDCLOUD */
+
+ if (offset & 0x0F)
+ return (1);
+
+ /* SET REGISTER VALUE */
+
+ lock = READ_REG32(MDC_UNLOCK);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_CB_ST_OFFSET, offset & 0x0FFFFFFF);
+ WRITE_REG32(MDC_UNLOCK, lock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_pitch
+ *
+ * This routine sets the pitch, in bytes, of the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_compression_pitch(unsigned short pitch)
+#else
+int
+gfx_set_compression_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long lock, line_delta;
+
+ lock = READ_REG32(MDC_UNLOCK);
+
+ /* SET REGISTER VALUE */
+
+ line_delta = READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF;
+ line_delta |= (((unsigned long)pitch << 13) & 0xFFFF0000);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GFX_PITCH, line_delta);
+ WRITE_REG32(MDC_UNLOCK, lock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_size
+ *
+ * This routine sets the line size of the compression buffer, which is the
+ * maximum number of bytes allowed to store a compressed line.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_compression_size(unsigned short size)
+#else
+int
+gfx_set_compression_size(unsigned short size)
+#endif
+{
+ unsigned long lock, buf_size;
+
+ /* SUBTRACT 32 FROM SIZE */
+ /* The display controller will actually write */
+ /* 4 extra QWords. So, if we assume that "size" */
+ /* refers to the allocated size, we must subtract */
+ /* 32 bytes. */
+
+ size -= 32;
+
+ /* SET REGISTER VALUE */
+
+ lock = READ_REG32(MDC_UNLOCK);
+ buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF80FFFF;
+ buf_size |= ((((unsigned long)size >> 3) + 1) & 0x7F) << 16;
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_LINE_SIZE, buf_size);
+ WRITE_REG32(MDC_UNLOCK, lock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_format". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_format(unsigned long format)
+#else
+void
+gfx_set_display_video_format(unsigned long format)
+#endif
+{
+ unsigned long gcfg, lock;
+
+ lock = READ_REG32(MDC_UNLOCK);
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+
+ switch (format) {
+ case VIDEO_FORMAT_Y0Y1Y2Y3:
+ case VIDEO_FORMAT_Y3Y2Y1Y0:
+ case VIDEO_FORMAT_Y1Y0Y3Y2:
+ case VIDEO_FORMAT_Y1Y2Y3Y0:
+ gcfg |= MDC_GCFG_YUVM;
+ break;
+
+ default:
+ gcfg &= ~MDC_GCFG_YUVM;
+ break;
+ }
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_enable". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_enable(int enable)
+#else
+void
+gfx_set_display_video_enable(int enable)
+#endif
+{
+ unsigned long lock, gcfg, dcfg;
+
+ /* READ CURRENT VALUES */
+
+ lock = READ_REG32(MDC_UNLOCK);
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+ dcfg = READ_REG32(MDC_DISPLAY_CFG);
+
+ /* SET OR CLEAR VIDEO ENABLE IN GENERAL_CFG */
+
+ if (enable)
+ gcfg |= MDC_GCFG_VIDE;
+ else
+ gcfg &= ~MDC_GCFG_VIDE;
+
+ /* WRITE REGISTER */
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_size(unsigned short width, unsigned short height)
+#else
+void
+gfx_set_display_video_size(unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long lock, value, yuv_420;
+
+ /* READ CURRENT VALUES */
+
+ lock = READ_REG32(MDC_UNLOCK);
+ value = READ_REG32(MDC_LINE_SIZE) & 0x00FFFFFF;
+ yuv_420 = READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_YUVM;
+
+ /* LINE WIDTH IS 1/4 FOR 4:2:0 VIDEO */
+ /* All data must be 32-byte aligned. */
+
+ if (yuv_420) {
+ width >>= 1;
+ width = (width + 7) & 0xFFF8;
+ } else {
+ width <<= 1;
+ width = (width + 31) & 0xFFE0;
+ }
+
+ /* ONLY THE LINE SIZE IS PROGRAMMED IN THE DISPLAY CONTROLLER */
+
+ value |= ((unsigned long)width << 21);
+
+ /* WRITE THE REGISTER */
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_LINE_SIZE, value);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_offset(unsigned long offset)
+#else
+void
+gfx_set_display_video_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ lock = READ_REG32(MDC_UNLOCK);
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ offset &= 0x0FFFFFF0;
+ WRITE_REG32(MDC_VID_Y_ST_OFFSET, offset);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by gfx_set_video_yuv_offsets. It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset)
+#else
+void
+gfx_set_display_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset)
+#endif
+{
+ unsigned long lock;
+
+ lock = READ_REG32(MDC_UNLOCK);
+
+ yoffset &= 0x0FFFFFF0;
+ uoffset &= 0x0FFFFFF8;
+ voffset &= 0x0FFFFFF8;
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_VID_Y_ST_OFFSET, yoffset);
+ WRITE_REG32(MDC_VID_U_ST_OFFSET, uoffset);
+ WRITE_REG32(MDC_VID_V_ST_OFFSET, voffset);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by gfx_set_video_yuv_pitch. It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#else
+void
+gfx_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#endif
+{
+ unsigned long lock, pitch;
+
+ lock = READ_REG32(MDC_UNLOCK);
+
+ pitch = ((uvpitch << 13) & 0xFFFF0000) | ((ypitch >> 3) & 0xFFFF);
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_VID_YUV_PITCH, pitch);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_downscale (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by gfx_set_video_vertical_downscale. It abstracts
+ * the version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_downscale(unsigned short srch, unsigned short dsth)
+#else
+void
+gfx_set_display_video_downscale(unsigned short srch, unsigned short dsth)
+#endif
+{
+ unsigned long lock, delta;
+
+ lock = READ_REG32(MDC_UNLOCK);
+
+ /* CLIP SCALING LIMITS */
+ /* Upscaling is performed in a separate function. */
+ /* Maximum scale ratio is 1/2. */
+
+ if (dsth > srch || dsth <= (srch >> 1))
+ delta = 0;
+ else
+ delta = (((unsigned long)srch << 14) / (unsigned long)dsth) << 18;
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_VID_DS_DELTA, delta);
+ WRITE_REG32(MDC_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_vertical_downscale_enable".
+ * It abstracts the version of the display controller from the video overlay
+ * routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_set_display_video_vertical_downscale_enable(int enable)
+#else
+void
+gfx_set_display_video_vertical_downscale_enable(int enable)
+#endif
+{
+ unsigned long gcfg, unlock;
+
+ unlock = READ_REG32(MDC_UNLOCK);
+ gcfg = READ_REG32(MDC_GENERAL_CFG);
+
+ if (enable)
+ gcfg |= MDC_GCFG_VDSE;
+ else
+ gcfg &= ~MDC_GCFG_VDSE;
+
+ WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
+ WRITE_REG32(MDC_GENERAL_CFG, gcfg);
+ WRITE_REG32(MDC_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_timing_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_test_timing_active(void)
+#else
+int
+gfx_test_timing_active(void)
+#endif
+{
+ if (READ_REG32(MDC_DISPLAY_CFG) & MDC_DCFG_TGEN)
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_vertical_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_test_vertical_active(void)
+#else
+int
+gfx_test_vertical_active(void)
+#endif
+{
+ if (READ_REG32(MDC_LINE_CNT_STATUS) & MDC_LNCNT_VNA)
+ return (0);
+
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_wait_vertical_blank
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_wait_vertical_blank(void)
+#else
+int
+gfx_wait_vertical_blank(void)
+#endif
+{
+ if (gfx_test_timing_active()) {
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_panning
+ *
+ * This routine enables the panning when the Mode is bigger than the panel
+ * size.
+ *---------------------------------------------------------------------------
+ */
+
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_enable_panning(int x, int y)
+#else
+void
+gfx_enable_panning(int x, int y)
+#endif
+{
+ unsigned long modeBytesPerPixel;
+ unsigned long modeBytesPerScanline = 0;
+ unsigned long startAddress = 0;
+
+ modeBytesPerPixel = (gbpp + 7) / 8;
+ modeBytesPerScanline = (READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3;
+
+ /* TEST FOR NO-WORK */
+
+ if (x >= DeltaX && x < ((int)PanelWidth + DeltaX) &&
+ y >= DeltaY && y < ((int)PanelHeight + DeltaY))
+ return;
+
+ /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */
+ /* Test the boundary conditions for each coordinate and update */
+ /* all variables and the starting offset accordingly. */
+
+ if (x < DeltaX)
+ DeltaX = x;
+
+ else if (x >= (DeltaX + (int)PanelWidth))
+ DeltaX = x - (int)PanelWidth + 1;
+
+ if (y < DeltaY)
+ DeltaY = y;
+
+ else if (y >= (DeltaY + (int)PanelHeight))
+ DeltaY = y - (int)PanelHeight + 1;
+
+ /* CALCULATE THE START OFFSET */
+
+ startAddress =
+ (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
+
+ gfx_set_display_offset(startAddress);
+
+ /* SET PANEL COORDINATES */
+ /* Panel's x position must be DWORD aligned */
+
+ panelTop = DeltaY;
+ panelLeft = DeltaX * modeBytesPerPixel;
+
+ if (panelLeft & 3)
+ panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
+
+ panelLeft /= modeBytesPerPixel;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_is_panel_mode_supported
+ *---------------------------------------------------------------------------
+ */
+
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_is_panel_mode_supported(int panelResX, int panelResY,
+ unsigned short width, unsigned short height, unsigned short bpp)
+#else
+int
+gfx_is_panel_mode_supported(int panelResX, int panelResY,
+ unsigned short width, unsigned short height, unsigned short bpp)
+#endif
+{
+ unsigned int mode;
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
+ if ((FixedParams[mode].xres == width) &&
+ (FixedParams[mode].yres == height) &&
+ (FixedParams[mode].panelresx == panelResX) &&
+ (FixedParams[mode].panelresy == panelResY)) {
+ return ((int)mode);
+ }
+ }
+
+ return -1;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_fixed_timings
+ *---------------------------------------------------------------------------
+ */
+
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#else
+int
+gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#endif
+{
+ unsigned int mode;
+
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
+ if ((FixedParams[mode].xres == width) &&
+ (FixedParams[mode].yres == height) &&
+ (FixedParams[mode].panelresx == panelResX) &&
+ (FixedParams[mode].panelresy == panelResY)) {
+
+ /* SET THE 92xx FOR THE SELECTED MODE */
+ FIXEDTIMINGS *fmode = &FixedParams[mode];
+
+ gfx_set_display_timings(bpp, 3, fmode->hactive,
+ fmode->hblankstart, fmode->hsyncstart, fmode->hsyncend,
+ fmode->hblankend, fmode->htotal, fmode->vactive,
+ fmode->vblankstart, fmode->vsyncstart, fmode->vsyncend,
+ fmode->vblankend, fmode->vtotal, fmode->frequency);
+
+ return (1);
+ } /* end if() */
+ } /* end for() */
+
+ return (-1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_panel_present
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#else
+int
+gfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#endif
+{
+ /* SET VALID BPP */
+ /* 16BPP is the default. */
+
+ if (bpp != 8 && bpp != 12 && bpp != 15 && bpp != 16 && bpp != 32)
+ bpp = 16;
+
+ /* RECORD PANEL PARAMETERS */
+ /* This routine does not touch any panel timings. It is used when custom
+ * panel settings are set up in advance by the BIOS or an application, but
+ * the application still requires access to other panel functionality
+ * provided by Durango (i.e. panning).
+ * */
+
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+ gbpp = bpp;
+
+ /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
+
+ gfx_set_display_bpp(bpp);
+
+ return (GFX_STATUS_OK);
+}
+
+/* THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: */
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_pitch
+ *
+ * This routine returns the current pitch of the frame buffer, in bytes.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_display_pitch(void)
+#else
+unsigned short
+gfx_get_display_pitch(void)
+#endif
+{
+ return ((unsigned short)(READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_mode_frequency_supported
+ *
+ * This routine examines if the requested mode with pixel frequency is
+ * supported.
+ *
+ * Returns >0 if successful , <0 if freq. could not be found and matched.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency)
+#else
+int
+gfx_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+
+ gfx_mode_bpp_conversion_def(bpp)
+
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned int)xres) &&
+ (DisplayParams[index].vactive == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].frequency == frequency)) {
+ int hz = 0;
+
+ value = DisplayParams[index].flags;
+
+ if (value & GFX_MODE_56HZ)
+ hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ hz = 85;
+ else if (value & GFX_MODE_90HZ)
+ hz = 90;
+ else if (value & GFX_MODE_100HZ)
+ hz = 100;
+ return (hz);
+ }
+ }
+
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_frequency
+ *
+ * This routine maps the frequency to close match refresh rate
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#else
+int
+gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch = 0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ gfx_mode_bpp_conversion_def(bpp)
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].htotal == (unsigned int)xres) &&
+ (DisplayParams[index].vtotal == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag)) {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < min) {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (value & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (value & GFX_MODE_100HZ)
+ *hz = 100;
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_mode
+ *
+ * This routine is identical to the gfx_get_refreshrate_from_frequency,
+ * except that the active timing values are compared instead of the total
+ * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#else
+int
+gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch = 0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ gfx_mode_bpp_conversion_def(bpp)
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned int)xres) &&
+ (DisplayParams[index].vactive == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag)) {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < min) {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (value & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (value & GFX_MODE_100HZ)
+ *hz = 100;
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frequency_from_refreshrate
+ *
+ * This routine maps the refresh rate to the closest matching PLL frequency.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency)
+#else
+int
+gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency)
+#endif
+{
+ unsigned int index;
+ int retval = -1;
+ unsigned long hz_flag = 0;
+ unsigned long bpp_flag = 0;
+
+ *frequency = 0;
+
+ gfx_mode_hz_conversion gfx_mode_bpp_conversion_def(bpp)
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned short)xres) &&
+ (DisplayParams[index].vactive == (unsigned short)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].flags & hz_flag)) {
+ *frequency = DisplayParams[index].frequency;
+ retval = 1;
+ }
+ }
+ return retval;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_supported_pixel_clock
+ *
+ * This routine returns the maximum recommended speed for the pixel clock. The
+ * return value is an integer of the format xxxyyy, where xxx.yyy is the
+ * maximum floating point pixel clock speed.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_max_supported_pixel_clock(void)
+#else
+unsigned long
+gfx_get_max_supported_pixel_clock(void)
+#endif
+{
+ return 229500;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_mode
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns >0 if successful and mode returned, <0 if mode could not be found.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#else
+int
+gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#endif
+{
+ unsigned int mode = 0;
+ unsigned long pll_freq = 0, bpp_flag = 0;
+
+ *xres = gfx_get_hactive();
+ *yres = gfx_get_vactive();
+ *bpp = gfx_get_display_bpp();
+ pll_freq = gfx_get_clock_frequency();
+
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+ gfx_mode_bpp_conversion_def(*bpp)
+
+ for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
+ if ((DisplayParams[mode].hactive == (unsigned int)*xres) &&
+ (DisplayParams[mode].vactive == (unsigned int)*yres) &&
+ (DisplayParams[mode].frequency == pll_freq) &&
+ (DisplayParams[mode].flags & bpp_flag)) {
+
+ pll_freq = DisplayParams[mode].flags;
+
+ if (pll_freq & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (pll_freq & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (pll_freq & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (pll_freq & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (pll_freq & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (pll_freq & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (pll_freq & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (pll_freq & GFX_MODE_100HZ)
+ *hz = 100;
+
+ return (1);
+ }
+ }
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_DETAILS
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be get.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#else
+int
+gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#endif
+{
+ if (mode < NUM_RC_DISPLAY_MODES) {
+ if (DisplayParams[mode].flags & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (DisplayParams[mode].flags & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (DisplayParams[mode].flags & GFX_MODE_100HZ)
+ *hz = 100;
+
+ *xres = DisplayParams[mode].hactive;
+ *yres = DisplayParams[mode].vactive;
+
+ if (DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE)
+ *xres >>= 1;
+ if (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE)
+ *yres >>= 1;
+
+ return (1);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_MODE_COUNT
+ *
+ * This routine gets the number of available display modes.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_display_mode_count(void)
+#else
+int
+gfx_get_display_mode_count(void)
+#endif
+{
+ return (NUM_RC_DISPLAY_MODES);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_line_size
+ *
+ * Returns the current frame buffer line size, in bytes
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_frame_buffer_line_size(void)
+#else
+unsigned long
+gfx_get_frame_buffer_line_size(void)
+#endif
+{
+ return ((READ_REG32(MDC_LINE_SIZE) & 0x7FF) << 3);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_hactive(void)
+#else
+unsigned short
+gfx_get_hactive(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(MDC_H_ACTIVE_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_hsync_start(void)
+#else
+unsigned short
+gfx_get_hsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(MDC_H_SYNC_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_hsync_end(void)
+#else
+unsigned short
+gfx_get_hsync_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(MDC_H_SYNC_TIMING) >> 16) & 0x0FF8)
+ + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_htotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_htotal(void)
+#else
+unsigned short
+gfx_get_htotal(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(MDC_H_ACTIVE_TIMING) >> 16) &
+ 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_vactive(void)
+#else
+unsigned short
+gfx_get_vactive(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(MDC_V_ACTIVE_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_vsync_end(void)
+#else
+unsigned short
+gfx_get_vsync_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(MDC_V_SYNC_TIMING) >> 16) & 0x07FF)
+ + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vtotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_vtotal(void)
+#else
+unsigned short
+gfx_get_vtotal(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(MDC_V_ACTIVE_TIMING) >> 16) &
+ 0x07FF) + 1));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_bpp
+ *
+ * This routine returns the current color depth of the active display.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_display_bpp(void)
+#else
+unsigned short
+gfx_get_display_bpp(void)
+#endif
+{
+ unsigned long dcfg = READ_REG32(MDC_DISPLAY_CFG);
+
+ switch ((dcfg & MDC_DCFG_DISP_MODE_MASK) >> 8) {
+ case 0:
+ return (8);
+ case 2:
+ return (32);
+ case 1:
+ switch ((dcfg & MDC_DCFG_16BPP_MODE_MASK) >> 10) {
+ case 0:
+ return (16);
+ case 1:
+ return (15);
+ case 2:
+ return (12);
+ default:
+ return (0);
+ }
+ }
+
+ /* INVALID SETTING */
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vline
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_vline(void)
+#else
+unsigned short
+gfx_get_vline(void)
+#endif
+{
+ unsigned short current_scan_line;
+
+ /* Read similar value twice to ensure that the value is not
+ * transitioning */
+ do
+ current_scan_line =
+ (unsigned short)(READ_REG32(MDC_LINE_CNT_STATUS) &
+ MDC_LNCNT_V_LINE_CNT);
+ while (current_scan_line !=
+ (unsigned short)(READ_REG32(MDC_LINE_CNT_STATUS) &
+ MDC_LNCNT_V_LINE_CNT));
+
+ return (current_scan_line >> 16);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_display_offset(void)
+#else
+unsigned long
+gfx_get_display_offset(void)
+#endif
+{
+ return (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_cursor_offset(void)
+#else
+unsigned long
+gfx_get_cursor_offset(void)
+#endif
+{
+ return (READ_REG32(MDC_CURS_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+#if GFX_READ_ROUTINES
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_hblank_start(void)
+#else
+unsigned short
+gfx_get_hblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(MDC_H_BLANK_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_hblank_end(void)
+#else
+unsigned short
+gfx_get_hblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(MDC_H_BLANK_TIMING) >> 16) & 0x0FF8)
+ + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_vblank_start(void)
+#else
+unsigned short
+gfx_get_vblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(MDC_V_BLANK_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_vsync_start(void)
+#else
+unsigned short
+gfx_get_vsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(MDC_V_SYNC_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_vblank_end(void)
+#else
+unsigned short
+gfx_get_vblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(MDC_V_BLANK_TIMING) >> 16) & 0x07FF)
+ + 1));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_palette_entry
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int
+gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(MDC_PAL_ADDRESS, index);
+ *palette = READ_REG32(MDC_PAL_DATA);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_palette
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_get_display_palette(unsigned long *palette)
+#else
+void
+gfx_get_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i;
+
+ WRITE_REG32(MDC_PAL_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ palette[i] = READ_REG32(MDC_PAL_DATA);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_enable
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_cursor_enable(void)
+#else
+unsigned long
+gfx_get_cursor_enable(void)
+#endif
+{
+ return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CURE);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_position
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_cursor_position(void)
+#else
+unsigned long
+gfx_get_cursor_position(void)
+#endif
+{
+ return ((READ_REG32(MDC_CURSOR_X) & 0x07FF) |
+ ((READ_REG32(MDC_CURSOR_Y) << 16) & 0x07FF0000));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_cursor_clip(void)
+#else
+unsigned long
+gfx_get_cursor_clip(void)
+#endif
+{
+ return (((READ_REG32(MDC_CURSOR_X) >> 11) & 0x03F) |
+ ((READ_REG32(MDC_CURSOR_Y) << 5) & 0x3F0000));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_color
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_cursor_color(int color)
+#else
+unsigned long
+gfx_get_cursor_color(int color)
+#endif
+{
+ if (color) {
+ WRITE_REG32(MDC_PAL_ADDRESS, 0x101);
+ } else {
+ WRITE_REG32(MDC_PAL_ADDRESS, 0x100);
+ }
+ return READ_REG32(MDC_PAL_DATA);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_icon_enable
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_icon_enable(void)
+#else
+unsigned long
+gfx_get_icon_enable(void)
+#endif
+{
+ return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_ICNE);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_icon_offset
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_icon_offset(void)
+#else
+unsigned long
+gfx_get_icon_offset(void)
+#endif
+{
+ return (READ_REG32(MDC_ICON_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_icon_position
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_icon_position(void)
+#else
+unsigned long
+gfx_get_icon_position(void)
+#endif
+{
+ return (READ_REG32(MDC_ICON_X) & 0x07FF);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_icon_color
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_icon_color(int color)
+#else
+unsigned long
+gfx_get_icon_color(int color)
+#endif
+{
+ if (color >= 3)
+ return 0;
+
+ WRITE_REG32(MDC_PAL_ADDRESS, 0x102 + color);
+
+ return READ_REG32(MDC_PAL_DATA);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_enable
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_compression_enable(void)
+#else
+int
+gfx_get_compression_enable(void)
+#endif
+{
+ if (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CMPE)
+ return (1);
+
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_offset
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_compression_offset(void)
+#else
+unsigned long
+gfx_get_compression_offset(void)
+#endif
+{
+ return (READ_REG32(MDC_CB_ST_OFFSET) & 0x007FFFFF);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_pitch
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_compression_pitch(void)
+#else
+unsigned short
+gfx_get_compression_pitch(void)
+#endif
+{
+ unsigned short pitch;
+
+ pitch = (unsigned short)(READ_REG32(MDC_GFX_PITCH) >> 16);
+ return (pitch << 3);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_size
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu2_get_compression_size(void)
+#else
+unsigned short
+gfx_get_compression_size(void)
+#endif
+{
+ unsigned short size;
+
+ size = (unsigned short)((READ_REG32(MDC_LINE_SIZE) >> 16) & 0x7F) - 1;
+ return ((size << 3) + 32);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_valid_bit
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_valid_bit(int line)
+#else
+int
+gfx_get_valid_bit(int line)
+#endif
+{
+ unsigned long offset;
+ int valid;
+
+ offset = READ_REG32(MDC_PHY_MEM_OFFSET) & 0xFF000000;
+ offset |= line;
+
+ WRITE_REG32(MDC_PHY_MEM_OFFSET, offset);
+ valid = (int)READ_REG32(MDC_DV_ACC) & 2;
+
+ if (valid)
+ return 1;
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_display_video_offset(void)
+#else
+unsigned long
+gfx_get_display_video_offset(void)
+#endif
+{
+ return (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_yuv_offsets". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_get_display_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset)
+#else
+void
+gfx_get_display_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset)
+#endif
+{
+ *yoffset = (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
+ *uoffset = (READ_REG32(MDC_VID_U_ST_OFFSET) & 0x0FFFFFFF);
+ *voffset = (READ_REG32(MDC_VID_V_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_yuv_pitch". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu2_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#else
+void
+gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#endif
+{
+ unsigned long pitch = READ_REG32(MDC_VID_YUV_PITCH);
+
+ *ypitch = ((pitch & 0xFFFF) << 3);
+ *uvpitch = (pitch >> 13) & 0x7FFF8;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_downscale_delta (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_downscale_delta". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_display_video_downscale_delta(void)
+#else
+unsigned long
+gfx_get_display_video_downscale_delta(void)
+#endif
+{
+ return (READ_REG32(MDC_VID_DS_DELTA) >> 18);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_vertical_downscale_enable".
+ * It abstracts the version of the display controller from the video overlay
+ * routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu2_get_display_video_downscale_enable(void)
+#else
+int
+gfx_get_display_video_downscale_enable(void)
+#endif
+{
+ return ((int)((READ_REG32(MDC_GENERAL_CFG) >> 19) & 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu2_get_display_video_size(void)
+#else
+unsigned long
+gfx_get_display_video_size(void)
+#endif
+{
+ /* RETURN THE LINE SIZE, AS THIS IS ALL THAT IS AVAILABLE */
+
+ return ((READ_REG32(MDC_LINE_SIZE) >> 21) & 0x000007FF);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/disp_gu3.c b/src/gfx/disp_gu3.c
new file mode 100644
index 0000000..8fdbb27
--- /dev/null
+++ b/src/gfx/disp_gu3.c
@@ -0,0 +1,2603 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ */
+
+/*
+ * This file contains routines for the second generation display controller.
+ * */
+
+void gu3_enable_compression(void); /* private routine definition */
+void gu3_disable_compression(void); /* private routine definition */
+int gfx_set_display_control(int sync_polarities); /* private routine definition */
+void gfx_reset_video(void);
+int gu3_set_specified_mode(DISPLAYMODE * pMode, int bpp);
+
+ /*---------------------------------------------------------------------------
+ * WARNING!!!! INACCURATE DELAY MECHANISM
+ *
+ * In an effort to keep the code self contained and operating system
+ * independent, the delay loop just performs reads of a display controller
+ * register. This time will vary for faster processors. The delay can always
+ * be longer than intended, only effecting the time of the mode switch
+ * (obviously want it to still be under a second). Problems with the hardware
+ * only arise if the delay is not long enough.
+ *----------------------------------------------------------------------------
+ */
+
+#define CSTL_READS_PER_MILLISECOND 15000L
+
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_delay_milliseconds(unsigned long milliseconds)
+#else
+void
+gfx_delay_milliseconds(unsigned long milliseconds)
+#endif
+{
+ /* ASSUME 300 MHZ 20 CLOCKS PER READ */
+
+ unsigned long loop;
+
+ loop = milliseconds * CSTL_READS_PER_MILLISECOND;
+ while (loop-- > 0) {
+ READ_REG32(DC3_UNLOCK);
+ }
+}
+
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_delay_microseconds(unsigned long microseconds)
+#else
+void
+gfx_delay_microseconds(unsigned long microseconds)
+#endif
+{
+ /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */
+
+ unsigned long loop_count = microseconds * 15;
+
+ while (loop_count-- > 0) {
+ READ_REG32(DC3_UNLOCK);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_BPP
+ *
+ * This routine programs the bpp in the display controller.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_display_bpp(unsigned short bpp)
+#else
+int
+gfx_set_display_bpp(unsigned short bpp)
+#endif
+{
+ unsigned long dcfg, lock;
+
+ dcfg =
+ READ_REG32(DC3_DISPLAY_CFG) & ~(DC3_DCFG_DISP_MODE_MASK |
+ DC3_DCFG_16BPP_MODE_MASK);
+ lock = READ_REG32(DC3_UNLOCK);
+
+ switch (bpp) {
+ case 12:
+ dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP);
+ break;
+ case 15:
+ dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP);
+ break;
+ case 16:
+ dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP);
+ break;
+ case 32:
+ dcfg |= (DC3_DCFG_DISP_MODE_24BPP);
+ break;
+ case 8:
+ dcfg |= (DC3_DCFG_DISP_MODE_8BPP);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32(DC3_UNLOCK, lock);
+
+ /* SET BPP IN GRAPHICS PIPELINE */
+
+ gfx_set_bpp(bpp);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * gu3_set_specified_mode (private routine)
+ * This routine uses the parameters in the specified display mode structure
+ * to program the display controller hardware.
+ *----------------------------------------------------------------------------
+ */
+int
+gu3_set_specified_mode(DISPLAYMODE * pMode, int bpp)
+{
+ Q_WORD msr_value;
+ unsigned long unlock, value;
+ unsigned long acfg, gcfg, dcfg;
+ unsigned long size, pitch;
+ unsigned long bpp_mask, temp, dv_size;
+
+ /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
+ /* Flag used for locking also overrides timing change restriction */
+
+ if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
+ return GFX_STATUS_ERROR;
+
+ /* CLEAR PANNING OFFSETS */
+
+ DeltaX = 0;
+ DeltaY = 0;
+ panelLeft = 0;
+ panelTop = 0;
+
+ /* SET GLOBAL FLAG */
+
+ if (pMode->flags & GFX_MODE_LOCK_TIMING)
+ gfx_timing_lock = 1;
+
+ /* CHECK FOR VALID BPP */
+ /* As this function can be called directly from */
+ /* gfx_set_display_timings, we must correct any */
+ /* invalid bpp settings. */
+
+ switch (bpp) {
+ case 12:
+ bpp_mask = 0x00000900;
+ break;
+ case 15:
+ bpp_mask = 0x00000500;
+ break;
+ case 16:
+ bpp_mask = 0x00000100;
+ break;
+ case 32:
+ bpp_mask = 0x00000200;
+ break;
+ default:
+ bpp_mask = 0x00000000;
+ bpp = 8;
+ break;
+ }
+
+ gbpp = bpp;
+
+ /* DISABLE COMPRESSION */
+
+ gu3_disable_compression();
+
+ /* ALSO DISABLE VIDEO */
+ /* Use private "reset video" routine to do all that is needed. */
+ /* SC1200, for example, also disables the alpha blending regions. */
+
+ gfx_reset_video();
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* READ THE CURRENT REGISTER VALUES */
+
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ dcfg = READ_REG32(DC3_DISPLAY_CFG);
+
+ /* BLANK THE DISPLAY IN THE DISPLAY FILTER */
+
+ gfx_set_crt_enable(0);
+
+ /* DISABLE THE TIMING GENERATOR */
+
+ dcfg &= ~(unsigned long)DC3_DCFG_TGEN;
+ WRITE_REG32(DC3_DISPLAY_CFG, dcfg);
+
+ /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */
+ /* This delay is used to make sure that all pending requests to the */
+ /* memory controller have completed before disabling the FIFO load. */
+
+ gfx_delay_milliseconds(1);
+
+ /* DISABLE DISPLAY FIFO LOAD */
+
+ gcfg &= ~(unsigned long)DC3_GCFG_DFLE;
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+
+ /* PRESERVE VIDEO INFORMATION */
+
+ gcfg &= (unsigned long)(DC3_GCFG_YUVM | DC3_GCFG_VDSE);
+ dcfg = 0;
+
+ /* DISABLE VGA */
+ /* VGA *MUST* be turned off before TGEN is enabled. If not, a condition
+ * will result where VGA Enable is waiting for a VSync to be latched but
+ * a VSync will not be generated until VGA is disabled.
+ * */
+
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+
+ /* SET THE DOT CLOCK FREQUENCY */
+ /* Mask off the divide by two bit (bit 31) */
+
+ gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
+
+ /* DELAY: WAIT FOR THE PLL TO SETTLE */
+ /* This allows the dot clock frequency that was just set to settle. */
+
+ gfx_delay_milliseconds(1);
+
+ /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
+
+ WRITE_REG32(DC3_FB_ST_OFFSET, 0);
+ WRITE_REG32(DC3_CB_ST_OFFSET, 0);
+ WRITE_REG32(DC3_CURS_ST_OFFSET, 0);
+
+ /* SET LINE SIZE AND PITCH */
+ /* 1. Flat Panels must use the mode width and not */
+ /* the timing width to set the pitch. */
+ /* 2. Mode sets will use a pitch that is aligned */
+ /* on a 1K boundary to preserve legacy. The */
+ /* pitch can be overridden by a subsequent call */
+ /* to gfx_set_display_pitch. */
+
+ if (PanelEnable)
+ size = ModeWidth;
+ else
+ size = pMode->hactive;
+
+ if (bpp > 8)
+ size <<= 1;
+ if (bpp > 16)
+ size <<= 1;
+
+ pitch = 1024;
+ dv_size = DC3_DV_LINE_SIZE_1024;
+
+ if (size > 1024) {
+ pitch = 2048;
+ dv_size = DC3_DV_LINE_SIZE_2048;
+ }
+
+ if (size > 2048) {
+ pitch = 4096;
+ dv_size = DC3_DV_LINE_SIZE_4096;
+ }
+
+ if (size > 4096) {
+ pitch = 8192;
+ dv_size = DC3_DV_LINE_SIZE_8192;
+ }
+
+ WRITE_REG32(DC3_GFX_PITCH, pitch >> 3);
+
+ /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */
+
+ temp = READ_REG32(DC3_DV_CTL);
+ WRITE_REG32(DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dv_size);
+
+ if (PanelEnable) {
+ size = pMode->hactive;
+ if (bpp > 8)
+ size <<= 1;
+ if (bpp > 16)
+ size <<= 1;
+ }
+
+ WRITE_REG32(DC3_LINE_SIZE, ((size >> 3)));
+
+ /* ALWAYS ENABLE VIDEO AND GRAPHICS DATA */
+ /* These bits are relics from a previous design and */
+ /* should always be enabled. */
+
+ dcfg |= (unsigned long)(DC3_DCFG_VDEN | DC3_DCFG_GDEN);
+
+ /* SET PIXEL FORMAT */
+
+ dcfg |= bpp_mask;
+
+ /* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
+ /* AND VERT. INT. SELECT */
+
+ dcfg |=
+ (unsigned long)(DC3_DCFG_TGEN | DC3_DCFG_TRUP | DC3_DCFG_PALB |
+ DC3_DCFG_VISL);
+
+ /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */
+
+ gcfg |= 0x0000BA01;
+ dcfg |= 0x000EA000;
+ acfg = 0x001A0000;
+
+ /* SET THE DISPLAY CHARACTERISTICS FOR HIGH BANDWIDTH CASES */
+
+ gfx_msr_read(RC_ID_VG, DC3_VG_SPARE_MSR, &msr_value);
+ msr_value.low &=
+ ~(VG_SPARE_DISABLE_CFIFO_HGO | VG_SPARE_VFIFO_ARB_SELECT |
+ VG_SPARE_LOAD_WM_LPEN_MASK | VG_SPARE_WM_LPEN_OVRD |
+ VG_SPARE_DISABLE_INIT_VID_PRI | VG_SPARE_DISABLE_VFIFO_WM);
+ msr_value.low |= VG_SPARE_DISABLE_CFIFO_HGO | VG_SPARE_VFIFO_ARB_SELECT;
+ gfx_msr_write(RC_ID_VG, DC3_VG_SPARE_MSR, &msr_value);
+ WRITE_REG32(DC3_ARB_CFG, acfg);
+
+ /* ENABLE FLAT PANEL CENTERING */
+ /* For panel modes having a resolution smaller than the */
+ /* panel resolution, turn on data centering. */
+
+ if (PanelEnable && ModeWidth < PanelWidth)
+ dcfg |= DC3_DCFG_DCEN;
+
+ /* SET THE GRAPHICS SCALE */
+ /* We do not support graphics scaling, but we need to ensure that the */
+ /* scale is set correctly none the less. */
+
+ WRITE_REG32(DC3_GFX_SCALE, 0x40004000);
+ WRITE_REG32(DC3_IRQ_CTL, 0);
+
+ /* COMBINE AND SET TIMING VALUES */
+
+ value = (unsigned long)(pMode->hactive - 1) |
+ (((unsigned long)(pMode->htotal - 1)) << 16);
+ WRITE_REG32(DC3_H_ACTIVE_TIMING, value);
+ value = (unsigned long)(pMode->hblankstart - 1) |
+ (((unsigned long)(pMode->hblankend - 1)) << 16);
+ WRITE_REG32(DC3_H_BLANK_TIMING, value);
+ value = (unsigned long)(pMode->hsyncstart - 1) |
+ (((unsigned long)(pMode->hsyncend - 1)) << 16);
+ WRITE_REG32(DC3_H_SYNC_TIMING, value);
+ value = (unsigned long)(pMode->vactive - 1) |
+ (((unsigned long)(pMode->vtotal - 1)) << 16);
+ WRITE_REG32(DC3_V_ACTIVE_TIMING, value);
+ value = (unsigned long)(pMode->vblankstart - 1) |
+ (((unsigned long)(pMode->vblankend - 1)) << 16);
+ WRITE_REG32(DC3_V_BLANK_TIMING, value);
+ value = (unsigned long)(pMode->vsyncstart - 1) |
+ (((unsigned long)(pMode->vsyncend - 1)) << 16);
+ WRITE_REG32(DC3_V_SYNC_TIMING, value);
+
+ WRITE_REG32(DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+
+ /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+
+ gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
+ ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
+
+ /* RESTORE VALUE OF DC3_UNLOCK */
+
+ WRITE_REG32(DC3_UNLOCK, unlock);
+
+ /* RESET THE PITCH VALUES IN THE GP */
+
+ gfx_reset_pitch((unsigned short)pitch);
+
+ gfx_set_bpp((unsigned short)bpp);
+
+ return GFX_STATUS_OK;
+}
+
+ /*---------------------------------------------------------------------------
+ * GFX_IS_DISPLAY_MODE_SUPPORTED
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#else
+int
+gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#endif
+{
+ unsigned int mode;
+ unsigned long hz_flag = 0, bpp_flag = 0;
+
+ /* SET FLAGS TO MATCH REFRESH RATE */
+ gfx_mode_hz_conversion
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+ gfx_mode_bpp_conversion
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
+ if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
+ (DisplayParams[mode].vactive == (unsigned short)yres) &&
+ (DisplayParams[mode].flags & hz_flag) &&
+ (DisplayParams[mode].flags & bpp_flag)) {
+
+ /* CASTLE DOES NOT SUPPORT EMULATED VGA MODES */
+
+ if ((DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) ||
+ (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE))
+ continue;
+
+ /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
+
+ return (mode);
+ }
+ }
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_display_mode
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_display_mode(int xres, int yres, int bpp, int hz)
+#else
+int
+gfx_set_display_mode(int xres, int yres, int bpp, int hz)
+#endif
+{
+ int mode;
+
+ /* DISABLE FLAT PANEL */
+ /* Flat Panel settings are enabled by the function gfx_set_fixed_timings
+ * and disabled by gfx_set_display_mode.
+ * */
+
+ PanelEnable = 0;
+
+ mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
+ if (mode >= 0) {
+ if (gu3_set_specified_mode(&DisplayParams[mode],
+ bpp) == GFX_STATUS_OK)
+ return (1);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_TIMINGS
+ *
+ * This routine sets the display controller mode using the specified timing
+ * values (as opposed to using the tables internal to Durango).
+ *
+ * Returns GFX_STATUS_OK ON SUCCESS, GFX_STATUS_ERROR otherwise.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
+#else
+int
+gfx_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
+#endif
+{
+ /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
+
+ gfx_display_mode.flags = 0;
+ if (flags & 1)
+ gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
+ if (flags & 2)
+ gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
+ if (flags & 0x1000)
+ gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
+ gfx_display_mode.hactive = hactive;
+ gfx_display_mode.hblankstart = hblankstart;
+ gfx_display_mode.hsyncstart = hsyncstart;
+ gfx_display_mode.hsyncend = hsyncend;
+ gfx_display_mode.hblankend = hblankend;
+ gfx_display_mode.htotal = htotal;
+ gfx_display_mode.vactive = vactive;
+ gfx_display_mode.vblankstart = vblankstart;
+ gfx_display_mode.vsyncstart = vsyncstart;
+ gfx_display_mode.vsyncend = vsyncend;
+ gfx_display_mode.vblankend = vblankend;
+ gfx_display_mode.vtotal = vtotal;
+ gfx_display_mode.frequency = frequency;
+
+ /* CALL ROUTINE TO SET MODE */
+
+ return (gu3_set_specified_mode(&gfx_display_mode, bpp));
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_VTOTAL
+ *
+ * This routine sets the display controller vertical total to
+ * "vtotal". As a side effect it also sets vertical blank end.
+ * It should be used when only this value needs to be changed,
+ * due to speed considerations.
+ *
+ * Note: it is the caller's responsibility to make sure that
+ * a legal vtotal is used, i.e. that "vtotal" is greater than or
+ * equal to vsync end.
+ *
+ * Always returns 0.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_vtotal(unsigned short vtotal)
+#else
+int
+gfx_set_vtotal(unsigned short vtotal)
+#endif
+{
+ unsigned long unlock, dcfg, vactive, vblank;
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* READ THE CURRENT RC VALUES */
+
+ dcfg = READ_REG32(DC3_DISPLAY_CFG);
+ vactive = READ_REG32(DC3_V_ACTIVE_TIMING);
+ vblank = READ_REG32(DC3_V_BLANK_TIMING);
+
+ /* DISABLE TIMING REGISTER UPDATES */
+
+ WRITE_REG32(DC3_DISPLAY_CFG, dcfg & ~(unsigned long)DC3_DCFG_TRUP);
+
+ /* WRITE NEW TIMING VALUES */
+
+ WRITE_REG32(DC3_V_ACTIVE_TIMING,
+ (vactive & DC3_VAT_VA_MASK) | (unsigned long)(vtotal - 1) << 16);
+ WRITE_REG32(DC3_V_BLANK_TIMING,
+ (vblank & DC3_VBT_VBS_MASK) | (unsigned long)(vtotal - 1) << 16);
+
+ /* RESTORE OLD RC VALUES */
+
+ WRITE_REG32(DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32(DC3_UNLOCK, unlock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_pitch
+ *
+ * This routine sets the pitch of the frame buffer to the specified value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_pitch(unsigned short pitch)
+#else
+void
+gfx_set_display_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long value = 0;
+ unsigned long lock = READ_REG32(DC3_UNLOCK);
+
+ value = READ_REG32(DC3_GFX_PITCH) & 0xFFFF0000;
+ value |= (pitch >> 3);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GFX_PITCH, value);
+
+ /* SET RENDERING PITCHES TO MATCH */
+
+ gfx_reset_pitch(pitch);
+
+ /* SET THE FRAME DIRTY MODE */
+ /* Non-standard pitches, i.e. pitches that */
+ /* are not 1K, 2K or 4K must mark the entire */
+ /* frame as dirty when writing to the frame */
+ /* buffer. */
+
+ value = READ_REG32(DC3_GENERAL_CFG);
+
+ if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
+ value &= ~(unsigned long)(DC3_GCFG_FDTY);
+ else
+ value |= (unsigned long)(DC3_GCFG_FDTY);
+
+ WRITE_REG32(DC3_GENERAL_CFG, value);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_offset
+ *
+ * This routine sets the start address of the frame buffer. It is
+ * typically used to pan across a virtual desktop (frame buffer larger than
+ * the displayed screen) or to flip the display between multiple buffers.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_offset(unsigned long offset)
+#else
+void
+gfx_set_display_offset(unsigned long offset)
+#endif
+{
+ /* UPDATE FRAME BUFFER OFFSET */
+ unsigned long lock;
+
+ lock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
+ /* Disable compression for non-zero start addresss values. */
+ /* Enable compression if offset is zero and comression is intended to */
+ /* be enabled from a previous call to "gfx_set_compression_enable". */
+ /* Compression should be disabled BEFORE the offset is changed */
+ /* and enabled AFTER the offset is changed. */
+
+ if (offset == 0) {
+ WRITE_REG32(DC3_FB_ST_OFFSET, offset);
+ if (gfx_compression_enabled) {
+ /* WAIT FOR THE OFFSET TO BE LATCHED */
+ gfx_wait_vertical_blank();
+ gu3_enable_compression();
+ }
+ } else {
+ /* ONLY DISABLE COMPRESSION ONCE */
+
+ if (gfx_compression_active)
+ gu3_disable_compression();
+
+ WRITE_REG32(DC3_FB_ST_OFFSET, offset);
+ }
+
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette_entry
+ *
+ * This routine sets an palette entry in the display controller.
+ * A 32-bit X:R:G:B value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_display_palette_entry(unsigned long index, unsigned long palette)
+#else
+int
+gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(DC3_PAL_ADDRESS, index);
+ WRITE_REG32(DC3_PAL_DATA, palette);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette
+ *
+ * This routine sets the entire palette in the display controller.
+ * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_display_palette(unsigned long *palette)
+#else
+int
+gfx_set_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i;
+
+ WRITE_REG32(DC3_PAL_ADDRESS, 0);
+
+ if (palette) {
+ for (i = 0; i < 256; i++) {
+ WRITE_REG32(DC3_PAL_DATA, palette[i]);
+ }
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_enable
+ *
+ * This routine enables or disables the hardware cursor.
+ *
+ * WARNING: The cursor start offset must be set by setting the cursor
+ * position before calling this routine to assure that memory reads do not
+ * go past the end of graphics memory (this can hang GXm).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_cursor_enable(int enable)
+#else
+void
+gfx_set_cursor_enable(int enable)
+#endif
+{
+ unsigned long unlock, gcfg;
+
+ /* SET OR CLEAR CURSOR ENABLE BIT */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ if (enable)
+ gcfg |= DC3_GCFG_CURE;
+ else
+ gcfg &= ~(DC3_GCFG_CURE);
+
+ /* WRITE NEW REGISTER VALUE */
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_colors
+ *
+ * This routine sets the colors of the hardware cursor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#else
+void
+gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#endif
+{
+ /* SET CURSOR COLORS */
+
+ WRITE_REG32(DC3_PAL_ADDRESS, 0x100);
+ WRITE_REG32(DC3_PAL_DATA, bkcolor);
+ WRITE_REG32(DC3_PAL_DATA, fgcolor);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_position
+ *
+ * This routine sets the position of the hardware cusror. The starting
+ * offset of the cursor buffer must be specified so that the routine can
+ * properly clip scanlines if the cursor is off the top of the screen.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#else
+void
+gfx_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#endif
+{
+ unsigned long unlock;
+
+ short x = (short)xpos - (short)xhotspot;
+ short y = (short)ypos - (short)yhotspot;
+ short xoffset = 0;
+ short yoffset = 0;
+
+ if (x < -63)
+ return;
+ if (y < -63)
+ return;
+
+ if (PanelEnable) {
+ if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
+ gfx_enable_panning(xpos, ypos);
+ x = x - (unsigned short)panelLeft;
+ y = y - (unsigned short)panelTop;
+ }
+ }
+
+ /* ADJUST OFFSETS */
+ /* Cursor movement and panning work as follows: The cursor position */
+ /* refers to where the hotspot of the cursor is located. However, for */
+ /* non-zero hotspots, the cursor buffer actually begins before the */
+ /* specified position. */
+
+ if (x < 0) {
+ xoffset = -x;
+ x = 0;
+ }
+ if (y < 0) {
+ yoffset = -y;
+ y = 0;
+ }
+ memoffset += (unsigned long)yoffset << 4;
+
+ /* SET CURSOR POSITION */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_CURS_ST_OFFSET, memoffset);
+ WRITE_REG32(DC3_CURSOR_X, (unsigned long)x |
+ (((unsigned long)xoffset) << 11));
+ WRITE_REG32(DC3_CURSOR_Y, (unsigned long)y |
+ (((unsigned long)yoffset) << 11));
+ WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape32
+ *
+ * This routine loads 32x32 cursor data into the cursor buffer in graphics
+ * memory.
+ * As the Castle cursor is actually 64x64, we must pad the outside of the
+ * cursor data with transparent pixels.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#else
+void
+gfx_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+
+ WRITE_FB32(memoffset, 0xFFFFFFFF);
+ WRITE_FB32(memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+
+ WRITE_FB32(memoffset + 8, 0x00000000);
+ WRITE_FB32(memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+
+ /* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
+
+ for (i = 0; i < 32; i++) {
+ WRITE_FB32(memoffset, 0xFFFFFFFF);
+ WRITE_FB32(memoffset + 4, 0xFFFFFFFF);
+ WRITE_FB32(memoffset + 8, 0x00000000);
+ WRITE_FB32(memoffset + 12, 0x00000000);
+
+ memoffset += 16;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape64
+ *
+ * This routine loads 64x64 cursor data into the cursor buffer in graphics
+ * memory.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#else
+void
+gfx_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+ int i;
+
+ for (i = 0; i < 128; i += 2) {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+ /* We invert the dwords to prevent the calling */
+ /* application from having to think in terms of Qwords. */
+ /* The hardware data order is actually 63:0, or 31:0 of */
+ /* the second dword followed by 31:0 of the first dword. */
+
+ WRITE_FB32(memoffset, andmask[i + 1]);
+ WRITE_FB32(memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+
+ WRITE_FB32(memoffset + 8, xormask[i + 1]);
+ WRITE_FB32(memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gu3_enable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It enables display compression.
+ *---------------------------------------------------------------------------
+ */
+void
+gu3_enable_compression(void)
+{
+ unsigned long unlock, gcfg, temp;
+
+ /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
+
+ if (READ_REG32(DC3_FB_ST_OFFSET) & 0x0FFFFFFF)
+ return;
+
+ /* SET GLOBAL INDICATOR */
+
+ gfx_compression_active = 1;
+
+ /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
+ /* Software is required to do this before enabling compression. */
+ /* Don't want controller to think that old lines are still valid. */
+ /* Writing a 1 to bit 0 of the DV Control register will force the */
+ /* hardware to clear all the valid bits. */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ temp = READ_REG32(DC3_DV_CTL);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_DV_CTL, temp | 0x00000001);
+
+ /* TURN ON COMPRESSION CONTROL BITS */
+
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ gcfg |= DC3_GCFG_CMPE | DC3_GCFG_DECE;
+
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gu3_disable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It disables display compression.
+ *---------------------------------------------------------------------------
+ */
+void
+gu3_disable_compression(void)
+{
+ unsigned long unlock, gcfg;
+
+ /* SET GLOBAL INDICATOR */
+
+ gfx_compression_active = 0;
+
+ /* TURN OFF COMPRESSION CONTROL BITS */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ gcfg &= ~(DC3_GCFG_CMPE | DC3_GCFG_DECE);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_enable
+ *
+ * This routine enables or disables display compression.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_compression_enable(int enable)
+#else
+int
+gfx_set_compression_enable(int enable)
+#endif
+{
+ /* SET GLOBAL VARIABLE FOR INDENDED STATE */
+ /* Compression can only be enabled for non-zero start address values. */
+ /* Keep state to enable compression on start address changes. */
+
+ gfx_compression_enabled = enable;
+ if (enable)
+ gu3_enable_compression();
+ else
+ gu3_disable_compression();
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_offset
+ *
+ * This routine sets the base offset for the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_compression_offset(unsigned long offset)
+#else
+int
+gfx_set_compression_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ /* MUST BE 16-BYTE ALIGNED FOR CASTLE */
+
+ if (offset & 0x0F)
+ return (1);
+
+ /* SET REGISTER VALUE */
+
+ lock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_CB_ST_OFFSET, offset & 0x0FFFFFFF);
+ WRITE_REG32(DC3_UNLOCK, lock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_pitch
+ *
+ * This routine sets the pitch, in bytes, of the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_compression_pitch(unsigned short pitch)
+#else
+int
+gfx_set_compression_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long lock, line_delta;
+
+ lock = READ_REG32(DC3_UNLOCK);
+
+ /* SET REGISTER VALUE */
+
+ line_delta = READ_REG32(DC3_GFX_PITCH) & 0x0000FFFF;
+ line_delta |= (((unsigned long)pitch << 13) & 0xFFFF0000);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GFX_PITCH, line_delta);
+ WRITE_REG32(DC3_UNLOCK, lock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_size
+ *
+ * This routine sets the line size of the compression buffer, which is the
+ * maximum number of bytes allowed to store a compressed line.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_compression_size(unsigned short size)
+#else
+int
+gfx_set_compression_size(unsigned short size)
+#endif
+{
+ unsigned long lock, buf_size;
+
+ /* SUBTRACT 32 FROM SIZE */
+ /* The display controller will actually write */
+ /* 4 extra QWords. So, if we assume that "size" */
+ /* refers to the allocated size, we must subtract */
+ /* 32 bytes. */
+
+ size -= 32;
+
+ /* SET REGISTER VALUE */
+
+ lock = READ_REG32(DC3_UNLOCK);
+ buf_size = READ_REG32(DC3_LINE_SIZE) & ~DC3_LINE_SIZE_CBLS_MASK;
+ buf_size |=
+ ((((unsigned long)size >> 3) + 1) & 0x7F) << DC3_LINE_SIZE_CB_SHIFT;
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_LINE_SIZE, buf_size);
+ WRITE_REG32(DC3_UNLOCK, lock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_color_key (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_color_key". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_video_color_key(unsigned long key, unsigned long mask,
+ int enable)
+#else
+void
+gfx_set_display_video_color_key(unsigned long key, unsigned long mask,
+ int enable)
+#endif
+{
+ unsigned long colorkey = 0;
+ unsigned long lock;
+
+ if (enable)
+ colorkey = (key & 0xFFFFFF) | DC3_CLR_KEY_ENABLE;
+
+ lock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ WRITE_REG32(DC3_COLOR_KEY, colorkey);
+ WRITE_REG32(DC3_COLOR_MASK, (mask & 0xFFFFFF));
+
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_format". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_video_format(unsigned long format)
+#else
+void
+gfx_set_display_video_format(unsigned long format)
+#endif
+{
+ unsigned long gcfg, lock;
+
+ lock = READ_REG32(DC3_UNLOCK);
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+
+ switch (format) {
+ case VIDEO_FORMAT_Y0Y1Y2Y3:
+ case VIDEO_FORMAT_Y3Y2Y1Y0:
+ case VIDEO_FORMAT_Y1Y0Y3Y2:
+ case VIDEO_FORMAT_Y1Y2Y3Y0:
+ gcfg |= DC3_GCFG_YUVM;
+ break;
+
+ default:
+ gcfg &= ~DC3_GCFG_YUVM;
+ break;
+ }
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_enable". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_video_enable(int enable)
+#else
+void
+gfx_set_display_video_enable(int enable)
+#endif
+{
+ unsigned long lock, gcfg, dcfg;
+
+ /* READ CURRENT VALUES */
+
+ lock = READ_REG32(DC3_UNLOCK);
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ dcfg = READ_REG32(DC3_DISPLAY_CFG);
+
+ /* SET OR CLEAR VIDEO ENABLE IN GENERAL_CFG */
+
+ if (enable)
+ gcfg |= DC3_GCFG_VIDE;
+ else
+ gcfg &= ~DC3_GCFG_VIDE;
+
+ /* WRITE REGISTER */
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_video_size(unsigned short width, unsigned short height)
+#else
+void
+gfx_set_display_video_size(unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long lock, value, yuv_420;
+
+ /* READ CURRENT VALUES */
+
+ lock = READ_REG32(DC3_UNLOCK);
+ value = READ_REG32(DC3_LINE_SIZE) & ~DC3_LINE_SIZE_VLS_MASK;
+ yuv_420 = READ_REG32(DC3_GENERAL_CFG) & DC3_GCFG_YUVM;
+
+ /* LINE WIDTH IS 1/4 FOR 4:2:0 VIDEO */
+ /* All data must be 32-byte aligned. */
+
+ if (yuv_420) {
+ width >>= 1;
+ width = (width + 7) & 0xFFF8;
+ } else {
+ width <<= 1;
+ width = (width + 31) & 0xFFE0;
+ }
+
+ /* ONLY THE LINE SIZE IS PROGRAMMED IN THE DISPLAY CONTROLLER */
+ /* Shift by three less than the bit position to effect a divide by 8 */
+
+ value |=
+ ((unsigned long)width << (DC3_LINE_SIZE_VB_SHIFT -
+ 3)) & DC3_LINE_SIZE_VLS_MASK;
+
+ /* WRITE THE REGISTER */
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_LINE_SIZE, value);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_video_offset(unsigned long offset)
+#else
+void
+gfx_set_display_video_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ lock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ offset &= 0x0FFFFFF0;
+ WRITE_REG32(DC3_VID_Y_ST_OFFSET, offset);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by gfx_set_video_yuv_offsets. It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset)
+#else
+void
+gfx_set_display_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset)
+#endif
+{
+ unsigned long lock;
+
+ lock = READ_REG32(DC3_UNLOCK);
+
+ yoffset &= 0x0FFFFFF0;
+ uoffset &= 0x0FFFFFF8;
+ voffset &= 0x0FFFFFF8;
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_VID_Y_ST_OFFSET, yoffset);
+ WRITE_REG32(DC3_VID_U_ST_OFFSET, uoffset);
+ WRITE_REG32(DC3_VID_V_ST_OFFSET, voffset);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by gfx_set_video_yuv_pitch. It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#else
+void
+gfx_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#endif
+{
+ unsigned long lock, pitch;
+
+ lock = READ_REG32(DC3_UNLOCK);
+
+ pitch = ((uvpitch << 13) & 0xFFFF0000) | ((ypitch >> 3) & 0xFFFF);
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_VID_YUV_PITCH, pitch);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_timing_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_test_timing_active(void)
+#else
+int
+gfx_test_timing_active(void)
+#endif
+{
+ if (READ_REG32(DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_vertical_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_test_vertical_active(void)
+#else
+int
+gfx_test_vertical_active(void)
+#endif
+{
+ if (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA)
+ return (0);
+
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_wait_vertical_blank
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_wait_vertical_blank(void)
+#else
+int
+gfx_wait_vertical_blank(void)
+#endif
+{
+ if (gfx_test_timing_active()) {
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_panning
+ *
+ * This routine enables the panning when the Mode is bigger than the panel
+ * size.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_enable_panning(int x, int y)
+#else
+void
+gfx_enable_panning(int x, int y)
+#endif
+{
+ unsigned long modeBytesPerPixel;
+ unsigned long modeBytesPerScanline = 0;
+ unsigned long startAddress = 0;
+
+ modeBytesPerPixel = (gbpp + 7) / 8;
+ modeBytesPerScanline = (READ_REG32(DC3_GFX_PITCH) & 0x0000FFFF) << 3;
+
+ /* TEST FOR NO-WORK */
+
+ if (x >= DeltaX && x < ((int)PanelWidth + DeltaX) &&
+ y >= DeltaY && y < ((int)PanelHeight + DeltaY))
+ return;
+
+ /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */
+ /* Test the boundary conditions for each coordinate and update */
+ /* all variables and the starting offset accordingly. */
+
+ if (x < DeltaX)
+ DeltaX = x;
+
+ else if (x >= (DeltaX + (int)PanelWidth))
+ DeltaX = x - (int)PanelWidth + 1;
+
+ if (y < DeltaY)
+ DeltaY = y;
+
+ else if (y >= (DeltaY + (int)PanelHeight))
+ DeltaY = y - (int)PanelHeight + 1;
+
+ /* CALCULATE THE START OFFSET */
+
+ startAddress =
+ (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
+
+ gfx_set_display_offset(startAddress);
+
+ /* SET PANEL COORDINATES */
+ /* Panel's x position must be DWORD aligned */
+
+ panelTop = DeltaY;
+ panelLeft = DeltaX * modeBytesPerPixel;
+
+ if (panelLeft & 3)
+ panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
+
+ panelLeft /= modeBytesPerPixel;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_fixed_timings
+ *---------------------------------------------------------------------------
+ */
+
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#else
+int
+gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#endif
+{
+ unsigned int mode;
+
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
+ if ((FixedParams[mode].xres == width) &&
+ (FixedParams[mode].yres == height) &&
+ (FixedParams[mode].panelresx == panelResX) &&
+ (FixedParams[mode].panelresy == panelResY)) {
+
+ /* SET THE 92xx FOR THE SELECTED MODE */
+ FIXEDTIMINGS *fmode = &FixedParams[mode];
+
+ gfx_set_display_timings(bpp, 3, fmode->hactive,
+ fmode->hblankstart, fmode->hsyncstart, fmode->hsyncend,
+ fmode->hblankend, fmode->htotal, fmode->vactive,
+ fmode->vblankstart, fmode->vsyncstart, fmode->vsyncend,
+ fmode->vblankend, fmode->vtotal, fmode->frequency);
+
+ return (1);
+ } /* end if() */
+ } /* end for() */
+
+ return (-1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_panel_present
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#else
+int
+gfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+#endif
+{
+ /* SET VALID BPP */
+ /* 16BPP is the default. */
+
+ if (bpp != 8 && bpp != 12 && bpp != 15 && bpp != 16 && bpp != 32)
+ bpp = 16;
+
+ /* RECORD PANEL PARAMETERS */
+ /* This routine does not touch any panel timings. It is used when custom
+ * panel settings are set up in advance by the BIOS or an application,
+ * but the application still requires access to other panel functionality
+ * provided by Durango (i.e. panning).
+ * */
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+ gbpp = bpp;
+
+ /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
+
+ gfx_set_display_bpp(bpp);
+
+ return (GFX_STATUS_OK);
+}
+
+/* THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: */
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_pitch
+ *
+ * This routine returns the current pitch of the frame buffer, in bytes.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_display_pitch(void)
+#else
+unsigned short
+gfx_get_display_pitch(void)
+#endif
+{
+ return ((unsigned short)(READ_REG32(DC3_GFX_PITCH) & 0x0000FFFF) << 3);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_mode_frequency_supported
+ *
+ * This routine examines if the requested mode with pixel frequency is
+ * supported.
+ *
+ * Returns >0 if successful , <0 if freq. could not be found and matched.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency)
+#else
+int
+gfx_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+
+ gfx_mode_bpp_conversion_def(bpp)
+
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned int)xres) &&
+ (DisplayParams[index].vactive == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].frequency == frequency)) {
+ int hz = 0;
+
+ value = DisplayParams[index].flags;
+
+ if (value & GFX_MODE_56HZ)
+ hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ hz = 85;
+ else if (value & GFX_MODE_90HZ)
+ hz = 90;
+ else if (value & GFX_MODE_100HZ)
+ hz = 100;
+ return (hz);
+ }
+ }
+
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_frequency
+ *
+ * This routine maps the frequency to close match refresh rate
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#else
+int
+gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch = 0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ gfx_mode_bpp_conversion_def(bpp)
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].htotal == (unsigned int)xres) &&
+ (DisplayParams[index].vtotal == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag)) {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < min) {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (value & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (value & GFX_MODE_100HZ)
+ *hz = 100;
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_mode
+ *
+ * This routine is identical to the gfx_get_refreshrate_from_frequency,
+ * except that the active timing values are compared instead of the total
+ * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#else
+int
+gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch = 0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ gfx_mode_bpp_conversion_def(bpp)
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned int)xres) &&
+ (DisplayParams[index].vactive == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag)) {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < min) {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (value & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (value & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (value & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (value & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (value & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (value & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (value & GFX_MODE_100HZ)
+ *hz = 100;
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frequency_from_refreshrate
+ *
+ * This routine maps the refresh rate to the closest matching PLL frequency.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency)
+#else
+int
+gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency)
+#endif
+{
+ unsigned int index;
+ int retval = -1;
+ unsigned long hz_flag = 0;
+ unsigned long bpp_flag = 0;
+
+ *frequency = 0;
+
+ gfx_mode_hz_conversion gfx_mode_bpp_conversion_def(bpp)
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
+ if ((DisplayParams[index].hactive == (unsigned short)xres) &&
+ (DisplayParams[index].vactive == (unsigned short)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].flags & hz_flag)) {
+ *frequency = (int)DisplayParams[index].frequency;
+ retval = 1;
+ }
+ }
+ return retval;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_supported_pixel_clock
+ *
+ * This routine returns the maximum recommended speed for the pixel clock. The
+ * return value is an integer of the format xxxyyy, where xxx.yyy is the
+ * maximum floating point pixel clock speed.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_max_supported_pixel_clock(void)
+#else
+unsigned long
+gfx_get_max_supported_pixel_clock(void)
+#endif
+{
+ return 229500;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_mode
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns >0 if successful and mode returned, <0 if mode could not be found.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#else
+int
+gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#endif
+{
+ unsigned int mode = 0;
+ unsigned long pll_freq = 0, bpp_flag = 0;
+
+ *xres = gfx_get_hactive();
+ *yres = gfx_get_vactive();
+ *bpp = gfx_get_display_bpp();
+ pll_freq = gfx_get_clock_frequency();
+
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+ gfx_mode_bpp_conversion_def(bpp)
+
+ for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
+ if ((DisplayParams[mode].hactive == (unsigned int)*xres) &&
+ (DisplayParams[mode].vactive == (unsigned int)*yres) &&
+ (DisplayParams[mode].frequency == pll_freq) &&
+ (DisplayParams[mode].flags & bpp_flag)) {
+
+ pll_freq = DisplayParams[mode].flags;
+
+ if (pll_freq & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (pll_freq & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (pll_freq & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (pll_freq & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (pll_freq & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (pll_freq & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (pll_freq & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (pll_freq & GFX_MODE_100HZ)
+ *hz = 100;
+
+ return (1);
+ }
+ }
+ return (-1);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_DETAILS
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be get.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#else
+int
+gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#endif
+{
+ if (mode < NUM_RC_DISPLAY_MODES) {
+ if (DisplayParams[mode].flags & GFX_MODE_56HZ)
+ *hz = 56;
+ else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
+ *hz = 60;
+ else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
+ *hz = 70;
+ else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
+ *hz = 72;
+ else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
+ *hz = 75;
+ else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
+ *hz = 85;
+ else if (DisplayParams[mode].flags & GFX_MODE_90HZ)
+ *hz = 90;
+ else if (DisplayParams[mode].flags & GFX_MODE_100HZ)
+ *hz = 100;
+
+ *xres = DisplayParams[mode].hactive;
+ *yres = DisplayParams[mode].vactive;
+
+ if (DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE)
+ *xres >>= 1;
+ if (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE)
+ *yres >>= 1;
+
+ return (1);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_MODE_COUNT
+ *
+ * This routine gets the number of available display modes.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_display_mode_count(void)
+#else
+int
+gfx_get_display_mode_count(void)
+#endif
+{
+ return (NUM_RC_DISPLAY_MODES);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_line_size
+ *
+ * Returns the current frame buffer line size, in bytes
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_frame_buffer_line_size(void)
+#else
+unsigned long
+gfx_get_frame_buffer_line_size(void)
+#endif
+{
+ return ((READ_REG32(DC3_LINE_SIZE) & 0x3FF) << 3);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_hactive(void)
+#else
+unsigned short
+gfx_get_hactive(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_H_ACTIVE_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_hsync_start(void)
+#else
+unsigned short
+gfx_get_hsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_H_SYNC_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_hsync_end(void)
+#else
+unsigned short
+gfx_get_hsync_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0x0FF8)
+ + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_htotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_htotal(void)
+#else
+unsigned short
+gfx_get_htotal(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) &
+ 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_vactive(void)
+#else
+unsigned short
+gfx_get_vactive(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_V_ACTIVE_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_vsync_end(void)
+#else
+unsigned short
+gfx_get_vsync_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0x07FF)
+ + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vtotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_vtotal(void)
+#else
+unsigned short
+gfx_get_vtotal(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) &
+ 0x07FF) + 1));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_bpp
+ *
+ * This routine returns the current color depth of the active display.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_display_bpp(void)
+#else
+unsigned short
+gfx_get_display_bpp(void)
+#endif
+{
+ unsigned long dcfg = READ_REG32(DC3_DISPLAY_CFG);
+
+ switch ((dcfg & DC3_DCFG_DISP_MODE_MASK) >> 8) {
+ case 0:
+ return (8);
+ case 2:
+ return (32);
+
+ case 1:
+
+ switch ((dcfg & DC3_DCFG_16BPP_MODE_MASK) >> 10) {
+ case 0:
+ return (16);
+ case 1:
+ return (15);
+ case 2:
+ return (12);
+ default:
+ return (0);
+ }
+ }
+
+ /* INVALID SETTING */
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vline
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_vline(void)
+#else
+unsigned short
+gfx_get_vline(void)
+#endif
+{
+ unsigned long current_scan_line;
+
+ /* Read similar value twice to ensure that the value is not transitioning
+ * */
+
+ do
+ current_scan_line =
+ (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT);
+ while (current_scan_line !=
+ (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT));
+
+ return ((unsigned short)(current_scan_line >> 16));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_offset
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_display_offset(void)
+#else
+unsigned long
+gfx_get_display_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_FB_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_cursor_offset(void)
+#else
+unsigned long
+gfx_get_cursor_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_CURS_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+#if GFX_READ_ROUTINES
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_hblank_start(void)
+#else
+unsigned short
+gfx_get_hblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_H_BLANK_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_hblank_end(void)
+#else
+unsigned short
+gfx_get_hblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_H_BLANK_TIMING) >> 16) & 0x0FF8)
+ + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_vblank_start(void)
+#else
+unsigned short
+gfx_get_vblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_V_BLANK_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_vsync_start(void)
+#else
+unsigned short
+gfx_get_vsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_V_SYNC_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_vblank_end(void)
+#else
+unsigned short
+gfx_get_vblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_V_BLANK_TIMING) >> 16) & 0x07FF)
+ + 1));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_palette_entry
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int
+gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(DC3_PAL_ADDRESS, index);
+ *palette = READ_REG32(DC3_PAL_DATA);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_palette
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_get_display_palette(unsigned long *palette)
+#else
+void
+gfx_get_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i;
+
+ WRITE_REG32(DC3_PAL_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ palette[i] = READ_REG32(DC3_PAL_DATA);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_enable
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_cursor_enable(void)
+#else
+unsigned long
+gfx_get_cursor_enable(void)
+#endif
+{
+ return (READ_REG32(DC3_GENERAL_CFG) & DC3_GCFG_CURE);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_position
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_cursor_position(void)
+#else
+unsigned long
+gfx_get_cursor_position(void)
+#endif
+{
+ return ((READ_REG32(DC3_CURSOR_X) & 0x07FF) |
+ ((READ_REG32(DC3_CURSOR_Y) << 16) & 0x07FF0000));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_cursor_clip(void)
+#else
+unsigned long
+gfx_get_cursor_clip(void)
+#endif
+{
+ return (((READ_REG32(DC3_CURSOR_X) >> 11) & 0x03F) |
+ ((READ_REG32(DC3_CURSOR_Y) << 5) & 0x3F0000));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cursor_color
+ *---------------------------------------------------------------------------- */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_cursor_color(int color)
+#else
+unsigned long
+gfx_get_cursor_color(int color)
+#endif
+{
+ if (color) {
+ WRITE_REG32(DC3_PAL_ADDRESS, 0x101);
+ } else {
+ WRITE_REG32(DC3_PAL_ADDRESS, 0x100);
+ }
+ return READ_REG32(DC3_PAL_DATA);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_enable
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_compression_enable(void)
+#else
+int
+gfx_get_compression_enable(void)
+#endif
+{
+ if (READ_REG32(DC3_GENERAL_CFG) & DC3_GCFG_CMPE)
+ return (1);
+
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_offset
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_compression_offset(void)
+#else
+unsigned long
+gfx_get_compression_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_CB_ST_OFFSET) & 0x007FFFFF);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_pitch
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_compression_pitch(void)
+#else
+unsigned short
+gfx_get_compression_pitch(void)
+#endif
+{
+ unsigned short pitch;
+
+ pitch = (unsigned short)(READ_REG32(DC3_GFX_PITCH) >> 16);
+ return (pitch << 3);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_compression_size
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short
+gu3_get_compression_size(void)
+#else
+unsigned short
+gfx_get_compression_size(void)
+#endif
+{
+ unsigned short size;
+
+ size =
+ (unsigned short)((READ_REG32(DC3_LINE_SIZE) >> DC3_LINE_SIZE_CB_SHIFT)
+ & 0x7F) - 1;
+ return ((size << 3) + 32);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_valid_bit
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int
+gu3_get_valid_bit(int line)
+#else
+int
+gfx_get_valid_bit(int line)
+#endif
+{
+ unsigned long lock;
+ unsigned long offset;
+ int valid;
+
+ lock = READ_REG32(DC3_UNLOCK);
+ offset = READ_REG32(DC3_PHY_MEM_OFFSET) & 0xFF000000;
+ offset |= line;
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_PHY_MEM_OFFSET, offset);
+ WRITE_REG32(DC3_UNLOCK, lock);
+ valid = (int)READ_REG32(DC3_DV_ACC) & 2;
+
+ if (valid)
+ return 1;
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_display_video_offset(void)
+#else
+unsigned long
+gfx_get_display_video_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_yuv_offsets". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_get_display_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset)
+#else
+void
+gfx_get_display_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset)
+#endif
+{
+ *yoffset = (READ_REG32(DC3_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
+ *uoffset = (READ_REG32(DC3_VID_U_ST_OFFSET) & 0x0FFFFFFF);
+ *voffset = (READ_REG32(DC3_VID_V_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_yuv_pitch". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void
+gu3_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#else
+void
+gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#endif
+{
+ unsigned long pitch = READ_REG32(DC3_VID_YUV_PITCH);
+
+ *ypitch = ((pitch & 0xFFFF) << 3);
+ *uvpitch = (pitch >> 13) & 0x7FFF8;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_display_video_size(void)
+#else
+unsigned long
+gfx_get_display_video_size(void)
+#endif
+{
+ /* RETURN THE LINE SIZE, AS THIS IS ALL THAT IS AVAILABLE */
+ /* Shift by three less to effect a multiply by 8. */
+
+ return ((READ_REG32(DC3_LINE_SIZE) & DC3_LINE_SIZE_VLS_MASK) >>
+ (DC3_LINE_SIZE_VB_SHIFT - 3));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_color_key (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_color_key". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_display_video_color_key(void)
+#else
+unsigned long
+gfx_get_display_video_color_key(void)
+#endif
+{
+ return (READ_REG32(DC3_COLOR_KEY) & 0xFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_color_key_mask (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_color_key_mask". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long
+gu3_get_display_video_color_key_mask(void)
+#else
+unsigned long
+gfx_get_display_video_color_key_mask(void)
+#endif
+{
+ return (READ_REG32(DC3_COLOR_MASK) & 0xFFFFFF);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/durango.c b/src/gfx/durango.c
new file mode 100644
index 0000000..47c72d8
--- /dev/null
+++ b/src/gfx/durango.c
@@ -0,0 +1,488 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This is the main file used to add Durango graphics support to a software
+ * project. The main reason to have a single file include the other files
+ * is that it centralizes the location of the compiler options. This file
+ * should be tuned for a specific implementation, and then modified as needed
+ * for new Durango releases. The releases.txt file indicates any updates to
+ * this main file, such as a new definition for a new hardware platform.
+ *
+ * In other words, this file should be copied from the Durango source files
+ * once when a software project starts, and then maintained as necessary.
+ * It should not be recopied with new versions of Durango unless the
+ * developer is willing to tune the file again for the specific project.
+ * */
+
+/* COMPILER OPTIONS
+ * These compiler options specify how the Durango routines are compiled
+ * for the different hardware platforms. For best performance, a driver
+ * would build for a specific platform. The "dynamic" switches are set
+ * by diagnostic applications such as Darwin that will run on a variety
+ * of platforms and use the appropriate code at runtime. Each component
+ * may be separately dynamic, so that a driver has the option of being
+ * tuned for a specific 2D accelerator, but will still run with a variety
+ * of chipsets.
+ */
+
+#define GFX_DISPLAY_DYNAMIC 1 /* runtime selection */
+#define GFX_DISPLAY_GU1 1 /* 1st generation display controller */
+#define GFX_DISPLAY_GU2 1 /* 2nd generation display controller */
+#define GFX_DISPLAY_GU3 1 /* 3rd generation display controller */
+
+#define GFX_INIT_DYNAMIC 1 /* runtime selection */
+#define GFX_INIT_GU1 1 /* Geode family */
+#define GFX_INIT_GU2 1 /* Redcloud */
+#define GFX_INIT_GU3 1 /* Castle */
+
+#define GFX_MSR_DYNAMIC 1 /* runtime selection */
+#define GFX_MSR_REDCLOUD 1 /* Redcloud */
+
+#define GFX_2DACCEL_DYNAMIC 1 /* runtime selection */
+#define GFX_2DACCEL_GU1 1 /* 1st generation 2D accelerator */
+#define GFX_2DACCEL_GU2 1 /* 2nd generation 2D accelerator */
+
+#define GFX_VIDEO_DYNAMIC 1 /* runtime selection */
+#define GFX_VIDEO_CS5530 1 /* support for CS5530 */
+#define GFX_VIDEO_SC1200 1 /* support for SC1200 */
+#define GFX_VIDEO_REDCLOUD 1 /* support for Redcloud */
+#define GFX_VIDEO_CASTLE 1 /* support for Castle */
+
+#define GFX_VIP_DYNAMIC 1 /* runtime selection */
+#define GFX_VIP_SC1200 1 /* support for SC1200 */
+
+#define GFX_DECODER_DYNAMIC 1 /* runtime selection */
+#define GFX_DECODER_SAA7114 1 /* Philips SAA7114 decoder */
+
+#define GFX_TV_DYNAMIC 1 /* runtime selection */
+#define GFX_TV_FS451 1 /* Focus Enhancements FS450 */
+#define GFX_TV_SC1200 1 /* SC1200 integrated TV encoder */
+
+#define GFX_I2C_DYNAMIC 1 /* runtime selection */
+#define GFX_I2C_ACCESS 1 /* support for ACCESS.BUS */
+#define GFX_I2C_GPIO 1 /* support for CS5530 GPIOs */
+
+#define GFX_VGA_DYNAMIC 1 /* runtime selection */
+#define GFX_VGA_GU1 1 /* 1st generation graphics unit */
+
+#define FB4MB 1 /* Set to use 4Mb video ram for Pyramid */
+
+#define GFX_NO_IO_IN_WAIT_MACROS 0 /* Set to remove I/O accesses in GP
+ * bit testing */
+
+/* ROUTINES TO READ VALUES
+ * These are routines used by Darwin or other diagnostics to read the
+ * current state of the hardware. Display drivers or embedded applications
+ * can reduce the size of the Durango code by not including these routines.
+ */
+#define GFX_READ_ROUTINES 1 /* add routines to read values */
+
+/* VARIABLES USED FOR RUNTIME SELECTION
+ * If part of the graphics subsystem is declared as dynamic, then the
+ * following variables are used to specify which platform has been detected.
+ * The variables are set in the "gfx_detect_cpu" routine. The values should
+ * be bit flags to allow masks to be used to check for multiple platforms.
+ */
+
+#if GFX_DISPLAY_DYNAMIC
+int gfx_display_type = 0;
+#endif
+
+#if GFX_INIT_DYNAMIC
+int gfx_init_type = 0;
+#endif
+
+#if GFX_MSR_DYNAMIC
+int gfx_msr_type = 0;
+#endif
+
+#if GFX_2DACCEL_DYNAMIC
+int gfx_2daccel_type = 0;
+#endif
+
+#if GFX_VIDEO_DYNAMIC
+int gfx_video_type = 0;
+#endif
+
+#if GFX_VIP_DYNAMIC
+int gfx_vip_type = 0;
+#endif
+
+#if GFX_DECODER_DYNAMIC
+int gfx_decoder_type = 0;
+#endif
+
+#if GFX_TV_DYNAMIC
+int gfx_tv_type = 0;
+#endif
+
+#if GFX_I2C_DYNAMIC
+int gfx_i2c_type = 0;
+#endif
+
+#if GFX_VGA_DYNAMIC
+int gfx_vga_type = 0;
+#endif
+
+/* HEADER FILE FOR DURANGO ROUTINE DEFINITIONS
+ * Needed since some of the Durango routines call other Durango routines.
+ * Also defines the size of chipset array (GFX_CSPTR_SIZE).
+ */
+#include "gfx_rtns.h" /* routine definitions */
+
+/* INCLUDE PROTOTYPES FOR PRIVATE ROUTINES */
+
+#include "gfx_priv.h"
+
+/* DEFINE POINTERS TO MEMORY MAPPED REGIONS
+ * These pointers are used by the Durango routines to access the hardware.
+ * The variables must be set by the project's initialization code after
+ * mapping the regions in the appropriate manner.
+ */
+
+/* DEFINE VIRTUAL ADDRESSES */
+/* Note: These addresses define the starting base expected by all */
+/* Durango offsets. Under an OS that requires these pointers */
+/* to be mapped to linear addresses (i.e Windows), it may not */
+/* be possible to keep these base offsets. In these cases, */
+/* the addresses are modified to point to the beginning of the */
+/* relevant memory region and the access macros are adjusted */
+/* to subtract the offset from the default base. For example, */
+/* the register pointer could be moved to be 0x40008000, while */
+/* the WRITE_REG* macros are modified to subtract 0x8000 from */
+/* the offset. */
+
+unsigned char *gfx_virt_regptr = (unsigned char *)0x40000000;
+unsigned char *gfx_virt_fbptr = (unsigned char *)0x40800000;
+unsigned char *gfx_virt_vidptr = (unsigned char *)0x40010000;
+unsigned char *gfx_virt_vipptr = (unsigned char *)0x40015000;
+unsigned char *gfx_virt_spptr = (unsigned char *)0x40000000;
+unsigned char *gfx_virt_gpptr = (unsigned char *)0x40000000;
+
+/* DEFINE PHYSICAL ADDRESSES */
+
+unsigned char *gfx_phys_regptr = (unsigned char *)0x40000000;
+unsigned char *gfx_phys_fbptr = (unsigned char *)0x40800000;
+unsigned char *gfx_phys_vidptr = (unsigned char *)0x40010000;
+unsigned char *gfx_phys_vipptr = (unsigned char *)0x40015000;
+
+/* HEADER FILE FOR GRAPHICS REGISTER DEFINITIONS
+ * This contains only constant definitions, so it should be able to be
+ * included in any software project as is.
+ */
+#include "gfx_regs.h" /* graphics register definitions */
+
+/* HEADER FILE FOR REGISTER ACCESS MACROS
+ * This file contains the definitions of the WRITE_REG32 and similar macros
+ * used by the Durango routines to access the hardware. The file assumes
+ * that the environment can handle 32-bit pointer access. If this is not
+ * the case, or if there are special requirements, then this header file
+ * should not be included and the project must define the macros itself.
+ * (A project may define WRITE_REG32 to call a routine, for example).
+ */
+#include "gfx_defs.h" /* register access macros */
+
+/* IO MACROS AND ROUTINES
+ * These macros must be defined before the initialization or I2C
+ * routines will work properly.
+ */
+
+#if defined(OS_WIN32) /* For Windows */
+
+/* VSA II CALL */
+
+void
+gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow)
+{
+ unsigned long temp1, temp2;
+
+ _asm {
+ mov dx, 0x0AC1C
+ mov eax, 0x0FC530007
+ out dx, eax add dl, 2 mov ecx, msrAddr mov cx, msrReg in ax, dx;
+ EDX:EAX will contain MSR contents.mov temp1, edx mov temp2, eax}
+
+ *ptrHigh = temp1;
+ *ptrLow = temp2;
+}
+
+void
+gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow)
+{
+ unsigned long temp1 = *ptrHigh;
+ unsigned long temp2 = *ptrLow;
+
+ _asm {
+
+ mov dx, 0x0AC1C
+ mov eax, 0x0FC530007 out dx, eax add dl, 2 mov ecx, msrAddr;
+ ECX contains msrAddr | msrReg mov cx, msrReg;
+ mov ebx, temp1;
+
+ <OR_mask_hi > mov eax, temp2;
+ <OR_mask_hi > mov esi, 0;
+ <AND_mask_hi > mov edi, 0;
+ <AND_mask_lo > out dx, ax;
+ MSR is written at this point}
+}
+
+unsigned char
+gfx_inb(unsigned short port)
+{
+ unsigned char data;
+
+ _asm {
+ pushf mov dx, port in al, dx mov data, al popf}
+ return (data);
+}
+
+unsigned short
+gfx_inw(unsigned short port)
+{
+ unsigned short data;
+
+ _asm {
+ pushf mov dx, port in ax, dx mov data, ax popf}
+ return (data);
+}
+
+unsigned long
+gfx_ind(unsigned short port)
+{
+ unsigned long data;
+
+ _asm {
+ pushf mov dx, port in eax, dx mov data, eax popf}
+ return (data);
+}
+
+void
+gfx_outb(unsigned short port, unsigned char data)
+{
+ _asm {
+ pushf mov al, data mov dx, port out dx, al popf}
+}
+
+void
+gfx_outw(unsigned short port, unsigned short data)
+{
+ _asm {
+ pushf mov ax, data mov dx, port out dx, ax popf}
+}
+
+void
+gfx_outd(unsigned short port, unsigned long data)
+{
+ _asm {
+ pushf mov eax, data mov dx, port out dx, eax popf}
+}
+
+#elif defined(OS_VXWORKS) || defined (OS_LINUX) /* VxWorks and Linux */
+
+#if defined(OS_LINUX)
+#include "asm/msr.h"
+#endif
+
+void
+gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow)
+{
+ unsigned long addr, val1, val2;
+
+ addr = msrAddr | (unsigned long)msrReg;
+ rdmsr(addr, val1, val2);
+
+ *ptrHigh = val2;
+ *ptrLow = val1;
+}
+
+void
+gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow)
+{
+ unsigned long addr, val1, val2;
+
+ val2 = *ptrHigh;
+ val1 = *ptrLow;
+
+ addr = (msrAddr & 0xFFFF0000) | (unsigned long)msrReg;
+ wrmsr(addr, val1, val2);
+}
+
+unsigned char
+gfx_inb(unsigned short port)
+{
+ unsigned char value;
+ __asm__ volatile ("inb %1,%0":"=a" (value):"d"(port));
+
+ return value;
+}
+
+unsigned short
+gfx_inw(unsigned short port)
+{
+ unsigned short value;
+ __asm__ volatile ("in %1,%0":"=a" (value):"d"(port));
+
+ return value;
+}
+
+unsigned long
+gfx_ind(unsigned short port)
+{
+ unsigned long value;
+ __asm__ volatile ("inl %1,%0":"=a" (value):"d"(port));
+
+ return value;
+}
+
+void
+gfx_outb(unsigned short port, unsigned char data)
+{
+ __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port));
+}
+
+void
+gfx_outw(unsigned short port, unsigned short data)
+{
+ __asm__ volatile ("out %0,%1"::"a" (data), "d"(port));
+}
+
+void
+gfx_outd(unsigned short port, unsigned long data)
+{
+ __asm__ volatile ("outl %0,%1"::"a" (data), "d"(port));
+}
+
+#else /* else nothing */
+
+unsigned char
+gfx_inb(unsigned short port)
+{
+ /* ADD OS SPECIFIC IMPLEMENTATION */
+ return (0);
+}
+
+unsigned short
+gfx_inw(unsigned short port)
+{
+ /* ADD OS SPECIFIC IMPLEMENTATION */
+ return (0);
+}
+
+unsigned long
+gfx_ind(unsigned short port)
+{
+ /* ADD OS SPECIFIC IMPLEMENTATION */
+ return (0);
+}
+
+void
+gfx_outb(unsigned short port, unsigned char data)
+{
+ /* ADD OS SPECIFIC IMPLEMENTATION */
+}
+
+void
+gfx_outw(unsigned short port, unsigned short data)
+{
+ /* ADD OS SPECIFIC IMPLEMENTATION */
+}
+
+void
+gfx_outd(unsigned short port, unsigned long data)
+{
+ /* ADD OS SPECIFIC IMPLEMENTATION */
+}
+#endif
+
+#define INB(port) gfx_inb(port)
+#define INW(port) gfx_inw(port)
+#define IND(port) gfx_ind(port)
+#define OUTB(port, data) gfx_outb(port, data)
+#define OUTW(port, data) gfx_outw(port, data)
+#define OUTD(port, data) gfx_outd(port, data)
+
+/* INITIALIZATION ROUTINES
+ * These routines are used during the initialization of the driver to
+ * perform such tasks as detecting the type of CPU and video hardware.
+ * The routines require the use of IO, so the above IO routines need
+ * to be implemented before the initialization routines will work
+ * properly.
+ */
+
+#include "gfx_init.c"
+
+/* INCLUDE MSR ACCESS ROUTINES */
+
+#include "gfx_msr.c"
+
+/* INCLUDE GRAPHICS ENGINE ROUTINES
+ * These routines are used to program the 2D graphics accelerator. If
+ * the project does not use graphics acceleration (direct frame buffer
+ * access only), then this file does not need to be included.
+ */
+#include "gfx_rndr.c" /* graphics engine routines */
+
+/* INCLUDE DISPLAY CONTROLLER ROUTINES
+ * These routines are used if the display mode is set directly. If the
+ * project uses VGA registers to set a display mode, then these files
+ * do not need to be included.
+ */
+#include "gfx_mode.h" /* display mode tables */
+#include "gfx_disp.c" /* display controller routines */
+
+/* INCLUDE VIDEO OVERLAY ROUTINES
+ * These routines control the video overlay hardware.
+ */
+#include "gfx_vid.c" /* video overlay routines */
+
+/* VIDEO PORT AND VIDEO DECODER ROUTINES
+ * These routines rely on the I2C routines.
+ */
+#include "gfx_vip.c" /* video port routines */
+#include "gfx_dcdr.c" /* video decoder routines */
+
+/* I2C BUS ACCESS ROUTINES
+ * These routines are used by the video decoder and possibly an
+ * external TV encoer.
+ */
+#include "gfx_i2c.c" /* I2C bus access routines */
+
+/* TV ENCODER ROUTINES
+ * This file does not need to be included if the system does not
+ * support TV output.
+ */
+#include "gfx_tv.c" /* TV encoder routines */
+
+/* VGA ROUTINES
+ * This file is used if setting display modes using VGA registers.
+ */
+#include "gfx_vga.c" /* VGA routines */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_dcdr.c b/src/gfx/gfx_dcdr.c
new file mode 100644
index 0000000..57abe37
--- /dev/null
+++ b/src/gfx/gfx_dcdr.c
@@ -0,0 +1,499 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the video decoder.
+ *
+ * gfx_set_decoder_defaults
+ * gfx_set_decoder_analog_input
+ * gfx_set_decoder_brightness
+ * gfx_set_decoder_contrast
+ * gfx_set_decoder_luminance_filter
+ * gfx_set_decoder_hue
+ * gfx_set_decoder_saturation
+ * gfx_set_decoder_input_offset
+ * gfx_set_decoder_input_size
+ * gfx_set_decoder_output_size
+ * gfx_set_decoder_scale
+ * gfx_set_decoder_TV_standard
+ * gfx_set_decoder_vbi_enable
+ * gfx_set_decoder_vbi_format
+ * gfx_set_decoder_vbi_upscale
+ * gfx_decoder_software_reset
+ * gfx_decoder_detect_macrovision
+ * gfx_decoder_detect_video
+ *
+ * And the following routines if GFX_READ_ROUTINES is set:
+ *
+ * gfx_get_decoder_brightness
+ * gfx_get_decoder_contrast
+ * gfx_get_decoder_hue
+ * gfx_get_decoder_saturation
+ * gfx_get_decoder_input_offset
+ * gfx_get_decoder_input_size
+ * gfx_get_decoder_output_size
+ * gfx_get_decoder_vbi_format
+ */
+
+/* INCLUDE SUPPORT FOR PHILIPS SAA7114 DECODER, IF SPECIFIED */
+
+#if GFX_DECODER_SAA7114
+#include "saa7114.c"
+#endif
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call various decoders. Currently only the Pillips */
+/* decoder is supported, but still organized to easily expand later. */
+
+#if GFX_DECODER_DYNAMIC
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_defaults
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_defaults(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_defaults();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_analog_input
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_analog_input(unsigned char input)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_analog_input(input);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_brightness
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_brightness(unsigned char brightness)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_brightness(brightness);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_contrast
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_contrast(unsigned char contrast)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_contrast(contrast);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_hue
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_hue(char hue)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_hue(hue);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_saturation
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_saturation(unsigned char saturation)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_saturation(saturation);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_input_offset
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_input_offset(unsigned short x, unsigned short y)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_input_offset(x, y);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_input_size
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_input_size(unsigned short width, unsigned short height)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_input_size(width, height);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_output_size
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_output_size(unsigned short width, unsigned short height)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_output_size(width, height);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_scale
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_scale(srcw, srch, dstw, dsth);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_vbi_format
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_vbi_format(int start, int end, int format)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_vbi_format(start, end, format);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_vbi_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_vbi_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_vbi_enable(enable);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_vbi_upscale
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_vbi_upscale(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_vbi_upscale();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_TV_standard
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_TV_standard(TVStandardType TVStandard)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_TV_standard(TVStandard);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_luminance_filter
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_decoder_luminance_filter(unsigned char lufi)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_set_decoder_luminance_filter(lufi);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_decoder_software_reset
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_decoder_software_reset(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_decoder_software_reset();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_decoder_detect_macrovision
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_decoder_detect_macrovision(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_decoder_detect_macrovision();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_decoder_detect_video
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_decoder_detect_video(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ status = saa7114_decoder_detect_video();
+#endif
+ return (status);
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_brightness
+ *----------------------------------------------------------------------------
+ */
+unsigned char
+gfx_get_decoder_brightness(void)
+{
+ unsigned char brightness = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ brightness = saa7114_get_decoder_brightness();
+#endif
+ return (brightness);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_contrast
+ *----------------------------------------------------------------------------
+ */
+unsigned char
+gfx_get_decoder_contrast(void)
+{
+ unsigned char contrast = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ contrast = saa7114_get_decoder_contrast();
+#endif
+ return (contrast);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_hue
+ *----------------------------------------------------------------------------
+ */
+char
+gfx_get_decoder_hue(void)
+{
+ unsigned char hue = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ hue = saa7114_get_decoder_hue();
+#endif
+ return ((char)hue);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_saturation
+ *----------------------------------------------------------------------------
+ */
+unsigned char
+gfx_get_decoder_saturation(void)
+{
+ unsigned char saturation = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ saturation = saa7114_get_decoder_saturation();
+#endif
+ return (saturation);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_input_offset
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_decoder_input_offset()
+{
+ unsigned long offset = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ offset = saa7114_get_decoder_input_offset();
+#endif
+ return (offset);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_input_size
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_decoder_input_size()
+{
+ unsigned long size = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ size = saa7114_get_decoder_input_size();
+#endif
+ return (size);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_output_size
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_decoder_output_size()
+{
+ unsigned long size = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ size = saa7114_get_decoder_output_size();
+#endif
+ return (size);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_vbi_format
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_decoder_vbi_format(int line)
+{
+ int format = 0;
+
+#if GFX_DECODER_SAA7114
+ if (gfx_decoder_type == GFX_DECODER_SAA7114)
+ format = saa7114_get_decoder_vbi_format(line);
+#endif
+ return (format);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+#endif /* GFX_DECODER_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_defs.h b/src/gfx/gfx_defs.h
new file mode 100644
index 0000000..dde8385
--- /dev/null
+++ b/src/gfx/gfx_defs.h
@@ -0,0 +1,348 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This header file contains the macros used to access the hardware. These
+ * macros assume that 32-bit access is possible, which is true for most
+ * applications. Projects using 16-bit compilers (the Windows98 display
+ * driver) and special purpose applications (such as Darwin) need to define
+ * their own versions of these macros, which typically call a subroutine.
+ * */
+
+/* ACCESS TO THE CPU REGISTERS */
+
+#define WRITE_REG8(offset, value) \
+ (*(volatile unsigned char *)(gfx_virt_regptr + (offset))) = (value)
+
+#define WRITE_REG16(offset, value) \
+ (*(volatile unsigned short *)(gfx_virt_regptr + (offset))) = (value)
+
+#define WRITE_REG32(offset, value) \
+ (*(volatile unsigned long *)(gfx_virt_regptr + (offset))) = (value)
+
+#define READ_REG16(offset) \
+ (*(volatile unsigned short *)(gfx_virt_regptr + (offset)))
+
+#define READ_REG32(offset) \
+ (*(volatile unsigned long *)(gfx_virt_regptr + (offset)))
+
+/* ACCESS TO THE ACCELERATOR REGISTERS (REDCLOUD ONLY) */
+
+#define WRITE_GP8(offset, value) \
+ (*(volatile unsigned char *)(gfx_virt_gpptr + (offset))) = (value)
+
+#define WRITE_GP16(offset, value) \
+ (*(volatile unsigned short *)(gfx_virt_gpptr + (offset))) = (value)
+
+#define WRITE_GP32(offset, value) \
+ (*(volatile unsigned long *)(gfx_virt_gpptr + (offset))) = (value)
+
+#define READ_GP16(offset) \
+ (*(volatile unsigned short *)(gfx_virt_gpptr + (offset)))
+
+#define READ_GP32(offset) \
+ (*(volatile unsigned long *)(gfx_virt_gpptr + (offset)))
+
+/* ACCESS TO THE FRAME BUFFER */
+
+#define WRITE_FB32(offset, value) \
+ (*(volatile unsigned long *)(gfx_virt_fbptr + (offset))) = (value)
+
+#define WRITE_FB16(offset, value) \
+ (*(volatile unsigned short *)(gfx_virt_fbptr + (offset))) = (value)
+
+#define WRITE_FB8(offset, value) \
+ (*(volatile unsigned char *)(gfx_virt_fbptr + (offset))) = (value)
+
+/* ACCESS TO THE VIDEO HARDWARE */
+
+#define READ_VID32(offset) \
+ (*(volatile unsigned long *)(gfx_virt_vidptr + (offset)))
+
+#define WRITE_VID32(offset, value) \
+ (*(volatile unsigned long *)(gfx_virt_vidptr + (offset))) = (value)
+
+/* ACCESS TO THE VIP HARDWARE */
+
+#define READ_VIP32(offset) \
+ (*(volatile unsigned long *)(gfx_virt_vipptr + (offset)))
+
+#define WRITE_VIP32(offset, value) \
+ (*(volatile unsigned long *)(gfx_virt_vipptr + (offset))) = (value)
+
+/* ACCESS TO THE SCRATCHPAD RAM */
+
+#define WRITE_SCRATCH32(offset, value) \
+ (*(volatile unsigned long *)(gfx_virt_spptr + (offset))) = (value)
+
+#define WRITE_SCRATCH16(offset, value) \
+ (*(volatile unsigned short *)(gfx_virt_spptr + (offset))) = (value)
+
+#define WRITE_SCRATCH8(offset, value) \
+ (*(volatile unsigned char *)(gfx_virt_spptr + (offset))) = (value)
+
+#define READ_SCRATCH16(offset) \
+ (*(volatile unsigned short *)(gfx_virt_spptr + (offset)))
+
+#define READ_SCRATCH32(offset) \
+ (*(volatile unsigned long *)(gfx_virt_spptr + (offset)))
+
+/* ACCESS TO MSRS */
+
+void gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow);
+void gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow);
+
+#define MSR_READ( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) \
+ gfx_msr_asm_read( ((unsigned short)(MBD_MSR_CAP)), address, \
+ valueHigh_ptr, valueLow_ptr )
+
+#define MSR_WRITE( MBD_MSR_CAP, address, valueHigh_ptr, valueLow_ptr ) \
+ gfx_msr_asm_write( ((unsigned short)(MBD_MSR_CAP)), address, \
+ valueHigh_ptr, valueLow_ptr )
+
+/* OPTIMIZATION MACROS */
+/* The following macros have been added to allow more complete optimization of
+ * the bitmap-to-screen routines in Durango. These routines also allow
+ * Durango to run properly within a 16-bit environment.
+ * */
+
+/*****************************************************************************
+ * Macro: SET_SCRATCH_BASE
+ * Purpose: Record the base address of the BLT buffers. The
+ * WRITE_SCRATCH_STRINGxx macros assume that this address is used
+ * as the base for all writes.
+ *
+ * Arguments:
+ * scratch_base - offset into the GX base for the first BLT buffer byte.
+ ****************************************************************************/
+
+#define SET_SCRATCH_BASE(scratch_base) \
+ { gfx_gx1_scratch_base = (unsigned long)gfx_virt_spptr + scratch_base; }
+
+#ifdef GFX_OPTIMIZE_ASSEMBLY
+
+/*****************************************************************************
+ * Macro: WRITE_SCRATCH_STRING
+ * Purpose: Write multiple bytes to the scratchpad buffer
+ *
+ * Arguments:
+ * dword_bytes - number of bytes to transfer. This number will always.
+ * be a multiple of 4. It cannot be modified within the
+ * macro (ex. bytes -= 4)
+ * bytes_extra - number of non-DWORD aligned bytes
+ * array - pointer to an array of unsigned characters.
+ * array_offset - offset into the array from which to pull the first
+ * character.
+ ****************************************************************************/
+
+#define WRITE_SCRATCH_STRING(dwords, bytes, array, array_offset) \
+{ \
+ _asm { mov edi, gfx_gx1_scratch_base } \
+ _asm { mov esi, array } \
+ _asm { add esi, array_offset } \
+ _asm { mov ecx, dwords } \
+ _asm { shr ecx, 2 } \
+ _asm { rep movsd } \
+ _asm { mov ecx, bytes } \
+ _asm { rep movsb } \
+}
+
+/*****************************************************************************
+ * Macro: WRITE_FRAME_BUFFER_STRING32
+ * Purpose: Write multiple dwords to the Frame buffer
+ *
+ * Arguments:
+ * fboffset - offset to the beginning frame buffer location.
+ * bytes - number of bytes to transfer. This number will always.
+ * be a multiple of 4. It cannot be modified within the
+ * macro (ex. bytes -= 4)
+ * array - pointer to an array of unsigned characters.
+ * array_offset - offset into the array from which to pull the first
+ * character.
+ ****************************************************************************/
+
+#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \
+{ \
+ _asm { mov ecx, bytes } \
+ _asm { shr ecx, 2 } \
+ _asm { cld } \
+ _asm { mov edi, gfx_virt_fbptr } \
+ _asm { add edi, fboffset } \
+ _asm { mov esi, array } \
+ _asm { add esi, array_offset } \
+ _asm { rep movsd } \
+}
+
+#else
+
+/*****************************************************************************
+ * Macro: WRITE_SCRATCH_STRING
+ * Purpose: Write multiple bytes to the scratchpad buffer
+ *
+ * Arguments:
+ * dword_bytes - number of bytes to transfer. This number will always.
+ * be a multiple of 4. It cannot be modified within the
+ * macro (ex. bytes -= 4)
+ * bytes_extra - number of non-DWORD aligned bytes
+ * array - pointer to an array of unsigned characters.
+ * array_offset - offset into the array from which to pull the first
+ * character.
+ ****************************************************************************/
+
+#define WRITE_SCRATCH_STRING(dword_bytes, bytes_extra, array, array_offset) \
+{ \
+ unsigned long i, j; \
+ unsigned long aroffset = (unsigned long)array + (array_offset); \
+ \
+ /* WRITE DWORDS */ \
+ \
+ for (i = 0; i < dword_bytes; i += 4) \
+ *((volatile unsigned long *)(gfx_gx1_scratch_base + i)) = \
+ *((unsigned long *)(aroffset + i)); \
+ \
+ /* WRITE BYTES */ \
+ \
+ j = i + bytes_extra; \
+ while (i < j) { \
+ *((volatile unsigned char *)(gfx_gx1_scratch_base + i)) = \
+ *((unsigned char *)(aroffset + i)); \
+ i++; \
+ } \
+}
+
+/*****************************************************************************
+ * Macro: WRITE_FRAME_BUFFER_STRING32
+ * Purpose: Write multiple dwords to the Frame buffer
+ *
+ * Arguments:
+ * fboffset - offset to the beginning frame buffer location.
+ * bytes - number of bytes to transfer. This number will always.
+ * be a multiple of 4. It cannot be modified within the
+ * macro (ex. bytes -= 4)
+ * array - pointer to an array of unsigned characters.
+ * array_offset - offset into the array from which to pull the first
+ * character.
+ ****************************************************************************/
+
+#define WRITE_FRAME_BUFFER_STRING32(fboffset, bytes, array, array_offset) \
+{ \
+ unsigned long i; \
+ unsigned long aroffset = (unsigned long)array + (array_offset); \
+ for (i = 0; i < bytes; i += 4) \
+ WRITE_FB32 ((fboffset) + i, *((unsigned long *)(aroffset + i))); \
+}
+
+#endif
+
+/*****************************************************************************
+ * Macro: WRITE_FRAME_BUFFER_STRING8
+ * Purpose: Write multiple bytes to the frame buffer
+ *
+ * Arguments:
+ * spoffset - offset to the beginning frame buffer location.
+ * bytes - number of bytes to transfer. This number cannot be
+ * modified within the macro (ex. bytes -= 4)
+ * array - pointer to an array of unsigned characters.
+ * array_offset - offset into the array from which to pull the first
+ * character.
+ ****************************************************************************/
+
+#define WRITE_FRAME_BUFFER_STRING8(fboffset, bytes, array, array_offset) \
+{ \
+ unsigned long i; \
+ unsigned long aroffset = (unsigned long)array + (array_offset); \
+ for (i = 0; i < bytes; i++) \
+ WRITE_FB8 ((fboffset) + i, *((unsigned char *)(aroffset + i))); \
+}
+
+/*****************************************************************************
+ * Macro: WRITE_GPREG_STRING32
+ * Purpose: Write multiple dwords to one GP register.
+ *
+ * Arguments:
+ * regoffset - Offset of the GP register to be written.
+ * dwords - number of dwords to transfer. It cannot be modified
+ * within the macro (ex. dwords--)
+ * counter - name of a counter variable that can be used in a loop.
+ * This is used to optimize macros written in C.
+ * array - pointer to an array of unsigned characters.
+ * array_offset - offset into the array from which to pull the first
+ * character.
+ * temp - name of a temporary variable that can be used for
+ * calculations.
+ * This argument is also used for C-only macros.
+ ****************************************************************************/
+
+#define WRITE_GPREG_STRING32(regoffset, dwords, counter, array, \
+ array_offset, temp) \
+{ \
+ temp = (unsigned long)array + (array_offset); \
+ for (counter = 0; counter < dwords; counter++) \
+ WRITE_GP32 (regoffset, *((unsigned long *)temp + counter)); \
+}
+
+/*****************************************************************************
+ * Macro: WRITE_GPREG_STRING8
+ * Purpose: Write 4 or less bytes to one GP register.
+ *
+ * Arguments:
+ * regoffset - Offset of the GP register to be written.
+ * bytes - number of bytes to transfer. This number will always.
+ * be less than 4. It cannot be modified within the
+ * macro (ex. bytes--)
+ * shift - name of a shift variable that can be used as a shift
+ * count.
+ * This variable holds the initial shift value into the
+ * GP register.
+ * counter - name of a counter variable that can be used in a loop.
+ * This is used to optimize macros written in C.
+ * array - pointer to an array of unsigned characters.
+ * array_offset - offset into the array from which to pull the first
+ * character.
+ * temp1 - name of a temporary variable that can be used for
+ * calculations.
+ * This argument is also used for C-only macros.
+ * temp2 - name of a temporary variable that can be used for
+ * calculations.
+ * This argument is also used for C-only macros.
+ ****************************************************************************/
+#define WRITE_GPREG_STRING8(regoffset, bytes, shift, counter, array, \
+ array_offset, temp1, temp2) \
+{ \
+ if (bytes) { \
+ temp1 = (unsigned long)array + (array_offset); \
+ temp2 = 0; \
+ for (counter = 0; counter < bytes; counter++) { \
+ temp2 |= ((unsigned long)(*((unsigned char *)(temp1 + \
+ counter)))) << shift; \
+ shift += 8; \
+ } \
+ WRITE_GP32 (regoffset, temp2); \
+ } \
+}
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_disp.c b/src/gfx/gfx_disp.c
new file mode 100644
index 0000000..035cbab
--- /dev/null
+++ b/src/gfx/gfx_disp.c
@@ -0,0 +1,2925 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to program the display controller.
+ *
+ * The "disp_gu1.c" and "disp_gu2.c" files implement the following routines:
+ *
+ * gfx_get_display_mode_count
+ * gfx_get_display_mode
+ * gfx_is_display_mode_supported
+ * gfx_get_display_details
+ * gfx_set_display_mode
+ * gfx_set_display_bpp
+ * gfx_set_display_timings
+ * gfx_set_vtotal
+ * gfx_get_display_pitch
+ * gfx_set_display_pitch
+ * gfx_set_display_offset
+ * gfx_set_display_palette
+ * gfx_set_display_palette_entry
+ * gfx_set_cursor_enable
+ * gfx_set_cursor_colors
+ * gfx_set_cursor_position
+ * gfx_set_cursor_shape32
+ * gfx_set_cursor_shape64
+ * gfx_set_compression_enable
+ * gfx_set_compression_offset
+ * gfx_set_compression_pitch
+ * gfx_set_compression_size
+ * gfx_set_display_priority_high
+ * gfx_test_timing_active
+ * gfx_test_vertical_active
+ * gfx_wait_vertical_blank
+ * gfx_reset_timing_lock
+ *
+ * And the following routines if GFX_READ_ROUTINES is set:
+ *
+ * gfx_get_hactive
+ * gfx_get_hblank_start
+ * gfx_get_hsync_start
+ * gfx_get_hsync_end
+ * gfx_get_hblank_end
+ * gfx_get_htotal
+ * gfx_get_vactive
+ * gfx_get_vblank_start
+ * gfx_get_vsync_start
+ * gfx_get_vsync_end
+ * gfx_get_vblank_end
+ * gfx_get_vtotal
+ * gfx_get_vline
+ * gfx_get_display_bpp
+ * gfx_get_display_offset
+ * gfx_get_display_palette
+ * gfx_get_cursor_enable
+ * gfx_get_cursor_base
+ * gfx_get_cursor_position
+ * gfx_get_cursor_offset
+ * gfx_get_cursor_color
+ * gfx_get_compression_enable
+ * gfx_get_compression_offset
+ * gfx_get_compression_pitch
+ * gfx_get_compression_size
+ * gfx_get_display_priority_high
+ * gfx_get_valid_bit
+ * */
+
+unsigned short PanelWidth = 0;
+unsigned short PanelHeight = 0;
+unsigned short PanelEnable = 0;
+unsigned short ModeWidth;
+unsigned short ModeHeight;
+
+int DeltaX = 0;
+int DeltaY = 0;
+unsigned long prevstartAddr = 0;
+unsigned long panelTop = 0;
+unsigned long panelLeft = 0;
+
+int gbpp = 8;
+
+int gfx_compression_enabled = 0;
+int gfx_compression_active = 0;
+int gfx_line_double = 0;
+int gfx_pixel_double = 0;
+int gfx_timing_lock = 0;
+DISPLAYMODE gfx_display_mode;
+
+/* DISPLAY MODE TIMINGS */
+
+DISPLAYMODE DisplayParams[] = {
+
+/* 320 x 200 */
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */
+ GFX_MODE_NEG_HSYNC | /* negative HSYNC */
+ GFX_MODE_PIXEL_DOUBLE | /* Double width */
+ GFX_MODE_LINE_DOUBLE, /* Double height */
+ 0x140, 0x288, 0x290, 0x2F0, 0x318, 0x320, /* horizontal timings */
+ 0x0C8, 0x197, 0x19C, 0x19E, 0x1BA, 0x1C1, /* vertical timings */
+ 0x00192CCC, /* freq = 25.175 MHz */
+ },
+
+/* 320 x 240 */
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */
+ GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC | /* negative syncs */
+ GFX_MODE_PIXEL_DOUBLE | /* Double width */
+ GFX_MODE_LINE_DOUBLE, /* Double height */
+ 0x0140, 0x0280, 0x0290, 0x02D0, 0x0348, 0x0348,
+ /* horizontal timings */
+ 0x00F0, 0x01E0, 0x01E1, 0x01E4, 0x01F4, 0x01F4,
+ /* vertical timings */
+ 0x001F8000, /* freq = 31.5 MHz */
+ },
+
+/* 400 x 300 */
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */
+ GFX_MODE_PIXEL_DOUBLE | /* Double width */
+ GFX_MODE_LINE_DOUBLE, /* Double height */
+ 0x0190, 0x0320, 0x0330, 0x0380, 0x0420, 0x0420,
+ /* horizontal timings */
+ 0x012C, 0x0258, 0x0259, 0x025C, 0x0271, 0x0271,
+ /* vertical timings */
+ 0x00318000, /* freq = 49.5 MHz */
+ },
+
+/* 512 x 384 */
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_16BPP | /* 8 and 16 BPP valid */
+ GFX_MODE_PIXEL_DOUBLE | /* Double width */
+ GFX_MODE_LINE_DOUBLE, /* Double height */
+ 0x0200, 0x0400, 0x0410, 0x0470, 0x0520, 0x0520,
+ /* horizontal timings */
+ 0x0180, 0x0300, 0x0301, 0x0304, 0x0320, 0x0320,
+ /* vertical timings */
+ 0x004EC000, /* freq = 78.75 MHz */
+ },
+
+/* 640 x 400 */
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC,
+ /* negative HSYNC */
+ 0x280, 0x288, 0x290, 0x2F0, 0x318, 0x320, /* horizontal timings */
+ 0x190, 0x197, 0x19C, 0x19E, 0x1BA, 0x1C1, /* vertical timings */
+ 0x00192CCC, /* freq = 25.175 MHz */
+ },
+
+/* 640x480 */
+
+ {
+ GFX_MODE_60HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */
+ 0x0280, 0x0288, 0x0290, 0x02E8, 0x0318, 0x0320,
+ /* horizontal timings */
+ 0x01E0, 0x01E8, 0x01EA, 0x01EC, 0x0205, 0x020D,
+ /* vertical timings */
+ 0x00192CCC, /* freq = 25.175 MHz */
+ },
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0280, 0x0280, 0x0298, 0x02D8, 0x0330, 0x0330,
+ /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E2, 0x01E5, 0x01F4, 0x01F4,
+ /* vertical timings */
+ 0x001C8F5C, /* freq = 28.560 MHz */
+ },
+
+ {
+ GFX_MODE_72HZ | /* refresh rate = 72 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */
+ 0x0280, 0x0288, 0x0298, 0x02c0, 0x0338, 0x0340,
+ /* horizontal timings */
+ 0x01e0, 0x01e8, 0x01e9, 0x01ec, 0x0200, 0x0208,
+ /* vertical timings */
+ 0x001F8000, /* freq = 31.5 MHz */
+ },
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */
+ 0x0280, 0x0280, 0x0290, 0x02D0, 0x0348, 0x0348,
+ /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01F4, 0x01F4,
+ /* vertical timings */
+ 0x001F8000, /* freq = 31.5 MHz */
+ },
+
+ {
+ GFX_MODE_85HZ | /* refresh rate = 85 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */
+ 0x0280, 0x0280, 0x02B8, 0x02F0, 0x0340, 0x0340,
+ /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FD, 0x01FD,
+ /* vertical timings */
+ 0x00240000, /* freq = 36.0 MHz */
+ },
+
+ {
+ GFX_MODE_90HZ | /* refresh rate = 90 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0280, 0x0280, 0x02A0, 0x02E0, 0x0340, 0x0340,
+ /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FA, 0x01FA,
+ /* vertical timings */
+ 0x0025E395, /* freq = 37.889 MHz */
+ },
+
+ {
+ GFX_MODE_100HZ | /* refresh rate = 100 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0280, 0x0280, 0x02A8, 0x02E8, 0x0350, 0x0350,
+ /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FD, 0x01FD,
+ /* vertical timings */
+ 0x002B29BA, /* freq = 43.163 MHz */
+ },
+
+/* 800x600 */
+
+ {
+ GFX_MODE_56HZ | /* refresh rate = 56 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0320, 0x0338, 0x0380, 0x0400, 0x0400,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025B, 0x0271, 0x0271,
+ /* vertical timings */
+ 0x00240000, /* freq = 36.00 MHz */
+ },
+
+ {
+ GFX_MODE_60HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0328, 0x0348, 0x03D0, 0x0418, 0x0420,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025D, 0x0274, 0x0274,
+ /* vertical timings */
+ 0x00280000, /* freq = 40.00 MHz */
+ },
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 70 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0320, 0x0348, 0x0398, 0x0410, 0x0410,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x025c, 0x025F, 0x0274, 0x0274,
+ /* vertical timings */
+ 0x002DB851, /* freq = 45.72 MHz */
+ },
+
+ {
+ GFX_MODE_72HZ | /* refresh rate = 72 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0320, 0x0358, 0x03D0, 0x0410, 0x0410,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x027D, 0x0283, 0x029A, 0x029A,
+ /* vertical timings */
+ 0x00320000, /* freq = 49.5 MHz */
+ },
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0320, 0x0330, 0x0380, 0x0420, 0x0420,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0271, 0x0271,
+ /* vertical timings */
+ 0x00318000, /* freq = 49.5 MHz */
+ },
+
+ {
+ GFX_MODE_85HZ | /* refresh rate = 85 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0320, 0x0340, 0x0380, 0x0418, 0x0418,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0277, 0x0277,
+ /* vertical timings */
+ 0x00384000, /* freq = 56.25 MHz */
+ },
+
+ {
+ GFX_MODE_90HZ | /* refresh rate = 90 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0320, 0x0348, 0x03A0, 0x0420, 0x0420,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0278, 0x0278,
+ /* vertical timings */
+ 0x003C10A3, /* freq = 60.065 MHz */
+ },
+
+ {
+ GFX_MODE_100HZ | /* refresh rate = 100 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0320, 0x0320, 0x0350, 0x03A8, 0x0430, 0x0430,
+ /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0277, 0x027C,
+ /* vertical timings */
+ 0x00442DD2, /* freq = 68.179 MHz */
+ },
+
+/* 1024x768 */
+
+ {
+ GFX_MODE_60HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540,
+ /* horizontal timings */
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,
+ /* vertical timings */
+ 0x00410000, /* freq = 65.00 MHz */
+ },
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 70 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP | GFX_MODE_NEG_HSYNC | GFX_MODE_NEG_VSYNC, /* negative syncs */
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0530, 0x0530,
+ /* horizontal timings */
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,
+ /* vertical timings */
+ 0x004B0000, /* freq = 75.00 MHz */
+ },
+
+ {
+ GFX_MODE_72HZ | /* refresh rate = 72 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0400, 0x0400, 0x0438, 0x04A8, 0x0550, 0x0550,
+ /* horizontal timings */
+ 0x0300, 0x0300, 0x0304, 0x0307, 0x0324, 0x0324,
+ /* vertical timings */
+ 0x004EC000, /* freq = 78.75 MHz */
+ },
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0400, 0x0400, 0x0410, 0x0470, 0x0520, 0x0520,
+ /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x0320, 0x0320,
+ /* vertical timings */
+ 0x004EC000, /* freq = 78.75 MHz */
+ },
+
+ {
+ GFX_MODE_85HZ | /* refresh rate = 85 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0400, 0x0400, 0x0430, 0x0490, 0x0560, 0x0560,
+ /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x0328, 0x0328,
+ /* vertical timings */
+ 0x005E8000, /* freq = 94.50 MHz */
+ },
+
+ {
+ GFX_MODE_90HZ | /* refresh rate = 90 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0400, 0x0400, 0x0440, 0x04B0, 0x0560, 0x0560,
+ /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x0329, 0x0329,
+ /* vertical timings */
+ 0x00642FDF, /* freq = 100.187 MHz */
+ },
+
+ {
+ GFX_MODE_100HZ | /* refresh rate = 100 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0400, 0x0400, 0x0448, 0x04B8, 0x0570, 0x0570,
+ /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x032E, 0x032E,
+ /* vertical timings */
+ 0x00714F1A, /* freq = 113.309 MHz */
+ },
+
+/* 1152x864 */
+
+ {
+ GFX_MODE_60HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0480, 0x0480, 0x04C0, 0x0538, 0x05F0, 0x05F0,
+ /* horizontal timings */
+ 0x0360, 0x0360, 0x0361, 0x0364, 0x037F, 0x037F,
+ /* vertical timings */
+ 0x00519999, /* freq = 81.60 MHz */
+ },
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 70 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0480, 0x0480, 0x04C8, 0x0540, 0x0600, 0x0600,
+ /* horizontal timings */
+ 0x0360, 0x0360, 0x0368, 0x036B, 0x038B, 0x038B,
+ /* vertical timings */
+ 0x00618560, /* freq = 97.521 MHz */
+ },
+
+ {
+ GFX_MODE_72HZ | /* refresh rate = 70 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0480, 0x0480, 0x04C8, 0x0548, 0x0610, 0x0610,
+ /* horizontal timings */
+ 0x0360, 0x0360, 0x0367, 0x036A, 0x038B, 0x038B,
+ /* vertical timings */
+ 0x00656B85, /* freq = 101.42 MHz */
+ },
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0480, 0x0480, 0x04C0, 0x0540, 0x0640, 0x0640,
+ /* horizontal timings */
+ 0x0360, 0x0360, 0x0361, 0x0364, 0x0384, 0x0384,
+ /* vertical timings */
+ 0x006C0000, /* freq = 108.00 MHz */
+ },
+
+ {
+ GFX_MODE_85HZ | /* refresh rate = 85 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0480, 0x0480, 0x04C8, 0x0548, 0x0610, 0x0610,
+ /* horizontal timings */
+ 0x0360, 0x0360, 0x0363, 0x0366, 0x038B, 0x038B,
+ /* vertical timings */
+ 0x0077A666, /* freq = 119.65 MHz */
+ },
+
+ {
+ GFX_MODE_90HZ | /* refresh rate = 90 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0480, 0x0480, 0x04D0, 0x0550, 0x0620, 0x0620,
+ /* horizontal timings */
+ 0x0360, 0x0360, 0x0363, 0x0366, 0x038E, 0x038E,
+ /* vertical timings */
+ 0x00806666, /* freq = 128.40 MHz */
+ },
+
+ {
+ GFX_MODE_100HZ | /* refresh rate = 100 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0480, 0x0480, 0x04D0, 0x0550, 0x0620, 0x0620,
+ /* horizontal timings */
+ 0x0360, 0x0360, 0x0365, 0x0368, 0x0398, 0x0398,
+ /* vertical timings */
+ 0x00906147, /* freq = 144.38 MHz */
+ },
+
+/* 1280x1024 */
+
+ {
+ GFX_MODE_60HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0500, 0x0500, 0x0530, 0x05A0, 0x0698, 0x0698,
+ /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A,
+ /* vertical timings */
+ 0x006C0000, /* freq = 108.0 MHz */
+ },
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 70 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0500, 0x0500, 0x0558, 0x05E0, 0x06C0, 0x06C0,
+ /* horizontal timings */
+ 0x0400, 0x0400, 0x040A, 0x040D, 0x0433, 0x0433,
+ /* vertical timings */
+ 0x00821999, /* freq = 130.1 MHz */
+ },
+
+ {
+ GFX_MODE_72HZ | /* refresh rate = 72 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0500, 0x0500, 0x0558, 0x05E0, 0x06C0, 0x06C0,
+ /* horizontal timings */
+ 0x0400, 0x0400, 0x0407, 0x040A, 0x0431, 0x0431,
+ /* vertical timings */
+ 0x00858000, /* freq = 133.5 MHz */
+ },
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0500, 0x0500, 0x0510, 0x05A0, 0x0698, 0x0698,
+ /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A,
+ /* vertical timings */
+ 0x00870000, /* freq = 135.0 MHz */
+ },
+
+ {
+ GFX_MODE_85HZ | /* refresh rate = 85 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0500, 0x0500, 0x0540, 0x05E0, 0x06C0, 0x06C0,
+ /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x0430, 0x0430,
+ /* vertical timings */
+ 0x009D8000, /* freq = 157.5 MHz */
+ },
+
+ {
+ GFX_MODE_90HZ | /* refresh rate = 90 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0500, 0x0500, 0x0560, 0x05E8, 0x06D0, 0x06D0,
+ /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x0436, 0x0436,
+ /* vertical timings */
+ 0x00A933F7, /* freq = 169.203 MHz */
+ },
+
+ {
+ GFX_MODE_100HZ | /* refresh rate = 100 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0500, 0x0500, 0x0560, 0x05F0, 0x06E0, 0x06E0,
+ /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x043D, 0x043D,
+ /* vertical timings */
+ 0x00BEF5C2, /* freq = 190.96 MHz */
+ },
+
+/*********************************/
+/* BEGIN REDCLOUD-SPECIFIC MODES */
+/*-------------------------------*/
+
+/* 1600 x 1200 */
+
+ {
+ GFX_MODE_60HZ | /* refresh rate = 60 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,
+ /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,
+ /* vertical timings */
+ 0x00A20000, /* freq = 162.0 MHz */
+ },
+
+ {
+ GFX_MODE_70HZ | /* refresh rate = 70 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,
+ /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,
+ /* vertical timings */
+ 0x00BD0000, /* freq = 189.0 MHz */
+ },
+
+ {
+ GFX_MODE_72HZ | /* refresh rate = 72 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0640, 0x0640, 0x06B0, 0x0760, 0x0880, 0x0880,
+ /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04BD, 0x04C0, 0x04EF, 0x04EF,
+ /* vertical timings */
+ 0x00C60000, /* freq = 198.0 MHz */
+ },
+
+ {
+ GFX_MODE_75HZ | /* refresh rate = 75 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,
+ /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,
+ /* vertical timings */
+ 0x00CA8000, /* freq = 202.5 MHz */
+ },
+
+ {
+ GFX_MODE_85HZ | /* refresh rate = 85 */
+ GFX_MODE_8BPP | GFX_MODE_12BPP | GFX_MODE_15BPP |
+ /* all BPP valid */
+ GFX_MODE_16BPP | GFX_MODE_24BPP,
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870,
+ /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2,
+ /* vertical timings */
+ 0x00E58000, /* freq = 229.5 MHz */
+ },
+};
+
+/* UPDATE THIS VARIABLE WHENEVER NEW REDCLOUD-SPECIFIC MODES ARE ADDED */
+
+#define REDCLOUD_SPECIFIC_MODES 4
+
+#define NUM_RC_DISPLAY_MODES sizeof(DisplayParams) / sizeof(DISPLAYMODE)
+#define NUM_GX_DISPLAY_MODES (NUM_RC_DISPLAY_MODES - REDCLOUD_SPECIFIC_MODES)
+
+FIXEDTIMINGS FixedParams[] = {
+/* 640x480 Panel */
+ {640, 480, 640, 480,
+ 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320,
+ 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D,
+ 0x00192CCC,
+ },
+
+ {640, 480, 800, 600,
+ 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320,
+ 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D,
+ 0x00192CCC,
+ },
+
+ {640, 480, 1024, 768,
+ 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320,
+ 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D,
+ 0x00192CCC,
+ },
+
+ {640, 480, 1152, 864,
+ 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320,
+ 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D,
+ 0x00192CCC,
+ },
+
+ {640, 480, 1280, 1024,
+ 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320,
+ 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D,
+ 0x00192CCC,
+ },
+
+ {640, 480, 1600, 1200,
+ 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320,
+ 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D,
+ 0x00192CCC,
+ },
+
+/* 800x600 Panel */
+ {800, 600, 640, 480,
+ 0x0280, 0x2d0, 0x2f8, 0x378, 0x3d0, 0x420,
+ 0x1e0, 0x21c, 0x21d, 0x221, 0x238, 0x274,
+ 0x00280000,
+ },
+
+ {800, 600, 800, 600,
+ 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420,
+ 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274,
+ 0x00280000,
+ },
+
+ {800, 600, 1024, 768,
+ 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420,
+ 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274,
+ 0x00280000,
+ },
+
+ {800, 600, 1152, 864,
+ 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420,
+ 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274,
+ 0x00280000,
+ },
+
+ {800, 600, 1280, 1024,
+ 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420,
+ 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274,
+ 0x00280000,
+ },
+
+ {800, 600, 1600, 1200,
+ 0x320, 0x320, 0x348, 0x3c8, 0x420, 0x420,
+ 0x258, 0x258, 0x259, 0x25d, 0x274, 0x274,
+ 0x00280000,
+ },
+
+/* 1024x768 panel */
+ {1024, 768, 640, 480,
+ 0x0280, 0x340, 0x368, 0x3e8, 0x480, 0x540,
+ 0x1e0, 0x270, 0x271, 0x275, 0x296, 0x326,
+ 0x00410000,
+ },
+
+ {1024, 768, 800, 600,
+ 0x0320, 0x390, 0x3b8, 0x438, 0x4D0, 0x540,
+ 0x258, 0x2ac, 0x2ad, 0x2b1, 0x2D2, 0x326,
+ 0x00410000,
+ },
+
+ {1024, 768, 1024, 768,
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540,
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,
+ 0x00410000,
+ },
+
+ {1024, 768, 1152, 864,
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540,
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,
+ 0x00410000,
+ },
+
+ {1024, 768, 1280, 1024,
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540,
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,
+ 0x00410000,
+ },
+
+ {1024, 768, 1600, 1200,
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540,
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326,
+ 0x00410000,
+ },
+
+/* 1280x1024 panel */
+ {1280, 1024, 640, 480,
+ 640, 960, 1008, 1120, 1368, 1688,
+ 480, 752, 753, 756, 794, 1066,
+ 0x006C0000,
+ },
+
+ {1280, 1024, 800, 600,
+ 800, 1040, 1088, 1200, 1448, 1688,
+ 600, 812, 813, 816, 854, 1066,
+ 0x006C0000,
+ },
+
+ {1280, 1024, 1024, 768,
+ 1024, 1152, 1200, 1312, 1560, 1688,
+ 768, 896, 897, 900, 938, 1066,
+ 0x006C0000,
+ },
+
+ {1280, 1024, 1152, 864,
+ 1152, 1216, 1264, 1376, 1624, 1688,
+ 864, 944, 945, 948, 986, 1066,
+ 0x006C0000,
+ },
+
+ {1280, 1024, 1280, 1024,
+ 1280, 1280, 1328, 1440, 1688, 1688,
+ 1024, 1024, 1025, 1028, 1066, 1066,
+ 0x006C0000,
+ },
+
+};
+
+#define NUM_FIXED_TIMINGS_MODES sizeof(FixedParams)/sizeof(FIXEDTIMINGS)
+
+/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */
+
+#if GFX_DISPLAY_GU1
+#include "disp_gu1.c"
+#endif
+
+/* INCLUDE SUPPORT FOR SECOND GENERATION, IF SPECIFIED. */
+
+#if GFX_DISPLAY_GU2
+#include "disp_gu2.c"
+#endif
+
+#if GFX_DISPLAY_GU3
+#include "disp_gu3.c"
+#endif
+
+/*---------------------------------------------------------------------------
+ * gfx_reset_timing_lock
+ *
+ * This routine resets the timing change lock. The lock can only be set by
+ * setting a flag when calling mode set.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_reset_timing_lock(void)
+{
+ gfx_timing_lock = 0;
+}
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either first or second generation routines. */
+
+#if GFX_DISPLAY_DYNAMIC
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_bpp
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_display_bpp(unsigned short bpp)
+{
+ int retval = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_set_display_bpp(bpp);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_set_display_bpp(bpp);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_set_display_bpp(bpp);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_is_display_mode_supported
+ * check if given mode supported,
+ * return the supported mode on success, -1 on fail
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+{
+ int retval = -1;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_is_display_mode_supported(xres, yres, bpp, hz);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_is_display_mode_supported(xres, yres, bpp, hz);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_is_display_mode_supported(xres, yres, bpp, hz);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_mode
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_display_mode(int xres, int yres, int bpp, int hz)
+{
+ int retval = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_set_display_mode(xres, yres, bpp, hz);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_set_display_mode(xres, yres, bpp, hz);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_set_display_mode(xres, yres, bpp, hz);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_timings
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal, unsigned long frequency)
+{
+ int retval = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_set_display_timings(bpp, flags,
+ hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal,
+ vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal,
+ frequency);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_set_display_timings(bpp, flags,
+ hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal,
+ vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal,
+ frequency);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_set_display_timings(bpp, flags,
+ hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal,
+ vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal,
+ frequency);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_pitch
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_pitch(unsigned short pitch)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_display_pitch(pitch);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_pitch(pitch);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_pitch(pitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_offset
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_offset(unsigned long offset)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_display_offset(offset);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_offset(offset);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_offset(offset);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette_entry
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_set_display_palette_entry(index, palette);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_set_display_palette_entry(index, palette);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_set_display_palette_entry(index, palette);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_display_palette(unsigned long *palette)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_set_display_palette(palette);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_set_display_palette(palette);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_set_display_palette(palette);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_enable
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_cursor_enable(int enable)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_cursor_enable(enable);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_cursor_enable(enable);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_cursor_enable(enable);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_colors
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_cursor_colors(bkcolor, fgcolor);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_cursor_colors(bkcolor, fgcolor);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_cursor_colors(bkcolor, fgcolor);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_position
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_cursor_position(memoffset, xpos, ypos, xhotspot, yhotspot);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_cursor_position(memoffset, xpos, ypos, xhotspot, yhotspot);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_cursor_position(memoffset, xpos, ypos, xhotspot, yhotspot);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape32
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_cursor_shape32(memoffset, andmask, xormask);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_cursor_shape32(memoffset, andmask, xormask);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_cursor_shape32(memoffset, andmask, xormask);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape64
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_cursor_shape64(memoffset, andmask, xormask);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_cursor_shape64(memoffset, andmask, xormask);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_enable
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_icon_enable(int enable)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_icon_enable(enable);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_colors
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_icon_colors(unsigned long color0, unsigned long color1,
+ unsigned long color2)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_icon_colors(color0, color1, color2);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_position
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_icon_position(unsigned long memoffset, unsigned short xpos)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_icon_position(memoffset, xpos);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_icon_shape64
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_icon_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask, unsigned int lines)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_icon_shape64(memoffset, andmask, xormask, lines);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_compression_enable(int enable)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_set_compression_enable(enable);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_set_compression_enable(enable);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_set_compression_enable(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_offset
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_compression_offset(unsigned long offset)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_set_compression_offset(offset);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_set_compression_offset(offset);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_set_compression_offset(offset);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_pitch
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_compression_pitch(unsigned short pitch)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_set_compression_pitch(pitch);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_set_compression_pitch(pitch);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_set_compression_pitch(pitch);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_size
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_compression_size(unsigned short size)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_set_compression_size(size);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_set_compression_size(size);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_set_compression_size(size);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_priority_high
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_priority_high(int enable)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_display_priority_high(enable);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_format". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_format(unsigned long format)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_format(format);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_video_format(format);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_color_key (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_color_key". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_color_key(unsigned long key, unsigned long mask,
+ int enable)
+{
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_video_color_key(key, mask, enable);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_enable". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_enable(int enable)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_display_video_enable(enable);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_enable(enable);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_video_enable(enable);
+#endif
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_size(unsigned short width, unsigned short height)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_display_video_size(width, height);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_size(width, height);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_video_size(width, height);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_offset(unsigned long offset)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_set_display_video_offset(offset);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_offset(offset);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_video_offset(offset);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_yuv_offsets". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_yuv_pitch". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_yuv_pitch(ypitch, uvpitch);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_set_display_video_yuv_pitch(ypitch, uvpitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_downscale (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_vertical_downscale". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_downscale(unsigned short srch, unsigned short dsth)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_downscale(srch, dsth);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_vertical_downscale_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_vertical_downscale_enable". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_display_video_vertical_downscale_enable(int enable)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_set_display_video_vertical_downscale_enable(enable);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_timing_active
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_test_timing_active(void)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_test_timing_active();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_test_timing_active();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_test_timing_active();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_vertical_active
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_test_vertical_active(void)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_test_vertical_active();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_test_vertical_active();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_test_vertical_active();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_wait_vertical_blank
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_wait_vertical_blank(void)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_wait_vertical_blank();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_wait_vertical_blank();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_wait_vertical_blank();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_delay_milliseconds
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_delay_milliseconds(unsigned long milliseconds)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_delay_milliseconds(milliseconds);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_delay_milliseconds(milliseconds);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_delay_milliseconds(milliseconds);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_delay_microseconds
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_delay_microseconds(unsigned long microseconds)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_delay_microseconds(microseconds);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_delay_microseconds(microseconds);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_delay_microseconds(microseconds);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_panning
+ *
+ * This routine enables the panning when the Mode is bigger than the panel
+ * size.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_enable_panning(int x, int y)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_enable_panning(x, y);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_enable_panning(x, y);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_enable_panning(x, y);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_is_panel_mode_supported
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_is_panel_mode_supported(int panelResX, int panelResY,
+ unsigned short width, unsigned short height, unsigned short bpp)
+{
+ int status = -1;
+
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status =
+ gu2_is_panel_mode_supported(panelResX, panelResY, width, height,
+ bpp);
+#endif
+
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_fixed_timings
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status =
+ gu1_set_fixed_timings(panelResX, panelResY, width, height, bpp);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status =
+ gu2_set_fixed_timings(panelResX, panelResY, width, height, bpp);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status =
+ gu3_set_fixed_timings(panelResX, panelResY, width, height, bpp);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_panel_present
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status =
+ gu1_set_panel_present(panelResX, panelResY, width, height, bpp);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status =
+ gu2_set_panel_present(panelResX, panelResY, width, height, bpp);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status =
+ gu3_set_panel_present(panelResX, panelResY, width, height, bpp);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vtotal
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_vtotal(unsigned short vtotal)
+{
+ int retval = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_set_vtotal(vtotal);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_set_vtotal(vtotal);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_set_vtotal(vtotal);
+#endif
+ return (retval);
+}
+
+/*-----------------------------------------------------------------------*
+ * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: *
+ * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal *
+ * are used by the video overlay routines. *
+ * *
+ * gfx_get_vline and gfx_vactive are used to prevent an issue for the *
+ * SC1200. *
+ * *
+ * The others are part of the Durango API. *
+ *-----------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * gfx_mode_frequency_supported
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency)
+{
+ int freq = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ freq = gu1_mode_frequency_supported(xres, yres, bpp, frequency);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ freq = gu2_mode_frequency_supported(xres, yres, bpp, frequency);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ freq = gu3_mode_frequency_supported(xres, yres, bpp, frequency);
+#endif
+ return (freq);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_frequency
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_get_refreshrate_from_frequency(xres, yres, bpp, hz, frequency);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_get_refreshrate_from_frequency(xres, yres, bpp, hz, frequency);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_get_refreshrate_from_frequency(xres, yres, bpp, hz, frequency);
+#endif
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_mode
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_get_refreshrate_from_mode(xres, yres, bpp, hz, frequency);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_get_refreshrate_from_mode(xres, yres, bpp, hz, frequency);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_get_refreshrate_from_mode(xres, yres, bpp, hz, frequency);
+#endif
+
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frequency_from_refreshrate
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency)
+{
+ int retval = -1;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval =
+ gu1_get_frequency_from_refreshrate(xres, yres, bpp, hz,
+ frequency);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval =
+ gu2_get_frequency_from_refreshrate(xres, yres, bpp, hz,
+ frequency);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval =
+ gu3_get_frequency_from_refreshrate(xres, yres, bpp, hz,
+ frequency);
+#endif
+
+ return retval;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_supported_pixel_clock
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_max_supported_pixel_clock(void)
+{
+ unsigned long status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_get_max_supported_pixel_clock();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_get_max_supported_pixel_clock();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_get_max_supported_pixel_clock();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_pitch
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_display_pitch(void)
+{
+ unsigned short pitch = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ pitch = gu1_get_display_pitch();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ pitch = gu2_get_display_pitch();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ pitch = gu3_get_display_pitch();
+#endif
+ return (pitch);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_mode_count
+ * return # of modes supported.
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_display_mode_count(void)
+{
+ int retval = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_get_display_mode_count();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_get_display_mode_count();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_get_display_mode_count();
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_frame_buffer_line_size
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_frame_buffer_line_size(void)
+{
+ unsigned long retval = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_get_frame_buffer_line_size();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_get_frame_buffer_line_size();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_get_frame_buffer_line_size();
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_mode
+ * get the curent mode set,
+ * return the supported mode on success, -1 on fail
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+{
+ int retval = -1;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_get_display_mode(xres, yres, bpp, hz);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_get_display_mode(xres, yres, bpp, hz);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_get_display_mode(xres, yres, bpp, hz);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_details
+ * given the mode get's the resoultion details, width, height, freq
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+{
+ int retval = -1;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ retval = gu1_get_display_details(mode, xres, yres, hz);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ retval = gu2_get_display_details(mode, xres, yres, hz);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ retval = gu3_get_display_details(mode, xres, yres, hz);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hactive
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_hactive(void)
+{
+ unsigned short hactive = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ hactive = gu1_get_hactive();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ hactive = gu2_get_hactive();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ hactive = gu3_get_hactive();
+#endif
+ return (hactive);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_start
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_hsync_start(void)
+{
+ unsigned short hsync_start = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ hsync_start = gu1_get_hsync_start();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ hsync_start = gu2_get_hsync_start();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ hsync_start = gu3_get_hsync_start();
+#endif
+ return (hsync_start);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_end
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_hsync_end(void)
+{
+ unsigned short hsync_end = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ hsync_end = gu1_get_hsync_end();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ hsync_end = gu2_get_hsync_end();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ hsync_end = gu3_get_hsync_end();
+#endif
+ return (hsync_end);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_htotal
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_htotal(void)
+{
+ unsigned short htotal = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ htotal = gu1_get_htotal();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ htotal = gu2_get_htotal();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ htotal = gu3_get_htotal();
+#endif
+ return (htotal);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vactive
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_vactive(void)
+{
+ unsigned short vactive = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ vactive = gu1_get_vactive();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ vactive = gu2_get_vactive();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ vactive = gu3_get_vactive();
+#endif
+ return (vactive);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_end
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_vsync_end(void)
+{
+ unsigned short vsync_end = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ vsync_end = gu1_get_vsync_end();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ vsync_end = gu2_get_vsync_end();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ vsync_end = gu3_get_vsync_end();
+#endif
+ return (vsync_end);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vtotal
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_vtotal(void)
+{
+ unsigned short vtotal = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ vtotal = gu1_get_vtotal();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ vtotal = gu2_get_vtotal();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ vtotal = gu3_get_vtotal();
+#endif
+ return (vtotal);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_bpp
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_display_bpp(void)
+{
+ unsigned short bpp = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ bpp = gu1_get_display_bpp();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ bpp = gu2_get_display_bpp();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ bpp = gu3_get_display_bpp();
+#endif
+ return (bpp);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vline
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_vline(void)
+{
+ unsigned short vline = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ vline = gu1_get_vline();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ vline = gu2_get_vline();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ vline = gu3_get_vline();
+#endif
+ return (vline);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_offset
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_display_offset(void)
+{
+ unsigned long offset = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ offset = gu1_get_display_offset();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ offset = gu2_get_display_offset();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ offset = gu3_get_display_offset();
+#endif
+ return (offset);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_cursor_offset(void)
+{
+ unsigned long base = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ base = gu1_get_cursor_offset();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ base = gu2_get_cursor_offset();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ base = gu3_get_cursor_offset();
+#endif
+ return (base);
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_start
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_hblank_start(void)
+{
+ unsigned short hblank_start = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ hblank_start = gu1_get_hblank_start();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ hblank_start = gu2_get_hblank_start();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ hblank_start = gu3_get_hblank_start();
+#endif
+ return (hblank_start);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_end
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_hblank_end(void)
+{
+ unsigned short hblank_end = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ hblank_end = gu1_get_hblank_end();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ hblank_end = gu2_get_hblank_end();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ hblank_end = gu3_get_hblank_end();
+#endif
+ return (hblank_end);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_start
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_vblank_start(void)
+{
+ unsigned short vblank_start = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ vblank_start = gu1_get_vblank_start();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ vblank_start = gu2_get_vblank_start();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ vblank_start = gu3_get_vblank_start();
+#endif
+ return (vblank_start);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_start
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_vsync_start(void)
+{
+ unsigned short vsync_start = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ vsync_start = gu1_get_vsync_start();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ vsync_start = gu2_get_vsync_start();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ vsync_start = gu3_get_vsync_start();
+#endif
+ return (vsync_start);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_end
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_vblank_end(void)
+{
+ unsigned short vblank_end = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ vblank_end = gu1_get_vblank_end();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ vblank_end = gu2_get_vblank_end();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ vblank_end = gu3_get_vblank_end();
+#endif
+ return (vblank_end);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_palette_entry
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
+{
+ int status = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ status = gu1_get_display_palette_entry(index, palette);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ status = gu2_get_display_palette_entry(index, palette);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ status = gu3_get_display_palette_entry(index, palette);
+#endif
+
+ return status;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_palette
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_display_palette(unsigned long *palette)
+{
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ gu1_get_display_palette(palette);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_get_display_palette(palette);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_get_display_palette(palette);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_cursor_enable
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_cursor_enable(void)
+{
+ unsigned long enable = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ enable = gu1_get_cursor_enable();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ enable = gu2_get_cursor_enable();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ enable = gu3_get_cursor_enable();
+#endif
+ return (enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_cursor_position
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_cursor_position(void)
+{
+ unsigned long position = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ position = gu1_get_cursor_position();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ position = gu2_get_cursor_position();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ position = gu3_get_cursor_position();
+#endif
+ return (position);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_cursor_clip
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_cursor_clip(void)
+{
+ unsigned long offset = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ offset = gu1_get_cursor_clip();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ offset = gu2_get_cursor_clip();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ offset = gu3_get_cursor_clip();
+#endif
+ return (offset);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_cursor_color
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_cursor_color(int index)
+{
+ unsigned long color = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ color = gu1_get_cursor_color(index);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ color = gu2_get_cursor_color(index);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ color = gu3_get_cursor_color(index);
+#endif
+ return (color);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_icon_enable
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_icon_enable(void)
+{
+ unsigned long enable = 0;
+
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ enable = gu2_get_icon_enable();
+#endif
+ return (enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_icon_offset
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_icon_offset(void)
+{
+ unsigned long base = 0;
+
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ base = gu2_get_icon_offset();
+#endif
+
+ return (base);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_icon_position
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_icon_position(void)
+{
+ unsigned long position = 0;
+
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ position = gu2_get_icon_position();
+#endif
+
+ return (position);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_icon_color
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_icon_color(int index)
+{
+ unsigned long color = 0;
+
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ color = gu2_get_icon_color(index);
+#endif
+
+ return (color);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_compression_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_compression_enable(void)
+{
+ int enable = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ enable = gu1_get_compression_enable();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ enable = gu2_get_compression_enable();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ enable = gu3_get_compression_enable();
+#endif
+ return (enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_compression_offset
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_compression_offset(void)
+{
+ unsigned long offset = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ offset = gu1_get_compression_offset();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ offset = gu2_get_compression_offset();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ offset = gu3_get_compression_offset();
+#endif
+ return (offset);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_compression_pitch
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_compression_pitch(void)
+{
+ unsigned short pitch = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ pitch = gu1_get_compression_pitch();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ pitch = gu2_get_compression_pitch();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ pitch = gu3_get_compression_pitch();
+#endif
+ return (pitch);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_compression_size
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+gfx_get_compression_size(void)
+{
+ unsigned short size = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ size = gu1_get_compression_size();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ size = gu2_get_compression_size();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ size = gu3_get_compression_size();
+#endif
+ return (size);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_priority_high
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_display_priority_high(void)
+{
+ int high = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ high = gu1_get_display_priority_high();
+#endif
+ return (high);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_valid_bit
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_valid_bit(int line)
+{
+ int valid = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ valid = gu1_get_valid_bit(line);
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ valid = gu2_get_valid_bit(line);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ valid = gu3_get_valid_bit(line);
+#endif
+ return (valid);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_color_key
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_display_video_color_key(void)
+{
+ unsigned long value = 0;
+
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ value = gu3_get_display_video_color_key();
+#endif
+ return (value);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_offset
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_display_video_offset(void)
+{
+ unsigned long offset = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ offset = gu1_get_display_video_offset();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ offset = gu2_get_display_video_offset();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ offset = gu3_get_display_video_offset();
+#endif
+ return (offset);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_offsets
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_display_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_get_display_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_get_display_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_offsets
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+{
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ gu2_get_display_video_yuv_pitch(ypitch, uvpitch);
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ gu3_get_display_video_yuv_pitch(ypitch, uvpitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_downscale_delta
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_display_video_downscale_delta(void)
+{
+ unsigned long ret_value = 0;
+
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ ret_value = gu2_get_display_video_downscale_delta();
+#endif
+
+ return ret_value;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_downscale_delta
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_display_video_downscale_enable(void)
+{
+ int ret_value = 0;
+
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ ret_value = gu2_get_display_video_downscale_enable();
+#endif
+
+ return ret_value;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_size
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_display_video_size(void)
+{
+ unsigned long size = 0;
+
+#if GFX_DISPLAY_GU1
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU1)
+ size = gu1_get_display_video_size();
+#endif
+#if GFX_DISPLAY_GU2
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU2)
+ size = gu2_get_display_video_size();
+#endif
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ size = gu3_get_display_video_size();
+#endif
+ return (size);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_color_key_mask
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_display_video_color_key_mask(void)
+{
+ unsigned long mask = 0;
+
+#if GFX_DISPLAY_GU3
+ if (gfx_display_type & GFX_DISPLAY_TYPE_GU3)
+ mask = gu3_get_display_video_color_key_mask();
+#endif
+ return (mask);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+#endif /* GFX_DISPLAY_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_i2c.c b/src/gfx/gfx_i2c.c
new file mode 100644
index 0000000..7a3ad42
--- /dev/null
+++ b/src/gfx/gfx_i2c.c
@@ -0,0 +1,168 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to write to and read from the I2C bus.
+ * */
+
+/* INCLUDE ROUTINES FOR ACCESS.BUS, IF SPECIFIED */
+/* This is for SC1200 systems. */
+
+#if GFX_I2C_ACCESS
+#include "i2c_acc.c"
+#endif
+
+/* INCLUDE ROUTINES FOR CS5530 GPIOs, IF SPECIFIED */
+/* This is for GXLV systems that use GPIOs on the CS5530 for I2C. */
+
+#if GFX_I2C_GPIO
+#include "i2c_gpio.c"
+#endif
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either ACCESS.bus or GPIO routines. */
+
+#if GFX_I2C_DYNAMIC
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_reset
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_i2c_reset(unsigned char busnum, short adr, char freq)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_I2C_ACCESS
+ if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS)
+ status = acc_i2c_reset(busnum, adr, freq);
+#endif
+#if GFX_I2C_GPIO
+ if (gfx_i2c_type & GFX_I2C_TYPE_GPIO)
+ status = gpio_i2c_reset(busnum, adr, freq);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_select_gpio
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_i2c_select_gpio(int clock, int data)
+{
+#if GFX_I2C_ACCESS
+ if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS)
+ acc_i2c_select_gpio(clock, data);
+#endif
+#if GFX_I2C_GPIO
+ if (gfx_i2c_type & GFX_I2C_TYPE_GPIO)
+ gpio_i2c_select_gpio(clock, data);
+#endif
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_write
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_i2c_write(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data)
+{
+ int status = -1;
+
+#if GFX_I2C_ACCESS
+ if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS)
+ status = acc_i2c_write(busnum, chipadr, subadr, bytes, data);
+#endif
+#if GFX_I2C_GPIO
+ if (gfx_i2c_type & GFX_I2C_TYPE_GPIO)
+ status = gpio_i2c_write(busnum, chipadr, subadr, bytes, data);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_read
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_i2c_read(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data)
+{
+ int status = -1;
+
+#if GFX_I2C_ACCESS
+ if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS)
+ status = acc_i2c_read(busnum, chipadr, subadr, bytes, data);
+#endif
+#if GFX_I2C_GPIO
+ if (gfx_i2c_type & GFX_I2C_TYPE_GPIO)
+ status = gpio_i2c_read(busnum, chipadr, subadr, bytes, data);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_init
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_i2c_init(void)
+{
+ int status = -1;
+
+#if GFX_I2C_ACCESS
+ if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS)
+ status = acc_i2c_init();
+#endif
+#if GFX_I2C_GPIO
+ if (gfx_i2c_type & GFX_I2C_TYPE_GPIO)
+ status = gpio_i2c_init();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_cleanup
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_i2c_cleanup(void)
+{
+#if GFX_I2C_ACCESS
+ if (gfx_i2c_type & GFX_I2C_TYPE_ACCESS)
+ acc_i2c_cleanup();
+#endif
+#if GFX_I2C_GPIO
+ if (gfx_i2c_type & GFX_I2C_TYPE_GPIO)
+ gpio_i2c_cleanup();
+#endif
+}
+
+#endif /* GFX_I2C_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_init.c b/src/gfx/gfx_init.c
new file mode 100644
index 0000000..73a8c80
--- /dev/null
+++ b/src/gfx/gfx_init.c
@@ -0,0 +1,731 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines typically used in driver initialization.
+ *
+ * Routines:
+ *
+ * gfx_pci_config_read
+ * gfx_cpu_config_read
+ * gfx_detect_cpu
+ * gfx_detect_video
+ * gfx_get_cpu_register_base
+ * gfx_get_frame_buffer_base
+ * gfx_get_frame_buffer_size
+ * gfx_get_vid_register_base
+ * gfx_get_vip_register_base
+ * */
+
+/* CONSTANTS USED BY THE INITIALIZATION CODE */
+
+#define PCI_CONFIG_ADDR 0x0CF8
+#define PCI_CONFIG_DATA 0x0CFC
+#define PCI_VENDOR_DEVICE_GXM 0x00011078
+#define PCI_VENDOR_DEVICE_REDCLOUD 0x0028100B
+#define REDCLOUD_VIDEO_PCI_VENDOR_DEVICE 0x0030100B
+#define PCI_VENDOR_DEVICE_CASTLE 0x20801022
+#define CASTLE_VIDEO_PCI_VENDOR_DEVICE 0x20811022
+
+#define GXM_CONFIG_GCR 0xB8
+#define GXM_CONFIG_CCR3 0xC3
+#define GXM_CONFIG_DIR0 0xFE
+#define GXM_CONFIG_DIR1 0xFF
+
+/* STATIC VARIABLES FOR THIS FILE */
+
+unsigned long gfx_cpu_version = 0;
+unsigned long gfx_cpu_frequency = 0;
+unsigned long gfx_vid_version = 0;
+unsigned long gfx_gx1_scratch_base = 0;
+unsigned long gfx_gx2_scratch_base = 0x7FC000;
+unsigned long gfx_pci_speed_khz = 33300;
+ChipType gfx_chip_revision = CHIP_NOT_DETECTED;
+
+ChipType gfx_detect_chip(void);
+
+/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */
+
+#if GFX_INIT_GU1
+#include "init_gu1.c"
+#endif
+
+/* INCLUDE SUPPORT FOR SECOND GENERATION, IF SPECIFIED. */
+
+#if GFX_INIT_GU2
+#include "init_gu2.c"
+#endif
+
+/* INCLUDE SUPPORT FOR THIRD GENERATION, IF SPECIFIED. */
+
+#if GFX_INIT_GU3
+#include "init_gu3.c"
+#endif
+
+/* THE FOLLOWING ROUTINES ARE NEVER DYNAMIC */
+/* They are used to set the variables for future dynamic */
+/* function calls. */
+
+/*----------------------------------------------------------------------------
+ * gfx_detect_chip
+ *
+ * This routine returns the name and revision of the chip. This function is
+ * only relevant to the SC1200.
+ *----------------------------------------------------------------------------
+ */
+ChipType
+gfx_detect_chip(void)
+{
+ unsigned char pid = INB(SC1200_CB_BASE_ADDR + SC1200_CB_PID);
+ unsigned char rev = INB(SC1200_CB_BASE_ADDR + SC1200_CB_REV);
+ unsigned short clk = INW(SC1200_CB_BASE_ADDR + SC1200_CB_CCFC);
+
+ gfx_chip_revision = CHIP_NOT_DETECTED;
+
+ if (pid == 0x4) {
+ switch (rev) {
+ case 0:
+ gfx_chip_revision = SC1200_REV_A;
+ break;
+ case 1:
+ gfx_chip_revision = SC1200_REV_B1_B2;
+ break;
+ case 2:
+ gfx_chip_revision = SC1200_REV_B3;
+ break;
+ case 3:
+ gfx_chip_revision = SC1200_REV_C1;
+ break;
+ case 4:
+ gfx_chip_revision = SC1200_REV_D1;
+ break;
+ case 5:
+ gfx_chip_revision = SC1200_REV_D1_1;
+ break;
+ case 6:
+ gfx_chip_revision = SC1200_REV_D2_MVD;
+ break;
+ }
+ if (rev > 0x6)
+ gfx_chip_revision = SC1200_FUTURE_REV;
+ } else if (pid == 0x5) {
+ if (rev == 0x6)
+ gfx_chip_revision = SC1200_REV_D2_MVE;
+ else if (rev > 0x6)
+ gfx_chip_revision = SC1200_FUTURE_REV;
+ }
+
+ switch ((clk >> 8) & 3) {
+ case 0:
+ default:
+ gfx_pci_speed_khz = 33300;
+ break;
+ case 1:
+ gfx_pci_speed_khz = 48000;
+ break;
+ case 2:
+ gfx_pci_speed_khz = 66600;
+ break;
+ }
+
+ return (gfx_chip_revision);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_detect_cpu
+ *
+ * This routine returns the type and revison of the CPU. If a Geode
+ * processor is not present, the routine returns zero.
+ *
+ * The return value is as follows:
+ * bits[24:16] = minor version
+ * bits[15:8] = major version
+ * bits[7:0] = type (1 = GXm, 2 = SC1200, 3 = Redcloud)
+ *
+ * A return value of 0x00020501, for example, indicates GXm version 5.2.
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_detect_cpu(void)
+{
+
+ unsigned long value = 0;
+ unsigned long version = 0;
+
+ /* initialize core freq. to 0 */
+ gfx_cpu_frequency = 0;
+
+#if GFX_INIT_GU1
+
+ value = gfx_pci_config_read(0x80000000);
+
+ if (value == PCI_VENDOR_DEVICE_GXM) {
+ unsigned char dir0 = gfx_gxm_config_read(GXM_CONFIG_DIR0) & 0xF0;
+ unsigned char dir1 = gfx_gxm_config_read(GXM_CONFIG_DIR1);
+
+ if (dir0 == 0x40) {
+ /* CHECK FOR GXLV (and GXm) (DIR1 = 0x30 THROUGH 0x82) */
+
+ if ((dir1 >= 0x30) && (dir1 <= 0x82)) {
+ /* Major version is one less than what appears in DIR1 */
+ if ((dir1 & 0xF0) < 0x70) {
+
+ version = GFX_CPU_GXLV | (((((unsigned long)dir1 >> 4) - 1) << 8)) | /* major - 1 */
+ ((((unsigned long)dir1 & 0x0F)) << 16); /* minor */
+ } else {
+ version = GFX_CPU_GXLV | ((((unsigned long)dir1 >> 4))
+ << 8) | /* major */
+ ((((unsigned long)dir1 & 0x0F)) << 16); /* minor */
+ }
+ /* Currently always CS5530 for video overlay. */
+
+#if GFX_VIDEO_DYNAMIC
+ gfx_video_type = GFX_VIDEO_TYPE_CS5530;
+#endif
+
+ /* Currently always CS5530 GPIOs for I2C access. */
+
+#if GFX_I2C_DYNAMIC
+ gfx_i2c_type = GFX_I2C_TYPE_GPIO;
+#endif
+
+#if GFX_TV_DYNAMIC
+ gfx_tv_type = GFX_TV_TYPE_FS451;
+#endif
+ }
+ } else if (dir0 == 0xB0) {
+ /* CHECK FOR SC1200 */
+
+ if ((dir1 == 0x70) || (dir1 == 0x81)) {
+ version = GFX_CPU_SC1200 | ((((unsigned long)dir1 >> 4))
+ << 8) | /* major */
+ ((((unsigned long)dir1 & 0x0F)) << 16); /* minor */
+
+ /* Detect SC1200 revision */
+
+ gfx_detect_chip();
+
+ /* SC1200 for video overlay and VIP. */
+
+#if GFX_VIDEO_DYNAMIC
+ gfx_video_type = GFX_VIDEO_TYPE_SC1200;
+#endif
+
+#if GFX_VIP_DYNAMIC
+ gfx_vip_type = GFX_VIP_TYPE_SC1200;
+#endif
+
+ /* Currently always SAA7114 decoder. */
+
+#if GFX_DECODER_DYNAMIC
+ gfx_decoder_type = GFX_DECODER_TYPE_SAA7114;
+#endif
+
+ /* SC1200 for TV encoder */
+
+#if GFX_TV_DYNAMIC
+ gfx_tv_type = GFX_TV_TYPE_SC1200;
+#endif
+
+ /* Currently always ACCESS.bus for I2C access. */
+
+#if GFX_I2C_DYNAMIC
+ gfx_i2c_type = GFX_I2C_TYPE_ACCESS;
+#endif
+ }
+ }
+
+ if (version) {
+ /* ALWAYS FIRST GENERATION GRAPHICS UNIT */
+
+#if GFX_DISPLAY_DYNAMIC
+ gfx_display_type = GFX_DISPLAY_TYPE_GU1;
+#endif
+#if GFX_2DACCEL_DYNAMIC
+ gfx_2daccel_type = GFX_2DACCEL_TYPE_GU1;
+#endif
+#if GFX_INIT_DYNAMIC
+ gfx_init_type = GFX_INIT_TYPE_GU1;
+#endif
+
+ /* READ THE CORE FREQUENCY */
+
+ gfx_cpu_frequency = gfx_get_core_freq();
+ }
+ }
+#endif
+
+#if GFX_INIT_GU2
+
+ value = gfx_pci_config_read(0x80000800);
+
+ if (value == PCI_VENDOR_DEVICE_REDCLOUD) {
+ Q_WORD msr_value;
+ int valid, i;
+
+ /* CHECK FOR SOFT VG */
+ /* If SoftVG is not present, the base addresses for all devices */
+ /* will not be allocated. Essentially, it is as if no Redcloud */
+ /* video hardware is present. */
+
+ value = gfx_pci_config_read(0x80000900);
+
+ if (value == REDCLOUD_VIDEO_PCI_VENDOR_DEVICE) {
+ valid = 1;
+
+ /* BAR0 - BAR3 HOLD THE PERIPHERAL BASE ADDRESSES */
+
+ for (i = 0; i < 4; i++) {
+ value = gfx_pci_config_read(0x80000910 + (i << 2));
+ if (value == 0x00000000 || value == 0xFFFFFFFF) {
+ valid = 0;
+ break;
+ }
+ }
+
+ if (valid) {
+ /* REDCLOUD INTEGRATED VIDEO */
+
+#if GFX_VIDEO_DYNAMIC
+ gfx_video_type = GFX_VIDEO_TYPE_REDCLOUD;
+#endif
+
+ /* CURRENTLY, ALWAYS GPIO FOR I2C ACCESS */
+
+#if GFX_I2C_DYNAMIC
+ gfx_i2c_type = GFX_I2C_TYPE_GPIO;
+#endif
+
+ /* SECOND-GENERATION DISPLAY CONTROLLER */
+
+#if GFX_DISPLAY_DYNAMIC
+ gfx_display_type = GFX_DISPLAY_TYPE_GU2;
+#endif
+
+ /* SECOND-GENERATION GRAPHICS UNIT */
+
+#if GFX_2DACCEL_DYNAMIC
+ gfx_2daccel_type = GFX_2DACCEL_TYPE_GU2;
+#endif
+
+ /* SECOND-GENERATION INITIALIZATION */
+
+#if GFX_INIT_DYNAMIC
+ gfx_init_type = GFX_INIT_TYPE_GU2;
+#endif
+
+ /* MBUS MSR ACCESSES */
+
+#if GFX_MSR_DYNAMIC
+ gfx_msr_type = GFX_MSR_TYPE_REDCLOUD;
+#endif
+
+ /* CS5530 GPIO I2C */
+
+#if GFX_I2C_DYNAMIC
+ gfx_i2c_type = GFX_I2C_TYPE_GPIO;
+#endif
+
+ /* READ VERSION */
+
+ gfx_msr_init();
+
+ gfx_msr_read(RC_ID_MCP, MCP_RC_REVID, &msr_value);
+
+ /* SUBTRACT 1 FROM REV ID */
+ /* REDCLOUD 1.X rev id is 1 less than the reported value */
+
+ if ((msr_value.low & 0xF0) == 0x10)
+ msr_value.low--;
+
+ version = GFX_CPU_REDCLOUD | ((msr_value.low & 0xF0) << 4) | /* MAJOR */
+ ((msr_value.low & 0x0F) << 16); /* MINOR */
+
+ /* READ THE CORE FREQUENCY */
+
+ gfx_cpu_frequency = gfx_get_core_freq();
+
+ /* SET THE GP SCRATCH AREA */
+ /* Color bitmap BLTs use the last 16K of frame buffer space */
+
+ gfx_gx2_scratch_base = gfx_get_frame_buffer_size() - 0x4000;
+ }
+ }
+ }
+#endif
+
+#if GFX_INIT_GU3
+
+ value = gfx_pci_config_read(0x80000800);
+
+ if (value == PCI_VENDOR_DEVICE_CASTLE) {
+ Q_WORD msr_value;
+ int valid, i;
+
+ /* CHECK FOR SOFT VG */
+ /* If SoftVG is not present, the base addresses for all devices */
+
+ /* will not be allocated. Essentially, it is as if no Redcloud */
+ /* video hardware is present. */
+
+ value = gfx_pci_config_read(0x80000900);
+
+ if (value == CASTLE_VIDEO_PCI_VENDOR_DEVICE) {
+ valid = 1;
+
+ /* BAR0 - BAR3 HOLD THE PERIPHERAL BASE ADDRESSES */
+
+ for (i = 0; i < 4; i++) {
+ value = gfx_pci_config_read(0x80000910 + (i << 2));
+ if (value == 0x00000000 || value == 0xFFFFFFFF) {
+ valid = 0;
+ break;
+ }
+ }
+
+ if (valid) {
+ /* REDCLOUD INTEGRATED VIDEO */
+
+#if GFX_VIDEO_DYNAMIC
+ gfx_video_type = GFX_VIDEO_TYPE_CASTLE;
+#endif
+
+ /* CURRENTLY, ALWAYS GPIO FOR I2C ACCESS */
+
+#if GFX_I2C_DYNAMIC
+ gfx_i2c_type = GFX_I2C_TYPE_GPIO;
+#endif
+
+ /* THIRD-GENERATION DISPLAY CONTROLLER */
+
+#if GFX_DISPLAY_DYNAMIC
+ gfx_display_type = GFX_DISPLAY_TYPE_GU3;
+#endif
+
+ /* SECOND-GENERATION GRAPHICS UNIT */
+
+#if GFX_2DACCEL_DYNAMIC
+ gfx_2daccel_type = GFX_2DACCEL_TYPE_GU2;
+#endif
+
+ /* THIRD-GENERATION INITIALIZATION */
+
+#if GFX_INIT_DYNAMIC
+ gfx_init_type = GFX_INIT_TYPE_GU3;
+#endif
+
+ /* MBUS MSR ACCESSES */
+
+#if GFX_MSR_DYNAMIC
+ gfx_msr_type = GFX_MSR_TYPE_REDCLOUD;
+#endif
+
+ /* READ VERSION */
+
+ gfx_msr_init();
+
+ gfx_msr_read(RC_ID_MCP, MCP_RC_REVID, &msr_value);
+
+ version = GFX_CPU_CASTLE | ((msr_value.low & 0xF0) << 4) | /* MAJOR */
+ ((msr_value.low & 0x0F) << 16); /* MINOR */
+
+ /* READ THE CORE FREQUENCY */
+
+ gfx_cpu_frequency = gfx_get_core_freq();
+
+ /* SET THE GP SCRATCH AREA */
+ /* Color bitmap BLTs use the last 16K of frame buffer space */
+
+ gfx_gx2_scratch_base = gfx_get_frame_buffer_size() - 0x4000;
+
+ /* CAP AT 16MB */
+
+ if (gfx_gx2_scratch_base > 0xFFC000)
+ gfx_gx2_scratch_base = 0xFFC000;
+ }
+
+ }
+ }
+#endif
+
+ if (!version) {
+ /* ALWAYS SECOND GENERATION IF SIMULATING */
+ /* For now, that is. This could change. */
+
+#if GFX_DISPLAY_DYNAMIC
+ gfx_display_type = GFX_DISPLAY_TYPE_GU2;
+#endif
+#if GFX_2DACCEL_DYNAMIC
+ gfx_2daccel_type = GFX_2DACCEL_TYPE_GU2;
+#endif
+#if GFX_INIT_DYNAMIC
+ gfx_init_type = GFX_INIT_TYPE_GU2;
+#endif
+#if GFX_MSR_DYNAMIC
+ gfx_msr_type = GFX_MSR_TYPE_REDCLOUD;
+#endif
+#if GFX_VIDEO_DYNAMIC
+ gfx_video_type = GFX_VIDEO_TYPE_REDCLOUD;
+#endif
+#if GFX_I2C_DYNAMIC
+ gfx_i2c_type = GFX_I2C_TYPE_GPIO;
+#endif
+ }
+ gfx_cpu_version = version;
+
+ return (version);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_detect_video
+ *
+ * This routine returns the type of the video hardware.
+ *
+ * The return value is as follows:
+ * bits[7:0] = type (1 = CS5530, 2 = SC1200, 3 = Redcloud)
+ *
+ * Currently this routine does not actually detect any hardware, and bases
+ * the video hardware entirely on the detected CPU.
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_detect_video(void)
+{
+ unsigned long version = 0;
+
+ if ((gfx_cpu_version & 0xFF) == GFX_CPU_GXLV)
+ version = GFX_VID_CS5530;
+ else if ((gfx_cpu_version & 0xFF) == GFX_CPU_SC1200)
+ version = GFX_VID_SC1200;
+ else if ((gfx_cpu_version & 0xFF) == GFX_CPU_REDCLOUD)
+ version = GFX_VID_REDCLOUD;
+ else if ((gfx_cpu_version & 0xFF) == GFX_CPU_CASTLE)
+ version = GFX_VID_CASTLE;
+ gfx_vid_version = version;
+ return (version);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_pci_config_read
+ *
+ * This routine reads a 32-bit value from the specified location in PCI
+ * configuration space.
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_pci_config_read(unsigned long address)
+{
+ unsigned long value = 0xFFFFFFFF;
+
+ OUTD(PCI_CONFIG_ADDR, address);
+ value = IND(PCI_CONFIG_DATA);
+ return (value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_pci_config_write
+ *
+ * This routine writes a 32-bit value to the specified location in PCI
+ * configuration space.
+ *----------------------------------------------------------------------------
+ */
+void
+gfx_pci_config_write(unsigned long address, unsigned long data)
+{
+ OUTD(PCI_CONFIG_ADDR, address);
+ OUTD(PCI_CONFIG_DATA, data);
+ return;
+}
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either first or second generation routines. */
+
+#if GFX_INIT_DYNAMIC
+
+/*----------------------------------------------------------------------------
+ * gfx_get_core_freq
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_core_freq(void)
+{
+ unsigned long freq = 0;
+
+#if GFX_INIT_GU1
+ if (gfx_init_type & GFX_INIT_TYPE_GU1)
+ freq = gu1_get_core_freq();
+#endif
+#if GFX_INIT_GU2
+ if (gfx_init_type & GFX_INIT_TYPE_GU2)
+ freq = gu2_get_core_freq();
+#endif
+#if GFX_INIT_GU3
+ if (gfx_init_type & GFX_INIT_TYPE_GU3)
+ freq = gu3_get_core_freq();
+#endif
+ return freq;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cpu_register_base
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_cpu_register_base(void)
+{
+ unsigned long base = 0;
+
+#if GFX_INIT_GU1
+ if (gfx_init_type & GFX_INIT_TYPE_GU1)
+ base = gu1_get_cpu_register_base();
+#endif
+#if GFX_INIT_GU2
+ if (gfx_init_type & GFX_INIT_TYPE_GU2)
+ base = gu2_get_cpu_register_base();
+#endif
+#if GFX_INIT_GU3
+ if (gfx_init_type & GFX_INIT_TYPE_GU3)
+ base = gu3_get_cpu_register_base();
+#endif
+
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_graphics_register_base
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_graphics_register_base(void)
+{
+ unsigned long base = 0;
+
+#if GFX_INIT_GU2
+ if (gfx_init_type & GFX_INIT_TYPE_GU2)
+ base = gu2_get_graphics_register_base();
+#endif
+#if GFX_INIT_GU3
+ if (gfx_init_type & GFX_INIT_TYPE_GU3)
+ base = gu3_get_graphics_register_base();
+#endif
+
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_base
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_frame_buffer_base(void)
+{
+ unsigned long base = 0;
+
+#if GFX_INIT_GU1
+ if (gfx_init_type & GFX_INIT_TYPE_GU1)
+ base = gu1_get_frame_buffer_base();
+#endif
+#if GFX_INIT_GU2
+ if (gfx_init_type & GFX_INIT_TYPE_GU2)
+ base = gu2_get_frame_buffer_base();
+#endif
+#if GFX_INIT_GU3
+ if (gfx_init_type & GFX_INIT_TYPE_GU3)
+ base = gu3_get_frame_buffer_base();
+#endif
+
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_size
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_frame_buffer_size(void)
+{
+ unsigned long size = 0;
+
+#if GFX_INIT_GU1
+ if (gfx_init_type & GFX_INIT_TYPE_GU1)
+ size = gu1_get_frame_buffer_size();
+#endif
+#if GFX_INIT_GU2
+ if (gfx_init_type & GFX_INIT_TYPE_GU2)
+ size = gu2_get_frame_buffer_size();
+#endif
+#if GFX_INIT_GU3
+ if (gfx_init_type & GFX_INIT_TYPE_GU3)
+ size = gu3_get_frame_buffer_size();
+#endif
+
+ return size;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vid_register_base
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vid_register_base(void)
+{
+ unsigned long base = 0;
+
+#if GFX_INIT_GU1
+ if (gfx_init_type & GFX_INIT_TYPE_GU1)
+ base = gu1_get_vid_register_base();
+#endif
+#if GFX_INIT_GU2
+ if (gfx_init_type & GFX_INIT_TYPE_GU2)
+ base = gu2_get_vid_register_base();
+#endif
+#if GFX_INIT_GU3
+ if (gfx_init_type & GFX_INIT_TYPE_GU3)
+ base = gu3_get_vid_register_base();
+#endif
+
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_register_base
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vip_register_base(void)
+{
+ unsigned long base = 0;
+
+#if GFX_INIT_GU1
+ if (gfx_init_type & GFX_INIT_TYPE_GU1)
+ base = gu1_get_vip_register_base();
+#endif
+
+ return (base);
+}
+
+#endif
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_mode.h b/src/gfx/gfx_mode.h
new file mode 100644
index 0000000..f9b42b0
--- /dev/null
+++ b/src/gfx/gfx_mode.h
@@ -0,0 +1,194 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This header file contains the mode tables. It is used by the "gfx_disp.c"
+ * file to set a display mode.
+ * */
+
+#ifndef _gfx_mode_h
+#define _gfx_mode_h
+
+/* MODE FLAGS (BITWISE-OR) */
+
+#define GFX_MODE_8BPP 0x00000001
+#define GFX_MODE_12BPP 0x00000002
+#define GFX_MODE_15BPP 0x00000004
+#define GFX_MODE_16BPP 0x00000008
+#define GFX_MODE_24BPP 0x00000010
+#define GFX_MODE_56HZ 0x00000020
+#define GFX_MODE_60HZ 0x00000040
+#define GFX_MODE_70HZ 0x00000080
+#define GFX_MODE_72HZ 0x00000100
+#define GFX_MODE_75HZ 0x00000200
+#define GFX_MODE_85HZ 0x00000400
+#define GFX_MODE_90HZ 0x00000800
+#define GFX_MODE_100HZ 0x00001000
+#define GFX_MODE_NEG_HSYNC 0x00002000
+#define GFX_MODE_NEG_VSYNC 0x00004000
+#define GFX_MODE_PIXEL_DOUBLE 0x00008000
+#define GFX_MODE_LINE_DOUBLE 0x00010000
+#define GFX_MODE_TV_NTSC 0x00020000
+#define GFX_MODE_TV_PAL 0x00040000
+#define GFX_MODE_EXCLUDE_PLL 0x00080000
+#define GFX_MODE_LOCK_TIMING 0x10000000
+
+#define gfx_mode_hz_conversion \
+ switch (hz) { \
+ case 56: \
+ hz_flag = GFX_MODE_56HZ; \
+ break; \
+ case 60: \
+ hz_flag = GFX_MODE_60HZ; \
+ break; \
+ case 70: \
+ hz_flag = GFX_MODE_70HZ; \
+ break; \
+ case 72: \
+ hz_flag = GFX_MODE_72HZ; \
+ break; \
+ case 75: \
+ hz_flag = GFX_MODE_75HZ; \
+ break; \
+ case 85: \
+ hz_flag = GFX_MODE_85HZ; \
+ break; \
+ case 90: \
+ hz_flag = GFX_MODE_90HZ; \
+ break; \
+ case 100: \
+ hz_flag = GFX_MODE_100HZ; \
+ break; \
+ }
+
+#define gfx_mode_bpp_conversion \
+ switch (bpp) { \
+ case 8: \
+ bpp_flag = GFX_MODE_8BPP; \
+ break; \
+ case 12: \
+ bpp_flag = GFX_MODE_12BPP; \
+ break; \
+ case 15: \
+ bpp_flag = GFX_MODE_15BPP; \
+ break; \
+ case 16: \
+ bpp_flag = GFX_MODE_16BPP; \
+ break; \
+ case 32: \
+ bpp_flag = GFX_MODE_24BPP; \
+ break; \
+ default: \
+ return -1; \
+ }
+
+#define gfx_mode_bpp_conversion_def(bpp) \
+ switch (bpp) { \
+ case 8: \
+ bpp_flag = GFX_MODE_8BPP; \
+ break; \
+ case 12: \
+ bpp_flag = GFX_MODE_12BPP; \
+ break; \
+ case 15: \
+ bpp_flag = GFX_MODE_15BPP; \
+ break; \
+ case 16: \
+ bpp_flag = GFX_MODE_16BPP; \
+ break; \
+ case 32: \
+ bpp_flag = GFX_MODE_24BPP; \
+ break; \
+ default: \
+ bpp_flag = GFX_MODE_8BPP; \
+ }
+
+/* STRUCTURE DEFINITION */
+
+typedef struct tagDISPLAYMODE
+{
+ /* DISPLAY MODE FLAGS */
+ /* Specify valid color depths and the refresh rate. */
+
+ unsigned long flags;
+
+ /* TIMINGS */
+
+ unsigned short hactive;
+ unsigned short hblankstart;
+ unsigned short hsyncstart;
+ unsigned short hsyncend;
+ unsigned short hblankend;
+ unsigned short htotal;
+
+ unsigned short vactive;
+ unsigned short vblankstart;
+ unsigned short vsyncstart;
+ unsigned short vsyncend;
+ unsigned short vblankend;
+ unsigned short vtotal;
+
+ /* CLOCK FREQUENCY */
+
+ unsigned long frequency;
+
+} DISPLAYMODE;
+
+/* For Fixed timings */
+typedef struct tagFIXEDTIMINGS
+{
+ /* DISPLAY MODE FLAGS */
+ /* Specify valid color depths and the refresh rate. */
+
+ int panelresx;
+ int panelresy;
+ unsigned short xres;
+ unsigned short yres;
+
+ /* TIMINGS */
+
+ unsigned short hactive;
+ unsigned short hblankstart;
+ unsigned short hsyncstart;
+ unsigned short hsyncend;
+ unsigned short hblankend;
+ unsigned short htotal;
+
+ unsigned short vactive;
+ unsigned short vblankstart;
+ unsigned short vsyncstart;
+ unsigned short vsyncend;
+ unsigned short vblankend;
+ unsigned short vtotal;
+
+ /* CLOCK FREQUENCY */
+
+ unsigned long frequency;
+
+} FIXEDTIMINGS;
+
+#endif /* !_gfx_mode_h */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_msr.c b/src/gfx/gfx_msr.c
new file mode 100644
index 0000000..3d48d3d
--- /dev/null
+++ b/src/gfx/gfx_msr.c
@@ -0,0 +1,152 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to read machine-specific registers (MSRs)
+ *
+ * Routines:
+ *
+ * gfx_msr_init
+ * gfx_id_msr_device
+ * gfx_get_msr_dev_address
+ * gfx_get_glink_id_at_address
+ * gfx_msr_read
+ * gfx_msr_write
+ * */
+
+/* INCLUDE SUPPORT FOR REDCLOUD, IF SPECIFIED */
+
+#if GFX_MSR_REDCLOUD
+#include "msr_rdcl.c"
+#endif
+
+/* EXTRA WRAPPERS FOR DYNAMIC SELECTION */
+
+#if GFX_MSR_DYNAMIC
+
+/*----------------------------------------------------------------------------
+ * gfx_msr_init
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_msr_init()
+{
+ int ret_value = 0;
+
+#if GFX_MSR_REDCLOUD
+ if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD)
+ ret_value = redcloud_msr_init();
+#endif
+
+ return ret_value;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_id_msr_device
+ *----------------------------------------------------------------------------
+ */
+DEV_STATUS
+gfx_id_msr_device(MSR * pDev, unsigned long address)
+{
+ DEV_STATUS ret_value = NOT_KNOWN;
+
+#if GFX_MSR_REDCLOUD
+ if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD)
+ ret_value = redcloud_id_msr_device(pDev, address);
+#endif
+
+ return ret_value;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_msr_dev_address
+ *----------------------------------------------------------------------------
+ */
+DEV_STATUS
+gfx_get_msr_dev_address(unsigned int device, unsigned long *address)
+{
+ DEV_STATUS ret_value = NOT_KNOWN;
+
+#if GFX_MSR_REDCLOUD
+ if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD)
+ ret_value = redcloud_get_msr_dev_address(device, address);
+#endif
+
+ return ret_value;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_glink_id_at_address
+ *----------------------------------------------------------------------------
+ */
+DEV_STATUS
+gfx_get_glink_id_at_address(unsigned int *device, unsigned long address)
+{
+ DEV_STATUS ret_value = NOT_KNOWN;
+
+#if GFX_MSR_REDCLOUD
+ if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD)
+ ret_value = redcloud_get_glink_id_at_address(device, address);
+#endif
+
+ return ret_value;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_msr_read
+ *----------------------------------------------------------------------------
+ */
+DEV_STATUS
+gfx_msr_read(unsigned int device, unsigned int msrRegister, Q_WORD * msrValue)
+{
+ DEV_STATUS ret_value = NOT_KNOWN;
+
+#if GFX_MSR_REDCLOUD
+ if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD)
+ ret_value = redcloud_msr_read(device, msrRegister, msrValue);
+#endif
+
+ return ret_value;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_msr_write
+ *----------------------------------------------------------------------------
+ */
+DEV_STATUS
+gfx_msr_write(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue)
+{
+ DEV_STATUS ret_value = NOT_KNOWN;
+
+#if GFX_MSR_REDCLOUD
+ if (gfx_msr_type & GFX_MSR_TYPE_REDCLOUD)
+ ret_value = redcloud_msr_write(device, msrRegister, msrValue);
+#endif
+
+ return ret_value;
+}
+
+#endif
diff --git a/src/gfx/gfx_priv.h b/src/gfx/gfx_priv.h
new file mode 100644
index 0000000..5647af8
--- /dev/null
+++ b/src/gfx/gfx_priv.h
@@ -0,0 +1,981 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This header file contains the prototypes for local and private routines.
+ * */
+
+/*---------------------------------*/
+/* FIRST GENERATION INITIALIZATION */
+/*---------------------------------*/
+
+#if GFX_INIT_GU1
+
+/* PRIVATE ROUTINES */
+
+unsigned char gfx_gxm_config_read(unsigned char index);
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_INIT_DYNAMIC
+unsigned long gu1_get_core_freq(void);
+unsigned long gu1_get_cpu_register_base(void);
+unsigned long gu1_get_graphics_register_base(void);
+unsigned long gu1_get_frame_buffer_base(void);
+unsigned long gu1_get_frame_buffer_size(void);
+unsigned long gu1_get_vid_register_base(void);
+unsigned long gu1_get_vip_register_base(void);
+#endif
+
+#endif
+
+/*----------------------------------*/
+/* SECOND GENERATION INITIALIZATION */
+/*----------------------------------*/
+
+#if GFX_INIT_GU2
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_INIT_DYNAMIC
+unsigned long gu2_get_core_freq(void);
+unsigned long gu2_get_cpu_register_base(void);
+unsigned long gu2_get_graphics_register_base(void);
+unsigned long gu2_get_frame_buffer_base(void);
+unsigned long gu2_get_frame_buffer_size(void);
+unsigned long gu2_get_vid_register_base(void);
+unsigned long gu2_get_vip_register_base(void);
+#endif
+
+#endif
+
+/*----------------------------------*/
+/* MSR ROUTINES */
+/*----------------------------------*/
+
+#if GFX_MSR_REDCLOUD
+
+/* PRIVATE ROUTINES */
+
+void redcloud_build_mbus_tree(void);
+int redcloud_init_msr_devices(MSR aDev[], unsigned int array_size);
+DEV_STATUS redcloud_find_msr_device(MSR * pDev);
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_MSR_DYNAMIC
+int redcloud_msr_init(void);
+DEV_STATUS redcloud_id_msr_device(MSR * pDev, unsigned long address);
+DEV_STATUS redcloud_get_msr_dev_address(unsigned int device,
+ unsigned long *address);
+DEV_STATUS redcloud_get_glink_id_at_address(unsigned int *device,
+ unsigned long address);
+DEV_STATUS redcloud_msr_read(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue);
+DEV_STATUS redcloud_msr_write(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue);
+#endif
+
+#endif
+
+void gfx_set_display_video_enable(int enable);
+void gfx_set_display_video_size(unsigned short width, unsigned short height);
+void gfx_set_display_video_offset(unsigned long offset);
+unsigned long gfx_get_display_video_offset(void);
+unsigned long gfx_get_display_video_size(void);
+
+/*----------------------------------*/
+/* FIRST GENERATION DISPLAY */
+/*----------------------------------*/
+
+#if GFX_DISPLAY_GU1
+
+/* PRIVATE ROUTINES */
+
+void gu1_enable_compression(void);
+void gu1_disable_compression(void);
+void gu1_delay_approximate(unsigned long milliseconds);
+void gu1_delay_precise(unsigned long milliseconds);
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_DISPLAY_DYNAMIC
+void gu1_set_display_video_enable(int enable);
+void gu1_set_display_video_size(unsigned short width, unsigned short height);
+void gu1_set_display_video_offset(unsigned long offset);
+unsigned long gu1_get_display_video_offset(void);
+unsigned long gu1_get_display_video_size(void);
+int gu1_set_display_bpp(unsigned short bpp);
+int gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz);
+int gu1_set_display_mode(int xres, int yres, int bpp, int hz);
+int gu1_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblank_start,
+ unsigned short hsync_start, unsigned short hsync_end,
+ unsigned short hblank_end, unsigned short htotal,
+ unsigned short vactive, unsigned short vblank_start,
+ unsigned short vsync_start, unsigned short vsync_end,
+ unsigned short vblank_end, unsigned short vtotal,
+ unsigned long frequency);
+int gu1_set_vtotal(unsigned short vtotal);
+void gu1_set_display_pitch(unsigned short pitch);
+void gu1_set_display_offset(unsigned long offset);
+int gu1_set_display_palette_entry(unsigned long index, unsigned long palette);
+int gu1_set_display_palette(unsigned long *palette);
+void gu1_video_shutdown(void);
+void gu1_set_cursor_enable(int enable);
+void gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor);
+void gu1_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot);
+void gu1_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask);
+int gu1_set_compression_enable(int enable);
+int gu1_set_compression_offset(unsigned long offset);
+int gu1_set_compression_pitch(unsigned short pitch);
+int gu1_set_compression_size(unsigned short size);
+void gu1_set_display_priority_high(int enable);
+int gu1_test_timing_active(void);
+int gu1_test_vertical_active(void);
+int gu1_wait_vertical_blank(void);
+void gu1_delay_milliseconds(unsigned long milliseconds);
+void gu1_delay_microseconds(unsigned long microseconds);
+void gu1_enable_panning(int x, int y);
+int gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp);
+int gu1_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp);
+void gu1_reset_timing_lock(void);
+int gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz);
+unsigned short gu1_get_display_pitch(void);
+unsigned long gu1_get_max_supported_pixel_clock(void);
+int gu1_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency);
+int gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency);
+int gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency);
+int gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency);
+int gu1_get_display_mode_count(void);
+int gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz);
+unsigned long gu1_get_frame_buffer_line_size(void);
+unsigned short gu1_get_hactive(void);
+unsigned short gu1_get_hblank_start(void);
+unsigned short gu1_get_hsync_start(void);
+unsigned short gu1_get_hsync_end(void);
+unsigned short gu1_get_hblank_end(void);
+unsigned short gu1_get_htotal(void);
+unsigned short gu1_get_vactive(void);
+unsigned short gu1_get_vline(void);
+unsigned short gu1_get_vblank_start(void);
+unsigned short gu1_get_vsync_start(void);
+unsigned short gu1_get_vsync_end(void);
+unsigned short gu1_get_vblank_end(void);
+unsigned short gu1_get_vtotal(void);
+unsigned short gu1_get_display_bpp(void);
+unsigned long gu1_get_display_offset(void);
+int gu1_get_display_palette_entry(unsigned long index,
+ unsigned long *palette);
+void gu1_get_display_palette(unsigned long *palette);
+unsigned long gu1_get_cursor_enable(void);
+unsigned long gu1_get_cursor_offset(void);
+unsigned long gu1_get_cursor_position(void);
+unsigned long gu1_get_cursor_clip(void);
+unsigned long gu1_get_cursor_color(int color);
+unsigned long gu1_get_icon_enable(void);
+unsigned long gu1_get_icon_offset(void);
+unsigned long gu1_get_icon_position(void);
+unsigned long gu1_get_icon_color(int color);
+int gu1_get_compression_enable(void);
+unsigned long gu1_get_compression_offset(void);
+unsigned short gu1_get_compression_pitch(void);
+unsigned short gu1_get_compression_size(void);
+int gu1_get_display_priority_high(void);
+int gu1_get_valid_bit(int line);
+#endif
+
+#endif
+
+void gfx_set_display_video_format(unsigned long format);
+void gfx_set_display_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset);
+void gfx_set_display_video_yuv_pitch(unsigned long ypitch,
+ unsigned long uvpitch);
+void gfx_set_display_video_downscale(unsigned short srch,
+ unsigned short dsth);
+void gfx_set_display_video_vertical_downscale_enable(int enable);
+void gfx_get_display_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset);
+void gfx_get_display_video_yuv_pitch(unsigned long *ypitch,
+ unsigned long *uvpitch);
+unsigned long gfx_get_display_video_downscale_delta(void);
+int gfx_get_display_video_downscale_enable(void);
+
+/*----------------------------------*/
+/* SECOND GENERATION DISPLAY */
+/*----------------------------------*/
+
+#if GFX_DISPLAY_GU2
+
+/* PRIVATE ROUTINES */
+
+void gu2_enable_compression(void);
+void gu2_disable_compression(void);
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_DISPLAY_DYNAMIC
+void gu2_get_display_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset);
+void gu2_get_display_video_yuv_pitch(unsigned long *ypitch,
+ unsigned long *uvpitch);
+unsigned long gu2_get_display_video_downscale_delta(void);
+int gu2_get_display_video_downscale_enable(void);
+void gu2_set_display_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset);
+void gu2_set_display_video_format(unsigned long format);
+void gu2_set_display_video_yuv_pitch(unsigned long ypitch,
+ unsigned long uvpitch);
+void gu2_set_display_video_downscale(unsigned short srch,
+ unsigned short dsth);
+void gu2_set_display_video_vertical_downscale_enable(int enable);
+void gu2_set_display_video_enable(int enable);
+void gu2_set_display_video_size(unsigned short width, unsigned short height);
+void gu2_set_display_video_offset(unsigned long offset);
+unsigned long gu2_get_display_video_offset(void);
+unsigned long gu2_get_display_video_size(void);
+int gu2_set_display_bpp(unsigned short bpp);
+int gu2_is_display_mode_supported(int xres, int yres, int bpp, int hz);
+int gu2_set_display_mode(int xres, int yres, int bpp, int hz);
+int gu2_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblank_start,
+ unsigned short hsync_start, unsigned short hsync_end,
+ unsigned short hblank_end, unsigned short htotal,
+ unsigned short vactive, unsigned short vblank_start,
+ unsigned short vsync_start, unsigned short vsync_end,
+ unsigned short vblank_end, unsigned short vtotal,
+ unsigned long frequency);
+int gu2_set_vtotal(unsigned short vtotal);
+void gu2_set_display_pitch(unsigned short pitch);
+void gu2_set_display_offset(unsigned long offset);
+int gu2_set_display_palette_entry(unsigned long index, unsigned long palette);
+int gu2_set_display_palette(unsigned long *palette);
+void gu2_set_cursor_enable(int enable);
+void gu2_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor);
+void gu2_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot);
+void gu2_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask);
+void gu2_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask);
+void gu2_set_icon_enable(int enable);
+void gu2_set_icon_colors(unsigned long color0, unsigned long color1,
+ unsigned long color2);
+void gu2_set_icon_position(unsigned long memoffset, unsigned short xpos);
+void gu2_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned int lines);
+int gu2_set_compression_enable(int enable);
+int gu2_set_compression_offset(unsigned long offset);
+int gu2_set_compression_pitch(unsigned short pitch);
+int gu2_set_compression_size(unsigned short size);
+void gu2_set_display_priority_high(int enable);
+int gu2_test_timing_active(void);
+int gu2_test_vertical_active(void);
+int gu2_wait_vertical_blank(void);
+void gu2_delay_milliseconds(unsigned long milliseconds);
+void gu2_delay_microseconds(unsigned long microseconds);
+void gu2_enable_panning(int x, int y);
+int gu2_is_panel_mode_supported(int panelResX, int panelResY,
+ unsigned short width, unsigned short height, unsigned short bpp);
+int gu2_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp);
+int gu2_set_panel_present(int panelResX, int panelResY, unsigned short width,
+ unsigned short height, unsigned short bpp);
+void gu2_reset_timing_lock(void);
+int gu2_get_display_details(unsigned int mode, int *xres, int *yres, int *hz);
+unsigned short gu2_get_display_pitch(void);
+unsigned long gu2_get_max_supported_pixel_clock(void);
+int gu2_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency);
+int gu2_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency);
+int gu2_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency);
+int gu2_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
+ int *frequency);
+int gu2_get_display_mode_count(void);
+int gu2_get_display_mode(int *xres, int *yres, int *bpp, int *hz);
+unsigned long gu2_get_frame_buffer_line_size(void);
+unsigned short gu2_get_hactive(void);
+unsigned short gu2_get_hblank_start(void);
+unsigned short gu2_get_hsync_start(void);
+unsigned short gu2_get_hsync_end(void);
+unsigned short gu2_get_hblank_end(void);
+unsigned short gu2_get_htotal(void);
+unsigned short gu2_get_vactive(void);
+unsigned short gu2_get_vline(void);
+unsigned short gu2_get_vblank_start(void);
+unsigned short gu2_get_vsync_start(void);
+unsigned short gu2_get_vsync_end(void);
+unsigned short gu2_get_vblank_end(void);
+unsigned short gu2_get_vtotal(void);
+unsigned short gu2_get_display_bpp(void);
+unsigned long gu2_get_display_offset(void);
+int gu2_get_display_palette_entry(unsigned long index,
+ unsigned long *palette);
+void gu2_get_display_palette(unsigned long *palette);
+unsigned long gu2_get_cursor_enable(void);
+unsigned long gu2_get_cursor_offset(void);
+unsigned long gu2_get_cursor_position(void);
+unsigned long gu2_get_cursor_clip(void);
+unsigned long gu2_get_cursor_color(int color);
+unsigned long gu2_get_icon_enable(void);
+unsigned long gu2_get_icon_offset(void);
+unsigned long gu2_get_icon_position(void);
+unsigned long gu2_get_icon_color(int color);
+int gu2_get_compression_enable(void);
+unsigned long gu2_get_compression_offset(void);
+unsigned short gu2_get_compression_pitch(void);
+unsigned short gu2_get_compression_size(void);
+int gu2_get_valid_bit(int line);
+#endif
+
+#endif
+
+/*----------------------------------*/
+/* FIRST GENERATION 2D ACCELERATION */
+/*----------------------------------*/
+
+#if GFX_2DACCEL_GU1
+
+/* PRIVATE ROUTINES */
+
+void gu1_solid_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long color);
+void gu1_detect_blt_buffer_base(void);
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_2DACCEL_DYNAMIC
+void gu1_set_bpp(unsigned short bpp);
+void gu1_set_solid_pattern(unsigned long color);
+void gu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparency);
+void gu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned long data2,
+ unsigned long data3, unsigned char transparency);
+void gu1_load_color_pattern_line(short y, unsigned long *pattern_8x8);
+void gu1_set_solid_source(unsigned long color);
+void gu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent);
+void gu1_set_pattern_flags(unsigned short flags);
+void gu1_set_raster_operation(unsigned char rop);
+void gu1_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height);
+void gu1_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern);
+void gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height);
+void gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color);
+void gu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch);
+void gu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch,
+ unsigned long color);
+void gu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch);
+void gu1_text_blt(unsigned short dstx, unsigned short dsty,
+ unsigned short width, unsigned short height, unsigned char *data);
+void gu1_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr, unsigned short axialerr,
+ unsigned short diagerr, unsigned short flags);
+void gu1_wait_until_idle(void);
+int gu1_test_blt_pending(void);
+#endif
+
+#endif
+
+/*-----------------------------------*/
+/* SECOND GENERATION 2D ACCELERATION */
+/*-----------------------------------*/
+
+#if GFX_2DACCEL_GU2
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_2DACCEL_DYNAMIC
+void gfx_reset_pitch(unsigned short pitch);
+void gu2_reset_pitch(unsigned short pitch);
+void gu2_set_bpp(unsigned short bpp);
+void gu2_set_solid_pattern(unsigned long color);
+void gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparency);
+void gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned long data2,
+ unsigned long data3, unsigned char transparency);
+void gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8);
+void gu2_set_solid_source(unsigned long color);
+void gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent);
+void gu2_set_pattern_flags(unsigned short flags);
+void gu2_set_raster_operation(unsigned char rop);
+void gu2_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height);
+void gu2_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern);
+void gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height);
+void gu2_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color);
+void gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch);
+void gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch,
+ unsigned long color);
+void gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch);
+void gu2_text_blt(unsigned short dstx, unsigned short dsty,
+ unsigned short width, unsigned short height, unsigned char *data);
+void gu2_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr, unsigned short axialerr,
+ unsigned short diagerr, unsigned short flags);
+void gu2_wait_until_idle(void);
+int gu2_test_blt_pending(void);
+
+void gu22_set_source_stride(unsigned short stride);
+void gu22_set_destination_stride(unsigned short stride);
+void gu22_set_pattern_origin(int x, int y);
+void gu22_set_source_transparency(unsigned long color, unsigned long mask);
+void gu22_set_alpha_mode(int mode);
+void gu22_set_alpha_value(unsigned char value);
+void gu22_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height);
+void gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned long *pattern);
+void gu22_screen_to_screen_blt(unsigned long srcoffset,
+ unsigned long dstoffset, unsigned short width, unsigned short height,
+ int flags);
+void gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
+ unsigned short srcy, unsigned long dstoffset, unsigned short width,
+ unsigned short height, int byte_packed);
+void gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width, unsigned short height,
+ unsigned char *data, short pitch);
+void gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width, unsigned short height,
+ unsigned char *data, short pitch);
+void gu22_text_blt(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data);
+void gu22_bresenham_line(unsigned long dstoffset, unsigned short length,
+ unsigned short initerr, unsigned short axialerr, unsigned short diagerr,
+ unsigned short flags);
+void gu22_sync_to_vblank(void);
+#endif
+
+#endif
+
+void gfx_reset_video(void);
+int gfx_set_display_control(int sync_polarities);
+int gfx_set_screen_enable(int enable);
+
+/*-----------------------*/
+/* CS5530 VIDEO ROUTINES */
+/*-----------------------*/
+
+#if GFX_VIDEO_CS5530
+
+/* PRIVATE ROUTINES */
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_VIDEO_DYNAMIC
+void cs5530_reset_video(void);
+int cs5530_set_display_control(int sync_polarities);
+void cs5530_set_clock_frequency(unsigned long frequency);
+unsigned long cs5530_get_clock_frequency(void);
+int cs5530_set_crt_enable(int enable);
+int cs5530_get_sync_polarities(void);
+int cs5530_get_vsa2_softvga_enable(void);
+int cs5530_set_video_enable(int enable);
+int cs5530_set_video_format(unsigned long format);
+int cs5530_set_video_size(unsigned short width, unsigned short height);
+int cs5530_set_video_offset(unsigned long offset);
+int cs5530_set_video_window(short x, short y, unsigned short w,
+ unsigned short h);
+int cs5530_set_video_left_crop(unsigned short x);
+int cs5530_set_video_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+int cs5530_set_video_color_key(unsigned long key, unsigned long mask,
+ int bluescreen);
+int cs5530_set_video_filter(int xfilter, int yfilter);
+int cs5530_set_video_palette(unsigned long *palette);
+int cs5530_set_video_palette_entry(unsigned long index, unsigned long color);
+int cs5530_disable_softvga(void);
+int cs5530_enable_softvga(void);
+unsigned long cs5530_get_max_video_width(void);
+
+/* READ ROUTINES IN GFX_VID.C */
+
+int cs5530_get_video_enable(void);
+int cs5530_get_video_format(void);
+unsigned long cs5530_get_video_src_size(void);
+unsigned long cs5530_get_video_line_size(void);
+unsigned long cs5530_get_video_xclip(void);
+unsigned long cs5530_get_video_offset(void);
+unsigned long cs5530_get_video_upscale(void);
+unsigned long cs5530_get_video_scale(void);
+unsigned long cs5530_get_video_dst_size(void);
+unsigned long cs5530_get_video_position(void);
+unsigned long cs5530_get_video_color_key(void);
+unsigned long cs5530_get_video_color_key_mask(void);
+int cs5530_get_video_palette_entry(unsigned long index,
+ unsigned long *palette);
+int cs5530_get_video_color_key_src(void);
+int cs5530_get_video_filter(void);
+unsigned long cs5530_read_crc(void);
+#endif
+#endif
+
+/*-----------------------*/
+/* SC1200 VIDEO ROUTINES */
+/*-----------------------*/
+
+#if GFX_VIDEO_SC1200
+
+/* PRIVATE ROUTINES */
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_VIDEO_DYNAMIC
+void sc1200_reset_video(void);
+int sc1200_set_display_control(int sync_polarities);
+int sc1200_set_screen_enable(int enable);
+void sc1200_set_clock_frequency(unsigned long frequency);
+unsigned long sc1200_get_clock_frequency(void);
+int sc1200_set_crt_enable(int enable);
+int sc1200_get_sync_polarities(void);
+int sc1200_get_vsa2_softvga_enable(void);
+int sc1200_set_video_enable(int enable);
+int sc1200_set_video_format(unsigned long format);
+int sc1200_set_video_size(unsigned short width, unsigned short height);
+int sc1200_set_video_offset(unsigned long offset);
+int sc1200_set_video_window(short x, short y, unsigned short w,
+ unsigned short h);
+int sc1200_set_video_left_crop(unsigned short x);
+int sc1200_set_video_upscale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+int sc1200_set_video_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+int sc1200_set_video_downscale_config(unsigned short type, unsigned short m);
+int sc1200_set_video_color_key(unsigned long key, unsigned long mask,
+ int bluescreen);
+int sc1200_set_video_filter(int xfilter, int yfilter);
+int sc1200_set_video_palette(unsigned long *palette);
+int sc1200_set_video_palette_bypass(int enable);
+int sc1200_set_video_palette_entry(unsigned long index, unsigned long color);
+int sc1200_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4);
+int sc1200_set_video_downscale_enable(int enable);
+int sc1200_set_video_source(VideoSourceType source);
+int sc1200_set_vbi_source(VbiSourceType source);
+int sc1200_set_vbi_lines(unsigned long even, unsigned long odd);
+int sc1200_set_vbi_total(unsigned long even, unsigned long odd);
+int sc1200_set_video_interlaced(int enable);
+int sc1200_set_color_space_YUV(int enable);
+int sc1200_set_vertical_scaler_offset(char offset);
+int sc1200_set_top_line_in_odd(int enable);
+int sc1200_set_genlock_delay(unsigned long delay);
+int sc1200_set_genlock_enable(int flags);
+int sc1200_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2);
+int sc1200_set_video_request(short x, short y);
+
+int sc1200_select_alpha_region(int region);
+int sc1200_set_alpha_enable(int enable);
+int sc1200_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height);
+int sc1200_set_alpha_value(unsigned char alpha, char delta);
+int sc1200_set_alpha_priority(int priority);
+int sc1200_set_alpha_color(unsigned long color);
+int sc1200_set_alpha_color_enable(int enable);
+int sc1200_set_no_ck_outside_alpha(int enable);
+int sc1200_disable_softvga(void);
+int sc1200_enable_softvga(void);
+int sc1200_set_macrovision_enable(int enable);
+unsigned long sc1200_get_max_video_width(void);
+
+/* READ ROUTINES IN GFX_VID.C */
+
+int sc1200_get_video_enable(void);
+int sc1200_get_video_format(void);
+unsigned long sc1200_get_video_src_size(void);
+unsigned long sc1200_get_video_line_size(void);
+unsigned long sc1200_get_video_xclip(void);
+unsigned long sc1200_get_video_offset(void);
+unsigned long sc1200_get_video_upscale(void);
+unsigned long sc1200_get_video_scale(void);
+int sc1200_get_video_downscale_config(unsigned short *type,
+ unsigned short *m);
+void sc1200_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4);
+void sc1200_get_video_downscale_enable(int *enable);
+unsigned long sc1200_get_video_dst_size(void);
+unsigned long sc1200_get_video_position(void);
+unsigned long sc1200_get_video_color_key(void);
+unsigned long sc1200_get_video_color_key_mask(void);
+int sc1200_get_video_palette_entry(unsigned long index,
+ unsigned long *palette);
+int sc1200_get_video_color_key_src(void);
+int sc1200_get_video_filter(void);
+int sc1200_get_video_request(short *x, short *y);
+int sc1200_get_video_source(VideoSourceType * source);
+int sc1200_get_vbi_source(VbiSourceType * source);
+unsigned long sc1200_get_vbi_lines(int odd);
+unsigned long sc1200_get_vbi_total(int odd);
+int sc1200_get_video_interlaced(void);
+int sc1200_get_color_space_YUV(void);
+int sc1200_get_vertical_scaler_offset(char *offset);
+unsigned long sc1200_get_genlock_delay(void);
+int sc1200_get_genlock_enable(void);
+int sc1200_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2);
+unsigned long sc1200_read_crc(void);
+int sc1200_get_macrovision_enable(void);
+
+void sc1200_get_alpha_enable(int *enable);
+void sc1200_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height);
+void sc1200_get_alpha_value(unsigned char *alpha, char *delta);
+void sc1200_get_alpha_priority(int *priority);
+void sc1200_get_alpha_color(unsigned long *color);
+#endif
+#endif
+
+/*-------------------------*/
+/* REDCLOUD VIDEO ROUTINES */
+/*-------------------------*/
+
+#if GFX_VIDEO_REDCLOUD
+
+/* PRIVATE ROUTINES */
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_VIDEO_DYNAMIC
+void redcloud_reset_video(void);
+int redcloud_set_display_control(int sync_polarities);
+void redcloud_set_clock_frequency(unsigned long frequency);
+unsigned long redcloud_get_clock_frequency(void);
+int redcloud_set_crt_enable(int enable);
+int redcloud_get_sync_polarities(void);
+int redcloud_set_video_enable(int enable);
+int redcloud_set_video_format(unsigned long format);
+int redcloud_set_video_size(unsigned short width, unsigned short height);
+int redcloud_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch);
+int redcloud_set_video_offset(unsigned long offset);
+int redcloud_set_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset);
+int redcloud_set_video_window(short x, short y, unsigned short w,
+ unsigned short h);
+int redcloud_set_video_left_crop(unsigned short x);
+int redcloud_set_video_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+int redcloud_set_video_vertical_downscale(unsigned short srch,
+ unsigned short dsth);
+void redcloud_set_video_vertical_downscale_enable(int enable);
+int redcloud_set_video_downscale_config(unsigned short type,
+ unsigned short m);
+int redcloud_set_video_color_key(unsigned long key, unsigned long mask,
+ int bluescreen);
+int redcloud_set_video_filter(int xfilter, int yfilter);
+int redcloud_set_video_palette(unsigned long *palette);
+int redcloud_set_graphics_palette(unsigned long *palette);
+int redcloud_set_video_palette_bypass(int enable);
+int redcloud_set_video_palette_entry(unsigned long index,
+ unsigned long color);
+int redcloud_set_graphics_palette_entry(unsigned long index,
+ unsigned long color);
+int redcloud_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4);
+int redcloud_set_video_downscale_enable(int enable);
+int redcloud_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2);
+int redcloud_set_video_cursor_enable(int enable);
+
+int redcloud_select_alpha_region(int region);
+int redcloud_set_alpha_enable(int enable);
+int redcloud_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height);
+int redcloud_set_alpha_value(unsigned char alpha, char delta);
+int redcloud_set_alpha_priority(int priority);
+int redcloud_set_alpha_color(unsigned long color);
+int redcloud_set_alpha_color_enable(int enable);
+int redcloud_set_no_ck_outside_alpha(int enable);
+int redcloud_set_video_request(short x, short y);
+
+/* READ ROUTINES IN GFX_VID.C */
+
+int redcloud_get_video_enable(void);
+int redcloud_get_video_format(void);
+unsigned long redcloud_get_video_src_size(void);
+unsigned long redcloud_get_video_line_size(void);
+unsigned long redcloud_get_video_xclip(void);
+unsigned long redcloud_get_video_offset(void);
+void redcloud_get_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset);
+void redcloud_get_video_yuv_pitch(unsigned long *ypitch,
+ unsigned long *uvpitch);
+unsigned long redcloud_get_video_scale(void);
+unsigned long redcloud_get_video_downscale_delta(void);
+int redcloud_get_video_vertical_downscale_enable(void);
+int redcloud_get_video_downscale_config(unsigned short *type,
+ unsigned short *m);
+void redcloud_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4);
+void redcloud_get_video_downscale_enable(int *enable);
+unsigned long redcloud_get_video_dst_size(void);
+unsigned long redcloud_get_video_position(void);
+unsigned long redcloud_get_video_color_key(void);
+unsigned long redcloud_get_video_color_key_mask(void);
+int redcloud_get_video_palette_entry(unsigned long index,
+ unsigned long *palette);
+int redcloud_get_video_color_key_src(void);
+int redcloud_get_video_filter(void);
+int redcloud_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2);
+unsigned long redcloud_read_crc(void);
+unsigned long redcloud_read_crc32(void);
+unsigned long redcloud_read_window_crc(int source, unsigned short x,
+ unsigned short y, unsigned short width, unsigned short height, int crc32);
+
+void redcloud_get_alpha_enable(int *enable);
+void redcloud_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height);
+void redcloud_get_alpha_value(unsigned char *alpha, char *delta);
+void redcloud_get_alpha_priority(int *priority);
+void redcloud_get_alpha_color(unsigned long *color);
+int redcloud_get_video_request(short *x, short *y);
+#endif
+#endif
+
+/*--------------*/
+/* VIP ROUTINES */
+/*--------------*/
+
+#if GFX_VIP_SC1200
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_VIP_DYNAMIC
+int sc1200_set_vip_enable(int enable);
+int sc1200_set_vip_capture_run_mode(int mode);
+int sc1200_set_vip_base(unsigned long even, unsigned long odd);
+int sc1200_set_vip_pitch(unsigned long pitch);
+int sc1200_set_vip_mode(int mode);
+int sc1200_set_vbi_enable(int enable);
+int sc1200_set_vbi_mode(int mode);
+int sc1200_set_vbi_base(unsigned long even, unsigned long odd);
+int sc1200_set_vbi_pitch(unsigned long pitch);
+int sc1200_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines);
+int sc1200_set_vbi_interrupt(int enable);
+int sc1200_set_vip_bus_request_threshold_high(int enable);
+int sc1200_set_vip_last_line(int last_line);
+int sc1200_test_vip_odd_field(void);
+int sc1200_test_vip_bases_updated(void);
+int sc1200_test_vip_fifo_overflow(void);
+int sc1200_get_vip_line(void);
+int sc1200_get_vip_enable(void);
+unsigned long sc1200_get_vip_base(int odd);
+unsigned long sc1200_get_vip_pitch(void);
+int sc1200_get_vip_mode(void);
+int sc1200_get_vbi_enable(void);
+int sc1200_get_vbi_mode(void);
+unsigned long sc1200_get_vbi_base(int odd);
+unsigned long sc1200_get_vbi_pitch(void);
+unsigned long sc1200_get_vbi_direct(int odd);
+int sc1200_get_vbi_interrupt(void);
+int sc1200_get_vip_bus_request_threshold_high(void);
+#endif
+#endif
+
+/* DECODER ROUTINES */
+
+#if GFX_DECODER_SAA7114
+
+/* PRIVATE ROUTINES */
+
+int saa7114_write_reg(unsigned char reg, unsigned char val);
+int saa7114_read_reg(unsigned char reg, unsigned char *val);
+
+/* DYNAMIC ROUTINES */
+
+#if GFX_DECODER_DYNAMIC
+int saa7114_set_decoder_defaults(void);
+int saa7114_set_decoder_analog_input(unsigned char input);
+int saa7114_set_decoder_brightness(unsigned char brightness);
+int saa7114_set_decoder_contrast(unsigned char contrast);
+int saa7114_set_decoder_hue(char hue);
+int saa7114_set_decoder_saturation(unsigned char saturation);
+int saa7114_set_decoder_input_offset(unsigned short x, unsigned short y);
+int saa7114_set_decoder_input_size(unsigned short width,
+ unsigned short height);
+int saa7114_set_decoder_output_size(unsigned short width,
+ unsigned short height);
+int saa7114_set_decoder_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+int saa7114_set_decoder_vbi_format(int start, int end, int format);
+int saa7114_set_decoder_vbi_enable(int enable);
+int saa7114_set_decoder_vbi_upscale(void);
+int saa7114_set_decoder_TV_standard(TVStandardType TVStandard);
+int saa7114_set_decoder_luminance_filter(unsigned char lufi);
+int saa7114_decoder_software_reset(void);
+int saa7114_decoder_detect_macrovision(void);
+int saa7114_decoder_detect_video(void);
+unsigned char saa7114_get_decoder_brightness(void);
+unsigned char saa7114_get_decoder_contrast(void);
+char saa7114_get_decoder_hue(void);
+unsigned char saa7114_get_decoder_saturation(void);
+unsigned long saa7114_get_decoder_input_offset(void);
+unsigned long saa7114_get_decoder_input_size(void);
+unsigned long saa7114_get_decoder_output_size(void);
+int saa7114_get_decoder_vbi_format(int line);
+#endif
+#endif
+
+/* ACCESS I2C ROUTINES */
+
+#if GFX_I2C_ACCESS
+
+#if GFX_I2C_DYNAMIC
+int acc_i2c_reset(unsigned char busnum, short adr, char freq);
+int acc_i2c_write(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data);
+int acc_i2c_read(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data);
+int acc_i2c_select_gpio(int clock, int data);
+int acc_i2c_init(void);
+void acc_i2c_cleanup(void);
+#endif
+#endif
+
+/* GPIO I2C ROUTINES */
+
+#if GFX_I2C_GPIO
+
+#if GFX_I2C_DYNAMIC
+int gpio_i2c_reset(unsigned char busnum, short adr, char freq);
+int gpio_i2c_write(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data);
+int gpio_i2c_read(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data);
+int gpio_i2c_select_gpio(int clock, int data);
+int gpio_i2c_init(void);
+void gpio_i2c_cleanup(void);
+#endif
+#endif
+
+/* TV ROUTINES */
+
+#if GFX_TV_SC1200
+
+#if GFX_TV_DYNAMIC
+int sc1200_set_tv_format(TVStandardType format, GfxOnTVType resolution);
+int sc1200_set_tv_output(int output);
+int sc1200_set_tv_enable(int enable);
+int sc1200_set_tv_flicker_filter(int ff);
+int sc1200_set_tv_sub_carrier_reset(int screset);
+int sc1200_set_tv_vphase(int vphase);
+int sc1200_set_tv_YC_delay(int delay);
+int sc1200_set_tvenc_reset_interval(int interval);
+int sc1200_set_tv_cc_enable(int enable);
+int sc1200_set_tv_cc_data(unsigned char data1, unsigned char data2);
+int sc1200_set_tv_display(int width, int height);
+int sc1200_test_tvout_odd_field(void);
+int sc1200_test_tvenc_odd_field(void);
+int sc1200_set_tv_field_status_invert(int enable);
+int sc1200_get_tv_vphase(void);
+int sc1200_get_tv_enable(unsigned int *p_on);
+int sc1200_get_tv_output(void);
+int sc1200_get_tv_mode_count(TVStandardType format);
+int sc1200_get_tv_display_mode(int *width, int *height, int *bpp, int *hz);
+int sc1200_get_tv_display_mode_frequency(unsigned short width,
+ unsigned short height, TVStandardType format, int *frequency);
+int sc1200_is_tv_display_mode_supported(unsigned short width,
+ unsigned short height, TVStandardType format);
+unsigned char cc_add_parity_bit(unsigned char data);
+
+#endif
+#endif
+
+/* FS450 ROUTINES */
+
+#if GFX_TV_FS451
+
+#if GFX_TV_DYNAMIC
+int fs450_set_tv_format(TVStandardType format, GfxOnTVType resolution);
+int fs450_set_tv_output(int output);
+int fs450_set_tv_enable(int enable);
+int fs450_get_tv_standard(unsigned long *p_standard);
+int fs450_get_available_tv_standards(unsigned long *p_standards);
+int fs450_set_tv_standard(unsigned long standard);
+int fs450_get_tv_vga_mode(unsigned long *p_vga_mode);
+int fs450_get_available_tv_vga_modes(unsigned long *p_vga_modes);
+int fs450_set_tv_vga_mode(unsigned long vga_mode);
+int fs450_get_tvout_mode(unsigned long *p_tvout_mode);
+int fs450_set_tvout_mode(unsigned long tvout_mode);
+int fs450_get_sharpness(int *p_sharpness);
+int fs450_set_sharpness(int sharpness);
+int fs450_get_flicker_filter(int *p_flicker);
+int fs450_set_flicker_filter(int flicker);
+int fs450_get_overscan(int *p_x, int *p_y);
+int fs450_set_overscan(int x, int y);
+int fs450_get_position(int *p_x, int *p_y);
+int fs450_set_position(int x, int y);
+int fs450_get_color(int *p_color);
+int fs450_set_color(int color);
+int fs450_get_brightness(int *p_brightness);
+int fs450_set_brightness(int brightness);
+int fs450_get_contrast(int *p_contrast);
+int fs450_set_contrast(int constrast);
+int fs450_get_yc_filter(unsigned int *p_yc_filter);
+int fs450_set_yc_filter(unsigned int yc_filter);
+int fs450_get_aps_trigger_bits(unsigned int *p_trigger_bits);
+int fs450_set_aps_trigger_bits(unsigned int trigger_bits);
+#endif
+#endif
diff --git a/src/gfx/gfx_regs.h b/src/gfx/gfx_regs.h
new file mode 100644
index 0000000..8d062f7
--- /dev/null
+++ b/src/gfx/gfx_regs.h
@@ -0,0 +1,1654 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This header file contains the graphics register definitions.
+ * */
+
+/*----------------------------------*/
+/* FIRST GENERATION GRAPHICS UNIT */
+/*----------------------------------*/
+
+#define GP_DST_XCOOR 0x8100 /* x destination origin */
+#define GP_DST_YCOOR 0x8102 /* y destination origin */
+#define GP_WIDTH 0x8104 /* pixel width */
+#define GP_HEIGHT 0x8106 /* pixel height */
+#define GP_SRC_XCOOR 0x8108 /* x source origin */
+#define GP_SRC_YCOOR 0x810A /* y source origin */
+
+#define GP_VECTOR_LENGTH 0x8104 /* vector length */
+#define GP_INIT_ERROR 0x8106 /* vector initial error */
+#define GP_AXIAL_ERROR 0x8108 /* axial error increment */
+#define GP_DIAG_ERROR 0x810A /* diagonal error increment */
+
+#define GP_SRC_COLOR_0 0x810C /* source color 0 */
+#define GP_SRC_COLOR_1 0x810E /* source color 1 */
+#define GP_PAT_COLOR_0 0x8110 /* pattern color 0 */
+#define GP_PAT_COLOR_1 0x8112 /* pattern color 1 */
+#define GP_PAT_COLOR_2 0x8114 /* pattern color 2 */
+#define GP_PAT_COLOR_3 0x8116 /* pattern color 3 */
+#define GP_PAT_DATA_0 0x8120 /* bits 31:0 of pattern */
+#define GP_PAT_DATA_1 0x8124 /* bits 63:32 of pattern */
+#define GP_PAT_DATA_2 0x8128 /* bits 95:64 of pattern */
+#define GP_PAT_DATA_3 0x812C /* bits 127:96 of pattern */
+
+#define GP_VGA_WRITE 0x8140 /* VGA write path control */
+#define GP_VGA_READ 0x8144 /* VGA read path control */
+
+#define GP_RASTER_MODE 0x8200 /* raster operation */
+#define GP_VECTOR_MODE 0x8204 /* vector mode register */
+#define GP_BLIT_MODE 0x8208 /* blit mode register */
+#define GP_BLIT_STATUS 0x820C /* blit status register */
+
+#define GP_VGA_BASE 0x8210 /* VGA memory offset (x64K) */
+#define GP_VGA_LATCH 0x8214 /* VGA display latch */
+
+/* "GP_VECTOR_MODE" BIT DEFINITIONS */
+
+#define VM_X_MAJOR 0x0000 /* X major vector */
+#define VM_Y_MAJOR 0x0001 /* Y major vector */
+#define VM_MAJOR_INC 0x0002 /* positive major axis step */
+#define VM_MINOR_INC 0x0004 /* positive minor axis step */
+#define VM_READ_DST_FB 0x0008 /* read destination data */
+
+/* "GP_RASTER_MODE" BIT DEFINITIONS */
+
+#define RM_PAT_DISABLE 0x0000 /* pattern is disabled */
+#define RM_PAT_MONO 0x0100 /* 1BPP pattern expansion */
+#define RM_PAT_DITHER 0x0200 /* 2BPP pattern expansion */
+#define RM_PAT_COLOR 0x0300 /* 8BPP or 16BPP pattern */
+#define RM_PAT_MASK 0x0300 /* mask for pattern mode */
+#define RM_PAT_TRANSPARENT 0x0400 /* transparent 1BPP pattern */
+#define RM_SRC_TRANSPARENT 0x0800 /* transparent 1BPP source */
+
+/* "GP_BLIT_STATUS" BIT DEFINITIONS */
+
+#define BS_BLIT_BUSY 0x0001 /* blit engine is busy */
+#define BS_PIPELINE_BUSY 0x0002 /* graphics pipeline is busy */
+#define BS_BLIT_PENDING 0x0004 /* blit pending */
+#define BC_FLUSH 0x0080 /* flush pipeline requests */
+#define BC_8BPP 0x0000 /* 8BPP mode */
+#define BC_16BPP 0x0100 /* 16BPP mode */
+#define BC_FB_WIDTH_1024 0x0000 /* framebuffer width = 1024 */
+#define BC_FB_WIDTH_2048 0x0200 /* framebuffer width = 2048 */
+#define BC_FB_WIDTH_4096 0x0400 /* framebuffer width = 4096 */
+
+/* "GP_BLIT_MODE" BIT DEFINITIONS */
+
+#define BM_READ_SRC_NONE 0x0000 /* source foreground color */
+#define BM_READ_SRC_FB 0x0001 /* read source from FB */
+#define BM_READ_SRC_BB0 0x0002 /* read source from BB0 */
+#define BM_READ_SRC_BB1 0x0003 /* read source from BB1 */
+#define BM_READ_SRC_MASK 0x0003 /* read source mask */
+
+#define BM_READ_DST_NONE 0x0000 /* no destination data */
+#define BM_READ_DST_BB0 0x0008 /* destination from BB0 */
+#define BM_READ_DST_BB1 0x000C /* destination from BB1 */
+#define BM_READ_DST_FB0 0x0010 /* dest from FB (store BB0) */
+#define BM_READ_DST_FB1 0x0014 /* dest from FB (store BB1) */
+#define BM_READ_DST_MASK 0x001C /* read destination mask */
+
+#define BM_WRITE_FB 0x0000 /* write to framebuffer */
+#define BM_WRITE_MEM 0x0020 /* write to memory */
+#define BM_WRITE_MASK 0x0020 /* write mask */
+
+#define BM_SOURCE_COLOR 0x0000 /* source is 8BPP or 16BPP */
+#define BM_SOURCE_EXPAND 0x0040 /* source is 1BPP */
+#define BM_SOURCE_TEXT 0x00C0 /* source is 1BPP text */
+#define BM_SOURCE_MASK 0x00C0 /* source mask */
+
+#define BM_REVERSE_Y 0x0100 /* reverse Y direction */
+
+/*---------------------------------------*/
+/* FIRST GENERATION DISPLAY CONTROLLER */
+/*---------------------------------------*/
+
+#define DC_UNLOCK 0x8300 /* lock register */
+#define DC_GENERAL_CFG 0x8304 /* config registers... */
+#define DC_TIMING_CFG 0x8308
+#define DC_OUTPUT_CFG 0x830C
+
+#define DC_FB_ST_OFFSET 0x8310 /* framebuffer start offset */
+#define DC_CB_ST_OFFSET 0x8314 /* compression start offset */
+#define DC_CURS_ST_OFFSET 0x8318 /* cursor start offset */
+#define DC_ICON_ST_OFFSET 0x831C /* icon start offset */
+#define DC_VID_ST_OFFSET 0x8320 /* video start offset */
+#define DC_LINE_DELTA 0x8324 /* fb and cb skip counts */
+#define DC_BUF_SIZE 0x8328 /* fb and cb line size */
+
+#define DC_H_TIMING_1 0x8330 /* horizontal timing... */
+#define DC_H_TIMING_2 0x8334
+#define DC_H_TIMING_3 0x8338
+#define DC_FP_H_TIMING 0x833C
+
+#define DC_V_TIMING_1 0x8340 /* vertical timing... */
+#define DC_V_TIMING_2 0x8344
+#define DC_V_TIMING_3 0x8348
+#define DC_FP_V_TIMING 0x834C
+
+#define DC_CURSOR_X 0x8350 /* cursor x position */
+#define DC_ICON_X 0x8354 /* HACK - 1.3 definition */
+#define DC_V_LINE_CNT 0x8354 /* vertical line counter */
+#define DC_CURSOR_Y 0x8358 /* cursor y position */
+#define DC_ICON_Y 0x835C /* HACK - 1.3 definition */
+#define DC_SS_LINE_CMP 0x835C /* line compare value */
+#define DC_CURSOR_COLOR 0x8360 /* cursor colors */
+#define DC_ICON_COLOR 0x8364 /* icon colors */
+#define DC_BORDER_COLOR 0x8368 /* border color */
+#define DC_PAL_ADDRESS 0x8370 /* palette address */
+#define DC_PAL_DATA 0x8374 /* palette data */
+#define DC_DFIFO_DIAG 0x8378 /* display FIFO diagnostic */
+#define DC_CFIFO_DIAG 0x837C /* compression FIF0 diagnostic */
+
+/* PALETTE LOCATIONS */
+
+#define PAL_CURSOR_COLOR_0 0x100
+#define PAL_CURSOR_COLOR_1 0x101
+#define PAL_ICON_COLOR_0 0x102
+#define PAL_ICON_COLOR_1 0x103
+#define PAL_OVERSCAN_COLOR 0x104
+
+/* UNLOCK VALUE */
+
+#define DC_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */
+
+/* "DC_GENERAL_CFG" BIT DEFINITIONS */
+
+#define DC_GCFG_DFLE 0x00000001 /* display FIFO load enable */
+#define DC_GCFG_CURE 0x00000002 /* cursor enable */
+#define DC_GCFG_VCLK_DIV 0x00000004 /* vid clock divisor */
+#define DC_GCFG_PLNO 0x00000004 /* planar offset LSB */
+#define DC_GCFG_PPC 0x00000008 /* pixel pan compatibility */
+#define DC_GCFG_CMPE 0x00000010 /* compression enable */
+#define DC_GCFG_DECE 0x00000020 /* decompression enable */
+#define DC_GCFG_DCLK_MASK 0x000000C0 /* dotclock multiplier */
+#define DC_GCFG_DCLK_POS 6 /* dotclock multiplier */
+#define DC_GCFG_DFHPSL_MASK 0x00000F00 /* FIFO high-priority start */
+#define DC_GCFG_DFHPSL_POS 8 /* FIFO high-priority start */
+#define DC_GCFG_DFHPEL_MASK 0x0000F000 /* FIFO high-priority end */
+#define DC_GCFG_DFHPEL_POS 12 /* FIFO high-priority end */
+#define DC_GCFG_CIM_MASK 0x00030000 /* compressor insert mode */
+#define DC_GCFG_CIM_POS 16 /* compressor insert mode */
+#define DC_GCFG_FDTY 0x00040000 /* frame dirty mode */
+#define DC_GCFG_RTPM 0x00080000 /* real-time perf. monitor */
+#define DC_GCFG_DAC_RS_MASK 0x00700000 /* DAC register selects */
+#define DC_GCFG_DAC_RS_POS 20 /* DAC register selects */
+#define DC_GCFG_CKWR 0x00800000 /* clock write */
+#define DC_GCFG_LDBL 0x01000000 /* line double */
+#define DC_GCFG_DIAG 0x02000000 /* FIFO diagnostic mode */
+#define DC_GCFG_CH4S 0x04000000 /* sparse refresh mode */
+#define DC_GCFG_SSLC 0x08000000 /* enable line compare */
+#define DC_GCFG_VIDE 0x10000000 /* video enable */
+#define DC_GCFG_DFCK 0x20000000 /* divide flat-panel clock */
+ /* - rev 2.3 down */
+#define DC_GCFG_VRDY 0x20000000 /* video port speed */
+ /* - rev 2.4 up */
+#define DC_GCFG_DPCK 0x40000000 /* divide pixel clock */
+#define DC_GCFG_DDCK 0x80000000 /* divide dot clock */
+
+/* "DC_TIMING_CFG" BIT DEFINITIONS */
+
+#define DC_TCFG_FPPE 0x00000001 /* flat-panel power enable */
+#define DC_TCFG_HSYE 0x00000002 /* horizontal sync enable */
+#define DC_TCFG_VSYE 0x00000004 /* vertical sync enable */
+#define DC_TCFG_BLKE 0x00000008 /* blank enable */
+#define DC_TCFG_DDCK 0x00000010 /* DDC clock */
+#define DC_TCFG_TGEN 0x00000020 /* timing generator enable */
+#define DC_TCFG_VIEN 0x00000040 /* vertical interrupt enable */
+#define DC_TCFG_BLNK 0x00000080 /* blink enable */
+#define DC_TCFG_CHSP 0x00000100 /* horizontal sync polarity */
+#define DC_TCFG_CVSP 0x00000200 /* vertical sync polarity */
+#define DC_TCFG_FHSP 0x00000400 /* panel horz sync polarity */
+#define DC_TCFG_FVSP 0x00000800 /* panel vert sync polarity */
+#define DC_TCFG_FCEN 0x00001000 /* flat-panel centering */
+#define DC_TCFG_CDCE 0x00002000 /* HACK - 1.3 definition */
+#define DC_TCFG_PLNR 0x00002000 /* planar mode enable */
+#define DC_TCFG_INTL 0x00004000 /* interlace scan */
+#define DC_TCFG_PXDB 0x00008000 /* pixel double */
+#define DC_TCFG_BKRT 0x00010000 /* blink rate */
+#define DC_TCFG_PSD_MASK 0x000E0000 /* power sequence delay */
+#define DC_TCFG_PSD_POS 17 /* power sequence delay */
+#define DC_TCFG_DDCI 0x08000000 /* DDC input (RO) */
+#define DC_TCFG_SENS 0x10000000 /* monitor sense (RO) */
+#define DC_TCFG_DNA 0x20000000 /* display not active (RO) */
+#define DC_TCFG_VNA 0x40000000 /* vertical not active (RO) */
+#define DC_TCFG_VINT 0x80000000 /* vertical interrupt (RO) */
+
+/* "DC_OUTPUT_CFG" BIT DEFINITIONS */
+
+#define DC_OCFG_8BPP 0x00000001 /* 8/16 bpp select */
+#define DC_OCFG_555 0x00000002 /* 16 bpp format */
+#define DC_OCFG_PCKE 0x00000004 /* PCLK enable */
+#define DC_OCFG_FRME 0x00000008 /* frame rate mod enable */
+#define DC_OCFG_DITE 0x00000010 /* dither enable */
+#define DC_OCFG_2PXE 0x00000020 /* 2 pixel enable */
+#define DC_OCFG_2XCK 0x00000040 /* 2 x pixel clock */
+#define DC_OCFG_2IND 0x00000080 /* 2 index enable */
+#define DC_OCFG_34ADD 0x00000100 /* 3- or 4-bit add */
+#define DC_OCFG_FRMS 0x00000200 /* frame rate mod select */
+#define DC_OCFG_CKSL 0x00000400 /* clock select */
+#define DC_OCFG_PRMP 0x00000800 /* palette re-map */
+#define DC_OCFG_PDEL 0x00001000 /* panel data enable low */
+#define DC_OCFG_PDEH 0x00002000 /* panel data enable high */
+#define DC_OCFG_CFRW 0x00004000 /* comp line buffer r/w sel */
+#define DC_OCFG_DIAG 0x00008000 /* comp line buffer diag */
+
+#define MC_MEM_CNTRL1 0x00008400
+#define MC_DR_ADD 0x00008418
+#define MC_DR_ACC 0x0000841C
+
+/* MC_MEM_CNTRL1 BIT DEFINITIONS */
+
+#define MC_XBUSARB 0x00000008 /* 0 = GP priority < CPU priority */
+ /* 1 = GP priority = CPU priority */
+ /* GXm databook V2.0 is wrong ! */
+/*----------*/
+/* CS5530 */
+/*----------*/
+
+/* CS5530 REGISTER DEFINITIONS */
+
+#define CS5530_VIDEO_CONFIG 0x0000
+#define CS5530_DISPLAY_CONFIG 0x0004
+#define CS5530_VIDEO_X_POS 0x0008
+#define CS5530_VIDEO_Y_POS 0x000C
+#define CS5530_VIDEO_SCALE 0x0010
+#define CS5530_VIDEO_COLOR_KEY 0x0014
+#define CS5530_VIDEO_COLOR_MASK 0x0018
+#define CS5530_PALETTE_ADDRESS 0x001C
+#define CS5530_PALETTE_DATA 0x0020
+#define CS5530_DOT_CLK_CONFIG 0x0024
+#define CS5530_CRCSIG_TFT_TV 0x0028
+
+/* "CS5530_VIDEO_CONFIG" BIT DEFINITIONS */
+
+#define CS5530_VCFG_VID_EN 0x00000001
+#define CS5530_VCFG_VID_REG_UPDATE 0x00000002
+#define CS5530_VCFG_VID_INP_FORMAT 0x0000000C
+#define CS5530_VCFG_8_BIT_4_2_0 0x00000004
+#define CS5530_VCFG_16_BIT_4_2_0 0x00000008
+#define CS5530_VCFG_GV_SEL 0x00000010
+#define CS5530_VCFG_CSC_BYPASS 0x00000020
+#define CS5530_VCFG_X_FILTER_EN 0x00000040
+#define CS5530_VCFG_Y_FILTER_EN 0x00000080
+#define CS5530_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00
+#define CS5530_VCFG_INIT_READ_MASK 0x01FF0000
+#define CS5530_VCFG_EARLY_VID_RDY 0x02000000
+#define CS5530_VCFG_LINE_SIZE_UPPER 0x08000000
+#define CS5530_VCFG_4_2_0_MODE 0x10000000
+#define CS5530_VCFG_16_BIT_EN 0x20000000
+#define CS5530_VCFG_HIGH_SPD_INT 0x40000000
+
+/* "CS5530_DISPLAY_CONFIG" BIT DEFINITIONS */
+
+#define CS5530_DCFG_DIS_EN 0x00000001
+#define CS5530_DCFG_HSYNC_EN 0x00000002
+#define CS5530_DCFG_VSYNC_EN 0x00000004
+#define CS5530_DCFG_DAC_BL_EN 0x00000008
+#define CS5530_DCFG_DAC_PWDNX 0x00000020
+#define CS5530_DCFG_FP_PWR_EN 0x00000040
+#define CS5530_DCFG_FP_DATA_EN 0x00000080
+#define CS5530_DCFG_CRT_HSYNC_POL 0x00000100
+#define CS5530_DCFG_CRT_VSYNC_POL 0x00000200
+#define CS5530_DCFG_FP_HSYNC_POL 0x00000400
+#define CS5530_DCFG_FP_VSYNC_POL 0x00000800
+#define CS5530_DCFG_XGA_FP 0x00001000
+#define CS5530_DCFG_FP_DITH_EN 0x00002000
+#define CS5530_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
+#define CS5530_DCFG_CRT_SYNC_SKW_INIT 0x00010000
+#define CS5530_DCFG_PWR_SEQ_DLY_MASK 0x000E0000
+#define CS5530_DCFG_PWR_SEQ_DLY_INIT 0x00080000
+#define CS5530_DCFG_VG_CK 0x00100000
+#define CS5530_DCFG_GV_PAL_BYP 0x00200000
+#define CS5530_DCFG_DDC_SCL 0x00400000
+#define CS5530_DCFG_DDC_SDA 0x00800000
+#define CS5530_DCFG_DDC_OE 0x01000000
+#define CS5530_DCFG_16_BIT_EN 0x02000000
+
+/*----------*/
+/* SC1200 */
+/*----------*/
+
+/* SC1200 VIDEO REGISTER DEFINITIONS */
+
+#define SC1200_VIDEO_CONFIG 0x000
+#define SC1200_DISPLAY_CONFIG 0x004
+#define SC1200_VIDEO_X_POS 0x008
+#define SC1200_VIDEO_Y_POS 0x00C
+#define SC1200_VIDEO_UPSCALE 0x010
+#define SC1200_VIDEO_COLOR_KEY 0x014
+#define SC1200_VIDEO_COLOR_MASK 0x018
+#define SC1200_PALETTE_ADDRESS 0x01C
+#define SC1200_PALETTE_DATA 0x020
+#define SC1200_VID_MISC 0x028
+#define SC1200_VID_CLOCK_SELECT 0x02C
+#define SC1200_VIDEO_DOWNSCALER_CONTROL 0x03C
+#define SC1200_VIDEO_DOWNSCALER_COEFFICIENTS 0x40
+#define SC1200_VID_CRC 0x044
+#define SC1200_DEVICE_ID 0x048
+#define SC1200_VID_ALPHA_CONTROL 0x04C
+#define SC1200_CURSOR_COLOR_KEY 0x050
+#define SC1200_CURSOR_COLOR_MASK 0x054
+#define SC1200_CURSOR_COLOR_1 0x058
+#define SC1200_CURSOR_COLOR_2 0x05C
+#define SC1200_ALPHA_XPOS_1 0x060
+#define SC1200_ALPHA_YPOS_1 0x064
+#define SC1200_ALPHA_COLOR_1 0x068
+#define SC1200_ALPHA_CONTROL_1 0x06C
+#define SC1200_ALPHA_XPOS_2 0x070
+#define SC1200_ALPHA_YPOS_2 0x074
+#define SC1200_ALPHA_COLOR_2 0x078
+#define SC1200_ALPHA_CONTROL_2 0x07C
+#define SC1200_ALPHA_XPOS_3 0x080
+#define SC1200_ALPHA_YPOS_3 0x084
+#define SC1200_ALPHA_COLOR_3 0x088
+#define SC1200_ALPHA_CONTROL_3 0x08C
+#define SC1200_VIDEO_REQUEST 0x090
+#define SC1200_ALPHA_WATCH 0x094
+#define SC1200_VIDEO_DISPLAY_MODE 0x400
+#define SC1200_VIDEO_ODD_VBI_LINE_ENABLE 0x40C
+#define SC1200_VIDEO_EVEN_VBI_LINE_ENABLE 0x410
+#define SC1200_VIDEO_VBI_HORIZ_CONTROL 0x414
+#define SC1200_VIDEO_ODD_VBI_TOTAL_COUNT 0x418
+#define SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT 0x41C
+#define SC1200_GENLOCK 0x420
+#define SC1200_GENLOCK_DELAY 0x424
+#define SC1200_TVOUT_HORZ_TIM 0x800
+#define SC1200_TVOUT_HORZ_SYNC 0x804
+#define SC1200_TVOUT_VERT_SYNC 0x808
+#define SC1200_TVOUT_LINE_END 0x80C
+#define SC1200_TVOUT_VERT_DOWNSCALE 0x810 /* REV. A & B */
+#define SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE 0x810 /* REV. C */
+#define SC1200_TVOUT_HORZ_SCALING 0x814
+#define SC1200_TVOUT_DEBUG 0x818
+#define SC1200_TVENC_TIM_CTRL_1 0xC00
+#define SC1200_TVENC_TIM_CTRL_2 0xC04
+#define SC1200_TVENC_TIM_CTRL_3 0xC08
+#define SC1200_TVENC_SUB_FREQ 0xC0C
+#define SC1200_TVENC_DISP_POS 0xC10
+#define SC1200_TVENC_DISP_SIZE 0xC14
+#define SC1200_TVENC_CC_DATA 0xC18
+#define SC1200_TVENC_EDS_DATA 0xC1C
+#define SC1200_TVENC_CGMS_DATA 0xC20
+#define SC1200_TVENC_WSS_DATA 0xC24
+#define SC1200_TVENC_CC_CONTROL 0xC28
+#define SC1200_TVENC_DAC_CONTROL 0xC2C
+#define SC1200_TVENC_MV_CONTROL 0xC30
+
+/* "SC1200_VIDEO_CONFIG" BIT DEFINITIONS */
+
+#define SC1200_VCFG_VID_EN 0x00000001
+#define SC1200_VCFG_VID_INP_FORMAT 0x0000000C
+#define SC1200_VCFG_UYVY_FORMAT 0x00000000
+#define SC1200_VCFG_Y2YU_FORMAT 0x00000004
+#define SC1200_VCFG_YUYV_FORMAT 0x00000008
+#define SC1200_VCFG_YVYU_FORMAT 0x0000000C
+#define SC1200_VCFG_X_FILTER_EN 0x00000040
+#define SC1200_VCFG_Y_FILTER_EN 0x00000080
+#define SC1200_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00
+#define SC1200_VCFG_INIT_READ_MASK 0x01FF0000
+#define SC1200_VCFG_LINE_SIZE_UPPER 0x08000000
+#define SC1200_VCFG_4_2_0_MODE 0x10000000
+
+/* "SC1200_DISPLAY_CONFIG" BIT DEFINITIONS */
+
+#define SC1200_DCFG_DIS_EN 0x00000001
+#define SC1200_DCFG_HSYNC_EN 0x00000002
+#define SC1200_DCFG_VSYNC_EN 0x00000004
+#define SC1200_DCFG_DAC_BL_EN 0x00000008
+#define SC1200_DCFG_FP_PWR_EN 0x00000040
+#define SC1200_DCFG_FP_DATA_EN 0x00000080
+#define SC1200_DCFG_CRT_HSYNC_POL 0x00000100
+#define SC1200_DCFG_CRT_VSYNC_POL 0x00000200
+#define SC1200_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
+#define SC1200_DCFG_CRT_SYNC_SKW_INIT 0x00010000
+#define SC1200_DCFG_PWR_SEQ_DLY_MASK 0x000E0000
+#define SC1200_DCFG_PWR_SEQ_DLY_INIT 0x00080000
+#define SC1200_DCFG_VG_CK 0x00100000
+#define SC1200_DCFG_GV_PAL_BYP 0x00200000
+#define SC1200_DCFG_DDC_SCL 0x00400000
+#define SC1200_DCFG_DDC_SDA 0x00800000
+#define SC1200_DCFG_DDC_OE 0x01000000
+
+/* "SC1200_VID_MISC" BIT DEFINITIONS */
+
+#define SC1200_GAMMA_BYPASS_BOTH 0x00000001
+#define SC1200_DAC_POWER_DOWN 0x00000400
+#define SC1200_ANALOG_POWER_DOWN 0x00000800
+#define SC1200_PLL_POWER_NORMAL 0x00001000
+
+/* "SC1200_VIDEO_DOWNSCALER_CONTROL" BIT DEFINITIONS */
+
+#define SC1200_VIDEO_DOWNSCALE_ENABLE 0x00000001
+#define SC1200_VIDEO_DOWNSCALE_FACTOR_POS 1
+#define SC1200_VIDEO_DOWNSCALE_FACTOR_MASK 0x0000001E
+#define SC1200_VIDEO_DOWNSCALE_TYPE_A 0x00000000
+#define SC1200_VIDEO_DOWNSCALE_TYPE_B 0x00000040
+#define SC1200_VIDEO_DOWNSCALE_TYPE_MASK 0x00000040
+
+/* "SC1200_VIDEO_DOWNSCALER_COEFFICIENTS" BIT DEFINITIONS */
+
+#define SC1200_VIDEO_DOWNSCALER_COEF1_POS 0
+#define SC1200_VIDEO_DOWNSCALER_COEF2_POS 8
+#define SC1200_VIDEO_DOWNSCALER_COEF3_POS 16
+#define SC1200_VIDEO_DOWNSCALER_COEF4_POS 24
+#define SC1200_VIDEO_DOWNSCALER_COEF_MASK 0xF
+
+/* VIDEO DE-INTERLACING AND ALPHA CONTROL (REGISTER 0x4C) */
+
+#define SC1200_VERTICAL_SCALER_SHIFT_MASK 0x00000007
+#define SC1200_VERTICAL_SCALER_SHIFT_INIT 0x00000004
+#define SC1200_VERTICAL_SCALER_SHIFT_EN 0x00000010
+#define SC1200_TOP_LINE_IN_ODD 0x00000040
+#define SC1200_NO_CK_OUTSIDE_ALPHA 0x00000100
+#define SC1200_VIDEO_IS_INTERLACED 0x00000200
+#define SC1200_CSC_VIDEO_YUV_TO_RGB 0x00000400
+#define SC1200_CSC_GFX_RGB_TO_YUV 0x00000800
+#define SC1200_VIDEO_INPUT_IS_RGB 0x00002000
+#define SC1200_VIDEO_LINE_OFFSET_ODD 0x00001000
+#define SC1200_ALPHA1_PRIORITY_POS 16
+#define SC1200_ALPHA1_PRIORITY_MASK 0x00030000
+#define SC1200_ALPHA2_PRIORITY_POS 18
+#define SC1200_ALPHA2_PRIORITY_MASK 0x000C0000
+#define SC1200_ALPHA3_PRIORITY_POS 20
+#define SC1200_ALPHA3_PRIORITY_MASK 0x00300000
+
+/* VIDEO CURSOR COLOR KEY DEFINITIONS (REGISTER 0x50) */
+
+#define SC1200_CURSOR_COLOR_KEY_OFFSET_POS 24
+#define SC1200_CURSOR_COLOR_BITS 23
+#define SC1200_COLOR_MASK 0x00FFFFFF /* 24 significant
+ * bits */
+
+/* ALPHA COLOR BIT DEFINITION (REGISTERS 0x68, 0x78, AND 0x88) */
+
+#define SC1200_ALPHA_COLOR_ENABLE 0x01000000
+
+/* ALPHA CONTROL BIT DEFINITIONS (REGISTERS 0x6C, 0x7C, AND 0x8C) */
+
+#define SC1200_ACTRL_WIN_ENABLE 0x00010000
+#define SC1200_ACTRL_LOAD_ALPHA 0x00020000
+
+/* VIDEO REQUEST DEFINITIONS (REGISTER 0x90) */
+
+#define SC1200_VIDEO_Y_REQUEST_POS 0
+#define SC1200_VIDEO_X_REQUEST_POS 16
+#define SC1200_VIDEO_REQUEST_MASK 0x00000FFF
+
+/* VIDEO DISPLAY MODE (REGISTER 0x400) */
+
+#define SC1200_VIDEO_SOURCE_MASK 0x00000003
+#define SC1200_VIDEO_SOURCE_GX1 0x00000000
+#define SC1200_VIDEO_SOURCE_DVIP 0x00000002
+#define SC1200_VBI_SOURCE_MASK 0x00000004
+#define SC1200_VBI_SOURCE_DVIP 0x00000000
+#define SC1200_VBI_SOURCE_GX1 0x00000004
+
+/* ODD/EVEN VBI LINE ENABLE (REGISTERS 0x40C, 0x410) */
+
+#define SC1200_VIDEO_VBI_LINE_ENABLE_MASK 0x00FFFFFC
+#define SC1200_VIDEO_ALL_ACTIVE_IS_VBI 0x01000000
+#define SC1200_VIDEO_VBI_LINE_OFFSET_POS 25
+#define SC1200_VIDEO_VBI_LINE_OFFSET_MASK 0x3E000000
+
+/* ODD/EVEN VBI TOTAL COUNT (REGISTERS 0x418, 0x41C) */
+
+#define SC1200_VIDEO_VBI_TOTAL_COUNT_MASK 0x000FFFFF
+
+/* GENLOCK BIT DEFINITIONS */
+
+#define SC1200_GENLOCK_SINGLE_ENABLE 0x00000001
+#define SC1200_GENLOCK_FIELD_SYNC_ENABLE 0x00000001
+#define SC1200_GENLOCK_CONTINUOUS_ENABLE 0x00000002
+#define SC1200_GENLOCK_GX_VSYNC_FALLING_EDGE 0x00000004
+#define SC1200_GENLOCK_VIP_VSYNC_FALLING_EDGE 0x00000008
+#define SC1200_GENLOCK_TIMEOUT_ENABLE 0x00000010
+#define SC1200_GENLOCK_TVENC_RESET_EVEN_FIELD 0x00000020
+#define SC1200_GENLOCK_TVENC_RESET_BEFORE_DELAY 0x00000040
+#define SC1200_GENLOCK_TVENC_RESET_ENABLE 0x00000080
+#define SC1200_GENLOCK_SYNC_TO_TVENC 0x00000100
+#define SC1200_GENLOCK_DELAY_MASK 0x001FFFFF
+
+/* TVOUT HORIZONTAL PRE ENCODER SCALE BIT DEFINITIONS */
+
+#define SC1200_TVOUT_YC_DELAY_MASK 0x00C00000
+#define SC1200_TVOUT_YC_DELAY_NONE 0x00000000
+#define SC1200_TVOUT_Y_DELAY_ONE_PIXEL 0x00400000
+#define SC1200_TVOUT_C_DELAY_ONE_PIXEL 0x00800000
+#define SC1200_TVOUT_C_DELAY_TWO_PIXELS 0x00C00000
+
+/* TVOUT HORIZONTAL SCALING/CONTROL BIT DEFINITIONS */
+
+#define SC1200_TVOUT_FLICKER_FILTER_MASK 0x60000000
+#define SC1200_TVOUT_FLICKER_FILTER_FOURTH_HALF_FOURTH 0x00000000
+#define SC1200_TVOUT_FLICKER_FILTER_HALF_ONE_HALF 0x20000000
+#define SC1200_TVOUT_FLICKER_FILTER_DISABLED 0x40000000
+#define SC1200_TVENC_EXTERNAL_RESET_INTERVAL_MASK 0x0F000000
+#define SC1200_TVENC_EXTERNAL_RESET_EVERY_ODD_FIELD 0x00000000
+#define SC1200_TVENC_EXTERNAL_RESET_EVERY_EVEN_FIELD 0x02000000
+#define SC1200_TVENC_EXTERNAL_RESET_NEXT_ODD_FIELD 0x05000000
+#define SC1200_TVENC_EXTERNAL_RESET_NEXT_EVEN_FIELD 0x07000000
+#define SC1200_TVENC_EXTERNAL_RESET_EVERY_FIELD 0x0E000000
+#define SC1200_TVENC_EXTERNAL_RESET_EVERY_X_ODD_FIELDS 0x08000000
+#define SC1200_TVENC_EXTERNAL_RESET_EVERY_X_EVEN_FIELDS 0x0A000000
+
+/* TVOUT DEBUG BIT DEFINITIONS */
+
+#define SC1200_TVOUT_FIELD_STATUS_EVEN 0x00000040
+#define SC1200_TVOUT_FIELD_STATUS_TV 0x00000080
+#define SC1200_TVOUT_CRT_VSYNC_STATUS_TRAILING 0x00000100
+#define SC1200_TVOUT_FIELD_STATUS_INVERT 0x00000200
+#define SC1200_TVOUT_CONVERTER_INTERPOLATION 0x00000400
+
+/* TVENC TIMING/CONTROL 1 BIT DEFINITIONS (REGISTER 0xC00) */
+
+#define SC1200_TVENC_VPHASE_MASK 0x001FF800
+#define SC1200_TVENC_VPHASE_POS 11
+#define SC1200_TVENC_SUB_CARRIER_RESET_MASK 0x30000000
+#define SC1200_TVENC_SUB_CARRIER_RESET_NEVER 0x00000000
+#define SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_LINES 0x10000000
+#define SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_FRAMES 0x20000000
+#define SC1200_TVENC_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES 0x30000000
+#define SC1200_TVENC_VIDEO_TIMING_ENABLE 0x80000000
+
+/* TVENC TIMING/CONTROL 2 BIT DEFINITIONS (REGISTER 0xC04) */
+
+#define SC1200_TVENC_OUTPUT_YCBCR 0x40000000
+#define SC1200_TVENC_CFS_MASK 0x00030000
+#define SC1200_TVENC_CFS_BYPASS 0x00000000
+#define SC1200_TVENC_CFS_CVBS 0x00020000
+#define SC1200_TVENC_CFS_SVIDEO 0x00030000
+
+/* TVENC TIMING/CONTROL 3 BIT DEFINITIONS (REGISTER 0xC08) */
+
+#define SC1200_TVENC_CS 0x00000001
+#define SC1200_TVENC_SYNCMODE_MASK 0x00000006
+#define SC1200_TVENC_SYNC_ON_GREEN 0x00000002
+#define SC1200_TVENC_SYNC_ON_CVBS 0x00000004
+#define SC1200_TVENC_CM 0x00000008
+
+/* TVENC DAC CONTROL BIT DEFINITIONS (REGISTER 0xC2C) */
+#define SC1200_TVENC_TRIM_MASK 0x00000007
+#define SC1200_TVENC_POWER_DOWN 0x00000020
+
+/* TVENC MV CONTROL BIT DEFINITIONS (REGISTER 0xC30) */
+#define SC1200_TVENC_MV_ENABLE 0xBE
+
+/* SC1200 VIP REGISTER DEFINITIONS */
+
+#define SC1200_VIP_CONFIG 0x00000000
+#define SC1200_VIP_CONTROL 0x00000004
+#define SC1200_VIP_STATUS 0x00000008
+#define SC1200_VIP_CURRENT_LINE 0x00000010
+#define SC1200_VIP_LINE_TARGET 0x00000014
+#define SC1200_ODD_DIRECT_VBI_LINE_ENABLE 0x00000018
+#define SC1200_EVEN_DIRECT_VBI_LINE_ENABLE 0x0000001C
+#define SC1200_VIP_ODD_BASE 0x00000020
+#define SC1200_VIP_EVEN_BASE 0x00000024
+#define SC1200_VIP_PITCH 0x00000028
+#define SC1200_VBI_ODD_BASE 0x00000040
+#define SC1200_VBI_EVEN_BASE 0x00000044
+#define SC1200_VBI_PITCH 0x00000048
+
+/* "SC1200_VIP_CONFIG" BIT DEFINITIONS */
+
+#define SC1200_VIP_MODE_MASK 0x00000003
+#define SC1200_VIP_MODE_C 0x00000002
+#define SC1200_VBI_ANCILLARY_TO_MEMORY 0x000C0000
+#define SC1200_VBI_TASK_A_TO_MEMORY 0x00140000
+#define SC1200_VBI_TASK_B_TO_MEMORY 0x00240000
+#define SC1200_VIP_BUS_REQUEST_THRESHOLD 0x00400000
+
+/* "SC1200_VIP_CONTROL" BIT DEFINITIONS */
+
+#define SC1200_CAPTURE_RUN_MODE_MASK 0x00000003
+#define SC1200_CAPTURE_RUN_MODE_STOP_LINE 0x00000000
+#define SC1200_CAPTURE_RUN_MODE_STOP_FIELD 0x00000001
+#define SC1200_CAPTURE_RUN_MODE_START 0x00000003
+#define SC1200_VIP_DATA_CAPTURE_EN 0x00000100
+#define SC1200_VIP_VBI_CAPTURE_EN 0x00000200
+#define SC1200_VIP_VBI_FIELD_INTERRUPT_EN 0x00010000
+
+/* "SC1200_VIP_STATUS" BIT DEFINITIONS */
+
+#define SC1200_VIP_CURRENT_FIELD_ODD 0x01000000
+#define SC1200_VIP_BASE_NOT_UPDATED 0x00200000
+#define SC1200_VIP_FIFO_OVERFLOW 0x00100000
+#define SC1200_VIP_CLEAR_LINE_INT 0x00020000
+#define SC1200_VIP_CLEAR_FIELD_INT 0x00010000
+#define SC1200_VBI_DATA_CAPTURE_ACTIVE 0x00000200
+#define SC1200_VIDEO_DATA_CAPTURE_ACTIVE 0x00000100
+
+/* "SC1200_VIP_CURRENT_LINE" BIT DEFINITIONS */
+
+#define SC1200_VIP_CURRENT_LINE_MASK 0x000003FF
+
+/* "SC1200_VIP_LINE_TARGET" BIT DEFINITIONS */
+
+#define SC1200_VIP_LAST_LINE_MASK 0x03FF0000
+
+/* "SC1200_VIP_PITCH" BIT DEFINITION */
+
+#define SC1200_VIP_PITCH_MASK 0x0000FFFC
+
+/* "SC1200_VBI_PITCH" BIT DEFINITION */
+
+#define SC1200_VBI_PITCH_MASK 0x0000FFFC
+
+/* SC1200 DIRECT VBI LINE ENABLE BIT DEFINITION */
+
+#define SC1200_DIRECT_VBI_LINE_ENABLE_MASK 0x00FFFFFF
+
+/* SC1200 CONFIGURATION BLOCK */
+
+#define SC1200_CB_BASE_ADDR 0x9000
+#define SC1200_CB_WDTO 0x0000
+#define SC1200_CB_WDCNFG 0x0002
+#define SC1200_CB_WDSTS 0x0004
+#define SC1200_CB_TMVALUE 0x0008
+#define SC1200_CB_TMCNFG 0x000D
+#define SC1200_CB_CCFC 0x001E
+#define SC1200_CB_PMR 0x0030
+#define SC1200_CB_MCR 0x0034
+#define SC1200_CB_INTSEL 0x0038
+#define SC1200_CB_PID 0x003C
+#define SC1200_CB_REV 0x003D
+
+/* SC1200 HIGH RESOLUTION TIMER CONFIGURATION REGISTER BITS */
+
+#define SC1200_TMCLKSEL_27MHZ 0x2
+
+/*---------------------------------*/
+/* PHILIPS SAA7114 VIDEO DECODER */
+/*---------------------------------*/
+
+#define SAA7114_CHIPADDR 0x42
+
+/* VIDEO DECODER REGISTER DEFINITIONS */
+
+#define SAA7114_ANALOG_INPUT_CTRL1 0x02
+#define SAA7114_LUMINANCE_CONTROL 0x09
+#define SAA7114_BRIGHTNESS 0x0A
+#define SAA7114_CONTRAST 0x0B
+#define SAA7114_SATURATION 0x0C
+#define SAA7114_HUE 0x0D
+#define SAA7114_STATUS 0x1F
+#define SAA7114_IPORT_CONTROL 0x86
+
+/* TASK A REGISTER DEFINITIONS */
+
+#define SAA7114_TASK_A_HORZ_OUTPUT_LO 0x9C
+#define SAA7114_TASK_A_HORZ_OUTPUT_HI 0x9D
+#define SAA7114_TASK_A_HSCALE_LUMA_LO 0xA8
+#define SAA7114_TASK_A_HSCALE_LUMA_HI 0xA9
+#define SAA7114_TASK_A_HSCALE_CHROMA_LO 0xAC
+#define SAA7114_TASK_A_HSCALE_CHROMA_HI 0xAD
+
+/* TASK B REGISTER DEFINITIONS */
+
+#define SAA7114_HORZ_OFFSET_LO 0xC4
+#define SAA7114_HORZ_OFFSET_HI 0xC5
+#define SAA7114_HORZ_INPUT_LO 0xC6
+#define SAA7114_HORZ_INPUT_HI 0xC7
+#define SAA7114_VERT_OFFSET_LO 0xC8
+#define SAA7114_VERT_OFFSET_HI 0xC9
+#define SAA7114_VERT_INPUT_LO 0xCA
+#define SAA7114_VERT_INPUT_HI 0xCB
+#define SAA7114_HORZ_OUTPUT_LO 0xCC
+#define SAA7114_HORZ_OUTPUT_HI 0xCD
+#define SAA7114_VERT_OUTPUT_LO 0xCE
+#define SAA7114_VERT_OUTPUT_HI 0xCF
+#define SAA7114_HORZ_PRESCALER 0xD0
+#define SAA7114_HORZ_ACL 0xD1
+#define SAA7114_HORZ_FIR_PREFILTER 0xD2
+#define SAA7114_FILTER_CONTRAST 0xD5
+#define SAA7114_FILTER_SATURATION 0xD6
+#define SAA7114_HSCALE_LUMA_LO 0xD8
+#define SAA7114_HSCALE_LUMA_HI 0xD9
+#define SAA7114_HSCALE_CHROMA_LO 0xDC
+#define SAA7114_HSCALE_CHROMA_HI 0xDD
+#define SAA7114_VSCALE_LUMA_LO 0xE0
+#define SAA7114_VSCALE_LUMA_HI 0xE1
+#define SAA7114_VSCALE_CHROMA_LO 0xE2
+#define SAA7114_VSCALE_CHROMA_HI 0xE3
+#define SAA7114_VSCALE_CONTROL 0xE4
+#define SAA7114_VSCALE_CHROMA_OFFS0 0xE8
+#define SAA7114_VSCALE_CHROMA_OFFS1 0xE9
+#define SAA7114_VSCALE_CHROMA_OFFS2 0xEA
+#define SAA7114_VSCALE_CHROMA_OFFS3 0xEB
+#define SAA7114_VSCALE_LUMINA_OFFS0 0xEC
+#define SAA7114_VSCALE_LUMINA_OFFS1 0xED
+#define SAA7114_VSCALE_LUMINA_OFFS2 0xEE
+#define SAA7114_VSCALE_LUMINA_OFFS3 0xEF
+
+/* Still need to determine PHO value (common phase offset) */
+#define SAA7114_VSCALE_PHO 0x00
+
+/*----------------------------------------------*/
+/* SECOND GENERATION GRAPHICS UNIT (REDCLOUD) */
+/*----------------------------------------------*/
+
+#define MGP_DST_OFFSET 0x0000 /* dst address */
+#define MGP_SRC_OFFSET 0x0004 /* src address */
+#define MGP_VEC_ERR 0x0004 /* vector diag/axial errors */
+#define MGP_STRIDE 0x0008 /* src and dst strides */
+#define MGP_WID_HEIGHT 0x000C /* width and height of BLT */
+#define MGP_VEC_LEN 0x000C /* vector length/init error */
+#define MGP_SRC_COLOR_FG 0x0010 /* src mono data fgcolor */
+#define MGP_SRC_COLOR_BG 0x0014 /* src mono data bkcolor */
+#define MGP_PAT_COLOR_0 0x0018 /* pattern color 0 */
+#define MGP_PAT_COLOR_1 0x001C /* pattern color 1 */
+#define MGP_PAT_COLOR_2 0x0020 /* pattern color 2 */
+#define MGP_PAT_COLOR_3 0x0024 /* pattern color 3 */
+#define MGP_PAT_COLOR_4 0x0028 /* pattern color 4 */
+#define MGP_PAT_COLOR_5 0x002C /* pattern color 5 */
+#define MGP_PAT_DATA_0 0x0030 /* pattern data 0 */
+#define MGP_PAT_DATA_1 0x0034 /* pattern data 1 */
+#define MGP_RASTER_MODE 0x0038 /* raster operation */
+#define MGP_VECTOR_MODE 0x003C /* render vector */
+#define MGP_BLT_MODE 0x0040 /* render BLT */
+#define MGP_BLT_STATUS 0x0044 /* BLT status register */
+#define MGP_RESET 0x0044 /* reset register (write) */
+#define MGP_HST_SOURCE 0x0048 /* host src data (bitmap) */
+#define MGP_BASE_OFFSET 0x004C /* base render offset */
+
+/* MGP_RASTER_MODE DEFINITIONS */
+
+#define MGP_RM_BPPFMT_332 0x00000000 /* 8 BPP, 3:3:2 */
+#define MGP_RM_BPPFMT_4444 0x40000000 /* 16 BPP, 4:4:4:4 */
+#define MGP_RM_BPPFMT_1555 0x50000000 /* 16 BPP, 1:5:5:5 */
+#define MGP_RM_BPPFMT_565 0x60000000 /* 16 BPP, 5:6:5 */
+#define MGP_RM_BPPFMT_8888 0x80000000 /* 32 BPP, 8:8:8:8 */
+#define MGP_RM_ALPHA_EN_MASK 0x00C00000 /* Alpha enable */
+#define MGP_RM_ALPHA_TO_RGB 0x00400000 /* Alpha applies to RGB */
+#define MGP_RM_ALPHA_TO_ALPHA 0x00800000 /* Alpha applies to alpha */
+#define MGP_RM_ALPHA_OP_MASK 0x00300000 /* Alpha operation */
+#define MGP_RM_ALPHA_TIMES_A 0x00000000 /* Alpha * A */
+#define MGP_RM_BETA_TIMES_B 0x00100000 /* (1-alpha) * B */
+#define MGP_RM_A_PLUS_BETA_B 0x00200000 /* A + (1-alpha) * B */
+#define MGP_RM_ALPHA_A_PLUS_BETA_B 0x00300000 /* alpha * A + (1 - alpha)B */
+#define MGP_RM_ALPHA_SELECT 0x000E0000 /* Alpha Select */
+#define MGP_RM_SELECT_ALPHA_A 0x00000000 /* Alpha from channel A */
+#define MGP_RM_SELECT_ALPHA_B 0x00020000 /* Alpha from channel B */
+#define MGP_RM_SELECT_ALPHA_R 0x00040000 /* Registered alpha */
+#define MGP_RM_SELECT_ALPHA_1 0x00060000 /* Constant 1 */
+#define MGP_RM_SELECT_ALPHA_CHAN_A 0x00080000 /* RGB Values from A */
+#define MGP_RM_SELECT_ALPHA_CHAN_B 0x000A0000 /* RGB Values from B */
+#define MGP_RM_DEST_FROM_CHAN_A 0x00010000 /* Alpha channel select */
+#define MGP_RM_PAT_FLAGS 0x00000700 /* pattern related bits */
+#define MGP_RM_PAT_MONO 0x00000100 /* monochrome pattern */
+#define MGP_RM_PAT_COLOR 0x00000200 /* color pattern */
+#define MGP_RM_PAT_TRANS 0x00000400 /* pattern transparency */
+#define MGP_RM_SRC_TRANS 0x00000800 /* source transparency */
+
+/* MGP_VECTOR_MODE DEFINITIONS */
+
+#define MGP_VM_DST_REQ 0x00000008 /* dst data required */
+#define MGP_VM_THROTTLE 0x00000010 /* sync to VBLANK */
+
+/* MGP_BLT_MODE DEFINITIONS */
+
+#define MGP_BM_SRC_FB 0x00000001 /* src = frame buffer */
+#define MGP_BM_SRC_HOST 0x00000002 /* src = host register */
+#define MGP_BM_DST_REQ 0x00000004 /* dst data required */
+#define MGP_BM_SRC_MONO 0x00000040 /* monochrome source data */
+#define MGP_BM_SRC_BP_MONO 0x00000080 /* Byte-packed monochrome */
+#define MGP_BM_SRC_TYPE_MASK 0x000000C0 /* Mask for all source fmts */
+#define MGP_BM_NEG_YDIR 0x00000100 /* negative Y direction */
+#define MGP_BM_NEG_XDIR 0x00000200 /* negative X direction */
+#define MGP_BM_THROTTLE 0x00000400 /* sync to VBLANK */
+
+/* MGP_BLT_STATUS DEFINITIONS */
+
+#define MGP_BS_BLT_BUSY 0x00000001 /* GP is not idle */
+#define MGP_BS_BLT_PENDING 0x00000004 /* second BLT is pending */
+#define MGP_BS_HALF_EMPTY 0x00000008 /* src FIFO half empty */
+
+/* ALPHA BLENDING MODES */
+
+#define ALPHA_MODE_BLEND 0x00000000
+
+/*---------------------------------------------------*/
+/* SECOND GENERATION DISPLAY CONTROLLER (REDCLOUD) */
+/*---------------------------------------------------*/
+
+#define MDC_UNLOCK 0x00000000 /* Unlock register */
+#define MDC_GENERAL_CFG 0x00000004 /* Config registers */
+#define MDC_DISPLAY_CFG 0x00000008
+#define MDC_GFX_SCL 0x0000000C /* Graphics scaling */
+
+#define MDC_FB_ST_OFFSET 0x00000010 /* Frame buffer start offset */
+#define MDC_CB_ST_OFFSET 0x00000014 /* Compression start offset */
+#define MDC_CURS_ST_OFFSET 0x00000018 /* Cursor buffer start */
+ /* offset */
+#define MDC_ICON_ST_OFFSET 0x0000001C /* Icon buffer start offset */
+#define MDC_VID_Y_ST_OFFSET 0x00000020 /* Video Y Buffer start */
+ /* offset */
+#define MDC_VID_U_ST_OFFSET 0x00000024 /* Video U Buffer start */
+ /* offset */
+#define MDC_VID_V_ST_OFFSET 0x00000028 /* Video V Buffer start */
+ /* offset */
+#define MDC_LINE_SIZE 0x00000030 /* Video, CB, and FB line */
+ /* sizes */
+#define MDC_GFX_PITCH 0x00000034 /* FB and DB skip counts */
+#define MDC_VID_YUV_PITCH 0x00000038 /* Y, U and V buffer skip */
+ /* counts */
+
+#define MDC_H_ACTIVE_TIMING 0x00000040 /* Horizontal timings */
+#define MDC_H_BLANK_TIMING 0x00000044
+#define MDC_H_SYNC_TIMING 0x00000048
+#define MDC_V_ACTIVE_TIMING 0x00000050 /* Vertical Timings */
+#define MDC_V_BLANK_TIMING 0x00000054
+#define MDC_V_SYNC_TIMING 0x00000058
+
+#define MDC_CURSOR_X 0x00000060 /* Cursor X position */
+#define MDC_CURSOR_Y 0x00000064 /* Cursor Y Position */
+#define MDC_ICON_X 0x00000068 /* Icon X Position */
+#define MDC_LINE_CNT_STATUS 0x0000006C /* Icon Y Position */
+
+#define MDC_PAL_ADDRESS 0x00000070 /* Palette Address */
+#define MDC_PAL_DATA 0x00000074 /* Palette Data */
+#define MDC_DFIFO_DIAG 0x00000078 /* Display FIFO diagnostic */
+#define MDC_CFIFO_DIAG 0x0000007C /* Compression FIFO */
+ /* diagnostic */
+
+#define MDC_VID_DS_DELTA 0x00000080 /* Vertical Downscaling */
+ /* fraction */
+
+#define MDC_PHY_MEM_OFFSET 0x00000084 /* VG Base Address Register */
+#define MDC_DV_CTL 0x00000088 /* Dirty-Valid Control */
+ /* Register */
+#define MDC_DV_ACC 0x0000008C /* Dirty-Valid RAM Access */
+
+/* UNLOCK VALUE */
+
+#define MDC_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */
+
+/* VG MBUS DEVICE SMI MSR FIELDS */
+
+#define MDC_VG_BL_MASK 0x00000001
+#define MDC_MISC_MASK 0x00000002
+#define MDC_ISR0_MASK 0x00000004
+#define MDC_VGA_BL_MASK 0x00000008
+#define MDC_CRTCIO_MSK 0x00000010
+#define MDC_VG_BLANK_SMI 0x00000001
+#define MDC_MISC_SMI 0x00000002
+#define MDC_ISR0_SMI 0x00000004
+#define MDC_VGA_BLANK_SMI 0x00000008
+#define MDC_CRTCIO_SMI 0x00000010
+
+/* MDC_GENERAL_CFG BIT FIELDS */
+
+#define MDC_GCFG_DBUG 0x80000000
+#define MDC_GCFG_DBSL 0x40000000
+#define MDC_GCFG_CFRW 0x20000000
+#define MDC_GCFG_DIAG 0x10000000
+#define MDC_GCFG_GXRFS4 0x08000000
+#define MDC_GCFG_SGFR 0x04000000
+#define MDC_GCFG_SGRE 0x02000000
+#define MDC_GCFG_SIGE 0x01000000
+#define MDC_GCFG_YUVM 0x00100000
+#define MDC_GCFG_VDSE 0x00080000
+#define MDC_GCFG_VGAFT 0x00040000
+#define MDC_GCFG_FDTY 0x00020000
+#define MDC_GCFG_STFM 0x00010000
+#define MDC_GCFG_DFHPEL_MASK 0x0000F000
+#define MDC_GCFG_DFHPSL_MASK 0x00000F00
+#define MDC_GCFG_VGAE 0x00000080
+#define MDC_GCFG_DECE 0x00000040
+#define MDC_GCFG_CMPE 0x00000020
+#define MDC_GCFG_VIDE 0x00000008
+#define MDC_GCFG_ICNE 0x00000004
+#define MDC_GCFG_CURE 0x00000002
+#define MDC_GCFG_DFLE 0x00000001
+
+/* MDC_DISPLAY_CFG BIT FIELDS */
+
+#define MDC_DCFG_A20M 0x80000000
+#define MDC_DCFG_A18M 0x40000000
+#define MDC_DCFG_VISL 0x08000000
+#define MDC_DCFG_FRLK 0x04000000
+#define MDC_DCFG_PALB 0x02000000
+#define MDC_DCFG_PIX_PAN_MASK 0x00F00000
+#define MDC_DCFG_DCEN 0x00080000
+#define MDC_DCFG_16BPP_MODE_MASK 0x00000C00
+#define MDC_DCFG_16BPP 0x00000000
+#define MDC_DCFG_15BPP 0x00000400
+#define MDC_DCFG_12BPP 0x00000800
+#define MDC_DCFG_DISP_MODE_MASK 0x00000300
+#define MDC_DCFG_DISP_MODE_8BPP 0x00000000
+#define MDC_DCFG_DISP_MODE_16BPP 0x00000100
+#define MDC_DCFG_DISP_MODE_24BPP 0x00000200
+#define MDC_DCFG_SCLE 0x00000080
+#define MDC_DCFG_TRUP 0x00000040
+#define MDC_DCFG_VIEN 0x00000020
+#define MDC_DCFG_VDEN 0x00000010
+#define MDC_DCFG_GDEN 0x00000008
+#define MDC_DCFG_VCKE 0x00000004
+#define MDC_DCFG_PCKE 0x00000002
+#define MDC_DCFG_TGEN 0x00000001
+
+/* MDC_LINE_CNT BIT FIELDS */
+
+#define MDC_LNCNT_DNA 0x80000000
+#define MDC_LNCNT_VNA 0x40000000
+#define MDC_LNCNT_VSA 0x20000000
+#define MDC_LNCNT_VINT 0x10000000
+#define MDC_LNCNT_FLIP 0x08000000
+#define MDC_LNCNT_V_LINE_CNT 0x07FF0000
+#define MDC_LNCNT_VFLIP 0x00008000
+#define MDC_LNCNT_SIGC 0x00004000
+#define MDC_LNCNT_SS_LINE_CMP 0x000007FF
+
+/* MDC_FB_ST_OFFSET BIT FIELDS */
+
+#define MDC_FB_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* MDC_CB_ST_OFFSET BIT FIELDS */
+
+#define MDC_CB_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* MDC_CURS_ST_OFFSET BIT FIELDS */
+
+#define MDC_CURS_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* MDC_ICON_ST_OFFSET BIT FIELDS */
+
+#define MDC_ICON_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* MDC_VID_Y_ST_OFFSET BIT FIELDS */
+
+#define MDC_VID_Y_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* MDC_VID_U_ST_OFFSET BIT FIELDS */
+
+#define MDC_VID_U_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* MDC_VID_V_ST_OFFSET BIT FIELDS */
+
+#define MDC_VID_V_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* MDC_LINE_SIZE BIT FIELDS */
+
+#define MDC_LINE_SIZE_VLS_MASK 0xFF000000
+#define MDC_LINE_SIZE_CBLS_MASK 0x007F0000
+#define MDC_LINE_SIZE_FBLS_MASK 0x000007FF
+
+/* MDC_GFX_PITCH BIT FIELDS */
+
+#define MDC_GFX_PITCH_CBP_MASK 0xFFFF0000
+#define MDC_GFX_PITCH_FBP_MASK 0x0000FFFF
+
+/* MDC_VID_YUV_PITCH BIT FIELDS */
+
+#define MDC_YUV_PITCH_UVP_MASK 0xFFFF0000
+#define MDC_YUV_PITCH_YBP_MASK 0x0000FFFF
+
+/* MDC_H_ACTIVE_TIMING BIT FIELDS */
+
+#define MDC_HAT_HT_MASK 0x0FF80000
+#define MDC_HAT_HA_MASK 0x00000FF8
+
+/* MDC_H_BLANK_TIMING BIT FIELDS */
+
+#define MDC_HBT_HBE_MASK 0x0FF80000
+#define MDC_HBT_HBS_MASK 0x00000FF8
+
+/* MDC_H_SYNC_TIMING BIT FIELDS */
+
+#define MDC_HST_HSE_MASK 0x0FF80000
+#define MDC_HST_HSS_MASK 0x00000FF8
+
+/* MDC_V_ACTIVE_TIMING BIT FIELDS */
+
+#define MDC_VAT_VT_MASK 0x07FF0000
+#define MDC_VAT_VA_MASK 0x000007FF
+
+/* MDC_V_BLANK_TIMING BIT FIELDS */
+
+#define MDC_VBT_VBE_MASK 0x07FF0000
+#define MDC_VBT_VBS_MASK 0x000007FF
+
+/* MDC_V_SYNC_TIMING BIT FIELDS */
+
+#define MDC_VST_VSE_MASK 0x07FF0000
+#define MDC_VST_VSS_MASK 0x000007FF
+
+/* MDC_DV_CTL BIT DEFINITIONS */
+
+#define MDC_DV_LINE_SIZE_MASK 0x00000C00
+#define MDC_DV_LINE_SIZE_1024 0x00000000
+#define MDC_DV_LINE_SIZE_2048 0x00000400
+#define MDC_DV_LINE_SIZE_4096 0x00000800
+#define MDC_DV_LINE_SIZE_8192 0x00000C00
+
+/* VGA DEFINITIONS */
+
+#define MDC_SEQUENCER_INDEX 0x03C4
+#define MDC_SEQUENCER_DATA 0x03C5
+#define MDC_SEQUENCER_RESET 0x00
+#define MDC_SEQUENCER_CLK_MODE 0x01
+
+#define MDC_RESET_VGA_DISP_ENABLE 0x03
+#define MDC_CLK_MODE_SCREEN_OFF 0x20
+
+/*---------------------------------------------------*/
+/* REDCLOUD DISPLAY FILTER */
+/*---------------------------------------------------*/
+
+/* RCDF VIDEO REGISTER DEFINITIONS */
+
+#define RCDF_VIDEO_CONFIG 0x000
+#define RCDF_DISPLAY_CONFIG 0x008
+#define RCDF_VIDEO_X_POS 0x010
+#define RCDF_VIDEO_Y_POS 0x018
+#define RCDF_VIDEO_SCALE 0x020
+#define RCDF_VIDEO_COLOR_KEY 0x028
+#define RCDF_VIDEO_COLOR_MASK 0x030
+#define RCDF_PALETTE_ADDRESS 0x038
+#define RCDF_PALETTE_DATA 0x040
+#define RCDF_VID_MISC 0x050
+#define RCDF_VID_CLOCK_SELECT 0x058
+#define RCDF_VIDEO_DOWNSCALER_CONTROL 0x078
+#define RCDF_VIDEO_DOWNSCALER_COEFFICIENTS 0x080
+#define RCDF_VID_CRC 0x088
+#define RCDF_VID_CRC32 0x090
+#define RCDF_VID_ALPHA_CONTROL 0x098
+#define RCDF_CURSOR_COLOR_KEY 0x0A0
+#define RCDF_CURSOR_COLOR_MASK 0x0A8
+#define RCDF_CURSOR_COLOR_1 0x0B0
+#define RCDF_CURSOR_COLOR_2 0x0B8
+#define RCDF_ALPHA_XPOS_1 0x0C0
+#define RCDF_ALPHA_YPOS_1 0x0C8
+#define RCDF_ALPHA_COLOR_1 0x0D0
+#define RCDF_ALPHA_CONTROL_1 0x0D8
+#define RCDF_ALPHA_XPOS_2 0x0E0
+#define RCDF_ALPHA_YPOS_2 0x0E8
+#define RCDF_ALPHA_COLOR_2 0x0F0
+#define RCDF_ALPHA_CONTROL_2 0x0F8
+#define RCDF_ALPHA_XPOS_3 0x100
+#define RCDF_ALPHA_YPOS_3 0x108
+#define RCDF_ALPHA_COLOR_3 0x110
+#define RCDF_ALPHA_CONTROL_3 0x118
+#define RCDF_VIDEO_REQUEST 0x120
+#define RCDF_ALPHA_WATCH 0x128
+#define RCDF_VIDEO_TEST_MODE 0x210
+#define RCDF_POWER_MANAGEMENT 0x410
+
+/* DISPLAY FILTER POWER MANAGEMENT DEFINITIONS */
+
+#define RCDF_PM_PANEL_POWER_ON 0x01000000
+
+/* DISPLAY FILTER MSRS */
+
+#define RCDF_MBD_MSR_DIAG_DF 0x2010
+#define RCDF_DIAG_32BIT_CRC 0x80000000
+
+/* "RCDF_VIDEO_CONFIG" BIT DEFINITIONS */
+
+#define RCDF_VCFG_VID_EN 0x00000001
+#define RCDF_VCFG_VID_INP_FORMAT 0x0000000C
+#define RCDF_VCFG_X_FILTER_EN 0x00000040
+#define RCDF_VCFG_Y_FILTER_EN 0x00000080
+#define RCDF_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00
+#define RCDF_VCFG_INIT_READ_MASK 0x01FF0000
+#define RCDF_VCFG_LINE_SIZE_UPPER 0x08000000
+#define RCDF_VCFG_4_2_0_MODE 0x10000000
+#define RCDF_VCFG_UYVY_FORMAT 0x00000000
+#define RCDF_VCFG_Y2YU_FORMAT 0x00000004
+#define RCDF_VCFG_YUYV_FORMAT 0x00000008
+#define RCDF_VCFG_YVYU_FORMAT 0x0000000C
+
+/* "RCDF_DISPLAY_CONFIG" BIT DEFINITIONS */
+
+#define RCDF_DCFG_DIS_EN 0x00000001
+#define RCDF_DCFG_HSYNC_EN 0x00000002
+#define RCDF_DCFG_VSYNC_EN 0x00000004
+#define RCDF_DCFG_DAC_BL_EN 0x00000008
+#define RCDF_DCFG_FP_PWR_EN 0x00000040
+#define RCDF_DCFG_FP_DATA_EN 0x00000080
+#define RCDF_DCFG_CRT_HSYNC_POL 0x00000100
+#define RCDF_DCFG_CRT_VSYNC_POL 0x00000200
+#define RCDF_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
+#define RCDF_DCFG_CRT_SYNC_SKW_INIT 0x00010000
+#define RCDF_DCFG_PWR_SEQ_DLY_MASK 0x000E0000
+#define RCDF_DCFG_PWR_SEQ_DLY_INIT 0x00080000
+#define RCDF_DCFG_VG_CK 0x00100000
+#define RCDF_DCFG_GV_PAL_BYP 0x00200000
+#define RCDF_DAC_VREF 0x04000000
+#define RCDF_FP_ON_STATUS 0x08000000
+
+/* "RCDF_VID_MISC" BIT DEFINITIONS */
+
+#define RCDF_GAMMA_BYPASS_BOTH 0x00000001
+#define RCDF_DAC_POWER_DOWN 0x00000400
+#define RCDF_ANALOG_POWER_DOWN 0x00000800
+
+/* "RCDF_VIDEO_DOWNSCALER_CONTROL" BIT DEFINITIONS */
+
+#define RCDF_VIDEO_DOWNSCALE_ENABLE 0x00000001
+#define RCDF_VIDEO_DOWNSCALE_FACTOR_POS 1
+#define RCDF_VIDEO_DOWNSCALE_FACTOR_MASK 0x0000001E
+#define RCDF_VIDEO_DOWNSCALE_TYPE_A 0x00000000
+#define RCDF_VIDEO_DOWNSCALE_TYPE_B 0x00000040
+#define RCDF_VIDEO_DOWNSCALE_TYPE_MASK 0x00000040
+
+/* "RCDF_VIDEO_DOWNSCALER_COEFFICIENTS" BIT DEFINITIONS */
+
+#define RCDF_VIDEO_DOWNSCALER_COEF1_POS 0
+#define RCDF_VIDEO_DOWNSCALER_COEF2_POS 8
+#define RCDF_VIDEO_DOWNSCALER_COEF3_POS 16
+#define RCDF_VIDEO_DOWNSCALER_COEF4_POS 24
+#define RCDF_VIDEO_DOWNSCALER_COEF_MASK 0xF
+
+/* VIDEO DE-INTERLACING AND ALPHA CONTROL */
+
+#define RCDF_NO_CK_OUTSIDE_ALPHA 0x00000100
+#define RCDF_CSC_VIDEO_YUV_TO_RGB 0x00000400
+#define RCDF_VIDEO_INPUT_IS_RGB 0x00002000
+#define RCDF_ALPHA1_PRIORITY_POS 16
+#define RCDF_ALPHA1_PRIORITY_MASK 0x00030000
+#define RCDF_ALPHA2_PRIORITY_POS 18
+#define RCDF_ALPHA2_PRIORITY_MASK 0x000C0000
+#define RCDF_ALPHA3_PRIORITY_POS 20
+#define RCDF_ALPHA3_PRIORITY_MASK 0x00300000
+
+/* VIDEO CURSOR COLOR KEY DEFINITIONS */
+
+#define RCDF_CURSOR_COLOR_KEY_ENABLE 0x20000000
+#define RCDF_CURSOR_COLOR_KEY_OFFSET_POS 24
+#define RCDF_CURSOR_COLOR_BITS 23
+#define RCDF_COLOR_MASK 0x00FFFFFF
+ /* 24 significant bits */
+
+/* ALPHA COLOR BIT DEFINITION (REGISTERS 0x68, 0x78, AND 0x88) */
+
+#define RCDF_ALPHA_COLOR_ENABLE 0x01000000
+
+/* ALPHA CONTROL BIT DEFINITIONS (REGISTERS 0x6C, 0x7C, AND 0x8C) */
+
+#define RCDF_ACTRL_WIN_ENABLE 0x00010000
+#define RCDF_ACTRL_LOAD_ALPHA 0x00020000
+
+/* VIDEO REQUEST DEFINITIONS (REGISTER 0x90) */
+
+#define RCDF_VIDEO_Y_REQUEST_POS 0
+#define RCDF_VIDEO_X_REQUEST_POS 16
+#define RCDF_VIDEO_REQUEST_MASK 0x000007FF
+
+/* GEODELINK DEVICE MSR REGISTER SUMMARY */
+
+#define MBD_MSR_CAP 0x2000 /* Device Capabilities */
+#define MBD_MSR_CONFIG 0x2001 /* Device Master Configuration */
+ /* Register */
+#define MBD_MSR_SMI 0x2002 /* MBus Device SMI Register */
+#define MBD_MSR_ERROR 0x2003 /* MBus Device Error */
+#define MBD_MSR_PM 0x2004 /* MBus Device Power Management */
+ /* Register */
+#define MBD_MSR_DIAG 0x2005 /* Mbus Device Diagnostic Register */
+
+/* DISPLAY FILTER MBD_MSR_DIAG DEFINITIONS */
+
+#define RCDF_MBD_DIAG_SEL0 0x00007FFF /* Lower 32-bits of Diag Bus
+ * Select */
+#define RCDF_MBD_DIAG_EN0 0x00008000 /* Enable for lower 32-bits of
+ * diag bus */
+#define RCDF_MBD_DIAG_SEL1 0x7FFF0000 /* Upper 32-bits of Diag Bus
+ * Select */
+#define RCDF_MBD_DIAG_EN1 0x80000000 /* Enable for upper 32-bits of
+ * diag bus */
+
+/* DISPLAY FILTER MBD_MSR_CONFIG DEFINITIONS */
+
+#define RCDF_CONFIG_FMT_MASK 0x00000038 /* Output Format */
+#define RCDF_CONFIG_FMT_CRT 0x00000000
+#define RCDF_CONFIG_FMT_FP 0x00000008
+
+/* MCP MSR DEFINITIONS */
+
+#define MCP_CLKOFF 0x0010
+#define MCP_CLKACTIVE 0x0011
+#define MCP_CLKDISABLE 0x0012
+#define MCP_CLK4ACK 0x0013
+#define MCP_SYS_RSTPLL 0x0014
+#define MCP_DOTPLL 0x0015
+#define MCP_DBGCLKCTL 0x0016
+#define MCP_RC_REVID 0x0017
+#define MCP_SETM0CTL 0x0040
+#define MCP_SETN0CTL 0x0048
+#define MCP_CMPVAL0 0x0050
+#define MCP_CMPMASK0 0x0051
+#define MCP_REGA 0x0058
+#define MCP_REGB 0x0059
+#define MCP_REGAMASK 0x005A
+#define MCP_REGAVAL 0x005B
+#define MCP_REGBMASK 0x005C
+#define MCP_REGBVAL 0x005D
+#define MCP_FIFOCTL 0x005E
+#define MCP_DIAGCTL 0x005F
+#define MCP_H0CTL 0x0060
+#define MCP_XSTATE 0x0066
+#define MCP_YSTATE 0x0067
+#define MCP_ACTION0 0x0068
+
+/* MCP_SYS_RSTPLL DEFINITIONS */
+
+#define MCP_DOTPOSTDIV3 0x00000008
+#define MCP_DOTPREMULT2 0x00000004
+#define MCP_DOTPREDIV2 0x00000002
+#define MCP_DOTPLL_HALFPIX 0x01000000
+
+/* MCP MBD_MSR_DIAG DEFINITIONS */
+
+#define MCP_MBD_DIAG_SEL0 0x00000007
+#define MCP_MBD_DIAG_EN0 0x00008000
+#define MCP_MBD_DIAG_SEL1 0x00070000
+#define MCP_MBD_DIAG_EN1 0x80000000
+
+/* MCP_DOTPLL DEFINITIONS */
+
+#define MCP_DOTPLL_P 0x00000003
+#define MCP_DOTPLL_N 0x000001FC
+#define MCP_DOTPLL_M 0x00001E00
+#define MCP_DOTPLL_LOCK 0x02000000
+#define MCP_DOTPLL_BYPASS 0x00008000
+
+/*---------------------------------------------------*/
+/* THIRD GENERATION DISPLAY CONTROLLER (CASTLE) */
+/*---------------------------------------------------*/
+
+#define DC3_VG_SPARE_MSR 0x2011
+
+#define DC3_UNLOCK 0x00000000 /* Unlock register */
+#define DC3_GENERAL_CFG 0x00000004 /* Config registers */
+#define DC3_DISPLAY_CFG 0x00000008
+#define DC3_ARB_CFG 0x0000000C
+
+#define DC3_FB_ST_OFFSET 0x00000010 /* Frame buffer start offset */
+#define DC3_CB_ST_OFFSET 0x00000014 /* Compression start offset */
+#define DC3_CURS_ST_OFFSET 0x00000018 /* Cursor buffer start
+ * offset */
+#define DC3_VID_Y_ST_OFFSET 0x00000020 /* Video Y Buffer start
+ * offset */
+#define DC3_VID_U_ST_OFFSET 0x00000024 /* Video U Buffer start
+ * offset */
+#define DC3_VID_V_ST_OFFSET 0x00000028 /* Video V Buffer start
+ * offset */
+#define DC3_LINE_SIZE 0x00000030 /* Video, CB, and FB line
+ * sizes */
+#define DC3_GFX_PITCH 0x00000034 /* FB and DB skip counts */
+#define DC3_VID_YUV_PITCH 0x00000038 /* Y, U and V buffer skip
+ * counts */
+
+#define DC3_H_ACTIVE_TIMING 0x00000040 /* Horizontal timings */
+#define DC3_H_BLANK_TIMING 0x00000044
+#define DC3_H_SYNC_TIMING 0x00000048
+#define DC3_V_ACTIVE_TIMING 0x00000050 /* Vertical Timings */
+#define DC3_V_BLANK_TIMING 0x00000054
+#define DC3_V_SYNC_TIMING 0x00000058
+
+#define DC3_CURSOR_X 0x00000060 /* Cursor X position */
+#define DC3_CURSOR_Y 0x00000064 /* Cursor Y Position */
+#define DC3_LINE_CNT_STATUS 0x0000006C /* Icon Y Position */
+
+#define DC3_PAL_ADDRESS 0x00000070 /* Palette Address */
+#define DC3_PAL_DATA 0x00000074 /* Palette Data */
+#define DC3_DFIFO_DIAG 0x00000078 /* Display FIFO diagnostic */
+#define DC3_CFIFO_DIAG 0x0000007C /* Compression FIFO
+ * diagnostic */
+
+#define DC3_VID_DS_DELTA 0x00000080 /* Vertical Downscaling
+ * fraction */
+
+#define DC3_PHY_MEM_OFFSET 0x00000084 /* VG Base Address Register */
+#define DC3_DV_CTL 0x00000088 /* Dirty-Valid Control
+ * Register */
+#define DC3_DV_ACC 0x0000008C /* Dirty-Valid RAM Access */
+
+#define DC3_GFX_SCALE 0x00000090
+#define DC3_IRQ_CTL 0x00000094
+
+#define DC3_COLOR_KEY 0x000000B8 /* Graphics color key */
+#define DC3_COLOR_MASK 0x000000BC /* Graphics color key mask */
+#define DC3_COLOR_KEY_X 0x000000C0 /* Color Key X Region */
+#define DC3_COLOR_KEY_Y 0x000000C4 /* Color Key Y Region */
+
+/* UNLOCK VALUE */
+
+#define DC3_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */
+
+/* VG SPARE MSR FIELDS */
+
+#define VG_SPARE_DISABLE_CFIFO_HGO 0x00000800
+#define VG_SPARE_VFIFO_ARB_SELECT 0x00000400
+#define VG_SPARE_WM_LPEN_OVRD 0x00000200
+#define VG_SPARE_LOAD_WM_LPEN_MASK 0x00000100
+#define VG_SPARE_DISABLE_INIT_VID_PRI 0x00000080
+#define VG_SPARE_DISABLE_VFIFO_WM 0x00000040
+#define VG_SPARE_DISABLE_CWD_CHECK 0x00000020
+#define VG_SPARE_PIX8_PAN_FIX 0x00000010
+#define VG_SPARE_FIRST_REQ_MASK 0x00000020
+
+/* VG MBUS DEVICE SMI MSR FIELDS */
+
+#define DC3_VG_BL_MASK 0x00000001
+#define DC3_MISC_MASK 0x00000002
+#define DC3_ISR0_MASK 0x00000004
+#define DC3_VGA_BL_MASK 0x00000008
+#define DC3_CRTCIO_MSK 0x00000010
+#define DC3_VG_BLANK_SMI 0x00000001
+#define DC3_MISC_SMI 0x00000002
+#define DC3_ISR0_SMI 0x00000004
+#define DC3_VGA_BLANK_SMI 0x00000008
+#define DC3_CRTCIO_SMI 0x00000010
+
+/* DC3_GENERAL_CFG BIT FIELDS */
+
+#define DC3_GCFG_DBUG 0x80000000
+#define DC3_GCFG_DBSL 0x40000000
+#define DC3_GCFG_CFRW 0x20000000
+#define DC3_GCFG_DIAG 0x10000000
+#define DC3_GCFG_SGFR 0x04000000
+#define DC3_GCFG_SGRE 0x02000000
+#define DC3_GCFG_SIGE 0x01000000
+#define DC3_GCFG_YUVM 0x00100000
+#define DC3_GCFG_VDSE 0x00080000
+#define DC3_GCFG_VGAFT 0x00040000
+#define DC3_GCFG_FDTY 0x00020000
+#define DC3_GCFG_STFM 0x00010000
+#define DC3_GCFG_DFHPEL_MASK 0x0000F000
+#define DC3_GCFG_DFHPSL_MASK 0x00000F00
+#define DC3_GCFG_VGAE 0x00000080
+#define DC3_GCFG_DECE 0x00000040
+#define DC3_GCFG_CMPE 0x00000020
+#define DC3_GCFG_VIDE 0x00000008
+#define DC3_GCFG_CURE 0x00000002
+#define DC3_GCFG_DFLE 0x00000001
+
+/* DC3_DISPLAY_CFG BIT FIELDS */
+
+#define DC3_DCFG_VISL 0x08000000
+#define DC3_DCFG_FRLK 0x04000000
+#define DC3_DCFG_PALB 0x02000000
+#define DC3_DCFG_PIX_PAN_MASK 0x00F00000
+#define DC3_DCFG_DCEN 0x00080000
+#define DC3_DCFG_16BPP_MODE_MASK 0x00000C00
+#define DC3_DCFG_16BPP 0x00000000
+#define DC3_DCFG_15BPP 0x00000400
+#define DC3_DCFG_12BPP 0x00000800
+#define DC3_DCFG_DISP_MODE_MASK 0x00000300
+#define DC3_DCFG_DISP_MODE_8BPP 0x00000000
+#define DC3_DCFG_DISP_MODE_16BPP 0x00000100
+#define DC3_DCFG_DISP_MODE_24BPP 0x00000200
+#define DC3_DCFG_SCLE 0x00000080
+#define DC3_DCFG_TRUP 0x00000040
+#define DC3_DCFG_VIEN 0x00000020
+#define DC3_DCFG_VDEN 0x00000010
+#define DC3_DCFG_GDEN 0x00000008
+#define DC3_DCFG_VCKE 0x00000004
+#define DC3_DCFG_PCKE 0x00000002
+#define DC3_DCFG_TGEN 0x00000001
+
+/* DC3_LINE_CNT BIT FIELDS */
+
+#define DC3_LNCNT_DNA 0x80000000
+#define DC3_LNCNT_VNA 0x40000000
+#define DC3_LNCNT_VSA 0x20000000
+#define DC3_LNCNT_VINT 0x10000000
+#define DC3_LNCNT_FLIP 0x08000000
+#define DC3_LNCNT_V_LINE_CNT 0x07FF0000
+#define DC3_LNCNT_VFLIP 0x00008000
+#define DC3_LNCNT_SIGC 0x00004000
+#define DC3_LNCNT_SS_LINE_CMP 0x000007FF
+
+/* DC3_FB_ST_OFFSET BIT FIELDS */
+
+#define DC3_FB_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_CB_ST_OFFSET BIT FIELDS */
+
+#define DC3_CB_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_CURS_ST_OFFSET BIT FIELDS */
+
+#define DC3_CURS_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_ICON_ST_OFFSET BIT FIELDS */
+
+#define DC3_ICON_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VID_Y_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_Y_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VID_U_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_U_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VID_V_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_V_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_LINE_SIZE BIT FIELDS */
+
+#define DC3_LINE_SIZE_VLS_MASK 0x3FF00000
+#define DC3_LINE_SIZE_CBLS_MASK 0x0007F000
+#define DC3_LINE_SIZE_FBLS_MASK 0x000003FF
+#define DC3_LINE_SIZE_CB_SHIFT 12
+#define DC3_LINE_SIZE_VB_SHIFT 20
+
+/* DC3_GFX_PITCH BIT FIELDS */
+
+#define DC3_GFX_PITCH_CBP_MASK 0xFFFF0000
+#define DC3_GFX_PITCH_FBP_MASK 0x0000FFFF
+
+/* DC3_VID_YUV_PITCH BIT FIELDS */
+
+#define DC3_YUV_PITCH_UVP_MASK 0xFFFF0000
+#define DC3_YUV_PITCH_YBP_MASK 0x0000FFFF
+
+/* DC3_H_ACTIVE_TIMING BIT FIELDS */
+
+#define DC3_HAT_HT_MASK 0x0FF80000
+#define DC3_HAT_HA_MASK 0x00000FF8
+
+/* DC3_H_BLANK_TIMING BIT FIELDS */
+
+#define DC3_HBT_HBE_MASK 0x0FF80000
+#define DC3_HBT_HBS_MASK 0x00000FF8
+
+/* DC3_H_SYNC_TIMING BIT FIELDS */
+
+#define DC3_HST_HSE_MASK 0x0FF80000
+#define DC3_HST_HSS_MASK 0x00000FF8
+
+/* DC3_V_ACTIVE_TIMING BIT FIELDS */
+
+#define DC3_VAT_VT_MASK 0x07FF0000
+#define DC3_VAT_VA_MASK 0x000007FF
+
+/* DC3_V_BLANK_TIMING BIT FIELDS */
+
+#define DC3_VBT_VBE_MASK 0x07FF0000
+#define DC3_VBT_VBS_MASK 0x000007FF
+
+/* DC3_V_SYNC_TIMING BIT FIELDS */
+
+#define DC3_VST_VSE_MASK 0x07FF0000
+#define DC3_VST_VSS_MASK 0x000007FF
+
+/* DC3_DV_CTL BIT DEFINITIONS */
+
+#define DC3_DV_LINE_SIZE_MASK 0x00000C00
+#define DC3_DV_LINE_SIZE_1024 0x00000000
+#define DC3_DV_LINE_SIZE_2048 0x00000400
+#define DC3_DV_LINE_SIZE_4096 0x00000800
+#define DC3_DV_LINE_SIZE_8192 0x00000C00
+
+#define DC3_CLR_KEY_DATA_MASK 0x00FFFFFF
+#define DC3_CLR_KEY_ENABLE 0x01000000
+#define DC3_CLR_KEY_INVERT 0x02000000
+
+/* VGA DEFINITIONS */
+
+#define DC3_SEQUENCER_INDEX 0x03C4
+#define DC3_SEQUENCER_DATA 0x03C5
+#define DC3_SEQUENCER_RESET 0x00
+#define DC3_SEQUENCER_CLK_MODE 0x01
+
+#define DC3_RESET_VGA_DISP_ENABLE 0x03
+#define DC3_CLK_MODE_SCREEN_OFF 0x20
+
+/*---------------------------------------------------*/
+/* CASTLE DISPLAY FILTER */
+/*---------------------------------------------------*/
+
+/* CASTLE VIDEO REGISTER DEFINITIONS */
+
+#define CASTLE_VIDEO_CONFIG 0x000
+#define CASTLE_DISPLAY_CONFIG 0x008
+#define CASTLE_VIDEO_X_POS 0x010
+#define CASTLE_VIDEO_Y_POS 0x018
+#define CASTLE_VIDEO_SCALER 0x020
+#define CASTLE_VIDEO_COLOR_KEY 0x028
+#define CASTLE_VIDEO_COLOR_MASK 0x030
+#define CASTLE_PALETTE_ADDRESS 0x038
+#define CASTLE_PALETTE_DATA 0x040
+#define CASTLE_VID_MISC 0x050
+#define CASTLE_VIDEO_YSCALE 0x060
+#define CASTLE_VIDEO_XSCALE 0x068
+#define CASTLE_VIDEO_DOWNSCALER_CONTROL 0x078
+#define CASTLE_VID_CRC 0x088
+#define CASTLE_VID_CRC32 0x090
+#define CASTLE_VID_ALPHA_CONTROL 0x098
+#define CASTLE_CURSOR_COLOR_KEY 0x0A0
+#define CASTLE_CURSOR_COLOR_MASK 0x0A8
+#define CASTLE_CURSOR_COLOR_1 0x0B0
+#define CASTLE_CURSOR_COLOR_2 0x0B8
+#define CASTLE_ALPHA_XPOS_1 0x0C0
+#define CASTLE_ALPHA_YPOS_1 0x0C8
+#define CASTLE_ALPHA_COLOR_1 0x0D0
+#define CASTLE_ALPHA_CONTROL_1 0x0D8
+#define CASTLE_ALPHA_XPOS_2 0x0E0
+#define CASTLE_ALPHA_YPOS_2 0x0E8
+#define CASTLE_ALPHA_COLOR_2 0x0F0
+#define CASTLE_ALPHA_CONTROL_2 0x0F8
+#define CASTLE_ALPHA_XPOS_3 0x100
+#define CASTLE_ALPHA_YPOS_3 0x108
+#define CASTLE_ALPHA_COLOR_3 0x110
+#define CASTLE_ALPHA_CONTROL_3 0x118
+#define CASTLE_VIDEO_REQUEST 0x120
+#define CASTLE_ALPHA_WATCH 0x128
+#define CASTLE_VIDEO_TEST_MODE 0x210
+#define CASTLE_POWER_MANAGEMENT 0x410
+#define CASTLE_COEFFICIENT_BASE 0x1000
+
+/* DISPLAY FILTER POWER MANAGEMENT DEFINITIONS */
+
+#define CASTLE_PM_PANEL_POWER_ON 0x01000000
+
+/* DISPLAY FILTER MSRS */
+
+#define CASTLE_MBD_MSR_DIAG_DF 0x2010
+#define CASTLE_DIAG_32BIT_CRC 0x80000000
+
+/* "CASTLE_VIDEO_CONFIG" BIT DEFINITIONS */
+
+#define CASTLE_VCFG_VID_EN 0x00000001
+#define CASTLE_VCFG_VID_INP_FORMAT 0x0000000C
+#define CASTLE_VCFG_SC_BYP 0x00000020
+#define CASTLE_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00
+#define CASTLE_VCFG_INIT_READ_MASK 0x01FF0000
+#define CASTLE_VCFG_LINE_SIZE_BIT9 0x04000000
+#define CASTLE_VCFG_LINE_SIZE_UPPER 0x08000000
+#define CASTLE_VCFG_4_2_0_MODE 0x10000000
+#define CASTLE_VCFG_UYVY_FORMAT 0x00000000
+#define CASTLE_VCFG_Y2YU_FORMAT 0x00000004
+#define CASTLE_VCFG_YUYV_FORMAT 0x00000008
+#define CASTLE_VCFG_YVYU_FORMAT 0x0000000C
+
+/* "CASTLE_DISPLAY_CONFIG" BIT DEFINITIONS */
+
+#define CASTLE_DCFG_DIS_EN 0x00000001
+#define CASTLE_DCFG_HSYNC_EN 0x00000002
+#define CASTLE_DCFG_VSYNC_EN 0x00000004
+#define CASTLE_DCFG_DAC_BL_EN 0x00000008
+#define CASTLE_DCFG_CRT_HSYNC_POL 0x00000100
+#define CASTLE_DCFG_CRT_VSYNC_POL 0x00000200
+#define CASTLE_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
+#define CASTLE_DCFG_CRT_SYNC_SKW_INIT 0x00010000
+#define CASTLE_DCFG_PWR_SEQ_DLY_MASK 0x000E0000
+#define CASTLE_DCFG_PWR_SEQ_DLY_INIT 0x00080000
+#define CASTLE_DCFG_VG_CK 0x00100000
+#define CASTLE_DCFG_GV_PAL_BYP 0x00200000
+#define CASTLE_DAC_VREF 0x04000000
+
+/* "CASTLE_VID_MISC" BIT DEFINITIONS */
+
+#define CASTLE_GAMMA_BYPASS_BOTH 0x00000001
+#define CASTLE_DAC_POWER_DOWN 0x00000400
+#define CASTLE_ANALOG_POWER_DOWN 0x00000800
+
+/* VIDEO DE-INTERLACING AND ALPHA CONTROL */
+
+#define CASTLE_NO_CK_OUTSIDE_ALPHA 0x00000100
+#define CASTLE_CSC_VIDEO_YUV_TO_RGB 0x00000400
+#define CASTLE_CSC_GRAPHICS_RGB_TO_YUV 0x00000800
+#define CASTLE_VIDEO_INPUT_IS_RGB 0x00002000
+#define CASTLE_ALPHA1_PRIORITY_POS 16
+#define CASTLE_ALPHA1_PRIORITY_MASK 0x00030000
+#define CASTLE_ALPHA2_PRIORITY_POS 18
+#define CASTLE_ALPHA2_PRIORITY_MASK 0x000C0000
+#define CASTLE_ALPHA3_PRIORITY_POS 20
+#define CASTLE_ALPHA3_PRIORITY_MASK 0x00300000
+
+/* VIDEO CURSOR COLOR KEY DEFINITIONS */
+
+#define CASTLE_CURSOR_COLOR_KEY_ENABLE 0x20000000
+#define CASTLE_CURSOR_COLOR_KEY_OFFSET_POS 24
+#define CASTLE_CURSOR_COLOR_BITS 23
+#define CASTLE_COLOR_MASK 0x00FFFFFF /* 24 significant
+ * bits */
+
+/* ALPHA COLOR BIT DEFINITION (REGISTERS 0x68, 0x78, AND 0x88) */
+
+#define CASTLE_ALPHA_COLOR_ENABLE 0x01000000
+
+/* ALPHA CONTROL BIT DEFINITIONS (REGISTERS 0x6C, 0x7C, AND 0x8C) */
+
+#define CASTLE_ACTRL_WIN_ENABLE 0x00010000
+#define CASTLE_ACTRL_LOAD_ALPHA 0x00020000
+
+/* CASTLE_VIDEO_SCALER DEFINITIONS */
+
+#define CASTLE_SCALE_128_PHASES 0x00002000
+
+/* VIDEO REQUEST DEFINITIONS (REGISTER 0x90) */
+
+#define CASTLE_VIDEO_Y_REQUEST_POS 0
+#define CASTLE_VIDEO_X_REQUEST_POS 16
+#define CASTLE_VIDEO_REQUEST_MASK 0x000007FF
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_rndr.c b/src/gfx/gfx_rndr.c
new file mode 100644
index 0000000..c5a46ac
--- /dev/null
+++ b/src/gfx/gfx_rndr.c
@@ -0,0 +1,671 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to program the 2D acceleration hardware:
+ *
+ * gfx_set_bpp
+ * gfx_set_solid_pattern
+ * gfx_set_mono_pattern
+ * gfx_set_color_pattern
+ * gfx_load_color_pattern_line
+ * gfx_set_solid_source
+ * gfx_set_mono_source
+ * gfx_set_raster_operation
+ * gfx_pattern_fill
+ * gfx_color_pattern_fill
+ * gfx_screen_to_screen_blt
+ * gfx_screen_to_screen_xblt
+ * gfx_color_bitmap_to_screen_blt
+ * gfx_color_bitmap_to_screen_xblt
+ * gfx_mono_bitmap_to_screen_blt
+ * gfx_bresenham_line
+ * gfx_wait_until_idle
+ * */
+
+/* STATIC VARIABLES */
+
+unsigned short GFXbpp = 16;
+unsigned short GFXbb0Base = 0x400;
+unsigned short GFXbb1Base = 0x930;
+unsigned short GFXbufferWidthPixels = 400;
+
+unsigned short GFXpatternFlags = 0;
+unsigned short GFXsourceFlags = 0;
+unsigned long GFXsavedColor = 0;
+unsigned short GFXsavedRop = 0;
+unsigned short GFXusesDstData = 0;
+
+/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */
+
+#if GFX_2DACCEL_GU1
+#include "rndr_gu1.c"
+#endif
+
+/* INCLUDE SUPPORT FOR SECOND GENERATION, IF SPECIFIED. */
+
+#if GFX_2DACCEL_GU2
+#include "rndr_gu2.c"
+#endif
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either first or second generation routines. */
+
+#if GFX_2DACCEL_DYNAMIC
+
+/*---------------------------------------------------------------------------
+ * gfx_reset_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_reset_pitch(unsigned short pitch)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_reset_pitch(pitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_bpp
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_bpp(unsigned short bpp)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_set_bpp(bpp);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_set_bpp(bpp);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_solid_source
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_solid_source(unsigned long color)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_set_solid_source(color);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_set_solid_source(color);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_mono_source
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_set_mono_source(bgcolor, fgcolor, transparent);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_set_mono_source(bgcolor, fgcolor, transparent);
+#endif
+}
+
+void
+gfx_set_pattern_flags(unsigned short flags)
+{
+ GFXpatternFlags |= flags;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_solid_pattern
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_solid_pattern(unsigned long color)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_set_solid_pattern(color);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_set_solid_pattern(color);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_mono_pattern
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparent)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_set_mono_pattern(bgcolor, fgcolor, data0, data1, transparent);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_set_mono_pattern(bgcolor, fgcolor, data0, data1, transparent);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_color_pattern
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1,
+ unsigned long data2, unsigned long data3, unsigned char transparent)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_set_color_pattern(bgcolor, fgcolor, data0, data1, data2, data3,
+ transparent);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_set_color_pattern(bgcolor, fgcolor, data0, data1, data2, data3,
+ transparent);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_load_color_pattern_line
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_load_color_pattern_line(y, pattern_8x8);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_load_color_pattern_line(y, pattern_8x8);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_raster_operation
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_raster_operation(unsigned char rop)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_set_raster_operation(rop);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_set_raster_operation(rop);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_pattern_fill
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_pattern_fill(x, y, width, height);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_pattern_fill(x, y, width, height);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_color_pattern_fill
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_color_pattern_fill(x, y, width, height, pattern);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_color_pattern_fill(x, y, width, height, pattern);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_screen_to_screen_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_screen_to_screen_xblt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_screen_to_screen_xblt(srcx, srcy, dstx, dsty, width, height,
+ color);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_screen_to_screen_xblt(srcx, srcy, dstx, dsty, width, height,
+ color);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_color_bitmap_to_screen_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height,
+ data, pitch);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height,
+ data, pitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_color_bitmap_to_screen_xblt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch,
+ unsigned long color)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_color_bitmap_to_screen_xblt(srcx, srcy, dstx, dsty, width, height,
+ data, pitch, color);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_color_bitmap_to_screen_xblt(srcx, srcy, dstx, dsty, width, height,
+ data, pitch, color);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_mono_bitmap_to_screen_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_mono_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height,
+ data, pitch);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_mono_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height,
+ data, pitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_text_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_text_blt(dstx, dsty, width, height, data);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_text_blt(dstx, dsty, width, height, data);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_bresenham_line
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_bresenham_line(x, y, length, initerr, axialerr, diagerr, flags);
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_bresenham_line(x, y, length, initerr, axialerr, diagerr, flags);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_wait_until_idle
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_wait_until_idle(void)
+{
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ gu1_wait_until_idle();
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu2_wait_until_idle();
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_blt_pending
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_test_blt_pending(void)
+{
+ int retval = 0;
+
+#if GFX_2DACCEL_GU1
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU1)
+ retval = gu1_test_blt_pending();
+#endif
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ retval = gu2_test_blt_pending();
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * NEW ROUTINES FOR REDCLOUD
+ *---------------------------------------------------------------------------
+ */
+
+/*---------------------------------------------------------------------------
+ * gfx2_set_source_stride
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_set_source_stride(unsigned short stride)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_set_source_stride(stride);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_set_destination_stride
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_set_destination_stride(unsigned short stride)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_set_destination_stride(stride);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_set_pattern_origin
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_set_pattern_origin(int x, int y)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_set_pattern_origin(x, y);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_set_source_transparency
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_set_source_transparency(unsigned long color, unsigned long mask)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_set_source_transparency(color, mask);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_set_alpha_mode
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_set_alpha_mode(int mode)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_set_alpha_mode(mode);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_set_alpha_value
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_set_alpha_value(unsigned char value)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_set_alpha_value(value);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_pattern_fill
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_pattern_fill(dstoffset, width, height);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_color_pattern_fill
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned long *pattern)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_color_pattern_fill(dstoffset, width, height, pattern);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_screen_to_screen_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset,
+ unsigned short width, unsigned short height, int flags)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_screen_to_screen_blt(srcoffset, dstoffset, width, height, flags);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_mono_expand_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
+ unsigned short srcy, unsigned long dstoffset, unsigned short width,
+ unsigned short height, int byte_packed)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_mono_expand_blt(srcbase, srcx, srcy, dstoffset, width, height,
+ byte_packed);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_color_bitmap_to_screen_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width, unsigned short height,
+ unsigned char *data, short pitch)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_color_bitmap_to_screen_blt(srcx, srcy, dstoffset, width, height,
+ data, pitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_text_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_text_blt(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_text_blt(dstoffset, width, height, data);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_mono_bitmap_to_screen_blt
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width, unsigned short height,
+ unsigned char *data, short pitch)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_mono_bitmap_to_screen_blt(srcx, srcy, dstoffset, width, height,
+ data, pitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_bresenham_line
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_bresenham_line(unsigned long dstoffset,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_bresenham_line(dstoffset, length, initerr, axialerr, diagerr,
+ flags);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx2_sync_to_vblank
+ *---------------------------------------------------------------------------
+ */
+void
+gfx2_sync_to_vblank(void)
+{
+#if GFX_2DACCEL_GU2
+ if (gfx_2daccel_type & GFX_2DACCEL_TYPE_GU2)
+ gu22_sync_to_vblank();
+#endif
+}
+
+#endif /* GFX_2DACCEL_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_rtns.h b/src/gfx/gfx_rtns.h
new file mode 100644
index 0000000..ad759f4
--- /dev/null
+++ b/src/gfx/gfx_rtns.h
@@ -0,0 +1,604 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This header file defines the Durango routines and variables used
+ * to access the memory mapped regions.
+ * */
+
+#ifndef _gfx_rtns_h
+#define _gfx_rtns_h
+
+/* INCLUDE DURANGO DEFINITIONS */
+/* These definitions are placed in another file to allow their inclusion
+ * in a user application. Such applications generally work through driver
+ * shell routines that simply pass their parameters to Durango routines.
+ * An external file provides an easy way to provide the definitions for these
+ * parameters without the applications gaining any Durango visisbility.
+ * */
+
+#include "gfx_type.h"
+
+/* COMPILER OPTION FOR C++ PROGRAMS */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* DURANGO MEMORY POINTERS */
+
+ extern unsigned char *gfx_virt_regptr;
+ extern unsigned char *gfx_virt_fbptr;
+ extern unsigned char *gfx_virt_vidptr;
+ extern unsigned char *gfx_virt_vipptr;
+ extern unsigned char *gfx_virt_spptr;
+ extern unsigned char *gfx_virt_gpptr;
+
+ extern unsigned char *gfx_phys_regptr;
+ extern unsigned char *gfx_phys_fbptr;
+ extern unsigned char *gfx_phys_vidptr;
+ extern unsigned char *gfx_phys_vipptr;
+ extern unsigned char *gfx_phys_spptr;
+ extern unsigned char *gfx_phys_gpptr;
+
+/* DURANGO VARIBLES FOR RUNTIME SELECTION AND POSSIBLE VALUES */
+
+ extern int gfx_display_type;
+#define GFX_DISPLAY_TYPE_GU1 0x0001
+#define GFX_DISPLAY_TYPE_GU2 0x0002
+#define GFX_DISPLAY_TYPE_GU3 0x0004
+
+ extern int gfx_init_type;
+#define GFX_INIT_TYPE_GU1 0x0001
+#define GFX_INIT_TYPE_GU2 0x0002
+#define GFX_INIT_TYPE_GU3 0x0004
+
+ extern int gfx_msr_type;
+#define GFX_MSR_TYPE_REDCLOUD 0x0001
+
+ extern int gfx_2daccel_type;
+#define GFX_2DACCEL_TYPE_GU1 0x0001
+#define GFX_2DACCEL_TYPE_GU2 0x0002
+
+ extern int gfx_video_type;
+#define GFX_VIDEO_TYPE_CS5530 0x0001
+#define GFX_VIDEO_TYPE_SC1200 0x0002
+#define GFX_VIDEO_TYPE_REDCLOUD 0x0004
+#define GFX_VIDEO_TYPE_CASTLE 0x0008
+
+ extern int gfx_vip_type;
+#define GFX_VIP_TYPE_SC1200 0x0001
+
+ extern int gfx_decoder_type;
+#define GFX_DECODER_TYPE_SAA7114 0x0001
+
+ extern int gfx_tv_type;
+#define GFX_TV_TYPE_SC1200 0x0001
+#define GFX_TV_TYPE_FS451 0x0002
+
+ extern int gfx_i2c_type;
+#define GFX_I2C_TYPE_ACCESS 0x0001
+#define GFX_I2C_TYPE_GPIO 0x0002
+
+/* GLOBAL CPU INFORMATION */
+
+ extern unsigned long gfx_cpu_version;
+ extern unsigned long gfx_cpu_frequency;
+ extern unsigned long gfx_vid_version;
+ extern ChipType gfx_chip_revision;
+
+/* ROUTINES IN GFX_INIT.C */
+
+ unsigned long gfx_pci_config_read(unsigned long address);
+ void gfx_pci_config_write(unsigned long address, unsigned long data);
+ unsigned long gfx_get_core_freq(void);
+ unsigned long gfx_detect_cpu(void);
+ unsigned long gfx_detect_video(void);
+ unsigned long gfx_get_cpu_register_base(void);
+ unsigned long gfx_get_graphics_register_base(void);
+ unsigned long gfx_get_frame_buffer_base(void);
+ unsigned long gfx_get_frame_buffer_size(void);
+ unsigned long gfx_get_vid_register_base(void);
+ unsigned long gfx_get_vip_register_base(void);
+
+/* ROUTINES IN GFX_MSR.C */
+
+ int gfx_msr_init(void);
+ DEV_STATUS gfx_id_msr_device(MSR * pDev, unsigned long address);
+ DEV_STATUS gfx_get_msr_dev_address(unsigned int device,
+ unsigned long *address);
+ DEV_STATUS gfx_get_glink_id_at_address(unsigned int *device,
+ unsigned long address);
+ DEV_STATUS gfx_msr_read(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue);
+ DEV_STATUS gfx_msr_write(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue);
+
+/* ROUTINES IN GFX_DISP.C */
+
+ int gfx_set_display_bpp(unsigned short bpp);
+ int gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz);
+ int gfx_set_display_mode(int xres, int yres, int bpp, int hz);
+ int gfx_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblank_start,
+ unsigned short hsync_start, unsigned short hsync_end,
+ unsigned short hblank_end, unsigned short htotal,
+ unsigned short vactive, unsigned short vblank_start,
+ unsigned short vsync_start, unsigned short vsync_end,
+ unsigned short vblank_end, unsigned short vtotal,
+ unsigned long frequency);
+ int gfx_set_vtotal(unsigned short vtotal);
+ void gfx_set_display_pitch(unsigned short pitch);
+ void gfx_set_display_offset(unsigned long offset);
+ int gfx_set_display_palette_entry(unsigned long index,
+ unsigned long palette);
+ int gfx_set_display_palette(unsigned long *palette);
+ void gfx_video_shutdown(void);
+ void gfx_set_clock_frequency(unsigned long frequency);
+ int gfx_set_crt_enable(int enable);
+ void gfx_set_cursor_enable(int enable);
+ void gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor);
+ void gfx_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot);
+ void gfx_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask);
+ void gfx_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask);
+ void gfx_set_icon_enable(int enable);
+ void gfx_set_icon_colors(unsigned long color0, unsigned long color1,
+ unsigned long color2);
+ void gfx_set_icon_position(unsigned long memoffset, unsigned short xpos);
+ void gfx_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned int lines);
+
+ int gfx_set_compression_enable(int enable);
+ int gfx_set_compression_offset(unsigned long offset);
+ int gfx_set_compression_pitch(unsigned short pitch);
+ int gfx_set_compression_size(unsigned short size);
+ void gfx_set_display_priority_high(int enable);
+ int gfx_test_timing_active(void);
+ int gfx_test_vertical_active(void);
+ int gfx_wait_vertical_blank(void);
+ void gfx_delay_milliseconds(unsigned long milliseconds);
+ void gfx_delay_microseconds(unsigned long microseconds);
+ void gfx_enable_panning(int x, int y);
+ int gfx_is_panel_mode_supported(int panelResX, int panelResY,
+ unsigned short width, unsigned short height, unsigned short bpp);
+ int gfx_set_fixed_timings(int panelResX, int panelResY,
+ unsigned short width, unsigned short height, unsigned short bpp);
+ int gfx_set_panel_present(int panelResX, int panelResY,
+ unsigned short width, unsigned short height, unsigned short bpp);
+ void gfx_reset_timing_lock(void);
+
+/* "READ" ROUTINES IN GFX_DISP.C */
+
+ int gfx_get_display_details(unsigned int mode, int *xres, int *yres,
+ int *hz);
+ unsigned short gfx_get_display_pitch(void);
+ int gfx_get_vsa2_softvga_enable(void);
+ int gfx_get_sync_polarities(void);
+ unsigned long gfx_get_clock_frequency(void);
+ unsigned long gfx_get_max_supported_pixel_clock(void);
+ int gfx_mode_frequency_supported(int xres, int yres, int bpp,
+ unsigned long frequency);
+ int gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp,
+ int *hz, unsigned long frequency);
+ int gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
+ unsigned long frequency);
+ int gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp,
+ int hz, int *frequency);
+ int gfx_get_display_mode_count(void);
+ int gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz);
+ unsigned long gfx_get_frame_buffer_line_size(void);
+ unsigned short gfx_get_hactive(void);
+ unsigned short gfx_get_hblank_start(void);
+ unsigned short gfx_get_hsync_start(void);
+ unsigned short gfx_get_hsync_end(void);
+ unsigned short gfx_get_hblank_end(void);
+ unsigned short gfx_get_htotal(void);
+ unsigned short gfx_get_vactive(void);
+ unsigned short gfx_get_vline(void);
+ unsigned short gfx_get_vblank_start(void);
+ unsigned short gfx_get_vsync_start(void);
+ unsigned short gfx_get_vsync_end(void);
+ unsigned short gfx_get_vblank_end(void);
+ unsigned short gfx_get_vtotal(void);
+ unsigned short gfx_get_display_bpp(void);
+ unsigned long gfx_get_display_offset(void);
+ int gfx_get_display_palette_entry(unsigned long index,
+ unsigned long *palette);
+ void gfx_get_display_palette(unsigned long *palette);
+ unsigned long gfx_get_cursor_enable(void);
+ unsigned long gfx_get_cursor_offset(void);
+ unsigned long gfx_get_cursor_position(void);
+ unsigned long gfx_get_cursor_clip(void);
+ unsigned long gfx_get_cursor_color(int color);
+ unsigned long gfx_get_icon_enable(void);
+ unsigned long gfx_get_icon_offset(void);
+ unsigned long gfx_get_icon_position(void);
+ unsigned long gfx_get_icon_color(int color);
+ int gfx_get_compression_enable(void);
+ unsigned long gfx_get_compression_offset(void);
+ unsigned short gfx_get_compression_pitch(void);
+ unsigned short gfx_get_compression_size(void);
+ int gfx_get_display_priority_high(void);
+ int gfx_get_valid_bit(int line);
+
+/* ROUTINES IN GFX_RNDR.C */
+
+ void gfx_set_bpp(unsigned short bpp);
+ void gfx_set_solid_pattern(unsigned long color);
+ void gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparency);
+ void gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned long data2,
+ unsigned long data3, unsigned char transparency);
+ void gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8);
+ void gfx_set_solid_source(unsigned long color);
+ void gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent);
+ void gfx_set_pattern_flags(unsigned short flags);
+ void gfx_set_raster_operation(unsigned char rop);
+ void gfx_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height);
+ void gfx_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern);
+ void gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height);
+ void gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color);
+ void gfx_color_bitmap_to_screen_blt(unsigned short srcx,
+ unsigned short srcy, unsigned short dstx, unsigned short dsty,
+ unsigned short width, unsigned short height, unsigned char *data,
+ long pitch);
+ void gfx_color_bitmap_to_screen_xblt(unsigned short srcx,
+ unsigned short srcy, unsigned short dstx, unsigned short dsty,
+ unsigned short width, unsigned short height, unsigned char *data,
+ long pitch, unsigned long color);
+ void gfx_mono_bitmap_to_screen_blt(unsigned short srcx,
+ unsigned short srcy, unsigned short dstx, unsigned short dsty,
+ unsigned short width, unsigned short height, unsigned char *data,
+ short pitch);
+ void gfx_text_blt(unsigned short dstx, unsigned short dsty,
+ unsigned short width, unsigned short height, unsigned char *data);
+ void gfx_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr,
+ unsigned short flags);
+ void gfx_wait_until_idle(void);
+ int gfx_test_blt_pending(void);
+
+/* SECOND GENERATION RENDERING ROUTINES */
+
+ void gfx2_set_source_stride(unsigned short stride);
+ void gfx2_set_destination_stride(unsigned short stride);
+ void gfx2_set_pattern_origin(int x, int y);
+ void gfx2_set_source_transparency(unsigned long color,
+ unsigned long mask);
+ void gfx2_set_alpha_mode(int mode);
+ void gfx2_set_alpha_value(unsigned char value);
+ void gfx2_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height);
+ void gfx2_color_pattern_fill(unsigned long dstoffset,
+ unsigned short width, unsigned short height, unsigned long *pattern);
+ void gfx2_screen_to_screen_blt(unsigned long srcoffset,
+ unsigned long dstoffset, unsigned short width, unsigned short height,
+ int flags);
+ void gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
+ unsigned short srcy, unsigned long dstoffset, unsigned short width,
+ unsigned short height, int byte_packed);
+ void gfx2_color_bitmap_to_screen_blt(unsigned short srcx,
+ unsigned short srcy, unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch);
+ void gfx2_mono_bitmap_to_screen_blt(unsigned short srcx,
+ unsigned short srcy, unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch);
+ void gfx2_text_blt(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data);
+ void gfx2_bresenham_line(unsigned long dstoffset, unsigned short length,
+ unsigned short initerr, unsigned short axialerr,
+ unsigned short diagerr, unsigned short flags);
+ void gfx2_sync_to_vblank(void);
+
+/* ROUTINES IN GFX_VID.C */
+
+ int gfx_set_video_enable(int enable);
+ int gfx_set_video_format(unsigned long format);
+ int gfx_set_video_size(unsigned short width, unsigned short height);
+ int gfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch);
+ int gfx_set_video_offset(unsigned long offset);
+ int gfx_set_video_yuv_offsets(unsigned long yoffset,
+ unsigned long uoffset, unsigned long voffset);
+ int gfx_set_video_window(short x, short y, unsigned short w,
+ unsigned short h);
+ int gfx_set_video_left_crop(unsigned short x);
+ int gfx_set_video_upscale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+ int gfx_set_video_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+ int gfx_set_video_vertical_downscale(unsigned short srch,
+ unsigned short dsth);
+ void gfx_set_video_vertical_downscale_enable(int enable);
+ int gfx_set_video_downscale_config(unsigned short type, unsigned short m);
+ int gfx_set_video_color_key(unsigned long key, unsigned long mask,
+ int bluescreen);
+ int gfx_set_video_filter(int xfilter, int yfilter);
+ int gfx_set_video_palette(unsigned long *palette);
+ int gfx_set_graphics_palette(unsigned long *palette);
+ int gfx_set_video_palette_bypass(int enable);
+ int gfx_set_video_palette_entry(unsigned long index, unsigned long color);
+ int gfx_set_graphics_palette_entry(unsigned long index,
+ unsigned long color);
+ int gfx_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4);
+ int gfx_set_video_downscale_enable(int enable);
+ int gfx_set_video_source(VideoSourceType source);
+ int gfx_set_vbi_source(VbiSourceType source);
+ int gfx_set_vbi_lines(unsigned long even, unsigned long odd);
+ int gfx_set_vbi_total(unsigned long even, unsigned long odd);
+ int gfx_set_video_interlaced(int enable);
+ int gfx_set_color_space_YUV(int enable);
+ int gfx_set_vertical_scaler_offset(char offset);
+ int gfx_set_top_line_in_odd(int enable);
+ int gfx_set_genlock_delay(unsigned long delay);
+ int gfx_set_genlock_enable(int flags);
+ int gfx_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1,
+ unsigned long color2);
+ int gfx_set_video_cursor_enable(int enable);
+ int gfx_set_video_request(short x, short y);
+
+ int gfx_select_alpha_region(int region);
+ int gfx_set_alpha_enable(int enable);
+ int gfx_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height);
+ int gfx_set_alpha_value(unsigned char alpha, char delta);
+ int gfx_set_alpha_priority(int priority);
+ int gfx_set_alpha_color(unsigned long color);
+ int gfx_set_alpha_color_enable(int enable);
+ int gfx_set_no_ck_outside_alpha(int enable);
+ int gfx_disable_softvga(void);
+ int gfx_enable_softvga(void);
+ int gfx_set_macrovision_enable(int enable);
+ unsigned long gfx_get_max_video_width(void);
+
+/* READ ROUTINES IN GFX_VID.C */
+
+ int gfx_get_video_enable(void);
+ int gfx_get_video_format(void);
+ unsigned long gfx_get_video_src_size(void);
+ unsigned long gfx_get_video_line_size(void);
+ unsigned long gfx_get_video_xclip(void);
+ unsigned long gfx_get_video_offset(void);
+ void gfx_get_video_yuv_offsets(unsigned long *yoffset,
+ unsigned long *uoffset, unsigned long *voffset);
+ void gfx_get_video_yuv_pitch(unsigned long *ypitch,
+ unsigned long *uvpitch);
+ unsigned long gfx_get_video_upscale(void);
+ unsigned long gfx_get_video_scale(void);
+ unsigned long gfx_get_video_downscale_delta(void);
+ int gfx_get_video_vertical_downscale_enable(void);
+ int gfx_get_video_downscale_config(unsigned short *type,
+ unsigned short *m);
+ void gfx_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4);
+ void gfx_get_video_downscale_enable(int *enable);
+ unsigned long gfx_get_video_dst_size(void);
+ unsigned long gfx_get_video_position(void);
+ unsigned long gfx_get_video_color_key(void);
+ unsigned long gfx_get_video_color_key_mask(void);
+ int gfx_get_video_palette_entry(unsigned long index,
+ unsigned long *palette);
+ int gfx_get_video_color_key_src(void);
+ int gfx_get_video_filter(void);
+ int gfx_get_video_request(short *x, short *y);
+ int gfx_get_video_source(VideoSourceType * source);
+ int gfx_get_vbi_source(VbiSourceType * source);
+ unsigned long gfx_get_vbi_lines(int odd);
+ unsigned long gfx_get_vbi_total(int odd);
+ int gfx_get_video_interlaced(void);
+ int gfx_get_color_space_YUV(void);
+ int gfx_get_vertical_scaler_offset(char *offset);
+ unsigned long gfx_get_genlock_delay(void);
+ int gfx_get_genlock_enable(void);
+ int gfx_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2);
+ unsigned long gfx_read_crc(void);
+ unsigned long gfx_read_crc32(void);
+ unsigned long gfx_read_window_crc(int source, unsigned short x,
+ unsigned short y, unsigned short width, unsigned short height,
+ int crc32);
+ int gfx_get_macrovision_enable(void);
+
+ void gfx_get_alpha_enable(int *enable);
+ void gfx_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height);
+ void gfx_get_alpha_value(unsigned char *alpha, char *delta);
+ void gfx_get_alpha_priority(int *priority);
+ void gfx_get_alpha_color(unsigned long *color);
+
+/* ROUTINES IN GFX_VIP.C */
+
+ int gfx_set_vip_enable(int enable);
+ int gfx_set_vip_capture_run_mode(int mode);
+ int gfx_set_vip_base(unsigned long even, unsigned long odd);
+ int gfx_set_vip_pitch(unsigned long pitch);
+ int gfx_set_vip_mode(int mode);
+ int gfx_set_vbi_enable(int enable);
+ int gfx_set_vbi_mode(int mode);
+ int gfx_set_vbi_base(unsigned long even, unsigned long odd);
+ int gfx_set_vbi_pitch(unsigned long pitch);
+ int gfx_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines);
+ int gfx_set_vbi_interrupt(int enable);
+ int gfx_set_vip_bus_request_threshold_high(int enable);
+ int gfx_set_vip_last_line(int last_line);
+ int gfx_test_vip_odd_field(void);
+ int gfx_test_vip_bases_updated(void);
+ int gfx_test_vip_fifo_overflow(void);
+ int gfx_get_vip_line(void);
+
+/* READ ROUTINES IN GFX_VIP.C */
+
+ int gfx_get_vip_enable(void);
+ unsigned long gfx_get_vip_base(int odd);
+ unsigned long gfx_get_vip_pitch(void);
+ int gfx_get_vip_mode(void);
+ int gfx_get_vbi_enable(void);
+ int gfx_get_vbi_mode(void);
+ unsigned long gfx_get_vbi_base(int odd);
+ unsigned long gfx_get_vbi_pitch(void);
+ unsigned long gfx_get_vbi_direct(int odd);
+ int gfx_get_vbi_interrupt(void);
+ int gfx_get_vip_bus_request_threshold_high(void);
+
+/* ROUTINES IN GFX_DCDR.C */
+
+ int gfx_set_decoder_defaults(void);
+ int gfx_set_decoder_analog_input(unsigned char input);
+ int gfx_set_decoder_brightness(unsigned char brightness);
+ int gfx_set_decoder_contrast(unsigned char contrast);
+ int gfx_set_decoder_hue(char hue);
+ int gfx_set_decoder_saturation(unsigned char saturation);
+ int gfx_set_decoder_input_offset(unsigned short x, unsigned short y);
+ int gfx_set_decoder_input_size(unsigned short width,
+ unsigned short height);
+ int gfx_set_decoder_output_size(unsigned short width,
+ unsigned short height);
+ int gfx_set_decoder_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth);
+ int gfx_set_decoder_vbi_format(int start, int end, int format);
+ int gfx_set_decoder_vbi_enable(int enable);
+ int gfx_set_decoder_vbi_upscale(void);
+ int gfx_set_decoder_TV_standard(TVStandardType TVStandard);
+ int gfx_set_decoder_luminance_filter(unsigned char lufi);
+ int gfx_decoder_software_reset(void);
+ int gfx_decoder_detect_macrovision(void);
+ int gfx_decoder_detect_video(void);
+
+/* READ ROUTINES IN GFX_DCDR.C */
+
+ unsigned char gfx_get_decoder_brightness(void);
+ unsigned char gfx_get_decoder_contrast(void);
+ char gfx_get_decoder_hue(void);
+ unsigned char gfx_get_decoder_saturation(void);
+ unsigned long gfx_get_decoder_input_offset(void);
+ unsigned long gfx_get_decoder_input_size(void);
+ unsigned long gfx_get_decoder_output_size(void);
+ int gfx_get_decoder_vbi_format(int line);
+
+/* ROUTINES IN GFX_I2C.C */
+
+ int gfx_i2c_reset(unsigned char busnum, short adr, char freq);
+ int gfx_i2c_write(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data);
+ int gfx_i2c_read(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data);
+ int gfx_i2c_select_gpio(int clock, int data);
+ int gfx_i2c_init(void);
+ void gfx_i2c_cleanup(void);
+
+/* ROUTINES IN GFX_TV.C */
+
+ int gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution);
+ int gfx_set_tv_output(int output);
+ int gfx_set_tv_enable(int enable);
+ int gfx_set_tv_flicker_filter(int ff);
+ int gfx_set_tv_sub_carrier_reset(int screset);
+ int gfx_set_tv_vphase(int vphase);
+ int gfx_set_tv_YC_delay(int delay);
+ int gfx_set_tvenc_reset_interval(int interval);
+ int gfx_set_tv_cc_enable(int enable);
+ int gfx_set_tv_cc_data(unsigned char data1, unsigned char data2);
+ int gfx_set_tv_display(int width, int height);
+ int gfx_test_tvout_odd_field(void);
+ int gfx_test_tvenc_odd_field(void);
+ int gfx_set_tv_field_status_invert(int enable);
+ int gfx_get_tv_vphase(void);
+ int gfx_get_tv_enable(unsigned int *p_on);
+ int gfx_get_tv_output(void);
+ int gfx_get_tv_mode_count(TVStandardType format);
+ int gfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz);
+ int gfx_get_tv_display_mode_frequency(unsigned short width,
+ unsigned short height, TVStandardType format, int *frequency);
+ int gfx_is_tv_display_mode_supported(unsigned short width,
+ unsigned short height, TVStandardType format);
+
+ int gfx_get_tv_standard(unsigned long *p_standard);
+ int gfx_get_available_tv_standards(unsigned long *p_standards);
+ int gfx_set_tv_standard(unsigned long standard);
+ int gfx_get_tv_vga_mode(unsigned long *p_vga_mode);
+ int gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes);
+ int gfx_set_tv_vga_mode(unsigned long vga_mode);
+ int gfx_get_tvout_mode(unsigned long *p_tvout_mode);
+ int gfx_set_tvout_mode(unsigned long tvout_mode);
+ int gfx_get_sharpness(int *p_sharpness);
+ int gfx_set_sharpness(int sharpness);
+ int gfx_get_flicker_filter(int *p_flicker);
+ int gfx_set_flicker_filter(int flicker);
+ int gfx_get_overscan(int *p_x, int *p_y);
+ int gfx_set_overscan(int x, int y);
+ int gfx_get_position(int *p_x, int *p_y);
+ int gfx_set_position(int x, int y);
+ int gfx_get_color(int *p_color);
+ int gfx_set_color(int color);
+ int gfx_get_brightness(int *p_brightness);
+ int gfx_set_brightness(int brightness);
+ int gfx_get_contrast(int *p_contrast);
+ int gfx_set_contrast(int constrast);
+ int gfx_get_yc_filter(unsigned int *p_yc_filter);
+ int gfx_set_yc_filter(unsigned int yc_filter);
+ int gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits);
+ int gfx_set_aps_trigger_bits(unsigned int trigger_bits);
+
+/* ROUTINES IN GFX_VGA.C */
+
+ int gfx_get_softvga_active(void);
+ int gfx_vga_test_pci(void);
+ unsigned char gfx_vga_get_pci_command(void);
+ int gfx_vga_set_pci_command(unsigned char command);
+ int gfx_vga_seq_reset(int reset);
+ int gfx_vga_set_graphics_bits(void);
+ int gfx_vga_mode(gfx_vga_struct * vga, int xres, int yres, int bpp,
+ int hz);
+ int gfx_vga_pitch(gfx_vga_struct * vga, unsigned short pitch);
+ int gfx_vga_save(gfx_vga_struct * vga, int flags);
+ int gfx_vga_restore(gfx_vga_struct * vga, int flags);
+ int gfx_vga_mode_switch(int active);
+ void gfx_vga_clear_extended(void);
+
+/* CLOSE BRACKET FOR C++ COMPLILATION */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_gfx_rtns_h */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_tv.c b/src/gfx/gfx_tv.c
new file mode 100644
index 0000000..fb34d60
--- /dev/null
+++ b/src/gfx/gfx_tv.c
@@ -0,0 +1,836 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to program TVOUT and TV encoder.
+ *
+ * Routines:
+ *
+ * gfx_set_tv_format
+ * gfx_set_tv_output
+ * gfx_set_tv_enable
+ * gfx_set_tv_flicker_filter
+ * gfx_set_tv_sub_carrier_reset
+ * gfx_set_tv_vphase
+ * gfx_set_tv_YC_delay
+ * gfx_set_tvenc_reset_interval
+ * gfx_set_tv_cc_enable
+ * gfx_set_tv_cc_data
+ * gfx_test_tvout_odd_field
+ * gfx_test_tvenc_odd_field
+ * gfx_set_tv_field_status_invert
+ * gfx_get_tv_vphase
+ * */
+
+/* TV TIMINGS */
+
+DISPLAYMODE TVTimings[] = {
+
+/* NTSC resolution */
+
+ {0x3 | /* negative syncs */
+ GFX_MODE_TV_NTSC, /* NTSC format */
+ 640, 640, 656, 744, 792, 792, /* horizontal timings */
+ 480, 480, 490, 492, 517, 525, /* vertical timings */
+ 0x0018EC4D, /* freq = 24.923052 MHz */
+ }
+ ,
+
+/* PAL resolution */
+
+ {0x3 | /* negative syncs */
+ GFX_MODE_TV_PAL, /* PAL format */
+ 768, 768, 800, 848, 864, 864, /* horizontal timings */
+ 576, 576, 586, 588, 625, 625, /* vertical timings */
+ 0x001B0000, /* freq = 27.00 MHz */
+ }
+ ,
+
+/* NTSC resolution non-square pixels */
+
+ {0x3 | /* negative syncs */
+ GFX_MODE_TV_NTSC, /* NTSC format */
+ 720, 720, 736, 752, 792, 792, /* horizontal timings */
+ 480, 480, 490, 492, 517, 525, /* vertical timings */
+ 0x0018EC4D, /* freq = 24.923052 MHz */
+ }
+ ,
+
+/* PAL resolution non-square pixels */
+
+ {0x3 | /* negative syncs */
+ GFX_MODE_TV_PAL, /* PAL format */
+ 720, 720, 752, 816, 864, 864, /* horizontal timings */
+ 576, 576, 586, 588, 625, 625, /* vertical timings */
+ 0x001B0000, /* freq = 27.00 MHz */
+ }
+};
+
+#define NUM_TV_MODES sizeof(TVTimings)/sizeof(DISPLAYMODE)
+
+/* INCLUDE SUPPORT FOR SC1200 TV ENCODER, IF SPECIFIED */
+
+#if GFX_TV_SC1200
+#include "tv_1200.c"
+#endif
+
+/* INCLUDE SUPPORT FOR FS450 TV ENCODER, IF SPECIFIED */
+
+#if GFX_TV_FS451
+#include "tv_fs450.c"
+#endif
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either SC1200 or FS450 TV encoder routines. */
+
+#if GFX_TV_DYNAMIC
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_format
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_format(format, resolution);
+#endif
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_tv_format(format, resolution);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_output
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_output(int output)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_output(output);
+#endif
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_tv_output(output);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_enable(int enable)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_enable(enable);
+#endif
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_tv_enable(enable);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_flicker_filter
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_flicker_filter(int ff)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_flicker_filter(ff);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_sub_carrier_reset
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_sub_carrier_reset(int screset)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_sub_carrier_reset(screset);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_vphase
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_vphase(int vphase)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_vphase(vphase);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_YC_delay
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_YC_delay(int delay)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_YC_delay(delay);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tvenc_reset_interval
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tvenc_reset_interval(int interval)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tvenc_reset_interval(interval);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_cc_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_cc_enable(int enable)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_cc_enable(enable);
+#endif
+ return (retval);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_cc_data
+ *
+ * This routine writes the two specified characters to the CC data register
+ * of the TV encoder.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_cc_data(unsigned char data1, unsigned char data2)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_cc_data(data1, data2);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_tv_display
+ *
+ * Set the timings in the display controller to support a TV resolution.
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_display(int width, int height)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ status = sc1200_set_tv_display(width, height);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_tvout_odd_field
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_test_tvout_odd_field(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ status = sc1200_test_tvout_odd_field();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_tvenc_odd_field
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_test_tvenc_odd_field(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ status = sc1200_test_tvenc_odd_field();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_field_status_invert
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_tv_field_status_invert(int enable)
+{
+ int retval = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_set_tv_field_status_invert(enable);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_vphase
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_tv_vphase(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ status = sc1200_get_tv_vphase();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_tv_enable(unsigned int *p_on)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_tv_enable(p_on);
+#endif
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_get_tv_enable(p_on);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_output
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_tv_output()
+{
+ int retval = -1;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_get_tv_output();
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_mode_count
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_tv_mode_count(TVStandardType format)
+{
+ int retval = -1;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_get_tv_mode_count(format);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_display_mode
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz)
+{
+ int retval = -1;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_get_tv_display_mode(width, height, bpp, hz);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_display_mode_frequency
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_tv_display_mode_frequency(unsigned short width, unsigned short height,
+ TVStandardType format, int *frequency)
+{
+ int retval = -1;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval =
+ sc1200_get_tv_display_mode_frequency(width, height, format,
+ frequency);
+#endif
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_is_tv_display_mode_supported
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_is_tv_display_mode_supported(unsigned short width, unsigned short height,
+ TVStandardType format)
+{
+ int retval = -1;
+
+#if GFX_TV_SC1200
+ if (gfx_tv_type & GFX_TV_TYPE_SC1200)
+ retval = sc1200_is_tv_display_mode_supported(width, height, format);
+#endif
+ return (retval);
+}
+
+/*------------------------------------------
+ * The following functions were added to support
+ * the FS450 and will eventually be removed. There
+ * is no equivalent support in the SC1200.
+ *----------------------------------------------*/
+
+/*==========================================================================
+ * TV standard
+ *==========================================================================
+ */
+int
+gfx_get_tv_standard(unsigned long *p_standard)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_tv_standard(p_standard);
+#endif
+ return (retval);
+}
+
+int
+gfx_get_available_tv_standards(unsigned long *p_standards)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_available_tv_standards(p_standards);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_tv_standard(unsigned long standard)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_tv_standard(standard);
+#endif
+ return (retval);
+}
+
+/*
+ *==========================================================================
+ * vga mode as known by the driver
+ *==========================================================================
+ */
+int
+gfx_get_tv_vga_mode(unsigned long *p_vga_mode)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_tv_vga_mode(p_vga_mode);
+#endif
+ return (retval);
+}
+
+int
+gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_available_tv_vga_modes(p_vga_modes);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_tv_vga_mode(unsigned long vga_mode)
+{
+ int re tval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_tv_vga_mode(vga_mode);
+#endif
+ return (retval);
+}
+
+/*
+ *==========================================================================
+ *
+ * tvout mode
+ */
+
+int
+gfx_get_tvout_mode(unsigned long *p_tvout_mode)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_tvout_mode(p_tvout_mode);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_tvout_mode(unsigned long tvout_mode)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_tvout_mode(tvout_mode);
+#endif
+ return (retval);
+}
+
+/*
+ *==========================================================================
+ *
+ * Sharpness
+ */
+int
+gfx_get_sharpness(int *p_sharpness)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_sharpness(p_sharpness);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_sharpness(int sharpness)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_sharpness(sharpness);
+#endif
+ return (retval);
+}
+
+/*
+ *==========================================================================
+ *
+ * flicker filter control.
+ */
+
+int
+gfx_get_flicker_filter(int *p_flicker)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_flicker_filter(p_flicker);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_flicker_filter(int flicker)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_flicker_filter(flicker);
+#endif
+ return (retval);
+}
+
+/*
+ *==========================================================================
+ *
+ * Overscan and Position
+ */
+
+int
+gfx_get_overscan(int *p_x, int *p_y)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_overscan(p_x, p_y);
+#endif
+ return (retval);
+
+}
+
+int
+gfx_set_overscan(int x, int y)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_overscan(x, y);
+#endif
+ return (retval);
+}
+
+int
+gfx_get_position(int *p_x, int *p_y)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_position(p_x, p_y);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_position(int x, int y)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_position(x, y);
+#endif
+ return (retval);
+}
+
+/*
+ *==========================================================================
+ *
+ * Color, Brightness, and Contrast
+ */
+
+int
+gfx_get_color(int *p_color)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_color(p_color);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_color(int color)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_color(color);
+#endif
+ return (retval);
+}
+
+int
+gfx_get_brightness(int *p_brightness)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_brightness(p_brightness);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_brightness(int brightness)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_brightness(brightness);
+#endif
+ return (retval);
+}
+
+int
+gfx_get_contrast(int *p_contrast)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_contrast(p_contrast);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_contrast(int contrast)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_contrast(contrast);
+#endif
+ return (retval);
+}
+
+/*
+ *==========================================================================
+ *
+ * YC filters
+ */
+
+int
+gfx_get_yc_filter(unsigned int *p_yc_filter)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_yc_filter(p_yc_filter);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_yc_filter(unsigned int yc_filter)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_yc_filter(yc_filter);
+#endif
+ return (retval);
+}
+
+int
+gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_get_aps_trigger_bits(p_trigger_bits);
+#endif
+ return (retval);
+}
+
+int
+gfx_set_aps_trigger_bits(unsigned int trigger_bits)
+{
+ int retval = -1;
+
+#if GFX_TV_FS451
+ if (gfx_tv_type & GFX_TV_TYPE_FS451)
+ retval = fs450_set_aps_trigger_bits(trigger_bits);
+#endif
+ return (retval);
+}
+
+#endif /* GFX_TV_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_type.h b/src/gfx/gfx_type.h
new file mode 100644
index 0000000..fbedd62
--- /dev/null
+++ b/src/gfx/gfx_type.h
@@ -0,0 +1,331 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This header file defines the pneumonics used when calling Durango routines.
+ * This file is automatically included by gfx_rtns.h
+ * */
+
+#ifndef _gfx_type_h
+#define _gfx_type_h
+
+/* MSR DEFINITIONS */
+
+typedef enum DevStatus
+{ FOUND, NOT_KNOWN, REQ_NOT_FOUND, REQ_NOT_INSTALLED } DEV_STATUS;
+
+typedef struct msr
+{
+ DEV_STATUS Present; /* Node enumeration status */
+ unsigned char Id; /* Device ID (from MSR specs) */
+ unsigned long Address; /* Address - 32-bit MBus address at */
+ /* which 'Id' is found */
+} MSR;
+
+typedef struct mValue
+{
+ unsigned long high;
+ unsigned long low;
+} Q_WORD;
+
+typedef struct mbusNode
+{
+ unsigned long address;
+ unsigned int deviceId;
+ unsigned int claimed;
+} MBUS_NODE;
+
+/* MSR ARRAY INDEXES */
+/* These are indexes into the array of MBus devices. These */
+/* should not be confused with the class codes at MSR register */
+/* 0x2000. */
+
+#define RC_ID_MBIU0 0x00
+#define RC_ID_MBIU1 0x01
+#define RC_ID_MCP 0x02
+#define RC_ID_MPCI 0x03
+#define RC_ID_MC 0x04
+#define RC_ID_GP 0x05
+#define RC_ID_VG 0x06
+#define RC_ID_DF 0x07
+#define RC_ID_FG 0x08
+#define RC_ID_VA 0x09
+#define CP_ID_MBIU 0x0A
+#define CP_ID_MPCI 0x0B
+#define CP_ID_USB2 0x0C
+#define CP_ID_ATAC 0x0D
+#define CP_ID_MDD 0x0E
+#define CP_ID_ACC 0x0F
+#define CP_ID_USB1 0x10
+#define CP_ID_MCP 0x11
+
+/* MBUS DEVICE CLASS CODES */
+/* These are the device ids for the known Redcloud MBus devices. */
+
+#define RC_CC_MBIU 0x01
+#define RC_CC_MCP 0x02
+#define RC_CC_MPCI 0x05
+#define RC_CC_MC 0x20
+#define RC_CC_GP 0x3D
+#define RC_CC_VG 0x3E
+#define RC_CC_DF 0x3F
+#define RC_CC_FG 0xF0
+#define RC_CC_VA 0x86
+#define CP_CC_MBIU 0x01
+#define CP_CC_MPCI 0x05
+#define CP_CC_USB2 0x42
+#define CP_CC_ATAC 0x47
+#define CP_CC_MDD 0xDF
+#define CP_CC_ACC 0x33
+#define CP_CC_USB1 0x42
+#define CP_CC_MCP 0x02
+
+/* VAIL AND MBIUS ARE AT KNOWN ADDRESSES */
+/* We can initialize the addresses of these devices in advance, */
+/* as their location should never change. */
+
+#define RC_MB0_MBIU0 0x10000000
+#define RC_MB0_MBIU1 0x40000000
+#define CP_MB0_MBIU0 0x51010000
+#define RC_MB0_CPU 0x00000000
+#define FAKE_ADDRESS 0xFFFFFFFF
+
+/* MSR PORT DESCRIPTORS */
+
+#define NOT_POPULATED 0
+#define NOT_INSTALLED 0xFFFE
+#define REFLECTIVE 0xFFFF
+
+/* CRC DATA SOURCES */
+
+#define CRC_SOURCE_GFX_DATA 0x00
+#define CRC_SOURCE_CRT_RGB 0x01
+#define CRC_SOURCE_FP_DATA 0x02
+
+/* TV DEFINITIONS */
+
+typedef enum TVStandardType
+{
+ TV_STANDARD_NTSC = 1,
+ TV_STANDARD_PAL
+} TVStandardType;
+
+typedef enum GfxOnTVType
+{
+ GFX_ON_TV_SQUARE_PIXELS = 1,
+ GFX_ON_TV_NO_SCALING
+} GfxOnTVType;
+
+#define CRT_DISABLE 0x00
+#define CRT_ENABLE 0x01
+#define CRT_STANDBY 0x02
+#define CRT_SUSPEND 0x03
+
+#define TV_OUTPUT_COMPOSITE 0x01
+#define TV_OUTPUT_S_VIDEO 0x02
+#define TV_OUTPUT_YUV 0x03
+#define TV_OUTPUT_SCART 0x04
+
+#define TV_FLICKER_FILTER_NONE 0x01
+#define TV_FLICKER_FILTER_NORMAL 0x02
+#define TV_FLICKER_FILTER_INTERLACED 0x03
+
+#define TV_YC_DELAY_NONE 0x01
+#define TV_Y_DELAY_ONE_PIXEL 0x02
+#define TV_C_DELAY_ONE_PIXEL 0x03
+#define TV_C_DELAY_TWO_PIXELS 0x04
+
+#define TV_SUB_CARRIER_RESET_NEVER 0x01
+#define TV_SUB_CARRIER_RESET_EVERY_TWO_LINES 0x02
+#define TV_SUB_CARRIER_RESET_EVERY_TWO_FRAMES 0x03
+#define TV_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES 0x04
+
+#define TVENC_RESET_EVERY_ODD_FIELD 0x01
+#define TVENC_RESET_EVERY_EVEN_FIELD 0x02
+#define TVENC_RESET_NEXT_ODD_FIELD 0x03
+#define TVENC_RESET_NEXT_EVEN_FIELD 0x04
+#define TVENC_RESET_EVERY_FIELD 0x05
+#define TVENC_RESET_EVERY_X_ODD_FIELDS 0x06
+#define TVENC_RESET_EVERY_X_EVEN_FIELDS 0x07
+
+/* VBI FORMATS */
+
+#define VBI_FORMAT_VIDEO 0x1
+#define VBI_FORMAT_RAW 0x2
+#define VBI_FORMAT_CC 0x4
+#define VBI_FORMAT_NABTS 0x8
+
+/* VIDEO DEFINITIONS */
+
+#define VIDEO_FORMAT_UYVY 0x0
+#define VIDEO_FORMAT_Y2YU 0x1
+#define VIDEO_FORMAT_YUYV 0x2
+#define VIDEO_FORMAT_YVYU 0x3
+#define VIDEO_FORMAT_Y0Y1Y2Y3 0x4
+#define VIDEO_FORMAT_Y3Y2Y1Y0 0x5
+#define VIDEO_FORMAT_Y1Y0Y3Y2 0x6
+#define VIDEO_FORMAT_Y1Y2Y3Y0 0x7
+#define VIDEO_FORMAT_RGB 0x8
+#define VIDEO_FORMAT_P2M_P2L_P1M_P1L 0x9
+#define VIDEO_FORMAT_P1M_P1L_P2M_P2L 0xA
+#define VIDEO_FORMAT_P1M_P2L_P2M_P1L 0xB
+
+#define VIDEO_DOWNSCALE_KEEP_1_OF 0x1
+#define VIDEO_DOWNSCALE_DROP_1_OF 0x2
+
+typedef enum VideoSourceType
+{ /* The source from which the video processor shows full screen video */
+ VIDEO_SOURCE_MEMORY = 1,
+ VIDEO_SOURCE_DVIP
+} VideoSourceType;
+
+typedef enum VbiSourceType
+{ /* The source from which the video processor takes VBI */
+ VBI_SOURCE_MEMORY = 1,
+ VBI_SOURCE_DVIP
+} VbiSourceType;
+
+/* GENLOCK DEFINITIONS */
+
+#define GENLOCK_SINGLE 0x001
+#define GENLOCK_FIELD_SYNC 0x001
+#define GENLOCK_CONTINUOUS 0x002
+#define GENLOCK_SYNCED_EDGE_FALLING 0x004
+#define GENLOCK_SYNCING_EDGE_FALLING 0x008
+#define GENLOCK_TIMEOUT 0x010
+#define GENLOCK_TVENC_RESET_EVEN_FIELD 0x020
+#define GENLOCK_TVENC_RESET_BEFORE_DELAY 0x040
+#define GENLOCK_TVENC_RESET 0x080
+#define GENLOCK_SYNC_TO_TVENC 0x100
+
+/* VIP DEFINITIONS */
+
+#define VIP_MODE_C 0x1
+
+#define VIP_CAPTURE_STOP_LINE 0x1
+#define VIP_CAPTURE_STOP_FIELD 0x2
+#define VIP_CAPTURE_START_FIELD 0x4
+
+#define VBI_ANCILLARY 0x1
+#define VBI_TASK_A 0x2
+#define VBI_TASK_B 0x4
+
+/* VGA STRUCTURE */
+
+#define GFX_STD_CRTC_REGS 25
+#define GFX_EXT_CRTC_REGS 16
+
+#define GFX_VGA_FLAG_MISC_OUTPUT 0x00000001
+#define GFX_VGA_FLAG_STD_CRTC 0x00000002
+#define GFX_VGA_FLAG_EXT_CRTC 0x00000004
+
+/* FS450 TV Standard flags */
+
+#define GFX_TV_STANDARD_NTSC_M 0x0001
+#define GFX_TV_STANDARD_NTSC_M_J 0x0002
+#define GFX_TV_STANDARD_PAL_B 0x0004
+#define GFX_TV_STANDARD_PAL_D 0x0008
+#define GFX_TV_STANDARD_PAL_H 0x0010
+#define GFX_TV_STANDARD_PAL_I 0x0020
+#define GFX_TV_STANDARD_PAL_M 0x0040
+#define GFX_TV_STANDARD_PAL_N 0x0080
+#define GFX_TV_STANDARD_PAL_G 0x0100
+
+/* FS450 VGA Mode flags */
+
+#define GFX_VGA_MODE_UNKNOWN 0
+#define GFX_VGA_MODE_640X480 0x0001
+#define GFX_VGA_MODE_720X487 0x0002
+#define GFX_VGA_MODE_720X576 0x0004
+#define GFX_VGA_MODE_800X600 0x0008
+#define GFX_VGA_MODE_1024X768 0x0010
+
+/* FS450 TVout mode flags */
+
+#define GFX_TVOUT_MODE_CVBS 0x0001
+#define GFX_TVOUT_MODE_YC 0x0002
+#define GFX_TVOUT_MODE_RGB 0x0004
+#define GFX_TVOUT_MODE_CVBS_YC (GFX_TVOUT_MODE_CVBS | GFX_TVOUT_MODE_YC)
+
+/* FS450 Luma and Chroma Filters */
+
+#define GFX_LUMA_FILTER 0x0001
+#define GFX_CHROMA_FILTER 0x0002
+
+/* APS Trigger Bits */
+
+#define GFX_APS_TRIGGER_OFF 0
+#define GFX_APS_TRIGGER_AGC_ONLY 1
+#define GFX_APS_TRIGGER_AGC_2_LINE 2
+#define GFX_APS_TRIGGER_AGC_4_LINE 3
+
+typedef struct
+{
+ int xsize;
+ int ysize;
+ int hz;
+ int clock;
+ unsigned char miscOutput;
+ unsigned char stdCRTCregs[GFX_STD_CRTC_REGS];
+ unsigned char extCRTCregs[GFX_EXT_CRTC_REGS];
+} gfx_vga_struct;
+
+/* POSSIBLE STATUS VALUES */
+
+#define GFX_STATUS_UNSUPPORTED (-3)
+#define GFX_STATUS_BAD_PARAMETER (-2)
+#define GFX_STATUS_ERROR (-1)
+#define GFX_STATUS_OK 0
+
+/* CPU AND VIDEO TYPES */
+
+#define GFX_CPU_GXLV 1
+#define GFX_CPU_SC1200 2
+#define GFX_CPU_REDCLOUD 3
+#define GFX_CPU_CASTLE 4
+#define GFX_CPU_PYRAMID 0x20801
+
+#define GFX_VID_CS5530 1
+#define GFX_VID_SC1200 2
+#define GFX_VID_REDCLOUD 3
+#define GFX_VID_CASTLE 4
+
+/* CHIP NAME AND REVISION */
+
+typedef enum ChipType
+{
+ CHIP_NOT_DETECTED,
+ SC1200_REV_A,
+ SC1200_REV_B1_B2,
+ SC1200_REV_B3,
+ SC1200_REV_C1,
+ SC1200_REV_D1,
+ SC1200_REV_D1_1,
+ SC1200_REV_D2_MVD, /* Macrovision disabled */
+ SC1200_REV_D2_MVE, /* Macrovision enabled */
+ SC1200_FUTURE_REV
+} ChipType;
+
+#endif /* !_gfx_type_h */
diff --git a/src/gfx/gfx_vga.c b/src/gfx/gfx_vga.c
new file mode 100644
index 0000000..8ab9b6a
--- /dev/null
+++ b/src/gfx/gfx_vga.c
@@ -0,0 +1,45 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to interface to the VGA registers. Some
+ * operating systems require mode sets be done through VGA, rather than
+ * directly using the "gfx_set_display_mode" routine.
+ * */
+
+/* INCLUDE SUPPORT FOR FIRST GENERATION, IF SPECIFIED. */
+
+#if GFX_VGA_GU1
+#include "vga_gu1.c"
+#endif
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either first or second generation routines. */
+
+#if GFX_VGA_DYNAMIC
+
+#endif /* GFX_DISPLAY_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_vid.c b/src/gfx/gfx_vid.c
new file mode 100644
index 0000000..ec1acbc
--- /dev/null
+++ b/src/gfx/gfx_vid.c
@@ -0,0 +1,2319 @@
+/* <LIC_AMD_STD>
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ * </LIC_AMD_STD> */
+/* <CTL_AMD_STD>
+ * </CTL_AMD_STD> */
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the video overlay window.
+ *
+ * Video overlay routines:
+ *
+ * gfx_set_clock_frequency
+ * gfx_set_crt_enable
+ * gfx_set_video_enable
+ * gfx_set_video_format
+ * gfx_set_video_size
+ * gfx_set_video_offset
+ * gfx_set_video_yuv_offsets
+ * gfx_set_video_yuv_pitch
+ * gfx_set_video_scale
+ * gfx_set_video_upscale
+ * gfx_set_video_downscale_config
+ * gfx_set_video_downscale_coefficients
+ * gfx_set_video_downscale_enable
+ * gfx_set_video_vertical_downscale
+ * gfx_set_video_vertical_downscale_enable
+ * gfx_set_video_window
+ * gfx_set_video_left_crop
+ * gfx_set_video_color_key
+ * gfx_set_video_filter
+ * gfx_set_video_palette
+ * gfx_set_video_request
+ * gfx_set_video_source
+ * gfx_set_vbi_source
+ * gfx_set_vbi_lines
+ * gfx_set_vbi_total
+ * gfx_set_video_interlaced
+ * gfx_set_color_space_YUV
+ * gfx_set_vertical_scaler_offset
+ * gfx_set_top_line_in_odd
+ * gfx_set_genlock_delay
+ * gfx_set_genlock_enable
+ * gfx_set_video_cursor
+ * gfx_set_video_cursor_enable
+ *
+ * Alpha blending routines (SC1200 ONLY):
+ *
+ * gfx_select_alpha_region
+ * gfx_set_alpha_enable
+ * gfx_set_alpha_window
+ * gfx_set_alpha_value
+ * gfx_set_alpha_priority
+ * gfx_set_alpha_color
+ * gfx_set_alpha_color_enable
+ * gfx_set_no_ck_outside_alpha
+ * gfx_test_tvout_odd_field
+ *
+ * And the following routines if GFX_READ_ROUTINES is set:
+ *
+ * gfx_get_sync_polarities
+ * gfx_get_video_enable
+ * gfx_get_video_format
+ * gfx_get_video_src_size
+ * gfx_get_video_line_size
+ * gfx_get_video_xclip
+ * gfx_get_video_offset
+ * gfx_get_video_yuv_offsets
+ * gfx_get_video_yuv_pitch
+ * gfx_get_video_scale
+ * gfx_get_video_upscale
+ * gfx_get_video_downscale_config
+ * gfx_get_video_downscale_coefficients
+ * gfx_get_video_downscale_enable
+ * gfx_get_video_downscale_delta
+ * gfx_get_video_vertical_downscale_enable
+ * gfx_get_video_dst_size
+ * gfx_get_video_position
+ * gfx_get_video_color_key
+ * gfx_get_video_color_key_mask
+ * gfx_get_video_color_key_src
+ * gfx_get_video_filter
+ * gfx_get_video_request
+ * gfx_get_video_source
+ * gfx_get_vbi_source
+ * gfx_get_vbi_lines
+ * gfx_get_vbi_total
+ * gfx_get_video_interlaced
+ * gfx_get_color_space_YUV
+ * gfx_get_vertical_scaler_offset
+ * gfx_get_genlock_delay
+ * gfx_get_genlock_enable
+ * gfx_get_video_cursor
+ * gfx_get_clock_frequency
+ * gfx_read_crc
+ *
+ * Alpha blending read routines (SC1200 ONLY):
+ *
+ * gfx_get_alpha_enable
+ * gfx_get_alpha_size
+ * gfx_get_alpha_value
+ * gfx_get_alpha_priority
+ * gfx_get_alpha_color
+ * */
+
+/* STATIC VARIABLES FOR VIDEO OVERLAY CONTROL */
+/* These are saved to allow these routines to do clipping. */
+
+unsigned long gfx_vid_offset = 0; /* copy from last gfx_set_video_offset */
+unsigned long gfx_vid_uoffset = 0; /* copy from last
+ * gfx_set_video_yuv_offsets */
+unsigned long gfx_vid_voffset = 0; /* copy from last
+ * gfx_set_video_yuv_offsets */
+unsigned long gfx_vid_srcw = 300; /* copy from last gfx_set_video_scale */
+unsigned long gfx_vid_srch = 300; /* copy from last gfx_set_video_scale */
+unsigned long gfx_vid_dstw = 300; /* copy from last gfx_set_video_scale */
+unsigned long gfx_vid_dsth = 300; /* copy from last gfx_set_video_scale */
+short gfx_vid_xpos = 0; /* copy from last gfx_set_video_window */
+short gfx_vid_ypos = 0; /* copy from last gfx_set_video_window */
+unsigned short gfx_vid_width = 0; /* copy from last gfx_set_video_window */
+unsigned short gfx_vid_height = 0; /* copy from last gfx_set_video_window */
+
+int gfx_alpha_select = 0; /* currently selected alpha region */
+
+int gfx_set_screen_enable(int enable); /* forward declaration */
+
+/* INCLUDE SUPPORT FOR CS5530, IF SPECIFIED. */
+
+#if GFX_VIDEO_CS5530
+#include "vid_5530.c"
+#endif
+
+/* INCLUDE SUPPORT FOR SC1200, IF SPECIFIED. */
+
+#if GFX_VIDEO_SC1200
+#include "vid_1200.c"
+#endif
+
+/* INLUDE SUPPORT FOR REDCLOUD, IF SPECIFIED. */
+
+#if GFX_VIDEO_REDCLOUD
+#include "vid_rdcl.c"
+#endif
+
+/* INLUDE SUPPORT FOR CASTLE, IF SPECIFIED. */
+
+#if GFX_VIDEO_CASTLE
+#include "vid_cstl.c"
+#endif
+
+/*---------------------------------------------------------------------------
+ * gfx_select_alpha_region
+ *
+ * This routine selects which alpha region should be used for future
+ * updates. The SC1200, for example, has 3 alpha windows available,
+ * so valid parameter values are 0..2.
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_select_alpha_region(int region)
+{
+ if (region > 2)
+ return (GFX_STATUS_BAD_PARAMETER);
+
+ gfx_alpha_select = region;
+ return (GFX_STATUS_OK);
+}
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either CS5530 or SC1200 routines. */
+
+#if GFX_VIDEO_DYNAMIC
+
+/*---------------------------------------------------------------------------
+ * 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.
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_reset_video(void)
+{
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ cs5530_reset_video();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_reset_video();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_reset_video();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_reset_video();
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
+ *
+ * This routine is used to configure the display output during a modeset
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_display_control(int sync_polarities)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_display_control(sync_polarities);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_display_control(sync_polarities);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_display_control(sync_polarities);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_display_control(sync_polarities);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_clock_frequency
+ *----------------------------------------------------------------------------
+ */
+void
+gfx_set_clock_frequency(unsigned long frequency)
+{
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ cs5530_set_clock_frequency(frequency);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_set_clock_frequency(frequency);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_set_clock_frequency(frequency);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_set_clock_frequency(frequency);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_crt_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_crt_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_crt_enable(enable);
+#endif
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_crt_enable(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_crt_enable(enable);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_crt_enable(enable);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_video_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_enable(enable);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_enable(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_enable(enable);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_enable(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_screen_enable (PRIVATE ROUTINE: NOT PART OF DURANGO API)
+ *
+ * This routine enables or disables the graphics display logic of the video
+ * processor.
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_screen_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_screen_enable(enable);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_format
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_video_format(unsigned long format)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_format(format);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_format(format);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_format(format);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_format(format);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_size
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_video_size(unsigned short width, unsigned short height)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_size(width, height);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_size(width, height);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_size(width, height);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_size(width, height);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_yuv_pitch
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_yuv_pitch(ypitch, uvpitch);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_yuv_pitch(ypitch, uvpitch);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_offset
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_video_offset(unsigned long offset)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_offset(offset);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_offset(offset);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_offset(offset);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_offset(offset);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_yuv_offsets
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
+ unsigned long voffset)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_scale
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_scale(srcw, srch, dstw, dsth);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_scale(srcw, srch, dstw, dsth);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_scale(srcw, srch, dstw, dsth);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_scale(srcw, srch, dstw, dsth);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_upscale
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_upscale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_upscale(srcw, srch, dstw, dsth);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_vertical_downscale
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_vertical_downscale(unsigned short srch, unsigned short dsth)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_vertical_downscale(srch, dsth);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_vertical_downscale_enable
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_set_video_vertical_downscale_enable(int enable)
+{
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_set_video_vertical_downscale_enable(enable);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_config
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_downscale_config(unsigned short type, unsigned short m)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_downscale_config(type, m);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_downscale_config(type, m);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_coefficients
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status =
+ sc1200_set_video_downscale_coefficients(coef1, coef2, coef3,
+ coef4);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status =
+ redcloud_set_video_downscale_coefficients(coef1, coef2, coef3,
+ coef4);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_downscale_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_downscale_enable(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_downscale_enable(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_window
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_window(short x, short y, unsigned short w, unsigned short h)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_window(x, y, w, h);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_window(x, y, w, h);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_window(x, y, w, h);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_window(x, y, w, h);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_left_crop
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_left_crop(unsigned short x)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_left_crop(x);
+#endif
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_left_crop(x);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_left_crop(x);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_left_crop(x);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_color_key
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_color_key(key, mask, graphics);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_color_key(key, mask, graphics);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_color_key(key, mask, graphics);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_color_key(key, mask, graphics);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_filter
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_filter(int xfilter, int yfilter)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_filter(xfilter, yfilter);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_filter(xfilter, yfilter);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_filter(xfilter, yfilter);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_palette(unsigned long *palette)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_palette(palette);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_palette(palette);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_palette(palette);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_palette(palette);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_graphics_palette
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_graphics_palette(unsigned long *palette)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_graphics_palette(palette);
+#endif
+
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_entry
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_palette_entry(unsigned long index, unsigned long palette)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_set_video_palette_entry(index, palette);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_palette_entry(index, palette);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_palette_entry(index, palette);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_palette_entry(index, palette);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_graphics_palette_entry
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_graphics_palette_entry(unsigned long index, unsigned long palette)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_graphics_palette_entry(index, palette);
+#endif
+
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_bypass
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_palette_bypass(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_palette_bypass(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_palette_bypass(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_request
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_request(short x, short y)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_request(x, y);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_request(x, y);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_request(x, y);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_source
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_source(VideoSourceType source)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_source(source);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vbi_source
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_source(VbiSourceType source)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_vbi_source(source);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vbi_lines
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_lines(unsigned long even, unsigned long odd)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_vbi_lines(even, odd);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vbi_total
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_total(unsigned long even, unsigned long odd)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_vbi_total(even, odd);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_interlaced
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_interlaced(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_video_interlaced(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_color_space_YUV
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_color_space_YUV(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_color_space_YUV(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vertical_scaler_offset
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_vertical_scaler_offset(char offset)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_vertical_scaler_offset(offset);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_top_line_in_odd
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_top_line_in_odd(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_top_line_in_odd(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_genlock_delay
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_genlock_delay(unsigned long delay)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_genlock_delay(delay);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_genlock_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_genlock_enable(int flags)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_genlock_enable(flags);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_cursor
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status =
+ sc1200_set_video_cursor(key, mask, select_color2, color1, color2);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status =
+ redcloud_set_video_cursor(key, mask, select_color2, color1,
+ color2);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status =
+ castle_set_video_cursor(key, mask, select_color2, color1, color2);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_cursor_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_video_cursor_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_video_cursor_enable(enable);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_video_cursor_enable(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_alpha_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_alpha_enable(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_alpha_enable(enable);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_alpha_enable(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_window
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_alpha_window(x, y, width, height);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_alpha_window(x, y, width, height);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_alpha_window(x, y, width, height);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_value
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_alpha_value(unsigned char alpha, char delta)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_alpha_value(alpha, delta);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_alpha_value(alpha, delta);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_alpha_value(alpha, delta);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_priority
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_alpha_priority(int priority)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_alpha_priority(priority);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_alpha_priority(priority);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_alpha_priority(priority);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_alpha_color(unsigned long color)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_alpha_color(color);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_alpha_color(color);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_alpha_color(color);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_alpha_color_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_alpha_color_enable(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_alpha_color_enable(enable);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_alpha_color_enable(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_no_ck_outside_alpha
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_no_ck_outside_alpha(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_no_ck_outside_alpha(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_set_no_ck_outside_alpha(enable);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_set_no_ck_outside_alpha(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_macrovision_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_set_macrovision_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_set_macrovision_enable(enable);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_disable_softvga
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_disable_softvga(void)
+{
+ int status = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_disable_softvga();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_disable_softvga();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_softvga
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_enable_softvga(void)
+{
+ int status = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_enable_softvga();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_enable_softvga();
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_clock_frequency
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_clock_frequency(void)
+{
+ unsigned long frequency = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ frequency = cs5530_get_clock_frequency();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ frequency = sc1200_get_clock_frequency();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ frequency = redcloud_get_clock_frequency();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ frequency = castle_get_clock_frequency();
+#endif
+ return (frequency);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_video_width
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_max_video_width(void)
+{
+ unsigned long width = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ width = cs5530_get_max_video_width();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ width = sc1200_get_max_video_width();
+#endif
+ return (width);
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsa2_softvga_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_vsa2_softvga_enable(void)
+{
+ int enable = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ enable = cs5530_get_vsa2_softvga_enable();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ enable = sc1200_get_vsa2_softvga_enable();
+#endif
+ return enable;
+
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_sync_polarities
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_sync_polarities(void)
+{
+ int polarities = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ polarities = cs5530_get_sync_polarities();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ polarities = sc1200_get_sync_polarities();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ polarities = redcloud_get_sync_polarities();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ polarities = castle_get_sync_polarities();
+#endif
+ return (polarities);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_palette_entry
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ status = cs5530_get_video_palette_entry(index, palette);
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_get_video_palette_entry(index, palette);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_get_video_palette_entry(index, palette);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_get_video_palette_entry(index, palette);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_video_enable(void)
+{
+ int enable = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ enable = cs5530_get_video_enable();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ enable = sc1200_get_video_enable();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ enable = redcloud_get_video_enable();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ enable = castle_get_video_enable();
+#endif
+ return (enable);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_format
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_video_format(void)
+{
+ int format = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ format = cs5530_get_video_format();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ format = sc1200_get_video_format();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ format = redcloud_get_video_format();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ format = castle_get_video_format();
+#endif
+ return (format);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_src_size
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_src_size(void)
+{
+ unsigned long size = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ size = cs5530_get_video_src_size();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ size = sc1200_get_video_src_size();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ size = redcloud_get_video_src_size();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ size = castle_get_video_src_size();
+#endif
+ return (size);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_line_size
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_line_size(void)
+{
+ unsigned long size = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ size = cs5530_get_video_line_size();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ size = sc1200_get_video_line_size();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ size = redcloud_get_video_line_size();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ size = castle_get_video_line_size();
+#endif
+ return (size);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_xclip
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_xclip(void)
+{
+ unsigned long size = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ size = cs5530_get_video_xclip();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ size = sc1200_get_video_xclip();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ size = redcloud_get_video_xclip();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ size = castle_get_video_xclip();
+#endif
+ return (size);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_offset
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_offset(void)
+{
+ unsigned long offset = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ offset = cs5530_get_video_offset();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ offset = sc1200_get_video_offset();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ offset = redcloud_get_video_offset();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ offset = castle_get_video_offset();
+#endif
+ return (offset);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_yuv_offsets
+ *----------------------------------------------------------------------------
+ */
+void
+gfx_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
+ unsigned long *voffset)
+{
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_get_video_yuv_offsets(yoffset, uoffset, voffset);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_yuv_pitch
+ *----------------------------------------------------------------------------
+ */
+void
+gfx_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+{
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_video_yuv_pitch(ypitch, uvpitch);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_get_video_yuv_pitch(ypitch, uvpitch);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_upscale
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_upscale(void)
+{
+ unsigned long scale = 0;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ scale = sc1200_get_video_upscale();
+#endif
+ return (scale);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_scale
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_scale(void)
+{
+ unsigned long scale = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ scale = cs5530_get_video_scale();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ scale = sc1200_get_video_scale();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ scale = redcloud_get_video_scale();
+#endif
+ return (scale);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_delta
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_downscale_delta(void)
+{
+ unsigned long delta = 0;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ delta = redcloud_get_video_downscale_delta();
+#endif
+ return (delta);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_vertical_downscale_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_vertical_downscale_enable(void)
+{
+ int enable = 0;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ enable = redcloud_get_video_vertical_downscale_enable();
+#endif
+ return (enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_config
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_downscale_config(unsigned short *type, unsigned short *m)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_get_video_downscale_config(type, m);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_get_video_downscale_config(type, m);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_coefficients
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4)
+{
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_get_video_downscale_coefficients(coef1, coef2, coef3, coef4);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_video_downscale_coefficients(coef1, coef2, coef3, coef4);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_enable
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_video_downscale_enable(int *enable)
+{
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_get_video_downscale_enable(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_video_downscale_enable(enable);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_dst_size
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_dst_size(void)
+{
+ unsigned long size = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ size = cs5530_get_video_dst_size();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ size = sc1200_get_video_dst_size();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ size = redcloud_get_video_dst_size();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ size = castle_get_video_dst_size();
+#endif
+ return (size);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_position
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_position(void)
+{
+ unsigned long position = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ position = cs5530_get_video_position();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ position = sc1200_get_video_position();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ position = redcloud_get_video_position();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ position = castle_get_video_position();
+#endif
+ return (position);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_color_key(void)
+{
+ unsigned long key = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ key = cs5530_get_video_color_key();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ key = sc1200_get_video_color_key();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ key = redcloud_get_video_color_key();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ key = castle_get_video_color_key();
+#endif
+ return (key);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key_mask
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_video_color_key_mask(void)
+{
+ unsigned long mask = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ mask = cs5530_get_video_color_key_mask();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ mask = sc1200_get_video_color_key_mask();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ mask = redcloud_get_video_color_key_mask();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ mask = castle_get_video_color_key_mask();
+#endif
+ return (mask);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key_src
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_color_key_src(void)
+{
+ int src = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ src = cs5530_get_video_color_key_src();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ src = sc1200_get_video_color_key_src();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ src = redcloud_get_video_color_key_src();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ src = castle_get_video_color_key_src();
+#endif
+ return (src);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_filter
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_filter(void)
+{
+ int filter = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ filter = cs5530_get_video_filter();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ filter = sc1200_get_video_filter();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ filter = redcloud_get_video_filter();
+#endif
+ return (filter);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_request
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_request(short *x, short *y)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_get_video_request(x, y);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ status = redcloud_get_video_request(x, y);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ status = castle_get_video_request(x, y);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_source
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_source(VideoSourceType * source)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_get_video_source(source);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vbi_source
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_vbi_source(VbiSourceType * source)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_get_vbi_source(source);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vbi_lines
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vbi_lines(int odd)
+{
+ unsigned long lines = (unsigned long)GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ lines = sc1200_get_vbi_lines(odd);
+#endif
+ return (lines);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vbi_total
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vbi_total(int odd)
+{
+ unsigned long total = (unsigned long)GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ total = sc1200_get_vbi_total(odd);
+#endif
+ return (total);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_interlaced
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_interlaced(void)
+{
+ int interlaced = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ interlaced = sc1200_get_video_interlaced();
+#endif
+ return (interlaced);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_color_space_YUV
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_color_space_YUV(void)
+{
+ int color_space = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ color_space = sc1200_get_color_space_YUV();
+#endif
+ return (color_space);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vertical_scaler_offset
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_vertical_scaler_offset(char *offset)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ status = sc1200_get_vertical_scaler_offset(offset);
+#endif
+ return (status);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_genlock_delay
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_genlock_delay(void)
+{
+ unsigned long delay = (unsigned long)GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ delay = sc1200_get_genlock_delay();
+#endif
+ return (delay);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_genlock_enable
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_genlock_enable(void)
+{
+ int enable = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ enable = sc1200_get_genlock_enable();
+#endif
+ return (enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_cursor
+ *---------------------------------------------------------------------------
+ */
+int
+gfx_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2)
+{
+ int enable = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ enable =
+ sc1200_get_video_cursor(key, mask, select_color2, color1, color2);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ enable =
+ redcloud_get_video_cursor(key, mask, select_color2, color1,
+ color2);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ enable =
+ castle_get_video_cursor(key, mask, select_color2, color1, color2);
+#endif
+ return (enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_read_crc
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_read_crc(void)
+{
+ unsigned long crc = 0;
+
+#if GFX_VIDEO_CS5530
+ if (gfx_video_type == GFX_VIDEO_TYPE_CS5530)
+ crc = cs5530_read_crc();
+#endif
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ crc = sc1200_read_crc();
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ crc = redcloud_read_crc();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ crc = castle_read_crc();
+#endif
+ return (crc);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_read_crc32
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_read_crc32(void)
+{
+ unsigned long crc = 0;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ crc = redcloud_read_crc32();
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ crc = castle_read_crc32();
+#endif
+ return (crc);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_read_window_crc
+ *---------------------------------------------------------------------------
+ */
+unsigned long
+gfx_read_window_crc(int source, unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, int crc32)
+{
+ unsigned long crc = 0;
+
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ crc = redcloud_read_window_crc(source, x, y, width, height, crc32);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ crc = castle_read_window_crc(source, x, y, width, height, crc32);
+#endif
+ return (crc);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_macrovision_enable
+ *-----------------------------------------------------------------------------
+ */
+int
+gfx_get_macrovision_enable(void)
+{
+ int enable = 0;
+
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ enable = sc1200_get_video_enable();
+#endif
+ return (enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_enable
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_alpha_enable(int *enable)
+{
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_get_alpha_enable(enable);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_alpha_enable(enable);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_get_alpha_enable(enable);
+#endif
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_size
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height)
+{
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_get_alpha_size(x, y, width, height);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_alpha_size(x, y, width, height);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_get_alpha_size(x, y, width, height);
+#endif
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_value
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_alpha_value(unsigned char *alpha, char *delta)
+{
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_get_alpha_value(alpha, delta);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_alpha_value(alpha, delta);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_get_alpha_value(alpha, delta);
+#endif
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_priority
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_alpha_priority(int *priority)
+{
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_get_alpha_priority(priority);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_alpha_priority(priority);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_get_alpha_priority(priority);
+#endif
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_color
+ *---------------------------------------------------------------------------
+ */
+void
+gfx_get_alpha_color(unsigned long *color)
+{
+#if GFX_VIDEO_SC1200
+ if (gfx_video_type == GFX_VIDEO_TYPE_SC1200)
+ sc1200_get_alpha_color(color);
+#endif
+#if GFX_VIDEO_REDCLOUD
+ if (gfx_video_type == GFX_VIDEO_TYPE_REDCLOUD)
+ redcloud_get_alpha_color(color);
+#endif
+#if GFX_VIDEO_CASTLE
+ if (gfx_video_type == GFX_VIDEO_TYPE_CASTLE)
+ castle_get_alpha_color(color);
+#endif
+ return;
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+#endif /* GFX_VIDEO_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/gfx_vip.c b/src/gfx/gfx_vip.c
new file mode 100644
index 0000000..e38c2f7
--- /dev/null
+++ b/src/gfx/gfx_vip.c
@@ -0,0 +1,531 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the video input port (VIP).
+ *
+ * gfx_set_vip_enable
+ * gfx_set_vip_capture_run_mode
+ * gfx_set_vip_base
+ * gfx_set_vip_pitch
+ * gfx_set_vip_mode
+ * gfx_set_vbi_enable
+ * gfx_set_vbi_mode
+ * gfx_set_vbi_base
+ * gfx_set_vbi_pitch
+ * gfx_set_vbi_direct
+ * gfx_set_vbi_interrupt
+ * gfx_set_vip_bus_request_threshold_high
+ * gfx_set_vip_last_line
+ * gfx_test_vip_odd_field
+ * gfx_test_vip_bases_updated
+ * gfx_test_vip_fifo_overflow
+ * gfx_get_vip_line
+ * gfx_get_vip_base
+ * gfx_get_vbi_pitch
+ *
+ * And the following routines if GFX_READ_ROUTINES is set:
+ *
+ * gfx_get_vip_enable
+ * gfx_get_vip_pitch
+ * gfx_get_vip_mode
+ * gfx_get_vbi_enable
+ * gfx_get_vbi_mode
+ * gfx_get_vbi_base
+ * gfx_get_vbi_direct
+ * gfx_get_vbi_interrupt
+ * gfx_get_vip_bus_request_threshold_high
+ * */
+
+/* INCLUDE SUPPORT FOR SC1200, IF SPECIFIED. */
+
+#if GFX_VIP_SC1200
+#include "vip_1200.c"
+#endif
+
+/* WRAPPERS IF DYNAMIC SELECTION */
+/* Extra layer to call either CS5530 or SC1200 routines. */
+
+#if GFX_VIP_DYNAMIC
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vip_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vip_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vip_enable(enable);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_capture_run_mode
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vip_capture_run_mode(int mode)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vip_capture_run_mode(mode);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_base
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vip_base(unsigned long even, unsigned long odd)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vip_base(even, odd);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_pitch
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vip_pitch(unsigned long pitch)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vip_pitch(pitch);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_mode
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vip_mode(int mode)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vip_mode(mode);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_enable(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vbi_enable(enable);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_mode
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_mode(int mode)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vbi_mode(mode);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_base
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_base(unsigned long even, unsigned long odd)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vbi_base(even, odd);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_pitch
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_pitch(unsigned long pitch)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vbi_pitch(pitch);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_direct
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vbi_direct(even_lines, odd_lines);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_interrupt
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vbi_interrupt(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vbi_interrupt(enable);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_bus_request_threshold_high
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vip_bus_request_threshold_high(int enable)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vip_bus_request_threshold_high(enable);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_last_line
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_set_vip_last_line(int last_line)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_set_vip_last_line(last_line);
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_test_vip_odd_field
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_test_vip_odd_field(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_test_vip_odd_field();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_test_vip_bases_updated
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_test_vip_bases_updated(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_test_vip_bases_updated();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_test_vip_fifo_overflow
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_test_vip_fifo_overflow(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_test_vip_fifo_overflow();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_line
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_vip_line(void)
+{
+ int status = GFX_STATUS_UNSUPPORTED;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ status = sc1200_get_vip_line();
+#endif
+ return (status);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_base
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vip_base(int odd)
+{
+ unsigned long base = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ base = sc1200_get_vip_base(odd);
+#endif
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_pitch
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vbi_pitch(void)
+{
+ unsigned long pitch = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ pitch = sc1200_get_vbi_pitch();
+#endif
+ return (pitch);
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_vip_enable(void)
+{
+ int enable = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ enable = sc1200_get_vip_enable();
+#endif
+ return (enable);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_pitch
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vip_pitch(void)
+{
+ unsigned long pitch = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ pitch = sc1200_get_vip_pitch();
+#endif
+ return (pitch);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_mode
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_vip_mode(void)
+{
+ int mode = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ mode = sc1200_get_vip_mode();
+#endif
+ return (mode);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_enable
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_vbi_enable(void)
+{
+ int enable = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ enable = sc1200_get_vbi_enable();
+#endif
+ return (enable);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_mode
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_vbi_mode(void)
+{
+ int mode = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ mode = sc1200_get_vbi_mode();
+#endif
+ return (mode);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_base
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vbi_base(int odd)
+{
+ unsigned long base = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ base = sc1200_get_vbi_base(odd);
+#endif
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_direct
+ *----------------------------------------------------------------------------
+ */
+unsigned long
+gfx_get_vbi_direct(int odd)
+{
+ unsigned long vbi_direct_lines = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ vbi_direct_lines = sc1200_get_vbi_direct(odd);
+#endif
+ return (vbi_direct_lines);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_interrupt
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_vbi_interrupt(void)
+{
+ int enable = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ enable = sc1200_get_vbi_interrupt();
+#endif
+ return (enable);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_bus_request_threshold_high
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_vip_bus_request_threshold_high(void)
+{
+ int enable = 0;
+
+#if GFX_VIP_SC1200
+ if (gfx_vip_type == GFX_VIP_TYPE_SC1200)
+ enable = sc1200_get_vip_bus_request_threshold_high();
+#endif
+ return (enable);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+#endif /* GFX_VIP_DYNAMIC */
+
+/* END OF FILE */
diff --git a/src/gfx/history.h b/src/gfx/history.h
new file mode 100644
index 0000000..ccb8d6a
--- /dev/null
+++ b/src/gfx/history.h
@@ -0,0 +1,33 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/* Version is in the format of MMmmpp
+ * where in MM is the Major version, mm is the minor version
+ * and pp is the patch number (0 - 99)
+ */
+
+#define DURANGO_VERSION 30003
+
+/* END OF FILE */
diff --git a/src/gfx/i2c_acc.c b/src/gfx/i2c_acc.c
new file mode 100644
index 0000000..a45a2c3
--- /dev/null
+++ b/src/gfx/i2c_acc.c
@@ -0,0 +1,876 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to write to and read from the I2C bus using
+ * the ACCESS.bus hardware in the SC1200.
+ * */
+
+/* SUPER IO DEFINITIONS */
+
+#define INDEX_1 0x15C /* base address 1 selected */
+#define DATA_1 0x15D
+#define INDEX_2 0x2E /* base address 2 selected */
+#define DATA_2 0x2F
+#define PCI_INDEX 0xCF8 /* PCI configuration space INDEX */
+#define PCI_DATA 0xCFC /* PCI configuration space DATA */
+#define BASE_ADR_MSB_REG 0x60 /* base address MSB register */
+#define BASE_ADR_LSB_REG 0x61 /* base address LSB register */
+
+#define SIO_BASE_ADR_15C_15D 0x6000000
+#define SIO_BASE_ADR_2E_2F 0x4000000
+
+/* SUPER IO GLOBALS */
+
+unsigned short index_reg, data_reg;
+
+/* ACCESS BUS DEFINITIONS */
+
+#define ACC_I2C_TIMEOUT 1000000 /* Number of reads before timing out */
+#define ACB1_BASE 0x810 /* ACCESS.bus base addresses */
+#define ACB2_BASE 0x820
+#define ACBSDA 0 /* ACB serial data */
+#define ACBST 1 /* ACB status */
+#define ACBCST 2 /* ACB control status */
+#define ACBCTL1 3 /* ACB control 1 */
+#define ACBADDR 4 /* ACB own address */
+#define ACBCTL2 5 /* ACB control 2 */
+#define LDN 0x7 /* Logical Device Numbers */
+#define ACB1_LDN 0x5
+#define ACB2_LDN 0x6
+
+/* INITIAL ACCESS.bus BASE ADDRESS VALUES */
+
+unsigned short base_address_array[3] = { 0, ACB1_BASE, ACB2_BASE };
+char Freq = 0x71;
+
+/* LOCAL ACCESS.bus FUNCTION DECLARATIONS */
+
+void acc_i2c_start(unsigned char busnum);
+void acc_i2c_stop(unsigned char busnum);
+void acc_i2c_abort_data(unsigned char busnum);
+void acc_i2c_bus_recovery(unsigned char busnum);
+void acc_i2c_stall_after_start(unsigned char busnum, int state);
+void acc_i2c_send_address(unsigned char busnum, unsigned char cData);
+int acc_i2c_ack(unsigned char busnum, int fPut, int negAck);
+void acc_i2c_stop_clock(unsigned char busnum);
+void acc_i2c_activate_clock(unsigned char busnum);
+void acc_i2c_write_byte(unsigned char busnum, unsigned char cData);
+unsigned char acc_i2c_read_byte(unsigned char busnum, int last_byte);
+void acc_i2c_reset_bus(unsigned char busnum);
+int acc_i2c_request_master(unsigned char busnum);
+void acc_i2c_config(unsigned char busnum, short adr, char freq);
+char acc_i2c_set_freq(unsigned char busnum, char freq);
+unsigned short acc_i2c_set_base_address(unsigned char busnum, short adr);
+
+/* LOCAL HELPER ROUTINES */
+
+void OsPciReadDWord(int bus, int dev, int func, int address,
+ unsigned long *data);
+int sio_set_index_data_reg(void);
+void sio_write_reg(unsigned char reg, unsigned char data);
+unsigned char sio_read_reg(unsigned char reg);
+
+/*---------------------------------------------------------------------------
+ * OsPciReadDWord
+ *
+ * This routine reads one double word from the PCI configuration header
+ * defined by 'bus', 'dev', 'func' and 'address' to the double word
+ * pointed to by 'data'.
+ *
+ * Returns : None.
+ *---------------------------------------------------------------------------
+ */
+void
+OsPciReadDWord(int bus, int dev, int func, int address, unsigned long *data)
+{
+ /*
+ * The address of a double word in the Configuration Header is built in
+ * the following way :
+ * {10000000,bus[23:16],device[15:11],function[10:8],address[7:2],00}
+ */
+ long addr = (0x80000000 |
+ ((bus & 0xff) << 16) |
+ ((dev & 0x1f) << 11) | ((func & 0x7) << 8) | (address & 0xff));
+ OUTD(PCI_INDEX, addr);
+ *data = IND(PCI_DATA);
+}
+
+/*---------------------------------------------------------------------------
+ * sio_set_index_data_reg
+ *
+ * This routine checks which index and data registers to use
+ * in order to access the Super I/O registers
+ *
+ * Returns : 1 - OK
+ * 0 - Super I/O disabled or configuration access disabled
+ *---------------------------------------------------------------------------
+ */
+int
+sio_set_index_data_reg(void)
+{
+ unsigned long xbus_expention_bar, io_control_reg1;
+
+ OsPciReadDWord(0, 0x12, 5, 0x10, &xbus_expention_bar);
+ xbus_expention_bar = xbus_expention_bar & 0xfffffffe;
+ io_control_reg1 = IND((unsigned short)xbus_expention_bar);
+
+ if ((io_control_reg1) & (SIO_BASE_ADR_15C_15D)) {
+ index_reg = INDEX_1;
+ data_reg = DATA_1;
+ return (1);
+ }
+
+ if ((io_control_reg1) & (SIO_BASE_ADR_2E_2F)) {
+ index_reg = INDEX_2;
+ data_reg = DATA_2;
+ return (1);
+ }
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * sio_write_reg
+ *
+ * This routine writes 'data' to 'reg' Super I/O register
+ *
+ * Returns : None
+ *---------------------------------------------------------------------------
+ */
+void
+sio_write_reg(unsigned char reg, unsigned char data)
+{
+ OUTB(index_reg, reg);
+ OUTB(data_reg, data);
+}
+
+/*---------------------------------------------------------------------------
+ * sio_read_reg
+ *
+ * This routine reads data from 'reg' Super I/O register
+ *
+ * Returns : The data read from the requested register
+ *---------------------------------------------------------------------------
+ */
+unsigned char
+sio_read_reg(unsigned char reg)
+{
+ OUTB(index_reg, reg);
+ return INB(data_reg);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_reset
+ *
+ * This routine resets the I2C bus as follows :
+ * · Sets the base address of the ACCESS.bus
+ * · Sets the frequency of the ACCESS.bus
+ * · Resets the ACCESS.bus
+ *
+ * If 'adr' is -1 the address is read from the hardware.
+ * If 'freq' is -1 the frequency is set to 56 clock cycles.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+acc_i2c_reset(unsigned char busnum, short adr, char freq)
+#else
+int
+gfx_i2c_reset(unsigned char busnum, short adr, char freq)
+#endif
+{
+ if ((busnum != 1) && (busnum != 2))
+ return GFX_STATUS_BAD_PARAMETER;
+ acc_i2c_config(busnum, adr, freq);
+ if (base_address_array[busnum] == 0)
+ return GFX_STATUS_ERROR;
+ acc_i2c_reset_bus(busnum);
+ return GFX_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_select_gpio
+ *
+ * This routine selects which GPIO pins to use.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+acc_i2c_select_gpio(int clock, int data)
+#else
+int
+gfx_i2c_select_gpio(int clock, int data)
+#endif
+{
+ /* THIS ROUTINE DOES NOT APPLY TO THE ACCESS.bus IMPLEMENTATION. */
+
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_write
+ *
+ * This routine writes data to the specified I2C address.
+ * busnum - ACCESS.bus number (1 or 2).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+acc_i2c_write(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data)
+#else
+int
+gfx_i2c_write(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data)
+#endif
+{
+ int loop = 0;
+
+ if ((busnum != 1) && (busnum != 2))
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* REQUEST MASTER */
+
+ if (!acc_i2c_request_master(busnum))
+ return (GFX_STATUS_ERROR);
+
+ /* WRITE ADDRESS COMMAND */
+
+ acc_i2c_ack(busnum, 1, 0);
+ acc_i2c_stall_after_start(busnum, 1);
+ acc_i2c_send_address(busnum, (unsigned char)(chipadr & 0xFE));
+ acc_i2c_stall_after_start(busnum, 0);
+ if (!acc_i2c_ack(busnum, 0, 0))
+ return (GFX_STATUS_ERROR);
+
+ /* WRITE COMMAND */
+
+ acc_i2c_write_byte(busnum, subadr);
+ if (!acc_i2c_ack(busnum, 0, 0))
+ return (GFX_STATUS_ERROR);
+
+ /* WRITE DATA */
+
+ for (loop = 0; loop < bytes; loop++) {
+ acc_i2c_write_byte(busnum, *data);
+ if (loop < (bytes - 1))
+ data += sizeof(unsigned char);
+ if (!acc_i2c_ack(busnum, 0, 0))
+ return (GFX_STATUS_ERROR);
+ }
+ data -= (bytes - 1);
+ acc_i2c_stop(busnum);
+
+ return GFX_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_read
+ *
+ * This routine reads data from the specified I2C address.
+ * busnum - ACCESS.bus number (1 or 2).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+acc_i2c_read(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data)
+#else
+int
+gfx_i2c_read(unsigned char busnum, unsigned char chipadr,
+ unsigned char subadr, unsigned char bytes, unsigned char *data)
+#endif
+{
+ unsigned char bytesRead;
+
+ if ((busnum != 1) && (busnum != 2))
+ return GFX_STATUS_BAD_PARAMETER;
+
+ if (bytes == 0)
+ return GFX_STATUS_OK;
+
+ /* REQUEST MASTER */
+
+ if (!acc_i2c_request_master(busnum))
+ return (GFX_STATUS_ERROR);
+
+ /* WRITE ADDRESS COMMAND */
+
+ acc_i2c_ack(busnum, 1, 0);
+ acc_i2c_stall_after_start(busnum, 1);
+ acc_i2c_send_address(busnum, (unsigned char)(chipadr & 0xFE));
+ acc_i2c_stall_after_start(busnum, 0);
+ if (!acc_i2c_ack(busnum, 0, 0))
+ return (GFX_STATUS_ERROR);
+
+ /* WRITE COMMAND */
+
+ acc_i2c_write_byte(busnum, subadr);
+ if (!acc_i2c_ack(busnum, 0, 0))
+ return (GFX_STATUS_ERROR);
+
+ /* START THE READ */
+
+ acc_i2c_start(busnum);
+
+ /* WRITE ADDRESS COMMAND */
+
+ acc_i2c_ack(busnum, 1, 1);
+ acc_i2c_stall_after_start(busnum, 1);
+ acc_i2c_send_address(busnum, (unsigned char)(chipadr | 0x01));
+
+ /* IF LAST BYTE */
+
+ if (bytes == 1)
+ acc_i2c_ack(busnum, 1, 1);
+ else
+ acc_i2c_ack(busnum, 1, 0);
+
+ acc_i2c_stall_after_start(busnum, 0);
+
+ if (!acc_i2c_ack(busnum, 0, 0))
+ return (GFX_STATUS_ERROR);
+
+ /* READ COMMAND */
+
+ for (bytesRead = 0; bytesRead < bytes; bytesRead += 1) {
+ if (bytesRead < (bytes - 2)) {
+ data[bytesRead] = acc_i2c_read_byte(busnum, 0);
+ acc_i2c_ack(busnum, 1, 0);
+ } else if (bytesRead == (bytes - 2)) { /* TWO BYTES LEFT */
+ acc_i2c_ack(busnum, 1, 1);
+ data[bytesRead] = acc_i2c_read_byte(busnum, 0);
+ acc_i2c_ack(busnum, 1, 1);
+ } else { /* LAST BYTE */
+
+ data[bytesRead] = acc_i2c_read_byte(busnum, 1);
+ acc_i2c_stop(busnum);
+ }
+
+ /* WHILE NOT LAST BYTE */
+
+ if ((!(bytesRead == (bytes - 1))) && (!acc_i2c_ack(busnum, 0, 0)))
+ return (bytesRead);
+ }
+
+ return GFX_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_init
+ *
+ * This routine initializes the use of the ACCESS.BUS.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+acc_i2c_init(void)
+#else
+int
+gfx_i2c_init(void)
+#endif
+{
+ /* ### ADD ### THIS ROUTINE IS NOT YET IMPLEMENTED FOR ACCESS.bus */
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_cleanup
+ *
+ * This routine ends the use of the ACCESS.BUS.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+void
+acc_i2c_cleanup(void)
+#else
+void
+gfx_i2c_cleanup(void)
+#endif
+{
+ /* ### ADD ### THIS ROUTINE IS NOT YET IMPLEMENTED FOR ACCESS.bus */
+}
+
+/*--------------------------------------------------------*/
+/* LOCAL ROUTINES SPECIFIC TO ACCESS.bus IMPLEMENTATION */
+/*--------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_reset_bus
+ *
+ * This routine resets the I2C bus.
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_reset_bus(unsigned char busnum)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ /* Disable the ACCESS.bus device and */
+ /* Configure the SCL frequency */
+ OUTB((unsigned short)(bus_base_address + ACBCTL2),
+ (unsigned char)(Freq & 0xFE));
+
+ /* Configure no interrupt mode (polling) and */
+ /* Disable global call address */
+ OUTB((unsigned short)(bus_base_address + ACBCTL1), 0x0);
+
+ /* Disable slave address */
+ OUTB((unsigned short)(bus_base_address + ACBADDR), 0x0);
+
+ /* Enable the ACCESS.bus device */
+ reg = INB((unsigned short)(bus_base_address + ACBCTL2));
+ reg |= 0x01;
+ OUTB((unsigned short)(bus_base_address + ACBCTL2), reg);
+
+ /* Issue STOP event */
+
+ acc_i2c_stop(busnum);
+
+ /* Clear NEGACK, STASTR and BER bits */
+ OUTB((unsigned short)(bus_base_address + ACBST), 0x38);
+
+ /* Clear BB (BUS BUSY) bit */
+ reg = INB((unsigned short)(bus_base_address + ACBCST));
+ reg |= 0x02;
+ OUTB((unsigned short)(bus_base_address + ACBCST), reg);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_start
+ *
+ * This routine starts a transfer on the I2C bus.
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_start(unsigned char busnum)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ reg = INB((unsigned short)(bus_base_address + ACBCTL1));
+ reg |= 0x01;
+ OUTB((unsigned short)(bus_base_address + ACBCTL1), reg);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_stop
+ *
+ * This routine stops a transfer on the I2C bus.
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_stop(unsigned char busnum)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ reg = INB((unsigned short)(bus_base_address + ACBCTL1));
+ reg |= 0x02;
+ OUTB((unsigned short)(bus_base_address + ACBCTL1), reg);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_abort_data
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_abort_data(unsigned char busnum)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ acc_i2c_stop(busnum);
+ reg = INB((unsigned short)(bus_base_address + ACBCTL1));
+ reg |= 0x10;
+ OUTB((unsigned short)(bus_base_address + ACBCTL1), reg);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_bus_recovery
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_bus_recovery(unsigned char busnum)
+{
+ acc_i2c_abort_data(busnum);
+ acc_i2c_reset_bus(busnum);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_stall_after_start
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_stall_after_start(unsigned char busnum, int state)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ reg = INB((unsigned short)(bus_base_address + ACBCTL1));
+ if (state)
+ reg |= 0x80;
+ else
+ reg &= 0x7F;
+ OUTB((unsigned short)(bus_base_address + ACBCTL1), reg);
+
+ if (!state) {
+ reg = INB((unsigned short)(bus_base_address + ACBST));
+ reg |= 0x08;
+ OUTB((unsigned short)(bus_base_address + ACBST), reg);
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_send_address
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_send_address(unsigned char busnum, unsigned char cData)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+ unsigned long timeout = 0;
+
+ /* WRITE THE DATA */
+
+ OUTB((unsigned short)(bus_base_address + ACBSDA), cData);
+ while (1) {
+ reg = INB((unsigned short)(bus_base_address + ACBST));
+ if ((reg & 0x38) != 0) /* check STASTR, BER and NEGACK */
+ break;
+ if (timeout++ == ACC_I2C_TIMEOUT) {
+ acc_i2c_bus_recovery(busnum);
+ return;
+ }
+ }
+
+ /* CHECK FOR BUS ERROR */
+
+ if (reg & 0x20) {
+ acc_i2c_bus_recovery(busnum);
+ return;
+ }
+
+ /* CHECK NEGATIVE ACKNOWLEDGE */
+
+ if (reg & 0x10) {
+ acc_i2c_abort_data(busnum);
+ return;
+ }
+
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_ack
+ *
+ * This routine looks for acknowledge on the I2C bus.
+ *---------------------------------------------------------------------------
+ */
+int
+acc_i2c_ack(unsigned char busnum, int fPut, int negAck)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+ unsigned long timeout = 0;
+
+ if (fPut) { /* read operation */
+ if (!negAck) {
+ /* Push Ack onto I2C bus */
+ reg = INB((unsigned short)(bus_base_address + ACBCTL1));
+ reg &= 0xE7;
+ OUTB((unsigned short)(bus_base_address + ACBCTL1), reg);
+ } else {
+ /* Push negAck onto I2C bus */
+ reg = INB((unsigned short)(bus_base_address + ACBCTL1));
+ reg |= 0x10;
+ OUTB((unsigned short)(bus_base_address + ACBCTL1), reg);
+ }
+ } else { /* write operation */
+ /* Receive Ack from I2C bus */
+ while (1) {
+ reg = INB((unsigned short)(bus_base_address + ACBST));
+ if ((reg & 0x70) != 0) /* check SDAST, BER and NEGACK */
+ break;
+ if (timeout++ == ACC_I2C_TIMEOUT) {
+ acc_i2c_bus_recovery(busnum);
+ return (0);
+ }
+ }
+
+ /* CHECK FOR BUS ERROR */
+
+ if (reg & 0x20) {
+ acc_i2c_bus_recovery(busnum);
+ return (0);
+ }
+
+ /* CHECK NEGATIVE ACKNOWLEDGE */
+
+ if (reg & 0x10) {
+ acc_i2c_abort_data(busnum);
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_stop_clock
+ *
+ * This routine stops the ACCESS.bus clock.
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_stop_clock(unsigned char busnum)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ reg = INB((unsigned short)(bus_base_address + ACBCTL2));
+ reg &= ~0x01;
+ OUTB((unsigned short)(bus_base_address + ACBCTL2), reg);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_activate_clock
+ *
+ * This routine activates the ACCESS.bus clock.
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_activate_clock(unsigned char busnum)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ reg = INB((unsigned short)(bus_base_address + ACBCTL2));
+ reg |= 0x01;
+ OUTB((unsigned short)(bus_base_address + ACBCTL2), reg);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_write_byte
+ *
+ * This routine writes a byte to the I2C bus
+ *---------------------------------------------------------------------------
+ */
+void
+acc_i2c_write_byte(unsigned char busnum, unsigned char cData)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+ unsigned long timeout = 0;
+
+ while (1) {
+ reg = INB((unsigned short)(bus_base_address + ACBST));
+ if (reg & 0x70)
+ break;
+ if (timeout++ == ACC_I2C_TIMEOUT) {
+ acc_i2c_bus_recovery(busnum);
+ return;
+ }
+ }
+
+ /* CHECK FOR BUS ERROR */
+
+ if (reg & 0x20) {
+ acc_i2c_bus_recovery(busnum);
+ return;
+ }
+
+ /* CHECK NEGATIVE ACKNOWLEDGE */
+
+ if (reg & 0x10) {
+ acc_i2c_abort_data(busnum);
+ return;
+ }
+
+ /* WRITE THE DATA */
+
+ OUTB((unsigned short)(bus_base_address + ACBSDA), cData);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_read_byte
+ *
+ * This routine reads a byte from the I2C bus
+ *---------------------------------------------------------------------------
+ */
+unsigned char
+acc_i2c_read_byte(unsigned char busnum, int last_byte)
+{
+ unsigned char cData, reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+ unsigned long timeout = 0;
+
+ while (1) {
+ reg = INB((unsigned short)(bus_base_address + ACBST));
+ if (reg & 0x60)
+ break;
+ if (timeout++ == ACC_I2C_TIMEOUT) {
+ acc_i2c_bus_recovery(busnum);
+ return (0xEF);
+ }
+ }
+
+ /* CHECK FOR BUS ERROR */
+
+ if (reg & 0x20) {
+ acc_i2c_bus_recovery(busnum);
+ return (0xEE);
+ }
+
+ /* READ DATA */
+ if (last_byte)
+ acc_i2c_stop_clock(busnum);
+ cData = INB((unsigned short)(bus_base_address + ACBSDA));
+ if (last_byte)
+ acc_i2c_activate_clock(busnum);
+
+ return (cData);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_request_master
+ *---------------------------------------------------------------------------
+ */
+int
+acc_i2c_request_master(unsigned char busnum)
+{
+ unsigned char reg;
+ unsigned short bus_base_address = base_address_array[busnum];
+ unsigned long timeout = 0;
+
+ acc_i2c_start(busnum);
+ while (1) {
+ reg = INB((unsigned short)(bus_base_address + ACBST));
+ if (reg & 0x60)
+ break;
+ if (timeout++ == ACC_I2C_TIMEOUT) {
+ acc_i2c_bus_recovery(busnum);
+ return (0);
+ }
+ }
+
+ /* CHECK FOR BUS ERROR */
+
+ if (reg & 0x20) {
+ acc_i2c_abort_data(busnum);
+ return (0);
+ }
+
+ /* CHECK NEGATIVE ACKNOWLEDGE */
+
+ if (reg & 0x10) {
+ acc_i2c_abort_data(busnum);
+ return (0);
+ }
+ return (1);
+}
+
+/*--------------------------------------------------------*/
+/* LOCAL ROUTINES SPECIFIC TO ACCESS.bus INITIALIZATION */
+/*--------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * acc_i2c_config
+ *
+ * This routine configures the I2C bus
+ *----------------------------------------------------------------------------
+ */
+void
+acc_i2c_config(unsigned char busnum, short adr, char freq)
+{
+ base_address_array[busnum] = acc_i2c_set_base_address(busnum, adr);
+ Freq = acc_i2c_set_freq(busnum, freq);
+}
+
+/*----------------------------------------------------------------------------
+ * acc_i2c_set_freq
+ *
+ * This routine sets the frequency of the I2C bus
+ *----------------------------------------------------------------------------
+ */
+char
+acc_i2c_set_freq(unsigned char busnum, char freq)
+{
+ unsigned short bus_base_address = base_address_array[busnum];
+
+ OUTB((unsigned short)(bus_base_address + ACBCTL2), 0x0);
+
+ if (freq == -1)
+ freq = 0x71;
+ else {
+ freq = freq << 1;
+ freq |= 0x01;
+ }
+
+ OUTB((unsigned short)(bus_base_address + ACBCTL2), freq);
+ return (freq);
+}
+
+/*---------------------------------------------------------------------------
+ * acc_i2c_set_base_address
+ *
+ * This routine sets the base address of the I2C bus
+ *---------------------------------------------------------------------------
+ */
+unsigned short
+acc_i2c_set_base_address(unsigned char busnum, short adr)
+{
+ unsigned short ab_base_addr;
+
+ /* Get Super I/O Index and Data registers */
+ if (!sio_set_index_data_reg())
+ return (0);
+
+ /* Configure LDN to current ACB */
+ if (busnum == 1)
+ sio_write_reg(LDN, ACB1_LDN);
+ if (busnum == 2)
+ sio_write_reg(LDN, ACB2_LDN);
+
+ if (adr == -1) {
+ /* Get ACCESS.bus base address */
+ ab_base_addr = sio_read_reg(BASE_ADR_MSB_REG);
+ ab_base_addr = ab_base_addr << 8;
+ ab_base_addr |= sio_read_reg(BASE_ADR_LSB_REG);
+ if (ab_base_addr != 0)
+ return ab_base_addr;
+ else
+ adr = (busnum == 1 ? ACB1_BASE : ACB2_BASE);
+ }
+
+ /* Set ACCESS.bus base address */
+ sio_write_reg(BASE_ADR_LSB_REG, (unsigned char)(adr & 0xFF));
+ sio_write_reg(BASE_ADR_MSB_REG, (unsigned char)(adr >> 8));
+
+ return adr;
+}
+
+/* END OF FILE */
diff --git a/src/gfx/i2c_gpio.c b/src/gfx/i2c_gpio.c
new file mode 100644
index 0000000..7614cd0
--- /dev/null
+++ b/src/gfx/i2c_gpio.c
@@ -0,0 +1,639 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to write to and read from the I2C bus using
+ * the GPIO pins of the CS5530.
+ * */
+
+/* STATIC VARIABLES TO STORE WHAT GPIO PINS TO USE */
+
+int gpio_clock = 0;
+int gpio_data = 0;
+
+static int g_initialized = 0;
+
+#define I2CWRITE 0x00 /* Write address */
+#define I2CREAD 0x01 /* Read address */
+
+#define I2CACK 0x00 /* Ack value */
+#define I2CNACK 0x01 /* Not - ack value */
+
+#define CS5530_ID (0x80000000 | (0x00<<16) | (0x12<<11) | (0<<8) | 0x00)
+#define CS5530_GPIO (0x80000000 | (0x00<<16) | (0x12<<11) | (0<<8) | 0x90)
+#define SDA 0x0800
+#define SCL 0x0400
+#define SDADIR 0x0008
+#define SCLDIR 0x0004
+
+int I2C_init(void);
+void I2C_cleanup(void);
+
+int I2C_Read(unsigned char address, unsigned int reg, unsigned long *p_value,
+ unsigned int bytes);
+int I2C_Write(unsigned char address, unsigned int reg, unsigned long value,
+ unsigned int bytes);
+int I2CAL_init(void);
+void I2CAL_cleanup(void);
+
+void I2CAL_output_clock(int state);
+void I2CAL_output_data(int state);
+unsigned char I2CAL_input_data(void);
+
+void I2CAL_set_data_for_input(void);
+void I2CAL_set_data_for_output(void);
+
+void SendI2CStart(void);
+void SendI2CData(unsigned char inData);
+
+unsigned char ReceiveI2CAck(void);
+void SendI2CStop(void);
+void SendI2CNack(void);
+void SendI2CAck(void);
+unsigned char ReceiveI2CData(void);
+
+/* ### ADD ### ANY LOCAL ROUTINE DEFINITIONS SPECIFIC TO GPIO */
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_reset
+ *
+ * This routine resets the I2C bus.
+ *---------------------------------------------------------------------------
+ */
+
+#if GFX_I2C_DYNAMIC
+int
+gpio_i2c_reset(unsigned char busnum, short adr, char freq)
+#else
+int
+gfx_i2c_reset(unsigned char busnum, short adr, char freq)
+#endif
+{
+ /* ### ADD ### Any code needed to reset the state of the GPIOs. */
+ return GFX_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_select_gpio
+ *
+ * This routine selects which GPIO pins to use.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+gpio_i2c_select_gpio(int clock, int data)
+#else
+int
+gfx_i2c_select_gpio(int clock, int data)
+#endif
+{
+ gpio_clock = clock;
+ gpio_data = data;
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_write
+ *
+ * This routine writes data to the specified I2C address.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+gpio_i2c_write(unsigned char busnum, unsigned char address, unsigned char reg,
+ unsigned char bytes, unsigned char *value)
+#else
+int
+gfx_i2c_write(unsigned char busnum, unsigned char address, unsigned char reg,
+ unsigned char bytes, unsigned char *value)
+#endif
+{
+ /* ### ADD ### CODE TO WRITE BYTE TO I2B BUS */
+
+ int restart_count = 0;
+
+ while (restart_count++ < 5) {
+ /* set the access pointer register. */
+ /* The address is shifted left by one to make room for Read/Write
+ * bit */
+ SendI2CStart();
+ SendI2CData((char)((address << 1) | I2CWRITE));
+ if (!ReceiveI2CAck()) {
+ SendI2CStop();
+ gfx_delay_milliseconds(10);
+ continue;
+ }
+ SendI2CData((unsigned char)reg);
+ if (!ReceiveI2CAck()) {
+ SendI2CStop();
+ gfx_delay_milliseconds(10);
+ continue;
+ }
+
+ /* write the first byte */
+ SendI2CData(*value);
+ if (!ReceiveI2CAck()) {
+ SendI2CStop();
+ gfx_delay_milliseconds(10);
+ continue;
+ }
+
+ /* write the second byte. */
+ if (bytes == 2) {
+ SendI2CData(*(value + 1));
+ if (!ReceiveI2CAck()) {
+ SendI2CStop();
+ gfx_delay_milliseconds(10);
+ continue;
+ }
+ }
+
+ /* done. */
+ SendI2CStop();
+
+ return 0;
+ }
+
+ return (0);
+
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_i2c_read
+ *
+ * This routine reads data from the specified I2C address.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_I2C_DYNAMIC
+int
+gpio_i2c_read(unsigned char busnum, unsigned char address, unsigned char reg,
+ unsigned char bytes, unsigned char *p_value)
+#else
+int
+gfx_i2c_read(unsigned char busnum, unsigned char address, unsigned char reg,
+ unsigned char bytes, unsigned char *p_value)
+#endif
+{
+ /* ### ADD ### CODE TO WRITE BYTE TO I2B BUS */
+ /* For now return clock and data pins */
+
+ int restart_count = 0;
+
+ if (!p_value)
+ return (1);
+
+ while (restart_count++ < 5) {
+ /* set the access pointer register. */
+ /* The address is shifted left by one to make room for Read/Write
+ * bit */
+ SendI2CStart();
+ SendI2CData((char)((address << 1) | I2CWRITE));
+ if (!ReceiveI2CAck()) {
+ SendI2CStop();
+ gfx_delay_milliseconds(10);
+ continue;
+ }
+ SendI2CData((unsigned char)(reg & 0xFF));
+ SendI2CNack();
+
+ /* read the first data byte. */
+ SendI2CStart();
+ SendI2CData((char)((address << 1) | I2CREAD));
+ if (!ReceiveI2CAck()) {
+ SendI2CStop();
+ gfx_delay_milliseconds(10);
+ continue;
+ }
+ *p_value = ReceiveI2CData();
+
+ /* read the second byte. */
+ if (bytes == 2) {
+ SendI2CAck();
+ *(p_value + 1) = ReceiveI2CData();
+ }
+
+ /* done. */
+ SendI2CNack();
+ SendI2CStop();
+
+ return 0;
+ }
+
+ return (1);
+}
+
+/* Added i2c/gpio code to test fs451 chip. */
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * void SendI2CStart(void)
+ *
+ * Sends an I2C start signal on the bus.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+SendI2CStart(void)
+{
+ I2CAL_output_data(1);
+ I2CAL_output_clock(1);
+ I2CAL_output_data(0);
+ I2CAL_output_clock(0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * void SendI2CStop(void)
+ *
+ * Sends an I2C stop signal on the bus.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+SendI2CStop(void)
+{
+ I2CAL_output_data(0);
+ I2CAL_output_clock(1);
+ I2CAL_output_data(1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * void SendI2CAck(void)
+ *
+ * Sends the Ack signal on the I2C bus.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+SendI2CAck(void)
+{
+ I2CAL_output_data(0);
+ I2CAL_output_clock(1);
+ I2CAL_output_clock(0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * void SendI2CNack(void)
+ *
+ * Sends the Nt-Ack signal on the I2C bus.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+SendI2CNack(void)
+{
+ I2CAL_output_data(1);
+ I2CAL_output_clock(1);
+ I2CAL_output_clock(0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UInt8 SendI2CData( UInt8 inData )
+ *
+ * Sends a byte of data on the I2C bus and returns the TRUE if the slave
+ * ACK'dthe data.
+ *
+ * Input: inData - the byte of data to send
+ * Output: (return) - TRUE (1) if ACK was received, FALSE (0) if not
+ *
+ *----------------------------------------------------------------------
+ */
+void
+SendI2CData(unsigned char inData)
+{
+ unsigned char bit;
+
+ /* Send all 8 bits of data byte, MSB to LSB */
+ for (bit = 0x80; bit != 0; bit >>= 1) {
+ if (inData & bit)
+ I2CAL_output_data(1);
+ else
+ I2CAL_output_data(0);
+
+ I2CAL_output_clock(1);
+ I2CAL_output_clock(0);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UInt8 ReceiveI2CAck( )
+ *
+ * Receives the Ack (or Nack) from the slave.
+ *
+ * Output: (return) - TRUE (1) if ACK was received, FALSE (0) if not
+ *
+ *----------------------------------------------------------------------
+ */
+unsigned char
+ReceiveI2CAck(void)
+{
+ unsigned char bit;
+
+ /* Test for Ack/Nack */
+ I2CAL_set_data_for_input();
+ I2CAL_output_data(1);
+ I2CAL_output_clock(1);
+ bit = I2CAL_input_data();
+ I2CAL_output_clock(0);
+ I2CAL_set_data_for_output();
+ return !bit;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * unsigned char ReceiveI2CData(void)
+ *
+ * Receives a byte of data from the I2C bus.
+ *
+ * Output: (return) - The data byte recehved from the bus
+ *
+ *----------------------------------------------------------------------
+ */
+unsigned char
+ReceiveI2CData(void)
+{
+ unsigned char data = 0;
+ unsigned char x;
+
+ /* make sure the data line is released */
+ I2CAL_set_data_for_input();
+ I2CAL_output_data(1);
+
+ /* shift in the data */
+ for (x = 0; x < 8; x++) {
+ /* shift the data left */
+ I2CAL_output_clock(1);
+ data <<= 1;
+ data |= I2CAL_input_data();
+ I2CAL_output_clock(0);
+ }
+
+ I2CAL_set_data_for_output();
+ I2CAL_output_data(1);
+ return data;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * void I2C_init(void)
+ *
+ * This routine initializes the I2C interface. Clients of the I2C.c
+ * will call this routine before calling any other routine in the I2C.c
+ *
+ *----------------------------------------------------------------------
+ */
+
+#if GFX_I2C_DYNAMIC
+int
+gpio_i2c_init(void)
+#else
+int
+gfx_i2c_init(void)
+#endif
+{
+ int errc;
+
+ /* init I2CAL */
+ errc = I2CAL_init();
+ if (errc)
+ return errc;
+
+ /* set the clock and data lines to the proper states */
+ I2CAL_output_clock(1);
+ I2CAL_output_data(1);
+ I2CAL_set_data_for_output();
+
+ SendI2CStart();
+ SendI2CStop();
+ SendI2CStop();
+
+ g_initialized = 1;
+
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * void I2C_cleanup(void)
+ *
+ * This routine disables the I2C interface. Clients of the I2C.c will not
+ * call any other I2C routine after calling this routine.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#if GFX_I2C_DYNAMIC
+void
+gpio_i2c_cleanup(void)
+#else
+void
+gfx_i2c_cleanup(void)
+#endif
+{
+ if (g_initialized) {
+
+ /* set the clock and data lines to a harmless state */
+ I2CAL_output_clock(1);
+ I2CAL_output_data(1);
+
+ g_initialized = 0;
+ }
+
+ I2CAL_cleanup();
+}
+
+int
+I2CAL_init(void)
+{
+ unsigned long l_reg;
+ unsigned short reg;
+
+ /* initialize the i2c port. */
+ l_reg = gfx_pci_config_read(CS5530_GPIO);
+
+ if (l_reg != 0x01001078)
+ return 1;
+
+ l_reg = gfx_pci_config_read(CS5530_GPIO);
+ reg = (unsigned short)l_reg;
+
+ /* both outputs, both high. */
+ reg |= (SDADIR | SCLDIR | SDA | SCL);
+ l_reg = reg;
+ gfx_pci_config_write(CS5530_GPIO, l_reg);
+
+ g_initialized = 1;
+
+ return 0;
+}
+
+void
+I2CAL_cleanup(void)
+{
+ if (g_initialized) {
+
+ g_initialized = 0;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * set the I2C clock line state
+ *
+ *----------------------------------------------------------------------------
+ */
+void
+I2CAL_output_clock(int inState)
+{
+ unsigned short reg;
+ unsigned long value;
+
+ value = gfx_pci_config_read(CS5530_GPIO);
+ reg = (unsigned short)value;
+
+ if (inState) { /* write a 1. */
+ reg |= SCL;
+ } else { /* write a 0. */
+ reg &= ~SCL;
+ }
+
+ value = reg;
+ gfx_pci_config_write(CS5530_GPIO, value);
+
+ /* hold it for a minimum of 4.7us */
+ gfx_delay_microseconds(5);
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * set the I2C data line state
+ *
+ *----------------------------------------------------------------------------
+ */
+void
+I2CAL_output_data(int inState)
+{
+ unsigned short reg;
+ unsigned long value;
+
+ value = gfx_pci_config_read(CS5530_GPIO);
+ reg = (unsigned short)value;
+
+ if (inState) { /* write a 1. */
+ reg |= SDA;
+ } else {
+ /* write a 0. */
+ reg &= ~SDA;
+ }
+ value = reg;
+ gfx_pci_config_write(CS5530_GPIO, value);
+
+ /* 250 ns setup time */
+ gfx_delay_microseconds(1);
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * read the state of the data line
+ *
+ *----------------------------------------------------------------------------
+ */
+unsigned char
+I2CAL_input_data(void)
+{
+ unsigned short reg;
+ unsigned long value;
+
+ value = gfx_pci_config_read(CS5530_GPIO);
+ reg = (unsigned short)value;
+
+ if (reg & SDA)
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * set the I2C data for input mode
+ *
+ *----------------------------------------------------------------------------
+ */
+void
+I2CAL_set_data_for_input(void)
+{
+ unsigned short reg;
+ unsigned long value;
+
+ value = gfx_pci_config_read(CS5530_GPIO);
+ reg = (unsigned short)value;
+
+ reg &= ~SDADIR;
+
+ value = reg;
+
+ gfx_pci_config_write(CS5530_GPIO, value);
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * set the I2C data for output mode
+ *
+ *----------------------------------------------------------------------------
+ */
+void
+I2CAL_set_data_for_output(void)
+{
+ unsigned short reg;
+ unsigned long value;
+
+ value = gfx_pci_config_read(CS5530_GPIO);
+ reg = (unsigned short)value;
+ reg |= SDADIR;
+ value = reg;
+
+ gfx_pci_config_write(CS5530_GPIO, value);
+
+}
+
+/* END OF FILE */
diff --git a/src/gfx/init_gu1.c b/src/gfx/init_gu1.c
new file mode 100644
index 0000000..e7d9987
--- /dev/null
+++ b/src/gfx/init_gu1.c
@@ -0,0 +1,265 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines used in the initialization of Geode-family
+ * processors.
+ * */
+
+/*----------------------------------------------------------------------------
+ * gfx_gxm_config_read
+ *
+ * This routine reads the value of the specified GXm configuration register.
+ *----------------------------------------------------------------------------
+ */
+unsigned char
+gfx_gxm_config_read(unsigned char index)
+{
+ unsigned char value = 0xFF;
+ unsigned char lock;
+
+ OUTB(0x22, GXM_CONFIG_CCR3);
+ lock = INB(0x23);
+ OUTB(0x22, GXM_CONFIG_CCR3);
+ OUTB(0x23, (unsigned char)(lock | 0x10));
+ OUTB(0x22, index);
+ value = INB(0x23);
+ OUTB(0x22, GXM_CONFIG_CCR3);
+ OUTB(0x23, lock);
+ return (value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_core_freq
+ *
+ * This routine returns the core clock frequency of a GXm if valid jumper
+ * settings are detected; 0 It assumes that a 33.3 MHz PCI clock is being used
+ * for GX1.
+ * For SCx2xx, the fast PCI divisor is read.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu1_get_core_freq(void)
+#else
+unsigned long
+gfx_get_core_freq(void)
+#endif
+{
+ unsigned char dir0, dir1;
+ unsigned long cpu_speed;
+
+ dir0 = gfx_gxm_config_read(GXM_CONFIG_DIR0) & 0x0F;
+ dir1 = gfx_gxm_config_read(GXM_CONFIG_DIR1);
+
+ /* REVISION 4.0 AND UP */
+
+ if (dir1 >= 0x50) {
+ switch (dir0) {
+ case 0:
+ case 2:
+ cpu_speed = 133;
+ break;
+ case 5:
+ cpu_speed = 166;
+ break;
+ case 3:
+ cpu_speed = 200;
+ break;
+ case 6:
+ cpu_speed = 233;
+ break;
+ case 7:
+ cpu_speed = 266;
+ break;
+ case 4:
+ cpu_speed = 300;
+ break;
+ case 1:
+ cpu_speed = 333;
+ break;
+ default:
+ return (0);
+ }
+ } else {
+ switch (dir0) {
+ case 0:
+ case 2:
+ cpu_speed = 133;
+ break;
+ case 7:
+ cpu_speed = 166;
+ break;
+ case 1:
+ case 3:
+ cpu_speed = 200;
+ break;
+ case 4:
+ case 6:
+ cpu_speed = 233;
+ break;
+ case 5:
+ cpu_speed = 266;
+ break;
+ default:
+ return (0);
+ }
+ }
+
+ if ((gfx_cpu_version & 0xFF) == GFX_CPU_SC1200) {
+ cpu_speed = (cpu_speed * gfx_pci_speed_khz) / 33300;
+ }
+ return (cpu_speed);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cpu_register_base
+ *
+ * This routine returns the base address for graphics registers.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu1_get_cpu_register_base(void)
+#else
+unsigned long
+gfx_get_cpu_register_base(void)
+#endif
+{
+ unsigned long base;
+
+ base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR);
+ base = (base & 0x03) << 30;
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_base
+ *
+ * This routine returns the base address for graphics memory. This is an
+ * offset of 0x00800000 from the base address specified in the GCR register.
+ *
+ * The function returns zero if the GCR indicates the graphics subsystem
+ * is disabled.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu1_get_frame_buffer_base(void)
+#else
+unsigned long
+gfx_get_frame_buffer_base(void)
+#endif
+{
+ unsigned long base;
+
+ base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR);
+ base = (base & 0x03) << 30;
+ if (base)
+ base |= 0x00800000;
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_size
+ *
+ * This routine returns the total size of graphics memory, in bytes.
+ *
+ * Currently this routine is hardcoded to return 2 Meg.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu1_get_frame_buffer_size(void)
+#else
+unsigned long
+gfx_get_frame_buffer_size(void)
+#endif
+{
+#if FB4MB
+ return (0x00400000);
+#else
+ return (0x00200000);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vid_register_base
+ *
+ * This routine returns the base address for the video hardware. It assumes
+ * an offset of 0x00010000 from the base address specified by the GCR.
+ *
+ * The function returns zero if the GCR indicates the graphics subsystem
+ * is disabled.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu1_get_vid_register_base(void)
+#else
+unsigned long
+gfx_get_vid_register_base(void)
+#endif
+{
+ unsigned long base;
+
+ base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR);
+ base = (base & 0x03) << 30;
+ if (base)
+ base |= 0x00010000;
+ return (base);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_register_base
+ *
+ * This routine returns the base address for the VIP hardware. This is
+ * only applicable to the SC1200, for which this routine assumes an offset
+ * of 0x00015000 from the base address specified by the GCR.
+ *
+ * The function returns zero if the GCR indicates the graphics subsystem
+ * is disabled.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu1_get_vip_register_base(void)
+#else
+unsigned long
+gfx_get_vip_register_base(void)
+#endif
+{
+ unsigned long base = 0;
+
+ if ((gfx_cpu_version & 0xFF) == GFX_CPU_SC1200) {
+ base = (unsigned long)gfx_gxm_config_read(GXM_CONFIG_GCR);
+ base = (base & 0x03) << 30;
+ if (base)
+ base |= 0x00015000;
+ }
+ return (base);
+}
+
+/* END OF FILE */
diff --git a/src/gfx/init_gu2.c b/src/gfx/init_gu2.c
new file mode 100644
index 0000000..0bbb064
--- /dev/null
+++ b/src/gfx/init_gu2.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines used in Redcloud initialization.
+ * */
+
+/*----------------------------------------------------------------------------
+ * gfx_get_core_freq
+ *
+ * Returns the core clock frequency of a GX2.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu2_get_core_freq(void)
+#else
+unsigned long
+gfx_get_core_freq(void)
+#endif
+{
+ unsigned long value;
+
+ /* CPU SPEED IS REPORTED BY A VSM IN VSA II */
+ /* Virtual Register Class = 0x12 (Sysinfo) */
+ /* CPU Speed Register = 0x01 */
+
+ OUTW(0xAC1C, 0xFC53);
+ OUTW(0xAC1C, 0x1201);
+
+ value = (unsigned long)(INW(0xAC1E));
+
+ return (value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cpu_register_base
+ *
+ * This routine returns the base address for display controller registers.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu2_get_cpu_register_base(void)
+#else
+unsigned long
+gfx_get_cpu_register_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x80000918);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_graphics_register_base
+ *
+ * This routine returns the base address for the graphics acceleration.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu2_get_graphics_register_base(void)
+#else
+unsigned long
+gfx_get_graphics_register_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x80000914);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_base
+ *
+ * This routine returns the base address for graphics memory.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu2_get_frame_buffer_base(void)
+#else
+unsigned long
+gfx_get_frame_buffer_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x80000910);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_size
+ *
+ * This routine returns the total size of graphics memory, in bytes.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu2_get_frame_buffer_size(void)
+#else
+unsigned long
+gfx_get_frame_buffer_size(void)
+#endif
+{
+ unsigned long value;
+
+ /* FRAME BUFFER SIZE IS REPORTED BY A VSM IN VSA II */
+ /* Virtual Register Class = 0x02 */
+ /* VG_MEM_SIZE (512KB units) = 0x00 */
+
+ OUTW(0xAC1C, 0xFC53);
+ OUTW(0xAC1C, 0x0200);
+
+ value = (unsigned long)(INW(0xAC1E)) & 0xFFl;
+
+ return (value << 19);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vid_register_base
+ *
+ * This routine returns the base address for the video hardware.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu2_get_vid_register_base(void)
+#else
+unsigned long
+gfx_get_vid_register_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x8000091C);
+}
+
+/* END OF FILE */
diff --git a/src/gfx/init_gu3.c b/src/gfx/init_gu3.c
new file mode 100644
index 0000000..daf1513
--- /dev/null
+++ b/src/gfx/init_gu3.c
@@ -0,0 +1,159 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines used in Redcloud initialization.
+ * */
+
+/*----------------------------------------------------------------------------
+ * gfx_get_core_freq
+ *
+ * Returns the core clock frequency of a GX3.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu3_get_core_freq(void)
+#else
+unsigned long
+gfx_get_core_freq(void)
+#endif
+{
+ unsigned long value;
+
+ /* CPU SPEED IS REPORTED BY A VSM IN VSA II */
+ /* Virtual Register Class = 0x12 (Sysinfo) */
+ /* CPU Speed Register = 0x01 */
+
+ OUTW(0xAC1C, 0xFC53);
+ OUTW(0xAC1C, 0x1201);
+
+ value = (unsigned long)(INW(0xAC1E));
+
+ return (value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_cpu_register_base
+ *
+ * This routine returns the base address for display controller registers.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu3_get_cpu_register_base(void)
+#else
+unsigned long
+gfx_get_cpu_register_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x80000918);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_graphics_register_base
+ *
+ * This routine returns the base address for the graphics acceleration.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu3_get_graphics_register_base(void)
+#else
+unsigned long
+gfx_get_graphics_register_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x80000914);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_base
+ *
+ * This routine returns the base address for graphics memory.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu3_get_frame_buffer_base(void)
+#else
+unsigned long
+gfx_get_frame_buffer_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x80000910);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_size
+ *
+ * This routine returns the total size of graphics memory, in bytes.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu3_get_frame_buffer_size(void)
+#else
+unsigned long
+gfx_get_frame_buffer_size(void)
+#endif
+{
+ unsigned long value;
+
+ /* FRAME BUFFER SIZE IS REPORTED BY A VSM IN VSA II */
+ /* Virtual Register Class = 0x02 */
+ /* VG_MEM_SIZE (1MB units) = 0x00 */
+
+ OUTW(0xAC1C, 0xFC53);
+ OUTW(0xAC1C, 0x0200);
+
+ value = (unsigned long)(INW(0xAC1E)) & 0xFEl;
+
+ /* LIMIT FRAME BUFFER SIZE TO 16MB TO MATCH LEGACY */
+
+ if ((value << 20) > 0x1000000)
+ return 0x1000000;
+
+ return (value << 20);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vid_register_base
+ *
+ * This routine returns the base address for the video hardware.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long
+gu3_get_vid_register_base(void)
+#else
+unsigned long
+gfx_get_vid_register_base(void)
+#endif
+{
+ return gfx_pci_config_read(0x8000091C);
+}
+
+/* END OF FILE */
diff --git a/src/gfx/msr_rdcl.c b/src/gfx/msr_rdcl.c
new file mode 100644
index 0000000..8c927a4
--- /dev/null
+++ b/src/gfx/msr_rdcl.c
@@ -0,0 +1,632 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains MSR access routines for Redcloud.
+ * */
+
+void redcloud_build_mbus_tree(void); /* private routine definition */
+int redcloud_init_msr_devices(MSR aDev[], unsigned int array_size);
+
+ /* private routine definition */
+DEV_STATUS redcloud_find_msr_device(MSR * pDev);
+
+ /* private routine definition */
+
+/* REDCLOUD MSR BITMASKS */
+
+#define MBD_MSR_CAP 0x2000
+#define MSR_CAP_ID_MASK 0xFF000
+#define MSR_CAP_ID_SHIFT 12
+#define MSR_CAP_REV_MASK 0x0F
+#define MBIU_CAP 0x86
+#define NUM_PORTS_MASK 0x00380000
+#define NUM_PORTS_SHIFT 19
+#define MBIU_WHOAMI 0x8B
+#define WHOAMI_MASK 0x07
+
+/* REDCLOUD and CS5535 MSR DEVICES */
+
+MSR msrDev[] = {
+ {FOUND, RC_CC_MBIU, RC_MB0_MBIU0},
+ {FOUND, RC_CC_MBIU, RC_MB0_MBIU1},
+ {NOT_KNOWN, RC_CC_MCP, FAKE_ADDRESS},
+ {NOT_KNOWN, RC_CC_MPCI, FAKE_ADDRESS},
+ {NOT_KNOWN, RC_CC_MC, FAKE_ADDRESS},
+ {NOT_KNOWN, RC_CC_GP, FAKE_ADDRESS},
+ {NOT_KNOWN, RC_CC_VG, FAKE_ADDRESS},
+ {NOT_KNOWN, RC_CC_DF, FAKE_ADDRESS},
+ {NOT_KNOWN, RC_CC_FG, FAKE_ADDRESS},
+ {FOUND, RC_CC_VA, RC_MB0_CPU},
+ {FOUND, CP_CC_MBIU, CP_MB0_MBIU0},
+ {NOT_KNOWN, CP_CC_MPCI, FAKE_ADDRESS},
+ {NOT_KNOWN, CP_CC_USB2, FAKE_ADDRESS},
+ {NOT_KNOWN, CP_CC_ATAC, FAKE_ADDRESS},
+ {NOT_KNOWN, CP_CC_MDD, FAKE_ADDRESS},
+ {NOT_KNOWN, CP_CC_ACC, FAKE_ADDRESS},
+ {NOT_KNOWN, CP_CC_USB1, FAKE_ADDRESS},
+ {NOT_KNOWN, CP_CC_MCP, FAKE_ADDRESS},
+};
+
+#define NUM_DEVS sizeof(msrDev) / sizeof(struct msr)
+
+/* CAPISTRANO DEVICE INDEX LIMITS */
+/* These defines represent the start and stop indexes into the device array
+ * for all Capistrano devices. These should be updated whenever a device is
+ * added or removed to the Capistrano list.
+ * */
+
+#define CP_INDEX_START CP_ID_MBIU
+#define CP_INDEX_STOP CP_ID_MCP
+
+/* GLOBAL MBUS CACHE STRUCTURES */
+/* These structures contain a "cached" copy of the MBUS topology */
+/* for easy future lookup. */
+
+MBUS_NODE MBIU0[8], MBIU1[8], MBIU2[8];
+
+/* REGISTER MACROS */
+
+#define GET_DEVICE_ID( CAPABILITIES_HIGH, CAPABILITIES_LOW ) \
+ ((unsigned int)(( (CAPABILITIES_LOW) & MSR_CAP_ID_MASK ) >> MSR_CAP_ID_SHIFT ))
+
+#define GET_NUM_PORTS( MBIU_CAP_HIGH, MBIU_CAP_LOW ) (((MBIU_CAP_HIGH) & NUM_PORTS_MASK ) >> NUM_PORTS_SHIFT)
+
+/*----------------------------------------------------------------------------
+ * gfx_msr_init
+ *
+ * This routine initializes the base addresses of all known MBUS devices.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_MSR_DYNAMIC
+int
+redcloud_msr_init(void)
+#else
+int
+gfx_msr_init(void)
+#endif
+{
+ Q_WORD msrValue;
+ int return_value = 1;
+
+ /* CHECK FOR VALID MBUS CONFIGURATION */
+ /* The CPU and the two MBIUs are assumed to be at known static addresses,
+ * so we will check the device IDs at these addresses as proof of a valid
+ * mbus configuration.
+ * */
+
+ MSR_READ(MBD_MSR_CAP, RC_MB0_CPU, &(msrValue.high), &(msrValue.low));
+ if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_VA)
+ return_value = 0;
+
+ MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
+ if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU)
+ return_value = 0;
+
+ MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
+ if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU)
+ return_value = 0;
+
+ /* ENUMERATE VALID BUS */
+ /* If all static devices were identified, continue with the enumeration */
+
+ if (return_value) {
+ /* OPTIMIZATION */
+ /* Build a local copy of the MBUS topology. This allows us to */
+ /* quickly search the entire MBUS for a given device ID without */
+ /* repeated MSR accesses. */
+
+ redcloud_build_mbus_tree();
+
+ /* INITIALIZE MSR DEVICES */
+
+ return_value = redcloud_init_msr_devices(msrDev, NUM_DEVS);
+
+ }
+
+ return return_value;
+
+}
+
+/*--------------------------------------------------------------------------
+ * void redcloud_build_mbus_tree() (PRIVATE ROUTINE - NOT PART OF DURANGO API)
+ *
+ * This routine walks through the MBUS and records the address value and
+ * device ID found at each node. If a node (aka port) is not populated,
+ * that node returns '0'. The deviceID for that node is set to '0'
+ * (NOT_POPULATED) to reflect this. If the node being queried points back to
+ * Vail or MBIU0, the deviceID for that node is set to 'REFLECTIVE'.
+ * Reflective nodes are nodes that forward the given MBUS address BACK to the
+ * initiator.
+ *----------------------------------------------------------------------------
+ */
+void
+redcloud_build_mbus_tree(void)
+{
+ unsigned long mbiu_port_count, reflective;
+ unsigned long port;
+ Q_WORD msrValue;
+
+ /* */
+ /* ENUMERATE MBIU0 */
+ /* */
+
+ /* COUNT MBIU PORTS */
+
+ MSR_READ(MBIU_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
+ mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
+
+ /* FIND REFLECTIVE PORT */
+ /* Query the MBIU for the port through which we are communicating. */
+ /* We will avoid accesses to this port to avoid a self-reference. */
+
+ MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
+ reflective = msrValue.low & WHOAMI_MASK;
+
+ /* ENUMERATE ALL PORTS */
+ /* For every possible port, set the MBIU.deviceId to something. */
+
+ for (port = 0; port < 8; port++) {
+ /* FILL IN CLAIMED FIELD */
+ /* All MBIU ports can only be assigned to one device from the */
+ /* Durango table */
+
+ MBIU0[port].claimed = 0;
+
+ /* MBIU0 PORT NUMBERS ARE IN ADDRESS BITS 31:29 */
+
+ MBIU0[port].address = port << 29;
+
+ /* SPECIAL CASE FOR MBIU0 */
+ /* MBIU0 port 0 is a special case, as it points back to MBIU0. MBIU0
+ * responds at address 0x40000xxx, which does not equal 0 << 29.
+ * */
+
+ if (port == 0)
+ MBIU0[port].deviceId = RC_CC_MBIU;
+ else if (port == reflective)
+ MBIU0[port].deviceId = REFLECTIVE;
+ else if (port > mbiu_port_count)
+ MBIU0[port].deviceId = NOT_POPULATED;
+ else {
+ MSR_READ(MBD_MSR_CAP, MBIU0[port].address, &(msrValue.high),
+ &(msrValue.low));
+ MBIU0[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low);
+ }
+ }
+
+ /* */
+ /* ENUMERATE MBIU1 */
+ /* */
+
+ /* COUNT MBIU PORTS */
+
+ MSR_READ(MBIU_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
+ mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
+
+ /* FIND REFLECTIVE PORT */
+ /* Query the MBIU for the port through which we are communicating. */
+ /* We will avoid accesses to this port to avoid a self-reference. */
+
+ MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
+ reflective = msrValue.low & WHOAMI_MASK;
+
+ /* ENUMERATE ALL PORTS */
+ /* For every possible port, set the MBIU.deviceId to something. */
+
+ for (port = 0; port < 8; port++) {
+ /* FILL IN CLAIMED FIELD */
+ /* All MBIU ports can only be assigned to one device from the */
+ /* Durango table */
+
+ MBIU1[port].claimed = 0;
+
+ /* MBIU1 PORT NUMBERS ARE IN 28:26 AND 31:29 = 010B */
+
+ MBIU1[port].address = (0x02l << 29) + (port << 26);
+
+ if (port == reflective)
+ MBIU1[port].deviceId = REFLECTIVE;
+ else if (port > mbiu_port_count)
+ MBIU1[port].deviceId = NOT_POPULATED;
+ else {
+ MSR_READ(MBD_MSR_CAP, MBIU1[port].address, &(msrValue.high),
+ &(msrValue.low));
+ MBIU1[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low);
+ }
+ }
+
+ /* */
+ /* ENUMERATE MBIU2 (CS5535) */
+ /* (if present) */
+
+ MSR_READ(MBD_MSR_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
+ if (GET_DEVICE_ID(msrValue.high, msrValue.low) == CP_CC_MBIU) {
+ /* COUNT MBIU PORTS */
+
+ MSR_READ(MBIU_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
+ mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
+
+ /* FIND REFLECTIVE PORT */
+ /* Query the MBIU for the port through which we are communicating. */
+ /* We will avoid accesses to this port to avoid a self-reference. */
+
+ MSR_READ(MBIU_WHOAMI, CP_MB0_MBIU0, &(msrValue.high),
+ &(msrValue.low));
+ reflective = msrValue.low & WHOAMI_MASK;
+
+ /* ENUMERATE ALL PORTS */
+ /* For every possible port, set the MBIU.deviceId to something. */
+
+ for (port = 0; port < 8; port++) {
+ /* FILL IN CLAIMED FIELD */
+ /* All MBIU ports can only be assigned to one device from the */
+ /* Durango table */
+
+ MBIU2[port].claimed = 0;
+
+ /* MBIU2 PORT NUMBERS ARE IN 22:20 AND 31:23 = 010100010B */
+
+ MBIU2[port].address =
+ (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
+
+ if (port == reflective)
+ MBIU2[port].deviceId = REFLECTIVE;
+ else if (port > mbiu_port_count)
+ MBIU2[port].deviceId = NOT_POPULATED;
+ else {
+ MSR_READ(MBD_MSR_CAP, MBIU2[port].address, &(msrValue.high),
+ &(msrValue.low));
+ MBIU2[port].deviceId =
+ GET_DEVICE_ID(msrValue.high, msrValue.low);
+ }
+ }
+ } else {
+ /* NO 5535 */
+ /* If the CS5535 is not installed, fill in the cached table */
+ /* with the 'NOT_INSTALLED' flag. Also, fill in the device */
+ /* status from NOT_KNOWN to REQ_NOT_INSTALLED. */
+
+ for (port = 0; port < 8; port++) {
+ MBIU2[port].claimed = 0;
+ MBIU2[port].deviceId = NOT_INSTALLED;
+ MBIU2[port].address =
+ (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
+ }
+ for (port = CP_INDEX_START; port <= CP_INDEX_STOP; port++) {
+ msrDev[port].Present = REQ_NOT_INSTALLED;
+ }
+ }
+}
+
+/*------------------------------------------------------------------
+ * redcloud_init_msr_devices (PRIVATE ROUTINE - NOT PART OF DURANGO API)
+ *
+ * Handles the details of finding each possible device on the MBUS.
+ * If a given device is not found, its structure is left uninitialized.
+ * If a given device is found, its structure is updated.
+ *
+ * This init routine only checks for devices in aDev[].
+ *
+ * Passed:
+ * aDev - is a pointer to the array of MBUS devices.
+ * arraySize - number of elements in aDev.
+ *
+ * Returns:
+ * 1 - If, for every device, its address was found.
+ * 0 - If, for any device, an error was encountered.
+ *------------------------------------------------------------------
+ */
+int
+redcloud_init_msr_devices(MSR aDev[], unsigned int array_size)
+{
+ unsigned int i, issues = 0;
+
+ /* TRY TO FIND EACH ITEM IN THE ARRAY */
+
+ for (i = 0; i < array_size; i++) {
+ /* IGNORE DEVICES THAT ARE ALREADY FOUND */
+ /* The addresses for "found" devices are already known. */
+
+ if (aDev[i].Present == FOUND || aDev[i].Present == REQ_NOT_INSTALLED)
+ continue;
+
+ /* TRY TO FIND THE DEVICE ON THE MBUS */
+
+ aDev[i].Present = redcloud_find_msr_device(&aDev[i]);
+
+ /* INCREMENT ERROR COUNT IF DEVICE NOT FOUND */
+
+ if (aDev[i].Present != FOUND)
+ issues++;
+ }
+
+ return (issues == 0);
+}
+
+/*------------------------------------------------------------------
+ * redcloud_find_msr_device (PRIVATE ROUTINE - NOT PART OF DURANGO API)
+ *
+ * Passed:
+ * pDev - is a pointer to one element in the array of MBUS devices
+ *
+ * Returns:
+ * FOUND - Device was found and pDev->Address has been updated.
+ *
+ * REQ_NOT_FOUND - Device was not found and pDev->Address has not
+ * been updated.
+ *
+ *------------------------------------------------------------------
+ */
+DEV_STATUS
+redcloud_find_msr_device(MSR * pDev)
+{
+ unsigned int i;
+
+ /* SEARCH DURANGO'S CACHED MBUS TOPOLOGY */
+ /* This gets a little tricky. As the only identifier we have for each
+ * device is the device ID and we have multiple devices of the same type
+ * MCP, MPCI, USB, etc. we need to make some assumptions based on table
+ * order. These are as follows:
+ * 1. All Redcloud nodes are searched first, as we assume that they
+ * are first in the table.
+ * 2. If two devices have the same device ID and are found on the same
+ * device (GX2, CS5535, etc.) we assume that they are listed such
+ * that the first device in the table with this device ID has a lower
+ * port address.
+ * 3. After a device ID has been matched, the port is marked as
+ * 'claimed', such that future enumerations continue searching the
+ * GeodeLink topology.
+ */
+
+ /* SEARCH MBIU0 */
+
+ for (i = 0; i < 8; i++) {
+ if (MBIU0[i].deviceId == pDev->Id && !(MBIU0[i].claimed)) {
+ MBIU0[i].claimed = 1;
+ pDev->Address = MBIU0[i].address;
+ return FOUND;
+ }
+ }
+
+ /* SEARCH MBIU1 */
+
+ for (i = 0; i < 8; i++) {
+ if (MBIU1[i].deviceId == pDev->Id && !(MBIU1[i].claimed)) {
+ MBIU1[i].claimed = 1;
+ pDev->Address = MBIU1[i].address;
+ return FOUND;
+ }
+ }
+
+ /* SEARCH MBIU2 */
+
+ for (i = 0; i < 8; i++) {
+ if (MBIU2[i].deviceId == pDev->Id && !(MBIU2[i].claimed)) {
+ MBIU2[i].claimed = 1;
+ pDev->Address = MBIU2[i].address;
+ return FOUND;
+ }
+ }
+
+ return REQ_NOT_FOUND;
+}
+
+/*--------------------------------------------------------------------
+ * gfx_id_msr_device
+ *
+ * This routine handles reading the capabilities MSR register (typically
+ * 0x2000) and checking if the 'id' field matchs pDev.Id. This routine is
+ * used by applications/drivers that need to extend the list of known
+ * MBUS devices beyond those known by Durango.
+ *
+ * Passed:
+ * pDev - Pointer to MSR structure containing the device's ID.
+ * address - device address.
+ *
+ * Returns:
+ * FOUND - The IDs do match.
+ * REQ_NOT_FOUND - There was not a match.
+ *
+ *--------------------------------------------------------------------
+ */
+#if GFX_MSR_DYNAMIC
+DEV_STATUS
+redcloud_id_msr_device(MSR * pDev, unsigned long address)
+#else
+DEV_STATUS
+gfx_id_msr_device(MSR * pDev, unsigned long address)
+#endif
+{
+ Q_WORD msrValue;
+
+ MSR_READ(MBD_MSR_CAP, address, &(msrValue.high), &(msrValue.low));
+
+ if (GET_DEVICE_ID(msrValue.high, msrValue.low) == pDev->Id)
+ return FOUND;
+ else
+ return REQ_NOT_FOUND;
+}
+
+/*--------------------------------------------------------------------
+ * gfx_get_msr_dev_address
+ *
+ * This function returns the 32-bit address of the requested device.
+ * The device must be a known MBUS device. (It must be in Durango's
+ * device table.) DEV_STATUS should be checked to verify that the address
+ * was updated.
+ *
+ *
+ * Passed:
+ * device - device index of the device in question.
+ * *address - ptr to location where address should be stored.
+ *
+ * Returns:
+ * DEV_STATUS of device in question. (NOT_KNOWN if device is out of range.)
+ * *address - updated if 'device' is within range
+ *
+ * Notes:
+ * This function should only be called after gfx_msr_init
+ *
+ *--------------------------------------------------------------------
+ */
+#if GFX_MSR_DYNAMIC
+DEV_STATUS
+redcloud_get_msr_dev_address(unsigned int device, unsigned long *address)
+#else
+DEV_STATUS
+gfx_get_msr_dev_address(unsigned int device, unsigned long *address)
+#endif
+{
+ if (device < NUM_DEVS) {
+ if (msrDev[device].Present == FOUND)
+ *address = msrDev[device].Address;
+
+ return msrDev[device].Present;
+ }
+ return NOT_KNOWN;
+
+}
+
+/*--------------------------------------------------------------------
+ * gfx_get_glink_id_at_address
+ *
+ * This function returns the 16-bit deviceId at the requested address.
+ * DEV_STATUS should be checked to make sure that device was updated.
+ *
+ * Passed:
+ * device - ptr to location where device ID should be stored.
+ * address - address of desired device ID.
+ *
+ * Returns:
+ * FOUND if address is a valid address, NOT_KNOWN if address cannot be
+ * found on the mbus.
+ * *device - updated with device Id info.
+ *
+ * Notes:
+ * This function should be called after gfx_msr_init
+ *
+ *--------------------------------------------------------------------
+ */
+#if GFX_MSR_DYNAMIC
+DEV_STATUS
+redcloud_get_glink_id_at_address(unsigned int *device, unsigned long address)
+#else
+DEV_STATUS
+gfx_get_glink_id_at_address(unsigned int *device, unsigned long address)
+#endif
+{
+ int port;
+
+ for (port = 0; port < 8; port++) {
+ if (MBIU0[port].address == address) {
+ *device = MBIU0[port].deviceId;
+ return FOUND;
+ } else if (MBIU1[port].address == address) {
+ *device = MBIU1[port].deviceId;
+ return FOUND;
+ } else if (MBIU2[port].address == address) {
+ *device = MBIU2[port].deviceId;
+ return FOUND;
+ }
+ }
+
+ return NOT_KNOWN;
+
+}
+
+/*--------------------------------------------------------------------
+ * gfx_msr_read
+ *
+ * Performs a 64-bit read from 'msrRegister' in device 'device'. 'device' is
+ * an index into Durango's table of known MBUS devices.
+ *
+ * Returns:
+ * FOUND - if no errors were detected and msrValue has been
+ * updated.
+ * NOT_KNOWN - an error was detected. msrValue is not updated.
+ * REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller
+ * should call msrInit() first. msrValue is not
+ * updated.
+ * Notes:
+ * This function should be called after gfx_msr_init
+ *--------------------------------------------------------------------
+ */
+#if GFX_MSR_DYNAMIC
+DEV_STATUS
+redcloud_msr_read(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue)
+#else
+DEV_STATUS
+gfx_msr_read(unsigned int device, unsigned int msrRegister, Q_WORD * msrValue)
+#endif
+{
+ if (device < NUM_DEVS) {
+ if (msrDev[device].Present == FOUND)
+ MSR_READ(msrRegister, msrDev[device].Address, &(msrValue->high),
+ &(msrValue->low));
+
+ return msrDev[device].Present;
+ }
+ return NOT_KNOWN;
+}
+
+/*--------------------------------------------------------------------
+ * gfx_msr_write
+ *
+ * Performs a 64-bit write to 'msrRegister' in device 'devID'.
+ *
+ * Returns:
+ * FOUND - if no errors were detected and msrValue has been
+ * updated.
+ * NOT_KNOWN - an error was detected. msrValue is not updated.
+ * REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller
+ * should call msrInit() first. msrValue is not
+ * updated.
+ *
+ *Notes:
+ * This function is valid to call after initMSR_API()
+ *
+ *--------------------------------------------------------------------
+ */
+#if GFX_MSR_DYNAMIC
+DEV_STATUS
+redcloud_msr_write(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue)
+#else
+DEV_STATUS
+gfx_msr_write(unsigned int device, unsigned int msrRegister,
+ Q_WORD * msrValue)
+#endif
+{
+ if (device < NUM_DEVS) {
+ if (msrDev[device].Present == FOUND)
+ MSR_WRITE(msrRegister, msrDev[device].Address, &(msrValue->high),
+ &(msrValue->low));
+
+ return msrDev[device].Present;
+ }
+ return NOT_KNOWN;
+}
diff --git a/src/gfx/release.txt b/src/gfx/release.txt
new file mode 100644
index 0000000..805b847
--- /dev/null
+++ b/src/gfx/release.txt
@@ -0,0 +1,630 @@
+Durango Release Notes
+Version 2.57.00
+Win98/WinXP/DOS/Linux
+April 5, 2003
+
+-----------------------------------------------------------------------------
+PRODUCT INFORMATION
+-----------------------------------------------------------------------------
+Durango is a graphics/video software support package designed to assist in the
+development of display drivers and embedded applications. The core of this
+package is source code that performs most of the graphics related
+functionality for the National Semiconductor (c) Geode family of products.
+Development time for new software is reduced by using these routines to access
+the hardware.
+
+-----------------------------------------------------------------------------
+INSTALLATION INSTRUCTIONS
+-----------------------------------------------------------------------------
+Download the file to a directory. Modify and include the file durango.c
+according to the needs of the application.
+
+-----------------------------------------------------------------------------
+REVISION HISTORY
+-----------------------------------------------------------------------------
+
+04/05/04 Version 2.57.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Fixed the PLL setting for 1280x1024@70Hz and 1152x864@70Hz.
+
+=============================================================================
+
+03/30/04 Version 2.56.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Updated the GX2 render code such that BLTs that involve source will work
+ correctly even if source is not involved in the ROP.
+
+=============================================================================
+
+03/26/04 Version 2.55.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Filled in all missing refresh rates in the mode table for Redcloud and Castle.
+* Added a new routine gfx_is_panel_mode_supported.
+* Added new routines gfx_set_graphics_palette and gfx_set_graphics_palette_entry
+ to support using the video palette to gamma correct graphics data.
+
+=============================================================================
+
+03/11/04 Version 2.54.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Updated the video palette routines to clear the bypass both bit before
+ updating the palette.
+
+=============================================================================
+
+03/02/04 Version 2.53.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Added 1152x864@60, 85, 90 and 100Hz to the mode table.
+
+=============================================================================
+
+02/07/04 Version 2.52.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Updated Durango to support Castle, including a 48MHz dotref.
+* Added 90 and 100Hz modes for Redcloud.
+* Updated the PLL table to remove any pre-divides by 2.
+
+=============================================================================
+
+10/24/03 Version 2.51.08
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Removed GX2 1.0 support from the PLL routines, gfx_set_clock_frequency and
+ gfx_get_clock_frequency.
+* Fixed a bug in gfx_set_clock_frequency, wherein the last three PLL values in
+ Durango's PLL table could never be set.
+
+=============================================================================
+
+09/22/03 Version 2.51.07
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Changed gfx_set_video_palette and gfx_set_video_palette_entry such that calling
+ one of these routines will also configure the video hardware to route video
+ data through the DF palette RAM.
+* Added a new routine, gfx_set_video_palette_bypass to toggle the 'Bypass Both'
+ functionality of the SC1200 and GX2 palette RAMs.
+
+=============================================================================
+
+09/02/03 Version 2.51.06
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Added new routine gfx_get_max_video_width for SC1200 and CS5530. This routine
+ calculates the maximum theoretical video width based on the current display
+ mode and video clock.
+
+=============================================================================
+
+08/07/03 Version 2.51.05
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Fixed gfx_get_core_freq for SCx2xx when the fast PCI frequency is not 33MHz.
+* Fixed gfx_get_compression_pitch to mask correct bits.
+* Changed CS5530 and SCx2xx code to always enable video in the display
+ controller.
+* Modified GX2 PLL code to only update the PLL when the value has not already
+ been programmed.
+
+=============================================================================
+
+06/17/03 Version 2.51.04
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Fixed code to set default gamma RAM for SCx2xx.
+
+=============================================================================
+
+06/02/03 Version 2.51.03
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Fixed gfx_get_cursor_position for GX2 to support large display resolutions.
+* Added default gamma RAM table for SCx2xx and GX2 to correct CSC hardware.
+
+=============================================================================
+
+03/20/03 Version 2.51.02
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Changed all preprocessor statements to conform to K and R standard.
+* Added support for 56Hz modes to all Durango routines.
+* Added missing header file to gfx_priv.h
+
+=============================================================================
+
+03/13/03 Version 2.51.01
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Updated file headers to NSC standard headers.
+* Added routine definitions for private and local routines.
+* Minor fixes for compilation without warnings.
+* Fixed panel timings for 640x480 panels and 1024x768 panels.
+
+=============================================================================
+
+02/05/03 Version 2.49.02
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Fixed GX2 left clipping for 4:2:0 video.
+
+=============================================================================
+
+01/29/03 Version 2.49.01
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Removed unused variable in CS5530 video code.
+* Changed max supported pixel clock for SCx2xx to 157.5 MHz.
+
+=============================================================================
+
+01/10/03 Version 2.49.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Added extra wait loop when polling for CRC completion.
+* Removed code that sets the pitch offsets for 4:2:0 video within
+ gfx_set_video_size.
+* Fixed panning code to work with any display pitch.
+* Added code to clear the PLL bypass bit when setting the dot PLL.
+* Fixed panning code so cursor never disappears when panning.
+* Changed GX2 delay loops to do a volatile register read to prevent
+ the entire delay loop from being discarded by a compiler.
+
+=============================================================================
+
+11/19/02 Version 2.47.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Updated gfx2_* routines to use a signed stride.
+* SW workaround for issue #134.8 - Strange horizontal lines appearing while
+ drawing lines.
+* Implemented gfx_set_video_left_crop for CS5530
+* Updated sub carrier reset values for NTSC and PAL.
+
+=============================================================================
+
+08/29/02 Version 2.45.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Modified gfx_set_cursor_position to use cursor position when panning and not adjust
+ using hotspots.
+* Added new routine gfx_get_refreshrate_from_mode.
+* Added gfx_text_blt routine.
+* Added gfx_get_tv_display_mode_frequency routine.
+* Added gfx_get_frequency_from_refreshrate routine.
+* Added gfx_set_video_cursor_enable routine.
+* Fixed Linux compilation warnings.
+* Updated modeset code to clear panning variables.
+* Added panel timings for 1600x1200 desktops.
+* Removed wait for VBlank when panning using cursor routines.
+
+=============================================================================
+
+07/12/02 Version 2.43.03
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Modified gfx_get_display_mode to support 56 Hz modes.
+* Added support for 8K pitch when setting a true color mode above 1024x768
+* Added a byte-packed option to gfx2_mono_expand_blt
+* Fix for Carmel D2 alpha blending issue.
+* Added typecasts for proper compilation.
+* Fixed CS5535 MBIU address.
+* Added new GX2 routine, gfx2_text_blt
+* Added MSR implementations for Linux.
+* Further optimized default GX1 string macros.
+* Added new routine, gfx_set_panel_present to allow panning without adjusting panel timings.
+* Added assembly macros for 32-bit Windows applications.
+
+=============================================================================
+
+03/21/02 Version 2.41.02
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Optimized GX2 Bitmap-to-screen BLTs by using a 2-line offscreen scratch area.
+* Fixed a bug in GX2 monochrome bitmap BLTs.
+* Fixed gfx_get_clock_frequency for GX2 2.0
+* Added 56 Hz support to gfx_get_clock_frequency
+* Changed gfx_set_compression_size to subtract header size
+* Changed gfx_get_compression_size to add header size
+
+=============================================================================
+
+03/04/02 Version 2.39.01
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Added support for CS5535 MSRs.
+* Fixed a bug in monochrome bitmap BLTs.
+* Added support for 32-bit CRC mechanism in GX2 2.0.
+* First official GX2 release.
+* Added support for new Dot PLL mechanism in GX2 2.0
+* Added support for Carmel D1.1 and D2.
+
+=============================================================================
+
+01/24/02 Version 2.37.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* Changed gfx_get_clock_frequency, gfx_get_cursor_offset and gfx_get_display_offset
+ to be outside the GFX_READ_ROUTINES flag.
+* Modified the modeset code to set higher FIFO priority levels for high bandwidth
+ modes.
+* Init code no longer returns Redcloud ID when no chip detected.
+* Added fix for Redcloud 1.x rev ID
+* New GX2 PLL settings - updates to the 14 MHz table and a new 48 MHz table.
+* Optimized all bitmap-to-screen routines. Optimizations include new macros that
+ allow correct operation in a 16-bit environment.
+* 3K cache is now assumed to be the default scratchpad configuration.
+* gfx_get_frame_buffer_size for GX2 no longer uses a VGA register. This allows
+ correct operation even with an external VGA card present in the system.
+* Added support for 1152x864 desktop resolution on a flat panel.
+* Added 24BPP support for large display modes.
+* Modified gfx_set_video_scale such that an identity scale is now default.
+* Modifed flat panel modeset code to dynamically determine the size of the mode table.
+* Added support for Carmel Rev D2.
+
+=============================================================================
+
+10/22/01 Version 2.35.01
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+
+* New release notes format.
+* Added fix for SC1200 issue #813 (TVOut field indication is reversed.
+* Added check for invalid values in video upscale.
+* Fixed compilation warnings and run-time errors under DOS.
+* Added new macros for word I/O.
+* Optimized VSAII MSR code to used DWORD I/O.
+* Fixed SoftVG base PCI base addresses.
+* Several fixes to Redcloud API found during bringup.
+* Modified Durango to support 4-pixel video alignment for Redcloud.
+* Added the functions gfx_test_vip_overflow, gfx_get_vip_line,
+ gfx_set_decoder_luminance_filter, gfx_set_tv_YV_delya and
+ gfx_set_tv_field_status_invert.
+* Added support for Carmel D1 revision ID.
+* Moved gfx_get_vip_base and gfx_get_vbi_pitch outside of the
+ GXF_READ_ROUTINES flag.
+* Minor fixes to saa7114.c and gfx_set_tv-enable.
+* Added don't care option in gfx_set_vip_base.
+* Added fix for SC1200 issue #1121 (VIP FIFO bus request threshold bit
+ is inverted.
+
+=============================================================================
+
+07/31/01 Version 2.33.02
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Completed implementation of vertical downscaling support for GX2.
+* Added a method to lock the display controller timings.
+* Added support for SC1200 Rev C.
+* Small modifications to gfx_set_video_format.
+* Removed unused and unimplemented I2C functions.
+* Changes to prevent errors and compiler warnings in DOS.
+* Updated headers to include both BSD and GPL licenses.
+
+=============================================================================
+
+06/08/01 Version 2.31.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Added new routines to manipulate vertical video downscaling on GX2.
+* Minor fixes to the function gfx_read_window_crc.
+* Implemented all init routines for GX2 except gfx_get_core_freq.
+* Added support for 27MHz reference frequency to the GX2 PLL.
+* Added new function gfx_get_softvga_active.
+* Minor changes to the function sc1200_reset_video.
+* Fixed some minor compiler warnings.
+
+=============================================================================
+
+04/25/01 Version 2.29.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Disabled all CSC when setting an RGB video format.
+* Modified sc1200_set_video_size to add 2 to the window height.
+* Modified code to support the accelerator and cursor in pixel and line double modes.
+* Modified gfx_get_core_freq to be a dynamic API routine.
+* Added the function gfx_read_window_crc for GX2.
+* Added init routine gfx_get_graphics_register_base for GX2.
+* Added new macros to access the scratchpad RAM to support Win2K and WinME.
+* Added mew macros to access the GP registers for GX2.
+
+=============================================================================
+
+04/06/01 Version 2.27.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Added new TV read functions:
+ gfx_get_tv_enable, gfx_get_tv_output, gfx_get_tv_display_mode,
+ gfx_get_tv_mode_count, gfx_is_tv_display_mode_supported
+* Added new function gfx_set_display_bpp.
+* Added new function gfx_get_frame_buffer_line_size.
+* Modified gfx_set_vbi_base to accept pure physical addresses instead of offsets.
+* Implemented video and display controller routines for GX2.
+* Modified some initialization routines to be dynamic.
+* Created new API extension for GX2 MSR accesses.
+* Added new icon routines for GX2.
+* Modified gfx_set_tv_display to preserve current bpp.
+* Minor modifications to gfx_set_tv_format, gfx_set_video_palette and
+ gfx_set_video_palette entry.
+* Added support for 1152x864@75Hz
+
+=============================================================================
+
+03/12/01 Version 2.25.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Adapted new revision format system.
+* Synchronized with NSTA Durango. Updated support for all SC1200 features.
+* Added support for 640x400 as well as emulated VGA modes.
+* Added new routines to access single palette color entries.
+* Added new routine to return the maximum supported pixel clock.
+* Added new routine gfx_set_crt_enable to manipulate the CRT display logic.
+* Added new rendering routine gfx_color_pattern_fill.
+* Added 4:2:0 and RGB video format support for CS5530 and SC1200.
+* Modified code to allow operation under DOS.
+
+=============================================================================
+
+07/21/00 Version 2.04
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Verified Xfree86 driver version 1.1.4 under Linux, and ce v2.3.
+* Merged sc1200 changes.
+* Added routines to support the query of current display mode.
+* Added functions gfx_enable_softvga, dfx_disable_softvga.
+* Added code optimization in rendering loops to use 32 bit writes where possible.
+* Added gfx_is_mode_supported to query if given mode supported by the h/w.
+* Added Flat panel support, realy testing with panel done only for 800x600.
+* Removed subtraction of 16 from gfx_set_compression_size.
+* Added version.h file to reflect the version of the durango used.
+
+=============================================================================
+
+03/03/00 Version 2.01
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Verified Xfree86 driver version 1.1 under FreeBSD and Linux.
+* Added automatic detection of BLT buffer bases in "gfx_set_bpp" routine.
+* Fixed improper setting of VGA attrubute controller index register.
+* Moved "gfx_get_display_bpp" to always be included.
+* Moved "gfx_get_hactive" and "gfx_get_vactive" to always be included.
+* Clipped video source size if off bottom or right side.
+* Properly adjusted video offset if clipped on the top side.
+* Added "gfx_get_video_line_size" and "gfx_get_video_xclip" routines.
+
+=============================================================================
+
+02/21/00 Version 2.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Added gfx_vga.c.
+* Added write to GP_BLIT_STATUS in "gfx_set_bpp" routine.
+* Verified alpha blending on SC1200.
+* Removed "gfx_set_blt_buffers" routine.
+
+=============================================================================
+
+02/09/00 Version 1.20
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Verified display modes and graphics rendering on SC1200.
+* Updated PLL table for SC1200 to set modes.
+* DURANGO.C FILE CHANGE!: Modifed and added compiler definitions.
+* Split gfx_disp.c file into gu1_disp.c and gu2_disp.c
+* Split gfx_rndr.c file into gu1_rndr.c and gu2_rndr.c
+* Split gfx_vid.c file into vid_5530.c, vid_1400.c, and vid_1200.c
+* Split gfx_vip.c file into vip_1400.c and vip_1200.c
+* Split gfx_tv.c file into geode_tv.c and fs451_tv.c
+* Split gfx_i2c.c file into acc_i2c.c and gpio_i2c.c.
+* Split gfx_dcdr.c file to saa7114.c
+* Added GFX_READ_ROUTINES compiler definition.
+* Moved routines from gfx_read.c (no longer exists) to other files.
+* Abstracted display controller access in the video overlay routines.
+* Added routines to control display compression hardware.
+
+=============================================================================
+
+01/28/00 Version 1.13
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Passes randomly generated rendering tests in Darwin for GXLV.
+* Fixed bug for large bitmap to screen BLTs (greater than 64K).
+* Fixed bug for pattern fills using solid source data for plane masks.
+
+=============================================================================
+
+01/14/00 Version 1.12
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Added proper use of hotspot to gfx_set_cursor_position.
+* Fixed buffer size to handle all frame buffer start address alignments.
+* Added initial version of gfx_tv.c.
+
+=============================================================================
+
+01/07/00 Version 1.11
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Fixed bug with transparent BLTs (loading transparent color into BB1).
+* Added definition of gfx_color_bitmap_to_screen_blt to gfx_rtns.h.
+* Added gfx_color_bitmap_to_screen_xblt (transparent bitmap to screen).
+
+=============================================================================
+
+12/21/99 Version 1.10
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Added additional video decoder routines to gfx_dcdr.c.
+* Added VBI routines to gfx_vip.c.
+* Added alpha blending routines for SC1200 to gfx_vid.c
+
+=============================================================================
+
+10/01/99 Version 1.00
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Added video port, video decoder, I2C, and hardware query rouines.
+* New files: gfx_vip.c, gfx_dcdr.c, gfx_i2c.c, gfx_read.c.
+
+=============================================================================
+
+08/27/99 Version 0.05
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* INTERFACE CHANGE: Changed "gfx_csptr[]" to "gfx_vidptr" and "gfx_vipptr".
+* Added "gfx_get_vid_register_base" and "gfx_get_vip_register_base".
+* Added initial PLL table for SC1400.
+* Verified mode set and video overlay routines work correctly on SC1400.
+* Updated initilization routines.
+* Added update of graphics engine in "gfx_set_display_pitch".
+
+=============================================================================
+
+08/20/99 Version 0.04
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* INTERFACE CHANGE: "gfx_load_*" routines changed to "gfx_set_*" for naming
+ consistency. The "gfx_text_glyph" routine was removed.
+* Added video overlay routines.
+* Added gfx_vid.c file.
+
+=============================================================================
+
+08/16/99 Version 0.03
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* INTERFACE CHANGE: Access to CS5530 now through separate pointer. Project
+ must declare and map the gfx_csptr[GFX_CSPTR_SIZE] variable.
+* Added durango.c file as template for main source file.
+* Added gfx_init.c file.
+
+=============================================================================
+
+08/04/99 Version 0.02
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Additional modes in gfx_mode.h file.
+* Separated register definitions from gfx_defs.h into gfx_regs.h.
+
+=============================================================================
+
+07/30/99 Version 0.01
+
+-----------------------------------------------------------------------------
+FUNCTIONAL CHANGES
+-----------------------------------------------------------------------------
+* Initial release.
+-----------------------------------------------------------------------------
+
diff --git a/src/gfx/rndr_gu1.c b/src/gfx/rndr_gu1.c
new file mode 100644
index 0000000..5ad5af1
--- /dev/null
+++ b/src/gfx/rndr_gu1.c
@@ -0,0 +1,1584 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to program the 2D acceleration hardware for
+ * the first generation graphics unit (GXLV, SC1200).
+ *
+ * gfx_set_bpp
+ * gfx_set_solid_pattern
+ * gfx_set_mono_pattern
+ * gfx_set_color_pattern
+ * gfx_set_solid_source
+ * gfx_set_mono_source
+ * gfx_set_raster_operation
+ * gfx_pattern_fill
+ * gfx_screen_to_screen_blt
+ * gfx_screen_to_screen_xblt
+ * gfx_color_bitmap_to_screen_blt
+ * gfx_color_bitmap_to_screen_xblt
+ * gfx_mono_bitmap_to_screen_blt
+ * gfx_bresenham_line
+ * gfx_wait_until_idle
+ * */
+
+#if GFX_NO_IO_IN_WAIT_MACROS
+#define GFX_WAIT_PENDING \
+ while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { ; }
+#define GFX_WAIT_BUSY \
+ while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { ; }
+#define GFX_WAIT_PIPELINE \
+ while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { ; }
+#else
+#define GFX_WAIT_PENDING \
+ while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { INB (0x80); }
+#define GFX_WAIT_BUSY \
+ while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { INB (0x80); }
+#define GFX_WAIT_PIPELINE \
+ while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { INB (0x80); }
+#endif
+
+void gu1_detect_blt_buffer_base(void);
+
+/*---------------------------------------------------------------------------
+ * GFX_SET_BPP
+ *
+ * This routine sets the bits per pixel value in the graphics engine.
+ * It is also stored in a static variable to use in the future calls to
+ * the rendering routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_set_bpp(unsigned short bpp)
+#else
+void
+gfx_set_bpp(unsigned short bpp)
+#endif
+{
+ int control = 0;
+ unsigned short pitch = gfx_get_display_pitch();
+
+ GFXbpp = bpp;
+
+ /* DETECT BASE ADDRESSES FOR BLT BUFFERS */
+ /* Different for 2K or 3K of scratchpad. Also need to calculate */
+ /* the number of pixels that can fit in a BLT buffer - need to */
+ /* subtract 16 for alignment considerations. The 2K case, for */
+ /* example, is 816 bytes wide, allowing 800 pixels in 8 BPP, which */
+ /* means rendering operations won't be split for 800x600. */
+
+ gu1_detect_blt_buffer_base();
+ GFXbufferWidthPixels = GFXbb1Base - GFXbb0Base - 16;
+ if (bpp > 8) {
+ /* If 16bpp, divide GFXbufferWidthPixels by 2 */
+ GFXbufferWidthPixels >>= 1;
+ }
+
+ /* SET THE GRAPHICS CONTROLLER BPP AND PITCH */
+ if (bpp > 8) {
+ /* Set the 16bpp bit if necessary */
+ control = BC_16BPP;
+ }
+ if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) {
+ control |= BC_FB_WIDTH_4096;
+ } else if (pitch > 1024) {
+ control |= BC_FB_WIDTH_2048;
+ }
+ GFX_WAIT_BUSY;
+ WRITE_REG32(GP_BLIT_STATUS, control);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_SOLID_SOURCE
+ *
+ * This routine is used to specify a solid source color. For the Xfree96
+ * display driver, the source color is used to specify a planemask and the
+ * ROP is adjusted accordingly.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_set_solid_source(unsigned long color)
+#else
+void
+gfx_set_solid_source(unsigned long color)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* FORMAT 8 BPP COLOR */
+ /* GX requires 8BPP color data be duplicated into bits [15:8]. */
+
+ if (GFXbpp == 8) {
+ color &= 0x00FF;
+ color |= (color << 8);
+ }
+
+ /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)color);
+ WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)color);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_MONO_SOURCE
+ *
+ * This routine is used to specify the monochrome source colors.
+ * It must be called *after* loading any pattern data (those routines
+ * clear the source flags).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent)
+#else
+void
+gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent)
+#endif
+{
+ /* SET TRANSPARENCY FLAG */
+
+ GFXsourceFlags = transparent ? RM_SRC_TRANSPARENT : 0;
+
+ /* FORMAT 8 BPP COLOR */
+ /* GX requires 8BPP color data be duplicated into bits [15:8]. */
+
+ if (GFXbpp == 8) {
+ bgcolor &= 0x00FF;
+ bgcolor |= (bgcolor << 8);
+ fgcolor &= 0x00FF;
+ fgcolor |= (fgcolor << 8);
+ }
+
+ /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)bgcolor);
+ WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)fgcolor);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_SOLID_PATTERN
+ *
+ * This routine is used to specify a solid pattern color. It is called
+ * before performing solid rectangle fills or more complicated BLTs that
+ * use a solid pattern color.
+ *
+ * The driver should always call "gfx_load_raster_operation" after a call
+ * to this routine to make sure that the pattern flags are set appropriately.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_set_solid_pattern(unsigned long color)
+#else
+void
+gfx_set_solid_pattern(unsigned long color)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* SET PATTERN FLAGS */
+
+ GFXpatternFlags = 0;
+
+ /* FORMAT 8 BPP COLOR */
+ /* GX requires 8BPP color data be duplicated into bits [15:8]. */
+
+ if (GFXbpp == 8) {
+ color &= 0x00FF;
+ color |= (color << 8);
+ }
+
+ /* SAVE THE REFORMATTED COLOR FOR LATER */
+ /* Used to call the "GFX_solid_fill" routine for special cases. */
+
+ GFXsavedColor = color;
+
+ /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_MONO_PATTERN
+ *
+ * This routine is used to specify a monochrome pattern.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparent)
+#else
+void
+gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparent)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* SET PATTERN FLAGS */
+
+ GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT :
+ RM_PAT_MONO;
+
+ /* FORMAT 8 BPP COLOR */
+ /* GXm requires 8BPP color data be duplicated into bits [15:8]. */
+
+ if (GFXbpp == 8) {
+ bgcolor &= 0x00FF;
+ bgcolor |= (bgcolor << 8);
+ fgcolor &= 0x00FF;
+ fgcolor |= (fgcolor << 8);
+ }
+
+ /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor);
+ WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor);
+ WRITE_REG32(GP_PAT_DATA_0, data0);
+ WRITE_REG32(GP_PAT_DATA_1, data1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_COLOR_PATTERN
+ *
+ * This routine is used to specify a color pattern.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned long data2,
+ unsigned long data3, unsigned char transparent)
+#else
+void
+gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned long data2,
+ unsigned long data3, unsigned char transparent)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* SET PATTERN FLAGS */
+
+ GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT :
+ RM_PAT_MONO;
+
+ GFXpatternFlags |= RM_PAT_COLOR;
+ /* FORMAT 8 BPP COLOR */
+ /* GXm requires 8BPP color data be duplicated into bits [15:8]. */
+
+ if (GFXbpp == 8) {
+ bgcolor &= 0x00FF;
+ bgcolor |= (bgcolor << 8);
+ fgcolor &= 0x00FF;
+ fgcolor |= (fgcolor << 8);
+ }
+
+ /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor);
+ WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor);
+ WRITE_REG32(GP_PAT_DATA_0, data0);
+ WRITE_REG32(GP_PAT_DATA_1, data1);
+ if (GFXbpp > 8) {
+ WRITE_REG32(GP_PAT_DATA_2, data2);
+ WRITE_REG32(GP_PAT_DATA_3, data3);
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_LOAD_COLOR_PATTERN_LINE
+ *
+ * This routine is used to load a single line of a 8x8 color pattern.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_load_color_pattern_line(short y, unsigned long *pattern_8x8)
+#else
+void
+gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* SET PATTERN FLAGS */
+
+ GFXpatternFlags = RM_PAT_COLOR;
+
+ y &= 7;
+
+ if (GFXbpp > 8)
+ pattern_8x8 += (y << 2);
+ else
+ pattern_8x8 += (y << 1);
+
+ /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG32(GP_PAT_DATA_0, pattern_8x8[0]);
+ WRITE_REG32(GP_PAT_DATA_1, pattern_8x8[1]);
+ if (GFXbpp > 8) {
+ WRITE_REG32(GP_PAT_DATA_2, pattern_8x8[2]);
+ WRITE_REG32(GP_PAT_DATA_3, pattern_8x8[3]);
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_RASTER_OPERATION
+ *
+ * This routine loads the specified raster operation. It sets the pattern
+ * flags appropriately.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_set_raster_operation(unsigned char rop)
+#else
+void
+gfx_set_raster_operation(unsigned char rop)
+#endif
+{
+ unsigned short rop16;
+
+ /* GENERATE 16-BIT VERSION OF ROP WITH PATTERN FLAGS */
+
+ rop16 = (unsigned short)rop | GFXpatternFlags;
+ if ((rop & 0x33) ^ ((rop >> 2) & 0x33))
+ rop16 |= GFXsourceFlags;
+
+ /* SAVE ROP FOR LATER COMPARISONS */
+ /* Need to have the pattern flags included */
+
+ GFXsavedRop = rop16;
+
+ /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */
+ /* True if even bits (0:2:4:6) do not equal the correspinding */
+ /* even bits (1:3:5:7). */
+
+ GFXusesDstData = ((rop & 0x55) ^ ((rop >> 1) & 0x55));
+
+ /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
+ /* Only one operation can be pending at a time. */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_RASTER_MODE, rop16);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SOLID_FILL
+ *
+ * This routine MUST be used when performing a solid rectangle fill with
+ * the ROPs of PATCOPY (0xF0), BLACKNESS (0x00), WHITENESS (0xFF), or
+ * PATINVERT (0x0F). There is a bug in GXm for these cases that requires a
+ * workaround.
+ *
+ * For BLACKNESS (ROP = 0x00), set the color to 0x0000.
+ * For WHITENESS (ROP = 0xFF), set the color to 0xFFFF.
+ * For PATINVERT (ROP = 0x0F), invert the desired color.
+ *
+ * X screen X position (left)
+ * Y screen Y position (top)
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * COLOR fill color
+ *
+ * THIS ROUTINE SHOULD NOT BE DIRECTLY CALLED FROM THE DRIVER. The driver
+ * should always use GFX_pattern_fill and let that routine call this one
+ * when approipriate. This is to hide quirks specific to MediaGX hardware.
+ *---------------------------------------------------------------------------
+ */
+void
+gu1_solid_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long color)
+{
+ unsigned short section;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Only one operation can be pending at a time. */
+
+ GFX_WAIT_PENDING;
+
+ /* SET REGISTERS TO DRAW RECTANGLE */
+
+ WRITE_REG16(GP_DST_XCOOR, x);
+ WRITE_REG16(GP_DST_YCOOR, y);
+ WRITE_REG16(GP_HEIGHT, height);
+ WRITE_REG16(GP_RASTER_MODE, 0x00F0); /* PATCOPY */
+ WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color);
+
+ /* CHECK WIDTH FOR GX BUG WORKAROUND */
+
+ if (width <= 16) {
+ /* OK TO DRAW SMALL RECTANGLE IN ONE PASS */
+
+ WRITE_REG16(GP_WIDTH, width);
+ WRITE_REG16(GP_BLIT_MODE, 0);
+ } else {
+ /* DRAW FIRST PART OF RECTANGLE */
+ /* Get to a 16 pixel boundary. */
+
+ section = 0x10 - (x & 0x0F);
+ WRITE_REG16(GP_WIDTH, section);
+ WRITE_REG16(GP_BLIT_MODE, 0);
+
+ /* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_DST_XCOOR, x + section);
+ WRITE_REG16(GP_DST_YCOOR, y);
+ WRITE_REG16(GP_WIDTH, width - section);
+ WRITE_REG16(GP_BLIT_MODE, 0);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * GFX_PATTERN_FILL
+ *
+ * This routine is used to fill a rectangular region. The pattern must
+ * be previously loaded using one of GFX_load_*_pattern routines. Also, the
+ * raster operation must be previously specified using the
+ * "GFX_load_raster_operation" routine.
+ *
+ * X screen X position (left)
+ * Y screen Y position (top)
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height)
+#else
+void
+gfx_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height)
+#endif
+{
+ unsigned short section, buffer_width, blit_mode;
+
+ /* CHECK IF OPTIMIZED SOLID CASES */
+ /* Check all 16 bits of the ROP to include solid pattern flags. */
+
+ switch (GFXsavedRop) {
+ /* CHECK FOR SPECIAL CASES WITHOUT DESTINATION DATA */
+ /* Need hardware workaround for fast "burst write" cases. */
+
+ case 0x00F0:
+ gu1_solid_fill(x, y, width, height, (unsigned short)GFXsavedColor);
+ break;
+ case 0x000F:
+ gu1_solid_fill(x, y, width, height, (unsigned short)~GFXsavedColor);
+ break;
+ case 0x0000:
+ gu1_solid_fill(x, y, width, height, 0x0000);
+ break;
+ case 0x00FF:
+ gu1_solid_fill(x, y, width, height, 0xFFFF);
+ break;
+
+ /* REMAINING CASES REQUIRE DESTINATION DATA OR NOT SOLID COLOR */
+
+ default:
+
+ /* DETERMINE BLT MODE VALUE */
+ /* Still here for non-solid patterns without destination data. */
+
+ blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0;
+
+ /* SET SOURCE EXPANSION MODE */
+ /* If the ROP requires source data, then the source data is all 1's */
+ /* and then expanded into the desired color in GP_SRC_COLOR_1. */
+
+ blit_mode |= BM_SOURCE_EXPAND;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Write the registers that do not change for each section. */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_HEIGHT, height);
+
+ /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */
+ /* Therefore, width available = BLT buffer width * 2. */
+
+ buffer_width = GFXbufferWidthPixels << 1;
+
+ /* REPEAT UNTIL FINISHED WITH RECTANGLE */
+ /* Perform BLT in vertical sections, as wide as the BLT buffer */
+ /* allows. Hardware does not split the operations, so */
+ /* software must do it to avoid large scanlines that would */
+ /* overflow the BLT buffers. */
+
+ while (width > 0) {
+ /* DETERMINE WIDTH OF SECTION */
+
+ if (width > buffer_width)
+ section = buffer_width;
+ else
+ section = width;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_DST_XCOOR, x);
+ WRITE_REG16(GP_DST_YCOOR, y);
+ WRITE_REG16(GP_WIDTH, section);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+
+ /* ADJUST PARAMETERS FOR NEXT SECTION */
+
+ width -= section;
+ x += section;
+ }
+ break;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * GFX_COLOR_PATTERN_FILL
+ *
+ * This routine is used to render a rectangle using the current raster
+ * operation and the specified color pattern. It allows an 8x8 color
+ * pattern to be rendered without multiple calls to the gfx_set_color_pattern
+ * and gfx_pattern_fill routines.
+ *
+ * X screen X position (left)
+ * Y screen Y position (top)
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *PATTERN pointer to 8x8 color pattern data
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern)
+#else
+void
+gfx_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern)
+#endif
+{
+ unsigned short blit_mode, passes, cur_y, pat_y, i;
+ unsigned short buffer_width, line_width;
+ unsigned short bpp_shift, section, cur_x;
+
+ /* SET APPROPRIATE INCREMENT */
+
+ bpp_shift = (GFXbpp > 8) ? 2 : 1;
+
+ /* SET DESTINATION REQUIRED */
+
+ blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0;
+
+ /* SET SOURCE EXPANSION */
+
+ blit_mode |= BM_SOURCE_EXPAND;
+
+ /* OVERRIDE RASTER MODE TO FORCE A COLOR PATTERN */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_RASTER_MODE,
+ (GFXsavedRop & ~RM_PAT_MASK & ~RM_PAT_TRANSPARENT) | RM_PAT_COLOR);
+
+ /* WRITE THE REGISTERS THAT DO NOT CHANGE */
+ /* If destination data is required, the width and */
+ /* x position will be overwritten. */
+
+ WRITE_REG16(GP_HEIGHT, 1);
+ WRITE_REG16(GP_WIDTH, width);
+ WRITE_REG16(GP_DST_XCOOR, x);
+
+ /* THE ENTIRE PATTERN WILL NOT BE DRAWN IF THE HEIGHT IS LESS THAN 8 */
+
+ passes = (height < 8) ? height : 8;
+
+ /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */
+ /* Therefore, width available = BLT buffer width * 2. */
+
+ buffer_width = GFXbufferWidthPixels << 1;
+
+ for (i = 0; i < passes; i++) {
+ pat_y = ((y + i) & 7) << bpp_shift;
+ cur_y = y + i;
+
+ /* WRITE THE PATTERN DATA FOR THE ACTIVE LINE */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG32(GP_PAT_DATA_0, pattern[pat_y]);
+ WRITE_REG32(GP_PAT_DATA_1, pattern[pat_y + 1]);
+
+ if (GFXbpp > 8) {
+ WRITE_REG32(GP_PAT_DATA_2, pattern[pat_y + 2]);
+ WRITE_REG32(GP_PAT_DATA_3, pattern[pat_y + 3]);
+ }
+
+ /* SPLIT BLT LINE INTO SECTIONS IF REQUIRED */
+ /* If no destination data is required, we can ignore */
+ /* the BLT buffers. Otherwise, we must separate the BLT */
+ /* so as not to overflow the buffers */
+
+ if (blit_mode & BM_READ_DST_BB0) {
+ line_width = width;
+ cur_x = x;
+
+ while (line_width) {
+ section =
+ (line_width > buffer_width) ? buffer_width : line_width;
+ cur_y = y + i;
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_DST_XCOOR, cur_x);
+ WRITE_REG16(GP_WIDTH, section);
+
+ while (cur_y < y + height) {
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_DST_YCOOR, cur_y);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+ cur_y += 8;
+ }
+
+ cur_x += section;
+ line_width -= section;
+ }
+
+ } else {
+ while (cur_y < y + height) {
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_DST_YCOOR, cur_y);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+ cur_y += 8;
+ }
+ }
+
+ }
+
+ /* RESTORE ORIGINAL ROP AND FLAGS */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_RASTER_MODE, GFXsavedRop);
+
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * SCREEN TO SCREEN BLT
+ *
+ * This routine should be used to perform a screen to screen BLT when the
+ * ROP does not require destination data.
+ *
+ * SRCX screen X position to copy from
+ * SRCY screen Y position to copy from
+ * DSTX screen X position to copy to
+ * DSTY screen Y position to copy to
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height)
+#else
+void
+gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height)
+#endif
+{
+ unsigned short section, buffer_width;
+ unsigned short blit_mode;
+
+ /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */
+
+ blit_mode = GFXusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB :
+ BM_READ_SRC_FB;
+
+ /* CHECK Y DIRECTION */
+ /* Hardware has support for negative Y direction. */
+
+ if (dsty > srcy) {
+ blit_mode |= BM_REVERSE_Y;
+ srcy += height - 1;
+ dsty += height - 1;
+ }
+
+ /* CHECK X DIRECTION */
+ /* Hardware does not support negative X direction since at the time */
+ /* of development all supported resolutions could fit a scanline of */
+ /* data at once into the BLT buffers (using both BB0 and BB1). This */
+ /* code is more generic to allow for any size BLT buffer. */
+
+ if (dstx > srcx) {
+ srcx += width;
+ dstx += width;
+ }
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Write the registers that do not change for each section. */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_HEIGHT, height);
+
+ /* CHECK AVAILABLE BLT BUFFER SIZE */
+ /* Can use both BLT buffers if no destination data is required. */
+
+ buffer_width = GFXusesDstData ? GFXbufferWidthPixels :
+ GFXbufferWidthPixels << 1;
+
+ /* REPEAT UNTIL FINISHED WITH RECTANGLE */
+ /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */
+ /* Hardware does not split the operations, so software must do it to */
+ /* avoid large scanlines that would overflow the BLT buffers. */
+
+ while (width > 0) {
+ /* CHECK WIDTH OF CURRENT SECTION */
+
+ if (width > buffer_width)
+ section = buffer_width;
+ else
+ section = width;
+
+ /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_SRC_YCOOR, srcy);
+ WRITE_REG16(GP_DST_YCOOR, dsty);
+ WRITE_REG16(GP_WIDTH, section);
+
+ /* CHECK X DIRECTION */
+
+ if (dstx > srcx) {
+ /* NEGATIVE X DIRECTION */
+ /* Still positive X direction within the section. */
+
+ srcx -= section;
+ dstx -= section;
+ WRITE_REG16(GP_SRC_XCOOR, srcx);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+ } else {
+ /* POSITIVE X DIRECTION */
+
+ WRITE_REG16(GP_SRC_XCOOR, srcx);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+ dstx += section;
+ srcx += section;
+ }
+ width -= section;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * SCREEN TO SCREEN TRANSPARENT BLT
+ *
+ * This routine should be used to perform a screen to screen BLT when a
+ * specified color should by transparent. The only supported ROP is SRCCOPY.
+ *
+ * SRCX screen X position to copy from
+ * SRCY screen Y position to copy from
+ * DSTX screen X position to copy to
+ * DSTY screen Y position to copy to
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * COLOR transparent color
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color)
+#else
+void
+gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color)
+#endif
+{
+ unsigned short section, buffer_width;
+ unsigned short blit_mode = BM_READ_SRC_FB;
+
+ /* CHECK Y DIRECTION */
+ /* Hardware has support for negative Y direction. */
+
+ if (dsty > srcy) {
+ blit_mode |= BM_REVERSE_Y;
+ srcy += height - 1;
+ dsty += height - 1;
+ }
+
+ /* CHECK X DIRECTION */
+ /* Hardware does not support negative X direction since at the time */
+ /* of development all supported resolutions could fit a scanline of */
+ /* data at once into the BLT buffers (using both BB0 and BB1). This */
+ /* code is more generic to allow for any size BLT buffer. */
+
+ if (dstx > srcx) {
+ srcx += width;
+ dstx += width;
+ }
+
+ /* CALCULATE BLT BUFFER SIZE */
+ /* Need to use BB1 to store the BLT buffer data. */
+
+ buffer_width = GFXbufferWidthPixels;
+
+ /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */
+
+ if (GFXbpp == 8) {
+ color &= 0x00FF;
+ color |= (color << 8);
+ }
+ color = (color & 0x0000FFFF) | (color << 16);
+
+ /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */
+ /* Need to make sure any previous BLT using BB1 is complete. */
+ /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */
+
+ GFX_WAIT_BUSY;
+ WRITE_SCRATCH32(GFXbb1Base, color);
+
+ /* DO BOGUS BLT TO LATCH DATA FROM BB1 */
+ /* Already know graphics pipeline is idle. */
+ /* Only need to latch data into the holding registers for the current */
+ /* data from BB1. A 1 pixel wide BLT will suffice. */
+
+ WRITE_REG32(GP_DST_XCOOR, 0);
+ WRITE_REG32(GP_SRC_XCOOR, 0);
+ WRITE_REG32(GP_WIDTH, 0x00010001);
+ WRITE_REG16(GP_RASTER_MODE, 0x00CC);
+ WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1);
+
+ /* WRITE REGISTERS FOR REAL SCREEN TO SCREEN BLT */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_HEIGHT, height);
+ WRITE_REG16(GP_RASTER_MODE, 0x10C6);
+ WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF);
+
+ /* REPEAT UNTIL FINISHED WITH RECTANGLE */
+ /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */
+ /* Hardware does not split the operations, so software must do it to */
+ /* avoid large scanlines that would overflow the BLT buffers. */
+
+ while (width > 0) {
+ /* CHECK WIDTH OF CURRENT SECTION */
+
+ if (width > buffer_width)
+ section = buffer_width;
+ else
+ section = width;
+
+ /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_SRC_YCOOR, srcy);
+ WRITE_REG16(GP_DST_YCOOR, dsty);
+ WRITE_REG16(GP_WIDTH, section);
+
+ /* CHECK X DIRECTION */
+ /* Again, this must be done in software, and can be removed if the */
+ /* display driver knows that the BLT buffers will always be large */
+ /* enough to contain an entire scanline of a screen to screen BLT. */
+
+ if (dstx > srcx) {
+ /* NEGATIVE X DIRECTION */
+ /* Still positive X direction within the section. */
+
+ srcx -= section;
+ dstx -= section;
+ WRITE_REG16(GP_SRC_XCOOR, srcx);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+ } else {
+ /* POSITIVE X DIRECTION */
+
+ WRITE_REG16(GP_SRC_XCOOR, srcx);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+ dstx += section;
+ srcx += section;
+ }
+ width -= section;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * COLOR BITMAP TO SCREEN BLT
+ *
+ * This routine transfers color bitmap data to the screen. For most cases,
+ * when the ROP is SRCCOPY, it may be faster to write a separate routine that
+ * copies the data to the frame buffer directly. This routine should be
+ * used when the ROP requires destination data.
+ *
+ * Transparency is handled by another routine.
+ *
+ * SRCX X offset within source bitmap
+ * SRCY Y offset within source bitmap
+ * DSTX screen X position to render data
+ * DSTY screen Y position to render data
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *DATA pointer to bitmap data
+ * PITCH pitch of bitmap data (bytes between scanlines)
+ *----------------------------------------------------------------------------
+ */
+
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch)
+#else
+void
+gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch)
+#endif
+{
+ unsigned short section, buffer_width;
+ unsigned short blit_mode = BM_READ_SRC_BB0;
+ unsigned short temp_height;
+ unsigned long dword_bytes_needed, bytes_extra;
+ unsigned long bpp_shift;
+ long array_offset;
+
+ /* CHECK SIZE OF BLT BUFFER */
+
+ buffer_width = GFXbufferWidthPixels;
+
+ /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */
+ /* If no destination data, we have twice the room for */
+ /* source data. */
+
+ if (GFXusesDstData)
+ blit_mode |= BM_READ_DST_FB1;
+ else
+ buffer_width <<= 1;
+
+ /* SET THE SCRATCHPAD BASE */
+
+ SET_SCRATCH_BASE(GFXbb0Base);
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Write the registers that do not change for each section. */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_HEIGHT, 1);
+
+ bpp_shift = (GFXbpp + 7) >> 4;
+
+ while (width > 0) {
+ if (width > buffer_width)
+ section = buffer_width;
+ else
+ section = width;
+
+ dword_bytes_needed = (section << bpp_shift) & ~3l;
+ bytes_extra = (section << bpp_shift) & 3l;
+
+ temp_height = height;
+
+ /* WRITE THE REGISTERS FOR EACH SECTION */
+ /* The GX hardware will auto-increment the Y coordinate, meaning */
+ /* that we don't have to. */
+
+ WRITE_REG16(GP_WIDTH, section);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_DST_YCOOR, dsty);
+
+ /* CALCULATE THE BITMAP OFFSET */
+
+ array_offset =
+ (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift);
+
+ while (temp_height--) {
+ GFX_WAIT_PIPELINE;
+
+ /* WRITE ALL DATA TO THE BLT BUFFERS */
+ /* The WRITE_SCRATCH_STRING macro assumes that the data begins
+ * at the scratchpad offset set by the SET_SCRATCH_BASE macro.
+ * */
+
+ WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data,
+ array_offset);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+
+ array_offset += pitch;
+ }
+
+ width -= section;
+ srcx += section;
+ dstx += section;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * COLOR BITMAP TO SCREEN TRANSPARENT BLT
+ *
+ * This routine transfers color bitmap data to the screen with transparency.
+ * The transparent color is specified. The only supported ROP is SRCCOPY,
+ * meaning that transparency cannot be applied if the ROP requires
+ * destination data (this is a hardware restriction).
+ *
+ * SRCX X offset within source bitmap
+ * SRCY Y offset within source bitmap
+ * DSTX screen X position to render data
+ * DSTY screen Y position to render data
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *DATA pointer to bitmap data
+ * PITCH pitch of bitmap data (bytes between scanlines)
+ * COLOR transparent color
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch,
+ unsigned long color)
+#else
+void
+gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch,
+ unsigned long color)
+#endif
+{
+ unsigned short section, buffer_width;
+ unsigned short temp_height;
+ unsigned long dword_bytes_needed, bytes_extra;
+ unsigned long bpp_shift;
+ long array_offset;
+
+ /* CHECK SIZE OF BLT BUFFER */
+
+ buffer_width = GFXbufferWidthPixels;
+
+ /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */
+
+ if (GFXbpp == 8) {
+ color &= 0x00FF;
+ color |= (color << 8);
+ }
+ color = (color & 0x0000FFFF) | (color << 16);
+
+ /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */
+ /* Need to make sure any previous BLT using BB1 is complete. */
+ /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */
+
+ GFX_WAIT_PIPELINE;
+ GFX_WAIT_PENDING;
+ WRITE_SCRATCH32(GFXbb1Base, color);
+
+ /* DO BOGUS BLT TO LATCH DATA FROM BB1 */
+ /* Already know graphics pipeline is idle. */
+ /* Only need to latch data into the holding registers for the current */
+ /* data from BB1. A 1 pixel wide BLT will suffice. */
+
+ WRITE_REG32(GP_DST_XCOOR, 0);
+ WRITE_REG32(GP_SRC_XCOOR, 0);
+ WRITE_REG32(GP_WIDTH, 0x00010001);
+ WRITE_REG16(GP_RASTER_MODE, 0x00CC);
+ WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1);
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Write the registers that do not change for each section. */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_HEIGHT, 1);
+ WRITE_REG16(GP_RASTER_MODE, 0x10C6);
+ WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF);
+
+ bpp_shift = (GFXbpp + 7) >> 4;
+
+ /* SET THE SCRATCHPAD BASE */
+
+ SET_SCRATCH_BASE(GFXbb0Base);
+
+ while (width > 0) {
+ if (width > buffer_width)
+ section = buffer_width;
+ else
+ section = width;
+
+ dword_bytes_needed = (section << bpp_shift) & ~3l;
+ bytes_extra = (section << bpp_shift) & 3l;
+
+ temp_height = height;
+
+ /* WRITE THE REGISTERS FOR EACH SECTION */
+ /* The GX hardware will auto-increment the Y coordinate, meaning */
+ /* that we don't have to. */
+
+ WRITE_REG16(GP_WIDTH, section);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_DST_YCOOR, dsty);
+
+ /* CALCULATE THE BITMAP OFFSET */
+
+ array_offset =
+ (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift);
+
+ while (temp_height--) {
+ GFX_WAIT_PIPELINE;
+
+ /* WRITE ALL DATA TO THE BLT BUFFERS */
+ /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */
+ /* scratchpad offset set by the SET_SCRATCH_BASE macro. */
+
+ WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data,
+ array_offset);
+ WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0);
+
+ array_offset += pitch;
+ }
+
+ width -= section;
+ srcx += section;
+ dstx += section;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * MONOCHROME BITMAP TO SCREEN BLT
+ *
+ * This routine transfers monochrome bitmap data to the screen.
+ *
+ * SRCX X offset within source bitmap
+ * SRCY Y offset within source bitmap
+ * DSTX screen X position to render data
+ * DSTY screen Y position to render data
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *DATA pointer to bitmap data
+ * PITCH pitch of bitmap data (bytes between scanlines)
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#else
+void
+gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#endif
+{
+ unsigned short section, buffer_width;
+ unsigned short blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND;
+ unsigned short temp_height;
+ unsigned long dword_bytes_needed, bytes_extra;
+ long array_offset;
+
+ /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */
+ /* If no destination data, the source data will always fit. */
+ /* So, in that event we will set the buffer width to a */
+ /* fictitiously large value such that the BLT is never split. */
+
+ if (GFXusesDstData) {
+ buffer_width = GFXbufferWidthPixels;
+ blit_mode |= BM_READ_DST_FB1;
+ } else
+ buffer_width = 3200;
+
+ /* CHECK IF DATA ALREADY IN BLIT BUFFER */
+ /* If the pointer is NULL, data for the full BLT is already there */
+ /* WARNING: This could cause problems if destination data is */
+ /* involved and it overflows the BLT buffer. Need to remove */
+ /* this option and change the drivers to use a temporary buffer. */
+
+ if (!data) {
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_SRC_XCOOR, srcx & 7);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_DST_YCOOR, dsty);
+ WRITE_REG16(GP_WIDTH, width);
+ WRITE_REG16(GP_HEIGHT, height);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+ return;
+ }
+
+ /* SET THE SCRATCHPAD BASE */
+
+ SET_SCRATCH_BASE(GFXbb0Base);
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Write the registers that do not change for each section. */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_HEIGHT, 1);
+
+ while (width > 0) {
+ if (width > buffer_width)
+ section = buffer_width;
+ else
+ section = width;
+
+ /* CALCULATE BYTES NEEDED */
+ /* Add 1 for possible alignment issues. */
+
+ dword_bytes_needed = ((section + 7 + (srcx & 7)) >> 3) & ~3l;
+ bytes_extra = ((section + 7 + (srcx & 7)) >> 3) & 3l;
+
+ temp_height = height;
+
+ /* WRITE THE REGISTERS FOR EACH SECTION */
+ /* The GX hardware will auto-increment the Y coordinate, meaning */
+ /* that we don't have to. */
+
+ WRITE_REG16(GP_WIDTH, section);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_DST_YCOOR, dsty);
+ WRITE_REG16(GP_SRC_XCOOR, srcx & 7);
+
+ /* CALCULATE THE BITMAP OFFSET */
+
+ array_offset = (unsigned long)srcy *(long)pitch + ((long)srcx >> 3);
+
+ while (temp_height--) {
+ GFX_WAIT_PIPELINE;
+
+ /* WRITE ALL DATA TO THE BLT BUFFERS */
+ /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */
+ /* scratchpad offset set by the SET_SCRATCH_BASE macro. */
+
+ WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data,
+ array_offset);
+ WRITE_REG16(GP_BLIT_MODE, blit_mode);
+
+ array_offset += pitch;
+ }
+
+ width -= section;
+ srcx += section;
+ dstx += section;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * MONOCHROME TEXT BLT
+ *
+ * This routine transfers contiguous monochrome text data to the screen.
+ *
+ * DSTX screen X position to render data
+ * DSTY screen Y position to render data
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *DATA pointer to bitmap data
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data)
+#else
+void
+gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data)
+#endif
+{
+ unsigned long dword_bytes_needed, bytes_extra;
+ long pitch, buffer_bytes, data_bytes;
+
+ /* CALCULATE DATA SIZE */
+
+ pitch = (width + 7) >> 3;
+ data_bytes = (long)height *pitch;
+
+ /* CHECK FOR SIMPLE CASE */
+ /* This routine is designed to render a source copy text glyph. If
+ * destination data is required or the source data will not fit, we will
+ * punt the operation to the more versatile (and slow) mono bitmap routine
+ * */
+
+ if (GFXbpp > 8)
+ buffer_bytes = GFXbufferWidthPixels << 1;
+ else
+ buffer_bytes = GFXbufferWidthPixels;
+
+ if (GFXusesDstData || data_bytes > buffer_bytes) {
+ gfx_mono_bitmap_to_screen_blt(0, 0, dstx, dsty, width, height, data,
+ (short)pitch);
+ return;
+ }
+
+ /* SET THE SCRATCHPAD BASE */
+
+ SET_SCRATCH_BASE(GFXbb0Base);
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+
+ dword_bytes_needed = data_bytes & ~3l;
+ bytes_extra = data_bytes & 3l;
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_HEIGHT, height);
+ WRITE_REG16(GP_WIDTH, width);
+ WRITE_REG16(GP_DST_XCOOR, dstx);
+ WRITE_REG16(GP_DST_YCOOR, dsty);
+ WRITE_REG16(GP_SRC_XCOOR, 0);
+
+ /* WRITE ALL DATA TO THE BLT BUFFERS */
+ /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */
+ /* scratchpad offset set by the SET_SCRATCH_BASE macro. */
+
+ GFX_WAIT_PIPELINE;
+
+ WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 0);
+ WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_SOURCE_TEXT);
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * BRESENHAM LINE
+ *
+ * This routine draws a vector using the specified Bresenham parameters.
+ * Currently this file does not support a routine that accepts the two
+ * endpoints of a vector and calculates the Bresenham parameters. If it
+ * ever does, this routine is still required for vectors that have been
+ * clipped.
+ *
+ * X screen X position to start vector
+ * Y screen Y position to start vector
+ * LENGTH length of the vector, in pixels
+ * INITERR Bresenham initial error term
+ * AXIALERR Bresenham axial error term
+ * DIAGERR Bresenham diagonal error term
+ * FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+#else
+void
+gfx_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+#endif
+{
+ unsigned short vector_mode = flags;
+
+ if (GFXusesDstData)
+ vector_mode |= VM_READ_DST_FB;
+
+ /* CHECK NULL LENGTH */
+
+ if (!length)
+ return;
+
+ /* LOAD THE REGISTERS FOR THE VECTOR */
+
+ GFX_WAIT_PENDING;
+ WRITE_REG16(GP_DST_XCOOR, x);
+ WRITE_REG16(GP_DST_YCOOR, y);
+ WRITE_REG16(GP_VECTOR_LENGTH, length);
+ WRITE_REG16(GP_INIT_ERROR, initerr);
+ WRITE_REG16(GP_AXIAL_ERROR, axialerr);
+ WRITE_REG16(GP_DIAG_ERROR, diagerr);
+ WRITE_REG16(GP_VECTOR_MODE, vector_mode);
+}
+
+/*---------------------------------------------------------------------------
+ * GFX_WAIT_UNTIL_IDLE
+ *
+ * This routine waits until the graphics engine is idle. This is required
+ * before allowing direct access to the frame buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu1_wait_until_idle(void)
+#else
+void
+gfx_wait_until_idle(void)
+#endif
+{
+ GFX_WAIT_BUSY;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX_TEST_BLT_PENDING
+ *
+ * This routine returns 1 if a BLT is pending, meaning that a call to
+ * perform a rendering operation would stall. Otherwise it returns 0.
+ * It is used by Darwin during random testing to only start a BLT
+ * operation when it knows the Durango routines won't spin on graphics
+ * (so Darwin can continue to do frame buffer reads and writes).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+int
+gu1_test_blt_pending(void)
+#else
+int
+gfx_test_blt_pending(void)
+#endif
+{
+ if (READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING)
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * BLT BUFFERS!!!!!
+ *---------------------------------------------------------------------------
+ */
+
+/* THE BOOT CODE MUST SET THE BLT BUFFER BASES USING THE "CPU_WRITE" */
+/* INSTRUCTION TO ONE OF THE FOLLOWING VALUES: */
+
+#define BB0_BASE_2K 0x800
+#define BB1_BASE_2K 0xB30
+#define BB0_BASE_3K 0x400
+#define BB1_BASE_3K 0x930
+
+/*---------------------------------------------------------------------------
+ * gu1_detect_blt_buffer_base
+ *
+ * This detection is hidden from the driver by being called from the
+ * "gfx_set_bpp" routine.
+ *
+ * This is fairly ugly for the following reasons:
+ *
+ * - It is the boot code that must set the BLT buffer bases to the
+ * appropriate values and load the scratchpad tags.
+ * - The old drivers would also set the base address values to what they
+ * knew they should be for the 2K or 3K scratchpad configuration.
+ * - Unfortunately, to set the base addresses requires the use of the
+ * CPU_WRITE instruction, an instruction specific to GX.
+ * - Using the CPU_WRITE instruction requires the use of assembly to
+ * produce the appropriate op codes.
+ * - Assembly is something that is avoided in Durango because it is not
+ * platform independent. Some compilers do not support inline assembly.
+ * - Therefore Durango cannot use the CPU_WRITE instruction.
+ * - Therefore drivers using Durango must rely on the boot code to set
+ * the appropriate values. Durango uses this routine to check where
+ * the base addresses have been set.
+ * - Unfortunately, it is not as simple as using IO to check for 2K or 3K
+ * scratchpad size. In VSA1, even though the boot code may set it for
+ * 3K, SoftVGA comes along and resets it to 2K for it's use in text
+ * redraws. It used to be that the display driver would set it back
+ * to 3K.
+ * - So, the Durango code was changed to just always use 2K.
+ * - But, the XpressROM code sets it for 3K, and the newer versions of
+ * SoftVGA do not interfere with that, so then Durango needs to use
+ * the 3K values to work properly.
+ * - Therefore, Durango does somewhat of a kludge by writing to directly
+ * to the scratchpad at both the 2K and 3K locations, then performing
+ * a unobtrusive BLT that loads data into BB0 (the graphics engine
+ * always knows the true base). After the BLT, Durango looks to see
+ * which location changed to know where the base address is.
+ * - This is a relatively simple way to allow Durango to work on old
+ * and new platforms without using theCPU_WRITE instructions.
+ *
+ * To summarize, the BLT buffers are one of the most painful aspects of
+ * the GX graphics unit design, and have been removed from future designs
+ * (the graphics unit has its own dedicated RAM). Durango has tried to
+ * hide the BLT buffer use from the drivers.
+ *---------------------------------------------------------------------------
+ */
+void
+gu1_detect_blt_buffer_base(void)
+{
+ /* ASSUME 2K */
+
+ GFXbb0Base = BB0_BASE_2K;
+ GFXbb1Base = BB1_BASE_2K;
+
+ /* CHECK IF SCRATCHPAD IS SET TO 3K OR 4K */
+ /* Boot code should still set 3K values for 4K. */
+
+ if (gfx_gxm_config_read(GXM_CONFIG_GCR) & 0x08) {
+ /* WRITE DATA TO 3K LOCATION */
+
+ GFX_WAIT_BUSY;
+ WRITE_SCRATCH32(BB0_BASE_3K, 0xFEEDFACE);
+
+ /* HAVE THE GRAPHICS UNIT STORE SOMETHING IN BB0 */
+
+ WRITE_REG32(GP_DST_XCOOR, 0x00000000); /* AT (0,0) */
+ WRITE_REG32(GP_WIDTH, 0x00010004); /* 4x1 BLT */
+ WRITE_REG16(GP_RASTER_MODE, 0x00AA); /* KEEP DST */
+ WRITE_REG16(GP_BLIT_MODE, BM_READ_DST_FB0); /* STORE IN BB0 */
+
+ /* CHECK 3K LOCATION */
+ /* Breaks if data happened to be 0xFEEDFACE - unlikely. */
+
+ GFX_WAIT_BUSY;
+ if (READ_SCRATCH32(BB0_BASE_3K) != 0xFEEDFACE) {
+ GFXbb0Base = BB0_BASE_3K;
+ GFXbb1Base = BB1_BASE_3K;
+ }
+ }
+}
+
+/* END OF FILE */
diff --git a/src/gfx/rndr_gu2.c b/src/gfx/rndr_gu2.c
new file mode 100644
index 0000000..31a26e7
--- /dev/null
+++ b/src/gfx/rndr_gu2.c
@@ -0,0 +1,2180 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to program the 2D acceleration hardware for
+ * the second generation graphics unit.
+ *
+ * Basic rendering routines (common to all Geode processors):
+ * gfx_set_bpp
+ * gfx_set_solid_pattern
+ * gfx_set_mono_pattern
+ * gfx_set_color_pattern
+ * gfx_set_solid_source
+ * gfx_set_mono_source
+ * gfx_set_raster_operation
+ * gfx_pattern_fill
+ * gfx_color_pattern_fill
+ * gfx_screen_to_screen_blt
+ * gfx_screen_to_screen_xblt
+ * gfx_color_bitmap_to_screen_blt
+ * gfx_color_bitmap_to_screen_xblt
+ * gfx_mono_bitmap_to_screen_blt
+ * gfx_bresenham_line
+ * gfx_wait_until_idle
+ *
+ * Extended rendering routines for second generation functionality:
+ * gfx2_set_source_stride
+ * gfx2_set_destination_stride
+ * gfx2_set_pattern_origins
+ * gfx2_set_source_transparency
+ * gfx2_set_alpha_mode
+ * gfx2_set_alpha_value
+ * gfx2_pattern_fill
+ * gfx2_color_pattern_fill
+ * gfx2_screen_to_screen_blt
+ * gfx2_mono_expand_blt
+ * gfx2_color_bitmap_to_screen_blt
+ * gfx2_mono_bitmap_to_screen_blt
+ * gfx2_bresenham_line
+ * gfx2_sync_to_vblank
+ * */
+
+#define GU2_WAIT_PENDING \
+ while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
+#define GU2_WAIT_BUSY \
+ while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
+#define GU2_WAIT_HALF_EMPTY \
+ while(!(READ_GP32(MGP_BLT_STATUS) & MGP_BS_HALF_EMPTY))
+
+/* PATTERN SWIZZLES */
+
+#define WORD_SWIZZLE(x) (((x) << 16) | ((x) >> 16))
+#define BYTE_SWIZZLE(x) (((x) << 24) | ((x) >> 24) | (((x) << 8) & \
+ 0x00FF0000) | (((x) >> 8) & 0x0000FF00))
+
+/* GLOBAL VARIABLES USED BY THE RENDERING ROUTINES */
+
+unsigned long gu2_bpp;
+unsigned long gu2_pitch = 1280;
+unsigned long gu2_src_pitch = 1280;
+unsigned long gu2_dst_pitch = 1280;
+unsigned long gu2_xshift = 1;
+unsigned long gu2_pattern_origin = 0;
+unsigned long gu2_rop32;
+unsigned long gu2_alpha32 = 0;
+unsigned long gu2_alpha_value = 0;
+unsigned long gu2_alpha_mode = 0;
+unsigned long gu2_alpha_active = 0;
+unsigned short gu2_alpha_blt_mode = 0;
+unsigned short gu2_alpha_vec_mode = 0;
+unsigned short gu2_blt_mode = 0;
+unsigned short gu2_vector_mode = 0;
+unsigned short gu2_bm_throttle = 0;
+unsigned short gu2_vm_throttle = 0;
+int gu2_current_line = 0;
+
+/*---------------------------------------------------------------------------
+ * GFX_RESET_PITCH (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine resets all pitches in the graphics engine to one value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_reset_pitch(unsigned short pitch)
+#else
+void
+gfx_reset_pitch(unsigned short pitch)
+#endif
+{
+ gu2_pitch = pitch;
+ gu2_dst_pitch = pitch;
+ gu2_src_pitch = pitch;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX_SET_BPP
+ *
+ * This routine sets the bits per pixel value in the graphics engine.
+ * It is also stored in the static variable "gu2_bpp" to use in the future
+ * calls to the rendering routines. That variable contains the hardware
+ * specific value to load into the MGP_RASTER_MODE register.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_set_bpp(unsigned short bpp)
+#else
+void
+gfx_set_bpp(unsigned short bpp)
+#endif
+{
+ GFXbpp = bpp;
+
+ /* COVERT TO BPP/FORMAT VALUE */
+ /* Save in global to combine with ROP later. */
+ /* Could write register here and then use byte access for */
+ /* the ROP, but would need to set other 24 bits to make */
+ /* sure all are set to their appropriate values. */
+
+ switch (bpp) {
+ case 8:
+ gu2_bpp = MGP_RM_BPPFMT_332;
+ gu2_xshift = 0;
+ break;
+ case 12:
+ gu2_bpp = MGP_RM_BPPFMT_4444;
+ gu2_xshift = 1;
+ break;
+ case 15:
+ gu2_bpp = MGP_RM_BPPFMT_1555;
+ gu2_xshift = 1;
+ break;
+ case 16:
+ gu2_bpp = MGP_RM_BPPFMT_565;
+ gu2_xshift = 1;
+ break;
+ case 32:
+ gu2_bpp = MGP_RM_BPPFMT_8888;
+ gu2_xshift = 2;
+ break;
+ }
+
+ /* SET INITIAL ROP BASED ONLY ON BPP */
+ /* Needs to be set before loading any pattern or source colors. */
+ /* We must wait for BUSY because these bits are not pipelined */
+ /* in the hardware. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_bpp);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_SOLID_SOURCE
+ *
+ * This routine is used to specify a solid source color. For the Xfree96
+ * display driver, the source color is used to specify a planemask and the
+ * ROP is adjusted accordingly.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_set_solid_source(unsigned long color)
+#else
+void
+gfx_set_solid_source(unsigned long color)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* WRITE REGISTERS TO SPECIFY SOURCE COLOR */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_SRC_COLOR_FG, color);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_MONO_SOURCE
+ *
+ * This routine is used to specify the monochrome source colors.
+ * It must be called *after* loading any pattern data (those routines
+ * clear the source flags).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent)
+#else
+void
+gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned short transparent)
+#endif
+{
+ /* SET TRANSPARENCY FLAG */
+
+ GFXsourceFlags = transparent ? MGP_RM_SRC_TRANS : 0;
+
+ /* WRITE COLOR VALUES */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_SRC_COLOR_FG, fgcolor);
+ WRITE_GP32(MGP_SRC_COLOR_BG, bgcolor);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_SOLID_PATTERN
+ *
+ * This routine is used to specify a solid pattern color. It is called
+ * before performing solid rectangle fills or more complicated BLTs that
+ * use a solid pattern color.
+ *
+ * The driver should always call "gfx_load_raster_operation" after a call
+ * to this routine to make sure that the pattern flags are set appropriately.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_set_solid_pattern(unsigned long color)
+#else
+void
+gfx_set_solid_pattern(unsigned long color)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* SET PATTERN FLAGS */
+
+ GFXpatternFlags = 0;
+
+ /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_bpp);
+ WRITE_GP32(MGP_PAT_COLOR_0, color);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_MONO_PATTERN
+ *
+ * This routine is used to specify a monochrome pattern.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparent)
+#else
+void
+gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned char transparent)
+#endif
+{
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* SET PATTERN FLAGS */
+
+ if (transparent)
+ GFXpatternFlags = MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS;
+ else
+ GFXpatternFlags = MGP_RM_PAT_MONO;
+
+ /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GFXpatternFlags);
+ WRITE_GP32(MGP_PAT_COLOR_0, bgcolor);
+ WRITE_GP32(MGP_PAT_COLOR_1, fgcolor);
+ WRITE_GP32(MGP_PAT_DATA_0, data0);
+ WRITE_GP32(MGP_PAT_DATA_1, data1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_COLOR_PATTERN
+ *
+ * This routine is used to specify a color pattern.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned long data2,
+ unsigned long data3, unsigned char transparent)
+#else
+void
+gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, unsigned long data2,
+ unsigned long data3, unsigned char transparent)
+#endif
+{
+ /* REMOVE */
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_LOAD_COLOR_PATTERN_LINE
+ *
+ * This routine is used to load a single line of a 8x8 color pattern.
+ *--------------------------------------------------------------------------- */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8)
+#else
+void
+gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8)
+#endif
+{
+ unsigned long temp1, temp2, temp3, temp4;
+
+ /* CLEAR TRANSPARENCY FLAG */
+
+ GFXsourceFlags = 0;
+
+ /* SET PATTERN FLAGS */
+
+ GFXpatternFlags = MGP_RM_PAT_COLOR;
+
+ /* OVERRIDE THE RASTER MODE REGISTER */
+ /* If the pattern format is set to anything but color */
+ /* before loading the registers, some of the data will */
+ /* be duplicated according to the current mode. */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE,
+ (gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR);
+
+ /* LOAD THE PATTERN DATA */
+ /* This routine is designed to work in tandem with gfx_pattern_fill. */
+ /* It is used for cases when multiple BLTs with color pattern data */
+ /* are desired on the same line. It would be inefficient to */
+ /* repeatedly call gfx_color_pattern_fill for each single-line BLT. */
+ /* So, we will simply replicate the pattern data across all available */
+ /* lines such that the pattern y origin plays no part in the BLT. */
+
+ /* 8 BPP */
+
+ if (gu2_xshift == 0) {
+ pattern_8x8 += (y & 7) << 1;
+ temp1 = BYTE_SWIZZLE(pattern_8x8[0]);
+ temp2 = BYTE_SWIZZLE(pattern_8x8[1]);
+ WRITE_GP32(MGP_PAT_DATA_1, temp1);
+ WRITE_GP32(MGP_PAT_DATA_0, temp2);
+ WRITE_GP32(MGP_PAT_COLOR_1, temp1);
+ WRITE_GP32(MGP_PAT_COLOR_0, temp2);
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_3, temp1);
+ WRITE_GP32(MGP_PAT_COLOR_2, temp2);
+ WRITE_GP32(MGP_PAT_COLOR_5, temp1);
+ WRITE_GP32(MGP_PAT_COLOR_4, temp2);
+ } else if (gu2_xshift == 1) {
+ pattern_8x8 += (y & 7) << 2;
+ temp1 = WORD_SWIZZLE(pattern_8x8[0]);
+ temp2 = WORD_SWIZZLE(pattern_8x8[1]);
+ temp3 = WORD_SWIZZLE(pattern_8x8[2]);
+ temp4 = WORD_SWIZZLE(pattern_8x8[3]);
+
+ WRITE_GP32(MGP_PAT_COLOR_1, temp1);
+ WRITE_GP32(MGP_PAT_COLOR_0, temp2);
+ WRITE_GP32(MGP_PAT_DATA_1, temp3);
+ WRITE_GP32(MGP_PAT_DATA_0, temp4);
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_5, temp1);
+ WRITE_GP32(MGP_PAT_COLOR_4, temp2);
+ WRITE_GP32(MGP_PAT_COLOR_3, temp3);
+ WRITE_GP32(MGP_PAT_COLOR_2, temp4);
+ } else {
+ pattern_8x8 += (y & 7) << 3;
+
+ WRITE_GP32(MGP_PAT_COLOR_1, pattern_8x8[4]);
+ WRITE_GP32(MGP_PAT_COLOR_0, pattern_8x8[5]);
+ WRITE_GP32(MGP_PAT_DATA_1, pattern_8x8[6]);
+ WRITE_GP32(MGP_PAT_DATA_0, pattern_8x8[7]);
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_5, pattern_8x8[0]);
+ WRITE_GP32(MGP_PAT_COLOR_4, pattern_8x8[1]);
+ WRITE_GP32(MGP_PAT_COLOR_3, pattern_8x8[2]);
+ WRITE_GP32(MGP_PAT_COLOR_2, pattern_8x8[3]);
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * GFX_SET_RASTER_OPERATION
+ *
+ * This routine loads the specified raster operation. It sets the pattern
+ * flags appropriately.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_set_raster_operation(unsigned char rop)
+#else
+void
+gfx_set_raster_operation(unsigned char rop)
+#endif
+{
+ gu2_blt_mode = 0;
+
+ /* DISABLE ALPHA BLENDING */
+
+ gu2_alpha_active = 0;
+
+ /* GENERATE 32-BIT VERSION OF ROP WITH PATTERN FLAGS */
+
+ gu2_rop32 = (unsigned long)rop | GFXpatternFlags | gu2_bpp;
+
+ /* CHECK IF SOURCE FLAGS SHOULD BE MERGED */
+
+ if ((rop & 0x33) ^ ((rop >> 2) & 0x33))
+ gu2_rop32 |= GFXsourceFlags;
+ else
+ gu2_blt_mode = 0x40;
+
+ /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */
+ /* True if even bits (0:2:4:6) do not equal the corresponding */
+ /* even bits (1:3:5:7). */
+
+ if ((rop & 0x55) ^ ((rop >> 1) & 0x55)) {
+ gu2_blt_mode |= MGP_BM_DST_REQ;
+ gu2_vector_mode = MGP_VM_DST_REQ;
+ } else {
+ gu2_vector_mode = 0;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * GFX_PATTERN_FILL
+ *
+ * This routine is used to fill a rectangular region. The pattern must
+ * be previously loaded using one of GFX_load_*_pattern routines. Also, the
+ * raster operation must be previously specified using the
+ * "GFX_load_raster_operation" routine.
+ *
+ * X screen X position (left)
+ * Y screen Y position (top)
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height)
+#else
+void
+gfx_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long offset = 0, size;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* CALCULATE STARTING OFFSET */
+
+ offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift);
+
+ /* CHECK IF PATTERN ORIGINS NEED TO BE SET */
+
+ if (GFXpatternFlags) {
+ /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
+
+ offset |= ((unsigned long)(x & 7)) << 26;
+ offset |= ((unsigned long)(y & 7)) << 29;
+ }
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
+ WRITE_GP32(MGP_DST_OFFSET, offset);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_pitch);
+ WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode);
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * GFX_COLOR_PATTERN_FILL
+ *
+ * This routine is used to render a rectangle using the current raster
+ * operation and the specified color pattern. It allows an 8x8 color
+ * pattern to be rendered without multiple calls to the gfx_set_color_pattern
+ * and gfx_pattern_fill routines.
+ *
+ * X screen X position (left)
+ * Y screen Y position (top)
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *PATTERN pointer to 8x8 color pattern data
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern)
+#else
+void
+gfx_color_pattern_fill(unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, unsigned long *pattern)
+#endif
+{
+ /* CALL GFX2 ROUTINE TO AVOID DUPLICATION OF CODE */
+
+ unsigned long offset = (unsigned long)y * gu2_pitch +
+ (((unsigned long)x) << gu2_xshift);
+ unsigned long origin = gu2_pattern_origin;
+ unsigned long pitch = gu2_dst_pitch;
+
+ gfx2_set_pattern_origin(x, y);
+ gfx2_set_destination_stride((unsigned short)gu2_pitch);
+ gfx2_color_pattern_fill(offset, width, height, pattern);
+
+ /* RESTORE GFX2 VALUES */
+
+ gu2_pattern_origin = origin;
+ gu2_dst_pitch = pitch;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * SCREEN TO SCREEN BLT
+ *
+ * This routine should be used to perform a screen to screen BLT when the
+ * ROP does not require destination data.
+ *
+ * SRCX screen X position to copy from
+ * SRCY screen Y position to copy from
+ * DSTX screen X position to copy to
+ * DSTY screen Y position to copy to
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height)
+#else
+void
+gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height)
+#endif
+{
+ unsigned long srcoffset, dstoffset, size;
+ unsigned short blt_mode;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* CALCULATE THE DIRECTION OF THE BLT */
+
+ blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_FB;
+ if (dstx > srcx) {
+ blt_mode |= MGP_BM_NEG_XDIR;
+ srcx += width - 1;
+ dstx += width - 1;
+ }
+ if (dsty > srcy) {
+ blt_mode |= MGP_BM_NEG_YDIR;
+ srcy += height - 1;
+ dsty += height - 1;
+ }
+
+ /* CALCULATE STARTING OFFSETS */
+
+ srcoffset = (unsigned long)srcy *gu2_pitch +
+ (((unsigned long)srcx) << gu2_xshift);
+ dstoffset = ((unsigned long)dsty * gu2_pitch +
+ (((unsigned long)dstx) << gu2_xshift)) & 0xFFFFFF;
+
+ /* MERGE PATTERN INFORMATION */
+ /* This must be done after the x and y coordinates have been updated, */
+ /* as the x and y pattern origins correspond to the first ROPed pixel. */
+
+ if (GFXpatternFlags) {
+ /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
+
+ dstoffset |= ((unsigned long)(dstx & 7)) << 26;
+ dstoffset |= ((unsigned long)(dsty & 7)) << 29;
+ }
+
+ /* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */
+ /* This is a quirk of the hardware. */
+
+ if (blt_mode & MGP_BM_NEG_XDIR) {
+ srcoffset += (1 << gu2_xshift) - 1;
+ dstoffset += (1 << gu2_xshift) - 1;
+ }
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_pitch | (gu2_pitch << 16));
+ WRITE_GP16(MGP_BLT_MODE, blt_mode);
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * SCREEN TO SCREEN TRANSPARENT BLT
+ *
+ * This routine should be used to perform a screen to screen BLT when a
+ * specified color should by transparent. The only supported ROP is SRCCOPY.
+ *
+ * SRCX screen X position to copy from
+ * SRCY screen Y position to copy from
+ * DSTX screen X position to copy to
+ * DSTY screen Y position to copy to
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * COLOR transparent color
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color)
+#else
+void
+gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned long color)
+#endif
+{
+ unsigned long rop32;
+
+ /* SAVE ORIGINAL RASTER MODE SETTINGS */
+
+ rop32 = gu2_rop32;
+
+ /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */
+ /* Match GU1 implementation that only allows SRCCOPY for the ROP. */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_SRC_COLOR_FG, color);
+ WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF);
+
+ /* SET GLOBAL RASTER SETTINGS */
+ /* This is needed, as the screen-to-screen BLT */
+ /* routine will overwrite the raster mode register. */
+
+ gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC;
+
+ /* CALL NORMAL SCREEN TO SCREEN BLT ROUTINE */
+
+ gfx_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height);
+
+ /* RESTORE GLOBAL RASTER SETTINGS */
+
+ gu2_rop32 = rop32;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * COLOR BITMAP TO SCREEN BLT
+ *
+ * This routine transfers color bitmap data to the screen.
+ *
+ * SRCX X offset within source bitmap
+ * SRCY Y offset within source bitmap
+ * DSTX screen X position to render data
+ * DSTY screen Y position to render data
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *DATA pointer to bitmap data
+ * PITCH pitch of bitmap data (bytes between scanlines)
+ *
+ * Transparency is handled by another routine.
+ *----------------------------------------------------------------------------
+ */
+
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch)
+#else
+void
+gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch)
+#endif
+{
+ unsigned long dstoffset, srcoffset, size, bytes;
+ unsigned long offset, temp_offset;
+ unsigned long dword_bytes, bytes_extra;
+ unsigned short blt_mode;
+
+ blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_FB;
+ size = (((unsigned long)width) << 16) | 1;
+
+ /* CALCULATE STARTING OFFSETS */
+
+ offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift);
+
+ dstoffset = (unsigned long)dsty *gu2_pitch +
+ (((unsigned long)dstx) << gu2_xshift);
+
+ /* CHECK IF PATTERN ORIGINS NEED TO BE SET */
+
+ if (GFXpatternFlags) {
+ /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
+
+ dstoffset |= ((unsigned long)(dstx & 7)) << 26;
+ dstoffset |= ((unsigned long)(dsty & 7)) << 29;
+ }
+
+ bytes = width << gu2_xshift;
+ dword_bytes = bytes & ~0x3L;
+ bytes_extra = bytes & 0x3L;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+ /* The source offset is always 0 since we allow misaligned dword reads. */
+ /* We must wait for BLT busy because the GP may be executing a screen */
+ /* to screen BLT from the scratchpad area. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_pitch);
+
+ /* WRITE DATA ONE LINE AT A TIME */
+ /* For speed reasons, data is written to an offscreen scratch area and then */
+ /* BLTed using a screen to screen BLT. This is similar to the GX1 BLT buffers, but */
+ /* slightly more efficient in that we can queue up data while the GP is rendering */
+ /* a line. */
+
+ while (height--) {
+ temp_offset = offset;
+ srcoffset = gfx_gx2_scratch_base;
+ if (gu2_current_line)
+ srcoffset += 8192;
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset);
+ dstoffset += gu2_pitch;
+ dstoffset += 0x20000000;
+
+ WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data,
+ temp_offset);
+ if (bytes_extra) {
+ temp_offset += dword_bytes;
+ srcoffset += dword_bytes;
+ WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data,
+ temp_offset);
+ }
+ WRITE_GP16(MGP_BLT_MODE, blt_mode);
+ offset += pitch;
+ gu2_current_line = 1 - gu2_current_line;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * COLOR BITMAP TO SCREEN TRANSPARENT BLT
+ *
+ * This routine transfers color bitmap data to the screen with transparency.
+ * The transparent color is specified. The only supported ROP is SRCCOPY,
+ * meaning that transparency cannot be applied if the ROP requires
+ * destination data (this is a hardware restriction).
+ *
+ * SRCX X offset within source bitmap
+ * SRCY Y offset within source bitmap
+ * DSTX screen X position to render data
+ * DSTY screen Y position to render data
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *DATA pointer to bitmap data
+ * PITCH pitch of bitmap data (bytes between scanlines)
+ * COLOR transparent color
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch,
+ unsigned long color)
+#else
+void
+gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, long pitch,
+ unsigned long color)
+#endif
+{
+ unsigned long rop32;
+
+ /* SAVE EXISTING RASTER MODE SETTINGS */
+
+ rop32 = gu2_rop32;
+
+ /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */
+ /* Match GU1 implementation that only allows SRCCOPY for the ROP. */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_SRC_COLOR_FG, color);
+ WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF);
+
+ /* SET GLOBAL RASTER SETTINGS */
+ /* This is needed, as the screen-to-screen BLT */
+ /* routine will overwrite the raster mode register. */
+
+ gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC;
+
+ /* CALL NORMAL COLOR BITMAP TO SCREEN BLT ROUTINE */
+
+ gfx_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height,
+ data, pitch);
+
+ /* RESTORE RASTER SETTINGS */
+
+ gu2_rop32 = rop32;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * MONOCHROME BITMAP TO SCREEN BLT
+ *
+ * This routine transfers monochrome bitmap data to the screen.
+ *
+ * SRCX X offset within source bitmap
+ * SRCY Y offset within source bitmap
+ * DSTX screen X position to render data
+ * DSTY screen Y position to render data
+ * WIDTH width of rectangle, in pixels
+ * HEIGHT height of rectangle, in scanlines
+ * *DATA pointer to bitmap data
+ * PITCH pitch of bitmap data (bytes between scanlines)
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#else
+void
+gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#endif
+{
+ unsigned long dstoffset, size, bytes;
+ unsigned long offset, temp_offset, temp1 = 0, temp2 = 0;
+ unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
+ unsigned long shift = 0;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* CALCULATE STARTING OFFSETS */
+
+ offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3);
+
+ dstoffset = (unsigned long)dsty *gu2_pitch +
+ (((unsigned long)dstx) << gu2_xshift);
+
+ /* CHECK IF PATTERN ORIGINS NEED TO BE SET */
+
+ if (GFXpatternFlags) {
+ /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
+
+ dstoffset |= ((unsigned long)(dstx & 7)) << 26;
+ dstoffset |= ((unsigned long)(dsty & 7)) << 29;
+ }
+
+ bytes = ((srcx & 7) + width + 7) >> 3;
+ fifo_lines = bytes >> 5;
+ dwords_extra = (bytes & 0x0000001Cl) >> 2;
+ bytes_extra = bytes & 0x00000003l;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+ /* The source offset is always 0 since we allow misaligned dword reads. */
+ /* Need to wait for busy instead of pending, since hardware clears */
+ /* the host data FIFO at the beginning of a BLT. */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_pitch);
+ WRITE_GP16(MGP_BLT_MODE,
+ (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_HOST |
+ MGP_BM_SRC_MONO);
+
+ /* WAIT FOR BLT TO BE LATCHED */
+
+ GU2_WAIT_PENDING;
+
+ /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */
+
+ while (height--) {
+ temp_offset = offset;
+
+ /* WRITE ALL FULL FIFO LINES */
+
+ for (i = 0; i < fifo_lines; i++) {
+ GU2_WAIT_HALF_EMPTY;
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset,
+ temp1);
+ temp_offset += 32;
+ }
+
+ /* WRITE ALL FULL DWORDS */
+
+ GU2_WAIT_HALF_EMPTY;
+ if (dwords_extra) {
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
+ temp_offset, temp1);
+ temp_offset += (dwords_extra << 2);
+ }
+
+ /* WRITE REMAINING BYTES */
+
+ shift = 0;
+ if (bytes_extra)
+ WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
+ temp_offset, temp1, temp2);
+
+ offset += pitch;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * GFX_TEXT_BLT
+ *
+ * This routine is similar to the gfx_mono_bitmap_to_screen_blt routine
+ * but assumes that source data is byte-packed.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data)
+#else
+void
+gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
+ unsigned short height, unsigned char *data)
+#endif
+{
+ unsigned long size, bytes;
+ unsigned long dstoffset, temp1 = 0, temp2 = 0, temp_offset = 0;
+ unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
+ unsigned long shift;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ dstoffset = (unsigned long)dsty *gu2_pitch +
+ (((unsigned long)dstx) << gu2_xshift);
+
+ /* CHECK IF PATTERN ORIGINS NEED TO BE SET */
+
+ if (GFXpatternFlags) {
+ /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
+
+ dstoffset |= ((unsigned long)(dstx & 7)) << 26;
+ dstoffset |= ((unsigned long)(dsty & 7)) << 29;
+ }
+
+ /* CALCULATE STARTING OFFSETS */
+
+ bytes = ((width + 7) >> 3) * height;
+ fifo_lines = bytes >> 5;
+ dwords_extra = (bytes & 0x0000001Cl) >> 2;
+ bytes_extra = bytes & 0x00000003l;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ WRITE_GP32(MGP_SRC_OFFSET, 0);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_pitch);
+ WRITE_GP16(MGP_BLT_MODE,
+ (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_HOST |
+ MGP_BM_SRC_BP_MONO);
+
+ /* WAIT FOR BLT TO BE LATCHED */
+
+ GU2_WAIT_PENDING;
+
+ /* WRITE ALL FULL FIFO LINES */
+
+ for (i = 0; i < fifo_lines; i++) {
+ GU2_WAIT_HALF_EMPTY;
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
+ temp_offset += 32;
+ }
+
+ /* WRITE ALL FULL DWORDS */
+
+ if (dwords_extra || bytes_extra) {
+ GU2_WAIT_HALF_EMPTY;
+ if (dwords_extra) {
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
+ temp_offset, temp1);
+ temp_offset += (dwords_extra << 2);
+ }
+ if (bytes_extra) {
+ shift = 0;
+ WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
+ temp_offset, temp1, temp2);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * BRESENHAM LINE
+ *
+ * This routine draws a vector using the specified Bresenham parameters.
+ * Currently this file does not support a routine that accepts the two
+ * endpoints of a vector and calculates the Bresenham parameters. If it
+ * ever does, this routine is still required for vectors that have been
+ * clipped.
+ *
+ * X screen X position to start vector
+ * Y screen Y position to start vector
+ * LENGTH length of the vector, in pixels
+ * INITERR Bresenham initial error term
+ * AXIALERR Bresenham axial error term
+ * DIAGERR Bresenham diagonal error term
+ * FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC
+ *----------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+#else
+void
+gfx_bresenham_line(unsigned short x, unsigned short y,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+#endif
+{
+ unsigned long offset;
+ unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr;
+ unsigned long data2 = (((unsigned long)length) << 16) | initerr;
+ unsigned short vector_mode = gu2_vector_mode | flags;
+
+ /* CALCULATE STARTING OFFSET */
+
+ offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift);
+
+ /* CHECK NULL LENGTH */
+
+ if (!length)
+ return;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
+ WRITE_GP32(MGP_DST_OFFSET, offset);
+ WRITE_GP32(MGP_VEC_ERR, data1);
+ WRITE_GP32(MGP_VEC_LEN, data2);
+ WRITE_GP32(MGP_STRIDE, gu2_pitch);
+ WRITE_GP32(MGP_VECTOR_MODE, vector_mode);
+}
+
+/*---------------------------------------------------------------------------
+ * GFX_WAIT_UNTIL_IDLE
+ *
+ * This routine waits until the graphics engine is idle. This is required
+ * before allowing direct access to the frame buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu2_wait_until_idle(void)
+#else
+void
+gfx_wait_until_idle(void)
+#endif
+{
+ while (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) ;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX_TEST_BLT_PENDING
+ *
+ * This routine returns 1 if a BLT is pending, meaning that a call to
+ * perform a rendering operation would stall. Otherwise it returns 0.
+ * It is used by Darwin during random testing to only start a BLT
+ * operation when it knows the Durango routines won't spin on graphics
+ * (so Darwin can continue to do frame buffer reads and writes).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+int
+gu2_test_blt_pending(void)
+#else
+int
+gfx_test_blt_pending(void)
+#endif
+{
+ if (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
+ return (1);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * NEW ROUTINES FOR REDCLOUD
+ *---------------------------------------------------------------------------
+ */
+
+/*---------------------------------------------------------------------------
+ * GFX2_SET_SOURCE_STRIDE
+ *
+ * This routine sets the stride to be used in successive screen to screen
+ * BLTs (used by gfx2_screen_to_screen_blt and gfx2_mono_expand_blt).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_set_source_stride(unsigned short stride)
+#else
+void
+gfx2_set_source_stride(unsigned short stride)
+#endif
+{
+ /* SAVE STRIDE TO BE USED LATER */
+
+ gu2_src_pitch = (unsigned long)stride;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_SET_DESTINATION_STRIDE
+ *
+ * This routine sets the stride used when rendering to the screen.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_set_destination_stride(unsigned short stride)
+#else
+void
+gfx2_set_destination_stride(unsigned short stride)
+#endif
+{
+ /* SAVE STRIDE TO BE USED LATER */
+
+ gu2_dst_pitch = (unsigned long)stride;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_SET_PATTERN_ORIGIN
+ *
+ * This routine sets the origin within an 8x8 pattern. It is needed if
+ * using a monochrome or color pattern (not used for a solid pattern).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_set_pattern_origin(int x, int y)
+#else
+void
+gfx2_set_pattern_origin(int x, int y)
+#endif
+{
+ /* STORE IN FORMAT THAT CAN BE COMBINED WITH THE DESTINATION OFFSET */
+
+ gu2_pattern_origin = (((unsigned long)(x & 7)) << 26) |
+ (((unsigned long)(y & 7)) << 29);
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_SET_SOURCE_TRANSPARENCY
+ *
+ * This routine sets the source transparency color and mask to be used
+ * in future rendering operations. If both the color and mask are set
+ * to zero (normally completely transparent), those values indicate that
+ * transparency should be disabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_set_source_transparency(unsigned long color, unsigned long mask)
+#else
+void
+gfx2_set_source_transparency(unsigned long color, unsigned long mask)
+#endif
+{
+ /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_SRC_COLOR_FG, color);
+ WRITE_GP32(MGP_SRC_COLOR_BG, mask);
+
+ /* SET TRANSPARENCY FLAG */
+
+ GFXsourceFlags = (color || mask) ? MGP_RM_SRC_TRANS : 0;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_SET_ALPHA_MODE
+ *
+ * This routine sets the alpha blending mode to be used in successive
+ * rendering operations.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_set_alpha_mode(int mode)
+#else
+void
+gfx2_set_alpha_mode(int mode)
+#endif
+{
+ /* SAVE ALPHA MODE FOR LATER */
+
+ gu2_alpha_mode = mode;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_SET_ALPHA_VALUE
+ *
+ * This routine sets the alpha value to be used with certain alpha blending
+ * modes (ALPHA_MODE_BLEND).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_set_alpha_value(unsigned char value)
+#else
+void
+gfx2_set_alpha_value(unsigned char value)
+#endif
+{
+ /* SAVE ALPHA VALUE TO BE USED LATER */
+
+ gu2_alpha_value = (unsigned long)value;
+
+ /* SET GLOBAL FLAG */
+ /* gfx2_* routines will use this flag to program alpha values */
+ /* appropriately. Normal gfx_* routines will always write */
+ /* the current ROP settings. In this way, the alpha mode */
+ /* affects only second generation routines. */
+
+ gu2_alpha_active = 1;
+
+ switch (gu2_alpha_mode) {
+ case ALPHA_MODE_BLEND:
+
+ /* GENERATE 32-BIT VERSION OF RASTER MODE REGISTER */
+ /* Pattern data is not involved in the operation. */
+
+ gu2_alpha32 = gu2_alpha_value | gu2_bpp;
+
+ /* HANDLE SPECIAL CASES FOR ENDPOINTS */
+ /* The 8-bit hardware alpha value is always */
+ /* interpreted as a fraction. Consequently, there */
+ /* is no way to use values of 255 or 0 to exclude */
+ /* one of the inputs. */
+
+ switch (gu2_alpha_value) {
+ /* DESTINATION ONLY */
+ /* Operation is alpha * A, where A is destination */
+ /* and alpha is 1. */
+
+ case 0:
+
+ gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 |
+ MGP_RM_ALPHA_TIMES_A |
+ MGP_RM_ALPHA_TO_RGB | MGP_RM_DEST_FROM_CHAN_A;
+ break;
+
+ /* SOURCE ONLY */
+ /* Operation is alpha * A, where A is source and */
+ /* alpha is 1. */
+
+ case 255:
+
+ gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 |
+ MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_TIMES_A;
+ break;
+
+ /* DEFAULT */
+ /* Operation is alpha * A + (1 - alpha) * B; */
+ /* A is source, B is destination and alpha is the */
+ /* programmed 8-bit value. */
+
+ default:
+
+ gu2_alpha32 |= MGP_RM_SELECT_ALPHA_R |
+ MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_A_PLUS_BETA_B;
+
+ }
+
+ /* CHECK IF SOURCE INFORMATION SHOULD BE MERGED */
+ /* Alpha value of 0 indicates destination only. */
+
+ if (gu2_alpha_value != 0)
+ gu2_alpha32 |= GFXsourceFlags;
+
+ /* SET FLAG FOR DESTINATION DATA IF NECESSARY */
+ /* Alpha value of 255 indicates no destination */
+
+ if (gu2_alpha_value != 255) {
+ gu2_alpha_blt_mode = MGP_BM_DST_REQ;
+ gu2_alpha_vec_mode = MGP_VM_DST_REQ;
+ }
+
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_PATTERN_FILL
+ *
+ * This routine is similar to the gfx_pattern_fill routine, but allows the
+ * use of an arbitrary destination stride. The rendering position is
+ * also specified as an offset instead of an (x,y) position.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height)
+#else
+void
+gfx2_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height)
+#endif
+{
+ unsigned long size;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
+ WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_COLOR_PATTERN_FILL
+ *
+ * This routine is used to render a rectangle using the current raster
+ * operation and the specified color pattern. It allows an 8x8 color
+ * pattern to be rendered without multiple calls to the gfx_set_color_pattern
+ * and gfx_pattern_fill routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned long *pattern)
+#else
+void
+gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned long *pattern)
+#endif
+{
+ int pass;
+ unsigned long lines, size, patxorigin, patoffset;
+
+ /* ONLY USE HW PATTERN ORIGIN FOR THE X DIRECTION */
+ /* Y direction handled by referencing proper location in pattern data. */
+
+ patxorigin = (gu2_pattern_origin) & 0x1C000000;
+
+ /* OVERRIDE PATTERN FLAGS IN ROP TO FORCE COLOR PATTERN */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_RASTER_MODE,
+ (gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR);
+
+ /* ATTEMPT TO OPTIMIZE */
+ /* If possible, we can perform the pattern fill in only a few passes */
+ /* This is performed by multiplying the pitch by an appropriate amount. */
+ /* Consequently, if the multiplied pitch exceeds 16 bits, this */
+ /* optimization is impossible. */
+
+ if ((gu2_dst_pitch << (gu2_xshift + 1)) <= 0xFFFF) {
+ /* HANDLE VARIOUS COLOR DEPTHS DIFFERENTLY */
+
+ switch (gu2_xshift) {
+ case 0: /* 8 BPP */
+
+ /* TWO PASSES FOR 8 BPP */
+ /* Render every other line per pass by doubling the pitch. */
+
+ patoffset = (gu2_pattern_origin >> 28) & 0x0E;
+ for (pass = 0; pass < 2; pass++) {
+ /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
+ lines = (height + 1 - pass) >> 1;
+ if (!lines)
+ break;
+ size = (((unsigned long)width) << 16) | lines;
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 1);
+ WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_DATA_0,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ patoffset = (patoffset + 4) & 0x0E;
+ WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_0,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ patoffset = (patoffset + 4) & 0x0E;
+
+ /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
+ /* Those registers are not pipelined. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_2,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ patoffset = (patoffset + 4) & 0x0E;
+ WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_4,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+
+ /* ADJUST FOR NEXT PASS */
+
+ dstoffset += gu2_dst_pitch;
+ patoffset = (patoffset + 6) & 0x0E;
+ }
+ break;
+
+ case 1: /* 12, 15, OR 16 BPP */
+
+ /* FOUR PASSES FOR 16 BPP */
+ /* Render every 4th line per pass by quadrupling the pitch. */
+
+ patoffset = (gu2_pattern_origin >> 27) & 0x1C;
+ for (pass = 0; pass < 4; pass++) {
+ /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
+ lines = (height + 3 - pass) >> 2;
+ if (!lines)
+ break;
+ size = (((unsigned long)width) << 16) | lines;
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 2);
+ WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_0,
+ WORD_SWIZZLE(pattern[patoffset + 1]));
+ WRITE_GP32(MGP_PAT_DATA_1,
+ WORD_SWIZZLE(pattern[patoffset + 2]));
+ WRITE_GP32(MGP_PAT_DATA_0,
+ WORD_SWIZZLE(pattern[patoffset + 3]));
+ patoffset = (patoffset + 16) & 0x1C;
+
+ /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
+ /* Those registers are not pipelined. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_4,
+ WORD_SWIZZLE(pattern[patoffset + 1]));
+ WRITE_GP32(MGP_PAT_COLOR_3,
+ WORD_SWIZZLE(pattern[patoffset + 2]));
+ WRITE_GP32(MGP_PAT_COLOR_2,
+ WORD_SWIZZLE(pattern[patoffset + 3]));
+ WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+
+ /* ADJUST FOR NEXT PASS */
+
+ dstoffset += gu2_dst_pitch;
+ patoffset = (patoffset + 20) & 0x1C;
+ }
+ break;
+
+ case 2: /* 32 BPP */
+
+ /* EIGHT PASSES FOR 32 BPP */
+ /* Render every 8th line per pass by setting pitch * 8. */
+
+ patoffset = (gu2_pattern_origin >> 26) & 0x38;
+ for (pass = 0; pass < 8; pass++) {
+ /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
+ lines = (height + 7 - pass) >> 3;
+ if (!lines)
+ break;
+ size = (((unsigned long)width) << 16) | lines;
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 3);
+ WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]);
+ WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]);
+ WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]);
+ WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]);
+
+ /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
+ /* Those registers are not pipelined. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]);
+ WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]);
+ WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]);
+ WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]);
+ WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+
+ /* ADJUST FOR NEXT PASS */
+
+ dstoffset += gu2_dst_pitch;
+ patoffset = (patoffset + 8) & 0x38;
+ }
+ break;
+ }
+ }
+
+ else {
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
+
+ switch (gu2_xshift) {
+ case 0: /* 8 BPP - 4 LINES PER PASS */
+
+ patoffset = (gu2_pattern_origin >> 28) & 0x0E;
+ while (height) {
+ lines = height > 4 ? 4 : height;
+
+ /* CAN WRITE SOME REGISTERS WHILE PENDING */
+
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
+ WRITE_GP32(MGP_WID_HEIGHT,
+ (((unsigned long)width) << 16) | lines);
+ WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_DATA_0,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ patoffset = (patoffset + 2) & 0x0E;
+ WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_0,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ patoffset = (patoffset + 2) & 0x0E;
+
+ /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
+ /* Those registers are not pipelined. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_2,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ patoffset = (patoffset + 2) & 0x0E;
+ WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_4,
+ BYTE_SWIZZLE(pattern[patoffset + 1]));
+ patoffset = (patoffset + 2) & 0x0E;
+ WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
+
+ /* ADJUST FOR NEXT PASS */
+
+ dstoffset += gu2_dst_pitch << 2;
+ height -= (unsigned short)lines;
+ }
+ break;
+
+ case 1: /* 12, 15 AND 16 BPP - 2 LINES PER PASS */
+
+ patoffset = (gu2_pattern_origin >> 27) & 0x1C;
+ while (height) {
+ lines = height > 2 ? 2 : height;
+
+ /* CAN WRITE SOME REGISTERS WHILE PENDING */
+
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
+ WRITE_GP32(MGP_WID_HEIGHT,
+ (((unsigned long)width) << 16) | lines);
+ WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_0,
+ WORD_SWIZZLE(pattern[patoffset + 1]));
+ WRITE_GP32(MGP_PAT_DATA_1,
+ WORD_SWIZZLE(pattern[patoffset + 2]));
+ WRITE_GP32(MGP_PAT_DATA_0,
+ WORD_SWIZZLE(pattern[patoffset + 3]));
+ patoffset = (patoffset + 4) & 0x1C;
+
+ /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
+ /* Those registers are not pipelined. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset]));
+ WRITE_GP32(MGP_PAT_COLOR_4,
+ WORD_SWIZZLE(pattern[patoffset + 1]));
+ WRITE_GP32(MGP_PAT_COLOR_3,
+ WORD_SWIZZLE(pattern[patoffset + 2]));
+ WRITE_GP32(MGP_PAT_COLOR_2,
+ WORD_SWIZZLE(pattern[patoffset + 3]));
+ patoffset = (patoffset + 4) & 0x1C;
+ WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
+
+ /* ADJUST FOR NEXT PASS */
+
+ dstoffset += gu2_dst_pitch << 1;
+ height -= (unsigned short)lines;
+ }
+ break;
+
+ case 2: /* 32 BPP - 1 LINE PER PASS */
+
+ patoffset = (gu2_pattern_origin >> 26) & 0x38;
+ while (height) {
+ /* CAN WRITE SOME REGISTERS WHILE PENDING */
+
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
+ WRITE_GP32(MGP_WID_HEIGHT,
+ (((unsigned long)width) << 16) | 1l);
+ WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]);
+ WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]);
+ WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]);
+ WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]);
+
+ /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
+ /* Those registers are not pipelined. */
+
+ GU2_WAIT_BUSY;
+ WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]);
+ WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]);
+ WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]);
+ WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]);
+ patoffset = (patoffset + 8) & 0x38;
+ WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
+
+ /* ADJUST FOR NEXT PASS */
+
+ dstoffset += gu2_dst_pitch;
+ height--;
+ }
+ break;
+ }
+
+ }
+
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_SCREEN_TO_SCREEN_BLT
+ *
+ * This routine is similar to the gfx_screen_to_screen_blt routine but
+ * allows the use of arbitrary source and destination strides and alpha
+ * blending. It also allows the use of an arbitrary ROP with transparency.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset,
+ unsigned short width, unsigned short height, int flags)
+#else
+void
+gfx2_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset,
+ unsigned short width, unsigned short height, int flags)
+#endif
+{
+ unsigned long size, xbytes;
+ unsigned short blt_mode;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* USE ALPHA SETTINGS, IF REQUESTED */
+
+ if (gu2_alpha_active)
+ blt_mode = gu2_alpha_blt_mode | MGP_BM_SRC_FB;
+
+ else
+ blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_FB;
+
+ /* CALCULATE THE DIRECTION OF THE BLT */
+ /* Using offsets, so flags from the calling routine are needed. */
+
+ if (flags & 1) {
+ xbytes = (width - 1) << gu2_xshift;
+ srcoffset += xbytes;
+ dstoffset += xbytes;
+ blt_mode |= MGP_BM_NEG_XDIR;
+ }
+ if (flags & 2) {
+ srcoffset += (height - 1) * gu2_src_pitch;
+ dstoffset += (height - 1) * gu2_dst_pitch;
+ blt_mode |= MGP_BM_NEG_YDIR;
+ }
+
+ /* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */
+ /* This is a quirk of the hardware. */
+
+ if (blt_mode & MGP_BM_NEG_XDIR) {
+ srcoffset += (1 << gu2_xshift) - 1;
+ dstoffset += (1 << gu2_xshift) - 1;
+ }
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+
+ GU2_WAIT_PENDING;
+
+ if (gu2_alpha_active) {
+ WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
+ } else {
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ }
+
+ WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16));
+ WRITE_GP16(MGP_BLT_MODE, blt_mode | gu2_bm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_MONO_EXPAND_BLT
+ *
+ * This routine is similar to the gfx2_screen_to_screen_blt routine but
+ * expands monochrome data stored in graphics memory.
+ * WARNING: This routine assumes that the regions in graphics memory
+ * will not overlap, and therefore does not check the BLT direction.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
+ unsigned short srcy, unsigned long dstoffset, unsigned short width,
+ unsigned short height, int byte_packed)
+#else
+void
+gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
+ unsigned short srcy, unsigned long dstoffset, unsigned short width,
+ unsigned short height, int byte_packed)
+#endif
+{
+ unsigned long size, srcoffset;
+ unsigned short blt_mode;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* CALCULATE SOURCE OFFSET */
+
+ srcoffset = srcbase + (unsigned long)srcy *gu2_src_pitch;
+
+ srcoffset += srcx >> 3;
+ srcoffset |= ((unsigned long)srcx & 7) << 26;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+
+ GU2_WAIT_PENDING;
+
+ if (gu2_alpha_active) {
+ blt_mode = gu2_alpha_blt_mode;
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
+ } else {
+ blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ }
+
+ if (byte_packed)
+ blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_BP_MONO | gu2_bm_throttle;
+ else
+ blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_MONO | gu2_bm_throttle;
+
+ WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16));
+ WRITE_GP16(MGP_BLT_MODE, blt_mode);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_COLOR_BITMAP_TO_SCREEN_BLT
+ *
+ * This routine is similar to the gfx_color_bitmap_to_screen_blt routine
+ * but allows the use of an arbitrary destination stride and alpha blending.
+ * It also allows the use of an arbitrary ROP with transparency.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#else
+void
+gfx2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#endif
+{
+ unsigned long size, bytes;
+ unsigned long offset, temp_offset;
+ unsigned long srcoffset, dword_bytes, bytes_extra;
+ unsigned short blt_mode;
+
+ size = (((unsigned long)width) << 16) | 1;
+
+ /* CALCULATE STARTING OFFSETS */
+
+ offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift);
+
+ dstoffset |= gu2_pattern_origin;
+
+ bytes = width << gu2_xshift;
+ dword_bytes = bytes & ~0x3L;
+ bytes_extra = bytes & 0x3L;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+ /* The source offset is always 0 since we allow misaligned dword reads. */
+ /* We must wait for BLT busy because the GP may be executing a screen */
+ /* to screen BLT from the scratchpad area. */
+
+ GU2_WAIT_BUSY;
+
+ if (gu2_alpha_active) {
+ blt_mode = gu2_alpha_blt_mode;
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
+ } else {
+ blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ }
+ blt_mode |= MGP_BM_SRC_FB | gu2_bm_throttle;
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+
+ /* WRITE DATA ONE LINE AT A TIME */
+ /* For speed reasons, data is written to an offscreen scratch area and
+ * then BLTed using a screen to screen BLT. This is similar to the GX1 BLT
+ * buffers, but slightly more efficient in that we can queue up data while
+ * the GP is rendering a line.
+ * */
+
+ while (height--) {
+ temp_offset = offset;
+ srcoffset = gfx_gx2_scratch_base;
+ if (gu2_current_line)
+ srcoffset += 8192;
+
+ GU2_WAIT_PENDING;
+ WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset);
+ dstoffset += gu2_dst_pitch;
+ dstoffset += 0x20000000;
+
+ WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data,
+ temp_offset);
+ if (bytes_extra) {
+ temp_offset += dword_bytes;
+ srcoffset += dword_bytes;
+ WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data,
+ temp_offset);
+ }
+ WRITE_GP16(MGP_BLT_MODE, blt_mode);
+ offset += pitch;
+ gu2_current_line = 1 - gu2_current_line;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_TEXT_BLT
+ *
+ * This routine is similar to the gfx2_mono_bitmap_to_screen_blt routine
+ * but assumes that source data is byte-packed.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_text_blt(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data)
+#else
+void
+gfx2_text_blt(unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data)
+#endif
+{
+ unsigned long size, bytes;
+ unsigned long temp1 = 0, temp2 = 0, temp_offset = 0;
+ unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
+ unsigned long shift;
+ unsigned short blt_mode;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* CALCULATE STARTING OFFSETS */
+
+ bytes = ((width + 7) >> 3) * height;
+ fifo_lines = bytes >> 5;
+ dwords_extra = (bytes & 0x0000001Cl) >> 2;
+ bytes_extra = bytes & 0x00000003l;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+
+ GU2_WAIT_PENDING;
+
+ if (gu2_alpha_active) {
+ blt_mode = gu2_alpha_blt_mode;
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
+ } else {
+ blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ }
+
+ WRITE_GP32(MGP_SRC_OFFSET, 0);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
+ WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST |
+ MGP_BM_SRC_BP_MONO | gu2_bm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+
+ /* WAIT FOR BLT TO BE LATCHED */
+
+ GU2_WAIT_PENDING;
+
+ /* WRITE ALL FULL FIFO LINES */
+
+ for (i = 0; i < fifo_lines; i++) {
+ GU2_WAIT_HALF_EMPTY;
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
+ temp_offset += 32;
+ }
+
+ /* WRITE ALL FULL DWORDS */
+
+ if (dwords_extra || bytes_extra) {
+ GU2_WAIT_HALF_EMPTY;
+ if (dwords_extra) {
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
+ temp_offset, temp1);
+ temp_offset += (dwords_extra << 2);
+ }
+ if (bytes_extra) {
+ shift = 0;
+ WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
+ temp_offset, temp1, temp2);
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_MONO_BITMAP_TO_SCREEN_BLT
+ *
+ * This routine is similar to the gfx_mono_bitmap_to_screen_blt routine
+ * but allows the use of an arbitrary destination stride and alpha blending.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#else
+void
+gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
+ unsigned long dstoffset, unsigned short width,
+ unsigned short height, unsigned char *data, short pitch)
+#endif
+{
+ unsigned long size, bytes;
+ unsigned long offset, temp_offset, temp1 = 0, temp2 = 0;
+ unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
+ unsigned long shift = 0;
+ unsigned short blt_mode;
+
+ size = (((unsigned long)width) << 16) | height;
+
+ /* CALCULATE STARTING OFFSETS */
+
+ offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3);
+
+ bytes = ((srcx & 7) + width + 7) >> 3;
+ fifo_lines = bytes >> 5;
+ dwords_extra = (bytes & 0x0000001Cl) >> 2;
+ bytes_extra = bytes & 0x00000003l;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+
+ GU2_WAIT_PENDING;
+
+ if (gu2_alpha_active) {
+ blt_mode = gu2_alpha_blt_mode;
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
+ } else {
+ blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
+ }
+
+ WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26);
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
+ WRITE_GP32(MGP_WID_HEIGHT, size);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
+ WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST |
+ MGP_BM_SRC_MONO | gu2_bm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+
+ /* WAIT FOR BLT TO BE LATCHED */
+
+ GU2_WAIT_PENDING;
+
+ /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */
+
+ while (height--) {
+ temp_offset = offset;
+
+ /* WRITE ALL FULL FIFO LINES */
+
+ for (i = 0; i < fifo_lines; i++) {
+ GU2_WAIT_HALF_EMPTY;
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset,
+ temp1);
+ temp_offset += 32;
+ }
+
+ /* WRITE ALL FULL DWORDS */
+
+ GU2_WAIT_HALF_EMPTY;
+ if (dwords_extra)
+ WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
+ temp_offset, temp1);
+ temp_offset += (dwords_extra << 2);
+
+ /* WRITE REMAINING BYTES */
+
+ shift = 0;
+ if (bytes_extra)
+ WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
+ temp_offset, temp1, temp2);
+
+ offset += pitch;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_BRESENHAM_LINE
+ *
+ * This routine is similar to the gfx_bresenam_line routine but allows
+ * the use of an arbitrary destination stride.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_bresenham_line(unsigned long dstoffset,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+#else
+void
+gfx2_bresenham_line(unsigned long dstoffset,
+ unsigned short length, unsigned short initerr,
+ unsigned short axialerr, unsigned short diagerr, unsigned short flags)
+#endif
+{
+ unsigned long vector_mode = gu2_vector_mode | flags;
+ unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr;
+ unsigned long data2 = (((unsigned long)length) << 16) | initerr;
+
+ /* CHECK NULL LENGTH */
+
+ if (!length)
+ return;
+
+ /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
+ /* Put off poll for as long as possible (do most calculations first). */
+
+ GU2_WAIT_PENDING;
+
+ if (gu2_alpha_active) {
+ vector_mode = gu2_alpha_vec_mode | flags;
+
+ WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
+ } else
+ WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
+
+ WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
+ WRITE_GP32(MGP_VEC_ERR, data1);
+ WRITE_GP32(MGP_VEC_LEN, data2);
+ WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
+ WRITE_GP32(MGP_VECTOR_MODE, vector_mode | gu2_vm_throttle);
+ gu2_bm_throttle = 0;
+ gu2_vm_throttle = 0;
+}
+
+/*---------------------------------------------------------------------------
+ * GFX2_SYNC_TO_VBLANK
+ *
+ * This routine sets a flag to synchronize the next rendering routine to
+ * VBLANK. The flag is cleared by the rendering routine.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_2DACCEL_DYNAMIC
+void
+gu22_sync_to_vblank(void)
+#else
+void
+gfx2_sync_to_vblank(void)
+#endif
+{
+ /* SET FLAGS TO THROTTLE NEXT RENDERING ROUTINE */
+
+ gu2_bm_throttle = MGP_BM_THROTTLE;
+ gu2_vm_throttle = MGP_VM_THROTTLE;
+}
+
+/* END OF FILE */
diff --git a/src/gfx/saa7114.c b/src/gfx/saa7114.c
new file mode 100644
index 0000000..df516bc
--- /dev/null
+++ b/src/gfx/saa7114.c
@@ -0,0 +1,916 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the Philips SAA7114 video decoder.
+ * */
+
+/*---------------------------*/
+/* TABLE OF DEFAULT VALUES */
+/*---------------------------*/
+
+typedef struct tagGFX_SAA7114_INIT
+{
+ unsigned char index;
+ unsigned char value;
+} GFX_SAA7114_INIT;
+
+/* Task A is for VBI raw data and task B is for video */
+
+GFX_SAA7114_INIT gfx_saa7114_init_values[] = {
+ {0x01, 0x08}, {0x02, 0xC0}, {0x03, 0x00}, {0x04, 0x90},
+ {0x05, 0x90}, {0x06, 0xEB}, {0x07, 0xE0}, {0x08, 0x88},
+ {0x09, 0x40}, {0x0A, 0x80}, {0x0B, 0x44}, {0x0C, 0x40},
+ {0x0D, 0x00}, {0x0E, 0x89}, {0x0F, 0x2E}, {0x10, 0x0E},
+ {0x11, 0x00}, {0x12, 0x05}, {0x13, 0x00}, {0x14, 0x08},
+ {0x15, 0x11}, {0x16, 0xFE}, {0x17, 0x00}, {0x18, 0x40},
+ {0x19, 0x80}, {0x30, 0xBC}, {0x31, 0xDF}, {0x32, 0x02},
+ {0x34, 0xCD}, {0x35, 0xCC}, {0x36, 0x3A}, {0x38, 0x03},
+ {0x39, 0x10}, {0x3A, 0x00}, {0x40, 0x00}, {0x41, 0xFF},
+ {0x42, 0xFF}, {0x43, 0xFF}, {0x44, 0xFF}, {0x45, 0xFF},
+ {0x46, 0xFF}, {0x47, 0xFF}, {0x48, 0xFF}, {0x49, 0xFF},
+ {0x4A, 0xFF}, {0x4B, 0xFF}, {0x4C, 0xFF}, {0x4D, 0xFF},
+ {0x4E, 0xFF}, {0x4F, 0xFF}, {0x50, 0xFF}, {0x51, 0xFF},
+ {0x52, 0xFF}, {0x53, 0xFF}, {0x54, 0xFF}, {0x55, 0xFF},
+ {0x56, 0xFF}, {0x57, 0xFF}, {0x58, 0x00}, {0x59, 0x47},
+ {0x5A, 0x06}, {0x5B, 0x43}, {0x5D, 0x3E}, {0x5E, 0x00},
+ {0x80, 0x30}, {0x83, 0x00}, {0x84, 0x60}, {0x85, 0x00},
+ {0x86, 0xE5}, {0x87, 0x01}, {0x88, 0xF8},
+
+ /* VBI task */
+
+ {0x90, 0x01}, {0x91, 0xC8}, {0x92, 0x08}, {0x93, 0x84},
+ {0x94, 0x10}, {0x95, 0x00}, {0x96, 0xD0}, {0x97, 0x02},
+ {0x98, 0x05}, {0x99, 0x00}, {0x9A, 0x0B}, {0x9B, 0x00},
+ {0x9C, 0xA0}, {0x9D, 0x05}, {0x9E, 0x0B}, {0x9F, 0x00},
+ {0xA0, 0x01}, {0xA1, 0x00}, {0xA2, 0x00}, {0xA4, 0x80},
+ {0xA5, 0x40}, {0xA6, 0x40}, {0xA8, 0x00}, {0xA9, 0x02},
+ {0xAA, 0x00}, {0xAC, 0x00}, {0xAD, 0x01}, {0xAE, 0x00},
+ {0xB0, 0x00}, {0xB1, 0x04}, {0xB2, 0x00}, {0xB3, 0x04},
+ {0xB4, 0x00}, {0xB8, 0x00}, {0xB9, 0x00}, {0xBA, 0x00},
+ {0xBB, 0x00}, {0xBC, 0x00}, {0xBD, 0x00}, {0xBE, 0x00},
+ {0xBF, 0x00},
+
+ /* Video task */
+
+ {0xC0, 0x80}, {0xC1, 0x08}, {0xC2, 0x00}, {0xC3, 0x80},
+ {0xC4, 0x10}, {0xC5, 0x00}, {0xC6, 0xD0}, {0xC7, 0x02},
+ {0xC8, 0x11}, {0xC9, 0x00}, {0xCA, 0xF1}, {0xCB, 0x00},
+ {0xCC, 0xD0}, {0xCD, 0x02}, {0xCE, 0xF1}, {0xCF, 0x00},
+ {0xD0, 0x01}, {0xD1, 0x00}, {0xD2, 0x00}, {0xD4, 0x80},
+ {0xD5, 0x40}, {0xD6, 0x40}, {0xD8, 0x00}, {0xD9, 0x04},
+ {0xDA, 0x00}, {0xDC, 0x00}, {0xDD, 0x02}, {0xDE, 0x00},
+ {0xE0, 0x00}, {0xE1, 0x04}, {0xE2, 0x00}, {0xE3, 0x04},
+ {0xE4, 0x00}, {0xE8, 0x00}, {0xE9, 0x00}, {0xEA, 0x00},
+ {0xEB, 0x00}, {0xEC, 0x00}, {0xED, 0x00}, {0xEE, 0x00},
+ {0xEF, 0x00},
+};
+
+#define GFX_NUM_SAA7114_INIT_VALUES \
+ sizeof(gfx_saa7114_init_values)/sizeof(GFX_SAA7114_INIT)
+
+/*-----------------------------------------------------*/
+/* TABLE OF FIR PREFILTER RECOMMENDED VALUES */
+/*-----------------------------------------------------*/
+
+int optimize_for_aliasing = 0;
+
+typedef struct tagGFX_SAA7114_FIR_PREFILTER
+{
+ unsigned char prescaler;
+ unsigned char acl_low;
+ unsigned char prefilter_low;
+ unsigned char acl_high;
+ unsigned char prefilter_high;
+} GFX_SAA7114_FIR_PREFILTER;
+
+GFX_SAA7114_FIR_PREFILTER gfx_saa7114_fir_values[] = {
+ {0x01, 0x00, 0x00, 0x00, 0x00}, {0x02, 0x02, 0x5A, 0x01, 0x51},
+ {0x03, 0x04, 0xAB, 0x03, 0xA2}, {0x04, 0x07, 0xA3, 0x04, 0xAB},
+ {0x05, 0x08, 0xAC, 0x07, 0xA3}, {0x06, 0x08, 0xFC, 0x07, 0xF3},
+ {0x07, 0x08, 0xFC, 0x07, 0xF3}, {0x08, 0x0F, 0xF4, 0x08, 0xFC},
+ {0x09, 0x0F, 0xF4, 0x08, 0xFC}, {0x0A, 0x10, 0xFD, 0x08, 0xFC},
+ {0x0B, 0x10, 0xFD, 0x08, 0xFC}, {0x0C, 0x10, 0xFD, 0x08, 0xFC},
+ {0x0D, 0x10, 0xFD, 0x10, 0xFD}, {0x0E, 0x10, 0xFD, 0x10, 0xFD},
+ {0x0F, 0x1F, 0xF5, 0x10, 0xFD}, {0x10, 0x20, 0xFE, 0x10, 0xFD},
+ {0x11, 0x20, 0xFE, 0x10, 0xFD}, {0x12, 0x20, 0xFE, 0x10, 0xFD},
+ {0x13, 0x20, 0xFE, 0x20, 0xFE}, {0x14, 0x20, 0xFE, 0x20, 0xFE},
+ {0x15, 0x20, 0xFE, 0x20, 0xFE}, {0x16, 0x20, 0xFE, 0x20, 0xFE},
+ {0x17, 0x20, 0xFE, 0x20, 0xFE}, {0x18, 0x20, 0xFE, 0x20, 0xFE},
+ {0x19, 0x20, 0xFE, 0x20, 0xFE}, {0x1A, 0x20, 0xFE, 0x20, 0xFE},
+ {0x1B, 0x20, 0xFE, 0x20, 0xFE}, {0x1C, 0x20, 0xFE, 0x20, 0xFE},
+ {0x1D, 0x20, 0xFE, 0x20, 0xFE}, {0x1E, 0x20, 0xFE, 0x20, 0xFE},
+ {0x1F, 0x20, 0xFE, 0x20, 0xFE}, {0x20, 0x3F, 0xFF, 0x20, 0xFE},
+ {0x21, 0x3F, 0xFF, 0x20, 0xFE}, {0x22, 0x3F, 0xFF, 0x20, 0xFE},
+ {0x23, 0x3F, 0xFF, 0x20, 0xFF}
+};
+
+int
+saa7114_write_reg(unsigned char reg, unsigned char val)
+{
+ return gfx_i2c_write(2, SAA7114_CHIPADDR, reg, 1, &val);
+}
+
+int
+saa7114_read_reg(unsigned char reg, unsigned char *val)
+{
+ return gfx_i2c_read(2, SAA7114_CHIPADDR, reg, 1, val);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_vbi_upscale
+ *
+ * This routine configures the video decoder task A to upscale raw VBI data
+ * horizontally to match a different system clock.
+ * The upscale is from 13.5 MHz (SAA7114) to 14.318 MHz (Bt835).
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_vbi_upscale(void)
+#else
+int
+gfx_set_decoder_vbi_upscale(void)
+#endif
+{
+ /* Set horizontal output length to 1528 (720 * 2 * 14.318 / 13.5) */
+ saa7114_write_reg(SAA7114_TASK_A_HORZ_OUTPUT_LO, 0xF8);
+ saa7114_write_reg(SAA7114_TASK_A_HORZ_OUTPUT_HI, 0x05);
+
+ /* Set horizontal luminance scaling increment to 484 (1024 * 13.5 /
+ * 28.636) */
+ saa7114_write_reg(SAA7114_TASK_A_HSCALE_LUMA_LO, 0xE4);
+ saa7114_write_reg(SAA7114_TASK_A_HSCALE_LUMA_HI, 0x01);
+
+ /* Set horizontal chrominance scaling increment to 242 */
+ saa7114_write_reg(SAA7114_TASK_A_HSCALE_CHROMA_LO, 0xF2);
+ saa7114_write_reg(SAA7114_TASK_A_HSCALE_CHROMA_HI, 0x00);
+
+ return GFX_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_decoder_software_reset
+ *
+ * This routine performs a software reset of the decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_decoder_software_reset(void)
+#else
+int
+gfx_decoder_software_reset(void)
+#endif
+{
+ saa7114_write_reg(0x88, 0xC0);
+ /* I2C-bus latency should be sufficient for resetting the internal state
+ * machine. */
+ /* gfx_delay_milliseconds(10); */
+ saa7114_write_reg(0x88, 0xF0);
+ return GFX_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_decoder_detect_macrovision
+ *
+ * This routine detects if macrovision exists in the input of the video
+ * decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_decoder_detect_macrovision(void)
+#else
+int
+gfx_decoder_detect_macrovision(void)
+#endif
+{
+ unsigned char macrovision = 0xff;
+
+ saa7114_read_reg(SAA7114_STATUS, &macrovision);
+ return ((macrovision & 0x02) >> 1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_decoder_detect_video
+ *
+ * This routine detects if video exists in the input of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_decoder_detect_video(void)
+#else
+int
+gfx_decoder_detect_video(void)
+#endif
+{
+ unsigned char video = 0xff;
+
+ saa7114_read_reg(SAA7114_STATUS, &video);
+ return !((video & 0x40) >> 6);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_defaults
+ *
+ * This routine is called to set the initial register values of the
+ * video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_defaults(void)
+#else
+int
+gfx_set_decoder_defaults(void)
+#endif
+{
+ unsigned int i;
+
+ /* LOOP THROUGH INDEX/DATA PAIRS IN THE TABLE */
+
+ for (i = 0; i < GFX_NUM_SAA7114_INIT_VALUES; i++) {
+ saa7114_write_reg(gfx_saa7114_init_values[i].index,
+ gfx_saa7114_init_values[i].value);
+ }
+
+ gfx_decoder_software_reset();
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_analog_input
+ *
+ * This routine sets the analog input of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_analog_input(unsigned char input)
+#else
+int
+gfx_set_decoder_analog_input(unsigned char input)
+#endif
+{
+ saa7114_write_reg(SAA7114_ANALOG_INPUT_CTRL1, input);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_brightness
+ *
+ * This routine sets the brightness of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_brightness(unsigned char brightness)
+#else
+int
+gfx_set_decoder_brightness(unsigned char brightness)
+#endif
+{
+ saa7114_write_reg(SAA7114_BRIGHTNESS, brightness);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_contrast
+ *
+ * This routine sets the contrast of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_contrast(unsigned char contrast)
+#else
+int
+gfx_set_decoder_contrast(unsigned char contrast)
+#endif
+{
+ saa7114_write_reg(SAA7114_CONTRAST, (unsigned char)(contrast >> 1));
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_hue
+ *
+ * This routine sets the hue control of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_hue(char hue)
+#else
+int
+gfx_set_decoder_hue(char hue)
+#endif
+{
+ saa7114_write_reg(SAA7114_HUE, (unsigned char)hue);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_saturation
+ *
+ * This routine sets the saturation adjustment of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_saturation(unsigned char saturation)
+#else
+int
+gfx_set_decoder_saturation(unsigned char saturation)
+#endif
+{
+ saa7114_write_reg(SAA7114_SATURATION, (unsigned char)(saturation >> 1));
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_input_offset
+ *
+ * This routine sets the size of the decoder input window.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_input_offset(unsigned short x, unsigned short y)
+#else
+int
+gfx_set_decoder_input_offset(unsigned short x, unsigned short y)
+#endif
+{
+ /* SET THE INPUT WINDOW OFFSET */
+
+ saa7114_write_reg(SAA7114_HORZ_OFFSET_LO, (unsigned char)(x & 0x00FF));
+ saa7114_write_reg(SAA7114_HORZ_OFFSET_HI, (unsigned char)(x >> 8));
+ saa7114_write_reg(SAA7114_VERT_OFFSET_LO, (unsigned char)(y & 0x00FF));
+ saa7114_write_reg(SAA7114_VERT_OFFSET_HI, (unsigned char)(y >> 8));
+
+ gfx_decoder_software_reset();
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_input_size
+ *
+ * This routine sets the size of the decoder input window.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_input_size(unsigned short width, unsigned short height)
+#else
+int
+gfx_set_decoder_input_size(unsigned short width, unsigned short height)
+#endif
+{
+ /* DIVIDE HEIGHT BY TWO FOR INTERLACING */
+
+ height = (height + 1) >> 1;
+
+ /* SET THE INPUT WINDOW SIZE */
+
+ saa7114_write_reg(SAA7114_HORZ_INPUT_LO, (unsigned char)(width & 0x00FF));
+ saa7114_write_reg(SAA7114_HORZ_INPUT_HI, (unsigned char)(width >> 8));
+ saa7114_write_reg(SAA7114_VERT_INPUT_LO,
+ (unsigned char)(height & 0x00FF));
+ saa7114_write_reg(SAA7114_VERT_INPUT_HI, (unsigned char)(height >> 8));
+
+ gfx_decoder_software_reset();
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_output_size
+ *
+ * This routine sets the size of the decoder output window.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_output_size(unsigned short width, unsigned short height)
+#else
+int
+gfx_set_decoder_output_size(unsigned short width, unsigned short height)
+#endif
+{
+ /* ROUND WIDTH UP TO EVEN NUMBER TO PREVENT DECODER BECOMING STUCK */
+
+ width = ((width + 1) >> 1) << 1;
+
+ /* DIVIDE HEIGHT BY TWO FOR INTERLACING */
+
+ height = (height + 1) >> 1;
+
+ /* SET THE OUTPUT WINDOW SIZE */
+
+ saa7114_write_reg(SAA7114_HORZ_OUTPUT_LO,
+ (unsigned char)(width & 0x00FF));
+ saa7114_write_reg(SAA7114_HORZ_OUTPUT_HI, (unsigned char)(width >> 8));
+ saa7114_write_reg(SAA7114_VERT_OUTPUT_LO,
+ (unsigned char)(height & 0x00FF));
+ saa7114_write_reg(SAA7114_VERT_OUTPUT_HI, (unsigned char)(height >> 8));
+
+ gfx_decoder_software_reset();
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_scale
+ *
+ * This routine sets the scaling of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth)
+#else
+int
+gfx_set_decoder_scale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth)
+#endif
+{
+ unsigned char prescale = 0;
+ int scale = 0;
+
+ /* SET THE HORIZONTAL PRESCALE */
+ /* Downscale from 1 to 1/63 source size. */
+
+ if (dstw)
+ prescale = (unsigned char)(srcw / dstw);
+ if (!prescale)
+ prescale = 1;
+ if (prescale > 63)
+ return (1);
+ saa7114_write_reg(SAA7114_HORZ_PRESCALER, prescale);
+
+ /* USE FIR PREFILTER FUNCTIONALITY (OPTIMISATION) */
+
+ if (prescale < 36) {
+ if (optimize_for_aliasing) {
+ saa7114_write_reg(SAA7114_HORZ_ACL,
+ gfx_saa7114_fir_values[prescale - 1].acl_low);
+ saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER,
+ gfx_saa7114_fir_values[prescale - 1].prefilter_low);
+ } else {
+ saa7114_write_reg(SAA7114_HORZ_ACL,
+ gfx_saa7114_fir_values[prescale - 1].acl_high);
+ saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER,
+ gfx_saa7114_fir_values[prescale - 1].prefilter_high);
+ }
+ } else {
+ /* SAME SETTINGS FOR RATIO 1/35 DOWNTO 1/63 */
+ if (optimize_for_aliasing) {
+ saa7114_write_reg(SAA7114_HORZ_ACL,
+ gfx_saa7114_fir_values[34].acl_low);
+ saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER,
+ gfx_saa7114_fir_values[34].prefilter_low);
+ } else {
+ saa7114_write_reg(SAA7114_HORZ_ACL,
+ gfx_saa7114_fir_values[34].acl_high);
+ saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER,
+ gfx_saa7114_fir_values[34].prefilter_high);
+ }
+ }
+
+ /* SET THE HORIZONTAL SCALING */
+
+ if (!dstw)
+ return (1);
+ scale = ((1024 * srcw * 1000) / (dstw * prescale)) / 1000;
+ if ((scale > 8191) || (scale < 300))
+ return (1);
+ saa7114_write_reg(SAA7114_HSCALE_LUMA_LO,
+ (unsigned char)(scale & 0x00FF));
+ saa7114_write_reg(SAA7114_HSCALE_LUMA_HI, (unsigned char)(scale >> 8));
+ scale >>= 1;
+ saa7114_write_reg(SAA7114_HSCALE_CHROMA_LO,
+ (unsigned char)(scale & 0x00FF));
+ saa7114_write_reg(SAA7114_HSCALE_CHROMA_HI, (unsigned char)(scale >> 8));
+
+ /* SET THE VERTICAL SCALING (INTERPOLATION MODE) */
+
+ if (!dsth)
+ return (1);
+
+ /* ROUND DESTINATION HEIGHT UP TO EVEN NUMBER TO PREVENT DECODER BECOMING
+ * STUCK */
+
+ dsth = ((dsth + 1) >> 1) << 1;
+
+ scale = (int)((1024 * srch) / dsth);
+ saa7114_write_reg(SAA7114_VSCALE_LUMA_LO,
+ (unsigned char)(scale & 0x00FF));
+ saa7114_write_reg(SAA7114_VSCALE_LUMA_HI, (unsigned char)(scale >> 8));
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_LO,
+ (unsigned char)(scale & 0x00FF));
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_HI, (unsigned char)(scale >> 8));
+
+ if (dsth >= (srch >> 1)) {
+ /* USE INTERPOLATION MODE FOR SCALE FACTOR ABOVE 0.5 */
+
+ saa7114_write_reg(SAA7114_VSCALE_CONTROL, 0x00);
+
+ /* SET VERTICAL PHASE REGISTER FOR CORRECT SCALED INTERLACED OUTPUT
+ * (OPTIMISATION) */
+ /* THE OPTIMISATION IS BASED ON OFIDC = 0 (REG 90h[6] = 0 ) */
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS0, SAA7114_VSCALE_PHO);
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS1, SAA7114_VSCALE_PHO);
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS2,
+ (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 16));
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS3,
+ (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 16));
+
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS0, SAA7114_VSCALE_PHO);
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS1, SAA7114_VSCALE_PHO);
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS2,
+ (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 16));
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS3,
+ (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 16));
+
+ /* RESTORE CONTRAST AND SATURATION FOR INTERPOLATION MODE */
+
+ saa7114_write_reg(SAA7114_FILTER_CONTRAST, (unsigned char)0x40);
+ saa7114_write_reg(SAA7114_FILTER_SATURATION, (unsigned char)0x40);
+ } else {
+ /* USE ACCUMULATION MODE FOR DOWNSCALING BY MORE THAN 2x */
+
+ saa7114_write_reg(SAA7114_VSCALE_CONTROL, 0x01);
+
+ /* SET VERTICAL PHASE OFFSETS OFF (OPTIMISATION) */
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS0, 0x00);
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS1, 0x00);
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS2, 0x00);
+ saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS3, 0x00);
+
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS0, 0x00);
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS1, 0x00);
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS2, 0x00);
+ saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS3, 0x00);
+
+ /* ADJUST CONTRAST AND SATURATION FOR ACCUMULATION MODE */
+
+ if (srch)
+ scale = (64 * dsth) / srch;
+ saa7114_write_reg(SAA7114_FILTER_CONTRAST, (unsigned char)scale);
+ saa7114_write_reg(SAA7114_FILTER_SATURATION, (unsigned char)scale);
+ }
+
+ gfx_decoder_software_reset();
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_vbi_format
+ *
+ * This routine programs the decoder to produce the specified format of VBI
+ * data for the specified lines.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_vbi_format(int start, int end, int format)
+#else
+int
+gfx_set_decoder_vbi_format(int start, int end, int format)
+#endif
+{
+ int i;
+ unsigned char data;
+
+ for (i = start; i <= end; i++) {
+ switch (format) {
+ case VBI_FORMAT_VIDEO:
+ data = 0xFF;
+ break; /* Active video */
+ case VBI_FORMAT_RAW:
+ data = 0x77;
+ break; /* Raw VBI data */
+ case VBI_FORMAT_CC:
+ data = 0x55;
+ break; /* US CC */
+ case VBI_FORMAT_NABTS:
+ data = 0xCC;
+ break; /* US NABTS */
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ saa7114_write_reg((unsigned char)(0x3F + i), data);
+ }
+ return GFX_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_vbi_enable
+ *
+ * This routine enables or disables VBI transfer in the decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_vbi_enable(int enable)
+#else
+int
+gfx_set_decoder_vbi_enable(int enable)
+#endif
+{
+ unsigned char data;
+
+ saa7114_read_reg(SAA7114_IPORT_CONTROL, &data);
+ if (enable)
+ data |= 0x80;
+ else
+ data &= ~0x80;
+ saa7114_write_reg(SAA7114_IPORT_CONTROL, data);
+ return GFX_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_TV_standard
+ *
+ * This routine configures the decoder for the required TV standard.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_TV_standard(TVStandardType TVStandard)
+#else
+int
+gfx_set_decoder_TV_standard(TVStandardType TVStandard)
+#endif
+{
+ switch (TVStandard) {
+ case TV_STANDARD_NTSC:
+ saa7114_write_reg(0x0E, 0x89);
+ saa7114_write_reg(0x5A, 0x06);
+ break;
+ case TV_STANDARD_PAL:
+ saa7114_write_reg(0x0E, 0x81);
+ saa7114_write_reg(0x5A, 0x03);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ gfx_decoder_software_reset();
+ return GFX_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_decoder_luminance_filter
+ *
+ * This routine sets the hue control of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_set_decoder_luminance_filter(unsigned char lufi)
+#else
+int
+gfx_set_decoder_luminance_filter(unsigned char lufi)
+#endif
+{
+ unsigned char data;
+
+ saa7114_read_reg(SAA7114_LUMINANCE_CONTROL, &data);
+ saa7114_write_reg(SAA7114_LUMINANCE_CONTROL,
+ (unsigned char)((data & ~0x0F) | (lufi & 0x0F)));
+ return (0);
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_brightness
+ *
+ * This routine returns the current brightness of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+unsigned char
+saa7114_get_decoder_brightness(void)
+#else
+unsigned char
+gfx_get_decoder_brightness(void)
+#endif
+{
+ unsigned char brightness = 0;
+
+ saa7114_read_reg(SAA7114_BRIGHTNESS, &brightness);
+ return (brightness);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_contrast
+ *
+ * This routine returns the current contrast of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+unsigned char
+saa7114_get_decoder_contrast(void)
+#else
+unsigned char
+gfx_get_decoder_contrast(void)
+#endif
+{
+ unsigned char contrast = 0;
+
+ saa7114_read_reg(SAA7114_CONTRAST, &contrast);
+ contrast <<= 1;
+ return (contrast);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_hue
+ *
+ * This routine returns the current hue of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+char
+saa7114_get_decoder_hue(void)
+#else
+char
+gfx_get_decoder_hue(void)
+#endif
+{
+ unsigned char hue = 0;
+
+ saa7114_read_reg(SAA7114_HUE, &hue);
+ return ((char)hue);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_saturation
+ *
+ * This routine returns the current saturation of the video decoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+unsigned char
+saa7114_get_decoder_saturation(void)
+#else
+unsigned char
+gfx_get_decoder_saturation(void)
+#endif
+{
+ unsigned char saturation = 0;
+
+ saa7114_read_reg(SAA7114_SATURATION, &saturation);
+ saturation <<= 1;
+ return (saturation);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_input_offset
+ *
+ * This routine returns the offset into the input window.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+unsigned long
+saa7114_get_decoder_input_offset(void)
+#else
+unsigned long
+gfx_get_decoder_input_offset(void)
+#endif
+{
+ unsigned long value = 0;
+ unsigned char data;
+
+ saa7114_read_reg(SAA7114_HORZ_OFFSET_LO, &data);
+ value = (unsigned long)data;
+ saa7114_read_reg(SAA7114_HORZ_OFFSET_HI, &data);
+ value |= ((unsigned long)data) << 8;
+ saa7114_read_reg(SAA7114_VERT_OFFSET_LO, &data);
+ value |= ((unsigned long)data) << 16;
+ saa7114_read_reg(SAA7114_VERT_OFFSET_HI, &data);
+ value |= ((unsigned long)data) << 24;
+ return (value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_input_size
+ *
+ * This routine returns the current size of the input window
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+unsigned long
+saa7114_get_decoder_input_size(void)
+#else
+unsigned long
+gfx_get_decoder_input_size(void)
+#endif
+{
+ unsigned long value = 0;
+ unsigned char data;
+
+ saa7114_read_reg(SAA7114_HORZ_INPUT_LO, &data);
+ value = (unsigned long)data;
+ saa7114_read_reg(SAA7114_HORZ_INPUT_HI, &data);
+ value |= ((unsigned long)data) << 8;
+ saa7114_read_reg(SAA7114_VERT_INPUT_LO, &data);
+ value |= ((unsigned long)data) << 17;
+ saa7114_read_reg(SAA7114_VERT_INPUT_HI, &data);
+ value |= ((unsigned long)data) << 25;
+ return (value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_output_size
+ *
+ * This routine returns the current size of the output window.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+unsigned long
+saa7114_get_decoder_output_size(void)
+#else
+unsigned long
+gfx_get_decoder_output_size(void)
+#endif
+{
+ unsigned long value = 0;
+ unsigned char data;
+
+ saa7114_read_reg(SAA7114_HORZ_OUTPUT_LO, &data);
+ value = (unsigned long)data;
+ saa7114_read_reg(SAA7114_HORZ_OUTPUT_HI, &data);
+ value |= ((unsigned long)data) << 8;
+ saa7114_read_reg(SAA7114_VERT_OUTPUT_LO, &data);
+ value |= ((unsigned long)data) << 17;
+ saa7114_read_reg(SAA7114_VERT_OUTPUT_HI, &data);
+ value |= ((unsigned long)data) << 25;
+ return (value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_decoder_vbi_format
+ *
+ * This routine returns the current format of VBI data for the specified line.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DECODER_DYNAMIC
+int
+saa7114_get_decoder_vbi_format(int line)
+#else
+int
+gfx_get_decoder_vbi_format(int line)
+#endif
+{
+ unsigned char format = 0, data;
+
+ saa7114_read_reg((unsigned char)(0x3F + line), &data);
+ switch (data) {
+ case 0xFF:
+ format = VBI_FORMAT_VIDEO;
+ break; /* Active video */
+ case 0x77:
+ format = VBI_FORMAT_RAW;
+ break; /* Raw VBI data */
+ case 0x55:
+ format = VBI_FORMAT_CC;
+ break; /* US CC */
+ case 0xCC:
+ format = VBI_FORMAT_NABTS;
+ break; /* US NABTS */
+ }
+ return (format);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/tv_1200.c b/src/gfx/tv_1200.c
new file mode 100644
index 0000000..a75cc32
--- /dev/null
+++ b/src/gfx/tv_1200.c
@@ -0,0 +1,967 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the SC1200 TVOUT and TV encoder.
+ * */
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_format
+ *
+ * This routine sets the TV encoder registers to the specified format
+ * and resolution.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_format(TVStandardType format, GfxOnTVType resolution)
+#else
+int
+gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution)
+#endif
+{
+ unsigned long ctrl2, mode;
+
+ /* Save TV output mode */
+ ctrl2 =
+ READ_VID32(SC1200_TVENC_TIM_CTRL_2) & (SC1200_TVENC_OUTPUT_YCBCR |
+ SC1200_TVENC_CFS_MASK);
+ /* Save flicker filter setting */
+ mode =
+ READ_VID32(SC1200_TVOUT_HORZ_SCALING) &
+ SC1200_TVOUT_FLICKER_FILTER_MASK;
+
+ switch (format) {
+ case TV_STANDARD_NTSC:
+ /* Horizontal Sync Start is 848 */
+ /* Horizontal Sync End is 856 */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, 0x03580350);
+ /* Vertical Sync Start is 0 */
+ /* Vertical Sync End is 1 */
+ /* Vertical Display Start Skew is 1 */
+ /* Vertical Display End Skew is 1 */
+ WRITE_VID32(SC1200_TVOUT_VERT_SYNC, 0x05001000);
+ /* Disable vertical down scaling, take all lines */
+ if (gfx_chip_revision <= SC1200_REV_B3)
+ WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE, 0xffffffff);
+ /* Enable video timing */
+ /* Reset sub carrier every two frames */
+ /* Disable BLANK */
+ /* Enable color burst */
+ /* Add the IRE offset */
+ /* NTSC color encoding */
+ /* Video generator timing is 525 lines / 60Hz */
+ /* Horizontal and Vertical counters are initialized to HPHASE &
+ * VPHASE */
+ /* VPHASE is 2, HPHASE is 0x50 */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 0xa2a01050);
+ /* Increase horizontal blanking interval */
+ /* Low Water Mark for Y is 0x1F */
+ /* Low Water Mark for Cb is 0xF */
+ /* HUE is 0 */
+ /* SCPHASE is 0xF9 */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, 0x9ff000f9 | ctrl2);
+ /* Subcarrier Frequency is 3.579545 MHz */
+ WRITE_VID32(SC1200_TVENC_SUB_FREQ, 0x21f07c1f);
+ /* VSTART is 18, HSTART is 113 */
+ WRITE_VID32(SC1200_TVENC_DISP_POS, 0x00120071);
+ /* Display size: HEIGHT is 239, WIDTH is 719 */
+ WRITE_VID32(SC1200_TVENC_DISP_SIZE, 0x00ef02cf);
+ switch (resolution) {
+ case GFX_ON_TV_SQUARE_PIXELS:
+ if (gfx_chip_revision <= SC1200_REV_B3) {
+ /* Horizontal Display start is 116 */
+ /* Total number of pixels per line is 857 */
+ WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x00740359);
+ /* HSYNC generated in the TV Encoder module */
+ /* Interval between resets of TV Encoder is once every odd
+ * field */
+ /* Enable Horizontal interpolation */
+ /* Enable Horizontal up scaling 9/8 */
+ /* Disable Horizontal downscale */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020700 | mode);
+ /* Horizontal display end is 919, i.e. 720 active pixels */
+ /* Total number of display lines per field is 240 */
+ WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039700f0);
+ } else { /* Use new scaler available in Rev. C */
+ /* Horizontal Display start is 111 */
+ /* Total number of pixels per line is 857 */
+ WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x006f0359);
+ /* HSYNC generated in the TV Encoder module */
+ /* Interval between resets of TV Encoder is once every odd
+ * field */
+ /* Enable Horizontal interpolation */
+ /* Disable Horizontal up scaling 9/8 */
+ /* Disable Horizontal downscale */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode);
+ /* Set Horizontal upscaling to 64/58 (~ 11/10) */
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x3A000000);
+ /* Horizontal display end is 900, i.e. 706 active pixels */
+ /* Total number of display lines per field is 240 */
+ WRITE_VID32(SC1200_TVOUT_LINE_END, 0x038400f0);
+ }
+ break;
+ case GFX_ON_TV_NO_SCALING:
+ /* Horizontal Display start is 116 */
+ /* Total number of pixels per line is 857 */
+ WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x00740359);
+ /* HSYNC generated in the TV Encoder module */
+ /* Interval between resets of TV Encoder is once every odd field */
+ /* Enable Horizontal interpolation */
+ /* Disable Horizontal up scaling 9/8 */
+ /* Disable Horizontal downscale */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode);
+ /* Disable Horizontal scaling (set to 64/64) */
+ if (gfx_chip_revision >= SC1200_REV_C1)
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x40000000);
+ /* Horizontal display end is 919, i.e. 720 active pixels */
+ /* Total number of display lines per field is 240 */
+ WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039700f0);
+ break;
+ default:
+ return (GFX_STATUS_BAD_PARAMETER);
+ }
+ break;
+ case TV_STANDARD_PAL:
+ /* Horizontal Sync Start is 854 */
+ /* Horizontal Sync End is 862 */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, 0x035e0356);
+ /* Vertical Sync Start is 0 */
+ /* Vertical Sync End is 1 */
+ /* Vertical Display Start Skew is 1 */
+ /* Vertical Display End Skew is 1 */
+ WRITE_VID32(SC1200_TVOUT_VERT_SYNC, 0x05001000);
+ /* Disable vertical down scaling, take all lines */
+ if (gfx_chip_revision <= SC1200_REV_B3)
+ WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE, 0xffffffff);
+ /* Enable video timing */
+ /* Never reset sub carrier (should be every 4 frames but doesn't work
+ * with genlock) */
+ /* Disable BLANK */
+ /* Enable color burst */
+ /* Do not add the IRE offset */
+ /* NTSC color encoding */
+ /* Video generator timing is 625 lines / 50Hz */
+ /* Horizontal and Vertical counters are initialized to HPHASE & VPHASE
+ * */
+ /* VPHASE is 2, HPHASE is 50 */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, 0xB1201050);
+ /* Increase horizontal blanking interval */
+ /* Low Water Mark for Y is 0x1F */
+ /* Low Water Mark for Cb is 0xF */
+ /* HUE is 0 */
+ /* SCPHASE is 0xD9 */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, 0x9ff000d9 | ctrl2);
+ /* Subcarrier Frequency is 4.43361875 MHz */
+ WRITE_VID32(SC1200_TVENC_SUB_FREQ, 0x2a098acb);
+ /* VSTART is 22, HSTART is 123 */
+ WRITE_VID32(SC1200_TVENC_DISP_POS, 0x0016007b);
+ /* Display size: HEIGHT is 287, WIDTH is 719 */
+ WRITE_VID32(SC1200_TVENC_DISP_SIZE, 0x011f02cf);
+ switch (resolution) {
+ case GFX_ON_TV_NO_SCALING:
+ /* Horizontal Display start is 124 */
+ /* Total number of pixels per line is 863 */
+ WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x007c035f);
+ /* HSYNC generated in the TV Encoder module */
+ /* Interval between resets of TV Encoder is once every odd field */
+ /* Enable Horizontal interpolation */
+ /* Disable Horizontal up scaling 9/8 */
+ /* Disable Horizontal downscale */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode);
+ /* Disable Horizontal scaling (set to 64/64) */
+ if (gfx_chip_revision >= SC1200_REV_C1)
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x40000000);
+ /* Horizontal display end is 924, i.e. 720 active pixels */
+ /* Total number of display lines per field is 288 */
+ WRITE_VID32(SC1200_TVOUT_LINE_END, 0x039c0120);
+ break;
+ case GFX_ON_TV_SQUARE_PIXELS:
+ /* Horizontal Display start is 122 */
+ /* Total number of pixels per line is 863 */
+ WRITE_VID32(SC1200_TVOUT_HORZ_TIM, 0x007a035f);
+ if (gfx_chip_revision <= SC1200_REV_B3) {
+ /* HSYNC generated in the TV Encoder module */
+ /* Interval between resets of TV Encoder is once every odd
+ * field */
+ /* Enable Horizontal interpolation */
+ /* Disable Horizontal up scaling 9/8 */
+ /* Horizontal downscale m/(m+1), m = 11, (i.e. 11/12 - closest
+ * possible to 54/59) */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x1002040b | mode);
+ /* Horizontal display end is 906, i.e. 704 active pixels */
+ /* Total number of display lines per field is 288 */
+ WRITE_VID32(SC1200_TVOUT_LINE_END, 0x038a0120);
+ } else {
+ /* HSYNC generated in the TV Encoder module */
+ /* Interval between resets of TV Encoder is once every odd
+ * field */
+ /* Enable Horizontal interpolation */
+ /* Disable Horizontal up scaling 9/8 */
+ /* Disable Horizontal downscale */
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, 0x10020500 | mode);
+ /* Set Horizontal down scaling to 64/70 (closest possible to
+ * 54/59) */
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE, 0x46000000);
+ /* Horizontal display end is 904, i.e. 702 active pixels */
+ /* Total number of display lines per field is 288 */
+ WRITE_VID32(SC1200_TVOUT_LINE_END, 0x03880120);
+ }
+ break;
+ default:
+ return (GFX_STATUS_BAD_PARAMETER);
+ }
+ break;
+ default:
+ return (GFX_STATUS_BAD_PARAMETER);
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_output
+ *
+ * This routine sets the TV encoder registers to the specified output type.
+ * Supported output types are : S-VIDEO, Composite, YUV and SCART.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_output(int output)
+#else
+int
+gfx_set_tv_output(int output)
+#endif
+{
+ unsigned long ctrl2, ctrl3;
+
+ ctrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2);
+ ctrl3 = READ_VID32(SC1200_TVENC_TIM_CTRL_3);
+ ctrl2 &= ~(SC1200_TVENC_OUTPUT_YCBCR | SC1200_TVENC_CFS_MASK);
+ ctrl3 &=
+ ~(SC1200_TVENC_CM | SC1200_TVENC_SYNCMODE_MASK | SC1200_TVENC_CS);
+ switch (output) {
+ case TV_OUTPUT_COMPOSITE:
+ /* Analog outputs provide Y, C and CVBS */
+ /* Chrominance Lowpass filter is 1.3MHz (for composite video output) */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_CVBS);
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, ctrl3);
+ break;
+ case TV_OUTPUT_S_VIDEO:
+ /* Analog outputs provide Y, C and CVBS */
+ /* Chrominance Lowpass filter is 1.8MHz (for S-video output) */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_SVIDEO);
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_3, ctrl3);
+ break;
+ case TV_OUTPUT_YUV:
+ /* Analog outputs provide Y, Cb and Cr */
+ /* A 7.5 IRE setup is applied to the output */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_2,
+ ctrl2 | SC1200_TVENC_OUTPUT_YCBCR | SC1200_TVENC_CFS_BYPASS);
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_3,
+ ctrl3 | SC1200_TVENC_CM | SC1200_TVENC_CS);
+ break;
+ case TV_OUTPUT_SCART:
+ /* Analog outputs provide SCART (RGB and CVBS) */
+ /* Sync is added to green signal */
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, ctrl2 | SC1200_TVENC_CFS_CVBS);
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_3,
+ ctrl3 | SC1200_TVENC_CM | SC1200_TVENC_SYNC_ON_GREEN);
+ break;
+ default:
+ return (GFX_STATUS_BAD_PARAMETER);
+ }
+
+ /* Adjusts the internal voltage reference */
+ ctrl2 = READ_VID32(SC1200_TVENC_DAC_CONTROL);
+ ctrl2 &= ~SC1200_TVENC_TRIM_MASK;
+
+ /* Bypass for issue #926 : Inadequate chroma level of S-Video output */
+ if ((gfx_chip_revision == SC1200_REV_B3) && (output == TV_OUTPUT_S_VIDEO))
+ ctrl2 |= 0x7;
+ else
+ ctrl2 |= 0x5;
+
+ WRITE_VID32(SC1200_TVENC_DAC_CONTROL, ctrl2);
+
+ /* Disable 4:2:2 to 4:4:4 converter interpolation */
+ WRITE_VID32(SC1200_TVOUT_DEBUG, SC1200_TVOUT_CONVERTER_INTERPOLATION);
+
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_enable
+ *
+ * This routine enables or disables the TV output.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_enable(int enable)
+#else
+int
+gfx_set_tv_enable(int enable)
+#endif
+{
+ unsigned long value_tim, value_dac;
+
+ value_tim = READ_VID32(SC1200_TVENC_TIM_CTRL_1);
+ value_dac = READ_VID32(SC1200_TVENC_DAC_CONTROL);
+
+ if (enable) {
+ value_tim |= SC1200_TVENC_VIDEO_TIMING_ENABLE;
+ value_dac &= ~SC1200_TVENC_POWER_DOWN;
+ /* ENABLE GRAPHICS DISPLAY LOGIC IN VIDEO PROCESSOR */
+ gfx_set_screen_enable(1);
+ } else {
+ value_tim &= ~SC1200_TVENC_VIDEO_TIMING_ENABLE;
+ value_dac |= SC1200_TVENC_POWER_DOWN;
+ /* Do not disable the graphics display logic because it might be
+ * needed for CRT */
+ }
+
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, value_tim);
+ WRITE_VID32(SC1200_TVENC_DAC_CONTROL, value_dac);
+
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_flicker_filter
+ *
+ * This routine configures the TV out flicker filter.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_flicker_filter(int ff)
+#else
+int
+gfx_set_tv_flicker_filter(int ff)
+#endif
+{
+ unsigned long mode;
+
+ mode = READ_VID32(SC1200_TVOUT_HORZ_SCALING);
+ mode &= ~SC1200_TVOUT_FLICKER_FILTER_MASK;
+ switch (ff) {
+ case TV_FLICKER_FILTER_NONE:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ mode | SC1200_TVOUT_FLICKER_FILTER_DISABLED);
+ break;
+ case TV_FLICKER_FILTER_NORMAL:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ mode | SC1200_TVOUT_FLICKER_FILTER_FOURTH_HALF_FOURTH);
+ break;
+ case TV_FLICKER_FILTER_INTERLACED:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ mode | SC1200_TVOUT_FLICKER_FILTER_HALF_ONE_HALF);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_sub_carrier_reset
+ *
+ * This routine configures the TV encoder sub carrier reset interval.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_sub_carrier_reset(int screset)
+#else
+int
+gfx_set_tv_sub_carrier_reset(int screset)
+#endif
+{
+ unsigned long mode;
+
+ mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1);
+ mode &= ~SC1200_TVENC_SUB_CARRIER_RESET_MASK;
+ switch (screset) {
+ case TV_SUB_CARRIER_RESET_NEVER:
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1,
+ mode | SC1200_TVENC_SUB_CARRIER_RESET_NEVER);
+ break;
+ case TV_SUB_CARRIER_RESET_EVERY_TWO_LINES:
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1,
+ mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_LINES);
+ break;
+ case TV_SUB_CARRIER_RESET_EVERY_TWO_FRAMES:
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1,
+ mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_TWO_FRAMES);
+ break;
+ case TV_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES:
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1,
+ mode | SC1200_TVENC_SUB_CARRIER_RESET_EVERY_FOUR_FRAMES);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_vphase
+ *
+ * This routine sets the tv encoder VPHASE value.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_vphase(int vphase)
+#else
+int
+gfx_set_tv_vphase(int vphase)
+#endif
+{
+ unsigned long mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1);
+
+ mode &= ~SC1200_TVENC_VPHASE_MASK;
+ mode |= (vphase << SC1200_TVENC_VPHASE_POS) & SC1200_TVENC_VPHASE_MASK;
+ WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, mode);
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_YC_delay
+ *
+ * This routine configures the TV out Y/C delay.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_YC_delay(int delay)
+#else
+int
+gfx_set_tv_YC_delay(int delay)
+#endif
+{
+ unsigned long mode;
+
+ /* This feature is implemented in Rev C1 */
+ if (gfx_chip_revision < SC1200_REV_C1)
+ return (GFX_STATUS_OK);
+
+ mode = READ_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE);
+ mode &= ~SC1200_TVOUT_YC_DELAY_MASK;
+ switch (delay) {
+ case TV_YC_DELAY_NONE:
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE,
+ mode | SC1200_TVOUT_YC_DELAY_NONE);
+ break;
+ case TV_Y_DELAY_ONE_PIXEL:
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE,
+ mode | SC1200_TVOUT_Y_DELAY_ONE_PIXEL);
+ break;
+ case TV_C_DELAY_ONE_PIXEL:
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE,
+ mode | SC1200_TVOUT_C_DELAY_ONE_PIXEL);
+ break;
+ case TV_C_DELAY_TWO_PIXELS:
+ WRITE_VID32(SC1200_TVOUT_HORZ_PRE_ENCODER_SCALE,
+ mode | SC1200_TVOUT_C_DELAY_TWO_PIXELS);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tvenc_reset_interval
+ *
+ * This routine sets the interval between external resets of the TV encoder
+ * timing generator by the TV out.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tvenc_reset_interval(int interval)
+#else
+int
+gfx_set_tvenc_reset_interval(int interval)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VID32(SC1200_TVOUT_HORZ_SCALING);
+ value &= ~SC1200_TVENC_EXTERNAL_RESET_INTERVAL_MASK;
+ switch (interval) {
+ case TVENC_RESET_EVERY_ODD_FIELD:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ value | SC1200_TVENC_EXTERNAL_RESET_EVERY_ODD_FIELD);
+ break;
+ case TVENC_RESET_EVERY_EVEN_FIELD:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ value | SC1200_TVENC_EXTERNAL_RESET_EVERY_EVEN_FIELD);
+ break;
+ case TVENC_RESET_NEXT_ODD_FIELD:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ value | SC1200_TVENC_EXTERNAL_RESET_NEXT_ODD_FIELD);
+ break;
+ case TVENC_RESET_NEXT_EVEN_FIELD:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ value | SC1200_TVENC_EXTERNAL_RESET_NEXT_EVEN_FIELD);
+ break;
+ case TVENC_RESET_EVERY_FIELD:
+ WRITE_VID32(SC1200_TVOUT_HORZ_SCALING,
+ value | SC1200_TVENC_EXTERNAL_RESET_EVERY_FIELD);
+ break;
+ case TVENC_RESET_EVERY_X_ODD_FIELDS:
+ case TVENC_RESET_EVERY_X_EVEN_FIELDS:
+ return GFX_STATUS_UNSUPPORTED;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_cc_enable
+ *
+ * This routine enables or disables the use of the hardware CC registers
+ * in the TV encoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_cc_enable(int enable)
+#else
+int
+gfx_set_tv_cc_enable(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VID32(SC1200_TVENC_CC_CONTROL);
+ value &= ~(0x0005F);
+ if (enable)
+ value |= 0x51;
+ WRITE_VID32(SC1200_TVENC_CC_CONTROL, value);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_tv_display
+ *
+ * This routine sets the timings in the display controller to support a
+ * TV resolution.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_display(int width, int height)
+#else
+int
+gfx_set_tv_display(int width, int height)
+#endif
+{
+ DISPLAYMODE *pMode;
+ unsigned int i;
+
+ for (i = 0; i < NUM_TV_MODES; i++) {
+ pMode = &TVTimings[i];
+ if ((unsigned)width == pMode->hactive
+ && (unsigned)height == pMode->vactive)
+ break;
+ }
+
+ if (i == NUM_TV_MODES)
+ return 0;
+
+ gfx_set_display_timings(gfx_get_display_bpp(),
+ (unsigned short)pMode->flags, pMode->hactive, pMode->hblankstart,
+ pMode->hsyncstart, pMode->hsyncend, pMode->hblankend, pMode->htotal,
+ pMode->vactive, pMode->vblankstart, pMode->vsyncstart,
+ pMode->vsyncend, pMode->vblankend, pMode->vtotal, pMode->frequency);
+
+ return 1;
+}
+
+/*----------------------------------------------------------------------------
+ * cc_add_parity_bit
+ *
+ * This routine adds the (odd) parity bit to the data character.
+ *----------------------------------------------------------------------------
+ */
+unsigned char
+cc_add_parity_bit(unsigned char data)
+{
+ int i, num = 0;
+ unsigned char d = data;
+
+ for (i = 0; i < 7; i++) {
+ if (d & 0x1)
+ num++;
+ d >>= 1;
+ }
+ if (num & 0x1)
+ return (data & ~0x80);
+ else
+ return (data | 0x80);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_cc_data
+ *
+ * This routine writes the two specified characters to the CC data register
+ * of the TV encoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_cc_data(unsigned char data1, unsigned char data2)
+#else
+int
+gfx_set_tv_cc_data(unsigned char data1, unsigned char data2)
+#endif
+{
+ unsigned long value;
+
+ value = cc_add_parity_bit(data1) | (cc_add_parity_bit(data2) << 8);
+ WRITE_VID32(SC1200_TVENC_CC_DATA, value);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_tvout_odd_field
+ *
+ * This routine returns 1 if the current TVout field is odd. Otherwise returns
+ * 0.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_test_tvout_odd_field(void)
+#else
+int
+gfx_test_tvout_odd_field(void)
+#endif
+{
+ unsigned long debug = READ_VID32(SC1200_TVOUT_DEBUG);
+
+ WRITE_VID32(SC1200_TVOUT_DEBUG, debug | SC1200_TVOUT_FIELD_STATUS_TV);
+ if (READ_VID32(SC1200_TVOUT_DEBUG) & SC1200_TVOUT_FIELD_STATUS_EVEN)
+ return (0);
+ else
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_tvenc_odd_field
+ *
+ * This routine returns 1 if the current TV encoder field is odd. Otherwise
+ * returns 0.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_test_tvenc_odd_field(void)
+#else
+int
+gfx_test_tvenc_odd_field(void)
+#endif
+{
+ unsigned long debug = READ_VID32(SC1200_TVOUT_DEBUG);
+
+ WRITE_VID32(SC1200_TVOUT_DEBUG, debug & ~SC1200_TVOUT_FIELD_STATUS_TV);
+ if (READ_VID32(SC1200_TVOUT_DEBUG) & SC1200_TVOUT_FIELD_STATUS_EVEN)
+ return (0);
+ else
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_field_status_invert
+ *
+ * This routines determines whether the tvout/tvencoder field status bit is
+ * inverted (enable = 1) or not (enable = 0).
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_set_tv_field_status_invert(int enable)
+#else
+int
+gfx_set_tv_field_status_invert(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VID32(SC1200_TVOUT_DEBUG);
+
+ if (enable) {
+ value |= SC1200_TVOUT_FIELD_STATUS_INVERT;
+ } else {
+ value &= ~(SC1200_TVOUT_FIELD_STATUS_INVERT);
+ }
+
+ WRITE_VID32(SC1200_TVOUT_DEBUG, value);
+
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_vphase
+ *
+ * This routine returns the tv encoder vertical phase.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_get_tv_vphase(void)
+#else
+int
+gfx_get_tv_vphase(void)
+#endif
+{
+ unsigned long mode = READ_VID32(SC1200_TVENC_TIM_CTRL_1);
+
+ return (int)((mode & SC1200_TVENC_VPHASE_MASK) >>
+ SC1200_TVENC_VPHASE_POS);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_enable
+ *
+ * This routine returns the current tv enable status
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_get_tv_enable(unsigned int *p_on)
+#else
+int
+gfx_get_tv_enable(unsigned int *p_on)
+#endif
+{
+ unsigned long control = READ_VID32(SC1200_TVENC_DAC_CONTROL);
+
+ *p_on = (unsigned int)(!(control & SC1200_TVENC_POWER_DOWN));
+
+ return GFX_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_output
+ *
+ * This routine returns the current programmed TV output type. It does not
+ * detect invalid configurations.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_get_tv_output(void)
+#else
+int
+gfx_get_tv_output(void)
+#endif
+{
+ unsigned long ctrl2, ctrl3;
+ int format = 0;
+
+ ctrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2);
+ ctrl3 = READ_VID32(SC1200_TVENC_TIM_CTRL_3);
+
+ if ((ctrl2 & SC1200_TVENC_CFS_MASK) == SC1200_TVENC_CFS_SVIDEO)
+ format = TV_OUTPUT_S_VIDEO;
+ else if (ctrl2 & SC1200_TVENC_OUTPUT_YCBCR)
+ format = TV_OUTPUT_YUV;
+ else if ((ctrl2 & SC1200_TVENC_CFS_MASK) == SC1200_TVENC_CFS_CVBS) {
+ if (ctrl3 & SC1200_TVENC_CM)
+ format = TV_OUTPUT_SCART;
+ else
+ format = TV_OUTPUT_COMPOSITE;
+ }
+
+ return format;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_mode_count
+ *
+ * This routine returns the number of valid TV out resolutions.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_get_tv_mode_count(TVStandardType format)
+#else
+int
+gfx_get_tv_mode_count(TVStandardType format)
+#endif
+{
+ unsigned int mode, count = 0;
+ unsigned long flag;
+
+ switch (format) {
+ case TV_STANDARD_NTSC:
+ flag = GFX_MODE_TV_NTSC;
+ break;
+ case TV_STANDARD_PAL:
+ flag = GFX_MODE_TV_PAL;
+ break;
+ default:
+ return 0;
+ }
+
+ for (mode = 0; mode < NUM_TV_MODES; mode++) {
+ if (TVTimings[mode].flags & flag)
+ count++;
+ }
+
+ return count;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_display_mode
+ *
+ * This routine returns the current TV display parameters.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_get_tv_display_mode(int *width, int *height, int *bpp, int *hz)
+#else
+int
+gfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz)
+#endif
+{
+ unsigned long frequency;
+ unsigned long mode, flags;
+
+ *width = gfx_get_hactive();
+ *height = gfx_get_vactive();
+ *bpp = gfx_get_display_bpp();
+ frequency = gfx_get_clock_frequency();
+
+ for (mode = 0; mode < NUM_TV_MODES; mode++) {
+ if (TVTimings[mode].hactive == (unsigned short)(*width) &&
+ TVTimings[mode].vactive == (unsigned short)(*height) &&
+ TVTimings[mode].frequency == frequency) {
+ flags = TVTimings[mode].flags;
+
+ if (flags & GFX_MODE_TV_NTSC)
+ *hz = 60;
+ else if (flags & GFX_MODE_TV_PAL)
+ *hz = 50;
+ else
+ *hz = 0;
+ return (1);
+ }
+ }
+
+ return -1;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_tv_display_mode_frequency
+ *
+ * This routine returns the PLL frequency of a given TV mode.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_get_tv_display_mode_frequency(unsigned short width,
+ unsigned short height, TVStandardType format, int *frequency)
+#else
+int
+gfx_get_tv_display_mode_frequency(unsigned short width, unsigned short height,
+ TVStandardType format, int *frequency)
+#endif
+{
+ unsigned long mode, flag;
+ int retval = -1;
+
+ *frequency = 0;
+
+ switch (format) {
+ case TV_STANDARD_NTSC:
+ flag = GFX_MODE_TV_NTSC;
+ break;
+ case TV_STANDARD_PAL:
+ flag = GFX_MODE_TV_PAL;
+ break;
+ default:
+ return -1;
+ }
+
+ for (mode = 0; mode < NUM_TV_MODES; mode++) {
+ if ((TVTimings[mode].hactive == width) &&
+ (TVTimings[mode].vactive == height) &&
+ (TVTimings[mode].flags & flag)) {
+ *frequency = TVTimings[mode].frequency;
+ retval = 1;
+ }
+ }
+ return retval;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_is_tv_display_mode_supported
+ *
+ * Returns >= 0 if the mode is available, -1 if the mode could not be found
+ *---------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+sc1200_is_tv_display_mode_supported(unsigned short width,
+ unsigned short height, TVStandardType format)
+#else
+int
+gfx_is_tv_display_mode_supported(unsigned short width, unsigned short height,
+ TVStandardType format)
+#endif
+{
+ unsigned long mode, flag;
+
+ switch (format) {
+ case TV_STANDARD_NTSC:
+ flag = GFX_MODE_TV_NTSC;
+ break;
+ case TV_STANDARD_PAL:
+ flag = GFX_MODE_TV_PAL;
+ break;
+ default:
+ return -1;
+ }
+
+ for (mode = 0; mode < NUM_TV_MODES; mode++) {
+ if (TVTimings[mode].hactive == width &&
+ TVTimings[mode].vactive == height &&
+ (TVTimings[mode].flags & flag)) {
+ return ((int)mode);
+ }
+ }
+
+ return -1;
+}
+
+/* END OF FILE */
diff --git a/src/gfx/tv_fs450.c b/src/gfx/tv_fs450.c
new file mode 100644
index 0000000..942907b
--- /dev/null
+++ b/src/gfx/tv_fs450.c
@@ -0,0 +1,3261 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+#define FS450_DIRECTREG 0
+
+#include "tv_fs450.h"
+
+/*==========================================================================
+ * Macros
+ *==========================================================================
+ */
+#undef fsmax
+#undef fsmin
+#define fsmax(a, b) ((a) > (b) ? (a) : (b))
+#define fsmin(a, b) ((a) < (b) ? (a) : (b))
+
+#undef range_limit
+#define range_limit(val,min_val,max_val) (fsmax((min_val),fsmin((val),(max_val))))
+
+/*==========================================================================
+ * Registers
+ *==========================================================================
+ */
+
+#define MAX_REGISTERS 32
+#define MAX_BITS 32
+
+#define READ 1
+#define WRITE 2
+#define READ_WRITE (READ | WRITE)
+
+typedef struct
+{
+ char *name;
+ unsigned long offset;
+ unsigned char bit_length;
+ unsigned char valid_bits;
+ unsigned char read_write;
+ char *bitfield_names[MAX_BITS];
+} S_REGISTER_DESCRIP;
+
+typedef struct
+{
+ int source;
+ char *name;
+ S_REGISTER_DESCRIP registers[MAX_REGISTERS];
+} S_SET_DESCRIP;
+
+const S_SET_DESCRIP *houston_regs(void);
+const S_SET_DESCRIP *encoder_regs(void);
+const S_SET_DESCRIP *macrovision_regs(void);
+const S_SET_DESCRIP *gcc_regs(void);
+
+/*==========================================================================
+ * Houston Register Addresses & Bit Definitions
+ *==========================================================================
+ */
+#define HOUSTON_IHO 0x00 /* Input Horizontal Offset */
+#define HOUSTON_IVO 0x02 /* Input Vertical Offset */
+#define HOUSTON_IHA 0x04 /* Input Horizontal Active Width */
+#define HOUSTON_VSC 0x06 /* Vertical Scaling Coeficient */
+#define HOUSTON_HSC 0x08 /* Horizontal Scaling Coeficient */
+#define HOUSTON_BYP 0x0A /* Bypass Register */
+#define HOUSTON_CR 0x0C /* Control Register */
+#define HOUSTON_SP 0x0E /* Status */
+#define HOUSTON_NCONL 0x10 /* NCO numerator low word */
+#define HOUSTON_NCONH 0x12 /* NCO numerator high word */
+#define HOUSTON_NCODL 0x14 /* NCO denominator low word */
+#define HOUSTON_NCODH 0x16 /* NCO denominator high word */
+#define HOUSTON_APO 0x18
+#define HOUSTON_ALO 0x1A
+#define HOUSTON_AFO 0x1C
+#define HOUSTON_HSOUTWID 0x1E
+#define HOUSTON_HSOUTST 0x20
+#define HOUSTON_HSOUTEND 0x22
+#define HOUSTON_SHP 0x24 /* Sharpness */
+#define HOUSTON_FLK 0x26 /* Flicker Filter */
+#define HOUSTON_BCONTL 0x28
+#define HOUSTON_BCONTH 0x2A
+#define HOUSTON_BDONE 0x2C
+#define HOUSTON_BDIAGL 0x2E
+#define HOUSTON_BDIAGH 0x30
+#define HOUSTON_REV 0x32
+#define HOUSTON_MISC 0x34
+#define HOUSTON_FFO 0x36
+#define HOUSTON_FFO_LAT 0x38
+#define HOUSTON_VSOUTWID 0x3A
+#define HOUSTON_VSOUTST 0x3C
+#define HOUSTON_VSOUTEND 0x3E
+/* BYP Register Bits */
+#define BYP_RGB_BYPASS 0x0001
+#define BYP_HDS_BYPASS 0x0002
+#define BYP_HDS_TBYPASS 0x0004
+#define BYP_CAC_BYPASS 0x0008
+#define BYP_R2V_SBYPASS 0x0010
+#define BYP_R2V_BYPASS 0x0020
+#define BYP_VDS_BYPASS 0x0040
+#define BYP_FFT_BYPASS 0x0080
+#define BYP_FIF_BYPASS 0x0100
+#define BYP_FIF_TBYPASS 0x0200
+#define BYP_HUS_BYPASS 0x0400
+#define BYP_HUS_TBYPASS 0x0800
+#define BYP_CCR_BYPASS 0x1000
+#define BYP_PLL_BYPASS 0x2000
+#define BYP_NCO_BYPASS 0x4000
+#define BYP_ENC_BYPASS 0x8000
+/* CR Register Bits */
+#define CR_RESET 0x0001
+#define CR_CLKOFF 0x0002
+#define CR_NCO_EN 0x0004
+#define CR_COMPOFF 0x0008
+#define CR_YCOFF 0x0010
+#define CR_LP_EN 0x0020
+#define CR_CACQ_CLR 0x0040
+#define CR_FFO_CLR 0x0080
+#define CR_656_PAL_NTSC 0x0100
+#define CR_656_STD_VMI 0x0200
+#define CR_OFMT 0x0400
+#define CR_UIM_CLK 0x0800
+#define CR_UIM_DEC 0x1000
+#define CR_BIPGEN_EN1 0x2000
+#define CR_UIM_MOD0 0x4000
+#define CR_UIM_MOD1 0x8000
+/* Status Register Bits */
+#define SP_CACQ_ST 0x0001
+#define SP_FFO_ST 0x0002
+#define SP_REVID_MASK 0x7FFC
+#define SP_MV_EN 0x8000
+/* BDONE Register Bits */
+#define BDONE_BIST_DONE_A 0x0001
+#define BDONE_BIST_DONE_B 0x0002
+#define BDONE_BIST_DONE_C 0x0004
+#define BDONE_BIST_DONE_D 0x0008
+#define BDONE_BIST_DONE_E 0x0010
+#define BDONE_BIST_DONE_F 0x0020
+#define BDONE_BIST_DONE_G 0x0040
+/* BDIAGL Register Bits */
+#define BDIAGL_BIST_DIAG_A 0x000F
+#define BDIAGL_BIST_DIAG_B 0x00F0
+#define BDIAGL_BIST_DIAG_C 0x0F00
+#define BDIAGL_BIST_DIAG_D 0xF000
+/* BDIAGH Register Bits */
+#define BDIAGH_BIST_DIAG_E 0x000F
+#define BDIAGH_BIST_DIAG_F 0x000F
+#define BDIAGH_BIST_DIAG_G 0x000F
+/* MISC Register Bits */
+#define MISC_TV_SHORT_FLD 0x0001
+#define MISC_ENC_TEST 0x0002
+#define MISC_DAC_TEST 0x0004
+#define MISC_MV_SOFT_EN 0x0008
+#define MISC_NCO_LOAD0 0x0010
+#define MISC_NCO_LOAD1 0x0020
+#define MISC_VGACKDIV 0x0200
+#define MISC_BRIDGE_SYNC 0x0400
+#define MISC_GTLIO_PD 0x8000
+/*==========================================================================
+ * Encoder Registers & Bit Definitions
+ *==========================================================================
+ */
+#define ENC_CHROMA_FREQ 0x40
+#define ENC_CHROMA_PHASE 0x44
+#define ENC_REG05 0x45
+#define ENC_REG06 0x46
+#define ENC_REG07 0x47
+#define ENC_HSYNC_WIDTH 0x48
+#define ENC_BURST_WIDTH 0x49
+#define ENC_BACK_PORCH 0x4A
+#define ENC_CB_BURST_LEVEL 0x4B
+#define ENC_CR_BURST_LEVEL 0x4C
+#define ENC_SLAVE_MODE 0x4D
+#define ENC_BLACK_LEVEL 0x4e
+#define ENC_BLANK_LEVEL 0x50
+#define ENC_NUM_LINES 0x57
+#define ENC_WHITE_LEVEL 0x5e
+#define ENC_CB_GAIN 0x60
+#define ENC_CR_GAIN 0x62
+#define ENC_TINT 0x65
+#define ENC_BREEZE_WAY 0x69
+#define ENC_FRONT_PORCH 0x6C
+#define ENC_ACTIVELINE 0x71
+#define ENC_FIRST_LINE 0x73
+#define ENC_REG34 0x74
+#define ENC_SYNC_LEVEL 0x75
+#define ENC_VBI_BLANK_LEVEL 0x7C
+#define ENC_RESET 0x7e
+#define ENC_NOTCH_FILTER 0x8d
+/*==========================================================================
+ * Macrovision Registers & Bit Definitions
+ *==========================================================================
+ */
+#define MV_N0 0x59
+#define MV_N1 0x52
+#define MV_N2 0x7b
+#define MV_N3 0x53
+#define MV_N4 0x79
+#define MV_N5 0x5d
+#define MV_N6 0x7a
+#define MV_N7 0x64
+#define MV_N8 0x54
+#define MV_N9 0x55
+#define MV_N10 0x56
+#define MV_N11 0x6d
+#define MV_N12 0x6f
+#define MV_N13 0x5a
+#define MV_N14 0x5b
+#define MV_N15 0x5c
+#define MV_N16 0x63
+#define MV_N17 0x66
+#define MV_N18 0x68
+#define MV_N19 0x67
+#define MV_N20 0x61
+#define MV_N21 0x6a
+#define MV_N22 0x76
+#define MV_AGC_PULSE_LEVEL 0x77
+#define MV_BP_PULSE_LEVEL 0x78
+/*==========================================================================
+ * The TRACE macro can be used to display debug information. It can display
+ * one or more parameters in a formatted string like printf. No code will be
+ * generated for a release build. Use double parentheses for compatibility
+ * with C #define statements. Newline characters are not added
+ * automatically. Usage example:
+ *
+ * TRACE(("Number is %d, Name is %s.\n",iNumber,lpszName))
+ *==========================================================================
+ */
+#define TRACE(parameters) {}
+/* GCC timing structure */
+typedef struct _S_TIMING_SPECS
+{
+ int vga_width;
+ int vga_lines;
+ int tv_width;
+ int tv_lines;
+ int h_total;
+ int h_sync;
+ int v_total;
+ int v_sync;
+} S_TIMING_SPECS;
+
+/* Revision of Houston chip */
+#define HOUSTON_REV_A 0
+#define HOUSTON_REV_B 1
+static int houston_Rev(void);
+
+/*==========================================================================
+ * Functions
+ *==========================================================================
+ */
+static int houston_init(void);
+
+static unsigned char PLAL_FS450_i2c_address(void);
+static int PLAL_FS450_UIM_mode(void);
+static int PLAL_ReadRegister(S_REG_INFO * p_reg);
+static int PLAL_WriteRegister(const S_REG_INFO * p_reg);
+static int PLAL_IsTVOn(void);
+static int PLAL_EnableVga(void);
+static int PLAL_PrepForTVout(void);
+static int PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs);
+static int PLAL_FinalEnableTVout(unsigned long vga_mode);
+
+/* Direct Memory Access Functions */
+/* NOTE: Cx5530 is assumed hardcoded at 0x10000 offset from MediaGX base.
+ * F4Bar is bogus as described in the Cx5530 datasheet (actually points to GX
+ * frame buffer). */
+static int
+DMAL_ReadUInt32(unsigned long phys_addr, unsigned long *p_data)
+{
+ *p_data = READ_REG32(phys_addr);
+ return 0;
+}
+
+static int
+DMAL_WriteUInt32(unsigned long phys_addr, unsigned long data)
+{
+ WRITE_REG32(phys_addr, data);
+ return 0;
+}
+
+/* Houston register access functions. */
+static int
+houston_ReadReg(unsigned int reg, unsigned long *p_value, unsigned int bytes)
+{
+ return gfx_i2c_read(1, PLAL_FS450_i2c_address(), (unsigned char)reg,
+ (unsigned char)bytes, (unsigned char *)p_value);
+}
+
+static int
+houston_WriteReg(unsigned int reg, unsigned long value, unsigned int bytes)
+{
+ return gfx_i2c_write(1, PLAL_FS450_i2c_address(), (unsigned char)reg,
+ (unsigned char)bytes, (unsigned char *)&value);
+}
+
+/* TV configuration functions. */
+static int config_init(void);
+static const S_TIMING_SPECS *p_specs(void);
+static void config_power(int on);
+static void config_vga_mode(unsigned long vga_mode);
+static void config_tv_std(unsigned long tv_std, unsigned int trigger_bits);
+static void conget_tv_std(unsigned long *p_tv_std);
+static unsigned long supported_standards(void);
+static void config_tvout_mode(unsigned long tvout_mode);
+static void conget_tvout_mode(unsigned long *p_tvout_mode);
+static void config_overscan_xy(unsigned long tv_std, unsigned long vga_mode,
+ int overscan_x, int overscan_y, int pos_x, int pos_y);
+static void config_nco(unsigned long tv_std, unsigned long vga_mode);
+static void config_sharpness(int sharpness);
+static void conget_sharpness(int *p_sharpness);
+static void config_flicker(int flicker);
+static void conget_flicker(int *p_flicker);
+static void config_color(int color);
+static void conget_color(int *p_color);
+static void config_brightness_contrast(unsigned long tv_std,
+ unsigned int trigger_bits, int brightness, int contrast);
+static void conget_brightness_contrast(unsigned long tv_std,
+ unsigned int trigger_bits, int *p_brightness, int *p_contrast);
+static void config_yc_filter(unsigned long tv_std, int luma_filter,
+ int chroma_filter);
+static void conget_yc_filter(int *p_luma_filter, int *p_chroma_filter);
+static void config_macrovision(unsigned long tv_std,
+ unsigned int cp_trigger_bits);
+static void conget_macrovision(unsigned long tv_std,
+ unsigned int *p_cp_trigger_bits);
+
+/* Device settings. */
+typedef struct _S_DEVICE_SETTINGS
+{
+ int tv_on;
+ unsigned long vga_mode;
+ unsigned long tv_std;
+ unsigned long tvout_mode;
+ int overscan_x;
+ int overscan_y;
+ int position_x;
+ int position_y;
+ int sharpness;
+ int flicker;
+ int color;
+ int brightness;
+ int contrast;
+ unsigned char yc_filter;
+ unsigned int aps_trigger_bits;
+ int last_overscan_y;
+} S_DEVICE_SETTINGS;
+
+static S_DEVICE_SETTINGS d;
+
+/*==========================================================================
+ * TV Setup Parameters
+ *==========================================================================
+ * */
+
+static const struct
+{
+ unsigned long chroma_freq[5];
+ unsigned short chroma_phase[5];
+ unsigned short cphase_rst[5];
+ unsigned short color[5];
+ unsigned short cr_burst_level[5];
+ unsigned short cb_burst_level[5];
+ unsigned short sys625_50[5];
+ unsigned short vsync5[5];
+ unsigned short pal_mode[5];
+ unsigned short hsync_width[5];
+ unsigned short burst_width[5];
+ unsigned short back_porch[5];
+ unsigned short front_porch[5];
+ unsigned short breeze_way[5];
+ unsigned short activeline[5];
+ unsigned short blank_level[5];
+ unsigned short vbi_blank_level[5];
+ unsigned short black_level[5];
+ unsigned short white_level[5];
+ unsigned short hamp_offset[5];
+ unsigned short sync_level[5];
+ unsigned short tv_lines[5];
+ unsigned short tv_width[5];
+ unsigned short tv_active_lines[5];
+ unsigned short tv_active_width[5];
+ unsigned char notch_filter[5];
+ unsigned short houston_cr[5];
+ unsigned short houston_ncodl[5];
+ unsigned short houston_ncodh[5];
+} tvsetup = {
+ /* ntsc, pal, ntsc-eij, pal-m, pal-n */
+ {
+ 0x1f7cf021, 0xcb8a092a, 0x1f7cf021, 0xe3efe621, 0xcb8a092a},
+ /* chroma_freq */
+ {
+ 0, 0, 0, 0, 0},
+ /* chroma_phase */
+ {
+ 2, 0, 2, 0, 0},
+ /* cphase_rst */
+ {
+ 54, 43, 54, 43, 43},
+ /* color */
+ {
+ 0, 31, 0, 29, 29},
+ /* cr_burst_level */
+ {
+ 59, 44, 59, 41, 41},
+ /* cb_burst_level */
+ {
+ 0, 1, 0, 0, 1},
+ /* sys625_50 */
+ {
+ 0, 1, 0, 0, 0},
+ /* vsync5 */
+ {
+ 0, 1, 0, 1, 1},
+ /* pal_mode */
+ {
+ 0x7a, 0x7a, 0x7a, 0x7a, 0x7a},
+ /* hsync_width */
+ {
+ 0x40, 0x3c, 0x40, 0x40, 0x3c},
+ /* burst_width */
+ {
+ 0x80, 0x9a, 0x80, 0x80, 0x9a},
+ /* back_porch */
+ {
+ 0x24, 0x1e, 0x24, 0x24, 0x1e},
+ /* front_porch */
+ {
+ 0x19, 0x1a, 0x19, 0x12, 0x1a},
+ /* breeze_way */
+ {
+ 0xb4, 0xb4, 0xb4, 0xb4, 0xb4},
+ /* active_line */
+ {
+ 240, 251, 240, 240, 240},
+ /* blank_level */
+ {
+ 240, 251, 240, 240, 240},
+ /* vbi_blank_level */
+ {
+ 284, 252, 240, 252, 252},
+ /* black_level */
+ {
+ 823, 821, 823, 821, 821},
+ /* white_level */
+ {
+ 60, 48, 60, 48, 48},
+ /* hamp_offset */
+ {
+ 0x08, 0x08, 0x08, 0x08, 0x08},
+ /* sync_level */
+ {
+ 525, 625, 525, 525, 625},
+ /* tv_lines */
+ {
+ 858, 864, 858, 858, 864},
+ /* tv_width */
+ {
+ 487, 576, 487, 487, 576},
+ /* tv_active_lines */
+ {
+ 800, 800, 800, 800, 800},
+ /* tv_active_width */
+ {
+ 0x1a, 0x1d, 0x1a, 0x1d, 0x1d},
+ /* notch filter enabled */
+ {
+ 0x0000, 0x0100, 0x0000, 0x0000, 0x0100},
+ /* houston cr pal */
+ {
+ 0x7e48, 0xf580, 0x7e48, 0x7e48, 0xf580},
+ /* houston ncodl */
+ {
+ 0x001b, 0x0020, 0x001b, 0x001b, 0x0020}
+ /* houston ncodh */
+};
+
+/* MediaGX default underscan and centered position setups. */
+#define SCANTABLE_ENTRIES 5
+struct _scantable
+{
+ unsigned long mode;
+ unsigned short v_total[5];
+ unsigned short v_sync[5];
+ unsigned short iha[5];
+ signed short iho[5];
+ signed short hsc[5];
+};
+
+static struct _scantable scantable[SCANTABLE_ENTRIES] = {
+ {
+ GFX_VGA_MODE_640X480,
+ {617, 624, 617, 624, 624}, /* v_total */
+ {69, 88, 69, 88, 88}, /* v_sync */
+ {720, 720, 720, 720, 720}, /* iha */
+ {0, 0, 0, 0, 0}, /* iho */
+ {-12, 0, -6, 0, 0} /* hsc */
+ },
+ {
+ GFX_VGA_MODE_800X600,
+ {740, 740, 740, 740, 740}, /* v_total */
+ {90, 88, 90, 88, 88}, /* v_sync */
+ {720, 720, 508, 720, 720}, /* iha */
+ {-8, 11, -8, -8, 11}, /* iho */
+ {-27, -27, -27, -27, -27} /* hsc */
+ },
+ {
+ GFX_VGA_MODE_720X487,
+ {525, 720, 525, 720, 720}, /* v_total */
+ {23, 230, 23, 230, 230}, /* v_sync */
+ {720, 720, 720, 720, 720}, /* iha */
+ {0xa2, 0xa2, 0xa2, 0xa2, 0xa2}, /* iho */
+ {0, 0, 0, 0, 0} /* hsc */
+ },
+ {
+ GFX_VGA_MODE_720X576,
+ {720, 625, 720, 625, 625}, /* v_total */
+ {129, 25, 129, 25, 25}, /* v_sync */
+ {720, 720, 720, 720, 720}, /* iha */
+ {0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, /* iho */
+ {0, 0, 0, 0, 0} /* hsc */
+ },
+ {
+ GFX_VGA_MODE_1024X768,
+ {933, 942, 933, 806, 806}, /* v_total */
+ {121, 112, 121, 88, 88}, /* v_sync */
+ {600, 600, 600, 600, 600}, /* iha */
+ {0x3c, 0x23, 0x3c, 0x65, 0x65}, /* iho */
+ {35, 26, 35, 26, 26} /* hsc */
+ },
+};
+
+/* Houston fifo configuration constants. */
+struct _ffolat
+{
+ int v_total;
+ unsigned short ffolat;
+};
+
+struct _ffolativo
+{
+ int v_total;
+ unsigned short ivo;
+ unsigned short ffolat;
+};
+
+/* h_total=832, ivo=40, tv_width=858, tv_lines=525, vga_lines=480 */
+#define SIZE6X4NTSC 66
+static struct _ffolat ffo6x4ntsc[SIZE6X4NTSC + 1] = {
+ {541, 0x40}, {545, 0x40}, {549, 0x40}, {553, 0x40},
+ {557, 0x58}, {561, 0x40}, {565, 0x40}, {569, 0x40},
+ {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40},
+ {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40},
+ {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48},
+ {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40},
+ {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56},
+ {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40},
+ {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40},
+ {685, 0x40}, {689, 0x40}, {693, 0x40}, {697, 0x40},
+ {701, 0x40}, {705, 0x40}, {709, 0x40}, {713, 0x40},
+ {717, 0x40}, {721, 0x40}, {725, 0x40}, {729, 0x40},
+ {733, 0x40}, {737, 0x40}, {741, 0x40}, {745, 0x40},
+ {749, 0x40}, {753, 0x40}, {757, 0x40}, {761, 0x40},
+ {765, 0x40}, {769, 0x40}, {773, 0x40}, {777, 0x40},
+ {781, 0x40}, {785, 0x40}, {789, 0x40}, {793, 0x40},
+ {797, 0x30}, {801, 0x40},
+ {-1, 0}
+};
+
+#define SIZE6X4PAL 45
+static struct _ffolat ffo6x4pal[SIZE6X4PAL + 1] = {
+ {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
+ {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
+ {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
+ {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
+ {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
+ {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
+ {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60},
+ {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60},
+ {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60},
+ {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60},
+ {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60},
+ {801, 0x60},
+ {-1, 0}
+};
+
+#define SIZE7X4NTSC 40
+static struct _ffolat ffo7x4ntsc[SIZE7X4NTSC + 1] = {
+ {525, 0x52}, {529, 0x52}, {533, 0x52}, {537, 0x52},
+ {541, 0x52}, {545, 0x40}, {549, 0x40}, {553, 0x40},
+ {557, 0x58}, {561, 0x40}, {565, 0x58}, {569, 0x40},
+ {573, 0x48}, {577, 0x40}, {581, 0x40}, {585, 0x40},
+ {589, 0x40}, {593, 0x48}, {597, 0x40}, {601, 0x40},
+ {605, 0x40}, {609, 0x40}, {613, 0x5b}, {617, 0x48},
+ {621, 0x60}, {625, 0x48}, {629, 0x48}, {633, 0x40},
+ {637, 0x5e}, {641, 0x40}, {645, 0x50}, {649, 0x56},
+ {653, 0x58}, {657, 0x6c}, {661, 0x40}, {665, 0x40},
+ {669, 0x40}, {673, 0x40}, {677, 0x40}, {681, 0x40},
+ {-1, 0}
+};
+
+#define SIZE7X4PAL 24
+static struct _ffolat ffo7x4pal[SIZE7X4PAL + 1] = {
+ {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
+ {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
+ {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
+ {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
+ {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
+ {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
+ {-1, 0}
+};
+
+#define SIZE7X5NTSC 54
+static struct _ffolat ffo7x5ntsc[SIZE7X5NTSC + 1] = {
+ {590, 0x40}, {594, 0x48}, {598, 0x40}, {602, 0x40},
+ {606, 0x40}, {610, 0x40}, {614, 0x5b}, {618, 0x48},
+ {622, 0x60}, {626, 0x48}, {630, 0x48}, {634, 0x40},
+ {638, 0x5e}, {642, 0x40}, {646, 0x50}, {650, 0x56},
+ {654, 0x58}, {658, 0x6c}, {662, 0x40}, {666, 0x40},
+ {670, 0x40}, {674, 0x40}, {678, 0x40}, {682, 0x40},
+ {686, 0x40}, {690, 0x40}, {694, 0x40}, {698, 0x40},
+ {702, 0x40}, {706, 0x40}, {710, 0x40}, {714, 0x40},
+ {718, 0x40}, {722, 0x40}, {726, 0x40}, {730, 0x40},
+ {734, 0x40}, {738, 0x40}, {742, 0x40}, {746, 0x40},
+ {750, 0x40}, {754, 0x40}, {758, 0x40}, {762, 0x40},
+ {766, 0x40}, {770, 0x40}, {774, 0x40}, {778, 0x40},
+ {782, 0x40}, {786, 0x40}, {790, 0x40}, {794, 0x40},
+ {798, 0x30}, {802, 0x40},
+ {-1, 0}
+};
+
+#define SIZE7X5PAL 45
+static struct _ffolat ffo7x5pal[SIZE7X5PAL + 1] = {
+ {625, 0x60}, {629, 0x60}, {633, 0x60}, {637, 0x60},
+ {641, 0x50}, {645, 0x60}, {649, 0x60}, {653, 0x60},
+ {657, 0x60}, {661, 0x60}, {665, 0x60}, {669, 0x60},
+ {673, 0x60}, {677, 0x60}, {681, 0x60}, {685, 0x60},
+ {689, 0x60}, {693, 0x60}, {697, 0x60}, {701, 0x60},
+ {705, 0x60}, {709, 0x60}, {713, 0x60}, {717, 0x60},
+ {721, 0x60}, {725, 0x60}, {729, 0x60}, {733, 0x60},
+ {737, 0x60}, {741, 0x60}, {745, 0x60}, {749, 0x60},
+ {753, 0x60}, {757, 0x60}, {761, 0x60}, {765, 0x60},
+ {769, 0x60}, {773, 0x60}, {777, 0x60}, {781, 0x60},
+ {785, 0x60}, {789, 0x60}, {793, 0x60}, {797, 0x60},
+ {801, 0x60},
+ {-1, 0}
+};
+
+/* h_total=1056, vga_lines=600 */
+#define SIZE8X6NTSC 37
+static struct _ffolat ffo8x6ntsc[SIZE8X6NTSC + 1] = {
+ {620, 0x40}, /* v_total_min >= vsync+10 >= vga_lines+10 = 610 */
+ {625, 0x58}, {630, 0x40}, {635, 0x40}, {640, 0x40},
+ {645, 0x46}, {650, 0x46}, {655, 0x4f}, {660, 0x4c},
+ {665, 0x4a}, {670, 0x50}, {675, 0x2f}, {680, 0x48},
+ {685, 0x38}, {690, 0x31}, {695, 0x40}, {700, 0x21},
+ {705, 0x25}, {710, 0x40}, {715, 0x48}, {720, 0x50},
+ {725, 0x30}, {730, 0x50}, {735, 0x50}, {740, 0x50},
+ {745, 0x40}, {750, 0x38}, {755, 0x50}, {760, 0x50},
+ {765, 0x40}, {770, 0x38}, {775, 0x40}, {780, 0x40},
+ {785, 0x40}, {790, 0x38}, {795, 0x50}, {800, 0x50},
+ {-1, 0}
+};
+
+/* h_total=1056, vga_lines=600 */
+#define SIZE8X6PAL 36
+static struct _ffolat ffo8x6pal[SIZE8X6PAL + 1] = {
+ {625, 0x80}, {630, 0x80}, {635, 0x5a}, {640, 0x55},
+ {645, 0x48}, {650, 0x65}, {655, 0x65}, {660, 0x50},
+ {665, 0x80}, {670, 0x70}, {675, 0x56}, {680, 0x80},
+ {685, 0x58}, {690, 0x31}, {695, 0x80}, {700, 0x60},
+ {705, 0x45}, {710, 0x4a}, {715, 0x50}, {720, 0x50},
+ {725, 0x50}, {730, 0x45}, {735, 0x50}, {740, 0x50},
+ {745, 0x50}, {750, 0x50}, {755, 0x50}, {760, 0x50},
+ {765, 0x50}, {770, 0x50}, {775, 0x50}, {780, 0x50},
+ {785, 0x50}, {790, 0x50}, {795, 0x50}, {800, 0x50},
+ {-1, 0}
+};
+
+/* h_total=1344, vga_lines=768 */
+#define SIZE10X7NTSC 45
+static struct _ffolativo ffo10x7ntsc[SIZE10X7NTSC] = {
+ {783, 0x4d, 0x40},
+ {789, 0x47, 0x14},
+ {795, 0x47, 0x7f},
+ {801, 0x47, 0x53},
+ {807, 0x47, 0x11},
+ {813, 0x47, 0x78},
+ {819, 0x47, 0x54},
+ {825, 0x47, 0x40},
+ {831, 0x47, 0x0f},
+ {837, 0x4d, 0x40},
+ {843, 0x47, 0x5a},
+ {849, 0x4d, 0x40},
+ {855, 0x47, 0x4b},
+ {861, 0x4d, 0x40},
+ {867, 0x47, 0x4b},
+ {873, 0x4d, 0x40},
+ {879, 0x47, 0x07},
+ {885, 0x48, 0x20},
+ {891, 0x47, 0x82},
+ {897, 0x47, 0x60},
+ {903, 0x47, 0x7f},
+ {909, 0x4d, 0x40},
+ {915, 0x48, 0x40},
+ {921, 0x4c, 0x40},
+ {927, 0x49, 0x40},
+ {933, 0x48, 0x40},
+ {939, 0x4a, 0x40},
+ {945, 0x46, 0x40},
+ {951, 0x4a, 0x40},
+ {957, 0x4a, 0x40},
+ {963, 0x4b, 0x40},
+ {969, 0x4b, 0x40},
+ {975, 0x48, 0x40},
+ {981, 0x47, 0x40},
+ {987, 0x47, 0x40},
+ {993, 0x47, 0x40},
+ {999, 0x48, 0x40},
+ {1005, 0x48, 0x40},
+ {1011, 0x47, 0x40},
+ {1017, 0x47, 0x40},
+ {1023, 0x48, 0x40},
+ {1029, 0x48, 0x40},
+ {1035, 0x46, 0x40},
+ {1041, 0x47, 0x40},
+ {1047, 0x47, 0x40}
+};
+
+/* h_total=1344, vga_lines=768 */
+#define SIZE10X7PAL 46
+static struct _ffolativo ffo10x7pal[SIZE10X7PAL] = {
+ {781, 0x49, 0x40},
+ {787, 0x46, 0x40},
+ {793, 0x48, 0x40},
+ {799, 0x46, 0x40},
+ {805, 0x49, 0x40},
+ {811, 0x47, 0x40},
+ {817, 0x46, 0x40},
+ {823, 0x46, 0x56},
+ {829, 0x46, 0x2d},
+ {835, 0x46, 0x40},
+ {841, 0x46, 0x2d},
+ {847, 0x46, 0x3f},
+ {853, 0x46, 0x10},
+ {859, 0x46, 0x86},
+ {865, 0x46, 0xc9},
+ {871, 0x46, 0x83},
+ {877, 0x46, 0xa8},
+ {883, 0x46, 0x81},
+ {889, 0x46, 0xa5},
+ {895, 0x46, 0xa9},
+ {901, 0x46, 0x81},
+ {907, 0x46, 0xa4},
+ {913, 0x46, 0xa5},
+ {919, 0x46, 0x7f},
+ {925, 0x46, 0xa2},
+ {931, 0x46, 0x9d},
+ {937, 0x46, 0xc1},
+ {943, 0x46, 0x96},
+ {949, 0x46, 0xb7},
+ {955, 0x46, 0xb1},
+ {961, 0x46, 0x8a},
+ {967, 0x46, 0xa9},
+ {973, 0x46, 0xa0},
+ {979, 0x46, 0x40},
+ {985, 0x46, 0x97},
+ {991, 0x46, 0xb5},
+ {997, 0x46, 0xaa},
+ {1003, 0x46, 0x83},
+ {1009, 0x46, 0x9f},
+ {1015, 0x47, 0x40},
+ {1021, 0x46, 0xad},
+ {1027, 0x46, 0x87},
+ {1033, 0x46, 0xa2},
+ {1039, 0x47, 0x40},
+ {1045, 0x46, 0xac},
+ {1051, 0x46, 0x86}
+};
+
+/*==========================================================================*/
+/*FS450 API Functions. */
+/*==========================================================================*/
+
+/* Initialize device settings */
+static void
+initialize_houston_static_registers(void)
+{
+ houston_WriteReg(HOUSTON_BYP, 0, 2);
+ houston_WriteReg(HOUSTON_APO, 0, 2);
+ houston_WriteReg(HOUSTON_ALO, 0, 2);
+ houston_WriteReg(HOUSTON_AFO, 0, 2);
+ houston_WriteReg(HOUSTON_BCONTL, 0, 2);
+ houston_WriteReg(HOUSTON_BCONTH, 0, 2);
+ houston_WriteReg(HOUSTON_BDONE, 0, 2);
+ houston_WriteReg(HOUSTON_BDIAGL, 0, 2);
+ houston_WriteReg(HOUSTON_BDIAGH, 0, 2);
+ houston_WriteReg(HOUSTON_MISC, 0, 2);
+}
+
+int
+FS450_init(void)
+{
+ int err;
+
+ TRACE(("FS450_Init()\n"))
+
+ err = houston_init();
+ if (err)
+ return err;
+
+ initialize_houston_static_registers();
+
+ d.tv_on = PLAL_IsTVOn()? 1 : 0;
+
+ /* get the current tv standard */
+ conget_tv_std(&d.tv_std);
+
+ d.vga_mode = 0;
+
+ /* default to VP_TVOUT_MODE_CVBS_YC */
+ d.tvout_mode = GFX_TVOUT_MODE_CVBS_YC;
+
+ /* default to 1000 out of 1000 */
+ d.sharpness = 1000;
+ config_sharpness(d.sharpness);
+
+ /* default to 800 out of 1000 */
+ d.flicker = 800;
+ config_flicker(d.flicker);
+
+ /* default to zeros */
+ d.overscan_x = 0;
+ d.overscan_y = 0;
+ d.position_x = 0;
+ d.position_y = 0;
+
+ d.color = 50;
+ /* d.color = tvsetup.color[k]; */
+ config_color(d.color);
+
+ /* default */
+ d.brightness = 50;
+ d.contrast = 60;
+ config_brightness_contrast(d.tv_std, d.aps_trigger_bits, d.brightness,
+ d.contrast);
+
+ /* get the current yc filtering */
+ {
+ int luma_filter, chroma_filter;
+
+ conget_yc_filter(&luma_filter, &chroma_filter);
+ d.yc_filter = 0;
+ if (luma_filter)
+ d.yc_filter |= GFX_LUMA_FILTER;
+ if (chroma_filter)
+ d.yc_filter |= GFX_CHROMA_FILTER;
+ }
+
+ d.aps_trigger_bits = 0;
+ config_macrovision(d.tv_std, d.aps_trigger_bits);
+
+ d.last_overscan_y = -10000;
+
+ return 0;
+}
+
+void
+FS450_cleanup(void)
+{
+}
+
+/*==========================================================================*/
+/* Required configuration calls to write new settings to the device */
+/*==========================================================================*/
+
+#define REQ_TV_STANDARD_BIT 0x0002
+#define REQ_VGA_MODE_BIT 0x0004
+#define REQ_TVOUT_MODE_BIT 0x0008
+#define REQ_SHARPNESS_BIT 0x0010
+#define REQ_FLICKER_BIT 0x0020
+#define REQ_OVERSCAN_POSITION_BIT 0x0040
+#define REQ_COLOR_BIT 0x0080
+#define REQ_BRIGHTNESS_CONTRAST_BIT 0x0100
+#define REQ_YC_FILTER_BIT 0x0200
+#define REQ_MACROVISION_BIT 0x0400
+#define REQ_NCO_BIT 0x1000
+
+#define REQ_TV_STANDARD (REQ_TV_STANDARD_BIT | REQ_OVERSCAN_POSITION \
+ | REQ_BRIGHTNESS_CONTRAST \
+ | REQ_MACROVISION_BIT | REQ_YC_FILTER)
+#define REQ_VGA_MODE (REQ_VGA_MODE_BIT | REQ_OVERSCAN_POSITION)
+#define REQ_TVOUT_MODE (REQ_TVOUT_MODE_BIT)
+#define REQ_SHARPNESS (REQ_SHARPNESS_BIT)
+#define REQ_FLICKER (REQ_FLICKER_BIT)
+#define REQ_OVERSCAN_POSITION (REQ_OVERSCAN_POSITION_BIT | REQ_NCO)
+#define REQ_COLOR (REQ_COLOR_BIT)
+#define REQ_BRIGHTNESS_CONTRAST (REQ_BRIGHTNESS_CONTRAST_BIT)
+#define REQ_YC_FILTER (REQ_YC_FILTER_BIT)
+#define REQ_MACROVISION (REQ_TV_STANDARD_BIT | \
+ REQ_BRIGHTNESS_CONTRAST_BIT | \
+ REQ_MACROVISION_BIT)
+#define REQ_NCO (REQ_NCO_BIT)
+#define REQ_ENCODER (REQ_TV_STANDARD | REQ_COLOR | \
+ REQ_BRIGHTNESS_CONTRAST | REQ_YC_FILTER)
+
+static int
+write_config(int req)
+{
+ unsigned long reg, reg_encoder_reset = 0;
+ int reset;
+
+ /*if we're changing the nco, and the vertical scaling has changed... */
+ reset = ((REQ_NCO_BIT & req) && (d.overscan_y != d.last_overscan_y));
+ if (reset) {
+ /*put the encoder into reset while making changes */
+ houston_ReadReg(ENC_RESET, &reg, 1);
+ houston_WriteReg(ENC_RESET, reg | 0x01, 1);
+ reg_encoder_reset = reg & 0x01;
+ }
+
+ if (REQ_TV_STANDARD_BIT & req)
+ config_tv_std(d.tv_std, d.aps_trigger_bits);
+
+ if (REQ_VGA_MODE_BIT & req)
+ config_vga_mode(d.vga_mode);
+
+ if (REQ_TVOUT_MODE_BIT & req)
+ config_tvout_mode(d.tvout_mode);
+
+ if (REQ_OVERSCAN_POSITION_BIT & req) {
+ config_overscan_xy(d.tv_std,
+ d.vga_mode,
+ d.overscan_x, d.overscan_y, d.position_x, d.position_y);
+
+ /*h_timing and v_timing and syncs. */
+ if (PLAL_IsTVOn())
+ PLAL_SetTVTimingRegisters(p_specs());
+ }
+
+ if (REQ_NCO_BIT & req)
+ config_nco(d.tv_std, d.vga_mode);
+
+ if (REQ_SHARPNESS_BIT & req)
+ config_sharpness(d.sharpness);
+
+ if (REQ_FLICKER_BIT & req)
+ config_flicker(d.flicker);
+
+ if (REQ_COLOR_BIT & req)
+ config_color(d.color);
+
+ if (REQ_BRIGHTNESS_CONTRAST_BIT & req) {
+ config_brightness_contrast(d.tv_std,
+ d.aps_trigger_bits, d.brightness, d.contrast);
+ }
+
+ if (REQ_YC_FILTER_BIT & req) {
+ config_yc_filter(d.tv_std,
+ (d.yc_filter & GFX_LUMA_FILTER),
+ (d.yc_filter & GFX_CHROMA_FILTER));
+ }
+
+ if (REQ_MACROVISION_BIT & req)
+ config_macrovision(d.tv_std, d.aps_trigger_bits);
+
+ /*if we decided to put the encoder into reset, put it back */
+ if (reset) {
+ houston_ReadReg(ENC_RESET, &reg, 1);
+ houston_WriteReg(ENC_RESET, reg_encoder_reset | (reg & ~0x01), 1);
+
+ d.last_overscan_y = d.overscan_y;
+ }
+ return 0;
+}
+
+/*==========================================================================*/
+/* TV On */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_tv_enable(unsigned int *p_on)
+#else
+int
+gfx_get_tv_enable(unsigned int *p_on)
+#endif
+{
+ if (!p_on)
+ return ERR_INVALID_PARAMETER;
+
+ *p_on = d.tv_on;
+
+ return 0;
+}
+
+/*//int FS450_set_tv_on(unsigned int on)*/
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_enable(int on)
+#else
+int
+gfx_set_tv_enable(int on)
+#endif
+{
+ unsigned long reg;
+
+ /*if not mode change, just return */
+ if ((d.tv_on && on) || (!d.tv_on && !on))
+ return 0;
+
+ /*if turning off... */
+ if (!on) {
+ /*reenable vga. */
+ PLAL_EnableVga();
+
+ /*power down houston */
+ config_power(0);
+
+ d.tv_on = 0;
+
+ return 0;
+ }
+
+ /*turning on... */
+
+ /*power up houston */
+ config_power(1);
+
+ /*assert encoder reset. */
+ houston_WriteReg(ENC_RESET, 0x01, 1);
+
+ /*initial platform preparation */
+ PLAL_PrepForTVout();
+
+ /*configure encoder and nco. */
+ write_config(REQ_VGA_MODE |
+ REQ_TV_STANDARD |
+ REQ_TVOUT_MODE |
+ REQ_OVERSCAN_POSITION | REQ_YC_FILTER | REQ_MACROVISION);
+
+ /*set LP_EN and UIM */
+ houston_ReadReg(HOUSTON_CR, &reg, 2);
+ reg |= CR_LP_EN;
+ reg &= ~(CR_UIM_MOD0 | CR_UIM_MOD1);
+ reg |= (PLAL_FS450_UIM_mode() << 14);
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+
+ /*set platform timing registers */
+ PLAL_SetTVTimingRegisters(p_specs());
+
+ PLAL_FinalEnableTVout(d.vga_mode);
+
+ /*sync bridge */
+ {
+ int retry_count = 0;
+
+ /*sync 50 times */
+ while (retry_count++ < 50) {
+ /*sync bridge. */
+ houston_ReadReg(HOUSTON_MISC, &reg, 2);
+ reg |= MISC_BRIDGE_SYNC;
+ houston_WriteReg(HOUSTON_MISC, reg, 2);
+ reg &= ~MISC_BRIDGE_SYNC;
+ houston_WriteReg(HOUSTON_MISC, reg, 2);
+ }
+ }
+
+ /*deassert encoder reset. */
+ houston_WriteReg(ENC_RESET, 0x00, 1);
+
+ d.tv_on = 1;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_defaults(int format)
+#else
+int
+gfx_set_tv_defaults(int format)
+#endif
+{
+ return 0;
+}
+
+/*==========================================================================*/
+/* TV standard */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_tv_standard(unsigned long *p_standard)
+#else
+int
+gfx_get_tv_standard(unsigned long *p_standard)
+#endif
+{
+ if (!p_standard)
+ return ERR_INVALID_PARAMETER;
+
+ *p_standard = d.tv_std;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_available_tv_standards(unsigned long *p_standards)
+#else
+int
+gfx_get_available_tv_standards(unsigned long *p_standards)
+#endif
+{
+ if (!p_standards)
+ return ERR_INVALID_PARAMETER;
+
+ *p_standards = supported_standards();
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_standard(unsigned long standard)
+#else
+int
+gfx_set_tv_standard(unsigned long standard)
+#endif
+{
+ /* verify supported standard. */
+ if (!(standard & supported_standards()))
+ return ERR_INVALID_PARAMETER;
+
+ /* disallow if tv is on */
+ if (d.tv_on)
+ return ERR_CANNOT_CHANGE_WHILE_TV_ON;
+
+ d.tv_std = standard;
+ /* d.color = tvsetup.color[k]; */
+
+ return write_config(REQ_TV_STANDARD);
+}
+
+/*==========================================================================*/
+/* vga mode as known by the driver */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_tv_vga_mode(unsigned long *p_vga_mode)
+#else
+int
+gfx_get_tv_vga_mode(unsigned long *p_vga_mode)
+#endif
+{
+ if (!p_vga_mode)
+ return ERR_INVALID_PARAMETER;
+
+ *p_vga_mode = d.vga_mode;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_available_tv_vga_modes(unsigned long *p_vga_modes)
+#else
+int
+gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes)
+#endif
+{
+ if (!p_vga_modes)
+ return ERR_INVALID_PARAMETER;
+
+ *p_vga_modes =
+ GFX_VGA_MODE_640X480 |
+ GFX_VGA_MODE_720X487 | GFX_VGA_MODE_720X576 | GFX_VGA_MODE_800X600;
+ if (houston_Rev() >= HOUSTON_REV_B)
+ *p_vga_modes |= GFX_VGA_MODE_1024X768;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_vga_mode(unsigned long vga_mode)
+#else
+int
+gfx_set_tv_vga_mode(unsigned long vga_mode)
+#endif
+{
+ /*reject if not a single valid VGA mode */
+ switch (vga_mode) {
+ default:
+ return ERR_INVALID_PARAMETER;
+ case GFX_VGA_MODE_640X480:
+ case GFX_VGA_MODE_720X487:
+ case GFX_VGA_MODE_720X576:
+ case GFX_VGA_MODE_800X600:
+ break;
+ case GFX_VGA_MODE_1024X768:
+ if (houston_Rev() >= HOUSTON_REV_B)
+ break;
+ return ERR_INVALID_PARAMETER;
+ }
+
+ /*if the mode has changed... */
+ if (vga_mode != d.vga_mode) {
+ d.vga_mode = vga_mode;
+
+ return write_config(REQ_VGA_MODE);
+ }
+
+ return 0;
+}
+
+/*==========================================================================*/
+/* tvout mode */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_tvout_mode(unsigned long *p_tvout_mode)
+#else
+int
+gfx_get_tvout_mode(unsigned long *p_tvout_mode)
+#endif
+{
+ if (!p_tvout_mode)
+ return ERR_INVALID_PARAMETER;
+
+ *p_tvout_mode = d.tvout_mode;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tvout_mode(unsigned long tvout_mode)
+#else
+int
+gfx_set_tvout_mode(unsigned long tvout_mode)
+#endif
+{
+ d.tvout_mode = tvout_mode;
+
+ return write_config(REQ_TVOUT_MODE);
+}
+
+/*==========================================================================*/
+/* Sharpness */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_sharpness(int *p_sharpness)
+#else
+int
+gfx_get_sharpness(int *p_sharpness)
+#endif
+{
+ if (!p_sharpness)
+ return ERR_INVALID_PARAMETER;
+
+ *p_sharpness = d.sharpness;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_sharpness(int sharpness)
+#else
+int
+gfx_set_sharpness(int sharpness)
+#endif
+{
+ d.sharpness = range_limit(sharpness, 0, 1000);
+
+ return write_config(REQ_SHARPNESS);
+}
+
+/*==========================================================================*/
+/* flicker filter control. */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_flicker_filter(int *p_flicker)
+#else
+int
+gfx_get_flicker_filter(int *p_flicker)
+#endif
+{
+ if (!p_flicker)
+ return ERR_INVALID_PARAMETER;
+
+ *p_flicker = d.flicker;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_flicker_filter(int flicker)
+#else
+int
+gfx_set_flicker_filter(int flicker)
+#endif
+{
+ d.flicker = range_limit(flicker, 0, 1000);
+
+ return write_config(REQ_FLICKER);
+}
+
+/*==========================================================================*/
+/* Overscan and Position */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_overscan(int *p_x, int *p_y)
+#else
+int
+gfx_get_overscan(int *p_x, int *p_y)
+#endif
+{
+ if (!p_x || !p_y)
+ return ERR_INVALID_PARAMETER;
+
+ *p_x = d.overscan_x;
+ *p_y = d.overscan_y;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_overscan(int x, int y)
+#else
+int
+gfx_set_overscan(int x, int y)
+#endif
+{
+ d.overscan_x = range_limit(x, -1000, 1000);
+ d.overscan_y = range_limit(y, -1000, 1000);
+
+ return write_config(REQ_OVERSCAN_POSITION);
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_position(int *p_x, int *p_y)
+#else
+int
+gfx_get_position(int *p_x, int *p_y)
+#endif
+{
+ if (!p_x || !p_y)
+ return ERR_INVALID_PARAMETER;
+
+ *p_x = d.position_x;
+ *p_y = d.position_y;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_position(int x, int y)
+#else
+int
+gfx_set_position(int x, int y)
+#endif
+{
+ d.position_x = range_limit(x, -1000, 1000);
+ d.position_y = range_limit(y, -1000, 1000);
+
+ return write_config(REQ_OVERSCAN_POSITION);
+}
+
+/*==========================================================================*/
+/* Color, Brightness, and Contrast */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_color(int *p_color)
+#else
+int
+gfx_get_color(int *p_color)
+#endif
+{
+ if (!p_color)
+ return ERR_INVALID_PARAMETER;
+
+ *p_color = d.color;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_color(int color)
+#else
+int
+gfx_set_color(int color)
+#endif
+{
+ d.color = range_limit(color, 0, 100);
+
+ return write_config(REQ_COLOR);
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_brightness(int *p_brightness)
+#else
+int
+gfx_get_brightness(int *p_brightness)
+#endif
+{
+ if (!p_brightness)
+ return ERR_INVALID_PARAMETER;
+
+ *p_brightness = d.brightness;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_brightness(int brightness)
+#else
+int
+gfx_set_brightness(int brightness)
+#endif
+{
+ d.brightness = range_limit(brightness, 0, 100);
+
+ return write_config(REQ_BRIGHTNESS_CONTRAST);
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_contrast(int *p_contrast)
+#else
+int
+gfx_get_contrast(int *p_contrast)
+#endif
+{
+ if (!p_contrast)
+ return ERR_INVALID_PARAMETER;
+
+ *p_contrast = d.contrast;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_contrast(int constrast)
+#else
+int
+gfx_set_contrast(int constrast)
+#endif
+{
+ d.contrast = range_limit(constrast, 0, 100);
+
+ return write_config(REQ_BRIGHTNESS_CONTRAST);
+}
+
+/*==========================================================================*/
+/* YC filters */
+/*==========================================================================*/
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_yc_filter(unsigned int *p_yc_filter)
+#else
+int
+gfx_get_yc_filter(unsigned int *p_yc_filter)
+#endif
+{
+ if (!p_yc_filter)
+ return ERR_INVALID_PARAMETER;
+
+ if (houston_Rev() < HOUSTON_REV_B)
+ return ERR_NOT_SUPPORTED;
+
+ *p_yc_filter = d.yc_filter;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_yc_filter(unsigned int yc_filter)
+#else
+int
+gfx_set_yc_filter(unsigned int yc_filter)
+#endif
+{
+ if (houston_Rev() < HOUSTON_REV_B)
+ return ERR_NOT_SUPPORTED;
+
+ /*luma filter. */
+ if (yc_filter & GFX_LUMA_FILTER)
+ d.yc_filter |= GFX_LUMA_FILTER;
+ else
+ d.yc_filter &= ~GFX_LUMA_FILTER;
+
+ /*chroma filter. */
+ if (yc_filter & GFX_CHROMA_FILTER)
+ d.yc_filter |= GFX_CHROMA_FILTER;
+ else
+ d.yc_filter &= ~GFX_CHROMA_FILTER;
+
+ return write_config(REQ_YC_FILTER);
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_get_aps_trigger_bits(unsigned int *p_trigger_bits)
+#else
+int
+gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits)
+#endif
+{
+ if (!p_trigger_bits)
+ return ERR_INVALID_PARAMETER;
+
+ *p_trigger_bits = d.aps_trigger_bits;
+
+ return 0;
+}
+
+#if GFX_TV_DYNAMIC
+int
+fs450_set_aps_trigger_bits(unsigned int trigger_bits)
+#else
+int
+gfx_set_aps_trigger_bits(unsigned int trigger_bits)
+#endif
+{
+ d.aps_trigger_bits = trigger_bits;
+
+ return write_config(REQ_MACROVISION);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_format
+ *
+ * This routine sets the TV encoder registers to the specified format
+ * and resolution.
+ * Currently only NTSC 640x480 is supported.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_format(TVStandardType format, GfxOnTVType resolution)
+#else
+int
+gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution)
+#endif
+{
+ /* ### ADD ### IMPLEMENTATION */
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_output
+ *
+ * This routine sets the TV encoder registers to the specified output type.
+ * Supported output types are : S-VIDEO and Composite.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_output(int output)
+#else
+int
+gfx_set_tv_output(int output)
+#endif
+{
+ /* ### ADD ### IMPLEMENTATION */
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_cc_enable
+ *
+ * This routine enables or disables the use of the hardware CC registers
+ * in the TV encoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_cc_enable(int enable)
+#else
+int
+gfx_set_tv_cc_enable(int enable)
+#endif
+{
+ /* ### ADD ### IMPLEMENTATION */
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_tv_cc_data
+ *
+ * This routine writes the two specified characters to the CC data register
+ * of the TV encoder.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_TV_DYNAMIC
+int
+fs450_set_tv_cc_data(unsigned char data1, unsigned char data2)
+#else
+int
+gfx_set_tv_cc_data(unsigned char data1, unsigned char data2)
+#endif
+{
+ /* ### ADD ### IMPLEMENTATION */
+ return (0);
+}
+
+#ifdef FS450_DIRECTREG
+
+/*==========================================================================*/
+/* Direct Read and Write registers */
+/*==========================================================================*/
+
+int
+FS450_ReadRegister(S_REG_INFO * p_reg)
+{
+ unsigned long tmp;
+
+ if (PLAL_ReadRegister(p_reg))
+ return 0;
+
+ if (SOURCE_HOUSTON == p_reg->source) {
+ switch (p_reg->size) {
+ case 1:
+ case 2:
+ {
+ houston_ReadReg((int)p_reg->offset, &tmp, (int)p_reg->size);
+ p_reg->value = tmp;
+ }
+ return 0;
+
+ case 4:
+ {
+ houston_ReadReg((unsigned int)p_reg->offset, &tmp, 2);
+ p_reg->value = (tmp << 16);
+ houston_ReadReg((unsigned int)(p_reg->offset + 2), &tmp, 2);
+ p_reg->value |= tmp;
+ }
+ return 0;
+ }
+ }
+
+ return ERR_INVALID_PARAMETER;
+}
+
+int
+FS450_WriteRegister(S_REG_INFO * p_reg)
+{
+ if (PLAL_WriteRegister(p_reg))
+ return 0;
+
+ if (SOURCE_HOUSTON == p_reg->source) {
+ houston_WriteReg((unsigned int)p_reg->offset, p_reg->value,
+ p_reg->size);
+
+ return 0;
+ }
+
+ return ERR_INVALID_PARAMETER;
+}
+
+#endif
+
+/* Houston initialization function. */
+static int g_houston_rev = -1;
+
+static int
+houston_init(void)
+{
+ /*//int errc; */
+ unsigned long write, read;
+
+ TRACE(("houston_init()\n"))
+
+ /*Before we begin, we must enable power to the TFT */
+ read = READ_VID32(CS5530_DISPLAY_CONFIG);
+ read |= CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN;
+ WRITE_VID32(CS5530_DISPLAY_CONFIG, read);
+
+ /*simple w/r test. */
+ write = 0x0055;
+ read = 0;
+
+ houston_WriteReg(HOUSTON_IHO, write, 2);
+ houston_ReadReg(HOUSTON_IHO, &read, 2);
+ if (read != write) {
+ houston_WriteReg(HOUSTON_IHO, write, 2);
+ houston_ReadReg(HOUSTON_IHO, &read, 2);
+ if (read != write) {
+ /*chip is not there, do something appropriate? */
+ TRACE(("wrote HOUSTON_IHO=0x0055, read 0x%04x\n", read))
+ return ERR_DEVICE_NOT_FOUND;
+ }
+ }
+
+ /*read chip revision. */
+ houston_ReadReg(HOUSTON_REV, &read, 2);
+ g_houston_rev = (int)read;
+
+ /*ok. */
+ return 0;
+}
+
+static int
+houston_Rev(void)
+{
+ return g_houston_rev;
+}
+
+static S_TIMING_SPECS g_specs;
+
+static const S_TIMING_SPECS *
+p_specs(void)
+{
+ return &g_specs;
+}
+
+/*==========================================================================*/
+/* FS450 configuration functions. */
+/*==========================================================================*/
+static int
+config_init(void)
+{
+ int err;
+
+ TRACE(("config_init()\n"))
+
+ err = houston_init();
+ if (err)
+ return err;
+
+ return 0;
+}
+
+/*==========================================================================*/
+/* convert word to encoder 10 bit value. */
+/*==========================================================================*/
+
+static unsigned short
+w10bit2z(unsigned short w)
+{
+ return (w >> 2) | ((w & 0x03) << 8);
+}
+
+static unsigned short
+z2w10bit(unsigned short z)
+{
+ return (0x03 & (z >> 8)) | ((0xFF & z) << 2);
+}
+
+/*==========================================================================*/
+/* TV Standards */
+/*==========================================================================*/
+
+static const struct
+{
+ unsigned long standard;
+ int tvsetup_index;
+} g_tv_standards[] = {
+ {
+ GFX_TV_STANDARD_NTSC_M, 0}, {
+ GFX_TV_STANDARD_NTSC_M_J, 2}, {
+ GFX_TV_STANDARD_PAL_B, 1}, {
+ GFX_TV_STANDARD_PAL_D, 1}, {
+ GFX_TV_STANDARD_PAL_H, 1}, {
+ GFX_TV_STANDARD_PAL_I, 1}, {
+ GFX_TV_STANDARD_PAL_M, 3}, {
+ GFX_TV_STANDARD_PAL_N, 4}, {
+GFX_TV_STANDARD_PAL_G, 1},};
+
+static int
+map_tvstd_to_index(unsigned long tv_std)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) {
+ if (tv_std == g_tv_standards[i].standard)
+ return g_tv_standards[i].tvsetup_index;
+ }
+
+ return -1;
+}
+
+static unsigned long
+supported_standards(void)
+{
+ unsigned long standards = 0;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(g_tv_standards) / sizeof(*g_tv_standards); i++) {
+ if (g_tv_standards[i].tvsetup_index >= 0)
+ standards |= g_tv_standards[i].standard;
+ }
+
+ return standards;
+}
+
+/*==========================================================================*/
+
+static void
+config_power(int on)
+{
+ unsigned long reg;
+
+ if (houston_Rev() < HOUSTON_REV_B) {
+ /* no power down supported, but still turn of clock in off mode */
+ if (on) {
+ houston_ReadReg(HOUSTON_CR, &reg, 2);
+ reg &= ~(CR_CLKOFF | CR_RESET);
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+ reg |= CR_RESET;
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+ reg &= ~CR_RESET;
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+ } else {
+ houston_ReadReg(HOUSTON_CR, &reg, 2);
+ reg |= CR_CLKOFF;
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+ }
+
+ return;
+ }
+
+ if (on) {
+ /* !CLKOFF, !COMPOFF, !YCOFF */
+ /* and reset Houston */
+ houston_ReadReg(HOUSTON_CR, &reg, 2);
+ reg &= ~(CR_CLKOFF | CR_RESET | CR_COMPOFF | CR_YCOFF);
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+ reg |= CR_RESET;
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+ reg &= ~CR_RESET;
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+
+ /* !GTLIO_PD */
+ houston_ReadReg(HOUSTON_MISC, &reg, 2);
+ reg &= ~MISC_GTLIO_PD;
+ houston_WriteReg(HOUSTON_MISC, reg, 2);
+ } else {
+ /* CLKOFF, COMPOFF, YCOFF */
+ houston_ReadReg(HOUSTON_CR, &reg, 2);
+ reg |= (CR_CLKOFF | CR_COMPOFF | CR_YCOFF);
+ houston_WriteReg(HOUSTON_CR, reg, 2);
+
+ /* GTLIO_PD */
+ houston_ReadReg(HOUSTON_MISC, &reg, 2);
+ reg |= MISC_GTLIO_PD;
+ houston_WriteReg(HOUSTON_MISC, reg, 2);
+ }
+}
+
+/*==========================================================================*/
+/* VGA mode */
+/*==========================================================================*/
+
+static void
+config_vga_mode(unsigned long vga_mode)
+{
+ /*h_total must be evenly divisible by 32? */
+
+ static struct
+ {
+ unsigned long mode;
+ int width;
+ int lines;
+ int h_total;
+ } vgaparams[] = {
+ {
+ GFX_VGA_MODE_640X480, 640, 480, 1056}, {
+ GFX_VGA_MODE_720X487, 720, 487, 1056}, {
+ GFX_VGA_MODE_720X576, 720, 576, 1056}, {
+ GFX_VGA_MODE_800X600, 800, 600, 1056}, {
+ GFX_VGA_MODE_1024X768, 1024, 768, 1344},};
+
+ unsigned long cr, misc, byp;
+ unsigned int i;
+
+ g_specs.vga_width = 0;
+ g_specs.vga_lines = 0;
+ g_specs.h_total = 0;
+
+ for (i = 0; i < sizeof(vgaparams) / sizeof(*vgaparams); i++) {
+ if (vga_mode == vgaparams[i].mode) {
+ g_specs.vga_width = vgaparams[i].width;
+ g_specs.vga_lines = vgaparams[i].lines;
+ g_specs.h_total = vgaparams[i].h_total;
+ break;
+ }
+ }
+ if (!g_specs.h_total)
+ return;
+
+ /*clock mux decimator and vga dual. */
+ houston_ReadReg(HOUSTON_CR, &cr, 2);
+ houston_ReadReg(HOUSTON_MISC, &misc, 2);
+ houston_ReadReg(HOUSTON_BYP, &byp, 2);
+
+ if (vga_mode == GFX_VGA_MODE_1024X768) {
+ /*XGA*/ cr |= CR_UIM_DEC;
+ misc |= MISC_VGACKDIV;
+ byp |= (BYP_HDS_BYPASS | BYP_CAC_BYPASS);
+ } else {
+ /*VGA,SVGA */
+ cr &= ~CR_UIM_DEC;
+ misc &= ~MISC_VGACKDIV;
+ byp &= ~(BYP_HDS_BYPASS | BYP_CAC_BYPASS);
+ }
+
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+ houston_WriteReg(HOUSTON_MISC, misc, 2);
+ houston_WriteReg(HOUSTON_BYP, byp, 2);
+}
+
+/*==========================================================================*/
+/* Write settings for TV standard to device */
+/*==========================================================================*/
+
+static void
+config_tv_std(unsigned long tv_std, unsigned int trigger_bits)
+{
+ int k;
+ unsigned short reg34;
+ unsigned long cr, w;
+ unsigned long l;
+
+ /*verify supported standard. */
+ k = map_tvstd_to_index(tv_std);
+ if (k < 0)
+ return;
+
+ /*store tv width and lines */
+ g_specs.tv_width = tvsetup.tv_width[k];
+ g_specs.tv_lines = tvsetup.tv_lines[k];
+
+ /*houston CR register. */
+ houston_ReadReg(HOUSTON_CR, &cr, 2);
+ cr &= ~CR_656_PAL_NTSC;
+ cr |= tvsetup.houston_cr[k];
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+
+ /*setup the encoder. */
+ l = tvsetup.chroma_freq[k];
+ houston_WriteReg(ENC_CHROMA_FREQ, (int)(l & 0x00ff), 1);
+ houston_WriteReg(ENC_CHROMA_FREQ + 1, (int)((l >> 8) & 0x00ff), 1);
+ houston_WriteReg(ENC_CHROMA_FREQ + 2, (int)((l >> 16) & 0x00ff), 1);
+ houston_WriteReg(ENC_CHROMA_FREQ + 3, (int)((l >> 24) & 0x00ff), 1);
+
+ houston_WriteReg(ENC_CHROMA_PHASE, tvsetup.chroma_phase[k], 1);
+ houston_WriteReg(ENC_REG05, 0x00, 1); /*reg 0x05 */
+ houston_WriteReg(ENC_REG06, 0x89, 1); /*reg 0x06 */
+ houston_WriteReg(ENC_REG07, 0x00, 1); /*reg 0x07 */
+ houston_WriteReg(ENC_HSYNC_WIDTH, tvsetup.hsync_width[k], 1);
+ houston_WriteReg(ENC_BURST_WIDTH, tvsetup.burst_width[k], 1);
+ houston_WriteReg(ENC_BACK_PORCH, tvsetup.back_porch[k], 1);
+ houston_WriteReg(ENC_CB_BURST_LEVEL, tvsetup.cb_burst_level[k], 1);
+ houston_WriteReg(ENC_CR_BURST_LEVEL, tvsetup.cr_burst_level[k], 1);
+ houston_WriteReg(ENC_SLAVE_MODE, 0x01, 1); /*slave mode */
+ if (trigger_bits == 0)
+ w = w10bit2z(tvsetup.blank_level[k]); /*blank level */
+ else
+ w = w10bit2z((unsigned short)(tvsetup.blank_level[k] -
+ tvsetup.hamp_offset[k]));
+ houston_WriteReg(ENC_BLANK_LEVEL, w & 0x00ff, 1);
+ houston_WriteReg(ENC_BLANK_LEVEL + 1, w >> 8, 1);
+ w = w10bit2z(tvsetup.tv_lines[k]); /*num_lines */
+ houston_WriteReg(ENC_NUM_LINES, w & 0x00ff, 1);
+ houston_WriteReg(ENC_NUM_LINES + 1, w >> 8, 1);
+
+ houston_WriteReg(ENC_TINT, 0x00, 1); /*tint */
+ houston_WriteReg(ENC_BREEZE_WAY, tvsetup.breeze_way[k], 1);
+ houston_WriteReg(ENC_FRONT_PORCH, tvsetup.front_porch[k], 1);
+ houston_WriteReg(ENC_ACTIVELINE, tvsetup.activeline[k], 1);
+ houston_WriteReg(ENC_FIRST_LINE, 0x15, 1); /*firstvideoline */
+ reg34 =
+ 0x80 |
+ (tvsetup.pal_mode[k] << 6) |
+ (tvsetup.sys625_50[k] << 3) |
+ (tvsetup.cphase_rst[k] << 1) | (tvsetup.vsync5[k]);
+ houston_WriteReg(ENC_REG34, reg34, 1); /*reg 0x34 */
+ houston_WriteReg(ENC_SYNC_LEVEL, tvsetup.sync_level[k], 1);
+ if (trigger_bits == 0)
+ w = w10bit2z(tvsetup.vbi_blank_level[k]); /*blank level */
+ else
+ w = w10bit2z((unsigned short)(tvsetup.vbi_blank_level[k] - 1));
+ houston_WriteReg(ENC_VBI_BLANK_LEVEL, w & 0x00ff, 1);
+ houston_WriteReg(ENC_VBI_BLANK_LEVEL + 1, w >> 8, 1);
+}
+
+static void
+conget_tv_std(unsigned long *p_tv_standard)
+{
+ unsigned long cr;
+
+ if (!p_tv_standard)
+ return;
+
+ /*just pick between NTSC and PAL */
+ houston_ReadReg(HOUSTON_CR, &cr, 2);
+ if (CR_656_PAL_NTSC & cr)
+ *p_tv_standard = GFX_TV_STANDARD_PAL_B;
+ else
+ *p_tv_standard = GFX_TV_STANDARD_NTSC_M;
+}
+
+/*==========================================================================*/
+/* TVout mode */
+/*==========================================================================*/
+
+static void
+config_tvout_mode(unsigned long tvout_mode)
+{
+ unsigned long cr;
+
+ houston_ReadReg(HOUSTON_CR, &cr, 2);
+
+ /*all dacs off */
+ cr |= (CR_COMPOFF | CR_YCOFF);
+ /*not rgb */
+ cr &= ~CR_OFMT;
+
+ /*turn on requested output */
+ if (GFX_TVOUT_MODE_CVBS & tvout_mode)
+ cr &= ~CR_COMPOFF;
+ if (GFX_TVOUT_MODE_YC & tvout_mode)
+ cr &= ~CR_YCOFF;
+ if (GFX_TVOUT_MODE_RGB & tvout_mode) {
+ cr &= ~(CR_COMPOFF | CR_YCOFF);
+ cr |= CR_OFMT;
+ }
+
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+}
+
+static void
+conget_tvout_mode(unsigned long *p_tvout_mode)
+{
+ unsigned long cr;
+
+ if (!p_tvout_mode)
+ return;
+
+ houston_ReadReg(HOUSTON_CR, &cr, 2);
+
+ if (CR_OFMT & cr)
+ *p_tvout_mode = GFX_TVOUT_MODE_RGB;
+ else {
+ *p_tvout_mode = 0;
+ if (!(CR_YCOFF & cr))
+ *p_tvout_mode |= GFX_TVOUT_MODE_YC;
+ if (!(CR_COMPOFF & cr))
+ *p_tvout_mode |= GFX_TVOUT_MODE_CVBS;
+ }
+}
+
+/*==========================================================================*/
+/* Size & Position */
+/*==========================================================================*/
+
+#define IS_NTSC(tv_std) \
+ (tv_std & ( \
+ GFX_TV_STANDARD_NTSC_M | \
+ GFX_TV_STANDARD_NTSC_M_J | \
+ GFX_TV_STANDARD_PAL_M))
+#define IS_PAL(tv_std) \
+ (tv_std & ( \
+ GFX_TV_STANDARD_PAL_B | \
+ GFX_TV_STANDARD_PAL_D | \
+ GFX_TV_STANDARD_PAL_H | \
+ GFX_TV_STANDARD_PAL_I | \
+ GFX_TV_STANDARD_PAL_N | \
+ GFX_TV_STANDARD_PAL_G))
+
+/*return fifo delay setting for mode, std, and total lines.*/
+
+static void
+get_ffolat_ivo(unsigned long vga_mode,
+ unsigned long tv_std, long i, unsigned short *ffolat, unsigned short *ivo)
+{
+ switch (vga_mode) {
+ case GFX_VGA_MODE_640X480:
+ if (IS_NTSC(tv_std)) {
+ if (i > SIZE6X4NTSC - 1)
+ i = SIZE6X4NTSC - 1;
+ *ffolat = ffo6x4ntsc[i].ffolat;
+ *ivo = 0x20;
+ } else {
+ if (i > SIZE6X4PAL - 1)
+ i = SIZE6X4PAL - 1;
+ *ffolat = ffo6x4pal[i].ffolat;
+ *ivo = 0x28;
+ }
+ break;
+
+ case GFX_VGA_MODE_800X600:
+ if (IS_NTSC(tv_std)) {
+ if (i > SIZE8X6NTSC - 1)
+ i = SIZE8X6NTSC - 1;
+ *ffolat = ffo8x6ntsc[i].ffolat;
+ *ivo = 0x3a;
+ } else {
+ if (i > SIZE8X6PAL - 1)
+ i = SIZE8X6PAL - 1;
+ *ffolat = ffo8x6pal[i].ffolat;
+ *ivo = 0x39;
+ }
+ break;
+
+ case GFX_VGA_MODE_720X487:
+ *ffolat = 0x40; /*FFO7x4; */
+ *ivo = 0x1a;
+ break;
+
+ case GFX_VGA_MODE_720X576:
+ *ffolat = 0x40; /*FFO7x5; */
+ *ivo = 0x1a;
+ break;
+
+ case GFX_VGA_MODE_1024X768:
+ default:
+ if (IS_NTSC(tv_std)) {
+ if (i > SIZE10X7NTSC - 1)
+ i = SIZE10X7NTSC - 1;
+ *ffolat = ffo10x7ntsc[i].ffolat;
+ *ivo = ffo10x7ntsc[i].ivo;
+ } else {
+ if (i > SIZE10X7PAL - 1)
+ i = SIZE10X7PAL - 1;
+ *ffolat = ffo10x7pal[i].ffolat;
+ *ivo = ffo10x7pal[i].ivo;
+ }
+ break;
+ }
+}
+
+/*get vertical line min and max for mode and std.*/
+
+static void
+get_vtotal_min_max(unsigned long vga_mode,
+ unsigned long tv_std, int *v_total_min, int *v_total_max, int *v_step)
+{
+ int k = map_tvstd_to_index(tv_std);
+
+ switch (vga_mode) {
+ case GFX_VGA_MODE_640X480:
+ if (IS_NTSC(tv_std)) {
+ *v_total_min = ffo6x4ntsc[0].v_total;
+ *v_total_max = ffo6x4ntsc[SIZE6X4NTSC - 1].v_total;
+ } else {
+ *v_total_min = ffo6x4pal[0].v_total;
+ *v_total_max = ffo6x4pal[SIZE6X4PAL - 1].v_total;
+ }
+ *v_step = 4;
+ break;
+
+ case GFX_VGA_MODE_800X600:
+ if (IS_NTSC(tv_std)) {
+ *v_total_min = ffo8x6ntsc[0].v_total;
+ *v_total_max = ffo8x6ntsc[SIZE8X6NTSC - 1].v_total;
+ } else {
+ *v_total_min = ffo8x6pal[0].v_total;
+ *v_total_max = ffo8x6pal[SIZE8X6PAL - 1].v_total;
+ }
+ *v_step = 5;
+ break;
+
+ case GFX_VGA_MODE_720X487:
+ case GFX_VGA_MODE_720X576:
+ *v_total_min = tvsetup.tv_lines[k];
+ *v_total_max = tvsetup.tv_lines[k];
+ *v_step = 4;
+ break;
+
+ case GFX_VGA_MODE_1024X768:
+ if (IS_NTSC(tv_std)) {
+ *v_total_min = ffo10x7ntsc[0].v_total;
+ *v_total_max = ffo10x7ntsc[SIZE10X7NTSC - 1].v_total;
+ } else {
+ *v_total_min = ffo10x7pal[0].v_total;
+ *v_total_max = ffo10x7pal[SIZE10X7PAL - 1].v_total;
+ }
+ *v_step = 6;
+ break;
+ }
+}
+
+static void
+config_overscan_xy(unsigned long tv_std,
+ unsigned long vga_mode,
+ int overscan_x, int overscan_y, int pos_x, int pos_y)
+{
+ unsigned int vga_index;
+ unsigned long reg;
+ double vsc;
+ int k;
+ unsigned short ffolat, ivo;
+ int base_v_total, range, v_offset;
+ int v_total_min, v_total_max, v_step;
+ float r, f;
+ int vga_pixels, pre_pixels;
+ float hscale, hscale_min, hscale_max;
+ int hsc;
+ int iho, iho_max, ihw;
+
+ /*tv_std is valid. */
+ k = map_tvstd_to_index(tv_std);
+
+ /*store tv width and lines */
+ g_specs.tv_width = tvsetup.tv_width[k];
+ g_specs.tv_lines = tvsetup.tv_lines[k];
+
+ /*determine vga mode index */
+ for (vga_index = 0; vga_index < SCANTABLE_ENTRIES; vga_index++) {
+ if (scantable[vga_index].mode == vga_mode)
+ break;
+ }
+ if (vga_index >= SCANTABLE_ENTRIES)
+ return;
+
+ /*vertical scaling (v_total setup). */
+ /*calculate vertical range. */
+ get_vtotal_min_max(vga_mode, tv_std, &v_total_min, &v_total_max, &v_step);
+ TRACE(("v_total min=%d, max=%d\n", v_total_min, v_total_max))
+ base_v_total = scantable[vga_index].v_total[k];
+ range = fsmax(base_v_total - v_total_min, v_total_max - base_v_total);
+ TRACE(("v_total range = %d\n", range))
+
+ /*map +/-1000 overscan y into +/-range. */
+ v_offset = (int)((((float)overscan_y * range) / 1000.f) + .5f);
+ TRACE(("v_offset = %d\n", v_offset))
+
+ /*range limit v_total. */
+ g_specs.v_total =
+ range_limit(base_v_total + v_offset, v_total_min, v_total_max);
+
+ /*round to calibrated value. */
+ v_offset = (g_specs.v_total - v_total_min + (v_step / 2)) / v_step;
+ g_specs.v_total = v_total_min + v_offset * v_step;
+ TRACE(("desired v_total=%d\n", g_specs.v_total))
+
+ /*vertical positioning (vsync setup). */
+ get_ffolat_ivo(vga_mode, tv_std, v_offset, &ffolat, &ivo);
+ houston_WriteReg(HOUSTON_IVO, ivo, 2);
+
+ /*scale base sync offset by scaling ratio. */
+ r = (float)g_specs.v_total / (float)base_v_total;
+ v_offset = (int)(r * (float)scantable[vga_index].v_sync[k]);
+
+ /*scale ivo. */
+ f = (float)ivo;
+ v_offset -= (int)(f - f / r);
+
+ /*compensate for center screen. */
+ f = (float)tvsetup.tv_active_lines[k] / 2.f;
+ v_offset += (int)(f * r - f);
+
+ /*calculate vsync. */
+ g_specs.v_sync = g_specs.v_total - v_offset + pos_y;
+ TRACE(("desired v_total=%d, desired v_sync=%d\n", g_specs.v_total,
+ g_specs.v_sync))
+ if (g_specs.v_sync < g_specs.vga_lines + 10) {
+ TRACE(("vsync too low\n"))
+ /*d.v_total += d.vga_lines+10-d.v_sync; */
+ g_specs.v_sync = g_specs.vga_lines + 10;
+ } else if (g_specs.v_sync > g_specs.v_total - 10) {
+ TRACE(("vsync too high\n"))
+ g_specs.v_sync = g_specs.v_total - 10;
+ }
+ TRACE(("v_total=%d v_sync=%d\n", g_specs.v_total, g_specs.v_sync))
+
+ /* FFOLAT. */
+ houston_WriteReg(HOUSTON_FFO_LAT, ffolat, 2);
+
+ /* VSC. */
+ vsc =
+ (65536.0f * (1.0f -
+ (double)g_specs.tv_lines / (double)g_specs.v_total)) + 0.5f;
+ reg = ((unsigned long)-vsc) & 0xffff;
+ TRACE(("vsc=%04x, tv_lines=%d, v_total=%d\n", reg, g_specs.tv_lines,
+ g_specs.v_total))
+ houston_WriteReg(HOUSTON_VSC, (int)reg, 2);
+
+ /* horizontal scaling. */
+
+ /* vga pixels is vga width, except in 1024x768, where it's half that. */
+ vga_pixels = g_specs.vga_width;
+ if (1024 == vga_pixels)
+ vga_pixels /= 2;
+
+ /* maximum scaling coefficient is tv_width / vga_pixels */
+ /* minimum is about 1/2, but that is quite small. arbitrarily set
+ * minimum at 75% maximum. */
+ hscale_max = (720.0f / vga_pixels);
+ hscale_min = fsmax((0.75f * hscale_max), (1.0f - (63.0f / 128.0f)));
+ TRACE(("hscale_min = %u.%u, hscale_max = %u.%u\n",
+ (int)hscale_min,
+ (int)((hscale_min - (int)hscale_min) * 1000),
+ (int)hscale_max, (int)((hscale_max - (int)hscale_max) * 1000)))
+
+ /* map overscan_x into min to max. */
+ hscale =
+ hscale_min + ((overscan_x + 1000.0f) / 2000.0f) * (hscale_max -
+ hscale_min);
+ TRACE(("hscale = %u.%u\n", (int)hscale,
+ (int)((hscale - (int)hscale) * 1000)))
+
+ /* determine hsc where hscale = (1 + hsc/128) */
+ if (hscale >= 1.0f)
+ hsc = (int)(128.f * (hscale - 1.0f) + .5f);
+ else
+ hsc = (int)(128.f * (hscale - 1.0f) - .5f);
+
+ TRACE(("hsc = %d\n", hsc))
+ if (hsc >= 0)
+ houston_WriteReg(HOUSTON_HSC, hsc << 8, 2);
+ else
+ houston_WriteReg(HOUSTON_HSC, hsc & 0xFF, 2);
+
+ /* recalculate hscale for future formulas */
+ hscale = 1.0f + (hsc / 128.0f);
+ TRACE(("recalculated hscale = %u.%u\n", (int)hscale,
+ (int)((hscale - (int)hscale) * 1000)))
+
+ /* horizontal offset. */
+ /* place hsync 40 before halfway from vga_width to htotal */
+ /* but not less than vga_width + 10 */
+ g_specs.h_sync =
+ fsmax((g_specs.h_total + g_specs.vga_width) / 2 - 40,
+ g_specs.vga_width + 10);
+ /* also, make it even */
+ g_specs.h_sync &= ~1;
+ TRACE(("hsync = %u\n", g_specs.h_sync))
+
+ /* iho range is 0 to iho_max. */
+ /* iho_max is 2 * iho_center. */
+ /* iho_center is pre_pixels - (tvwidth / hscale - vga pixels) / 2. */
+ /* pre_pixels = (htotal - hsync) * (vga_pixels / vga_width) */
+ /* note that the range is inverted also, because it specifies the number
+ * of pixels */
+ /* to skip, or subtract. iho=0 maps to farthest right. */
+ /* map -pos_x = +/-1000 into (0 to iho_max) */
+ pre_pixels =
+ (int)((long)(g_specs.h_total -
+ g_specs.h_sync) * vga_pixels / g_specs.vga_width);
+ iho_max = (2 * pre_pixels) - ((int)(720.0f / hscale + 0.5f) - vga_pixels);
+ TRACE(("iho_max = %u\n", iho_max))
+ iho =
+ (int)range_limit(((long)(1000 - pos_x) * iho_max / 2000) +
+ scantable[vga_index].iho[k], 0, iho_max);
+ TRACE(("iho = %u\n", iho))
+ houston_WriteReg(HOUSTON_IHO, iho, 2);
+
+ /* input horizontal width. */
+
+ /* input horizontal width is vga pixels + pre_pixels - iho */
+ /* additionally, ihw cannot exceed tv width / hscale */
+ /* and if hsc is negative, (ihw)(-hsc/128) cannot exceed ~250. */
+ /* and ihw should be even. */
+ ihw = fsmin(vga_pixels + pre_pixels - iho, (int)(720.0f / hscale));
+ if (hsc < 0)
+ ihw = (int)fsmin(ihw, 253L * 128 / (-hsc));
+ ihw &= ~1;
+ TRACE(("ihw = %u\n", ihw))
+ houston_WriteReg(HOUSTON_IHA, ihw, 2);
+
+ f = (((float)g_specs.h_total * g_specs.v_total) * 27.f) /
+ ((float)g_specs.tv_width * g_specs.tv_lines);
+
+ TRACE(("freq=%u.%uMHz\n", (int)f, (int)((f - (int)f) * 1000)))
+}
+
+/*==========================================================================*/
+/* configure houston nco. */
+/*==========================================================================*/
+
+static void
+config_nco(unsigned long tv_std, unsigned long vga_mode)
+{
+ unsigned long cr, misc;
+ unsigned long reg;
+ int k = map_tvstd_to_index(tv_std);
+
+ /*read and store CR. */
+ houston_ReadReg(HOUSTON_CR, &cr, 2);
+
+ /*make sure NCO_EN (enable latch) bit is clear */
+ cr &= ~CR_NCO_EN;
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+
+ /*clear NCO_LOADX. */
+ houston_ReadReg(HOUSTON_MISC, &misc, 2);
+ misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0);
+ houston_WriteReg(HOUSTON_MISC, misc, 2);
+
+ if (vga_mode == GFX_VGA_MODE_1024X768) {
+ /*setup for M and N load (Nco_load=1). */
+ misc |= (MISC_NCO_LOAD0);
+ houston_WriteReg(HOUSTON_MISC, misc, 2);
+
+ /*M and N. */
+ houston_WriteReg(HOUSTON_NCONL, 1024 - 2, 2);
+ houston_WriteReg(HOUSTON_NCODL, 128 - 1, 2);
+
+ /*latch M/N in. */
+ cr |= CR_NCO_EN;
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+ cr &= ~CR_NCO_EN;
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+
+ /*setup ncon and ncod load (Nco_load=0). */
+ misc &= ~(MISC_NCO_LOAD1 + MISC_NCO_LOAD0);
+ houston_WriteReg(HOUSTON_MISC, misc, 2);
+
+ /*NCON. */
+ reg = ((unsigned long)g_specs.v_total * g_specs.h_total) / 2;
+ houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2);
+ houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2);
+
+ /*NCOD. */
+ houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
+ houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
+ } else {
+ /*setup for M and N load (Nco_load=2). */
+ misc |= (MISC_NCO_LOAD1);
+ houston_WriteReg(HOUSTON_MISC, misc, 2);
+
+ /*NCON. */
+ reg = (unsigned long)g_specs.v_total * g_specs.h_total;
+ houston_WriteReg(HOUSTON_NCONH, reg >> 16, 2);
+ houston_WriteReg(HOUSTON_NCONL, reg & 0xffff, 2);
+
+ /*NCOD. */
+ houston_WriteReg(HOUSTON_NCODL, tvsetup.houston_ncodl[k], 2);
+ houston_WriteReg(HOUSTON_NCODH, tvsetup.houston_ncodh[k], 2);
+
+ TRACE(("NCON = %lu (0x%08lx), NCOD = %lu (0x%08lx)\n",
+ reg,
+ reg,
+ ((unsigned long)tvsetup.houston_ncodh[k] << 16) +
+ tvsetup.houston_ncodl[k],
+ ((unsigned long)tvsetup.houston_ncodh[k] << 16) +
+ tvsetup.houston_ncodl[k]))
+ }
+
+ /*latch M/N and NCON/NCOD in. */
+ cr |= CR_NCO_EN;
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+ cr &= ~CR_NCO_EN;
+ houston_WriteReg(HOUSTON_CR, cr, 2);
+}
+
+/*==========================================================================*/
+/* Write sharpness settings to device */
+/*==========================================================================*/
+
+static void
+config_sharpness(int sharpness)
+{
+ unsigned int shp;
+
+ /*map 0-1000 to 0-20. */
+ shp = (unsigned int)(0.5f + ((float)sharpness * 20.0f / 1000.0f));
+ shp = range_limit(shp, 0, 20);
+
+ houston_WriteReg(HOUSTON_SHP, shp, 2);
+}
+
+static void
+conget_sharpness(int *p_sharpness)
+{
+ unsigned long shp;
+
+ if (!p_sharpness)
+ return;
+
+ houston_ReadReg(HOUSTON_SHP, &shp, 2);
+
+ /*map 0-20 to 0-1000. */
+ *p_sharpness = (int)(0.5f + ((float)shp * 1000.0f / 20.0f));
+}
+
+/*==========================================================================*/
+/* Write flicker settings to device */
+/*==========================================================================*/
+
+static void
+config_flicker(int flicker)
+{
+ unsigned int flk;
+
+ /*map 0-1000 to 0-16. */
+ flk = (unsigned int)(0.5f + ((float)flicker * 16.0f / 1000.0f));
+ flk = range_limit(flk, 0, 16);
+
+ houston_WriteReg(HOUSTON_FLK, flk, 2);
+}
+
+static void
+conget_flicker(int *p_flicker)
+{
+ unsigned long flk;
+
+ if (!p_flicker)
+ return;
+
+ houston_ReadReg(HOUSTON_FLK, &flk, 2);
+
+ /*map 0-16 to 0-1000. */
+ *p_flicker = (int)(0.5f + ((float)flk * 1000.0f / 16.0f));
+}
+
+/*==========================================================================*/
+/* Write color settings to device */
+/*==========================================================================*/
+
+static void
+config_color(int color)
+{
+ unsigned long clr;
+
+ /*map 0-100 to 0-255. */
+ /*montreal production test needs 169 to be mappable, so */
+ /*use .8 rounding factor, 169=(int)(66.*2.55+.8). */
+ clr = (unsigned long)(0.8f + ((float)color * 255.0f / 100.0f));
+ clr = range_limit(clr, 0, 255);
+
+ houston_WriteReg(ENC_CR_GAIN, clr, 1);
+ houston_WriteReg(ENC_CB_GAIN, clr, 1);
+}
+
+static void
+conget_color(int *p_color)
+{
+ unsigned long cr_gain;
+
+ if (!p_color)
+ return;
+
+ /*just get CR GAIN, CB GAIN should match. */
+ houston_ReadReg(ENC_CR_GAIN, &cr_gain, 1);
+
+ /*map 0-255 to 0-100. */
+ *p_color = (int)(0.5f + ((float)cr_gain * 100.0f / 255.0f));
+}
+
+/*==========================================================================*/
+/* Write brightness and contrast settings to device */
+/*==========================================================================*/
+
+#define NTSC_BLANK_LEVEL 240
+
+static const int min_black_level = NTSC_BLANK_LEVEL + 1;
+static const int max_white_level = 1023;
+
+static void
+config_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
+ int brightness, int contrast)
+{
+ int brightness_off;
+ float contrast_mult;
+ int black, white;
+ unsigned short w;
+ int k = map_tvstd_to_index(tv_std);
+
+ /*0-100 maps to +/-220. */
+ brightness_off =
+ (int)(0.5f + ((float)brightness * 440.0f / 100.0f)) - 220;
+
+ /*0-100 maps to .75-1.25. */
+ contrast_mult = ((float)contrast * 0.5f / 100.0f) + 0.75f;
+
+ black = tvsetup.black_level[k];
+ if (trigger_bits != 0)
+ black -= tvsetup.hamp_offset[k];
+
+ white = tvsetup.white_level[k];
+ if (trigger_bits != 0)
+ white -= tvsetup.hamp_offset[k];
+
+ black = (int)((float)(black + brightness_off) * contrast_mult);
+ white = (int)((float)(white + brightness_off) * contrast_mult);
+ if (black < min_black_level)
+ black = min_black_level;
+ if (white > max_white_level)
+ white = max_white_level;
+
+ w = w10bit2z((unsigned short)black);
+ houston_WriteReg(ENC_BLACK_LEVEL, w & 0x00ff, 1);
+ houston_WriteReg(ENC_BLACK_LEVEL + 1, w >> 8, 1);
+ w = w10bit2z((unsigned short)white);
+ houston_WriteReg(ENC_WHITE_LEVEL, w & 0x00ff, 1);
+ houston_WriteReg(ENC_WHITE_LEVEL + 1, w >> 8, 1);
+}
+
+static void
+conget_brightness_contrast(unsigned long tv_std, unsigned int trigger_bits,
+ int *p_brightness, int *p_contrast)
+{
+ int brightness_off;
+ float contrast_mult;
+ unsigned short black, white;
+ unsigned long zh, zl;
+ int k;
+
+ if (!p_brightness || !p_contrast)
+ return;
+
+ k = map_tvstd_to_index(tv_std);
+
+ houston_ReadReg(ENC_BLACK_LEVEL, &zl, 1);
+ houston_ReadReg(ENC_BLACK_LEVEL + 1, &zh, 1);
+ black = z2w10bit((unsigned short)(zl + (zh << 8)));
+ if (trigger_bits != 0)
+ black += tvsetup.hamp_offset[k];
+ houston_ReadReg(ENC_WHITE_LEVEL, &zl, 1);
+ houston_ReadReg(ENC_WHITE_LEVEL + 1, &zh, 1);
+ white = z2w10bit((unsigned short)(zl + (zh << 8)));
+ if (trigger_bits != 0)
+ white += tvsetup.hamp_offset[k];
+
+ /*this reverse computation does not account for clipping, but should */
+ /*provide somewhat reasonable numbers */
+ contrast_mult =
+ ((float)white - (float)black) / ((float)tvsetup.white_level[k] -
+ (float)tvsetup.black_level[k]);
+ brightness_off =
+ (int)(((float)black / contrast_mult) - tvsetup.black_level[k]);
+
+ /*+/-220 maps to 0-100. */
+ *p_brightness =
+ range_limit((int)(0.5f + ((float)(brightness_off +
+ 220) * 100.0f / 440.0f)), 0, 100);
+
+ /*.75-1.25 maps to 0-100. */
+ *p_contrast =
+ range_limit((int)(0.5f + ((float)(contrast_mult -
+ 0.75f) * 100.0f / 0.5f)), 0, 100);
+}
+
+/*==========================================================================*/
+/* configure luma/chroma filters. */
+/*==========================================================================*/
+
+static void
+config_yc_filter(unsigned long tv_std, int luma_filter, int chroma_filter)
+{
+ unsigned long reg, reg07, reg34;
+
+ if (houston_Rev() < HOUSTON_REV_B)
+ return;
+
+ /*luma filter. */
+ if (luma_filter)
+ reg = tvsetup.notch_filter[map_tvstd_to_index(tv_std)];
+ else
+ reg = 0;
+ houston_WriteReg(ENC_NOTCH_FILTER, reg, 1);
+
+ /*chroma filter. */
+ houston_ReadReg(ENC_REG07, &reg07, 1);
+ houston_ReadReg(ENC_REG34, &reg34, 1);
+ if (chroma_filter) {
+ reg07 &= ~0x08;
+ reg34 &= ~0x20;
+ } else {
+ reg07 |= 0x08;
+ reg34 |= 0x20;
+ }
+ houston_WriteReg(ENC_REG07, reg07, 1);
+ houston_WriteReg(ENC_REG34, reg34, 1);
+}
+
+static void
+conget_yc_filter(int *p_luma_filter, int *p_chroma_filter)
+{
+ unsigned long reg, reg07, reg34;
+
+ if (!p_luma_filter || !p_chroma_filter)
+ return;
+
+ if (houston_Rev() < HOUSTON_REV_B) {
+ *p_luma_filter = 0;
+ *p_chroma_filter = 0;
+ return;
+ }
+
+ /*luma filter. */
+ houston_ReadReg(ENC_NOTCH_FILTER, &reg, 1);
+ *p_luma_filter = (reg ? 1 : 0);
+
+ /*chroma filter. */
+ houston_ReadReg(ENC_REG07, &reg07, 1);
+ houston_ReadReg(ENC_REG34, &reg34, 1);
+ *p_chroma_filter = !((0x08 & reg07) || (0x20 & reg34));
+}
+
+/*==========================================================================*/
+/* Macrovision */
+/*==========================================================================*/
+
+static void
+config_macrovision(unsigned long tv_std, unsigned int trigger_bits)
+{
+/*Constants to index into mvsetup columns.*/
+#define nNTSC_APS00 0 /*ntsc mv off. */
+#define nNTSC_APS01 1 /*ntsc AGC only. */
+#define nNTSC_APS10 2 /*ntsc AGC + 2-line CS. */
+#define nNTSC_APS11 3 /*ntsc AGC + 4-line CS. */
+#define nPAL_APS00 4 /*pal mv off. */
+#define nPAL_APSXX 5 /*pal mv on. */
+#define nMVModes 6
+
+ /*Macrovision setup table. */
+ static const struct mvparms
+ {
+ unsigned short n0[nMVModes];
+ unsigned short n1[nMVModes];
+ unsigned short n2[nMVModes];
+ unsigned short n3[nMVModes];
+ unsigned short n4[nMVModes];
+ unsigned short n5[nMVModes];
+ unsigned short n6[nMVModes];
+ unsigned short n7[nMVModes];
+ unsigned short n8[nMVModes];
+ unsigned short n9[nMVModes];
+ unsigned short n10[nMVModes];
+ unsigned short n11[nMVModes];
+ unsigned short n12[nMVModes];
+ unsigned short n13[nMVModes];
+ unsigned short n14[nMVModes];
+ unsigned short n15[nMVModes];
+ unsigned short n16[nMVModes];
+ unsigned short n17[nMVModes];
+ unsigned short n18[nMVModes];
+ unsigned short n19[nMVModes];
+ unsigned short n20[nMVModes];
+ unsigned short n21[nMVModes];
+ unsigned short n22[nMVModes];
+ unsigned short agc_pulse_level[nMVModes];
+ unsigned short bp_pulse_level[nMVModes];
+ }
+
+ mvsetup = {
+ /* ntsc ntsc ntsc ntsc pal pal */
+ /* MV AGC AGC + AGC + MV MV */
+ /* off. only 2-line 4-line off. on. */
+ /* CS. CS. */
+ {
+ 0x00, 0x36, 0x3e, 0x3e, 0x00, 0x3e}, /*n0 */
+ {
+ 0x1d, 0x1d, 0x1d, 0x17, 0x1a, 0x1a}, /*n1 */
+ {
+ 0x11, 0x11, 0x11, 0x15, 0x22, 0x22}, /*n2 */
+ {
+ 0x25, 0x25, 0x25, 0x21, 0x2a, 0x2a}, /*n3 */
+ {
+ 0x11, 0x11, 0x11, 0x15, 0x22, 0x22}, /*n4 */
+ {
+ 0x01, 0x01, 0x01, 0x05, 0x05, 0x05}, /*n5 */
+ {
+ 0x07, 0x07, 0x07, 0x05, 0x02, 0x02}, /*n6 */
+ {
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}, /*n7 */
+ {
+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c}, /*n8 */
+ {
+ 0x1b, 0x1b, 0x1b, 0x1b, 0x3d, 0x3d}, /*n9 */
+ {
+ 0x24, 0x24, 0x24, 0x24, 0x14, 0x14}, /*n10 */
+ {
+ 0x780f, 0x780f, 0x780f, 0x780f, 0x7e07, 0x7e07}, /*n11 */
+ {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5402, 0x5402}, /*n12 */
+ {
+ 0x0f, 0x0f, 0x0f, 0x0f, 0xfe, 0xfe}, /*n13 */
+ {
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x7e, 0x7e}, /*n14 */
+ {
+ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60}, /*n15 */
+ {
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /*n16 */
+ {
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08, 0x08}, /*n17 */
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*n18 */
+ {
+ 0x05, 0x05, 0x05, 0x05, 0x04, 0x04}, /*n19 */
+ {
+ 0x04, 0x04, 0x04, 0x04, 0x07, 0x07}, /*n20 */
+ {
+ 0x03ff, 0x03ff, 0x03ff, 0x03ff, 0x0155, 0x0155}, /*n21 */
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*n22 */
+ {
+ 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3}, /*agc_pulse_level */
+ {
+ 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8}, /*bp_pulse_level */
+ };
+
+ int nMode;
+ unsigned long misc;
+ unsigned short n0;
+
+ trigger_bits &= 0x3;
+
+ /*Determine the OEM Macrovision Program Mode and Register 0 Data. */
+ if (IS_NTSC(tv_std)) {
+ /*NTSC TV Standard. */
+ if (trigger_bits == 0) {
+ /*turn Macrovision OFF. */
+ nMode = nNTSC_APS00;
+ } else if (trigger_bits == 1) {
+ /*AGC Only. */
+ nMode = nNTSC_APS01;
+ } else if (trigger_bits == 2) {
+ /*AGC + 2-line CS. */
+ nMode = nNTSC_APS10;
+ } else {
+ /*AGC + 4-line CS. */
+ nMode = nNTSC_APS11;
+ }
+ } else {
+ /*PAL TV Standard. */
+ if (trigger_bits == 0) {
+ /*turn Macrovision OFF. */
+ nMode = nPAL_APS00;
+ } else {
+ /*APS 01, 10, or 11. */
+ nMode = nPAL_APSXX;
+ }
+ }
+
+ /*Retrieve the Macrovision Program Mode Data */
+ if (tv_std != GFX_TV_STANDARD_PAL_M)
+ n0 = mvsetup.n0[nMode];
+ else {
+ /*PAL-M sets up like NTSC except for n0. */
+ if ((trigger_bits & 0x03) == 0)
+ n0 = mvsetup.n0[nPAL_APS00];
+ else
+ n0 = mvsetup.n0[nPAL_APSXX];
+ }
+
+ /*download settings now. */
+ houston_WriteReg(MV_N0, n0, 1);
+ houston_WriteReg(MV_N1, mvsetup.n1[nMode], 1);
+ houston_WriteReg(MV_N2, mvsetup.n2[nMode], 1);
+ houston_WriteReg(MV_N3, mvsetup.n3[nMode], 1);
+ houston_WriteReg(MV_N4, mvsetup.n4[nMode], 1);
+ houston_WriteReg(MV_N5, mvsetup.n5[nMode], 1);
+ houston_WriteReg(MV_N6, mvsetup.n6[nMode], 1);
+ houston_WriteReg(MV_N7, mvsetup.n7[nMode], 1);
+ houston_WriteReg(MV_N8, mvsetup.n8[nMode], 1);
+ houston_WriteReg(MV_N9, mvsetup.n9[nMode], 1);
+ houston_WriteReg(MV_N10, mvsetup.n10[nMode], 1);
+ houston_WriteReg(MV_N11, mvsetup.n11[nMode] & 0xff, 1);
+ houston_WriteReg(MV_N11 + 1, mvsetup.n11[nMode] >> 8, 1);
+ houston_WriteReg(MV_N12, mvsetup.n12[nMode] & 0xff, 1);
+ houston_WriteReg(MV_N12 + 1, mvsetup.n12[nMode] >> 8, 1);
+ houston_WriteReg(MV_N13, mvsetup.n13[nMode], 1);
+ houston_WriteReg(MV_N14, mvsetup.n14[nMode], 1);
+ houston_WriteReg(MV_N15, mvsetup.n15[nMode], 1);
+ houston_WriteReg(MV_N16, mvsetup.n16[nMode], 1);
+ houston_WriteReg(MV_N17, mvsetup.n17[nMode], 1);
+ houston_WriteReg(MV_N18, mvsetup.n18[nMode], 1);
+ houston_WriteReg(MV_N19, mvsetup.n19[nMode], 1);
+ houston_WriteReg(MV_N20, mvsetup.n20[nMode], 1);
+ houston_WriteReg(MV_N21, mvsetup.n21[nMode] & 0xff, 1);
+ houston_WriteReg(MV_N21 + 1, mvsetup.n21[nMode] >> 8, 1);
+ houston_WriteReg(MV_N22, mvsetup.n22[nMode], 1);
+ houston_WriteReg(MV_AGC_PULSE_LEVEL, mvsetup.agc_pulse_level[nMode], 1);
+ houston_WriteReg(MV_BP_PULSE_LEVEL, mvsetup.bp_pulse_level[nMode], 1);
+
+ houston_ReadReg(HOUSTON_MISC, &misc, 2);
+ if (trigger_bits == 0)
+ misc &= ~MISC_MV_SOFT_EN;
+ else
+ misc |= MISC_MV_SOFT_EN;
+ houston_WriteReg(HOUSTON_MISC, misc, 2);
+}
+
+static void
+conget_macrovision(unsigned long tv_std, unsigned int *p_cp_trigger_bits)
+{
+ unsigned long n0, n1;
+
+ if (!p_cp_trigger_bits)
+ return;
+
+ houston_ReadReg(MV_N0, &n0, 1);
+ houston_ReadReg(MV_N1, &n1, 1);
+
+ *p_cp_trigger_bits = 0;
+
+ if (IS_NTSC(tv_std)) {
+ switch (n0) {
+ case 0:
+ *p_cp_trigger_bits = 0;
+ break;
+
+ case 0x36:
+ *p_cp_trigger_bits = 1;
+ break;
+
+ case 0x3E:
+ {
+ if (0x1D == n1)
+ *p_cp_trigger_bits = 2;
+ else
+ *p_cp_trigger_bits = 3;
+ }
+ break;
+ }
+ } else if (IS_PAL(tv_std)) {
+ if (0 == n0)
+ *p_cp_trigger_bits = 0;
+ else {
+ /*don't know here what the non-zero trigger bits were */
+ *p_cp_trigger_bits = 1;
+ }
+ }
+}
+
+/* PLAL_MediaGX.cpp */
+/*==========================================================================*/
+/* These functions provides implementation of platform-specific functions */
+/* MediaGX platform. */
+/*==========================================================================*/
+
+/*MediaGX control registers.*/
+#define CCR3 0xC3
+#define GCR 0xb8
+
+/*Media GX general config register.*/
+#define GX_DCLK_MUL 0x00c0
+#define GX_DCLKx1 0x0040
+#define GX_DCLKx2 0x0080
+#define GX_DCLKx4 0x00c0
+
+/*Media GX timing config register.*/
+#define GX_TGEN 0x0020
+
+/*Cx5530 register offsets (from GX_BASE).*/
+#define CX_DISPLAY_CONFIG 0x10004
+#define CX_DOT_CLK 0x10024
+#define CX_TV_CONFIG 0x10028
+
+/*Cx5530 display configuration register.*/
+#define CX_FPVSYNC_POL 0x0800
+#define CX_FPHSYNC_POL 0x0400
+#define CX_FPDATA_ENB 0x0080
+#define CX_FPPOWER_ENB 0x0040
+#define CX_CRTVSYNC_POL 0x0200
+#define CX_CRTHSYNC_POL 0x0100
+
+/*Cx5530 dot clock configuration register.*/
+#define CX_TVCLK_SELECT 0x0400
+
+/*Cx5530 tv configuration register*/
+#define CX_INVERT_FPCLK (1 << 6)
+
+/*==========================================================================
+ * FS450 I2C Address
+ * There are two possible 7-bit addresses, 0x4A and 0x6A.
+ * The address if selectable via pins on the FS450.
+ * There are also two possible 10-bit addresses, 0x224 and 0x276, but this
+ * source is not designed to use them.
+ *==========================================================================*/
+
+#define FS450_I2C_ADDRESS (0x4A)
+
+static unsigned char
+PLAL_FS450_i2c_address(void)
+{
+ return FS450_I2C_ADDRESS;
+}
+
+/*==========================================================================
+ * FS450 UIM mode
+ * This mode is programmed in the FS450 command register when enabling TV
+ * out.
+ *==========================================================================
+ */
+static int
+PLAL_FS450_UIM_mode(void)
+{
+ return 3;
+}
+
+/*==========================================================================*/
+/* Read and Write MediaGX registers */
+/*==========================================================================*/
+static unsigned long
+ReadGx(unsigned long inRegAddr)
+{
+ unsigned long data;
+
+ DMAL_ReadUInt32(inRegAddr, &data);
+
+ return data;
+}
+
+static void
+WriteGx(unsigned long inRegAddr, unsigned long inData)
+{
+ int is_timing_register;
+ unsigned long reg_timing_cfg;
+
+ /*because the unlock register for the MediaGx video registers may not */
+ /*persist, we will write the unlock code before every write. */
+ DMAL_WriteUInt32(DC_UNLOCK, 0x4758);
+
+ /*see if register is a timing register */
+ is_timing_register =
+ (DC_H_TIMING_1 == inRegAddr) ||
+ (DC_H_TIMING_2 == inRegAddr) ||
+ (DC_H_TIMING_3 == inRegAddr) ||
+ (DC_FP_H_TIMING == inRegAddr) ||
+ (DC_V_TIMING_1 == inRegAddr) ||
+ (DC_V_TIMING_2 == inRegAddr) ||
+ (DC_V_TIMING_3 == inRegAddr) || (DC_FP_V_TIMING == inRegAddr);
+
+ /*if the register is a timing register, clear the TGEN bit to allow
+ * modification */
+ if (is_timing_register) {
+ DMAL_ReadUInt32(DC_TIMING_CFG, &reg_timing_cfg);
+ DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg & ~GX_TGEN);
+ }
+
+ /*write the requested register */
+ DMAL_WriteUInt32(inRegAddr, inData);
+
+ /*reset the TGEN bit to previous state */
+ if (is_timing_register) {
+ DMAL_WriteUInt32(DC_TIMING_CFG, reg_timing_cfg);
+ }
+}
+
+#ifdef FS450_DIRECTREG
+
+/*==========================================================================*/
+/* Platform-specific processing for a Read or Write Register calls. */
+/* The functions should return true if the specified register belongs to */
+/* this platform. */
+/*==========================================================================*/
+
+static int
+PLAL_ReadRegister(S_REG_INFO * p_reg)
+{
+ if (!p_reg)
+ return 0;
+
+ if (SOURCE_GCC == p_reg->source) {
+ p_reg->value = ReadGx(p_reg->offset);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+PLAL_WriteRegister(const S_REG_INFO * p_reg)
+{
+ if (!p_reg)
+ return 0;
+
+ if (SOURCE_GCC == p_reg->source) {
+ WriteGx(p_reg->offset, p_reg->value);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+#endif
+
+/*==========================================================================
+ * Determine if TV is on
+ *==========================================================================*/
+static int
+PLAL_IsTVOn(void)
+{
+ unsigned long reg;
+
+ /*check Cx5530 dot clock */
+ reg = ReadGx(CX_DOT_CLK);
+ return (reg & CX_TVCLK_SELECT) ? 1 : 0;
+}
+
+/*==========================================================================
+ * Platform-specific actions to reset to VGA mode
+ *==========================================================================*/
+
+static int
+PLAL_EnableVga(void)
+{
+ unsigned long reg;
+
+ /*2 x dclk */
+ reg = ReadGx(DC_GENERAL_CFG);
+ reg &= ~GX_DCLK_MUL;
+ reg |= GX_DCLKx2;
+ WriteGx(DC_GENERAL_CFG, reg);
+
+ /*select pll dot clock. */
+ reg = ReadGx(CX_DOT_CLK);
+ reg &= ~CX_TVCLK_SELECT;
+ WriteGx(CX_DOT_CLK, reg);
+
+ /*timing config, reset everything on dclk. */
+ reg = ReadGx(DC_TIMING_CFG);
+ reg &= ~GX_TGEN;
+ WriteGx(DC_TIMING_CFG, reg);
+ reg |= GX_TGEN;
+ WriteGx(DC_TIMING_CFG, reg);
+
+ /*un-invert FP clock */
+ reg = ReadGx(CX_TV_CONFIG);
+ reg &= ~CX_INVERT_FPCLK;
+ WriteGx(CX_TV_CONFIG, reg);
+
+ return 0;
+}
+
+/*==========================================================================*/
+/*Platform-specific actions to enter TVout mode */
+/*==========================================================================*/
+
+static int
+PLAL_PrepForTVout(void)
+{
+ unsigned int reg;
+
+ /*Cx5530 tv config. */
+ reg = 0;
+ WriteGx(CX_TV_CONFIG, reg);
+
+ /*invert FP clock */
+ reg = (int)ReadGx(CX_TV_CONFIG);
+ reg |= CX_INVERT_FPCLK;
+ WriteGx(CX_TV_CONFIG, reg);
+
+ return 0;
+}
+
+static int
+PLAL_SetTVTimingRegisters(const S_TIMING_SPECS * p_specs)
+{
+ unsigned long reg;
+
+ /*timing config, reset everything on dclk. */
+ reg = ReadGx(DC_TIMING_CFG);
+ reg &= ~GX_TGEN;
+ WriteGx(DC_TIMING_CFG, reg);
+
+ /*htotal and hactive. */
+ reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
+ WriteGx(DC_H_TIMING_1, reg);
+
+ /*hblank. */
+ reg = ((p_specs->h_total - 1) << 16) | (p_specs->vga_width - 1);
+ WriteGx(DC_H_TIMING_2, reg);
+
+ /*hsync. */
+ reg = ((p_specs->h_sync + 63) << 16) | p_specs->h_sync;
+ WriteGx(DC_H_TIMING_3, reg);
+
+ /*fp hsync. */
+ WriteGx(DC_FP_H_TIMING, reg);
+
+ /*vtotal and vactive. */
+ reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
+ WriteGx(DC_V_TIMING_1, reg);
+
+ /*vblank. */
+ reg = ((p_specs->v_total - 1) << 16) | (p_specs->vga_lines - 1);
+ WriteGx(DC_V_TIMING_2, reg);
+
+ /*vsync. */
+ reg = ((p_specs->v_sync) << 16) | (p_specs->v_sync - 1);
+ WriteGx(DC_V_TIMING_3, reg);
+
+ /*fp vsync. */
+ reg = ((p_specs->v_sync - 1) << 16) | (p_specs->v_sync - 2);
+ WriteGx(DC_FP_V_TIMING, reg);
+
+ /*timing config, reenable all dclk stuff. */
+ reg = ReadGx(DC_TIMING_CFG);
+ reg |= GX_TGEN;
+ WriteGx(DC_TIMING_CFG, reg);
+
+ return 0;
+}
+
+static int
+PLAL_FinalEnableTVout(unsigned long vga_mode)
+{
+ unsigned int reg;
+
+ /*Cx5530 select tv dot clock. */
+ reg = (int)ReadGx(CX_DOT_CLK);
+ reg |= CX_TVCLK_SELECT;
+ WriteGx(CX_DOT_CLK, reg);
+
+ /*2 x dclk (actually 1x) */
+ reg = (int)ReadGx(DC_GENERAL_CFG);
+ reg &= ~GX_DCLK_MUL;
+ WriteGx(DC_GENERAL_CFG, reg);
+
+ reg |= GX_DCLKx2;
+ WriteGx(DC_GENERAL_CFG, reg);
+
+ /*Cx5530 display configuration register. */
+ reg = (int)ReadGx(CX_DISPLAY_CONFIG);
+ reg |= (CX_FPVSYNC_POL | CX_FPHSYNC_POL | CX_FPDATA_ENB | CX_FPPOWER_ENB);
+ WriteGx(CX_DISPLAY_CONFIG, reg);
+
+ return 0;
+}
diff --git a/src/gfx/tv_fs450.h b/src/gfx/tv_fs450.h
new file mode 100644
index 0000000..7e917c0
--- /dev/null
+++ b/src/gfx/tv_fs450.h
@@ -0,0 +1,206 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file defines the common FS450 API.
+ * */
+
+#ifndef __FS450_H__
+#define __FS450_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*==========================================================================*/
+/* Init and cleanup functions*/
+
+ int FS450_init(void);
+ void FS450_cleanup(void);
+ /* call FS450_init at startup to probe for and initialize FS450. */
+ /* returns 0 if successful. */
+
+/*==========================================================================*/
+/* TV output on or off*/
+
+ int FS450_get_tv_enable(unsigned int *p_on);
+ int FS450_set_tv_enable(unsigned int on);
+ /* on is 1 for TV on, 0 for off */
+
+/*==========================================================================*/
+/* TV standard*/
+
+ int FS450_get_tv_standard(unsigned long *p_standard);
+ int FS450_get_available_tv_standards(unsigned long *p_standards);
+ int FS450_set_tv_standard(unsigned long standard);
+ /* standard is one of the FS450_TV_STANDARD constants */
+ /* standards is a bitmask of zero or more FS450_TV_STANDARD constants */
+
+/* FS450 TV Standard flags*/
+#define FS450_TV_STANDARD_NTSC_M 0x0001
+#define FS450_TV_STANDARD_NTSC_M_J 0x0002
+#define FS450_TV_STANDARD_PAL_B 0x0004
+#define FS450_TV_STANDARD_PAL_D 0x0008
+#define FS450_TV_STANDARD_PAL_H 0x0010
+#define FS450_TV_STANDARD_PAL_I 0x0020
+#define FS450_TV_STANDARD_PAL_M 0x0040
+#define FS450_TV_STANDARD_PAL_N 0x0080
+#define FS450_TV_STANDARD_PAL_G 0x0100
+
+/*==========================================================================*/
+/* VGA mode assumed by FS450*/
+
+ int FS450_get_vga_mode(unsigned long *p_vga_mode);
+ int FS450_get_available_vga_modes(unsigned long *p_vga_modes);
+ int FS450_set_vga_mode(unsigned long vga_mode);
+ /* vga_mode is one of the FS450_VGA_MODE constants */
+ /* vga_modes is a bitmask of zero or more FS450_VGA_MODE constants */
+
+/* FS450 VGA Mode flags*/
+#define FS450_VGA_MODE_UNKNOWN 0
+#define FS450_VGA_MODE_640X480 0x0001
+#define FS450_VGA_MODE_720X487 0x0002
+#define FS450_VGA_MODE_720X576 0x0004
+#define FS450_VGA_MODE_800X600 0x0008
+#define FS450_VGA_MODE_1024X768 0x0010
+
+/*==========================================================================*/
+/* TVout mode*/
+
+ int FS450_get_tvout_mode(unsigned long *p_tvout_mode);
+ int FS450_set_tvout_mode(unsigned long tvout_mode);
+ /* tvout_mode is a bitmask of FS450_TVOUT_MODE constants */
+
+/* FS450 TVout mode flags*/
+#define FS450_TVOUT_MODE_CVBS 0x0001
+#define FS450_TVOUT_MODE_YC 0x0002
+#define FS450_TVOUT_MODE_RGB 0x0004
+#define FS450_TVOUT_MODE_CVBS_YC (FS450_TVOUT_MODE_CVBS | FS450_TVOUT_MODE_YC)
+
+/*==========================================================================*/
+/* Flicker control*/
+
+ int FS450_get_sharpness(int *p_sharpness);
+ int FS450_set_sharpness(int sharpness);
+ /* sharpness is a percentage in tenths of a percent, 0 to 1000 */
+
+ int FS450_get_flicker_filter(int *p_flicker);
+ int FS450_set_flicker_filter(int flicker);
+ /* flicker_filter is a percentage in tenths of a percent, 0 to 1000 */
+
+/*==========================================================================*/
+/* Size and Position*/
+
+ int FS450_get_overscan(int *p_x, int *p_y);
+ int FS450_set_overscan(int x, int y);
+ int FS450_get_position(int *p_x, int *p_y);
+ int FS450_set_position(int x, int y);
+ /* x and y are horizontal and vertical adjustments, -1000 to +1000 */
+
+/*==========================================================================*/
+/* Visual adjustments*/
+
+ int FS450_get_color(int *p_color);
+ int FS450_set_color(int color);
+ /* color is a percentage, 0 to 100 */
+
+ int FS450_get_brightness(int *p_brightness);
+ int FS450_set_brightness(int brightness);
+ /* brightness is a percentage, 0 to 100 */
+
+ int FS450_get_contrast(int *p_contrast);
+ int FS450_set_contrast(int constrast);
+ /* contrast is a percentage, 0 to 100 */
+
+/*==========================================================================*/
+/* Luma and Chroma filter*/
+
+ int FS450_get_yc_filter(unsigned int *p_yc_filter);
+ int FS450_set_yc_filter(unsigned int yc_filter);
+ /* yc_filter is a bitmask of FS450_LUMA_FILTER and/or FS450_CHROMA_FILTER */
+
+/* FS450 Luma and Chroma Filters*/
+#define FS450_LUMA_FILTER 0x0001
+#define FS450_CHROMA_FILTER 0x0002
+
+/*==========================================================================*/
+/* Macrovision*/
+
+ int FS450_get_aps_trigger_bits(unsigned int *p_trigger_bits);
+ int FS450_set_aps_trigger_bits(unsigned int trigger_bits);
+ /* trigger_bits is one of the FS450_APS_TRIGGER constants */
+
+/* APS Trigger Bits*/
+#define FS450_APS_TRIGGER_OFF 0
+#define FS450_APS_TRIGGER_AGC_ONLY 1
+#define FS450_APS_TRIGGER_AGC_2_LINE 2
+#define FS450_APS_TRIGGER_AGC_4_LINE 3
+
+/*==========================================================================*/
+/* direct access to Houston and platform registers (debug builds only)
+ * The two functions FS450_ReadRegister and FS450_WriteRegister allow access
+ * to device registers. These functions are intended for debugging purposes
+ * only and should not be included in a shipping product.
+ * */
+
+#ifdef FS450_DIRECTREG
+
+#define SOURCE_HOUSTON 0
+#define SOURCE_GCC 1
+
+ typedef struct _S_REG_INFO
+ {
+ int source;
+ unsigned int size;
+ unsigned long offset;
+ unsigned long value;
+ } S_REG_INFO;
+
+ int FS450_ReadRegister(S_REG_INFO * p_reg);
+ int FS450_WriteRegister(S_REG_INFO * p_reg);
+
+#endif
+
+/*==========================================================================*/
+/* Error Codes*/
+
+#define ERR_INVALID_PARAMETER 0x1000
+#define ERR_NOT_SUPPORTED 0x1001
+#define ERR_CANNOT_CHANGE_WHILE_TV_ON 0x1002
+
+#define ERR_DRIVER_NOT_FOUND 0x1100
+#define ERR_DRIVER_ERROR 0x1101
+#define ERR_DEVICE_NOT_FOUND 0x1120
+
+#define ERR_I2C_MISSING_DEVICE 0x1200
+#define ERR_I2C_WRITE_FAILED 0x1201
+#define ERR_I2C_READ_FAILED 0x1202
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gfx/vga_gu1.c b/src/gfx/vga_gu1.c
new file mode 100644
index 0000000..20cf232
--- /dev/null
+++ b/src/gfx/vga_gu1.c
@@ -0,0 +1,680 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to set modes using the VGA registers.
+ * Since this file is for the first generation graphics unit, it interfaces
+ * to SoftVGA registers. It works for both VSA1 and VSA2.
+ * */
+
+/* SoftVGA Extended CRTC register indices and bit definitions */
+
+#define CRTC_EXTENDED_REGISTER_LOCK 0x30
+#define CRTC_MODE_SWITCH_CONTROL 0x3F
+
+/* BIT DEFINITIONS */
+
+#define CRTC_BIT_16BPP 0x01
+#define CRTC_BIT_555 0x02
+
+/* LOCAL ROUTINE DEFINITIONS */
+
+int gu1_detect_vsa2(void);
+
+/*---------------------------------*/
+/* MODE TABLES FOR VGA REGISTERS */
+/*---------------------------------*/
+
+/* FOR SoftVGA, the CRTC_EXTENDED_ADDRESS_CONTROL (0x43) is always equal to
+ * 0x03 for a packed linear frame buffer organization. The
+ * CRTC_EXTENDED_DAC_CONTROL (0x4B) is always equal to 0x03 to work with
+ * older versions of VSA1 (that needed to specify 8 or 16 bit bus to an
+ * external RAMDAC. This is not used in VSA2. The clock frequency is
+ * specified in register 0x4D if clock control (0x4C) is set to 0x80.
+ * Higher resolutions (1280x1024) use the CRTC_EXTENDED_VERTICAL_TIMING
+ * register (index 0x41).
+ */
+
+gfx_vga_struct gfx_vga_modes[] = {
+/*--------------------------------------------------------------------------*/
+ {
+ 640, 480, 60, /* 640x480 */
+ 25, /* 25 MHz clock = 60 Hz refresh rate */
+ 0xE3, /* miscOutput register */
+ {
+ 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E,
+ /* standard CRTC */
+ 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF},
+ {
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 640, 480, 72, /* 640x480 */
+ 29, /* 29 MHz clock = 72 Hz refresh rate */
+ 0xE3, /* miscOutput register */
+ {
+ 0x63, 0x4f, 0x50, 0x86, 0x55, 0x99, 0x06, 0x3e,
+ /* standard CRTC */
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe9, 0x0c, 0xdf, 0x00, 0x00, 0xe7, 0x00, 0xe3, 0xff},
+ {
+ 0x6D, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x01, 0x08, 0x80, 0x1F, 0x00, 0x4B}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 640, 480, 75, /* 640x480 */
+ 31,
+ /* 31.5 MHz clock = 75 Hz refresh rate */
+ 0xE3, /* miscOutput register */
+ {
+ 0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F,
+ /* standard CRTC */
+ 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF},
+ {
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x80, 0x1F, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 800, 600, 60, /* 800x600 */
+ 40, /* 40 MHz clock = 60 Hz refresh rate */
+ 0x23, /* miscOutput register */
+ {
+ 0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0,
+ /* standard CRTC */
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF},
+ {
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x80, 0x28, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 800, 600, 72, /* 800x600 */
+ 47, /* 47 MHz clock = 72 Hz refresh rate */
+ 0x2B, /* miscOutput register */
+ {
+ 0x7D, 0x63, 0x63, 0x81, 0x6D, 0x1B, 0x98, 0xF0,
+ /* standard CRTC */
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7D, 0x03, 0x57, 0x00, 0x00, 0x57, 0x9A, 0xE3, 0xFF},
+ {
+ 0x6F, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x01, 0x08, 0x80, 0x32, 0x00, 0x4B}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 800, 600, 75, /* 800x600 */
+ 49,
+ /* 49.5 MHz clock = 75 Hz refresh rate */
+ 0x23, /* miscOutput register */
+ {
+ 0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0,
+ /* standard CRTC */
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF},
+ {
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x80, 0x31, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 1024, 768, 60, /* 1024x768 */
+ 65, /* 65 MHz clock = 60 Hz refresh rate */
+ 0xE3, /* miscOutput register */
+ {
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5,
+ /* standard CRTC */
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF},
+ {
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x80, 0x41, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 1024, 768, 70, /* 1024x768 */
+ 76, /* 76 MHz clock = 70 Hz refresh rate */
+ 0x2B, /* miscOutput register */
+ {
+ 0xA1, 0x7F, 0x7F, 0x85, 0x85, 0x95, 0x24, 0xF5,
+ /* standard CRTC */
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x00, 0x00, 0xFF, 0x26, 0xE3, 0xFF},
+ {
+ 0x62, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x01, 0x02, 0x80, 0x4B, 0x00, 0x4B}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 1024, 768, 75, /* 1024x768 */
+ 79, /* 79 MHz clock = 75 Hz refresh rate */
+ 0xE3, /* miscOutput register */
+ {
+ 0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5,
+ /* standard CRTC */
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF},
+ {
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x80, 0x4F, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 1280, 1024, 60, /* 1280x1024 */
+ 108,
+ /* 108 MHz clock = 60 Hz refresh rate */
+ 0x23, /* miscOutput register */
+ {
+ 0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52,
+ /* standard CRTC */
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF},
+ {
+ 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x80, 0x6C, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 1280, 1024, 75, /* 1280x1024 */
+ 135,
+ /* 135 MHz clock = 75 Hz refresh rate */
+ 0x23, /* miscOutput register */
+ {
+ 0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52,
+ /* standard CRTC */
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF},
+ {
+ 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x00, 0x03, 0x80, 0x87, 0x00, 0x00}
+ },
+/*--------------------------------------------------------------------------*/
+ {
+ 1280, 1024, 85, /* 1280x1024 */
+ 159,
+ /* 159 MHz clock = 85 Hz refresh rate */
+ 0x2B, /* miscOutput register */
+ {
+ 0xD3, 0x9F, 0xA0, 0x98, 0xA8, 0x9C, 0x2E, 0x5A,
+ /* standard CRTC */
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x04, 0xFF, 0x00, 0x00, 0xFF, 0x30, 0xE3, 0xFF},
+ {
+ 0x6B, 0x41, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00,
+ /* extended CRTC */
+ 0x00, 0x00, 0x01, 0x00, 0x80, 0x9D, 0x00, 0x4B}
+ },
+/*--------------------------------------------------------------------------*/
+};
+
+#define GFX_VGA_MODES sizeof(gfx_vga_modes)/sizeof(gfx_vga_struct)
+
+/*----------------------------------------------------------------------------
+ * gfx_get_softvga_active
+ *
+ * This returns the active status of SoftVGA
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_get_softvga_active(void)
+{
+ unsigned short crtcindex, crtcdata;
+
+ if (gu1_detect_vsa2())
+ return (gfx_get_vsa2_softvga_enable());
+
+ crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
+ crtcdata = crtcindex + 1;
+
+ OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL);
+ return (INB(crtcdata) & 0x1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_test_pci
+ *
+ * This routine looks for the VGA PCI header. It checks to see that bit 1
+ * of the command register is writable to know that SoftVGA is trapping
+ * the PCI config cuscles. If SoftVGA is not emulating the header, the
+ * hardware will still respond with the proper device ID, etc.
+ *
+ * We need to know that SoftVGA is really there so that we can set the
+ * command register and have the proper effect (enable trapping of VGA).
+ * Otherwise, if we enable VGA via the PCI header, trapping really won't be
+ * enabled and the VGA register writes will go out to the external card.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_test_pci(void)
+{
+ int softvga = 1;
+ unsigned long value;
+
+ value = gfx_pci_config_read(0x80009400);
+ if ((value & 0x0000FFFF) != 0x1078)
+ softvga = 0;
+ else {
+ value = gfx_pci_config_read(0x80009404);
+ gfx_pci_config_write(0x80009404, value | 0x02);
+ if (!(gfx_pci_config_read(0x80009404) & 0x02))
+ softvga = 0;
+ gfx_pci_config_write(0x80009404, value);
+ }
+ return (softvga);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_get_pci_command
+ *
+ * This routine returns the value of the PCI command register.
+ *----------------------------------------------------------------------------
+ */
+unsigned char
+gfx_vga_get_pci_command(void)
+{
+ unsigned long value;
+
+ value = gfx_pci_config_read(0x80009404);
+ return ((unsigned char)value);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_set_pci_command
+ *
+ * This routine writes the value of the PCI command register. It is used
+ * to enable or disable SoftVGA.
+ *
+ * Bit 0: Enable VGA IO
+ * Bit 1: Enable VGA memory
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_set_pci_command(unsigned char command)
+{
+ unsigned long value;
+
+ value = gfx_pci_config_read(0x80009404) & 0xFFFFFF00;
+ value |= (unsigned long)command;
+ gfx_pci_config_write(0x80009404, value);
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_seq_reset
+ *
+ * This routine enables or disables SoftVGA. It is used to make SoftVGA
+ * "be quiet" and not interfere with any of the direct hardware access from
+ * Durango. For VSA1, the sequencer is reset to stop text redraws. VSA2 may
+ * provide a better way to have SoftVGA sit in the background.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_seq_reset(int reset)
+{
+ OUTB(0x3C4, 0);
+ OUTB(0x3C5, (unsigned char)(reset ? 0x00 : 0x03));
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_set_graphics_bits
+ *
+ * This routine sets the standard VGA sequencer, graphics controller, and
+ * attribute registers to appropriate values for a graphics mode (packed,
+ * 8 BPP or greater). This is also known as "VESA" modes. The timings for
+ * a particular mode are handled by the CRTC registers, which are set by
+ * the "gfx_vga_restore" routine. Most OSs that use VGA to set modes save
+ * and restore the standard VGA registers themselves, which is why these
+ * registers are not part of the save/restore paradigm.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_set_graphics_bits(void)
+{
+ /* SET GRAPHICS BIT IN GRAPHICS CONTROLLER REG 0x06 */
+
+ OUTB(0x3CE, 0x06);
+ OUTB(0x3CF, 0x01);
+
+ /* SET GRAPHICS BIT IN ATTRIBUTE CONTROLLER REG 0x10 */
+
+ INB(0x3BA); /* Reset flip-flop */
+ INB(0x3DA);
+ OUTB(0x3C0, 0x10);
+ OUTB(0x3C0, 0x01);
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_mode
+ *
+ * This routine searches the VGA mode table for a match of the specified
+ * mode and then fills in the VGA structure with the associated VGA register
+ * values. The "gfx_vga_restore" routine can then be called to actually
+ * set the mode.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_mode(gfx_vga_struct * vga, int xres, int yres, int bpp, int hz)
+{
+ unsigned int i;
+ unsigned short pitch;
+
+ for (i = 0; i < GFX_VGA_MODES; i++) {
+ if ((gfx_vga_modes[i].xsize == xres) &&
+ (gfx_vga_modes[i].ysize == yres) && (gfx_vga_modes[i].hz == hz)) {
+ /* COPY ENTIRE STRUCTURE FROM THE TABLE */
+
+ *vga = gfx_vga_modes[i];
+
+ /* SET PITCH TO 1K OR 2K */
+ /* CRTC_EXTENDED_OFFSET index is 0x45, so offset = 0x05 */
+
+ pitch = (unsigned short)xres;
+ if (bpp > 8)
+ pitch <<= 1;
+ if (pitch <= 1024)
+ pitch = 1024 >> 3;
+ else
+ pitch = 2048 >> 3;
+ vga->stdCRTCregs[0x13] = (unsigned char)pitch;
+ vga->extCRTCregs[0x05] = (unsigned char)((pitch >> 8) & 0x03);
+
+ /* SET PROPER COLOR DEPTH VALUE */
+ /* CRTC_EXTENDED_COLOR_CONTROL index is 0x46, so offset = 0x06 */
+
+ switch (bpp) {
+ case 15:
+ vga->extCRTCregs[0x06] = CRTC_BIT_16BPP | CRTC_BIT_555;
+ break;
+ case 16:
+ vga->extCRTCregs[0x06] = CRTC_BIT_16BPP;
+ break;
+ default:
+ vga->extCRTCregs[0x06] = 0;
+ break;
+ }
+ return (GFX_STATUS_OK);
+ }
+ }
+ return (GFX_STATUS_UNSUPPORTED);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_pitch
+ *
+ * This routine updates the VGA regisers in the specified VGA structure for
+ * the specified pitch. It does not program the hardware.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_pitch(gfx_vga_struct * vga, unsigned short pitch)
+{
+ pitch >>= 3;
+ vga->stdCRTCregs[0x13] = (unsigned char)pitch;
+ vga->extCRTCregs[0x05] = (unsigned char)((pitch >> 8) & 0x03);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_save
+ *
+ * This routine saves the state of the VGA registers into the specified
+ * structure. Flags indicate what portions of the register state need to
+ * be saved.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_save(gfx_vga_struct * vga, int flags)
+{
+ int i;
+ unsigned short crtcindex, crtcdata;
+
+ crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
+ crtcdata = crtcindex + 1;
+
+ /* CHECK MISCELLANEOUS OUTPUT FLAG */
+
+ if (flags & GFX_VGA_FLAG_MISC_OUTPUT) {
+ /* SAVE MISCCELLANEOUS OUTPUT REGISTER */
+
+ vga->miscOutput = INB(0x3CC);
+ }
+
+ /* CHECK STANDARD CRTC FLAG */
+
+ if (flags & GFX_VGA_FLAG_STD_CRTC) {
+ /* SAVE STANDARD CRTC REGISTERS */
+
+ for (i = 0; i < GFX_STD_CRTC_REGS; i++) {
+ OUTB(crtcindex, (unsigned char)i);
+ vga->stdCRTCregs[i] = INB(crtcdata);
+ }
+ }
+
+ /* CHECK EXTENDED CRTC FLAG */
+
+ if (flags & GFX_VGA_FLAG_EXT_CRTC) {
+ /* SAVE EXTENDED CRTC REGISTERS */
+
+ for (i = 0; i < GFX_EXT_CRTC_REGS; i++) {
+ OUTB(crtcindex, (unsigned char)(0x40 + i));
+ vga->extCRTCregs[i] = INB(crtcdata);
+ }
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_clear_extended
+ *
+ * This routine clears the extended SoftVGA register values to have SoftVGA
+ * behave like standard VGA.
+ *----------------------------------------------------------------------------
+ */
+void
+gfx_vga_clear_extended(void)
+{
+ int i;
+ unsigned short crtcindex, crtcdata;
+
+ crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
+ crtcdata = crtcindex + 1;
+
+ OUTB(crtcindex, 0x30);
+ OUTB(crtcdata, 0x57);
+ OUTB(crtcdata, 0x4C);
+ for (i = 0x40; i <= 0x4F; i++) {
+ OUTB(crtcindex, (unsigned char)i);
+ OUTB(crtcdata, 0);
+ }
+ OUTB(crtcindex, 0x30);
+ OUTB(crtcdata, 0x00);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_restore
+ *
+ * This routine restores the state of the VGA registers from the specified
+ * structure. Flags indicate what portions of the register state need to
+ * be saved.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_restore(gfx_vga_struct * vga, int flags)
+{
+ int i;
+ unsigned short crtcindex, crtcdata;
+
+ crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
+ crtcdata = crtcindex + 1;
+
+ /* CHECK MISCELLANEOUS OUTPUT FLAG */
+
+ if (flags & GFX_VGA_FLAG_MISC_OUTPUT) {
+ /* RESTORE MISCELLANEOUS OUTPUT REGISTER VALUE */
+
+ OUTB(0x3C2, vga->miscOutput);
+ }
+
+ /* CHECK STANDARD CRTC FLAG */
+
+ if (flags & GFX_VGA_FLAG_STD_CRTC) {
+ /* UNLOCK STANDARD CRTC REGISTERS */
+
+ OUTB(crtcindex, 0x11);
+ OUTB(crtcdata, 0);
+
+ /* RESTORE STANDARD CRTC REGISTERS */
+
+ for (i = 0; i < GFX_STD_CRTC_REGS; i++) {
+ OUTB(crtcindex, (unsigned char)i);
+ OUTB(crtcdata, vga->stdCRTCregs[i]);
+ }
+ }
+
+ /* CHECK EXTENDED CRTC FLAG */
+
+ if (flags & GFX_VGA_FLAG_EXT_CRTC) {
+ /* UNLOCK EXTENDED CRTC REGISTERS */
+
+ OUTB(crtcindex, 0x30);
+ OUTB(crtcdata, 0x57);
+ OUTB(crtcdata, 0x4C);
+
+ /* RESTORE EXTENDED CRTC REGISTERS */
+
+ for (i = 0; i < GFX_EXT_CRTC_REGS; i++) {
+ OUTB(crtcindex, (unsigned char)(0x40 + i));
+ OUTB(crtcdata, vga->extCRTCregs[i]);
+ }
+
+ /* LOCK EXTENDED CRTC REGISTERS */
+
+ OUTB(crtcindex, 0x30);
+ OUTB(crtcdata, 0x00);
+
+ /* CHECK IF DIRECT FRAME BUFFER MODE (VESA MODE) */
+
+ if (vga->extCRTCregs[0x03] & 1) {
+ /* SET BORDER COLOR TO BLACK */
+ /* This really should be another thing saved/restored, but */
+ /* Durango currently doesn't do the attr controller registers. */
+
+ INB(0x3BA); /* Reset flip-flop */
+ INB(0x3DA);
+ OUTB(0x3C0, 0x11);
+ OUTB(0x3C0, 0x00);
+ }
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_vga_mode_switch
+ *
+ * This routine programs the SoftVGA register to indicate that a mode switch
+ * is in progress. This results in a cleaner mode switch since SoftVGA will
+ * not validate the hardware with intermediate values.
+ *----------------------------------------------------------------------------
+ */
+int
+gfx_vga_mode_switch(int active)
+{
+ unsigned short crtcindex, crtcdata;
+
+ crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
+ crtcdata = crtcindex + 1;
+
+ /* UNLOCK EXTENDED CRTC REGISTERS */
+
+ OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK);
+ OUTB(crtcdata, 0x57);
+ OUTB(crtcdata, 0x4C);
+
+ /* SIGNAL THE BEGINNING OR END OF THE MODE SWITCH */
+ /* SoftVGA will hold off validating the back end hardware. */
+
+ OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL);
+ active = active ? 1 : 0;
+ OUTB(crtcdata, (unsigned char)active);
+
+ /* WAIT UNTIL SOFTVGA HAS VALIDATED MODE IF ENDING MODE SWITCH */
+ /* This is for VSA1 only, where SoftVGA waits until the next */
+ /* vertical blank to validate the hardware state. */
+
+ if ((!active) && (!(gu1_detect_vsa2()))) {
+ OUTB(crtcindex, 0x33);
+ while (INB(crtcdata) & 0x80) ;
+ }
+
+ /* LOCK EXTENDED CRTC REGISTERS */
+
+ OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK);
+ OUTB(crtcdata, 0x00);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gu1_detect_vsa2
+ *
+ * This routine detects if VSA2 is present. The interface to SoftVGA
+ * changed slightly.
+ *----------------------------------------------------------------------------
+ */
+int
+gu1_detect_vsa2(void)
+{
+ unsigned short crtcindex, crtcdata;
+
+ crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
+ crtcdata = crtcindex + 1;
+ OUTB(crtcindex, 0x35);
+ if (INB(crtcdata) != 'C')
+ return (0);
+ OUTB(crtcindex, 0x36);
+ if (INB(crtcdata) != 'X')
+ return (0);
+ return (1);
+}
+
+/* END OF FILE */
diff --git a/src/gfx/vid_1200.c b/src/gfx/vid_1200.c
new file mode 100644
index 0000000..5eb5793
--- /dev/null
+++ b/src/gfx/vid_1200.c
@@ -0,0 +1,2849 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the SC1200 video overlay hardware.
+ * */
+
+/*----------------------------------------------------------------------------
+ * SC1200 GAMMA RAM TABLE
+ *----------------------------------------------------------------------------
+ */
+
+unsigned long gfx_gamma_ram_1200[] = {
+ 0x00000000, 0x00040003, 0x00050104, 0x00060205, 0x00070306, 0x00080407,
+ 0x00090508, 0x000A0609, 0x000B070A, 0x000C080B, 0x000D090C, 0x000E0A0D,
+ 0x000F0B0E, 0x00100C0F, 0x00110D10, 0x00110E11, 0x00120F12, 0x00141013,
+ 0x00151114, 0x00161215, 0x00171316, 0x00181417, 0x00191518, 0x001A1619,
+ 0x001B171A, 0x001C181B, 0x001D191C, 0x001D1A1D, 0x001E1B1E, 0x00201C1F,
+ 0x00201D20, 0x00221E21, 0x00231F22, 0x00242023, 0x00252124, 0x00262225,
+ 0x00262326, 0x00282427, 0x00292528, 0x00292629, 0x002B272A, 0x002C282B,
+ 0x002D292C, 0x002E2A2D, 0x002F2B2E, 0x00302C2F, 0x00312D30, 0x00322E31,
+ 0x00332F32, 0x00343033, 0x00353134, 0x00363235, 0x00373336, 0x00383437,
+ 0x00393538, 0x003A3639, 0x003B373A, 0x003C383B, 0x003D393C, 0x003E3A3D,
+ 0x003F3B3E, 0x00403C3F, 0x00413D40, 0x00423E41, 0x00433F42, 0x00444043,
+ 0x00444144, 0x00454245, 0x00474346, 0x00484447, 0x00494548, 0x004A4649,
+ 0x004B474A, 0x004C484B, 0x004D494C, 0x004E4A4D, 0x004F4B4E, 0x00504C4F,
+ 0x00514D50, 0x00524E51, 0x00534F52, 0x00545053, 0x00555154, 0x00565255,
+ 0x00575356, 0x00585457, 0x00595558, 0x005A5659, 0x005B575A, 0x005C585B,
+ 0x005D595C, 0x005E5A5D, 0x005F5B5E, 0x00605C5F, 0x00615D60, 0x00625E61,
+ 0x00635F62, 0x00646063, 0x00656164, 0x00666265, 0x00676366, 0x00686467,
+ 0x00696568, 0x006A6669, 0x006B676A, 0x006C686B, 0x006D696C, 0x006E6A6D,
+ 0x006F6B6E, 0x00706C6F, 0x00716D70, 0x00726E71, 0x00736F72, 0x00747073,
+ 0x00757174, 0x00767275, 0x00777376, 0x00787477, 0x00797578, 0x007A7679,
+ 0x007B777A, 0x007C787B, 0x007D797C, 0x007E7A7D, 0x007F7B7E, 0x00807C7F,
+ 0x00817D80, 0x00827E81, 0x00837F82, 0x00848083, 0x00858184, 0x00868285,
+ 0x00878386, 0x00888487, 0x00898588, 0x008A8689, 0x008B878A, 0x008C888B,
+ 0x008D898C, 0x008E8A8D, 0x008F8B8E, 0x00908C8F, 0x00918D90, 0x00928E91,
+ 0x00938F92, 0x00949093, 0x00959194, 0x00969295, 0x00979396, 0x00989497,
+ 0x00999598, 0x009A9699, 0x009B979A, 0x009C989B, 0x009D999C, 0x009E9A9D,
+ 0x009F9B9E, 0x00A09C9F, 0x00A19DA0, 0x00A29EA1, 0x00A39FA2, 0x00A4A0A3,
+ 0x00A5A1A4, 0x00A6A2A5, 0x00A7A3A6, 0x00A8A4A7, 0x00A9A5A8, 0x00AAA6A9,
+ 0x00ABA7AA, 0x00ACA8AB, 0x00ADA9AC, 0x00AEAAAD, 0x00AFABAE, 0x00B0ACAF,
+ 0x00B1ADB0, 0x00B2AEB1, 0x00B3AFB2, 0x00B4B0B3, 0x00B5B1B4, 0x00B6B2B5,
+ 0x00B7B3B6, 0x00B8B4B7, 0x00B9B5B8, 0x00BAB6B9, 0x00BBB7BA, 0x00BCB8BB,
+ 0x00BDB9BC, 0x00BEBABD, 0x00BFBBBE, 0x00C0BCBF, 0x00C1BDC0, 0x00C2BEC1,
+ 0x00C3BFC2, 0x00C4C0C3, 0x00C5C1C4, 0x00C6C2C5, 0x00C7C3C6, 0x00C8C4C7,
+ 0x00C9C5C8, 0x00CAC6C9, 0x00CBC7CA, 0x00CCC8CB, 0x00CDC9CC, 0x00CECACD,
+ 0x00CFCBCE, 0x00D0CCCF, 0x00D1CDD0, 0x00D2CED1, 0x00D3CFD2, 0x00D4D0D3,
+ 0x00D5D1D4, 0x00D6D2D5, 0x00D7D3D6, 0x00D8D4D7, 0x00D9D5D8, 0x00DAD6D9,
+ 0x00DBD7DA, 0x00DCD8DB, 0x00DDD9DC, 0x00DEDADD, 0x00DFDBDE, 0x00E0DCDF,
+ 0x00E1DDE0, 0x00E2DEE1, 0x00E3DFE2, 0x00E4E0E3, 0x00E5E1E4, 0x00E6E2E5,
+ 0x00E7E3E6, 0x00E8E4E7, 0x00E9E5E8, 0x00EAE6E9, 0x00EBE7EA, 0x00ECE8EB,
+ 0x00EDE9EC, 0x00EEEAED, 0x00EFEBEE, 0x00F0ECEF, 0x00F1EDF0, 0x00F2EEF1,
+ 0x00F3EFF2, 0x00F4F0F3, 0x00F5F1F4, 0x00F6F2F5, 0x00F7F3F6, 0x00F8F4F7,
+ 0x00F9F5F8, 0x00FAF6F9, 0x00FBF7FA, 0x00FCF8FB, 0x00FDF9FC, 0x00FEFAFD,
+ 0x00FFFBFE, 0x00FFFCFE, 0x00FFFDFE, 0x00FFFFFF
+};
+
+/*----------------------------------------------------------------------------
+ * SC1200 PLL TABLE
+ *----------------------------------------------------------------------------
+ */
+
+typedef struct tagSC1200PLL
+{
+ long frequency; /* 16.16 fixed point frequency */
+ unsigned long clock_select; /* clock select register (0x2C) */
+} SC1200PLL;
+
+SC1200PLL gfx_sc1200_clock_table[] = {
+ {(25L << 16) | ((1750L * 65536L) / 10000L), 0x0070E00C}, /* 25.1750
+ * (sc=24.9231) */
+ {(27L << 16) | ((0000L * 65536L) / 10000L), 0x00300100}, /* 27.0000 */
+ {(28L << 16) | ((3220L * 65536L) / 10000L), 0x0070EC0C}, /* 28.3220
+ * (SC=27.000) */
+ {(31L << 16) | ((5000L * 65536L) / 10000L), 0x00500D02}, /* 31.5000 */
+ {(36L << 16) | ((0000L * 65536L) / 10000L), 0x00500F02}, /* 36.0000 */
+ {(37L << 16) | ((5000L * 65536L) / 10000L), 0x0050B108}, /* 37.5000 */
+ {(40L << 16) | ((0000L * 65536L) / 10000L), 0x0050D20D}, /* 40.0000 */
+ {(44L << 16) | ((9000L * 65536L) / 10000L), 0x0050DC0D}, /* 44.9000 */
+ {(49L << 16) | ((5000L * 65536L) / 10000L), 0x00501502}, /* 49.5000 */
+ {(50L << 16) | ((0000L * 65536L) / 10000L), 0x0050A404}, /* 50.0000 */
+ {(50L << 16) | ((3500L * 65536L) / 10000L), 0x0050E00C}, /* 50.3500 */
+ {(54L << 16) | ((0000L * 65536L) / 10000L), 0x00300300}, /* 54.0000 */
+ {(56L << 16) | ((3916L * 65536L) / 10000L), 0x0050F40D}, /* 56.3916 */
+ {(56L << 16) | ((6440L * 65536L) / 10000L), 0x0050EC0C}, /* 56.6440 */
+ {(59L << 16) | ((0000L * 65536L) / 10000L), 0x0030A207}, /* 59.0000 */
+ {(63L << 16) | ((0000L * 65536L) / 10000L), 0x00300D02}, /* 63.0000 */
+ {(65L << 16) | ((0000L * 65536L) / 10000L), 0x0030CC0F}, /* 65.0000 */
+ {(67L << 16) | ((5000L * 65536L) / 10000L), 0x00300400}, /* 67.5000 */
+ {(70L << 16) | ((8000L * 65536L) / 10000L), 0x00301403}, /* 70.8000 */
+ {(72L << 16) | ((0000L * 65536L) / 10000L), 0x00300F02}, /* 72.0000 */
+ {(75L << 16) | ((0000L * 65536L) / 10000L), 0x0030B108}, /* 75.0000 */
+ {(78L << 16) | ((7500L * 65536L) / 10000L), 0x0030A205}, /* 78.7500 */
+ {(80L << 16) | ((0000L * 65536L) / 10000L), 0x0030D20D}, /* 80.0000 */
+ {(87L << 16) | ((2728L * 65536L) / 10000L), 0x0030E00E}, /* 87.2728 */
+ {(89L << 16) | ((8000L * 65536L) / 10000L), 0x0030DC0D}, /* 89.8000 */
+ {(94L << 16) | ((5000L * 65536L) / 10000L), 0x00300600}, /* 99.0000 */
+ {(99L << 16) | ((0000L * 65536L) / 10000L), 0x00301502}, /* 99.0000 */
+ {(100L << 16) | ((0000L * 65536L) / 10000L), 0x0030A404}, /* 100.00 */
+ {(108L << 16) | ((0000L * 65536L) / 10000L), 0x00100300}, /* 108.00 */
+ {(112L << 16) | ((5000L * 65536L) / 10000L), 0x00301802}, /* 108.00 */
+ {(130L << 16) | ((0000L * 65536L) / 10000L), 0x0010CC0F}, /* 130.00 */
+ {(135L << 16) | ((0000L * 65536L) / 10000L), 0x00100400}, /* 135.00 */
+ {(157L << 16) | ((5000L * 65536L) / 10000L), 0x0010A205}, /* 157.50 */
+ {(162L << 16) | ((0000L * 65536L) / 10000L), 0x00100500}, /* 162.00 */
+ {(175L << 16) | ((0000L * 65536L) / 10000L), 0x0010E00E}, /* 175.50 */
+ {(189L << 16) | ((0000L * 65536L) / 10000L), 0x00100600}, /* 189.00 */
+ {(202L << 16) | ((0000L * 65536L) / 10000L), 0x0010EF0E}, /* 202.50 */
+ {(232L << 16) | ((0000L * 65536L) / 10000L), 0x0010AA04}, /* 232.50 */
+
+ /* Precomputed inidces in the hardware */
+ {0x0018EC4D, 0x000F0000}, /* 24.923052 */
+ {0x00192CCC, 0x00000000}, /* 25.1750 */
+ {0x001B0000, 0x00300100}, /* 27.0000 */
+ {0x001F8000, 0x00010000}, /* 31.5000 */
+ {0x00240000, 0x00020000}, /* 36.0000 */
+ {0x00280000, 0x00030000}, /* 40.0000 */
+ {0x00318000, 0x00050000}, /* 49.5000 */
+ {0x00320000, 0x00040000}, /* 50.0000 */
+ {0x00384000, 0x00060000}, /* 56.2500 */
+ {0x00410000, 0x00080000}, /* 65.0000 */
+ {0x004E8000, 0x000A0000}, /* 78.5000 */
+ {0x005E8000, 0x000B0000}, /* 94.5000 */
+ {0x006C0000, 0x000C0000}, /* 108.0000 */
+ {0x00870000, 0x000D0000}, /* 135.0000 */
+};
+
+#define NUM_SC1200_FREQUENCIES \
+ sizeof(gfx_sc1200_clock_table)/sizeof(SC1200PLL)
+
+/*---------------------------------------------------------------------------
+ * 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
+sc1200_reset_video(void)
+#else
+void
+gfx_reset_video(void)
+#endif
+{
+ int i;
+
+ gfx_set_video_enable(0);
+
+ /* SET WINDOW 0 AFTER RESET */
+
+ for (i = 2; i >= 0; i--) {
+ gfx_select_alpha_region(i);
+ gfx_set_alpha_enable(0);
+ gfx_set_alpha_color_enable(0);
+ }
+
+ /* CLEAR THE DISPLAY BUFFER SIZE TO ZERO */
+ /* During a modeset,if FIFO load is enabled with a large buffer size, */
+ /* the FIFO can hang. To prevent this, we set the buffer size to zero */
+ /* and wait for this new size to be latched */
+
+ gfx_set_display_video_size(0, 0);
+
+ if (gfx_test_timing_active()) {
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
+ *
+ * This routine configures the display output.
+ *
+ * "sync_polarities" is used to set the polarities of the sync pulses
+ * according to the following mask:
+ *
+ * Bit 0: If set to 1, negative horizontal polarity is programmed,
+ * otherwise positive horizontal polarity is programmed.
+ * Bit 1: If set to 1, negative vertical polarity is programmed,
+ * otherwise positive vertical polarity is programmed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_display_control(int sync_polarities)
+#else
+int
+gfx_set_display_control(int sync_polarities)
+#endif
+{
+ unsigned long dcfg;
+
+ /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+
+ dcfg = READ_VID32(SC1200_DISPLAY_CONFIG);
+ dcfg &= ~(SC1200_DCFG_CRT_SYNC_SKW_MASK | SC1200_DCFG_PWR_SEQ_DLY_MASK |
+ SC1200_DCFG_CRT_HSYNC_POL | SC1200_DCFG_CRT_VSYNC_POL |
+ SC1200_DCFG_FP_PWR_EN | SC1200_DCFG_FP_DATA_EN);
+
+ dcfg |= (SC1200_DCFG_CRT_SYNC_SKW_INIT |
+ SC1200_DCFG_PWR_SEQ_DLY_INIT | SC1200_DCFG_GV_PAL_BYP);
+
+ if (PanelEnable)
+ dcfg |= SC1200_DCFG_FP_PWR_EN;
+
+ /* SET APPROPRIATE SYNC POLARITIES */
+
+ if (sync_polarities & 0x1)
+ dcfg |= SC1200_DCFG_CRT_HSYNC_POL;
+ if (sync_polarities & 0x2)
+ dcfg |= SC1200_DCFG_CRT_VSYNC_POL;
+
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg);
+
+ return (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
+sc1200_set_clock_frequency(unsigned long frequency)
+#else
+void
+gfx_set_clock_frequency(unsigned long frequency)
+#endif
+{
+ unsigned int index;
+ unsigned long value, pll;
+ long min, diff;
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+
+ value = gfx_sc1200_clock_table[0].clock_select;
+ min = (long)gfx_sc1200_clock_table[0].frequency - frequency;
+ if (min < 0L)
+ min = -min;
+ for (index = 1; index < NUM_SC1200_FREQUENCIES; index++) {
+ diff = (long)gfx_sc1200_clock_table[index].frequency - frequency;
+ if (diff < 0L)
+ diff = -diff;
+ if (diff < min) {
+ min = diff;
+ value = gfx_sc1200_clock_table[index].clock_select;
+ }
+ }
+
+ /* SET THE DOT CLOCK REGISTER */
+
+ pll = READ_VID32(SC1200_VID_MISC);
+ WRITE_VID32(SC1200_VID_MISC, pll | SC1200_PLL_POWER_NORMAL);
+ WRITE_VID32(SC1200_VID_CLOCK_SELECT, value);
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_screen_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine enables or disables the graphics display logic of the video
+ * processor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_screen_enable(int enable)
+#else
+int
+gfx_set_screen_enable(int enable)
+#endif
+{
+ unsigned long config;
+
+ config = READ_VID32(SC1200_DISPLAY_CONFIG);
+ if (enable)
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_DIS_EN);
+ else
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~SC1200_DCFG_DIS_EN);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_crt_enable
+ *
+ * This routine enables or disables the CRT output from the video processor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_crt_enable(int enable)
+#else
+int
+gfx_set_crt_enable(int enable)
+#endif
+{
+ unsigned long config, misc;
+
+ config = READ_VID32(SC1200_DISPLAY_CONFIG);
+ misc = READ_VID32(SC1200_VID_MISC);
+
+ /*
+ * IMPORTANT: For all modes do NOT disable the graphics display logic
+ * because it might be needed for TV
+ */
+
+ switch (enable) {
+ case CRT_DISABLE: /* HSync:Off VSync:Off */
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, config & ~(SC1200_DCFG_HSYNC_EN
+ | SC1200_DCFG_VSYNC_EN | SC1200_DCFG_DAC_BL_EN));
+ WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN);
+ break;
+ case CRT_ENABLE: /* Enable CRT display, including
+ * display logic */
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, config | SC1200_DCFG_HSYNC_EN
+ | SC1200_DCFG_VSYNC_EN | SC1200_DCFG_DAC_BL_EN);
+ WRITE_VID32(SC1200_VID_MISC, misc & ~SC1200_DAC_POWER_DOWN);
+
+ /* ENABLE GRAPHICS DISPLAY LOGIC */
+ gfx_set_screen_enable(1);
+ break;
+ case CRT_STANDBY: /* HSync:Off VSync:On */
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_HSYNC_EN
+ | SC1200_DCFG_DAC_BL_EN))
+ | SC1200_DCFG_VSYNC_EN);
+ WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN);
+ break;
+ case CRT_SUSPEND: /* HSync:On VSync:Off */
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, (config & ~(SC1200_DCFG_VSYNC_EN
+ | SC1200_DCFG_DAC_BL_EN))
+ | SC1200_DCFG_HSYNC_EN);
+ WRITE_VID32(SC1200_VID_MISC, misc | SC1200_DAC_POWER_DOWN);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_enable
+ *
+ * This routine enables or disables the video overlay functionality.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_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(SC1200_VIDEO_CONFIG);
+ if (enable) {
+ /* ENABLE SC1200 VIDEO OVERLAY */
+
+ vcfg |= SC1200_VCFG_VID_EN;
+ WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
+ } else {
+ /* DISABLE SC1200 VIDEO OVERLAY */
+
+ vcfg &= ~SC1200_VCFG_VID_EN;
+ WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_format
+ *
+ * Sets input video format type, to one of the YUV formats or to RGB.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_format(unsigned long format)
+#else
+int
+gfx_set_video_format(unsigned long format)
+#endif
+{
+ unsigned long ctrl, vcfg = 0;
+
+ /* SET THE SC1200 VIDEO INPUT FORMAT */
+
+ vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
+ ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ ctrl &= ~(SC1200_VIDEO_INPUT_IS_RGB);
+ vcfg &= ~(SC1200_VCFG_VID_INP_FORMAT | SC1200_VCFG_4_2_0_MODE);
+ switch (format) {
+ case VIDEO_FORMAT_UYVY:
+ vcfg |= SC1200_VCFG_UYVY_FORMAT;
+ break;
+ case VIDEO_FORMAT_YUYV:
+ vcfg |= SC1200_VCFG_YUYV_FORMAT;
+ break;
+ case VIDEO_FORMAT_Y2YU:
+ vcfg |= SC1200_VCFG_Y2YU_FORMAT;
+ break;
+ case VIDEO_FORMAT_YVYU:
+ vcfg |= SC1200_VCFG_YVYU_FORMAT;
+ break;
+ case VIDEO_FORMAT_Y0Y1Y2Y3:
+ vcfg |= SC1200_VCFG_UYVY_FORMAT;
+ vcfg |= SC1200_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y3Y2Y1Y0:
+ vcfg |= SC1200_VCFG_Y2YU_FORMAT;
+ vcfg |= SC1200_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y1Y0Y3Y2:
+ vcfg |= SC1200_VCFG_YUYV_FORMAT;
+ vcfg |= SC1200_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y1Y2Y3Y0:
+ vcfg |= SC1200_VCFG_YVYU_FORMAT;
+ vcfg |= SC1200_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_RGB:
+ ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
+ vcfg |= SC1200_VCFG_UYVY_FORMAT;
+ break;
+ case VIDEO_FORMAT_P2M_P2L_P1M_P1L:
+ ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
+ vcfg |= SC1200_VCFG_Y2YU_FORMAT;
+ break;
+ case VIDEO_FORMAT_P1M_P1L_P2M_P2L:
+ ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
+ vcfg |= SC1200_VCFG_YUYV_FORMAT;
+ break;
+ case VIDEO_FORMAT_P1M_P2L_P2M_P1L:
+ ctrl |= SC1200_VIDEO_INPUT_IS_RGB;
+ vcfg |= SC1200_VCFG_YVYU_FORMAT;
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+
+ /* ALWAYS DISABLE GRAPHICS CSC */
+ /* This is enabled in the function gfx_set_color_space_YUV for */
+ /* YUV blending on TV. */
+
+ ctrl &= ~SC1200_CSC_GFX_RGB_TO_YUV;
+
+ if (ctrl & SC1200_VIDEO_INPUT_IS_RGB)
+ ctrl &= ~SC1200_CSC_VIDEO_YUV_TO_RGB;
+ else
+ ctrl |= SC1200_CSC_VIDEO_YUV_TO_RGB;
+
+ WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL, ctrl);
+
+ 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
+sc1200_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 SC1200 VIDEO LINE SIZE */
+
+ vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
+ vcfg &= ~(SC1200_VCFG_LINE_SIZE_LOWER_MASK | SC1200_VCFG_LINE_SIZE_UPPER);
+ size = (width >> 1);
+ vcfg |= (size & 0x00FF) << 8;
+ if (size & 0x0100)
+ vcfg |= SC1200_VCFG_LINE_SIZE_UPPER;
+ WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);
+
+ /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ /* Add 1 line to bypass issue #803 */
+ gfx_set_display_video_size(width, (unsigned short)(height + 2));
+ 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
+sc1200_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_upscale
+ *
+ * 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
+sc1200_set_video_upscale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth)
+#else
+int
+gfx_set_video_upscale(unsigned short srcw, unsigned short srch,
+ unsigned short dstw, unsigned short dsth)
+#endif
+{
+ unsigned long xscale, yscale;
+
+ /* SAVE PARAMETERS (unless don't-care zero destination arguments are used)
+ * */
+ /* These are needed for clipping the video window later. */
+
+ if (dstw != 0) {
+ gfx_vid_srcw = srcw;
+ gfx_vid_dstw = dstw;
+ }
+ if (dsth != 0) {
+ gfx_vid_srch = srch;
+ gfx_vid_dsth = dsth;
+ }
+
+ /* CALCULATE SC1200 SCALE FACTORS */
+
+ if (dstw == 0)
+ xscale = READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff;
+ /* keep previous if don't-care argument */
+ else if (dstw <= srcw)
+ xscale = 0x2000l;
+ /* horizontal downscaling is currently done in a separate function */
+ else if ((srcw == 1) || (dstw == 1))
+ return GFX_STATUS_BAD_PARAMETER;
+ else
+ xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l);
+
+ if (dsth == 0)
+ yscale = (READ_VID32(SC1200_VIDEO_UPSCALE) & 0xffff0000) >> 16;
+ /* keep previous if don't-care argument */
+ else if (dsth <= srch)
+ yscale = 0x2000l;
+ /* No vertical downscaling in SC1200 so force to 1x if attempted */
+ else if ((srch == 1) || (dsth == 1))
+ return GFX_STATUS_BAD_PARAMETER;
+ else
+ yscale = (0x2000l * (srch - 1l)) / (dsth - 1l);
+
+ WRITE_VID32(SC1200_VIDEO_UPSCALE, (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_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
+sc1200_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
+{
+ return gfx_set_video_upscale(srcw, srch, dstw, dsth);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_config
+ *
+ * This routine sets the downscale type and factor for the video overlay
+ * window.
+ * Note: No downscaling support for RGB565 and YUV420 video formats.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_downscale_config(unsigned short type, unsigned short m)
+#else
+int
+gfx_set_video_downscale_config(unsigned short type, unsigned short m)
+#endif
+{
+ unsigned long downscale;
+
+ if ((m < 1) || (m > 16))
+ return GFX_STATUS_BAD_PARAMETER;
+
+ downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL);
+ downscale &=
+ ~(SC1200_VIDEO_DOWNSCALE_FACTOR_MASK |
+ SC1200_VIDEO_DOWNSCALE_TYPE_MASK);
+ downscale |= ((m - 1l) << SC1200_VIDEO_DOWNSCALE_FACTOR_POS);
+ switch (type) {
+ case VIDEO_DOWNSCALE_KEEP_1_OF:
+ downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_A;
+ break;
+ case VIDEO_DOWNSCALE_DROP_1_OF:
+ downscale |= SC1200_VIDEO_DOWNSCALE_TYPE_B;
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_coefficients
+ *
+ * This routine sets the downscale filter coefficients.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4)
+#else
+int
+gfx_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4)
+#endif
+{
+ if ((coef1 + coef2 + coef3 + coef4) != 16)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS,
+ ((unsigned long)coef1 << SC1200_VIDEO_DOWNSCALER_COEF1_POS) |
+ ((unsigned long)coef2 << SC1200_VIDEO_DOWNSCALER_COEF2_POS) |
+ ((unsigned long)coef3 << SC1200_VIDEO_DOWNSCALER_COEF3_POS) |
+ ((unsigned long)coef4 << SC1200_VIDEO_DOWNSCALER_COEF4_POS));
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_enable
+ *
+ * This routine enables or disables downscaling for the video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_downscale_enable(int enable)
+#else
+int
+gfx_set_video_downscale_enable(int enable)
+#endif
+{
+ unsigned long downscale;
+
+ downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL);
+ downscale &= ~SC1200_VIDEO_DOWNSCALE_ENABLE;
+ if (enable)
+ downscale |= SC1200_VIDEO_DOWNSCALE_ENABLE;
+ WRITE_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL, downscale);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_window
+ *
+ * This routine sets the position and size of the video overlay window. The
+ * y 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.
+ * For the effect of negative x values, call the function
+ * gfx_set_video_left_crop().
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_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 control;
+ unsigned long hadjust, vadjust;
+ unsigned long xstart, ystart, xend, yend;
+
+ /* For left cropping call the function gfx_set_video_left_crop() */
+
+ if (x < 0)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* SAVE PARAMETERS */
+ /* These are needed to call this routine if the scale value changes. */
+ /* In the case of SC1200 they are also needed for restoring when video
+ * is re-enabled */
+
+ 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() - 14l;
+ vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
+
+ /* HORIZONTAL START */
+
+ xstart = (unsigned long)x + hadjust;
+
+ /* HORIZONTAL END */
+ /* End positions in register are non-inclusive (one more than the actual
+ * end) */
+
+ if ((x + w) < gfx_get_hactive())
+ xend = (unsigned long)x + (unsigned long)w + hadjust;
+ else /* right clipping needed */
+ xend = (unsigned long)gfx_get_hactive() + hadjust;
+
+ /* VERTICAL START */
+
+ ystart = (unsigned long)y + vadjust;
+
+ /* VERTICAL END */
+
+ if ((y + h) < gfx_get_vactive())
+ yend = (unsigned long)y + (unsigned long)h + vadjust;
+ else /* bottom clipping needed */
+ yend = (unsigned long)gfx_get_vactive() + vadjust;
+
+ /* SET VIDEO LINE INVERT BIT */
+
+ control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ if (y & 0x1)
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
+ control | SC1200_VIDEO_LINE_OFFSET_ODD);
+ else
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
+ control & ~SC1200_VIDEO_LINE_OFFSET_ODD);
+
+ /* SET VIDEO POSITION */
+
+ WRITE_VID32(SC1200_VIDEO_X_POS, (xend << 16) | xstart);
+ WRITE_VID32(SC1200_VIDEO_Y_POS, (yend << 16) | ystart);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_left_crop
+ *
+ * This routine sets the number of pixels which will be cropped from the
+ * beginning of each video line. The video window will begin to display only
+ * from the pixel following the cropped pixels, and the cropped pixels
+ * will be ignored.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_left_crop(unsigned short x)
+#else
+int
+gfx_set_video_left_crop(unsigned short x)
+#endif
+{
+ unsigned long vcfg, initread;
+
+ /* CLIPPING ON LEFT */
+ /* Adjust initial read for scale, checking for divide by zero */
+
+ if (gfx_vid_dstw)
+ initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw;
+
+ else
+ initread = 0l;
+
+ /* SET INITIAL READ ADDRESS */
+
+ vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
+ vcfg &= ~SC1200_VCFG_INIT_READ_MASK;
+ vcfg |= (initread << 15) & SC1200_VCFG_INIT_READ_MASK;
+ WRITE_VID32(SC1200_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))
+ *
+ * If "graphics" is set to TRUE, the source data is graphics, and color key
+ * is an RGB value. If "graphics" is set to FALSE, the source data is the
+ * video, and color key is a YUV value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_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 SC1200 COLOR KEY VALUE */
+
+ WRITE_VID32(SC1200_VIDEO_COLOR_KEY, key);
+ WRITE_VID32(SC1200_VIDEO_COLOR_MASK, mask);
+
+ /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */
+
+ dcfg = READ_VID32(SC1200_DISPLAY_CONFIG);
+ if (graphics & 0x01)
+ dcfg &= ~SC1200_DCFG_VG_CK;
+ else
+ dcfg |= SC1200_DCFG_VG_CK;
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_filter
+ *
+ * This routine enables or disables the video overlay filters.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_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 SC1200 VIDEO OVERLAY FILTERS */
+
+ vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
+ vcfg &= ~(SC1200_VCFG_X_FILTER_EN | SC1200_VCFG_Y_FILTER_EN);
+ if (xfilter)
+ vcfg |= SC1200_VCFG_X_FILTER_EN;
+ if (yfilter)
+ vcfg |= SC1200_VCFG_Y_FILTER_EN;
+ WRITE_VID32(SC1200_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 SC1200, this means loading the
+ * palette with identity values).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_palette(unsigned long *palette)
+#else
+int
+gfx_set_video_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i, entry;
+ unsigned long dcfg, misc;
+
+ /* WAIT FOR VERTICAL BLANK TO END */
+ /* Otherwise palette will not be written properly. */
+
+ if (gfx_test_timing_active()) {
+ if (gfx_test_vertical_active()) {
+ while (gfx_test_vertical_active()) ;
+ }
+ while (!gfx_test_vertical_active()) ;
+ }
+
+ /* LOAD SC1200 VIDEO PALETTE */
+
+ WRITE_VID32(SC1200_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ if (palette)
+ entry = palette[i];
+ else
+ entry = gfx_gamma_ram_1200[i] << 8;
+ WRITE_VID32(SC1200_PALETTE_DATA, entry);
+ }
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32(SC1200_DISPLAY_CONFIG);
+ misc = READ_VID32(SC1200_VID_MISC);
+
+ dcfg |= SC1200_DCFG_GV_PAL_BYP;
+ misc &= ~SC1200_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32(SC1200_VID_MISC, misc);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_entry
+ *
+ * This routine loads a single entry of the video hardware palette.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_palette_entry(unsigned long index, unsigned long palette)
+#else
+int
+gfx_set_video_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ unsigned long dcfg, misc;
+
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* WAIT FOR VERTICAL BLANK TO END */
+ /* Otherwise palette will not be written properly. */
+
+ if (gfx_test_timing_active()) {
+ if (gfx_test_vertical_active()) {
+ while (gfx_test_vertical_active()) ;
+ }
+ while (!gfx_test_vertical_active()) ;
+ }
+
+ /* SET A SINGLE ENTRY */
+
+ WRITE_VID32(SC1200_PALETTE_ADDRESS, index);
+ WRITE_VID32(SC1200_PALETTE_DATA, palette);
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32(SC1200_DISPLAY_CONFIG);
+ misc = READ_VID32(SC1200_VID_MISC);
+
+ dcfg |= SC1200_DCFG_GV_PAL_BYP;
+ misc &= ~SC1200_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(SC1200_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32(SC1200_VID_MISC, misc);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_bypass
+ *
+ * This routine enables/disables the pallete RAM bypass.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_palette_bypass(int enable)
+#else
+int
+gfx_set_video_palette_bypass(int enable)
+#endif
+{
+ unsigned long misc;
+
+ misc = READ_VID32(SC1200_VID_MISC);
+
+ if (enable)
+ misc |= SC1200_GAMMA_BYPASS_BOTH;
+ else
+ misc &= ~SC1200_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(SC1200_VID_MISC, misc);
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_request()
+ *
+ * This routine sets the horizontal (pixel) and vertical (line) video request
+ * values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_request(short x, short y)
+#else
+int
+gfx_set_video_request(short x, short y)
+#endif
+{
+ /* SET SC1200 VIDEO REQUEST */
+
+ x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ if ((x < 0) || (x > SC1200_VIDEO_REQUEST_MASK) ||
+ (y < 0) || (y > SC1200_VIDEO_REQUEST_MASK))
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_VID32(SC1200_VIDEO_REQUEST,
+ ((unsigned long)x << SC1200_VIDEO_X_REQUEST_POS) | ((unsigned long)y
+ << SC1200_VIDEO_Y_REQUEST_POS));
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_source()
+ *
+ * This routine sets the video source to either memory or Direct VIP.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_source(VideoSourceType source)
+#else
+int
+gfx_set_video_source(VideoSourceType source)
+#endif
+{
+ unsigned long display_mode;
+
+ display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE);
+
+ /* SET SC1200 VIDEO SOURCE */
+ switch (source) {
+ case VIDEO_SOURCE_MEMORY:
+ WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
+ (display_mode & ~SC1200_VIDEO_SOURCE_MASK) |
+ SC1200_VIDEO_SOURCE_GX1);
+ break;
+ case VIDEO_SOURCE_DVIP:
+ WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
+ (display_mode & ~SC1200_VIDEO_SOURCE_MASK) |
+ SC1200_VIDEO_SOURCE_DVIP);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vbi_source()
+ *
+ * This routine sets the vbi source to either memory or Direct VIP.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_vbi_source(VbiSourceType source)
+#else
+int
+gfx_set_vbi_source(VbiSourceType source)
+#endif
+{
+ unsigned long display_mode;
+
+ display_mode = READ_VID32(SC1200_VIDEO_DISPLAY_MODE);
+
+ /* SET SC1200 VBI SOURCE */
+ switch (source) {
+ case VBI_SOURCE_MEMORY:
+ WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
+ (display_mode & ~SC1200_VBI_SOURCE_MASK) | SC1200_VBI_SOURCE_GX1);
+ break;
+ case VBI_SOURCE_DVIP:
+ WRITE_VID32(SC1200_VIDEO_DISPLAY_MODE,
+ (display_mode & ~SC1200_VBI_SOURCE_MASK) |
+ SC1200_VBI_SOURCE_DVIP);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vbi_lines()
+ *
+ * This routine sets the VBI lines to pass to the TV encoder.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_vbi_lines(unsigned long even, unsigned long odd)
+#else
+int
+gfx_set_vbi_lines(unsigned long even, unsigned long odd)
+#endif
+{
+ /* SET SC1200 VBI LINES */
+ WRITE_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE,
+ even & SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
+ WRITE_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE,
+ odd & SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vbi_total()
+ *
+ * This routine sets the total number of VBI bytes for each field.
+ * The total is needed when both VBI and active video are received from memory
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_vbi_total(unsigned long even, unsigned long odd)
+#else
+int
+gfx_set_vbi_total(unsigned long even, unsigned long odd)
+#endif
+{
+ /* SET SC1200 VBI TOTAL */
+ WRITE_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT,
+ even & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
+ WRITE_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT,
+ odd & SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_interlaced()
+ *
+ * This routine configures the video processor video overlay mode to be
+ * interlaced YUV.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_interlaced(int enable)
+#else
+int
+gfx_set_video_interlaced(int enable)
+#endif
+{
+ unsigned long control;
+
+ control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ /* SET INTERLACED VIDEO */
+ if (enable)
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
+ control | SC1200_VIDEO_IS_INTERLACED);
+ else
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
+ control & ~SC1200_VIDEO_IS_INTERLACED);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_color_space_YUV()
+ *
+ * This routine configures the video processor to process graphics and video
+ * in either YUV or RGB color space. The mode should be set to tune image
+ * quality.
+ * Setting "enable" to TRUE improves image quality on TV,
+ * but in this mode colors on CRT will not be correct.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_color_space_YUV(int enable)
+#else
+int
+gfx_set_color_space_YUV(int enable)
+#endif
+{
+ unsigned long control;
+
+ control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+
+ /* SET SC1200 VIDEO COLOR SPACE TO YUV OR RGB */
+
+ if (enable) {
+ /* ENABLE YUV BLENDING */
+ /* YUV blending cannot be enabled in RGB video formats */
+
+ control |= SC1200_CSC_GFX_RGB_TO_YUV; /* Convert graphics to YUV */
+ control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in YUV */
+
+ if (control & SC1200_VIDEO_INPUT_IS_RGB)
+ return (GFX_STATUS_UNSUPPORTED); /* Can't convert video from
+ * RGB to YUV */
+ } else {
+ /* RGB BLENDING */
+
+ control &= ~SC1200_CSC_GFX_RGB_TO_YUV; /* Leave graphics in RGB */
+ if (control & SC1200_VIDEO_INPUT_IS_RGB)
+ control &= ~SC1200_CSC_VIDEO_YUV_TO_RGB; /* Leave video in RGB */
+ else
+ control |= SC1200_CSC_VIDEO_YUV_TO_RGB; /* Convert video to RGB */
+ }
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_vertical_scaler_offset()
+ *
+ * This routine sets the value by which the odd frame is shifted with respect
+ * to the even frame. This is useful for de-interlacing in Bob method, by
+ * setting the shift value to be one line.
+ * If offset is 0, no shifting occurs.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_vertical_scaler_offset(char offset)
+#else
+int
+gfx_set_vertical_scaler_offset(char offset)
+#endif
+{
+ unsigned long control;
+
+ control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ if (offset == 1) {
+ control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK;
+ /* Clear shifting value */
+ control |= SC1200_VERTICAL_SCALER_SHIFT_INIT;
+ /* Set shifting value */
+ control |= SC1200_VERTICAL_SCALER_SHIFT_EN;
+ /* Enable odd frame shifting */
+ } else if (offset == 0) {
+ control &= ~SC1200_VERTICAL_SCALER_SHIFT_EN;
+ /* No shifting occurs */
+ control &= ~SC1200_VERTICAL_SCALER_SHIFT_MASK;
+ /* Clear shifting value */
+ } else
+ return (GFX_STATUS_BAD_PARAMETER);
+ /* TODO: how to program other values ? */
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_top_line_in_odd()
+ *
+ * This routine sets the field in which the top line of input video resides.
+ * If enable is "0", this is the even field (default). [not to be confused
+ * with the odd field being the top field on TV].
+ * If enable is "1", this is the odd field.
+ * Use enable "1" for input devices whose field indication is reversed from
+ * normal, i.e. an indication of "odd" field is given for even field data,
+ * and vice versa.
+ * This setting affects the video processor only when it is in either
+ * interlaced or Bob (scaler offset active) modes.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_top_line_in_odd(int enable)
+#else
+int
+gfx_set_top_line_in_odd(int enable)
+#endif
+{
+ unsigned long control;
+
+ control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ if (enable)
+ control |= SC1200_TOP_LINE_IN_ODD; /* Set shifting value */
+ else
+ control &= ~SC1200_TOP_LINE_IN_ODD; /* No shifting occurs */
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL, control);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_genlock_delay()
+ *
+ * This routine sets the delay between VIP VSYNC and display controller VSYNC.
+ * The delay is in 27 MHz clocks.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_genlock_delay(unsigned long delay)
+#else
+int
+gfx_set_genlock_delay(unsigned long delay)
+#endif
+{
+ /* SET SC1200 GENLOCK DELAY */
+ WRITE_VID32(SC1200_GENLOCK_DELAY, delay & SC1200_GENLOCK_DELAY_MASK);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_genlock_enable()
+ *
+ * This routine sets and configures the genlock according to the flags
+ * parameter.
+ * Flags value of 0 disables genlock and resets its configuration.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_genlock_enable(int flags)
+#else
+int
+gfx_set_genlock_enable(int flags)
+#endif
+{
+ unsigned long genlock = 0;
+
+ if (flags) {
+ /* SET SC1200 GENLOCK CONFIGURATION */
+ if (flags & GENLOCK_SINGLE)
+ genlock |= SC1200_GENLOCK_SINGLE_ENABLE;
+ if (flags & GENLOCK_FIELD_SYNC)
+ genlock |= SC1200_GENLOCK_FIELD_SYNC_ENABLE;
+ if (flags & GENLOCK_CONTINUOUS)
+ genlock |= SC1200_GENLOCK_CONTINUOUS_ENABLE;
+ if (flags & GENLOCK_SYNCED_EDGE_FALLING)
+ genlock |= SC1200_GENLOCK_GX_VSYNC_FALLING_EDGE;
+ if (flags & GENLOCK_SYNCING_EDGE_FALLING)
+ genlock |= SC1200_GENLOCK_VIP_VSYNC_FALLING_EDGE;
+ if (flags & GENLOCK_TIMEOUT)
+ genlock |= SC1200_GENLOCK_TIMEOUT_ENABLE;
+ if (flags & GENLOCK_TVENC_RESET_EVEN_FIELD)
+ genlock |= SC1200_GENLOCK_TVENC_RESET_EVEN_FIELD;
+ if (flags & GENLOCK_TVENC_RESET_BEFORE_DELAY)
+ genlock |= SC1200_GENLOCK_TVENC_RESET_BEFORE_DELAY;
+ if (flags & GENLOCK_TVENC_RESET)
+ genlock |= SC1200_GENLOCK_TVENC_RESET_ENABLE;
+ if (flags & GENLOCK_SYNC_TO_TVENC)
+ genlock |= SC1200_GENLOCK_SYNC_TO_TVENC;
+ }
+ WRITE_VID32(SC1200_GENLOCK, genlock);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_cursor()
+ *
+ * This routine configures the video hardware cursor.
+ * If the "mask"ed bits in the graphics pixel match "key", then either
+ * "color1" or "color2" will be used for this pixel, according to the value of
+ * bit number "select_color2" of the graphics pixel.
+ *
+ * key - 24 bit RGB value
+ * mask - 24 bit mask
+ * color1, color2 - RGB or YUV, depending on the current color space
+ * conversion select_color2 - value between 0 to 23
+ *
+ * To disable match, a "mask" and "key" value of 0xffffff should be set,
+ * because the graphics pixels incoming to the video processor have maximum 16
+ * bits set (0xF8FCF8).
+ *
+ * This feature is useful for disabling alpha blending of the cursor.
+ * Otherwise cursor image would be blurred (or completely invisible if video
+ * alpha is maximum value).
+ * Note: the cursor pixel replacements take place both inside and outside the
+ * video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2)
+#else
+int
+gfx_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2)
+#endif
+{
+ if (select_color2 > SC1200_CURSOR_COLOR_BITS)
+ return GFX_STATUS_BAD_PARAMETER;
+ key =
+ (key & SC1200_COLOR_MASK) | ((unsigned long)select_color2 <<
+ SC1200_CURSOR_COLOR_KEY_OFFSET_POS);
+ WRITE_VID32(SC1200_CURSOR_COLOR_KEY, key);
+ WRITE_VID32(SC1200_CURSOR_COLOR_MASK, mask);
+ WRITE_VID32(SC1200_CURSOR_COLOR_1, color1);
+ WRITE_VID32(SC1200_CURSOR_COLOR_2, color2);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_enable
+ *
+ * This routine enables or disables the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_alpha_enable(int enable)
+#else
+int
+gfx_set_alpha_enable(int enable)
+#endif
+{
+ unsigned long address = 0, value = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4);
+ value = READ_VID32(address);
+ if (enable)
+ value |= (SC1200_ACTRL_WIN_ENABLE | SC1200_ACTRL_LOAD_ALPHA);
+ else
+ value &= ~(SC1200_ACTRL_WIN_ENABLE);
+ WRITE_VID32(address, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_window
+ *
+ * This routine sets the size of the currently selected alpha region.
+ * Note: "x" and "y" are signed to enable using negative values needed for
+ * implementing workarounds of hardware issues.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height)
+#else
+int
+gfx_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long address = 0;
+
+ /* CHECK FOR CLIPPING */
+
+ if ((x + width) > gfx_get_hactive())
+ width = gfx_get_hactive() - x;
+ if ((y + height) > gfx_get_vactive())
+ height = gfx_get_vactive() - y;
+
+ /* ADJUST POSITIONS */
+
+ x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = SC1200_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 4);
+
+ /* End positions in register are non-inclusive (one more than the actual
+ * end) */
+
+ WRITE_VID32(address, (unsigned long)x |
+ ((unsigned long)(x + width) << 16));
+ WRITE_VID32(address + 4l, (unsigned long)y |
+ ((unsigned long)(y + height) << 16));
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_value
+ *
+ * This routine sets the alpha value for the currently selected alpha
+ * region. It also specifies an increment/decrement value for fading.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_alpha_value(unsigned char alpha, char delta)
+#else
+int
+gfx_set_alpha_value(unsigned char alpha, char delta)
+#endif
+{
+ unsigned long address = 0, value = 0;
+ unsigned char new_value = 0;
+ int loop = 1;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = SC1200_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 4);
+ value = READ_VID32(address);
+ value &= SC1200_ACTRL_WIN_ENABLE; /* keep only enable bit */
+ value |= (unsigned long)alpha;
+ value |= (((unsigned long)delta) & 0xff) << 8;
+ value |= SC1200_ACTRL_LOAD_ALPHA;
+ WRITE_VID32(address, value);
+
+ /* WORKAROUND FOR ISSUE #1187 */
+ /* Need to verify that the alpha operation succeeded */
+
+ while (1) {
+ /* WAIT FOR VERTICAL BLANK TO END */
+ if (gfx_test_timing_active()) {
+ if (gfx_test_vertical_active())
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+ }
+ new_value =
+ (unsigned char)((READ_VID32(SC1200_ALPHA_WATCH) >>
+ (gfx_alpha_select << 3)) & 0xff);
+ if (new_value == alpha)
+ return GFX_STATUS_OK;
+ if (++loop > 10)
+ return GFX_STATUS_ERROR;
+ WRITE_VID32(address, value);
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_priority
+ *
+ * This routine sets the priority of the currently selected alpha region.
+ * A higher value indicates a higher priority.
+ * Note: Priority of enabled alpha windows must be different.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_alpha_priority(int priority)
+#else
+int
+gfx_set_alpha_priority(int priority)
+#endif
+{
+ unsigned long pos = 0, value = 0;
+
+ if (priority > 3)
+ return (GFX_STATUS_BAD_PARAMETER);
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ value = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ pos = 16 + (gfx_alpha_select << 1);
+ value &= ~(0x03l << pos);
+ value |= (unsigned long)priority << pos;
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color
+ *
+ * This routine sets the color to be displayed inside the currently selected
+ * alpha window when there is a color key match (when the alpha color
+ * mechanism is enabled).
+ * "color" is a 24 bit RGB value (for RGB blending) or YUV value (for YUV
+ * blending).
+ * In Interlaced YUV blending mode, Y/2 value should be used.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_alpha_color(unsigned long color)
+#else
+int
+gfx_set_alpha_color(unsigned long color)
+#endif
+{
+ unsigned long address = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4);
+
+ /* ONLY 24 VALID BITS */
+ color &= 0xffffffl;
+
+ /* KEEP UPPER BYTE UNCHANGED */
+ WRITE_VID32(address, (color | (READ_VID32(address) & ~0xffffffl)));
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color_enable
+ *
+ * Enable or disable the color mechanism in the alpha window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_alpha_color_enable(int enable)
+#else
+int
+gfx_set_alpha_color_enable(int enable)
+#endif
+{
+ unsigned long color;
+ unsigned long address = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = SC1200_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 4);
+ color = READ_VID32(address);
+ if (enable)
+ color |= SC1200_ALPHA_COLOR_ENABLE;
+ else
+ color &= ~SC1200_ALPHA_COLOR_ENABLE;
+ WRITE_VID32(address, color);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_no_ck_outside_alpha
+ *
+ * This function affects where inside the video window color key or chroma
+ * key comparison is done:
+ * If enable is TRUE, color/chroma key comparison is performed only inside
+ * the enabled alpha windows. Outside the (enabled) alpha windows, only video
+ * is displayed if color key is used, and only graphics is displayed if chroma
+ * key is used.
+ * If enable is FALSE, color/chroma key comparison is performed in all the
+ * video window area.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_no_ck_outside_alpha(int enable)
+#else
+int
+gfx_set_no_ck_outside_alpha(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ if (enable)
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
+ value | SC1200_NO_CK_OUTSIDE_ALPHA);
+ else
+ WRITE_VID32(SC1200_VID_ALPHA_CONTROL,
+ value & ~SC1200_NO_CK_OUTSIDE_ALPHA);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_macrovision_enable
+ *
+ * This routine enables or disables macrovision on the tv encoder output.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_set_macrovision_enable(int enable)
+#else
+int
+gfx_set_macrovision_enable(int enable)
+#endif
+{
+ if (enable)
+ WRITE_VID32(SC1200_TVENC_MV_CONTROL, SC1200_TVENC_MV_ENABLE);
+ else
+ WRITE_VID32(SC1200_TVENC_MV_CONTROL, 0);
+ return (GFX_STATUS_OK);
+}
+
+#define SC1200_VIDEO_PCI_44 0x80009444
+
+/*---------------------------------------------------------------------------
+ * gfx_disable_softvga
+ *
+ * Disables SoftVga. This function is only valid with VSA2, Returns 1 if
+ * SoftVga can be disabled; 0 if not.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_disable_softvga(void)
+#else
+int
+gfx_disable_softvga(void)
+#endif
+{
+ unsigned long reg_val;
+
+ /* get the current value */
+ reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
+ /* setting video PCI register 44 bit 0 to 1 disables SoftVga */
+ reg_val |= 0x1;
+ gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val);
+
+ /* see if we set the bit and return the appropriate value */
+ reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
+ if ((reg_val & 0x1) == 0x1)
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_softvga
+ *
+ * Enables SoftVga. This function is only valid with VSA2, Returns 1 if
+ * SoftVga can be enbled; 0 if not.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_enable_softvga(void)
+#else
+int
+gfx_enable_softvga(void)
+#endif
+{
+ unsigned long reg_val;
+
+ /* get the current value */
+ reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
+ /* clearing video PCI register 44 bit 0 enables SoftVga */
+ gfx_pci_config_write(SC1200_VIDEO_PCI_44, reg_val & 0xfffffffel);
+
+ /* see if we cleared the bit and return the appropriate value */
+ reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
+ if ((reg_val & 0x1) == 0)
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+sc1200_get_clock_frequency(void)
+#else
+unsigned long
+gfx_get_clock_frequency(void)
+#endif
+{
+ unsigned int index;
+ unsigned long value, mask;
+
+ mask = 0x007FFF0F;
+ value = READ_VID32(SC1200_VID_CLOCK_SELECT) & mask;
+ for (index = 0; index < NUM_SC1200_FREQUENCIES; index++) {
+ if ((gfx_sc1200_clock_table[index].clock_select & mask) == value)
+ return (gfx_sc1200_clock_table[index].frequency);
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_video_width
+ *
+ * This routine returns the maximum theoretical video width for the current
+ * display mode.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_max_video_width(void)
+#else
+unsigned long
+gfx_get_max_video_width(void)
+#endif
+{
+ /* RETURN MPEG2 MAXIMUM */
+
+ return 720;
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsa2_softvga_enable
+ *
+ * This function returns the enable status of SoftVGA. It is valid
+ * only if VSAII is present.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_vsa2_softvga_enable(void)
+#else
+int
+gfx_get_vsa2_softvga_enable(void)
+#endif
+{
+ unsigned long reg_val;
+
+ reg_val = gfx_pci_config_read(SC1200_VIDEO_PCI_44);
+ if ((reg_val & 0x1) == 0)
+ return (1);
+ else
+ return (0);
+
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+sc1200_get_sync_polarities(void)
+#else
+int
+gfx_get_sync_polarities(void)
+#endif
+{
+ int polarities = 0;
+
+ if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_HSYNC_POL)
+ polarities |= 1;
+ if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_DCFG_CRT_VSYNC_POL)
+ polarities |= 2;
+ return (polarities);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_palette_entry
+ *
+ * This routine returns a single palette entry.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int
+gfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* READ A SINGLE ENTRY */
+
+ WRITE_VID32(SC1200_PALETTE_ADDRESS, index);
+ *palette = READ_VID32(SC1200_PALETTE_DATA);
+
+ return (GFX_STATUS_OK);
+}
+
+/*-----------------------------------------------------------------------------
+ * 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
+sc1200_get_video_enable(void)
+#else
+int
+gfx_get_video_enable(void)
+#endif
+{
+ if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_VID_EN)
+ return (1);
+ return (0);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_video_format
+ *
+ * This routine returns the current video overlay format.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_video_format(void)
+#else
+int
+gfx_get_video_format(void)
+#endif
+{
+ unsigned long ctrl, vcfg;
+
+ ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
+
+ if (ctrl & SC1200_VIDEO_INPUT_IS_RGB) {
+ switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) {
+ case SC1200_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_RGB;
+ case SC1200_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_P2M_P2L_P1M_P1L;
+ case SC1200_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_P1M_P1L_P2M_P2L;
+ case SC1200_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_P1M_P2L_P2M_P1L;
+ }
+ }
+
+ if (vcfg & SC1200_VCFG_4_2_0_MODE) {
+ switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) {
+ case SC1200_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_Y0Y1Y2Y3;
+ case SC1200_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_Y3Y2Y1Y0;
+ case SC1200_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_Y1Y0Y3Y2;
+ case SC1200_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_Y1Y2Y3Y0;
+ }
+ } else {
+ switch (vcfg & SC1200_VCFG_VID_INP_FORMAT) {
+ case SC1200_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_UYVY;
+ case SC1200_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_Y2YU;
+ case SC1200_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_YUYV;
+ case SC1200_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_YVYU;
+ }
+ }
+ return (GFX_STATUS_ERROR);
+}
+
+/*----------------------------------------------------------------------------
+ * 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
+sc1200_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 SC1200 VIDEO LINE SIZE */
+
+ width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+
+ 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
+sc1200_get_video_line_size(void)
+#else
+unsigned long
+gfx_get_video_line_size(void)
+#endif
+{
+ unsigned long width = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */
+
+ width = (READ_VID32(SC1200_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+ 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
+sc1200_get_video_xclip(void)
+#else
+unsigned long
+gfx_get_video_xclip(void)
+#endif
+{
+ unsigned long clip = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE SC1200 VIDEO LINE SIZE */
+
+ clip = (READ_VID32(SC1200_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
+sc1200_get_video_offset(void)
+#else
+unsigned long
+gfx_get_video_offset(void)
+#endif
+{
+ return (gfx_get_display_video_offset());
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_upscale
+ *
+ * This routine returns the scale factor for the video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_video_upscale(void)
+#else
+unsigned long
+gfx_get_video_upscale(void)
+#endif
+{
+ return (READ_VID32(SC1200_VIDEO_UPSCALE));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_scale
+ *
+ * This routine returns the scale factor for the video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_video_scale(void)
+#else
+unsigned long
+gfx_get_video_scale(void)
+#endif
+{
+ return gfx_get_video_upscale();
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_config
+ *
+ * This routine returns the current type and value of video downscaling.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_video_downscale_config(unsigned short *type, unsigned short *m)
+#else
+int
+gfx_get_video_downscale_config(unsigned short *type, unsigned short *m)
+#endif
+{
+ unsigned long downscale;
+
+ downscale = READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL);
+ *m = (unsigned short)((downscale & SC1200_VIDEO_DOWNSCALE_FACTOR_MASK) >>
+ SC1200_VIDEO_DOWNSCALE_FACTOR_POS) + 1;
+
+ switch (downscale & SC1200_VIDEO_DOWNSCALE_TYPE_MASK) {
+ case SC1200_VIDEO_DOWNSCALE_TYPE_A:
+ *type = VIDEO_DOWNSCALE_KEEP_1_OF;
+ break;
+ case SC1200_VIDEO_DOWNSCALE_TYPE_B:
+ *type = VIDEO_DOWNSCALE_DROP_1_OF;
+ break;
+ default:
+ return GFX_STATUS_ERROR;
+ break;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_coefficients
+ *
+ * This routine returns the current video downscaling coefficients.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+sc1200_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4)
+#else
+void
+gfx_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4)
+#endif
+{
+ unsigned long coef;
+
+ coef = READ_VID32(SC1200_VIDEO_DOWNSCALER_COEFFICIENTS);
+ *coef1 =
+ (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF1_POS) &
+ SC1200_VIDEO_DOWNSCALER_COEF_MASK);
+ *coef2 =
+ (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF2_POS) &
+ SC1200_VIDEO_DOWNSCALER_COEF_MASK);
+ *coef3 =
+ (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF3_POS) &
+ SC1200_VIDEO_DOWNSCALER_COEF_MASK);
+ *coef4 =
+ (unsigned short)((coef >> SC1200_VIDEO_DOWNSCALER_COEF4_POS) &
+ SC1200_VIDEO_DOWNSCALER_COEF_MASK);
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_enable
+ *
+ * This routine returns 1 if video downscaling is currently enabled,
+ * or 0 if it is currently disabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+sc1200_get_video_downscale_enable(int *enable)
+#else
+void
+gfx_get_video_downscale_enable(int *enable)
+#endif
+{
+ if (READ_VID32(SC1200_VIDEO_DOWNSCALER_CONTROL) &
+ SC1200_VIDEO_DOWNSCALE_ENABLE)
+ *enable = 1;
+ else
+ *enable = 0;
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_dst_size
+ *
+ * This routine returns the size of the displayed video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_video_dst_size(void)
+#else
+unsigned long
+gfx_get_video_dst_size(void)
+#endif
+{
+ unsigned long xsize, ysize;
+
+ xsize = READ_VID32(SC1200_VIDEO_X_POS);
+ xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF);
+ ysize = READ_VID32(SC1200_VIDEO_Y_POS);
+ ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF);
+ 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
+sc1200_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(SC1200_VIDEO_X_POS) & 0x000007FF;
+ ypos = READ_VID32(SC1200_VIDEO_Y_POS) & 0x000007FF;
+
+ /* GET ADJUSTMENT VALUES */
+ /* Use routines to abstract version of display controller. */
+
+ hadjust =
+ (unsigned long)gfx_get_htotal() - (unsigned long)gfx_get_hsync_end() -
+ 14l;
+ vadjust =
+ (unsigned long)gfx_get_vtotal() - (unsigned long)gfx_get_vsync_end() +
+ 1l;
+ 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
+sc1200_get_video_color_key(void)
+#else
+unsigned long
+gfx_get_video_color_key(void)
+#endif
+{
+ return (READ_VID32(SC1200_VIDEO_COLOR_KEY));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key_mask
+ *
+ * This routine returns the current video color mask value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_video_color_key_mask(void)
+#else
+unsigned long
+gfx_get_video_color_key_mask(void)
+#endif
+{
+ return (READ_VID32(SC1200_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
+sc1200_get_video_color_key_src(void)
+#else
+int
+gfx_get_video_color_key_src(void)
+#endif
+{
+ if (READ_VID32(SC1200_DISPLAY_CONFIG) & SC1200_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
+sc1200_get_video_filter(void)
+#else
+int
+gfx_get_video_filter(void)
+#endif
+{
+ int retval = 0;
+
+ if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_X_FILTER_EN)
+ retval |= 1;
+ if (READ_VID32(SC1200_VIDEO_CONFIG) & SC1200_VCFG_Y_FILTER_EN)
+ retval |= 2;
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_request
+ *
+ * This routine returns the horizontal (pixel) and vertical (lines) video
+ * request values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_video_request(short *x, short *y)
+#else
+int
+gfx_get_video_request(short *x, short *y)
+#endif
+{
+ int request = 0;
+
+ request = (int)(READ_VID32(SC1200_VIDEO_REQUEST));
+ *x = (request >> SC1200_VIDEO_X_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK;
+ *y = (request >> SC1200_VIDEO_Y_REQUEST_POS) & SC1200_VIDEO_REQUEST_MASK;
+
+ *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_source
+ *
+ * This routine returns the current video source.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_video_source(VideoSourceType * source)
+#else
+int
+gfx_get_video_source(VideoSourceType * source)
+#endif
+{
+ switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VIDEO_SOURCE_MASK) {
+ case SC1200_VIDEO_SOURCE_GX1:
+ *source = VIDEO_SOURCE_MEMORY;
+ break;
+ case SC1200_VIDEO_SOURCE_DVIP:
+ *source = VIDEO_SOURCE_DVIP;
+ break;
+ default:
+ return GFX_STATUS_ERROR;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vbi_source
+ *
+ * This routine returns the current vbi source.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_vbi_source(VbiSourceType * source)
+#else
+int
+gfx_get_vbi_source(VbiSourceType * source)
+#endif
+{
+ switch (READ_VID32(SC1200_VIDEO_DISPLAY_MODE) & SC1200_VBI_SOURCE_MASK) {
+ case SC1200_VBI_SOURCE_GX1:
+ *source = VBI_SOURCE_MEMORY;
+ break;
+ case SC1200_VBI_SOURCE_DVIP:
+ *source = VBI_SOURCE_DVIP;
+ break;
+ default:
+ return GFX_STATUS_ERROR;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vbi_lines
+ *
+ * This routine returns the VBI lines which are sent to the TV encoder.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_vbi_lines(int odd)
+#else
+unsigned long
+gfx_get_vbi_lines(int odd)
+#endif
+{
+ if (odd)
+ return (READ_VID32(SC1200_VIDEO_ODD_VBI_LINE_ENABLE) &
+ SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
+ return (READ_VID32(SC1200_VIDEO_EVEN_VBI_LINE_ENABLE) &
+ SC1200_VIDEO_VBI_LINE_ENABLE_MASK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vbi_total
+ *
+ * This routine returns the total number of VBI bytes in the field.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_vbi_total(int odd)
+#else
+unsigned long
+gfx_get_vbi_total(int odd)
+#endif
+{
+ if (odd)
+ return (READ_VID32(SC1200_VIDEO_ODD_VBI_TOTAL_COUNT) &
+ SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
+ return (READ_VID32(SC1200_VIDEO_EVEN_VBI_TOTAL_COUNT) &
+ SC1200_VIDEO_VBI_TOTAL_COUNT_MASK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_interlaced()
+ *
+ * This routine returns "1" if input video is currently in interlaced mode.
+ * "0" otherwise.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_video_interlaced(void)
+#else
+int
+gfx_get_video_interlaced(void)
+#endif
+{
+ if (READ_VID32(SC1200_VID_ALPHA_CONTROL) & SC1200_VIDEO_IS_INTERLACED)
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_color_space_YUV()
+ *
+ * This routine returns "1" if video processor color space mode is currently
+ * YUV. "0" otherwise.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_color_space_YUV(void)
+#else
+int
+gfx_get_color_space_YUV(void)
+#endif
+{
+ unsigned long control;
+
+ control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+
+ /* IS SC1200 VIDEO COLOR SPACE RGB OR CONVERTED TO RGB */
+ if ((control & SC1200_VIDEO_INPUT_IS_RGB)
+ || (control & SC1200_CSC_VIDEO_YUV_TO_RGB))
+ return (0);
+ else
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vertical_scaler_offset()
+ *
+ * This routine sets "offset" to the value by which odd frames are shifted,
+ * if insert is enabled, and to 0 if no shifting occurs.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_vertical_scaler_offset(char *offset)
+#else
+int
+gfx_get_vertical_scaler_offset(char *offset)
+#endif
+{
+ unsigned long control;
+
+ control = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ if (control & SC1200_VERTICAL_SCALER_SHIFT_EN) {
+ if ((control & SC1200_VERTICAL_SCALER_SHIFT_MASK) ==
+ SC1200_VERTICAL_SCALER_SHIFT_INIT)
+ *offset = 1;
+ else
+ return GFX_STATUS_ERROR;
+ /* TODO: find the interpretation of other values */
+ } else
+ *offset = 0;
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_genlock_delay
+ *
+ * This routine returns the genlock delay in 27 MHz clocks.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+sc1200_get_genlock_delay(void)
+#else
+unsigned long
+gfx_get_genlock_delay(void)
+#endif
+{
+ return (READ_VID32(SC1200_GENLOCK_DELAY) & SC1200_GENLOCK_DELAY_MASK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_genlock_enable
+ *
+ * This routine returns "1" if genlock is currently enabled, "0" otherwise.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_genlock_enable(void)
+#else
+int
+gfx_get_genlock_enable(void)
+#endif
+{
+ if (READ_VID32(SC1200_GENLOCK) &
+ (SC1200_GENLOCK_SINGLE_ENABLE | SC1200_GENLOCK_CONTINUOUS_ENABLE))
+ return (1);
+ else
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_cursor()
+ *
+ * This routine configures the video hardware cursor.
+ * If the "mask"ed bits in the graphics pixel match "key", then either
+ * "color1" or "color2" will be used for this pixel, according to the value of
+ * the bit in offset "select_color2".
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2)
+#else
+int
+gfx_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2)
+#endif
+{
+ *select_color2 =
+ (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_KEY) >>
+ SC1200_CURSOR_COLOR_KEY_OFFSET_POS);
+ *key = READ_VID32(SC1200_CURSOR_COLOR_KEY) & SC1200_COLOR_MASK;
+ *mask = READ_VID32(SC1200_CURSOR_COLOR_MASK) & SC1200_COLOR_MASK;
+ *color1 = READ_VID32(SC1200_CURSOR_COLOR_1) & SC1200_COLOR_MASK;
+ *color2 =
+ (unsigned short)(READ_VID32(SC1200_CURSOR_COLOR_2) &
+ SC1200_COLOR_MASK);
+ 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
+sc1200_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(SC1200_VID_CRC, 0);
+ WRITE_VID32(SC1200_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(SC1200_VID_CRC) >> 8;
+ }
+ return (crc);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_macrovision_enable
+ *
+ * This routine returns the value "one" if macrovision currently enabled in
+ * the TV encoder, otherwise it returns the value "zero".
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+sc1200_get_macrovision_enable(void)
+#else
+int
+gfx_get_macrovision_enable(void)
+#endif
+{
+ if (READ_VID32(SC1200_TVENC_MV_CONTROL) == SC1200_TVENC_MV_ENABLE)
+ return (1);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_enable
+ *
+ * This routine returns 1 if the selected alpha window is currently
+ * enabled, or 0 if it is currently disabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+sc1200_get_alpha_enable(int *enable)
+#else
+void
+gfx_get_alpha_enable(int *enable)
+#endif
+{
+ unsigned long value = 0;
+
+ *enable = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(SC1200_ALPHA_CONTROL_1 +
+ ((unsigned long)gfx_alpha_select << 4));
+ if (value & SC1200_ACTRL_WIN_ENABLE)
+ *enable = 1;
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_size
+ *
+ * This routine returns the size of the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+sc1200_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height)
+#else
+void
+gfx_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height)
+#endif
+{
+ unsigned long value = 0;
+
+ *x = 0;
+ *y = 0;
+ *width = 0;
+ *height = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(SC1200_ALPHA_XPOS_1 +
+ ((unsigned long)gfx_alpha_select << 4));
+ *x = (unsigned short)(value & 0x000007FF);
+ *width = (unsigned short)((value >> 16) & 0x000007FF) - *x;
+ value =
+ READ_VID32(SC1200_ALPHA_YPOS_1 +
+ ((unsigned long)gfx_alpha_select << 4));
+ *y = (unsigned short)(value & 0x000007FF);
+ *height = (unsigned short)((value >> 16) & 0x000007FF) - *y;
+ }
+ *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_value
+ *
+ * This routine returns the alpha value and increment/decrement value of
+ * the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+sc1200_get_alpha_value(unsigned char *alpha, char *delta)
+#else
+void
+gfx_get_alpha_value(unsigned char *alpha, char *delta)
+#endif
+{
+ unsigned long value = 0;
+
+ *alpha = 0;
+ *delta = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(SC1200_ALPHA_CONTROL_1 +
+ ((unsigned long)gfx_alpha_select << 4));
+ *alpha = (unsigned char)(value & 0x00FF);
+ *delta = (char)((value >> 8) & 0x00FF);
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_priority
+ *
+ * This routine returns the priority of the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+sc1200_get_alpha_priority(int *priority)
+#else
+void
+gfx_get_alpha_priority(int *priority)
+#endif
+{
+ unsigned long pos = 0, value = 0;
+
+ *priority = 0;
+ if (gfx_alpha_select <= 2) {
+ value = READ_VID32(SC1200_VID_ALPHA_CONTROL);
+ pos = 16 + (gfx_alpha_select << 1);
+ *priority = (int)((value >> pos) & 3);
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_color
+ *
+ * This routine returns the color register value for the currently selected
+ * alpha region. Bit 24 is set if the color register is enabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+sc1200_get_alpha_color(unsigned long *color)
+#else
+void
+gfx_get_alpha_color(unsigned long *color)
+#endif
+{
+ *color = 0;
+ if (gfx_alpha_select <= 2) {
+ *color =
+ READ_VID32(SC1200_ALPHA_COLOR_1 +
+ ((unsigned long)gfx_alpha_select << 4));
+ }
+ return;
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/vid_5530.c b/src/gfx/vid_5530.c
new file mode 100644
index 0000000..40e3ffc
--- /dev/null
+++ b/src/gfx/vid_5530.c
@@ -0,0 +1,1354 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the CS5530 video overlay hardware.
+ */
+
+/*----------------------------------------------------------------------------
+ * CS5530 PLL TABLE
+ *----------------------------------------------------------------------------
+ */
+typedef struct tagCS5530PLLENTRY
+{
+ long frequency; /* 16.16 fixed point frequency */
+ unsigned long pll_value; /* associated register value */
+} CS5530PLLENTRY;
+
+CS5530PLLENTRY CS5530_PLLtable[] = {
+ {0x00192CCC, 0x31C45801,}, /* 25.1750 */
+ {0x001C526E, 0x20E36802,}, /* 28.3220 */
+ {0x001F8000, 0x33915801,}, /* 31.5000 */
+ {0x00240000, 0x31EC4801,}, /* 36.0000 */
+ {0x00258000, 0x21E22801,}, /* 37.5000 */
+ {0x00280000, 0x33088801,}, /* 40.0000 */
+ {0x002CE666, 0x33E22801,}, /* 44.9000 */
+ {0x00318000, 0x336C4801,}, /* 49.5000 */
+ {0x00320000, 0x23088801,}, /* 50.0000 */
+ {0x00325999, 0x23088801,}, /* 50.3500 */
+ {0x00360000, 0x3708A801,}, /* 54.0000 */
+ {0x00384000, 0x23E36802,}, /* 56.2500 */
+ {0x0038643F, 0x23E36802,}, /* 56.3916 */
+ {0x0038A4DD, 0x23E36802,}, /* 56.6444 */
+ {0x003B0000, 0x37C45801,}, /* 59.0000 */
+ {0x003F0000, 0x23EC4801,}, /* 63.0000 */
+ {0x00410000, 0x37911801,}, /* 65.0000 */
+ {0x00438000, 0x37963803,}, /* 67.5000 */
+ {0x0046CCCC, 0x37058803,}, /* 70.8000 */
+ {0x00480000, 0x3710C805,}, /* 72.0000 */
+ {0x004B0000, 0x37E22801,}, /* 75.0000 */
+ {0x004EC000, 0x27915801,}, /* 78.7500 */
+ {0x00500000, 0x37D8D802,}, /* 80.0000 */
+ {0x0059CCCC, 0x27588802,}, /* 89.8000 */
+ {0x005E8000, 0x27EC4802,}, /* 94.5000 */
+ {0x00630000, 0x27AC6803,}, /* 99.0000 */
+ {0x00640000, 0x27088801,}, /* 100.0000 */
+ {0x006C0000, 0x2710C805,}, /* 108.0000 */
+ {0x00708000, 0x27E36802,}, /* 112.5000 */
+ {0x00820000, 0x27C58803,}, /* 130.0000 */
+ {0x00870000, 0x27316803,}, /* 135.0000 */
+ {0x009D8000, 0x2F915801,}, /* 157.5000 */
+ {0x00A20000, 0x2F08A801,}, /* 162.0000 */
+ {0x00AF0000, 0x2FB11802,}, /* 175.0000 */
+ {0x00BD0000, 0x2FEC4802,}, /* 189.0000 */
+ {0x00CA0000, 0x2F963803,}, /* 202.0000 */
+ {0x00E80000, 0x2FB1B802,}, /* 232.0000 */
+};
+
+#define NUM_CS5530_FREQUENCIES sizeof(CS5530_PLLtable)/sizeof(CS5530PLLENTRY)
+
+/*---------------------------------------------------------------------------
+ * gfx_set_crt_enable
+ *
+ * This routine enables or disables the CRT output from the video processor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_set_crt_enable(int enable)
+#else
+int
+gfx_set_crt_enable(int enable)
+#endif
+{
+ unsigned long config;
+
+ config = READ_VID32(CS5530_DISPLAY_CONFIG);
+
+ switch (enable) {
+ case CRT_DISABLE: /* Disable everything */
+
+ WRITE_VID32(CS5530_DISPLAY_CONFIG,
+ config & ~(CS5530_DCFG_DIS_EN | CS5530_DCFG_HSYNC_EN |
+ CS5530_DCFG_VSYNC_EN | CS5530_DCFG_DAC_BL_EN |
+ CS5530_DCFG_DAC_PWDNX));
+ break;
+
+ case CRT_ENABLE: /* Enable CRT display, including display logic */
+
+ WRITE_VID32(CS5530_DISPLAY_CONFIG,
+ config | CS5530_DCFG_DIS_EN | CS5530_DCFG_HSYNC_EN |
+ CS5530_DCFG_VSYNC_EN | CS5530_DCFG_DAC_BL_EN |
+ CS5530_DCFG_DAC_PWDNX);
+ break;
+
+ case CRT_STANDBY: /* HSync:Off VSync:On */
+
+ WRITE_VID32(CS5530_DISPLAY_CONFIG,
+ (config & ~(CS5530_DCFG_DIS_EN | CS5530_DCFG_HSYNC_EN |
+ CS5530_DCFG_DAC_BL_EN | CS5530_DCFG_DAC_PWDNX))
+ | CS5530_DCFG_VSYNC_EN);
+ break;
+
+ case CRT_SUSPEND: /* HSync:On VSync:Off */
+
+ WRITE_VID32(CS5530_DISPLAY_CONFIG,
+ (config & ~(CS5530_DCFG_DIS_EN | CS5530_DCFG_VSYNC_EN |
+ CS5530_DCFG_DAC_BL_EN | CS5530_DCFG_DAC_PWDNX))
+ | CS5530_DCFG_HSYNC_EN);
+ break;
+
+ default:
+ return (GFX_STATUS_BAD_PARAMETER);
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+cs5530_reset_video(void)
+#else
+void
+gfx_reset_video(void)
+#endif
+{
+ gfx_set_video_enable(0);
+
+ /* CLEAR THE DISPLAY BUFFER SIZE TO ZERO */
+ /* During a modeset,if FIFO load is enabled with a large buffer size, */
+ /* the FIFO can hang. To prevent this, we set the buffer size to zero */
+ /* and wait for this new size to be latched */
+
+ gfx_set_display_video_size(0, 0);
+
+ if (gfx_test_timing_active()) {
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
+ *
+ * This routine configures the display output.
+ *
+ * "sync_polarities" is used to set the polarities of the sync pulses
+ * according to the following mask:
+ *
+ * Bit 0: If set to 1, negative horizontal polarity is programmed,
+ * otherwise positive horizontal polarity is programmed.
+ * Bit 1: If set to 1, negative vertical polarity is programmed,
+ * otherwise positive vertical polarity is programmed.
+ *
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_set_display_control(int sync_polarities)
+#else
+int
+gfx_set_display_control(int sync_polarities)
+#endif
+{
+ unsigned long dcfg;
+
+ /* ENABLE DISPLAY OUTPUT FROM CX5530 */
+
+ dcfg = READ_VID32(CS5530_DISPLAY_CONFIG);
+
+ /* CLEAR RELEVANT FIELDS */
+
+ dcfg &= ~(CS5530_DCFG_CRT_SYNC_SKW_MASK | CS5530_DCFG_PWR_SEQ_DLY_MASK |
+ CS5530_DCFG_CRT_HSYNC_POL | CS5530_DCFG_CRT_VSYNC_POL |
+ CS5530_DCFG_FP_PWR_EN | CS5530_DCFG_FP_DATA_EN);
+
+ /* INITIALIZATION */
+
+ dcfg |= (CS5530_DCFG_CRT_SYNC_SKW_INIT |
+ CS5530_DCFG_PWR_SEQ_DLY_INIT | CS5530_DCFG_GV_PAL_BYP);
+
+ if (PanelEnable) {
+ dcfg |= CS5530_DCFG_FP_PWR_EN;
+ dcfg |= CS5530_DCFG_FP_DATA_EN;
+ }
+
+ /* SET APPROPRIATE SYNC POLARITIES */
+
+ if (sync_polarities & 1)
+ dcfg |= CS5530_DCFG_CRT_HSYNC_POL;
+ if (sync_polarities & 2)
+ dcfg |= CS5530_DCFG_CRT_VSYNC_POL;
+
+ WRITE_VID32(CS5530_DISPLAY_CONFIG, dcfg);
+ return (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
+cs5530_set_clock_frequency(unsigned long frequency)
+#else
+void
+gfx_set_clock_frequency(unsigned long frequency)
+#endif
+{
+ unsigned 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 = CS5530_PLLtable[0].pll_value;
+ min = (long)CS5530_PLLtable[0].frequency - frequency;
+ if (min < 0L)
+ min = -min;
+ for (index = 1; index < NUM_CS5530_FREQUENCIES; index++) {
+ diff = (long)CS5530_PLLtable[index].frequency - frequency;
+ if (diff < 0L)
+ diff = -diff;
+ if (diff < min) {
+ min = diff;
+ value = CS5530_PLLtable[index].pll_value;
+ }
+ }
+
+ /* SET THE DOT CLOCK REGISTER */
+
+ WRITE_VID32(CS5530_DOT_CLK_CONFIG, value);
+ WRITE_VID32(CS5530_DOT_CLK_CONFIG, value | 0x80000100);
+ /* set reset/bypass */
+ gfx_delay_milliseconds(1); /* wait for PLL to settle */
+ WRITE_VID32(CS5530_DOT_CLK_CONFIG, value & 0x7FFFFFFF);
+ /* clear reset */
+ WRITE_VID32(CS5530_DOT_CLK_CONFIG, value & 0x7FFFFEFF);
+ /* clear bypass */
+ return;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_enable
+ *
+ * This routine enables or disables the video overlay functionality.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_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(CS5530_VIDEO_CONFIG);
+ if (enable) {
+ /* SET CS5530 BUS CONTROL PARAMETERS */
+ /* Currently always high speed, 8-bit interface. */
+
+ vcfg |= CS5530_VCFG_HIGH_SPD_INT;
+ vcfg &= ~(CS5530_VCFG_EARLY_VID_RDY | CS5530_VCFG_16_BIT_EN);
+
+ /* ENABLE CS5530 VIDEO OVERLAY */
+
+ vcfg |= CS5530_VCFG_VID_EN;
+ WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg);
+ } else {
+ /* DISABLE CS5530 VIDEO OVERLAY */
+
+ vcfg &= ~CS5530_VCFG_VID_EN;
+ WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg);
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_format
+ *
+ * Currently only sets 4:2:0 format, Y1 V Y0 U.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_set_video_format(unsigned long format)
+#else
+int
+gfx_set_video_format(unsigned long format)
+#endif
+{
+ unsigned long vcfg = 0;
+
+ /* SET THE CS5530 VIDEO INPUT FORMAT */
+
+ vcfg = READ_VID32(CS5530_VIDEO_CONFIG);
+ vcfg &= ~(CS5530_VCFG_VID_INP_FORMAT | CS5530_VCFG_4_2_0_MODE);
+ vcfg &= ~(CS5530_VCFG_CSC_BYPASS);
+ vcfg &= ~(CS5530_VCFG_GV_SEL);
+
+ if (format < 4)
+ vcfg |= (format << 2);
+ else {
+ if (format == VIDEO_FORMAT_Y0Y1Y2Y3) {
+ vcfg |= CS5530_VCFG_4_2_0_MODE;
+ vcfg |= 1 << 2;
+ }
+ if (format == VIDEO_FORMAT_RGB) {
+ vcfg |= CS5530_VCFG_CSC_BYPASS;
+ vcfg |= CS5530_VCFG_GV_SEL;
+ }
+ }
+
+ WRITE_VID32(CS5530_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
+cs5530_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 CS5530 VIDEO LINE SIZE */
+
+ vcfg = READ_VID32(CS5530_VIDEO_CONFIG);
+ vcfg &= ~(CS5530_VCFG_LINE_SIZE_LOWER_MASK | CS5530_VCFG_LINE_SIZE_UPPER);
+ size = (width >> 1);
+ vcfg |= (size & 0x00FF) << 8;
+ if (size & 0x0100)
+ vcfg |= CS5530_VCFG_LINE_SIZE_UPPER;
+ WRITE_VID32(CS5530_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
+cs5530_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
+cs5530_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 CS5530 SCALE FACTORS */
+ /* No downscaling in CS5530 so force to 1x if attempted. */
+
+ if (dstw <= srcw)
+ xscale = 0x1FFF;
+ else if (dstw == 1 || srcw == 1)
+ return GFX_STATUS_BAD_PARAMETER;
+ else
+ xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l);
+ if (dsth <= srch)
+ yscale = 0x1FFF;
+ else if (dsth == 1 || srch == 1)
+ return GFX_STATUS_BAD_PARAMETER;
+ else
+ yscale = (0x2000l * (srch - 1l)) / (dsth - 1l);
+ WRITE_VID32(CS5530_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
+cs5530_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 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() - 13l;
+ vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
+
+ /* LEFT CLIPPING */
+
+ if (x < 0) {
+ gfx_set_video_left_crop((unsigned short)(-x));
+ xstart = hadjust;
+ } else {
+ gfx_set_video_left_crop(0);
+ xstart = (unsigned long)x + hadjust;
+ }
+
+ /* 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(CS5530_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_LINE_SIZE_UPPER)
+ line_size += 512l;
+ 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(CS5530_VIDEO_CONFIG);
+ vcfg &= ~CS5530_VCFG_VID_REG_UPDATE;
+ WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg);
+
+ /* SET VIDEO POSITION */
+
+ WRITE_VID32(CS5530_VIDEO_X_POS, (xend << 16) | xstart);
+ WRITE_VID32(CS5530_VIDEO_Y_POS, (yend << 16) | ystart);
+
+ vcfg |= CS5530_VCFG_VID_REG_UPDATE;
+ WRITE_VID32(CS5530_VIDEO_CONFIG, vcfg);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_left_crop
+ *
+ * This routine sets the number of pixels which will be cropped from the
+ * beginning of each video line. The video window will begin to display only
+ * from the pixel following the cropped pixels, and the cropped pixels
+ * will be ignored.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_set_video_left_crop(unsigned short x)
+#else
+int
+gfx_set_video_left_crop(unsigned short x)
+#endif
+{
+ unsigned long vcfg, initread;
+
+ /* CLIPPING ON LEFT */
+ /* Adjust initial read for scale, checking for divide by zero */
+
+ if (gfx_vid_dstw)
+ initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw;
+
+ else
+ initread = 0;
+
+ /* SET INITIAL READ ADDRESS AND ENABLE REGISTER UPDATES */
+
+ vcfg = READ_VID32(CS5530_VIDEO_CONFIG);
+ vcfg &= ~CS5530_VCFG_INIT_READ_MASK;
+ vcfg |= (initread << 15) & CS5530_VCFG_INIT_READ_MASK;
+ vcfg |= CS5530_VCFG_VID_REG_UPDATE;
+ WRITE_VID32(CS5530_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
+cs5530_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 CS5530 COLOR KEY VALUE */
+
+ WRITE_VID32(CS5530_VIDEO_COLOR_KEY, key);
+ WRITE_VID32(CS5530_VIDEO_COLOR_MASK, mask);
+
+ /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */
+
+ dcfg = READ_VID32(CS5530_DISPLAY_CONFIG);
+ if (graphics & 0x01)
+ dcfg &= ~CS5530_DCFG_VG_CK;
+ else
+ dcfg |= CS5530_DCFG_VG_CK;
+ WRITE_VID32(CS5530_DISPLAY_CONFIG, dcfg);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_filter
+ *
+ * This routine enables or disables the video overlay filters.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_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 CS5530 VIDEO OVERLAY FILTERS */
+
+ vcfg = READ_VID32(CS5530_VIDEO_CONFIG);
+ vcfg &= ~(CS5530_VCFG_X_FILTER_EN | CS5530_VCFG_Y_FILTER_EN);
+ if (xfilter)
+ vcfg |= CS5530_VCFG_X_FILTER_EN;
+ if (yfilter)
+ vcfg |= CS5530_VCFG_Y_FILTER_EN;
+ WRITE_VID32(CS5530_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 CS5530, this means loading the
+ * palette with identity values).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_set_video_palette(unsigned long *palette)
+#else
+int
+gfx_set_video_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i, entry;
+
+ /* LOAD CS5530 VIDEO PALETTE */
+
+ WRITE_VID32(CS5530_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ if (palette)
+ entry = palette[i];
+ else
+ entry = i | (i << 8) | (i << 16);
+ WRITE_VID32(CS5530_PALETTE_DATA, entry);
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_entry
+ *
+ * This routine loads a single entry of the video hardware palette.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_set_video_palette_entry(unsigned long index, unsigned long palette)
+#else
+int
+gfx_set_video_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* SET A SINGLE ENTRY */
+
+ WRITE_VID32(CS5530_PALETTE_ADDRESS, index);
+ WRITE_VID32(CS5530_PALETTE_DATA, palette);
+
+ return (0);
+}
+
+#define CX55xx_VIDEO_PCI_44 0x80009444
+
+/*---------------------------------------------------------------------------
+ * gfx_disable_softvga
+ *
+ * Disables SoftVga. This function is only valid with VSA2, Returns 1 if
+ * SoftVga can be disabled; 0 if not.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_disable_softvga(void)
+#else
+int
+gfx_disable_softvga(void)
+#endif
+{
+ unsigned long reg_val;
+
+ /* get the current value */
+ reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44);
+ /* setting video PCI register 44 bit 0 to 1 disables SoftVga */
+ reg_val |= 0x1;
+ gfx_pci_config_write(CX55xx_VIDEO_PCI_44, reg_val);
+
+ /* see if we set the bit and return the appropriate value */
+ reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44);
+ if ((reg_val & 0x1) == 0x1)
+ return (1);
+ else
+ return (0);
+
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_softvga
+ *
+ * Enables SoftVga. This function is only valid with VSA2, Returns 1 if
+ * SoftVga can be enbled; 0 if not.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_enable_softvga(void)
+#else
+int
+gfx_enable_softvga(void)
+#endif
+{
+ unsigned long reg_val;
+
+ /* get the current value */
+ reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44);
+ /* clearing video PCI register 44 bit 0 enables SoftVga */
+ gfx_pci_config_write(CX55xx_VIDEO_PCI_44, reg_val & 0xfffffffe);
+
+ /* see if we cleared the bit and return the appropriate value */
+ reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44);
+ if ((reg_val & 0x1) == 0)
+ return (1);
+ else
+ return (0);
+
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+cs5530_get_clock_frequency(void)
+#else
+unsigned long
+gfx_get_clock_frequency(void)
+#endif
+{
+ unsigned int index;
+ unsigned long value, mask;
+
+ mask = 0x7FFFFEDC;
+ value = READ_VID32(CS5530_DOT_CLK_CONFIG) & mask;
+ for (index = 0; index < NUM_CS5530_FREQUENCIES; index++) {
+ if ((CS5530_PLLtable[index].pll_value & mask) == value)
+ return (CS5530_PLLtable[index].frequency);
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_video_width
+ *
+ * This routine returns the maximum theoretical video width for the current
+ * display mode.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+cs5530_get_max_video_width(void)
+#else
+unsigned long
+gfx_get_max_video_width(void)
+#endif
+{
+ unsigned long htotal, vidclk, dotpll;
+ unsigned long low, high, sublow, subhigh;
+ unsigned long width, value;
+ unsigned long temp0, temp1;
+ unsigned long highshift;
+ unsigned long divisor, dividend;
+
+ htotal = gfx_get_htotal();
+
+ vidclk = gfx_cpu_frequency << 15;
+ if (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_VCLK_DIV)
+ vidclk >>= 1;
+
+ dotpll = gfx_get_clock_frequency();
+
+ /* CHECK FOR UNKNOWN DOT CLOCK */
+
+ if (!dotpll)
+ return 0;
+
+ /* DERIVE THEORETICAL MAXIMUM */
+ /* The GX/CS5530 video interface transfers 8 bytes for every 9 video */
+ /* clocks. This implies that 4 video pixels are transferred for every */
+ /* 9 clocks. The time allowed to fill a line buffer is an entire */
+ /* display line, or (HTotal * DotPll). The time needed to fill the */
+ /* line buffer is thus ((4/9) * VidClk * VidWidth). Solving for */
+ /* equality yields the theoretical maximum: */
+ /* */
+ /* 4 * VidClk * HTotal */
+ /* VidWidth = ----------------------- */
+ /* 9 * DotPLL */
+
+ /* CALCULATE TOP OF EQUATION */
+ /* The equation as it stands will overflow 32-bit integer math. We must */
+ /* therefore use tricks to perform a 64-bit equation to calculate the */
+ /* correct value. We assume in this equation that the upper 16 bits of */
+ /* htotal are 0, i.e. that htotal is never greater than 65535. */
+
+ vidclk <<= 2;
+
+ low = (vidclk & 0xFFFF) * (htotal & 0xFFFF);
+ temp0 = (vidclk >> 16) * (htotal & 0xFFFF);
+ temp1 = temp0 << 16;
+
+ high = temp0 >> 16;
+ if ((0xFFFFFFFF - temp1) < low)
+ high++;
+ low += temp1;
+
+ /* DIVIDE BY BOTTOM OF EQUATION */
+ /* Use an iterative divide to avoid floating point or inline assembly */
+ /* Costly, but so is the price of OS independence. */
+
+ divisor = 9 * dotpll;
+ highshift = 0;
+ width = 0;
+ while (highshift <= 32) {
+ if (highshift == 0)
+ dividend = high;
+ else if (highshift == 32)
+ dividend = low;
+ else
+ dividend = (high << highshift) | (low >> (32 - highshift));
+
+ value = dividend / divisor;
+
+ width = (width << 4) + value;
+
+ value *= divisor;
+
+ subhigh = value >> highshift;
+ sublow = value << (32 - highshift);
+
+ if (low < sublow)
+ high = high - subhigh - 1;
+ else
+ high = high - subhigh;
+
+ low -= sublow;
+
+ highshift += 4;
+ }
+
+ /* ALIGN TO 8 PIXEL BOUNDARY */
+
+ width &= 0xFFFC;
+
+ return width;
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsa2_softvga_enable
+ *
+ * This function returns the enable status of SoftVGA. It is valid
+ * only if VSAII is present.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_get_vsa2_softvga_enable(void)
+#else
+int
+gfx_get_vsa2_softvga_enable(void)
+#endif
+{
+ unsigned long reg_val;
+
+ reg_val = gfx_pci_config_read(CX55xx_VIDEO_PCI_44);
+ if ((reg_val & 0x1) == 0)
+ return (1);
+ else
+ return (0);
+
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+cs5530_get_sync_polarities(void)
+#else
+int
+gfx_get_sync_polarities(void)
+#endif
+{
+ int polarities = 0;
+
+ if (READ_VID32(CS5530_DISPLAY_CONFIG) & 0x00000100)
+ polarities |= 1;
+ if (READ_VID32(CS5530_DISPLAY_CONFIG) & 0x00000200)
+ polarities |= 2;
+ return (polarities);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_palette_entry
+ *
+ * This routine returns a single palette entry.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int
+gfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* READ A SINGLE ENTRY */
+
+ WRITE_VID32(CS5530_PALETTE_ADDRESS, index);
+ *palette = READ_VID32(CS5530_PALETTE_DATA);
+
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * 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
+cs5530_get_video_enable(void)
+#else
+int
+gfx_get_video_enable(void)
+#endif
+{
+ if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_VID_EN)
+ return (1);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_format
+ *
+ * This routine returns the current video overlay format.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+cs5530_get_video_format(void)
+#else
+int
+gfx_get_video_format(void)
+#endif
+{
+ unsigned long vcfg;
+
+ vcfg = READ_VID32(CS5530_VIDEO_CONFIG);
+ if (vcfg & CS5530_VCFG_CSC_BYPASS)
+ return (VIDEO_FORMAT_RGB);
+ if (vcfg & CS5530_VCFG_4_2_0_MODE)
+ return (VIDEO_FORMAT_Y0Y1Y2Y3);
+
+ return ((int)((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
+cs5530_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 CS5530 VIDEO LINE SIZE */
+
+ width = (READ_VID32(CS5530_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+
+ 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
+cs5530_get_video_line_size(void)
+#else
+unsigned long
+gfx_get_video_line_size(void)
+#endif
+{
+ unsigned long width = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE CS5530 VIDEO LINE SIZE */
+
+ width = (READ_VID32(CS5530_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+ 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
+cs5530_get_video_xclip(void)
+#else
+unsigned long
+gfx_get_video_xclip(void)
+#endif
+{
+ unsigned long clip = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE CS5530 VIDEO LINE SIZE */
+
+ clip = (READ_VID32(CS5530_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
+cs5530_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
+cs5530_get_video_scale(void)
+#else
+unsigned long
+gfx_get_video_scale(void)
+#endif
+{
+ return (READ_VID32(CS5530_VIDEO_SCALE));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_dst_size
+ *
+ * This routine returns the size of the displayed video overlay window.
+ * NOTE: This is the displayed window size, which may be different from
+ * the real window size if clipped.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+cs5530_get_video_dst_size(void)
+#else
+unsigned long
+gfx_get_video_dst_size(void)
+#endif
+{
+ unsigned long xsize, ysize;
+
+ xsize = READ_VID32(CS5530_VIDEO_X_POS);
+ xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x07FF);
+ ysize = READ_VID32(CS5530_VIDEO_Y_POS);
+ ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x07FF);
+ 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.
+ * NOTE: This is the displayed window position, which may be different from
+ * the real window position if clipped.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+cs5530_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(CS5530_VIDEO_X_POS) & 0x000007FF;
+ ypos = READ_VID32(CS5530_VIDEO_Y_POS) & 0x000007FF;
+
+ /* GET ADJUSTMENT VALUES */
+ /* Use routines to abstract version of display controller. */
+
+ hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13l;
+ vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
+ 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
+cs5530_get_video_color_key(void)
+#else
+unsigned long
+gfx_get_video_color_key(void)
+#endif
+{
+ return (READ_VID32(CS5530_VIDEO_COLOR_KEY));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key_mask
+ *
+ * This routine returns the current video color mask value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+cs5530_get_video_color_key_mask(void)
+#else
+unsigned long
+gfx_get_video_color_key_mask(void)
+#endif
+{
+ return (READ_VID32(CS5530_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
+cs5530_get_video_color_key_src(void)
+#else
+int
+gfx_get_video_color_key_src(void)
+#endif
+{
+ if (READ_VID32(CS5530_DISPLAY_CONFIG) & CS5530_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
+cs5530_get_video_filter(void)
+#else
+int
+gfx_get_video_filter(void)
+#endif
+{
+ int retval = 0;
+
+ if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_X_FILTER_EN)
+ retval |= 1;
+ if (READ_VID32(CS5530_VIDEO_CONFIG) & CS5530_VCFG_Y_FILTER_EN)
+ retval |= 2;
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+cs5530_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(CS5530_CRCSIG_TFT_TV, 0);
+ WRITE_VID32(CS5530_CRCSIG_TFT_TV, 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(CS5530_CRCSIG_TFT_TV) >> 8;
+ }
+ return (crc);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/vid_cstl.c b/src/gfx/vid_cstl.c
new file mode 100644
index 0000000..5b642cc
--- /dev/null
+++ b/src/gfx/vid_cstl.c
@@ -0,0 +1,2571 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/* DEFAULT FILTER COEFFICIENTS */
+
+long DurangoVideoFilter[][2] = {
+ {0x10000000, 0x00000000}, /* 0, 4096, 0, 0 */
+ {0x10008008, 0x00000008}, /* -8, 4096, 8, 0 */
+ {0x10008010, 0x80010011}, /* -16, 4096, 17, -1 */
+ {0x10008019, 0x8001001A}, /* -25, 4096, 26, -1 */
+ {0x10008021, 0x80020023}, /* -33, 4096, 35, -2 */
+ {0x0FFF8029, 0x8003002D}, /* -41, 4095, 45, -3 */
+ {0x0FFE8031, 0x80030036}, /* -49, 4094, 54, -3 */
+ {0x0FFC8038, 0x80040040}, /* -56, 4092, 64, -4 */
+ {0x0FFB8040, 0x8005004A}, /* -64, 4091, 74, -5 */
+ {0x0FF88047, 0x80050054}, /* -71, 4088, 84, -5 */
+ {0x0FF6804E, 0x8006005E}, /* -78, 4086, 94, -6 */
+ {0x0FF48055, 0x80070068}, /* -85, 4084, 104, -7 */
+ {0x0FF0805C, 0x80070073}, /* -92, 4080, 115, -7 */
+ {0x0FEE8063, 0x8008007D}, /* -99, 4078, 125, -8 */
+ {0x0FEA8069, 0x80090088}, /* -105, 4074, 136, -9 */
+ {0x0FE78070, 0x800A0093}, /* -112, 4071, 147, -10 */
+ {0x0FE28076, 0x800A009E}, /* -118, 4066, 158, -10 */
+ {0x0FDD807C, 0x800B00AA}, /* -124, 4061, 170, -11 */
+ {0x0FD98082, 0x800C00B5}, /* -130, 4057, 181, -12 */
+ {0x0FD48088, 0x800D00C1}, /* -136, 4052, 193, -13 */
+ {0x0FCE808E, 0x800D00CD}, /* -142, 4046, 205, -13 */
+ {0x0FC88093, 0x800E00D9}, /* -147, 4040, 217, -14 */
+ {0x0FC38099, 0x800F00E5}, /* -153, 4035, 229, -15 */
+ {0x0FBD809E, 0x801000F1}, /* -158, 4029, 241, -16 */
+ {0x0FB680A3, 0x801000FD}, /* -163, 4022, 253, -16 */
+ {0x0FAF80A8, 0x8011010A}, /* -168, 4015, 266, -17 */
+ {0x0FA880AD, 0x80120117}, /* -173, 4008, 279, -18 */
+ {0x0FA180B2, 0x80130124}, /* -178, 4001, 292, -19 */
+ {0x0F9980B6, 0x80140131}, /* -182, 3993, 305, -20 */
+ {0x0F9280BB, 0x8015013E}, /* -187, 3986, 318, -21 */
+ {0x0F8880BF, 0x8015014C}, /* -191, 3976, 332, -21 */
+ {0x0F8080C3, 0x80160159}, /* -195, 3968, 345, -22 */
+ {0x0F7880C8, 0x80170167}, /* -200, 3960, 359, -23 */
+ {0x0F6E80CB, 0x80180175}, /* -203, 3950, 373, -24 */
+ {0x0F6580CF, 0x80190183}, /* -207, 3941, 387, -25 */
+ {0x0F5C80D3, 0x801A0191}, /* -211, 3932, 401, -26 */
+ {0x0F5280D7, 0x801B01A0}, /* -215, 3922, 416, -27 */
+ {0x0F4880DA, 0x801C01AE}, /* -218, 3912, 430, -28 */
+ {0x0F3D80DD, 0x801D01BD}, /* -221, 3901, 445, -29 */
+ {0x0F3280E0, 0x801E01CC}, /* -224, 3890, 460, -30 */
+ {0x0F2880E4, 0x801F01DB}, /* -228, 3880, 475, -31 */
+ {0x0F1C80E6, 0x802001EA}, /* -230, 3868, 490, -32 */
+ {0x0F1180E9, 0x802101F9}, /* -233, 3857, 505, -33 */
+ {0x0F0480EB, 0x80210208}, /* -235, 3844, 520, -33 */
+ {0x0EFA80EF, 0x80230218}, /* -239, 3834, 536, -35 */
+ {0x0EEC80F0, 0x80230227}, /* -240, 3820, 551, -35 */
+ {0x0EE080F3, 0x80240237}, /* -243, 3808, 567, -36 */
+ {0x0ED380F5, 0x80250247}, /* -245, 3795, 583, -37 */
+ {0x0EC780F7, 0x80270257}, /* -247, 3783, 599, -39 */
+ {0x0EB980F9, 0x80280268}, /* -249, 3769, 616, -40 */
+ {0x0EAC80FB, 0x80290278}, /* -251, 3756, 632, -41 */
+ {0x0E9E80FD, 0x802A0289}, /* -253, 3742, 649, -42 */
+ {0x0E9080FE, 0x802B0299}, /* -254, 3728, 665, -43 */
+ {0x0E838100, 0x802D02AA}, /* -256, 3715, 682, -45 */
+ {0x0E758102, 0x802E02BB}, /* -258, 3701, 699, -46 */
+ {0x0E668103, 0x802F02CC}, /* -259, 3686, 716, -47 */
+ {0x0E568104, 0x803002DE}, /* -260, 3670, 734, -48 */
+ {0x0E498106, 0x803202EF}, /* -262, 3657, 751, -50 */
+ {0x0E398107, 0x80330301}, /* -263, 3641, 769, -51 */
+ {0x0E298108, 0x80340313}, /* -264, 3625, 787, -52 */
+ {0x0E1A8109, 0x80360325}, /* -265, 3610, 805, -54 */
+ {0x0E0B810A, 0x80370336}, /* -266, 3595, 822, -55 */
+ {0x0DFA810A, 0x80380348}, /* -266, 3578, 840, -56 */
+ {0x0DEA810B, 0x803A035B}, /* -267, 3562, 859, -58 */
+ {0x0DDA810C, 0x803B036D}, /* -268, 3546, 877, -59 */
+ {0x0DCA810C, 0x803D037F}, /* -268, 3530, 895, -61 */
+ {0x0DB7810B, 0x803E0392}, /* -267, 3511, 914, -62 */
+ {0x0DA7810C, 0x804003A5}, /* -268, 3495, 933, -64 */
+ {0x0D95810C, 0x804103B8}, /* -268, 3477, 952, -65 */
+ {0x0D85810C, 0x804303CA}, /* -268, 3461, 970, -67 */
+ {0x0D73810C, 0x804403DD}, /* -268, 3443, 989, -68 */
+ {0x0D61810C, 0x804603F1}, /* -268, 3425, 1009, -70 */
+ {0x0D50810C, 0x80480404}, /* -268, 3408, 1028, -72 */
+ {0x0D3E810C, 0x80490417}, /* -268, 3390, 1047, -73 */
+ {0x0D2C810C, 0x804B042B}, /* -268, 3372, 1067, -75 */
+ {0x0D1B810C, 0x804D043E}, /* -268, 3355, 1086, -77 */
+ {0x0D07810B, 0x804E0452}, /* -267, 3335, 1106, -78 */
+ {0x0CF5810B, 0x80500466}, /* -267, 3317, 1126, -80 */
+ {0x0CE2810A, 0x8052047A}, /* -266, 3298, 1146, -82 */
+ {0x0CCF810A, 0x8053048E}, /* -266, 3279, 1166, -83 */
+ {0x0CBC8109, 0x805504A2}, /* -265, 3260, 1186, -85 */
+ {0x0CA98108, 0x805704B6}, /* -264, 3241, 1206, -87 */
+ {0x0C968108, 0x805904CB}, /* -264, 3222, 1227, -89 */
+ {0x0C838107, 0x805B04DF}, /* -263, 3203, 1247, -91 */
+ {0x0C6F8106, 0x805C04F3}, /* -262, 3183, 1267, -92 */
+ {0x0C5B8105, 0x805E0508}, /* -261, 3163, 1288, -94 */
+ {0x0C478104, 0x8060051D}, /* -260, 3143, 1309, -96 */
+ {0x0C348103, 0x80620531}, /* -259, 3124, 1329, -98 */
+ {0x0C1F8102, 0x80640547}, /* -258, 3103, 1351, -100 */
+ {0x0C0C8101, 0x8066055B}, /* -257, 3084, 1371, -102 */
+ {0x0BF88100, 0x80680570}, /* -256, 3064, 1392, -104 */
+ {0x0BE380FE, 0x806A0585}, /* -254, 3043, 1413, -106 */
+ {0x0BCF80FD, 0x806C059A}, /* -253, 3023, 1434, -108 */
+ {0x0BBA80FC, 0x806E05B0}, /* -252, 3002, 1456, -110 */
+ {0x0BA480F9, 0x807005C5}, /* -249, 2980, 1477, -112 */
+ {0x0B8F80F8, 0x807205DB}, /* -248, 2959, 1499, -114 */
+ {0x0B7A80F6, 0x807405F0}, /* -246, 2938, 1520, -116 */
+ {0x0B6580F5, 0x80760606}, /* -245, 2917, 1542, -118 */
+ {0x0B4F80F3, 0x8077061B}, /* -243, 2895, 1563, -119 */
+ {0x0B3A80F2, 0x80790631}, /* -242, 2874, 1585, -121 */
+ {0x0B2480F0, 0x807B0647}, /* -240, 2852, 1607, -123 */
+ {0x0B0F80EE, 0x807D065C}, /* -238, 2831, 1628, -125 */
+ {0x0AF980ED, 0x807F0673}, /* -237, 2809, 1651, -127 */
+ {0x0AE480EB, 0x80810688}, /* -235, 2788, 1672, -129 */
+ {0x0ACE80E9, 0x8084069F}, /* -233, 2766, 1695, -132 */
+ {0x0AB980E7, 0x808606B4}, /* -231, 2745, 1716, -134 */
+ {0x0AA380E6, 0x808806CB}, /* -230, 2723, 1739, -136 */
+ {0x0A8D80E4, 0x808A06E1}, /* -228, 2701, 1761, -138 */
+ {0x0A7780E2, 0x808C06F7}, /* -226, 2679, 1783, -140 */
+ {0x0A6180E0, 0x808E070D}, /* -224, 2657, 1805, -142 */
+ {0x0A4B80DE, 0x80910724}, /* -222, 2635, 1828, -145 */
+ {0x0A3580DC, 0x8093073A}, /* -220, 2613, 1850, -147 */
+ {0x0A1F80DA, 0x80950750}, /* -218, 2591, 1872, -149 */
+ {0x0A0880D8, 0x80970767}, /* -216, 2568, 1895, -151 */
+ {0x09F280D6, 0x8099077D}, /* -214, 2546, 1917, -153 */
+ {0x09DD80D4, 0x809C0793}, /* -212, 2525, 1939, -156 */
+ {0x09C680D2, 0x809E07AA}, /* -210, 2502, 1962, -158 */
+ {0x09B080D0, 0x80A007C0}, /* -208, 2480, 1984, -160 */
+ {0x099980CE, 0x80A207D7}, /* -206, 2457, 2007, -162 */
+ {0x098380CB, 0x80A507ED}, /* -203, 2435, 2029, -165 */
+ {0x096C80C9, 0x80A70804}, /* -201, 2412, 2052, -167 */
+ {0x095680C7, 0x80A9081A}, /* -199, 2390, 2074, -169 */
+ {0x094080C5, 0x80AB0830}, /* -197, 2368, 2096, -171 */
+ {0x092980C3, 0x80AE0848}, /* -195, 2345, 2120, -174 */
+ {0x091380C1, 0x80B0085E}, /* -193, 2323, 2142, -176 */
+ {0x08FC80BE, 0x80B20874}, /* -190, 2300, 2164, -178 */
+ {0x08E580BC, 0x80B4088B}, /* -188, 2277, 2187, -180 */
+ {0x08D080BB, 0x80B708A2}, /* -187, 2256, 2210, -183 */
+ {0x08B980B9, 0x80B908B9}, /* -185, 2233, 2233, -185 */
+ {0x08A380B7, 0x80BB08CF}, /* -183, 2211, 2255, -187 */
+ {0x088B80B4, 0x80BC08E5}, /* -180, 2187, 2277, -188 */
+ {0x087480B2, 0x80BE08FC}, /* -178, 2164, 2300, -190 */
+ {0x085E80B0, 0x80C10913}, /* -176, 2142, 2323, -193 */
+ {0x084880AE, 0x80C30929}, /* -174, 2120, 2345, -195 */
+ {0x083080AB, 0x80C50940}, /* -171, 2096, 2368, -197 */
+ {0x081A80A9, 0x80C70956}, /* -169, 2074, 2390, -199 */
+ {0x080480A7, 0x80C9096C}, /* -167, 2052, 2412, -201 */
+ {0x07ED80A5, 0x80CB0983}, /* -165, 2029, 2435, -203 */
+ {0x07D780A2, 0x80CE0999}, /* -162, 2007, 2457, -206 */
+ {0x07C080A0, 0x80D009B0}, /* -160, 1984, 2480, -208 */
+ {0x07AA809E, 0x80D209C6}, /* -158, 1962, 2502, -210 */
+ {0x0793809C, 0x80D409DD}, /* -156, 1939, 2525, -212 */
+ {0x077D8099, 0x80D609F2}, /* -153, 1917, 2546, -214 */
+ {0x07668097, 0x80D80A09}, /* -151, 1894, 2569, -216 */
+ {0x074F8095, 0x80DA0A20}, /* -149, 1871, 2592, -218 */
+ {0x073A8093, 0x80DC0A35}, /* -147, 1850, 2613, -220 */
+ {0x07238091, 0x80DE0A4C}, /* -145, 1827, 2636, -222 */
+ {0x070C808E, 0x80E00A62}, /* -142, 1804, 2658, -224 */
+ {0x06F7808C, 0x80E20A77}, /* -140, 1783, 2679, -226 */
+ {0x06E0808A, 0x80E40A8E}, /* -138, 1760, 2702, -228 */
+ {0x06CA8088, 0x80E60AA4}, /* -136, 1738, 2724, -230 */
+ {0x06B48086, 0x80E70AB9}, /* -134, 1716, 2745, -231 */
+ {0x069E8084, 0x80E90ACF}, /* -132, 1694, 2767, -233 */
+ {0x06878081, 0x80EB0AE5}, /* -129, 1671, 2789, -235 */
+ {0x0672807F, 0x80ED0AFA}, /* -127, 1650, 2810, -237 */
+ {0x065C807D, 0x80EE0B0F}, /* -125, 1628, 2831, -238 */
+ {0x0646807B, 0x80F00B25}, /* -123, 1606, 2853, -240 */
+ {0x06308079, 0x80F20B3B}, /* -121, 1584, 2875, -242 */
+ {0x061A8077, 0x80F30B50}, /* -119, 1562, 2896, -243 */
+ {0x06068076, 0x80F50B65}, /* -118, 1542, 2917, -245 */
+ {0x05F08074, 0x80F60B7A}, /* -116, 1520, 2938, -246 */
+ {0x05DB8072, 0x80F80B8F}, /* -114, 1499, 2959, -248 */
+ {0x05C58070, 0x80F90BA4}, /* -112, 1477, 2980, -249 */
+ {0x05B1806E, 0x80FC0BB9}, /* -110, 1457, 3001, -252 */
+ {0x059B806C, 0x80FD0BCE}, /* -108, 1435, 3022, -253 */
+ {0x0586806A, 0x80FE0BE2}, /* -106, 1414, 3042, -254 */
+ {0x05718068, 0x81000BF7}, /* -104, 1393, 3063, -256 */
+ {0x055C8066, 0x81010C0B}, /* -102, 1372, 3083, -257 */
+ {0x05478064, 0x81020C1F}, /* -100, 1351, 3103, -258 */
+ {0x05328062, 0x81030C33}, /* -98, 1330, 3123, -259 */
+ {0x051D8060, 0x81040C47}, /* -96, 1309, 3143, -260 */
+ {0x0508805E, 0x81050C5B}, /* -94, 1288, 3163, -261 */
+ {0x04F3805C, 0x81060C6F}, /* -92, 1267, 3183, -262 */
+ {0x04E0805B, 0x81070C82}, /* -91, 1248, 3202, -263 */
+ {0x04CB8059, 0x81080C96}, /* -89, 1227, 3222, -264 */
+ {0x04B68057, 0x81080CA9}, /* -87, 1206, 3241, -264 */
+ {0x04A28055, 0x81090CBC}, /* -85, 1186, 3260, -265 */
+ {0x048E8053, 0x810A0CCF}, /* -83, 1166, 3279, -266 */
+ {0x047A8052, 0x810A0CE2}, /* -82, 1146, 3298, -266 */
+ {0x04668050, 0x810B0CF5}, /* -80, 1126, 3317, -267 */
+ {0x0451804E, 0x810B0D08}, /* -78, 1105, 3336, -267 */
+ {0x043E804D, 0x810C0D1B}, /* -77, 1086, 3355, -268 */
+ {0x042B804B, 0x810C0D2C}, /* -75, 1067, 3372, -268 */
+ {0x04178049, 0x810C0D3E}, /* -73, 1047, 3390, -268 */
+ {0x04038048, 0x810C0D51}, /* -72, 1027, 3409, -268 */
+ {0x03F08046, 0x810C0D62}, /* -70, 1008, 3426, -268 */
+ {0x03DD8044, 0x810C0D73}, /* -68, 989, 3443, -268 */
+ {0x03CA8043, 0x810C0D85}, /* -67, 970, 3461, -268 */
+ {0x03B78041, 0x810C0D96}, /* -65, 951, 3478, -268 */
+ {0x03A48040, 0x810C0DA8}, /* -64, 932, 3496, -268 */
+ {0x0391803E, 0x810B0DB8}, /* -62, 913, 3512, -267 */
+ {0x0380803D, 0x810C0DC9}, /* -61, 896, 3529, -268 */
+ {0x036D803B, 0x810C0DDA}, /* -59, 877, 3546, -268 */
+ {0x035B803A, 0x810B0DEA}, /* -58, 859, 3562, -267 */
+ {0x03488038, 0x810A0DFA}, /* -56, 840, 3578, -266 */
+ {0x03368037, 0x810A0E0B}, /* -55, 822, 3595, -266 */
+ {0x03248036, 0x81090E1B}, /* -54, 804, 3611, -265 */
+ {0x03128034, 0x81080E2A}, /* -52, 786, 3626, -264 */
+ {0x03018033, 0x81070E39}, /* -51, 769, 3641, -263 */
+ {0x02EF8032, 0x81060E49}, /* -50, 751, 3657, -262 */
+ {0x02DE8030, 0x81040E56}, /* -48, 734, 3670, -260 */
+ {0x02CC802F, 0x81030E66}, /* -47, 716, 3686, -259 */
+ {0x02BB802E, 0x81020E75}, /* -46, 699, 3701, -258 */
+ {0x02AA802D, 0x81000E83}, /* -45, 682, 3715, -256 */
+ {0x0299802B, 0x80FE0E90}, /* -43, 665, 3728, -254 */
+ {0x0288802A, 0x80FD0E9F}, /* -42, 648, 3743, -253 */
+ {0x02778029, 0x80FB0EAD}, /* -41, 631, 3757, -251 */
+ {0x02678028, 0x80F90EBA}, /* -40, 615, 3770, -249 */
+ {0x02568027, 0x80F70EC8}, /* -39, 598, 3784, -247 */
+ {0x02468025, 0x80F50ED4}, /* -37, 582, 3796, -245 */
+ {0x02368024, 0x80F30EE1}, /* -36, 566, 3809, -243 */
+ {0x02268023, 0x80F00EED}, /* -35, 550, 3821, -240 */
+ {0x02188023, 0x80EF0EFA}, /* -35, 536, 3834, -239 */
+ {0x02078021, 0x80EB0F05}, /* -33, 519, 3845, -235 */
+ {0x01F98021, 0x80E90F11}, /* -33, 505, 3857, -233 */
+ {0x01EA8020, 0x80E60F1C}, /* -32, 490, 3868, -230 */
+ {0x01DC801F, 0x80E40F27}, /* -31, 476, 3879, -228 */
+ {0x01CD801E, 0x80E00F31}, /* -30, 461, 3889, -224 */
+ {0x01BE801D, 0x80DD0F3C}, /* -29, 446, 3900, -221 */
+ {0x01AF801C, 0x80DA0F47}, /* -28, 431, 3911, -218 */
+ {0x01A1801B, 0x80D70F51}, /* -27, 417, 3921, -215 */
+ {0x0192801A, 0x80D30F5B}, /* -26, 402, 3931, -211 */
+ {0x01848019, 0x80CF0F64}, /* -25, 388, 3940, -207 */
+ {0x01768018, 0x80CB0F6D}, /* -24, 374, 3949, -203 */
+ {0x01688017, 0x80C80F77}, /* -23, 360, 3959, -200 */
+ {0x015A8016, 0x80C30F7F}, /* -22, 346, 3967, -195 */
+ {0x014D8015, 0x80BF0F87}, /* -21, 333, 3975, -191 */
+ {0x013F8015, 0x80BB0F91}, /* -21, 319, 3985, -187 */
+ {0x01328014, 0x80B60F98}, /* -20, 306, 3992, -182 */
+ {0x01258013, 0x80B20FA0}, /* -19, 293, 4000, -178 */
+ {0x01188012, 0x80AD0FA7}, /* -18, 280, 4007, -173 */
+ {0x010B8011, 0x80A80FAE}, /* -17, 267, 4014, -168 */
+ {0x00FE8010, 0x80A30FB5}, /* -16, 254, 4021, -163 */
+ {0x00F28010, 0x809E0FBC}, /* -16, 242, 4028, -158 */
+ {0x00E6800F, 0x80990FC2}, /* -15, 230, 4034, -153 */
+ {0x00DA800E, 0x80930FC7}, /* -14, 218, 4039, -147 */
+ {0x00CE800D, 0x808E0FCD}, /* -13, 206, 4045, -142 */
+ {0x00C2800D, 0x80880FD3}, /* -13, 194, 4051, -136 */
+ {0x00B6800C, 0x80820FD8}, /* -12, 182, 4056, -130 */
+ {0x00AB800B, 0x807C0FDC}, /* -11, 171, 4060, -124 */
+ {0x009F800A, 0x80760FE1}, /* -10, 159, 4065, -118 */
+ {0x0094800A, 0x80700FE6}, /* -10, 148, 4070, -112 */
+ {0x00898009, 0x80690FE9}, /* -9, 137, 4073, -105 */
+ {0x007E8008, 0x80630FED}, /* -8, 126, 4077, -99 */
+ {0x00748007, 0x805C0FEF}, /* -7, 116, 4079, -92 */
+ {0x00698007, 0x80550FF3}, /* -7, 105, 4083, -85 */
+ {0x005F8006, 0x804E0FF5}, /* -6, 95, 4085, -78 */
+ {0x00558005, 0x80470FF7}, /* -5, 85, 4087, -71 */
+ {0x004B8005, 0x80400FFA}, /* -5, 75, 4090, -64 */
+ {0x00418004, 0x80380FFB}, /* -4, 65, 4091, -56 */
+ {0x00378003, 0x80310FFD}, /* -3, 55, 4093, -49 */
+ {0x002E8003, 0x80290FFE}, /* -3, 46, 4094, -41 */
+ {0x00238002, 0x80211000}, /* -2, 35, 4096, -33 */
+ {0x001A8001, 0x80191000}, /* -1, 26, 4096, -25 */
+ {0x00118001, 0x80101000}, /* -1, 17, 4096, -16 */
+ {0x00080000, 0x80081000}, /* 0, 8, 4096, -8 */
+};
+
+/* CASTLE PLL TABLE */
+
+typedef struct tagCASTLEPLL
+{
+ long frequency; /* 16.16 fixed point frequency */
+ unsigned long pll_value; /* MCP DotPLL Register Upper 32(0x0015) */
+} CASTLEPLLENTRY;
+
+CASTLEPLLENTRY CASTLE_PLLtable[] = {
+ {0x00192CCC, 0x0000215D}, /* 25.1750 */
+ {0x001C526E, 0x0000216C}, /* 28.3220 */
+ {0x001C8F5C, 0x0000218D}, /* 28.5600 */
+ {0x001F8000, 0x00003147}, /* 31.5000 */
+ {0x00240000, 0x00000057}, /* 36.0000 */
+ {0x0025E395, 0x0000219A}, /* 37.8890 */
+ {0x00280000, 0x00000045}, /* 40.0000 */
+ {0x002B29BA, 0x00000089}, /* 43.1630 */
+ {0x002CE666, 0x000010E7}, /* 44.9000 */
+ {0x002DB851, 0x00002136}, /* 45.7200 */
+ {0x00318000, 0x00003207}, /* 49.5000 */
+ {0x00320000, 0x00002187}, /* 50.0000 */
+ {0x00384000, 0x00004286}, /* 56.2500 */
+ {0x003C10A3, 0x000010E5}, /* 60.0650 */
+ {0x00410000, 0x00004214}, /* 65.0000 */
+ {0x00442DD2, 0x00001105}, /* 68.1790 */
+ {0x004B0000, 0x00003183}, /* 75.0000 */
+ {0x004EC000, 0x00004284}, /* 78.7500 */
+ {0x00519999, 0x00001104}, /* 81.6000 */
+ {0x005E8000, 0x00006363}, /* 94.5000 */
+ {0x00618560, 0x00005303}, /* 97.5200 */
+ {0x00630000, 0x00002523}, /* 99.0000 */
+ {0x00640000, 0x000000D1}, /* 100.0000 */
+ {0x00642FDF, 0x00002183}, /* 100.1870 */
+ {0x00656B85, 0x00002122}, /* 101.4200 */
+ {0x006C0000, 0x00001081}, /* 108.0000 */
+ {0x00708000, 0x000013E3}, /* 112.5000 */
+ {0x00714F1A, 0x00006201}, /* 113.3090 */
+ {0x0077A666, 0x00000041}, /* 119.6500 */
+ {0x00806666, 0x00000072}, /* 128.4000 */
+ {0x00821999, 0x00006382}, /* 130.1000 */
+ {0x00858000, 0x00002182}, /* 133.5000 */
+ {0x00870000, 0x000041B1}, /* 135.0000 */
+ {0x00906147, 0x00000051}, /* 144.3800 */
+ {0x009D8000, 0x000062D1}, /* 157.5000 */
+ {0x00A20000, 0x000031A1}, /* 162.0000 */
+ {0x00A933F7, 0x00000061}, /* 169.2030 */
+ {0x00AF8000, 0x00002151}, /* 175.5000 */
+ {0x00BD0000, 0x000052E1}, /* 189.0000 */
+ {0x00BEF5C2, 0x00000071}, /* 190.9600 */
+ {0x00C60000, 0x00003201}, /* 198.0000 */
+ {0x00CA8000, 0x00004291}, /* 202.5000 */
+ {0x00E58000, 0x00004170}, /* 229.5000 */
+};
+
+#define NUM_CASTLE_FREQUENCIES sizeof(CASTLE_PLLtable)/sizeof(CASTLEPLLENTRY)
+
+/*---------------------------------------------------------------------------
+ * 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
+castle_reset_video(void)
+#else
+void
+gfx_reset_video(void)
+#endif
+{
+ gfx_set_video_enable(0);
+ gfx_select_alpha_region(1);
+ gfx_set_alpha_enable(0);
+ gfx_select_alpha_region(2);
+ gfx_set_alpha_enable(0);
+
+ /* SET REGION 0 AFTER RESET */
+
+ gfx_select_alpha_region(0);
+ gfx_set_alpha_enable(0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
+ *
+ * This routine configures the display output.
+ *
+ * "sync_polarities" is used to set the polarities of the sync pulses
+ * according to the following mask:
+ *
+ * Bit 0: If set to 1, negative horizontal polarity is programmed,
+ * otherwise positive horizontal polarity is programmed.
+ * Bit 1: If set to 1, negative vertical polarity is programmed,
+ * otherwise positive vertical polarity is programmed.
+ *
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_display_control(int sync_polarities)
+#else
+int
+gfx_set_display_control(int sync_polarities)
+#endif
+{
+ unsigned long power;
+ unsigned long dcfg;
+
+ /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+
+ dcfg = READ_VID32(CASTLE_DISPLAY_CONFIG);
+ dcfg &= ~(CASTLE_DCFG_CRT_SYNC_SKW_MASK | CASTLE_DCFG_PWR_SEQ_DLY_MASK |
+ CASTLE_DCFG_CRT_HSYNC_POL | CASTLE_DCFG_CRT_VSYNC_POL);
+
+ dcfg |= (CASTLE_DCFG_CRT_SYNC_SKW_INIT |
+ CASTLE_DCFG_PWR_SEQ_DLY_INIT | CASTLE_DCFG_GV_PAL_BYP);
+
+ if (PanelEnable) {
+ power = READ_VID32(CASTLE_POWER_MANAGEMENT);
+ power |= CASTLE_PM_PANEL_POWER_ON;
+ WRITE_VID32(CASTLE_POWER_MANAGEMENT, power);
+ }
+
+ /* SET APPROPRIATE SYNC POLARITIES */
+
+ if (sync_polarities & 0x1)
+ dcfg |= CASTLE_DCFG_CRT_HSYNC_POL;
+ if (sync_polarities & 0x2)
+ dcfg |= CASTLE_DCFG_CRT_VSYNC_POL;
+
+ WRITE_VID32(CASTLE_DISPLAY_CONFIG, dcfg);
+
+ return (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
+castle_set_clock_frequency(unsigned long frequency)
+#else
+void
+gfx_set_clock_frequency(unsigned long frequency)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned int i, index = 0;
+ unsigned long value;
+ unsigned long unlock;
+ long timeout;
+ long min, diff;
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+
+ value = CASTLE_PLLtable[0].pll_value;
+ min = (long)CASTLE_PLLtable[0].frequency - frequency;
+ if (min < 0L)
+ min = -min;
+ for (i = 1; i < NUM_CASTLE_FREQUENCIES; i++) {
+ diff = (long)CASTLE_PLLtable[i].frequency - frequency;
+ if (diff < 0L)
+ diff = -diff;
+ if (diff < min) {
+ min = diff;
+ index = i;
+ }
+ }
+
+ /* VERIFY THAT WE ARE NOT WRITING WHAT IS ALREADY IN THE REGISTERS */
+ /* The Dot PLL reset bit is tied to VDD for flat panels. This can */
+ /* cause a brief drop in flat panel power, which can cause serious */
+ /* glitches on some panels. */
+
+ gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+
+ if ((msr_value.low & MCP_DOTPLL_LOCK) &&
+ ((msr_value.low & MCP_DOTPLL_HALFPIX) == 0) &&
+ (msr_value.high == CASTLE_PLLtable[index].pll_value)) {
+ return;
+ }
+
+ /* PROGRAM THE SETTINGS WITH THE RESET BIT SET */
+ /* Clear the bypass bit to ensure that the programmed */
+ /* M, N and P values are being used. */
+
+ msr_value.high = CASTLE_PLLtable[index].pll_value;
+ msr_value.low |= 0x00000001;
+ msr_value.low &= ~MCP_DOTPLL_BYPASS;
+ gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+
+ /* WAIT FOR THE LOCK BIT */
+ /* The official word from LEDA is that the PLL may take up to 100 */
+ /* us to lock and the lock bit is unreliable. We thus add a long */
+ /* delay followed by a timed-out poll */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ for (timeout = 0; timeout < 1280; timeout++)
+ WRITE_REG32(DC3_UNLOCK, unlock);
+
+ for (timeout = 0; timeout < 1000; timeout++) {
+ gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+ if (msr_value.low & MCP_DOTPLL_LOCK)
+ break;
+ }
+
+ /* CLEAR THE RESET BIT */
+
+ msr_value.low &= 0xFFFFFFFE;
+ gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_crt_enable
+ *
+ * This routine enables or disables the CRT output from the video processor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_crt_enable(int enable)
+#else
+int
+gfx_set_crt_enable(int enable)
+#endif
+{
+ unsigned long config, misc;
+
+ config = READ_VID32(CASTLE_DISPLAY_CONFIG);
+ misc = READ_VID32(CASTLE_VID_MISC);
+
+ switch (enable) {
+ case CRT_DISABLE: /* DISABLE EVERYTHING */
+
+ WRITE_VID32(CASTLE_DISPLAY_CONFIG,
+ config & ~(CASTLE_DCFG_DIS_EN | CASTLE_DCFG_HSYNC_EN |
+ CASTLE_DCFG_VSYNC_EN | CASTLE_DCFG_DAC_BL_EN));
+ WRITE_VID32(CASTLE_VID_MISC, misc | CASTLE_DAC_POWER_DOWN);
+ break;
+
+ case CRT_ENABLE: /* ENABLE CRT DISPLAY, INCLUDING DISPLAY LOGIC */
+
+ WRITE_VID32(CASTLE_DISPLAY_CONFIG,
+ config | CASTLE_DCFG_DIS_EN | CASTLE_DCFG_HSYNC_EN |
+ CASTLE_DCFG_VSYNC_EN | CASTLE_DCFG_DAC_BL_EN);
+ WRITE_VID32(CASTLE_VID_MISC,
+ misc & ~CASTLE_DAC_POWER_DOWN & ~CASTLE_ANALOG_POWER_DOWN);
+ break;
+
+ case CRT_STANDBY: /* HSYNC:OFF VSYNC:ON */
+
+ WRITE_VID32(CASTLE_DISPLAY_CONFIG,
+ (config & ~(CASTLE_DCFG_DIS_EN | CASTLE_DCFG_HSYNC_EN |
+ CASTLE_DCFG_DAC_BL_EN)) | CASTLE_DCFG_VSYNC_EN);
+ WRITE_VID32(CASTLE_VID_MISC, misc | CASTLE_DAC_POWER_DOWN);
+ break;
+
+ case CRT_SUSPEND: /* HSYNC:ON VSYNC:OFF */
+
+ WRITE_VID32(CASTLE_DISPLAY_CONFIG,
+ (config & ~(CASTLE_DCFG_DIS_EN | CASTLE_DCFG_VSYNC_EN |
+ CASTLE_DCFG_DAC_BL_EN)) | CASTLE_DCFG_HSYNC_EN);
+ WRITE_VID32(CASTLE_VID_MISC, misc | CASTLE_DAC_POWER_DOWN);
+ break;
+
+ default:
+ return (GFX_STATUS_BAD_PARAMETER);
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_enable
+ *
+ * This routine enables or disables the video overlay functionality.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_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(CASTLE_VIDEO_CONFIG);
+ if (enable) {
+ /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_enable(1);
+
+ /* ENABLE DISPLAY FILTER VIDEO OVERLAY */
+
+ vcfg |= CASTLE_VCFG_VID_EN;
+ WRITE_VID32(CASTLE_VIDEO_CONFIG, vcfg);
+ } else {
+ /* DISABLE DISPLAY FILTER VIDEO OVERLAY */
+
+ vcfg &= ~CASTLE_VCFG_VID_EN;
+ WRITE_VID32(CASTLE_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
+ *
+ * Sets input video format type, to one of the YUV formats or to RGB.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_format(unsigned long format)
+#else
+int
+gfx_set_video_format(unsigned long format)
+#endif
+{
+ unsigned long ctrl, vcfg = 0;
+
+ /* SET THE DISPLAY FILTER VIDEO INPUT FORMAT */
+
+ vcfg = READ_VID32(CASTLE_VIDEO_CONFIG);
+ ctrl = READ_VID32(CASTLE_VID_ALPHA_CONTROL);
+ ctrl &=
+ ~(CASTLE_VIDEO_INPUT_IS_RGB | CASTLE_CSC_VIDEO_YUV_TO_RGB |
+ CASTLE_CSC_GRAPHICS_RGB_TO_YUV);
+ vcfg &= ~(CASTLE_VCFG_VID_INP_FORMAT | CASTLE_VCFG_4_2_0_MODE);
+ switch (format) {
+ case VIDEO_FORMAT_UYVY:
+ vcfg |= CASTLE_VCFG_UYVY_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_YUYV:
+ vcfg |= CASTLE_VCFG_YUYV_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_Y2YU:
+ vcfg |= CASTLE_VCFG_Y2YU_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_YVYU:
+ vcfg |= CASTLE_VCFG_YVYU_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_Y0Y1Y2Y3:
+ vcfg |= CASTLE_VCFG_UYVY_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= CASTLE_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y3Y2Y1Y0:
+ vcfg |= CASTLE_VCFG_Y2YU_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= CASTLE_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y1Y0Y3Y2:
+ vcfg |= CASTLE_VCFG_YUYV_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= CASTLE_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y1Y2Y3Y0:
+ vcfg |= CASTLE_VCFG_YVYU_FORMAT;
+ ctrl |= CASTLE_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= CASTLE_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_RGB:
+ ctrl |= CASTLE_VIDEO_INPUT_IS_RGB;
+ vcfg |= CASTLE_VCFG_UYVY_FORMAT;
+ break;
+ case VIDEO_FORMAT_P2M_P2L_P1M_P1L:
+ ctrl |= CASTLE_VIDEO_INPUT_IS_RGB;
+ vcfg |= CASTLE_VCFG_Y2YU_FORMAT;
+ break;
+ case VIDEO_FORMAT_P1M_P1L_P2M_P2L:
+ ctrl |= CASTLE_VIDEO_INPUT_IS_RGB;
+ vcfg |= CASTLE_VCFG_YUYV_FORMAT;
+ break;
+ case VIDEO_FORMAT_P1M_P2L_P2M_P1L:
+ ctrl |= CASTLE_VIDEO_INPUT_IS_RGB;
+ vcfg |= CASTLE_VCFG_YVYU_FORMAT;
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ WRITE_VID32(CASTLE_VIDEO_CONFIG, vcfg);
+ WRITE_VID32(CASTLE_VID_ALPHA_CONTROL, ctrl);
+
+ /* SET THE VIDEO FORMAT IN THE DISPLAY CONTROLLER */
+ /* Use private routine to abstract display controller. */
+
+ gfx_set_display_video_format(format);
+ 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
+castle_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, vid_420, pitch, scale;
+
+ /* SET THE DISPLAY FILTER VIDEO LINE SIZE */
+ /* Match the DC hardware alignment requirement. The line size must */
+ /* always be 32-byte aligned. However, we can manage smaller */
+ /* alignments by decreasing the pitch and clipping the video window. */
+ /* The VG will fetch extra data for each line, but the decreased */
+ /* pitch will ensure that it always begins fetching at the start of */
+ /* the video line. */
+
+ vcfg = READ_VID32(CASTLE_VIDEO_CONFIG);
+
+ vid_420 = vcfg & CASTLE_VCFG_4_2_0_MODE;
+
+ vcfg &=
+ ~(CASTLE_VCFG_LINE_SIZE_LOWER_MASK | CASTLE_VCFG_LINE_SIZE_UPPER |
+ CASTLE_VCFG_LINE_SIZE_BIT9);
+
+ size = ((width >> 1) + 7) & 0xFFF8;
+ pitch = ((width << 1) + 7) & 0xFFF8;
+
+ vcfg |= (size & 0x00FF) << 8;
+ if (size & 0x0100)
+ vcfg |= CASTLE_VCFG_LINE_SIZE_UPPER;
+ if (size & 0x0200)
+ vcfg |= CASTLE_VCFG_LINE_SIZE_BIT9;
+ WRITE_VID32(CASTLE_VIDEO_CONFIG, vcfg);
+
+ /* WRITE THE VIDEO HEIGHT */
+
+ scale = READ_VID32(CASTLE_VIDEO_SCALER);
+ scale = (scale & ~0x7FF) | height;
+ WRITE_VID32(CASTLE_VIDEO_SCALER, scale);
+
+ /* SET VIDEO BUFFER LINE SIZE IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_size(width, height);
+
+ /* SET VIDEO PITCH */
+ /* We are only maintaining legacy for 4:2:2 video formats. */
+ /* 4:2:0 video in previous chips was inadequate for most */
+ /* common video formats. */
+
+ if (!vid_420)
+ gfx_set_video_yuv_pitch(pitch, pitch << 1);
+
+ 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
+castle_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_yuv_offsets
+ *
+ * This routine sets the starting offset for the video buffer when displaying
+ * 4:2:0 video.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
+ unsigned long voffset)
+#else
+int
+gfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
+ unsigned long voffset)
+#endif
+{
+ /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
+
+ gfx_vid_offset = yoffset;
+ gfx_vid_uoffset = uoffset;
+ gfx_vid_voffset = voffset;
+
+ /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_yuv_offsets(yoffset, uoffset, voffset);
+
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_yuv_pitch
+ *
+ * This routine sets the byte offset between consecutive scanlines of YUV video data
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#else
+int
+gfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#endif
+{
+ /* SET VIDEO PITCH IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_yuv_pitch(ypitch, uvpitch);
+
+ 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
+castle_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, i;
+ unsigned long scale;
+ unsigned long temp;
+
+ /* SAVE PARAMETERS */
+ /* These are needed for clipping the video window later. Zero */
+ /* values indicate that the corresponding scale value should */
+ /* not be changed. */
+
+ if (dstw != 0) {
+ gfx_vid_srcw = srcw;
+ gfx_vid_dstw = dstw;
+ }
+ if (dsth != 0) {
+ gfx_vid_srch = srch;
+ gfx_vid_dsth = dsth;
+ }
+
+ /* CALCULATE DISPLAY FILTER SCALE FACTORS */
+ /* Zero width and height indicate don't care conditions */
+
+ if (dstw != 0) {
+ if (dstw <= srcw)
+ xscale = 0x10000;
+ else
+ xscale = (0x10000 * (unsigned long)srcw) / (unsigned long)dstw;
+
+ WRITE_VID32(CASTLE_VIDEO_XSCALE, xscale);
+ }
+ if (dsth != 0) {
+ if (dsth <= srch)
+ yscale = 0x10000;
+ else
+ yscale = (0x10000 * (unsigned long)srch) / (unsigned long)dsth;
+
+ WRITE_VID32(CASTLE_VIDEO_YSCALE, yscale);
+ }
+
+ /* ENABLE OR DISABLE FILTERING */
+
+ temp = READ_VID32(CASTLE_VIDEO_CONFIG);
+ if (READ_VID32(CASTLE_VIDEO_XSCALE) == 0x10000 &&
+ READ_VID32(CASTLE_VIDEO_YSCALE) == 0x10000) {
+ WRITE_VID32(CASTLE_VIDEO_CONFIG, (temp | CASTLE_VCFG_SC_BYP));
+ } else {
+ scale = READ_VID32(CASTLE_VIDEO_SCALER);
+
+ WRITE_VID32(CASTLE_VIDEO_SCALER, scale & ~CASTLE_SCALE_128_PHASES);
+ WRITE_VID32(CASTLE_VIDEO_CONFIG, (temp & ~CASTLE_VCFG_SC_BYP));
+
+ /* PROGRAM THE COEFFICIENTS */
+
+ for (i = 0; i < 256; i++) {
+ WRITE_VID32((CASTLE_COEFFICIENT_BASE + (i << 3)),
+ DurangoVideoFilter[i][0]);
+ WRITE_VID32((CASTLE_COEFFICIENT_BASE + (i << 3) + 4),
+ DurangoVideoFilter[i][1]);
+ }
+ }
+ /* CALL ROUTINE TO UPDATE WINDOW POSITION */
+ /* This is required because the scale values affect 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
+ * x and y positions are 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
+castle_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 hadjust, vadjust;
+ unsigned long xstart, ystart, xend, yend;
+ unsigned long lock;
+
+ lock = READ_REG32(DC3_UNLOCK);
+
+ /* 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() - 14l;
+ vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
+
+ /* LEFT CLIPPING */
+
+ if (x < 0) {
+ gfx_set_video_left_crop((unsigned short)(-x));
+ xstart = hadjust;
+ } else {
+ gfx_set_video_left_crop(0);
+ xstart = (unsigned long)x + hadjust;
+ }
+
+ /* HORIZONTAL END */
+ /* End positions in register are non-inclusive (one more than the actual
+ * end) */
+
+ if ((x + w) < gfx_get_hactive())
+ xend = (unsigned long)x + (unsigned long)w + hadjust;
+
+ /* RIGHT-CLIPPING */
+ else
+ xend = (unsigned long)gfx_get_hactive() + hadjust;
+
+ /* VERTICAL START */
+
+ ystart = (unsigned long)y + vadjust;
+
+ /* VERTICAL END */
+
+ if ((y + h) < gfx_get_vactive())
+ yend = (unsigned long)y + (unsigned long)h + vadjust;
+
+ /* BOTTOM-CLIPPING */
+ else
+ yend = (unsigned long)gfx_get_vactive() + vadjust;
+
+ /* SET VIDEO POSITION */
+
+ WRITE_VID32(CASTLE_VIDEO_X_POS, (xend << 16) | xstart);
+ WRITE_VID32(CASTLE_VIDEO_Y_POS, (yend << 16) | ystart);
+
+ /* SET COLOR KEY REGION */
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_COLOR_KEY_X,
+ ((xend - hadjust) << 16) | (xstart - hadjust));
+ WRITE_REG32(DC3_COLOR_KEY_Y,
+ ((yend - vadjust) << 16) | (ystart - vadjust));
+ WRITE_REG32(DC3_UNLOCK, lock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_left_crop
+ *
+ * This routine sets the number of pixels which will be cropped from the
+ * beginning of each video line. The video window will begin to display only
+ * from the pixel following the cropped pixels, and the cropped pixels
+ * will be ignored.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_left_crop(unsigned short x)
+#else
+int
+gfx_set_video_left_crop(unsigned short x)
+#endif
+{
+ unsigned long vcfg, initread;
+
+ vcfg = READ_VID32(CASTLE_VIDEO_CONFIG) & ~CASTLE_VCFG_INIT_READ_MASK;
+
+ /* CLIPPING ON LEFT */
+ /* Adjust initial read for scale, checking for divide by zero. All video */
+ /* formats must be clipped on a 4-pixel boundary */
+
+ if (gfx_vid_dstw) {
+ initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw;
+ } else
+ initread = 0;
+
+ /* SET INITIAL READ ADDRESS */
+
+ vcfg = vcfg | ((initread << 14) & CASTLE_VCFG_INIT_READ_MASK);
+ WRITE_VID32(CASTLE_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))
+ *
+ * If "graphics" is set to TRUE, the source data is graphics, and color key
+ * is an RGB value. If "graphics" is set to FALSE, the source data is video,
+ * and the color key is an RGB value that is compared to the video data after
+ * it has gone through color space conversion (CSC).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_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;
+
+ /* ENABLE OR DISABLE COLOR KEY LOGIC IN THE DISPLAY CONTROLLER */
+ /* When chroma key is enabled, the color key logic should be */
+ /* disabled in the VG to allow for per-pixel alpha blending. */
+
+ gfx_set_display_video_color_key(key, mask, graphics);
+
+ dcfg = READ_VID32(CASTLE_DISPLAY_CONFIG);
+
+ if (graphics)
+ dcfg &= ~CASTLE_DCFG_VG_CK;
+ else
+ dcfg |= CASTLE_DCFG_VG_CK;
+
+ WRITE_VID32(CASTLE_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32(CASTLE_VIDEO_COLOR_KEY, key & 0xFFFFFF);
+ WRITE_VID32(CASTLE_VIDEO_COLOR_MASK, mask & 0xFFFFFF);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette
+ *
+ * This routine loads the video hardware palette. If a NULL pointer is
+ * specified, the palette is bypassed (for Castle, this means loading the
+ * palette with identity values).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_palette(unsigned long *palette)
+#else
+int
+gfx_set_video_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i, entry;
+
+ /* LOAD CASTLE VIDEO PALETTE */
+
+ WRITE_VID32(CASTLE_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ if (palette)
+ entry = palette[i];
+ else
+ entry = i | (i << 8) | (i << 16);
+ WRITE_VID32(CASTLE_PALETTE_DATA, entry);
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_entry
+ *
+ * This routine loads a single entry of the video hardware palette.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_palette_entry(unsigned long index, unsigned long palette)
+#else
+int
+gfx_set_video_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* SET A SINGLE ENTRY */
+
+ WRITE_VID32(CASTLE_PALETTE_ADDRESS, index);
+ WRITE_VID32(CASTLE_PALETTE_DATA, palette);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_request()
+ *
+ * This routine sets the horizontal (pixel) and vertical (line) video request
+ * values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_request(short x, short y)
+#else
+int
+gfx_set_video_request(short x, short y)
+#endif
+{
+ /* SET DISPLAY FILTER VIDEO REQUEST */
+
+ x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ if ((x < 0) || (x > CASTLE_VIDEO_REQUEST_MASK) ||
+ (y < 0) || (y > CASTLE_VIDEO_REQUEST_MASK))
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_VID32(CASTLE_VIDEO_REQUEST,
+ ((unsigned long)x << CASTLE_VIDEO_X_REQUEST_POS) | ((unsigned long)y
+ << CASTLE_VIDEO_Y_REQUEST_POS));
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_cursor()
+ *
+ * This routine configures the video hardware cursor.
+ * If the "mask"ed bits in the graphics pixel match "key", then either
+ * "color1"or "color2" will be used for this pixel, according to the value of
+ * bit number "select_color2" of the graphics pixel.
+ *
+ * key - 24 bit RGB value
+ * mask - 24 bit mask
+ * color1, color2 - RGB or YUV, depending on the current color space
+ * conversion select_color2 - value between 0 to 23
+ *
+ * To disable match, a "mask" and "key" value of 0xffffff should be set,
+ * because the graphics pixels incoming to the video processor have maximum 16
+ * bits set (0xF8FCF8).
+ *
+ * This feature is useful for disabling alpha blending of the cursor.
+ * Otherwise cursor image would be blurred (or completely invisible if video
+ * alpha is maximum value).
+ * Note: the cursor pixel replacements take place both inside and outside the
+ * video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2)
+#else
+int
+gfx_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2)
+#endif
+{
+ if (select_color2 > CASTLE_CURSOR_COLOR_BITS)
+ return GFX_STATUS_BAD_PARAMETER;
+ key =
+ (key & CASTLE_COLOR_MASK) | ((unsigned long)select_color2 <<
+ CASTLE_CURSOR_COLOR_KEY_OFFSET_POS);
+ WRITE_VID32(CASTLE_CURSOR_COLOR_KEY, key);
+ WRITE_VID32(CASTLE_CURSOR_COLOR_MASK, mask);
+ WRITE_VID32(CASTLE_CURSOR_COLOR_1, color1);
+ WRITE_VID32(CASTLE_CURSOR_COLOR_2, color2);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_cursor_enable()
+ *
+ * This routine enables or disables the cursor color key mechanism.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_video_cursor_enable(int enable)
+#else
+int
+gfx_set_video_cursor_enable(int enable)
+#endif
+{
+ unsigned long temp = READ_VID32(CASTLE_CURSOR_COLOR_KEY);
+
+ if (enable)
+ temp |= CASTLE_CURSOR_COLOR_KEY_ENABLE;
+ else
+ temp &= ~CASTLE_CURSOR_COLOR_KEY_ENABLE;
+
+ WRITE_VID32(CASTLE_CURSOR_COLOR_KEY, temp);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_enable
+ *
+ * This routine enables or disables the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_alpha_enable(int enable)
+#else
+int
+gfx_set_alpha_enable(int enable)
+#endif
+{
+ unsigned long address = 0, value = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = CASTLE_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5);
+ value = READ_VID32(address);
+ if (enable)
+ value |= CASTLE_ACTRL_WIN_ENABLE;
+ else
+ value &= ~(CASTLE_ACTRL_WIN_ENABLE);
+ WRITE_VID32(address, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_window
+ *
+ * This routine sets the size of the currently selected alpha region.
+ * Note: "x" and "y" are signed to enable using negative values needed for
+ * implementing workarounds of hardware issues.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height)
+#else
+int
+gfx_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long address = 0;
+
+ /* CHECK FOR CLIPPING */
+
+ if ((x + width) > gfx_get_hactive())
+ width = gfx_get_hactive() - x;
+ if ((y + height) > gfx_get_vactive())
+ height = gfx_get_vactive() - y;
+
+ /* ADJUST POSITIONS */
+
+ x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = CASTLE_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 5);
+
+ /* END POSITIONS IN REGISTERS ARE NON-INCLUSIVE (ONE MORE THAN ACTUAL END)
+ * */
+
+ WRITE_VID32(address, (unsigned long)x |
+ ((unsigned long)(x + width) << 16));
+ WRITE_VID32(address + 8, (unsigned long)y |
+ ((unsigned long)(y + height) << 16));
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_value
+ *
+ * This routine sets the alpha value for the currently selected alpha
+ * region. It also specifies an increment/decrement value for fading.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_alpha_value(unsigned char alpha, char delta)
+#else
+int
+gfx_set_alpha_value(unsigned char alpha, char delta)
+#endif
+{
+ unsigned long address = 0, value = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = CASTLE_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5);
+ value = READ_VID32(address);
+ value &= CASTLE_ACTRL_WIN_ENABLE; /* keep only enable bit */
+ value |= (unsigned long)alpha;
+ value |= (((unsigned long)delta) & 0xff) << 8;
+ value |= CASTLE_ACTRL_LOAD_ALPHA;
+ WRITE_VID32(address, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_priority
+ *
+ * This routine sets the priority of the currently selected alpha region.
+ * A higher value indicates a higher priority.
+ * Note: Priority of enabled alpha windows must be different.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_alpha_priority(int priority)
+#else
+int
+gfx_set_alpha_priority(int priority)
+#endif
+{
+ unsigned long pos = 0, value = 0;
+
+ if (priority > 3)
+ return (GFX_STATUS_BAD_PARAMETER);
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ value = READ_VID32(CASTLE_VID_ALPHA_CONTROL);
+ pos = 16 + (gfx_alpha_select << 1);
+ value &= ~(0x03l << pos);
+ value |= (unsigned long)priority << pos;
+ WRITE_VID32(CASTLE_VID_ALPHA_CONTROL, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color
+ *
+ * This routine sets the color to be displayed inside the currently selected
+ * alpha window when there is a color key match (when the alpha color
+ * mechanism is enabled).
+ * "color" is an RGB value (for RGB blending) or a YUV value (for YUV
+ * blending).
+ * In Interlaced YUV blending mode, Y/2 value should be used.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_alpha_color(unsigned long color)
+#else
+int
+gfx_set_alpha_color(unsigned long color)
+#endif
+{
+ unsigned long address = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = CASTLE_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5);
+ WRITE_VID32(address, color);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color_enable
+ *
+ * Enable or disable the color mechanism in the alpha window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_alpha_color_enable(int enable)
+#else
+int
+gfx_set_alpha_color_enable(int enable)
+#endif
+{
+ unsigned long color;
+ unsigned long address = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = CASTLE_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5);
+ color = READ_VID32(address);
+ if (enable)
+ color |= CASTLE_ALPHA_COLOR_ENABLE;
+ else
+ color &= ~CASTLE_ALPHA_COLOR_ENABLE;
+ WRITE_VID32(address, color);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_no_ck_outside_alpha
+ *
+ * This function affects where inside the video window color key or chroma
+ * key comparison is done:
+ * If enable is TRUE, color/chroma key comparison is performed only inside
+ * the enabled alpha windows. Outside the (enabled) alpha windows, only video
+ * is displayed if color key is used, and only graphics is displayed if chroma
+ * key is used.
+ * If enable is FALSE, color/chroma key comparison is performed in all the
+ * video window area.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_set_no_ck_outside_alpha(int enable)
+#else
+int
+gfx_set_no_ck_outside_alpha(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VID32(CASTLE_VID_ALPHA_CONTROL);
+ if (enable)
+ WRITE_VID32(CASTLE_VID_ALPHA_CONTROL,
+ value | CASTLE_NO_CK_OUTSIDE_ALPHA);
+ else
+ WRITE_VID32(CASTLE_VID_ALPHA_CONTROL,
+ value & ~CASTLE_NO_CK_OUTSIDE_ALPHA);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+castle_get_clock_frequency(void)
+#else
+unsigned long
+gfx_get_clock_frequency(void)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned int index;
+ unsigned long value, mask = 0x00001FFF;
+
+ /* READ PLL SETTING */
+
+ gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+ value = msr_value.high & mask;
+
+ /* SEARCH FOR A MATCH */
+
+ for (index = 0; index < NUM_CASTLE_FREQUENCIES; index++) {
+ if ((CASTLE_PLLtable[index].pll_value & mask) == value)
+ return (CASTLE_PLLtable[index].frequency);
+ }
+ 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
+castle_get_sync_polarities(void)
+#else
+int
+gfx_get_sync_polarities(void)
+#endif
+{
+ int polarities = 0;
+
+ if (READ_VID32(CASTLE_DISPLAY_CONFIG) & CASTLE_DCFG_CRT_HSYNC_POL)
+ polarities |= 1;
+ if (READ_VID32(CASTLE_DISPLAY_CONFIG) & CASTLE_DCFG_CRT_VSYNC_POL)
+ polarities |= 2;
+ return (polarities);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_palette_entry
+ *
+ * This routine returns a single palette entry.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int
+gfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* READ A SINGLE ENTRY */
+
+ WRITE_VID32(CASTLE_PALETTE_ADDRESS, index);
+ *palette = READ_VID32(CASTLE_PALETTE_DATA);
+
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * 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
+castle_get_video_enable(void)
+#else
+int
+gfx_get_video_enable(void)
+#endif
+{
+ if (READ_VID32(CASTLE_VIDEO_CONFIG) & CASTLE_VCFG_VID_EN)
+ return (1);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_format
+ *
+ * This routine returns the current video overlay format.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_get_video_format(void)
+#else
+int
+gfx_get_video_format(void)
+#endif
+{
+ unsigned long ctrl, vcfg;
+
+ ctrl = READ_VID32(CASTLE_VID_ALPHA_CONTROL);
+ vcfg = READ_VID32(CASTLE_VIDEO_CONFIG);
+
+ if (ctrl & CASTLE_VIDEO_INPUT_IS_RGB) {
+ switch (vcfg & CASTLE_VCFG_VID_INP_FORMAT) {
+ case CASTLE_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_RGB;
+ case CASTLE_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_P2M_P2L_P1M_P1L;
+ case CASTLE_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_P1M_P1L_P2M_P2L;
+ case CASTLE_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_P1M_P2L_P2M_P1L;
+ }
+ }
+
+ if (vcfg & CASTLE_VCFG_4_2_0_MODE) {
+ switch (vcfg & CASTLE_VCFG_VID_INP_FORMAT) {
+ case CASTLE_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_Y0Y1Y2Y3;
+ case CASTLE_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_Y3Y2Y1Y0;
+ case CASTLE_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_Y1Y0Y3Y2;
+ case CASTLE_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_Y1Y2Y3Y0;
+ }
+ } else {
+ switch (vcfg & CASTLE_VCFG_VID_INP_FORMAT) {
+ case CASTLE_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_UYVY;
+ case CASTLE_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_Y2YU;
+ case CASTLE_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_YUYV;
+ case CASTLE_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_YVYU;
+ }
+ }
+ return (GFX_STATUS_ERROR);
+}
+
+/*----------------------------------------------------------------------------
+ * 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
+castle_get_video_src_size(void)
+#else
+unsigned long
+gfx_get_video_src_size(void)
+#endif
+{
+ unsigned long width, height;
+
+ /* DETERMINE SOURCE WIDTH FROM THE DISPLAY FILTER VIDEO LINE SIZE */
+
+ width = (READ_VID32(CASTLE_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(CASTLE_VIDEO_CONFIG) & CASTLE_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+ if (READ_VID32(CASTLE_VIDEO_CONFIG) & CASTLE_VCFG_LINE_SIZE_BIT9)
+ width += 1024l;
+
+ /* DETERMINE SOURCE HEIGHT FROM THE DISPLAY FILTER SCALE REGISTER */
+
+ height = READ_VID32(CASTLE_VIDEO_SCALER) & 0x7FF;
+
+ 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
+castle_get_video_line_size(void)
+#else
+unsigned long
+gfx_get_video_line_size(void)
+#endif
+{
+ unsigned long width = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE CASTLE VIDEO LINE SIZE */
+
+ width = (READ_VID32(CASTLE_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(CASTLE_VIDEO_CONFIG) & CASTLE_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+ 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
+castle_get_video_xclip(void)
+#else
+unsigned long
+gfx_get_video_xclip(void)
+#endif
+{
+ unsigned long clip = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE CASTLE VIDEO LINE SIZE */
+
+ clip = ((READ_VID32(CASTLE_VIDEO_CONFIG) >> 16) & 0x001FF) << 3;
+ return (clip);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_offset
+ *
+ * This routine returns the current offset for the video overlay buffer.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+castle_get_video_offset(void)
+#else
+unsigned long
+gfx_get_video_offset(void)
+#endif
+{
+ return (gfx_get_display_video_offset());
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_yuv_offsets
+ *
+ * This routine returns the current offsets for the video overlay buffer when in 4:2:0.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+castle_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
+ unsigned long *voffset)
+#else
+void
+gfx_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
+ unsigned long *voffset)
+#endif
+{
+ gfx_get_display_video_yuv_offsets(yoffset, uoffset, voffset);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_yuv_pitch
+ *
+ * This routine returns the current pitch values for the video overlay buffer.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+castle_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#else
+void
+gfx_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#endif
+{
+ gfx_get_display_video_yuv_pitch(ypitch, uvpitch);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_dst_size
+ *
+ * This routine returns the size of the displayed video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+castle_get_video_dst_size(void)
+#else
+unsigned long
+gfx_get_video_dst_size(void)
+#endif
+{
+ unsigned long xsize, ysize;
+
+ xsize = READ_VID32(CASTLE_VIDEO_X_POS);
+ xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF);
+ ysize = READ_VID32(CASTLE_VIDEO_Y_POS);
+ ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF);
+ 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
+castle_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(CASTLE_VIDEO_X_POS) & 0x000007FF;
+ ypos = READ_VID32(CASTLE_VIDEO_Y_POS) & 0x000007FF;
+
+ /* GET ADJUSTMENT VALUES */
+ /* Use routines to abstract version of display controller. */
+
+ hadjust =
+ (unsigned long)gfx_get_htotal() - (unsigned long)gfx_get_hsync_end() -
+ 14l;
+ vadjust =
+ (unsigned long)gfx_get_vtotal() - (unsigned long)gfx_get_vsync_end() +
+ 1l;
+ 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
+castle_get_video_color_key(void)
+#else
+unsigned long
+gfx_get_video_color_key(void)
+#endif
+{
+ if (READ_VID32(CASTLE_DISPLAY_CONFIG) & CASTLE_DCFG_VG_CK)
+ return (READ_VID32(CASTLE_VIDEO_COLOR_KEY));
+ else
+ return (gfx_get_display_video_color_key());
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key_mask
+ *
+ * This routine returns the current video color mask value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+castle_get_video_color_key_mask(void)
+#else
+unsigned long
+gfx_get_video_color_key_mask(void)
+#endif
+{
+ if (READ_VID32(CASTLE_DISPLAY_CONFIG) & CASTLE_DCFG_VG_CK)
+ return (READ_VID32(CASTLE_VIDEO_COLOR_MASK));
+ else
+ return (gfx_get_display_video_color_key_mask());
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key_src
+ *
+ * This routine returns 0 for video data compare, 1 for graphics data.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_get_video_color_key_src(void)
+#else
+int
+gfx_get_video_color_key_src(void)
+#endif
+{
+ if (READ_VID32(CASTLE_DISPLAY_CONFIG) & CASTLE_DCFG_VG_CK)
+ return (0);
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_request
+ *
+ * This routine returns the horizontal (pixel) and vertical (lines) video
+ * request values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_get_video_request(short *x, short *y)
+#else
+int
+gfx_get_video_request(short *x, short *y)
+#endif
+{
+ unsigned long request = 0;
+
+ request = (READ_VID32(CASTLE_VIDEO_REQUEST));
+ *x = (short)((request >> CASTLE_VIDEO_X_REQUEST_POS) &
+ CASTLE_VIDEO_REQUEST_MASK);
+ *y = (short)((request >> CASTLE_VIDEO_Y_REQUEST_POS) &
+ CASTLE_VIDEO_REQUEST_MASK);
+
+ *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_cursor()
+ *
+ * This routine configures the video hardware cursor.
+ * If the "mask"ed bits in the graphics pixel match "key", then either
+ * "color1" or "color2" will be used for this pixel, according to the value of
+ * the bit in offset "select_color2".
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+castle_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2)
+#else
+int
+gfx_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2)
+#endif
+{
+ *select_color2 =
+ (unsigned short)(READ_VID32(CASTLE_CURSOR_COLOR_KEY) >>
+ CASTLE_CURSOR_COLOR_KEY_OFFSET_POS);
+ *key = READ_VID32(CASTLE_CURSOR_COLOR_KEY) & CASTLE_COLOR_MASK;
+ *mask = READ_VID32(CASTLE_CURSOR_COLOR_MASK) & CASTLE_COLOR_MASK;
+ *color1 = READ_VID32(CASTLE_CURSOR_COLOR_1) & CASTLE_COLOR_MASK;
+ *color2 =
+ (unsigned short)(READ_VID32(CASTLE_CURSOR_COLOR_2) &
+ CASTLE_COLOR_MASK);
+ 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
+castle_read_crc(void)
+#else
+unsigned long
+gfx_read_crc(void)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned long crc = 0xFFFFFFFF;
+
+ /* DISABLE 32-BIT CRCS */
+ /* For GX1.x, this is a reserved bit, and is assumed to be a benign
+ * access */
+
+ gfx_msr_read(RC_ID_DF, CASTLE_MBD_MSR_DIAG_DF, &msr_value);
+ msr_value.low &= ~CASTLE_DIAG_32BIT_CRC;
+ gfx_msr_write(RC_ID_DF, CASTLE_MBD_MSR_DIAG_DF, &msr_value);
+
+ if (gfx_test_timing_active()) {
+ /* WAIT UNTIL ACTIVE DISPLAY */
+
+ while (!gfx_test_vertical_active()) ;
+
+ /* RESET CRC DURING ACTIVE DISPLAY */
+
+ WRITE_VID32(CASTLE_VID_CRC, 0);
+ WRITE_VID32(CASTLE_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()) ;
+ while (!gfx_test_vertical_active()) ;
+ crc = READ_VID32(CASTLE_VID_CRC) >> 8;
+ }
+ return (crc);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_read_crc32
+ *
+ * This routine returns the 32-bit 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
+castle_read_crc32(void)
+#else
+unsigned long
+gfx_read_crc32(void)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned long crc = 0xFFFFFFFF;
+
+ /* ENABLE 32-BIT CRCS */
+ /* For GX1.x, this is a reserved bit, and is assumed to be a benign
+ * access */
+
+ gfx_msr_read(RC_ID_DF, CASTLE_MBD_MSR_DIAG_DF, &msr_value);
+ msr_value.low |= CASTLE_DIAG_32BIT_CRC;
+ gfx_msr_write(RC_ID_DF, CASTLE_MBD_MSR_DIAG_DF, &msr_value);
+
+ if (gfx_test_timing_active()) {
+ /* WAIT UNTIL ACTIVE DISPLAY */
+
+ while (!gfx_test_vertical_active()) ;
+
+ /* RESET CRC DURING ACTIVE DISPLAY */
+
+ WRITE_VID32(CASTLE_VID_CRC, 0);
+ WRITE_VID32(CASTLE_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()) ;
+ while (!gfx_test_vertical_active()) ;
+ crc = READ_VID32(CASTLE_VID_CRC32);
+ }
+ return (crc);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_read_window_crc
+ *
+ * This routine returns the hardware CRC value for a subsection of the display
+ * This value is used to debug whole-screen CRC failures.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+castle_read_window_crc(int source, unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, int crc32)
+#else
+unsigned long
+gfx_read_window_crc(int source, unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, int crc32)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned long xpos, ypos, crc = 0;
+ unsigned long old_fmt = 0;
+ unsigned int vsync_active_base, vsync_inactive_base, hsync_active_base;
+ unsigned int vsync_active_shift, vsync_inactive_shift, hsync_active_shift;
+ unsigned int vsync_bit, hsync_bit, sync_polarities = 0;
+
+ /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */
+
+ msr_value.high = 0;
+ msr_value.low =
+ (source == CRC_SOURCE_GFX_DATA) ? (RCDF_MBD_DIAG_EN0 | 0x0000000F)
+ : (RCDF_MBD_DIAG_EN0 | 0x0000000B);
+ gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
+
+ /* CONFIGURE DISPLAY FILTER FOR APPROPRIATE OUTPUT */
+
+ if (source != CRC_SOURCE_GFX_DATA) {
+ gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ old_fmt = msr_value.low;
+ msr_value.low &= ~(RCDF_CONFIG_FMT_MASK);
+ msr_value.low |=
+ ((source ==
+ CRC_SOURCE_FP_DATA) ? RCDF_CONFIG_FMT_FP :
+ RCDF_CONFIG_FMT_CRT);
+ gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ }
+
+ /* CONFIGURE MCP TO LOAD REGB DATA ONTO UPPER 32-BITS */
+
+ msr_value.low = MCP_MBD_DIAG_EN1 | 0x00050000;
+ gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
+
+ /* ENABLE HW CLOCK GATING AND SET MCP CLOCK TO DOT CLOCK */
+
+ msr_value.low = 1l;
+ gfx_msr_write(RC_ID_MCP, MBD_MSR_PM, &msr_value);
+ msr_value.low = 0;
+ gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
+ msr_value.low = 3;
+ gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
+
+ /* DISABLE MCP ACTIONS */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
+
+ /* SET APPROPRIATE BASE ADDRESS */
+ /* M-Sets use normal diag bits, while N-Sets use inverted diag bits */
+ /* We thus use the M-sets when polling for a high signal and the N */
+ /* sets when polling for a low signal. */
+
+ if (source != CRC_SOURCE_GFX_DATA) {
+ sync_polarities = gfx_get_sync_polarities();
+ vsync_bit = 29;
+ hsync_bit = 30;
+ } else {
+ vsync_bit = 25;
+ hsync_bit = 26;
+ }
+
+ if (sync_polarities & 1) {
+ hsync_active_base = MCP_SETM0CTL;
+ hsync_active_shift = 2;
+ } else {
+ hsync_active_base = MCP_SETN0CTL;
+ hsync_active_shift = 1;
+ }
+ if (sync_polarities & 2) {
+ vsync_active_base = MCP_SETM0CTL;
+ vsync_inactive_base = MCP_SETN0CTL;
+ vsync_active_shift = 2;
+ vsync_inactive_shift = 1;
+ } else {
+ vsync_active_base = MCP_SETN0CTL;
+ vsync_inactive_base = MCP_SETM0CTL;
+ vsync_active_shift = 1;
+ vsync_inactive_shift = 2;
+ }
+
+ /* SET STATE TRANSITIONS */
+
+ /* STATE 0-1 TRANSITION (SET 0) */
+ /* XState = 00 and VSync Inactive */
+ /* Note: DF VSync = Diag Bus Bit 29 */
+ /* VG VSync = Diag Bus Bit 25 */
+
+ msr_value.low = 0x000000A0;
+ msr_value.high = 0x00008000 | ((unsigned long)vsync_bit << 16) |
+ ((unsigned long)vsync_bit << 21) | ((unsigned long)vsync_bit << 26);
+ gfx_msr_write(RC_ID_MCP, vsync_inactive_base, &msr_value);
+
+ /* STATE 1-2 TRANSITION (SET 4) */
+ /* XState = 01 and VSync Active */
+
+ msr_value.low = 0x000000C0;
+ gfx_msr_write(RC_ID_MCP, vsync_active_base + 4, &msr_value);
+
+ /* STATE 2-3 TRANSITION (SET 1) */
+ /* XState = 10 and VSync Inactive */
+
+ msr_value.low = 0x00000120;
+ gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 1, &msr_value);
+
+ /* HORIZONTAL COUNTER (SET 5) */
+ /* XState = 10 and HSync Active */
+ /* Notes: DF HSync = Diag Bus Bit 30 */
+ /* VG HSync = Diag Bus Bit 26 */
+
+ msr_value.high = 0x00008000 | ((unsigned long)hsync_bit << 16) |
+ ((unsigned long)hsync_bit << 21) | ((unsigned long)hsync_bit << 26);
+ msr_value.low = 0x00000120;
+ gfx_msr_write(RC_ID_MCP, hsync_active_base + 5, &msr_value);
+
+ /* HORIZONTAL COUNTER RESET (SET 4) */
+ /* XState = 10 and H. Counter = limit */
+ /* Note: H. Counter is lower 16-bits of */
+ /* RegB. */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000128;
+ gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 4, &msr_value);
+
+ /* CRC TRIGGER (SET 0) */
+ /* Cmp0 <= xpos < Cmp1 */
+ /* Cmp2 <= ypos < Cmp2 */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x10C20120;
+ gfx_msr_write(RC_ID_MCP, vsync_active_base, &msr_value);
+
+ /* SET COMPARATOR VALUES */
+ /* Note: The VG data outputs from the DF are delayed by one pixel clock. */
+ /* In this mode, we thus add one to horizontal comparator limits. */
+
+ /* COMPARATOR 0 */
+ /* Lower limit = xpos + (h_blank_pixels - 1) - 3 */
+ /* Notes: */
+ /* 1. 3 is the pipeline delay for MCP register */
+ /* data to access the diag bus */
+ /* 2. h_blank_pixels = HTOTAL - HSYNC_END */
+
+ xpos = (unsigned long)x + ((unsigned long)gfx_get_htotal() -
+ (unsigned long)gfx_get_hsync_end() - 1l) - 3l;
+ if (source == CRC_SOURCE_GFX_DATA)
+ xpos++;
+ msr_value.high = 0x00000000;
+ msr_value.low = xpos;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0, &msr_value);
+
+ /* COMPARATOR 1 */
+ /* Upper limit = xpos + width + (h_blank_pixels - 1) - 3 */
+
+ msr_value.low = xpos + (unsigned long)width;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 2, &msr_value);
+
+ /* COMPARATOR 2 */
+ /* Lower limit = ypos + v_blank_pixels */
+ /* Notes: */
+ /* 1. v_blank_pixels = VTOTAL - VSYNC_END */
+
+ ypos =
+ (unsigned long)y + (unsigned long)gfx_get_vtotal() -
+ (unsigned long)gfx_get_vsync_end();
+ msr_value.low = ypos << 16;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 4, &msr_value);
+
+ /* COMPARATOR 3 */
+ /* Upper limit = ypos + height + v_blank_pixels */
+
+ msr_value.low = (ypos + (unsigned long)height) << 16;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 6, &msr_value);
+
+ /* SET COMPARATOR MASKS */
+
+ /* COMPARATORS 0 AND 1 REFER TO LOWER 16 BITS OF REGB */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x0000FFFF;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 2, &msr_value);
+
+ /* COMPARATORS 2 AND 3 REFER TO UPPER 16 BITS OF REGB */
+
+ msr_value.low = 0xFFFF0000;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 4, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 6, &msr_value);
+
+ /* SET REGA MASK TO CRC ONLY 24 BITS OF DATA */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00FFFFFF;
+ gfx_msr_write(RC_ID_MCP, MCP_REGAMASK, &msr_value);
+
+ /* SET REGB VALUE */
+ /* Lower 16 bits use HTOTAL - SYNC TIME - 1 to set the counter rollover
+ * limit. */
+ /* Upper 16 bits use 0xFFFF to remove auto-clear behavior. */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0xFFFF0000 |
+ ((gfx_get_htotal() - (gfx_get_hsync_end() - gfx_get_hsync_start()) -
+ 1) & 0xFFFF);
+ gfx_msr_write(RC_ID_MCP, MCP_REGBVAL, &msr_value);
+
+ /* PROGRAM ACTIONS */
+
+ /* GOTO STATE 01 */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000008 | (1l << vsync_inactive_shift);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 14, &msr_value);
+
+ /* GOTO STATE 10 */
+
+ msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 15, &msr_value);
+
+ /* GOTO STATE 11 */
+
+ msr_value.low = 0x00000080 | (1l << (vsync_inactive_shift + 4));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 16, &msr_value);
+
+ /* CLEAR REGB (COUNTERS) */
+ /* RegB is cleared upon transitioning to state 10 */
+ /* RegA is not cleared as the initial value must be 0x00000001 */
+
+ msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0, &msr_value);
+
+ /* CRC INTO REGA */
+ /* INCREMENT H. COUNTER */
+ /* cmp0 <= xpos < cmp1 */
+ /* cmp2 <= ypos < cmp3 */
+ /* XState = 10 */
+
+ msr_value.low = 0x00000008 | (1l << vsync_active_shift) |
+ 0x00800000 | (1l << (hsync_active_shift + 20));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 1, &msr_value);
+
+ /* INCREMENT V. COUNTER */
+ /* V. Counter is incremented when the H. Counter */
+ /* rolls over. */
+
+ msr_value.low = 0x00080000 | (1l << (vsync_inactive_shift + 16));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 2, &msr_value);
+
+ /* CLEAR ALL OTHER ACTIONS */
+ /* This prevents side-effects from previous accesses to the MCP */
+ /* debug logic. */
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 3, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 4, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 5, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 6, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 7, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 8, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 9, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 10, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 11, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 12, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 13, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 17, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 18, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 19, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 20, &msr_value);
+
+ /* SET REGA CRC VALUE TO 1 OR 0 */
+
+ if (!crc32)
+ msr_value.low = 0x00000001;
+ gfx_msr_write(RC_ID_MCP, MCP_REGA, &msr_value);
+
+ /* SET XSTATE TO 0 */
+
+ msr_value.low = 0;
+ msr_value.high = 0;
+ gfx_msr_write(RC_ID_MCP, MCP_XSTATE, &msr_value);
+
+ /* CONFIGURE DIAG CONTROL */
+ /* Set all four comparators to watch the upper diag bus. */
+ /* Set REGA action1 to legacy CRC or 32-bit CRC. */
+ /* Set REGB action1 to increment lower 16 bits and clear at limit. */
+ /* Set REGB action2 to increment upper 16 bits. */
+ /* Enable all actions. */
+
+ if (crc32)
+ msr_value.low = 0x9A820055;
+ else
+ msr_value.low = 0x9A840055;
+ msr_value.high = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
+
+ /* DELAY TWO FRAMES */
+
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+
+ /* VERIFY THAT XSTATE = 11 */
+
+ gfx_msr_read(RC_ID_MCP, MCP_XSTATE, &msr_value);
+ if ((msr_value.low & 3) == 3) {
+ gfx_msr_read(RC_ID_MCP, MCP_REGA, &msr_value);
+
+ crc = msr_value.low;
+ if (!crc32)
+ crc &= 0xFFFFFF;
+ }
+
+ /* DISABLE MCP AND DF DIAG BUS OUTPUTS */
+
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
+
+ /* DISABLE MCP ACTIONS */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
+
+ /* RESTORE PREVIOUS OUTPUT FORMAT */
+
+ if (source != CRC_SOURCE_GFX_DATA) {
+ gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ msr_value.low = old_fmt;
+ gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ }
+ return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_enable
+ *
+ * This routine returns 1 if the selected alpha window is currently
+ * enabled, or 0 if it is currently disabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+castle_get_alpha_enable(int *enable)
+#else
+void
+gfx_get_alpha_enable(int *enable)
+#endif
+{
+ unsigned long value = 0;
+
+ *enable = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(CASTLE_ALPHA_CONTROL_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ if (value & CASTLE_ACTRL_WIN_ENABLE)
+ *enable = 1;
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_size
+ *
+ * This routine returns the size of the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+castle_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height)
+#else
+void
+gfx_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height)
+#endif
+{
+ unsigned long value = 0;
+
+ *x = 0;
+ *y = 0;
+ *width = 0;
+ *height = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(CASTLE_ALPHA_XPOS_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ *x = (unsigned short)(value & 0x000007FF);
+ *width = (unsigned short)((value >> 16) & 0x000007FF) - *x;
+ value =
+ READ_VID32(CASTLE_ALPHA_YPOS_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ *y = (unsigned short)(value & 0x000007FF);
+ *height = (unsigned short)((value >> 16) & 0x000007FF) - *y;
+ }
+ *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_value
+ *
+ * This routine returns the alpha value and increment/decrement value of
+ * the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+castle_get_alpha_value(unsigned char *alpha, char *delta)
+#else
+void
+gfx_get_alpha_value(unsigned char *alpha, char *delta)
+#endif
+{
+ unsigned long value = 0;
+
+ *alpha = 0;
+ *delta = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(CASTLE_ALPHA_CONTROL_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ *alpha = (unsigned char)(value & 0x00FF);
+ *delta = (char)((value >> 8) & 0x00FF);
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_priority
+ *
+ * This routine returns the priority of the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+castle_get_alpha_priority(int *priority)
+#else
+void
+gfx_get_alpha_priority(int *priority)
+#endif
+{
+ unsigned long pos = 0, value = 0;
+
+ *priority = 0;
+ if (gfx_alpha_select <= 2) {
+ value = READ_VID32(CASTLE_VID_ALPHA_CONTROL);
+ pos = 16 + (gfx_alpha_select << 1);
+ *priority = (int)((value >> pos) & 3);
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_color
+ *
+ * This routine returns the color register value for the currently selected
+ * alpha region. Bit 24 is set if the color register is enabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+castle_get_alpha_color(unsigned long *color)
+#else
+void
+gfx_get_alpha_color(unsigned long *color)
+#endif
+{
+ *color = 0;
+ if (gfx_alpha_select <= 2) {
+ *color =
+ READ_VID32(CASTLE_ALPHA_COLOR_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ }
+ return;
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/vid_rdcl.c b/src/gfx/vid_rdcl.c
new file mode 100644
index 0000000..ce03020
--- /dev/null
+++ b/src/gfx/vid_rdcl.c
@@ -0,0 +1,2887 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the Redcloud display filter video
+ * overlay hardware.
+ * */
+
+unsigned long gfx_gamma_ram_redcloud[] = {
+ 0x00000000, 0x00040003, 0x00050104, 0x00060205, 0x00070306, 0x00080407,
+ 0x00090508, 0x000A0609, 0x000B070A, 0x000C080B, 0x000D090C, 0x000E0A0D,
+ 0x000F0B0E, 0x00100C0F, 0x00110D10, 0x00110E11, 0x00120F12, 0x00141013,
+ 0x00151114, 0x00161215, 0x00171316, 0x00181417, 0x00191518, 0x001A1619,
+ 0x001B171A, 0x001C181B, 0x001D191C, 0x001D1A1D, 0x001E1B1E, 0x00201C1F,
+ 0x00201D20, 0x00221E21, 0x00231F22, 0x00242023, 0x00252124, 0x00262225,
+ 0x00262326, 0x00282427, 0x00292528, 0x00292629, 0x002B272A, 0x002C282B,
+ 0x002D292C, 0x002E2A2D, 0x002F2B2E, 0x00302C2F, 0x00312D30, 0x00322E31,
+ 0x00332F32, 0x00343033, 0x00353134, 0x00363235, 0x00373336, 0x00383437,
+ 0x00393538, 0x003A3639, 0x003B373A, 0x003C383B, 0x003D393C, 0x003E3A3D,
+ 0x003F3B3E, 0x00403C3F, 0x00413D40, 0x00423E41, 0x00433F42, 0x00444043,
+ 0x00444144, 0x00454245, 0x00474346, 0x00484447, 0x00494548, 0x004A4649,
+ 0x004B474A, 0x004C484B, 0x004D494C, 0x004E4A4D, 0x004F4B4E, 0x00504C4F,
+ 0x00514D50, 0x00524E51, 0x00534F52, 0x00545053, 0x00555154, 0x00565255,
+ 0x00575356, 0x00585457, 0x00595558, 0x005A5659, 0x005B575A, 0x005C585B,
+ 0x005D595C, 0x005E5A5D, 0x005F5B5E, 0x00605C5F, 0x00615D60, 0x00625E61,
+ 0x00635F62, 0x00646063, 0x00656164, 0x00666265, 0x00676366, 0x00686467,
+ 0x00696568, 0x006A6669, 0x006B676A, 0x006C686B, 0x006D696C, 0x006E6A6D,
+ 0x006F6B6E, 0x00706C6F, 0x00716D70, 0x00726E71, 0x00736F72, 0x00747073,
+ 0x00757174, 0x00767275, 0x00777376, 0x00787477, 0x00797578, 0x007A7679,
+ 0x007B777A, 0x007C787B, 0x007D797C, 0x007E7A7D, 0x007F7B7E, 0x00807C7F,
+ 0x00817D80, 0x00827E81, 0x00837F82, 0x00848083, 0x00858184, 0x00868285,
+ 0x00878386, 0x00888487, 0x00898588, 0x008A8689, 0x008B878A, 0x008C888B,
+ 0x008D898C, 0x008E8A8D, 0x008F8B8E, 0x00908C8F, 0x00918D90, 0x00928E91,
+ 0x00938F92, 0x00949093, 0x00959194, 0x00969295, 0x00979396, 0x00989497,
+ 0x00999598, 0x009A9699, 0x009B979A, 0x009C989B, 0x009D999C, 0x009E9A9D,
+ 0x009F9B9E, 0x00A09C9F, 0x00A19DA0, 0x00A29EA1, 0x00A39FA2, 0x00A4A0A3,
+ 0x00A5A1A4, 0x00A6A2A5, 0x00A7A3A6, 0x00A8A4A7, 0x00A9A5A8, 0x00AAA6A9,
+ 0x00ABA7AA, 0x00ACA8AB, 0x00ADA9AC, 0x00AEAAAD, 0x00AFABAE, 0x00B0ACAF,
+ 0x00B1ADB0, 0x00B2AEB1, 0x00B3AFB2, 0x00B4B0B3, 0x00B5B1B4, 0x00B6B2B5,
+ 0x00B7B3B6, 0x00B8B4B7, 0x00B9B5B8, 0x00BAB6B9, 0x00BBB7BA, 0x00BCB8BB,
+ 0x00BDB9BC, 0x00BEBABD, 0x00BFBBBE, 0x00C0BCBF, 0x00C1BDC0, 0x00C2BEC1,
+ 0x00C3BFC2, 0x00C4C0C3, 0x00C5C1C4, 0x00C6C2C5, 0x00C7C3C6, 0x00C8C4C7,
+ 0x00C9C5C8, 0x00CAC6C9, 0x00CBC7CA, 0x00CCC8CB, 0x00CDC9CC, 0x00CECACD,
+ 0x00CFCBCE, 0x00D0CCCF, 0x00D1CDD0, 0x00D2CED1, 0x00D3CFD2, 0x00D4D0D3,
+ 0x00D5D1D4, 0x00D6D2D5, 0x00D7D3D6, 0x00D8D4D7, 0x00D9D5D8, 0x00DAD6D9,
+ 0x00DBD7DA, 0x00DCD8DB, 0x00DDD9DC, 0x00DEDADD, 0x00DFDBDE, 0x00E0DCDF,
+ 0x00E1DDE0, 0x00E2DEE1, 0x00E3DFE2, 0x00E4E0E3, 0x00E5E1E4, 0x00E6E2E5,
+ 0x00E7E3E6, 0x00E8E4E7, 0x00E9E5E8, 0x00EAE6E9, 0x00EBE7EA, 0x00ECE8EB,
+ 0x00EDE9EC, 0x00EEEAED, 0x00EFEBEE, 0x00F0ECEF, 0x00F1EDF0, 0x00F2EEF1,
+ 0x00F3EFF2, 0x00F4F0F3, 0x00F5F1F4, 0x00F6F2F5, 0x00F7F3F6, 0x00F8F4F7,
+ 0x00F9F5F8, 0x00FAF6F9, 0x00FBF7FA, 0x00FCF8FB, 0x00FDF9FC, 0x00FEFAFD,
+ 0x00FFFBFE, 0x00FFFCFE, 0x00FFFDFE, 0x00FFFFFF
+};
+
+/* REDCLOUD PLL TABLE */
+
+typedef struct RCDFPLL
+{
+ long frequency; /* 16.16 fixed point frequency */
+ unsigned long post_div3; /* MCP Frequency dividers and multipliers */
+ unsigned long pre_mul2;
+ unsigned long pre_div2;
+ unsigned long pll_value; /* MCP DotPLL Register Upper 32(0x0015) */
+} RCDFPLLENTRY;
+
+RCDFPLLENTRY RCDF_PLLtable[] = {
+ {0x0018EC4D, 1, 0, 0, 0x0000099E}, /* 24.9230 */
+ {0x00192CCC, 0, 0, 0, 0x00000037}, /* 25.1750 */
+ {0x001C526E, 1, 0, 0, 0x000009DA}, /* 28.3220 */
+ {0x001C8F5C, 1, 0, 0, 0x0000005E}, /* 28.5600 */
+ {0x001F8000, 1, 0, 0, 0x000002D2}, /* 31.5000 */
+ {0x00240000, 1, 0, 0, 0x000007E2}, /* 36.0000 */
+ {0x00258000, 1, 0, 0, 0x0000057A}, /* 37.5000 */
+ {0x0025E395, 1, 0, 0, 0x000007FA}, /* 37.8890 */
+ {0x00280000, 1, 0, 0, 0x0000030A}, /* 40.0000 */
+ {0x002B29BA, 0, 0, 0, 0x0000005F}, /* 43.1630 */
+ {0x002CE666, 0, 0, 0, 0x00000063}, /* 44.9000 */
+ {0x002DB851, 1, 0, 0, 0x00000BC9}, /* 45.7200 */
+ {0x00318000, 0, 0, 0, 0x0000054B}, /* 49.5000 */
+ {0x00320000, 0, 0, 0, 0x0000006F}, /* 50.0000 */
+ {0x00325999, 0, 1, 0, 0x00000037}, /* 50.3500 */
+ {0x00360000, 1, 1, 0, 0x00000B0D}, /* 54.0000 */
+ {0x00384000, 0, 0, 0, 0x000007F7}, /* 56.2500 */
+ {0x0038643F, 0, 0, 0, 0x000007F7}, /* 56.3916 */
+ {0x0038A4DD, 0, 0, 0, 0x0000057B}, /* 56.6444 */
+ {0x003B0000, 0, 1, 0, 0x00000707}, /* 59.0000 */
+ {0x003C10A3, 0, 0, 0, 0x0000030B}, /* 60.0650 */
+ {0x003F0000, 1, 1, 0, 0x00000B39}, /* 63.0000 */
+ {0x00410000, 1, 0, 0, 0x00000545}, /* 65.0000 */
+ {0x00442DD2, 1, 0, 0, 0x000002E1}, /* 68.1790 */
+ {0x00438000, 1, 1, 0, 0x00000FC1}, /* 67.5000 */
+ {0x0046CCCC, 1, 0, 0, 0x00000561}, /* 70.8000 */
+ {0x00480000, 1, 0, 0, 0x000007E1}, /* 72.0000 */
+ {0x004A7B22, 0, 1, 0, 0x00000F4A}, /* 74.4810 */
+ {0x004B0000, 1, 0, 0, 0x000007F5}, /* 75.0000 */
+ {0x004EC000, 1, 0, 0, 0x00000305}, /* 78.7500 */
+ {0x00500000, 1, 1, 0, 0x00000709}, /* 80.0000 */
+ {0x00519999, 0, 0, 0, 0x000009C6}, /* 81.6000 */
+ {0x0059CCCC, 0, 1, 0, 0x00000262}, /* 89.8000 */
+ {0x005E8000, 0, 0, 0, 0x000002D2}, /* 94.5000 */
+ {0x00618560, 0, 0, 0, 0x00000546}, /* 97.5200 */
+ {0x00630000, 0, 1, 0, 0x00000B4A}, /* 99.0000 */
+ {0x00642FDF, 0, 0, 0, 0x0000006E}, /* 100.1870 */
+ {0x00656B85, 0, 0, 0, 0x00000552}, /* 101.4200 */
+ {0x006C0000, 0, 0, 0, 0x000007E2}, /* 108.0000 */
+ {0x00708000, 0, 0, 0, 0x000007F6}, /* 112.5000 */
+ {0x00714F1A, 0, 0, 0, 0x0000057A}, /* 113.3090 */
+ {0x0077A666, 0, 0, 0, 0x0000030A}, /* 119.6500 */
+ {0x00806666, 1, 0, 0, 0x00000068}, /* 128.4000 */
+ {0x00820000, 1, 1, 0, 0x00000FB0}, /* 130.0000 */
+ {0x00821999, 1, 0, 0, 0x00000544}, /* 130.1000 */
+ {0x00858000, 1, 0, 0, 0x0000006C}, /* 133.5000 */
+ {0x00870000, 1, 0, 0, 0x00000550}, /* 135.0000 */
+ {0x00906147, 1, 0, 0, 0x000007E0}, /* 144.3800 */
+ {0x009D8000, 1, 0, 0, 0x00000304}, /* 157.5000 */
+ {0x00A20000, 0, 0, 0, 0x000002B1}, /* 162.0000 */
+ {0x00A933F7, 0, 0, 0, 0x000002B9}, /* 169.2030 */
+ {0x00ACCC49, 0, 1, 0, 0x0000002D}, /* 172.798 */
+ {0x00AF8000, 0, 0, 0, 0x000002C1}, /* 175.5000 */
+ {0x00BD0000, 0, 0, 0, 0x000002D1}, /* 189.0000 */
+ {0x00BEF5C2, 0, 0, 0, 0x0000053D}, /* 190.9600 */
+ {0x00C60000, 0, 0, 0, 0x00000549}, /* 198.0000 */
+ {0x00CA8000, 0, 0, 0, 0x00000551}, /* 202.5000 */
+ {0x00E58000, 0, 0, 0, 0x0000057D}, /* 229.5000 */
+};
+
+#define NUM_RCDF_FREQUENCIES sizeof(RCDF_PLLtable)/sizeof(RCDFPLLENTRY)
+
+/*---------------------------------------------------------------------------
+ * 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
+redcloud_reset_video(void)
+#else
+void
+gfx_reset_video(void)
+#endif
+{
+ gfx_set_video_enable(0);
+ gfx_select_alpha_region(1);
+ gfx_set_alpha_enable(0);
+ gfx_select_alpha_region(2);
+ gfx_set_alpha_enable(0);
+
+ /* SET REGION 0 AFTER RESET */
+
+ gfx_select_alpha_region(0);
+ gfx_set_alpha_enable(0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_display_control (PRIVATE ROUTINE: NOT PART OF DURANGO API)
+ *
+ * This routine configures the display output.
+ *
+ * "sync_polarities" is used to set the polarities of the sync pulses
+ * according to the following mask:
+ *
+ * Bit 0: If set to 1, negative horizontal polarity is programmed,
+ * otherwise positive horizontal polarity is programmed.
+ * Bit 1: If set to 1, negative vertical polarity is programmed,
+ * otherwise positive vertical polarity is programmed.
+ *
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_display_control(int sync_polarities)
+#else
+int
+gfx_set_display_control(int sync_polarities)
+#endif
+{
+ unsigned long power;
+ unsigned long dcfg;
+
+ /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+
+ dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
+ dcfg &= ~(RCDF_DCFG_CRT_SYNC_SKW_MASK | RCDF_DCFG_PWR_SEQ_DLY_MASK |
+ RCDF_DCFG_CRT_HSYNC_POL | RCDF_DCFG_CRT_VSYNC_POL |
+ RCDF_DCFG_FP_PWR_EN | RCDF_DCFG_FP_DATA_EN);
+
+ dcfg |= (RCDF_DCFG_CRT_SYNC_SKW_INIT |
+ RCDF_DCFG_PWR_SEQ_DLY_INIT | RCDF_DCFG_GV_PAL_BYP);
+
+ if (PanelEnable) {
+ power = READ_VID32(RCDF_POWER_MANAGEMENT);
+ power |= RCDF_PM_PANEL_POWER_ON;
+ WRITE_VID32(RCDF_POWER_MANAGEMENT, power);
+ }
+
+ /* SET APPROPRIATE SYNC POLARITIES */
+
+ if (sync_polarities & 0x1)
+ dcfg |= RCDF_DCFG_CRT_HSYNC_POL;
+ if (sync_polarities & 0x2)
+ dcfg |= RCDF_DCFG_CRT_VSYNC_POL;
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
+
+ return (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
+redcloud_set_clock_frequency(unsigned long frequency)
+#else
+void
+gfx_set_clock_frequency(unsigned long frequency)
+#endif
+{
+ Q_WORD msr_value, sys_value;
+ unsigned long sys_low;
+ unsigned int i, index = 0;
+ unsigned long value;
+ long timeout = 1000;
+ long min, diff;
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+
+ value = RCDF_PLLtable[0].pll_value;
+ min = (long)RCDF_PLLtable[0].frequency - frequency;
+ if (min < 0L)
+ min = -min;
+ for (i = 1; i < NUM_RCDF_FREQUENCIES; i++) {
+ diff = (long)RCDF_PLLtable[i].frequency - frequency;
+ if (diff < 0L)
+ diff = -diff;
+ if (diff < min) {
+ min = diff;
+ index = i;
+ }
+ }
+
+ /* VERIFY THAT WE ARE NOT WRITING WHAT IS ALREADY IN THE REGISTERS */
+ /* The Dot PLL reset bit is tied to VDD for flat panels. This can */
+ /* cause a brief drop in flat panel power, which can cause serious */
+ /* glitches on some panels. */
+
+ gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+ gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &sys_value);
+
+ sys_low = 0;
+ if (RCDF_PLLtable[index].post_div3)
+ sys_low |= MCP_DOTPOSTDIV3;
+ if (RCDF_PLLtable[index].pre_div2)
+ sys_low |= MCP_DOTPREDIV2;
+ if (RCDF_PLLtable[index].pre_mul2)
+ sys_low |= MCP_DOTPREMULT2;
+
+ if ((msr_value.low & MCP_DOTPLL_LOCK) &&
+ (msr_value.high == RCDF_PLLtable[index].pll_value) &&
+ ((sys_value.
+ low & (MCP_DOTPOSTDIV3 | MCP_DOTPREDIV2 | MCP_DOTPREMULT2)) ==
+ sys_low)) {
+ return;
+ }
+
+ /* PROGRAM THE SETTINGS WITH THE RESET BIT SET */
+ /* Clear the bypass bit to ensure that the programmed */
+ /* M, N and P values are being used. */
+
+ msr_value.high = RCDF_PLLtable[index].pll_value;
+ msr_value.low |= 0x00000001;
+ msr_value.low &= ~MCP_DOTPLL_BYPASS;
+ gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+
+ /* PROGRAM THE MCP DIVIDER VALUES */
+
+ sys_value.low &= ~(MCP_DOTPOSTDIV3 | MCP_DOTPREDIV2 | MCP_DOTPREMULT2);
+ sys_value.low |= sys_low;
+ gfx_msr_write(RC_ID_MCP, MCP_SYS_RSTPLL, &sys_value);
+
+ /* CLEAR THE RESET BIT */
+
+ msr_value.low &= 0xFFFFFFFE;
+ gfx_msr_write(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+
+ /* WAIT FOR LOCK BIT */
+
+ do {
+ gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+ } while (timeout-- && !(msr_value.low & MCP_DOTPLL_LOCK));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_crt_enable
+ *
+ * This routine enables or disables the CRT output from the video processor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_crt_enable(int enable)
+#else
+int
+gfx_set_crt_enable(int enable)
+#endif
+{
+ unsigned long config, misc;
+
+ config = READ_VID32(RCDF_DISPLAY_CONFIG);
+ misc = READ_VID32(RCDF_VID_MISC);
+
+ switch (enable) {
+ case CRT_DISABLE: /* DISABLE EVERYTHING */
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG,
+ config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
+ RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN));
+ WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
+ break;
+
+ case CRT_ENABLE: /* ENABLE CRT DISPLAY, INCLUDING DISPLAY LOGIC */
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG,
+ config | RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
+ RCDF_DCFG_VSYNC_EN | RCDF_DCFG_DAC_BL_EN);
+ WRITE_VID32(RCDF_VID_MISC,
+ misc & ~RCDF_DAC_POWER_DOWN & ~RCDF_ANALOG_POWER_DOWN);
+ break;
+
+ case CRT_STANDBY: /* HSYNC:OFF VSYNC:ON */
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG,
+ (config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_HSYNC_EN |
+ RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_VSYNC_EN);
+ WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
+ break;
+
+ case CRT_SUSPEND: /* HSYNC:ON VSYNC:OFF */
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG,
+ (config & ~(RCDF_DCFG_DIS_EN | RCDF_DCFG_VSYNC_EN |
+ RCDF_DCFG_DAC_BL_EN)) | RCDF_DCFG_HSYNC_EN);
+ WRITE_VID32(RCDF_VID_MISC, misc | RCDF_DAC_POWER_DOWN);
+ break;
+
+ default:
+ return (GFX_STATUS_BAD_PARAMETER);
+ }
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_enable
+ *
+ * This routine enables or disables the video overlay functionality.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_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(RCDF_VIDEO_CONFIG);
+ if (enable) {
+ /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_enable(1);
+
+ /* ENABLE DISPLAY FILTER VIDEO OVERLAY */
+
+ vcfg |= RCDF_VCFG_VID_EN;
+ WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
+ } else {
+ /* DISABLE DISPLAY FILTER VIDEO OVERLAY */
+
+ vcfg &= ~RCDF_VCFG_VID_EN;
+ WRITE_VID32(RCDF_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
+ *
+ * Sets input video format type, to one of the YUV formats or to RGB.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_format(unsigned long format)
+#else
+int
+gfx_set_video_format(unsigned long format)
+#endif
+{
+ unsigned long ctrl, vcfg = 0;
+
+ /* SET THE DISPLAY FILTER VIDEO INPUT FORMAT */
+
+ vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
+ ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL);
+ ctrl &= ~(RCDF_VIDEO_INPUT_IS_RGB | RCDF_CSC_VIDEO_YUV_TO_RGB);
+ vcfg &= ~(RCDF_VCFG_VID_INP_FORMAT | RCDF_VCFG_4_2_0_MODE);
+ switch (format) {
+ case VIDEO_FORMAT_UYVY:
+ vcfg |= RCDF_VCFG_UYVY_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_YUYV:
+ vcfg |= RCDF_VCFG_YUYV_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_Y2YU:
+ vcfg |= RCDF_VCFG_Y2YU_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_YVYU:
+ vcfg |= RCDF_VCFG_YVYU_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ break;
+ case VIDEO_FORMAT_Y0Y1Y2Y3:
+ vcfg |= RCDF_VCFG_UYVY_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= RCDF_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y3Y2Y1Y0:
+ vcfg |= RCDF_VCFG_Y2YU_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= RCDF_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y1Y0Y3Y2:
+ vcfg |= RCDF_VCFG_YUYV_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= RCDF_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_Y1Y2Y3Y0:
+ vcfg |= RCDF_VCFG_YVYU_FORMAT;
+ ctrl |= RCDF_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= RCDF_VCFG_4_2_0_MODE;
+ break;
+ case VIDEO_FORMAT_RGB:
+ ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
+ vcfg |= RCDF_VCFG_UYVY_FORMAT;
+ break;
+ case VIDEO_FORMAT_P2M_P2L_P1M_P1L:
+ ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
+ vcfg |= RCDF_VCFG_Y2YU_FORMAT;
+ break;
+ case VIDEO_FORMAT_P1M_P1L_P2M_P2L:
+ ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
+ vcfg |= RCDF_VCFG_YUYV_FORMAT;
+ break;
+ case VIDEO_FORMAT_P1M_P2L_P2M_P1L:
+ ctrl |= RCDF_VIDEO_INPUT_IS_RGB;
+ vcfg |= RCDF_VCFG_YVYU_FORMAT;
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
+ WRITE_VID32(RCDF_VID_ALPHA_CONTROL, ctrl);
+
+ /* SET THE VIDEO FORMAT IN THE DISPLAY CONTROLLER */
+ /* Use private routine to abstract display controller. */
+
+ gfx_set_display_video_format(format);
+ 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
+redcloud_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, vid_420, pitch;
+
+ /* SET THE DISPLAY FILTER VIDEO LINE SIZE */
+ /* Match the DC hardware alignment requirement. The line size must */
+ /* always be 32-byte aligned. However, we can manage smaller */
+ /* alignments by decreasing the pitch and clipping the video window. */
+ /* The VG will fetch extra data for each line, but the decreased */
+ /* pitch will ensure that it always begins fetching at the start of */
+ /* the video line. */
+
+ vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
+
+ vid_420 = vcfg & RCDF_VCFG_4_2_0_MODE;
+
+ vcfg &= ~(RCDF_VCFG_LINE_SIZE_LOWER_MASK | RCDF_VCFG_LINE_SIZE_UPPER);
+
+ size = ((width >> 1) + 7) & 0xFFF8;
+ pitch = ((width << 1) + 7) & 0xFFF8;
+
+ vcfg |= (size & 0x00FF) << 8;
+ if (size & 0x0100)
+ vcfg |= RCDF_VCFG_LINE_SIZE_UPPER;
+ WRITE_VID32(RCDF_VIDEO_CONFIG, vcfg);
+
+ /* SET VIDEO BUFFER LINE SIZE IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_size(width, height);
+
+ /* SET VIDEO PITCH */
+ /* We are only maintaining legacy for 4:2:2 video formats. */
+ /* 4:2:0 video in previous chips was inadequate for most */
+ /* common video formats. */
+
+ if (!vid_420)
+ gfx_set_video_yuv_pitch(pitch, pitch << 1);
+
+ 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
+redcloud_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_yuv_offsets
+ *
+ * This routine sets the starting offset for the video buffer when displaying
+ * 4:2:0 video.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
+ unsigned long voffset)
+#else
+int
+gfx_set_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
+ unsigned long voffset)
+#endif
+{
+ /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */
+
+ gfx_vid_offset = yoffset;
+ gfx_vid_uoffset = uoffset;
+ gfx_vid_voffset = voffset;
+
+ /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_yuv_offsets(yoffset, uoffset, voffset);
+
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_video_yuv_pitch
+ *
+ * This routine sets the byte offset between consecutive scanlines of YUV video data
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#else
+int
+gfx_set_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
+#endif
+{
+ /* SET VIDEO PITCH IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract the display controller. */
+
+ gfx_set_display_video_yuv_pitch(ypitch, uvpitch);
+
+ 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
+redcloud_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 (unless don't-care zero destination arguments are used) */
+ /* These are needed for clipping the video window later. */
+
+ if (dstw != 0) {
+ gfx_vid_srcw = srcw;
+ gfx_vid_dstw = dstw;
+ }
+ if (dsth != 0) {
+ gfx_vid_srch = srch;
+ gfx_vid_dsth = dsth;
+ }
+
+ /* CALCULATE DISPLAY FILTER SCALE FACTORS */
+ /* Zero width and height indicate don't care conditions */
+ /* Downscaling is performed in a separate function. */
+
+ if (dstw == 0)
+ xscale = READ_VID32(RCDF_VIDEO_SCALE) & 0xffff;
+ /* keep previous if don't-care argument */
+ else if (dstw <= srcw)
+ xscale = 0x2000;
+ /* horizontal downscaling is currently done in a separate function */
+ else if ((srcw == 1) || (dstw == 1))
+ return GFX_STATUS_BAD_PARAMETER;
+ else
+ xscale = (0x2000l * (srcw - 1l)) / (dstw - 1l);
+
+ if (dsth == 0)
+ yscale = (READ_VID32(RCDF_VIDEO_SCALE) & 0xffff0000) >> 16;
+ /* keep previous if don't-care argument */
+ else if (dsth <= srch)
+ yscale = 0x2000;
+ /* vertical downscaling is handled in a separate function */
+ else if ((srch == 1) || (dsth == 1))
+ return GFX_STATUS_BAD_PARAMETER;
+ else
+ yscale = (0x2000l * (srch - 1l)) / (dsth - 1l);
+
+ WRITE_VID32(RCDF_VIDEO_SCALE, (yscale << 16) | xscale);
+
+ /* CALL ROUTINE TO UPDATE WINDOW POSITION */
+ /* This is required because the scale values affect 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_vertical_downscale
+ *
+ * This routine sets the vertical downscale factor for the video overlay
+ * window.
+ * The height of the source and destination regions are specified in pixels.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_vertical_downscale(unsigned short srch,
+ unsigned short dsth)
+#else
+int
+gfx_set_video_vertical_downscale(unsigned short srch, unsigned short dsth)
+#endif
+{
+ /* SET VIDEO SCALE IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract hardware */
+
+ gfx_set_display_video_downscale(srch, dsth);
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_vertical_downscale_enable
+ *
+ * This routine sets the vertical downscale enable for the video overlay
+ * window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_set_video_vertical_downscale_enable(int enable)
+#else
+void
+gfx_set_video_vertical_downscale_enable(int enable)
+#endif
+{
+ /* SET VIDEO SCALE IN DISPLAY CONTROLLER */
+ /* Use private routine to abstract hardware */
+
+ gfx_set_display_video_vertical_downscale_enable(enable);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_config
+ *
+ * This routine sets the downscale type and factor for the video overlay
+ * window.
+ * Note: No downscaling support for RGB565 and YUV420 video formats.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_downscale_config(unsigned short type, unsigned short m)
+#else
+int
+gfx_set_video_downscale_config(unsigned short type, unsigned short m)
+#endif
+{
+ unsigned long downscale;
+
+ if ((m < 1) || (m > 16))
+ return GFX_STATUS_BAD_PARAMETER;
+
+ downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
+ downscale &=
+ ~(RCDF_VIDEO_DOWNSCALE_FACTOR_MASK | RCDF_VIDEO_DOWNSCALE_TYPE_MASK);
+ downscale |= ((unsigned long)(m - 1) << RCDF_VIDEO_DOWNSCALE_FACTOR_POS);
+ switch (type) {
+ case VIDEO_DOWNSCALE_KEEP_1_OF:
+ downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_A;
+ break;
+ case VIDEO_DOWNSCALE_DROP_1_OF:
+ downscale |= RCDF_VIDEO_DOWNSCALE_TYPE_B;
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_coefficients
+ *
+ * This routine sets the downscale filter coefficients.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4)
+#else
+int
+gfx_set_video_downscale_coefficients(unsigned short coef1,
+ unsigned short coef2, unsigned short coef3, unsigned short coef4)
+#endif
+{
+ if ((coef1 + coef2 + coef3 + coef4) != 16)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS,
+ ((unsigned long)coef1 << RCDF_VIDEO_DOWNSCALER_COEF1_POS) |
+ ((unsigned long)coef2 << RCDF_VIDEO_DOWNSCALER_COEF2_POS) |
+ ((unsigned long)coef3 << RCDF_VIDEO_DOWNSCALER_COEF3_POS) |
+ ((unsigned long)coef4 << RCDF_VIDEO_DOWNSCALER_COEF4_POS));
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_downscale_enable
+ *
+ * This routine enables or disables downscaling for the video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_downscale_enable(int enable)
+#else
+int
+gfx_set_video_downscale_enable(int enable)
+#endif
+{
+ unsigned long downscale;
+
+ downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
+ if (enable)
+ downscale |= RCDF_VIDEO_DOWNSCALE_ENABLE;
+ else
+ downscale &= ~RCDF_VIDEO_DOWNSCALE_ENABLE;
+ WRITE_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL, downscale);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_window
+ *
+ * This routine sets the position and size of the video overlay window. The
+ * x and y positions are 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
+redcloud_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 hadjust, vadjust;
+ unsigned long xstart, ystart, xend, yend;
+
+ /* 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() - 14l;
+ vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1l;
+
+ /* LEFT CLIPPING */
+
+ if (x < 0) {
+ gfx_set_video_left_crop((unsigned short)(-x));
+ xstart = hadjust;
+ } else {
+ gfx_set_video_left_crop(0);
+ xstart = (unsigned long)x + hadjust;
+ }
+
+ /* HORIZONTAL END */
+ /* End positions in register are non-inclusive (one more than the actual
+ * end) */
+
+ if ((x + w) < gfx_get_hactive())
+ xend = (unsigned long)x + (unsigned long)w + hadjust;
+
+ /* RIGHT-CLIPPING */
+ else
+ xend = (unsigned long)gfx_get_hactive() + hadjust;
+
+ /* VERTICAL START */
+
+ ystart = (unsigned long)y + vadjust;
+
+ /* VERTICAL END */
+
+ if ((y + h) < gfx_get_vactive())
+ yend = (unsigned long)y + (unsigned long)h + vadjust;
+
+ /* BOTTOM-CLIPPING */
+ else
+ yend = (unsigned long)gfx_get_vactive() + vadjust;
+
+ /* SET VIDEO POSITION */
+
+ WRITE_VID32(RCDF_VIDEO_X_POS, (xend << 16) | xstart);
+ WRITE_VID32(RCDF_VIDEO_Y_POS, (yend << 16) | ystart);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_left_crop
+ *
+ * This routine sets the number of pixels which will be cropped from the
+ * beginning of each video line. The video window will begin to display only
+ * from the pixel following the cropped pixels, and the cropped pixels
+ * will be ignored.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_left_crop(unsigned short x)
+#else
+int
+gfx_set_video_left_crop(unsigned short x)
+#endif
+{
+ unsigned long vcfg, initread;
+
+ vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
+
+ /* CLIPPING ON LEFT */
+ /* Adjust initial read for scale, checking for divide by zero. Mask the
+ * lower three bits when clipping 4:2:0 video. By masking the bits instead
+ * of rounding up we ensure that we always clip less than or equal to the
+ * desired number of pixels. This prevents visual artifacts from
+ * over-clipping. We mask three bits to meet the HW requirement that 4:2:0
+ * clipping be 16-byte or 8-pixel aligned.
+ * */
+
+ if (gfx_vid_dstw) {
+ initread = (unsigned long)x *gfx_vid_srcw / gfx_vid_dstw;
+
+ if (vcfg & RCDF_VCFG_4_2_0_MODE)
+ initread &= 0xFFF8;
+ } else
+ initread = 0;
+
+ /* SET INITIAL READ ADDRESS */
+
+ vcfg &= ~RCDF_VCFG_INIT_READ_MASK;
+ vcfg |= (initread << 15) & RCDF_VCFG_INIT_READ_MASK;
+ WRITE_VID32(RCDF_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))
+ *
+ * If "graphics" is set to TRUE, the source data is graphics, and color key
+ * is an RGB value. If "graphics" is set to FALSE, the source data is the
+ * video, and color key is a YUV value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_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 RCDF COLOR KEY VALUE */
+
+ WRITE_VID32(RCDF_VIDEO_COLOR_KEY, key);
+ WRITE_VID32(RCDF_VIDEO_COLOR_MASK, mask);
+
+ /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */
+
+ dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
+ if (graphics & 0x01)
+ dcfg &= ~RCDF_DCFG_VG_CK;
+ else
+ dcfg |= RCDF_DCFG_VG_CK;
+ WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_filter
+ *
+ * This routine enables or disables the video overlay filters.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_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 DISPLAY FILTER VIDEO OVERLAY FILTERS */
+
+ vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
+ vcfg &= ~(RCDF_VCFG_X_FILTER_EN | RCDF_VCFG_Y_FILTER_EN);
+ if (xfilter)
+ vcfg |= RCDF_VCFG_X_FILTER_EN;
+ if (yfilter)
+ vcfg |= RCDF_VCFG_Y_FILTER_EN;
+ WRITE_VID32(RCDF_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 Redcloud, this means loading the
+ * palette with identity values).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_palette(unsigned long *palette)
+#else
+int
+gfx_set_video_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i, entry;
+ unsigned long misc, dcfg;
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
+ misc = READ_VID32(RCDF_VID_MISC);
+
+ dcfg |= RCDF_DCFG_GV_PAL_BYP;
+ misc &= ~RCDF_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32(RCDF_VID_MISC, misc);
+
+ if (gfx_test_timing_active()) {
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+ }
+
+ /* LOAD REDCLOUD VIDEO PALETTE */
+
+ WRITE_VID32(RCDF_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ if (palette)
+ entry = palette[i];
+ else
+ entry = gfx_gamma_ram_redcloud[i];
+ WRITE_VID32(RCDF_PALETTE_DATA, entry);
+ }
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_graphics_palette
+ *
+ * This routine loads the video hardware palette. If a NULL pointer is
+ * specified, the palette is bypassed (for Redcloud, this means loading the
+ * palette with identity values). Note that this routine is identical to
+ * gfx_set_video_palette, except that the hardware is updated to route
+ * graphics data through the palette.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_graphics_palette(unsigned long *palette)
+#else
+int
+gfx_set_graphics_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i, entry;
+ unsigned long misc, dcfg;
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
+ misc = READ_VID32(RCDF_VID_MISC);
+
+ dcfg &= ~RCDF_DCFG_GV_PAL_BYP;
+ misc &= ~RCDF_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32(RCDF_VID_MISC, misc);
+
+ if (gfx_test_timing_active()) {
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+ }
+
+ /* LOAD REDCLOUD VIDEO PALETTE */
+
+ WRITE_VID32(RCDF_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++) {
+ if (palette)
+ entry = palette[i];
+ else
+ entry = gfx_gamma_ram_redcloud[i];
+ WRITE_VID32(RCDF_PALETTE_DATA, entry);
+ }
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_graphics_palette_entry
+ *
+ * This routine loads a single entry of the video hardware palette.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_graphics_palette_entry(unsigned long index,
+ unsigned long palette)
+#else
+int
+gfx_set_graphics_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ unsigned long dcfg, misc;
+
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
+ misc = READ_VID32(RCDF_VID_MISC);
+
+ dcfg &= ~RCDF_DCFG_GV_PAL_BYP;
+ misc &= ~RCDF_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32(RCDF_VID_MISC, misc);
+
+ /* SET A SINGLE ENTRY */
+
+ WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
+ WRITE_VID32(RCDF_PALETTE_DATA, palette);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_entry
+ *
+ * This routine loads a single entry of the video hardware palette.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_palette_entry(unsigned long index, unsigned long palette)
+#else
+int
+gfx_set_video_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ unsigned long dcfg, misc;
+
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32(RCDF_DISPLAY_CONFIG);
+ misc = READ_VID32(RCDF_VID_MISC);
+
+ dcfg |= RCDF_DCFG_GV_PAL_BYP;
+ misc &= ~RCDF_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32(RCDF_VID_MISC, misc);
+
+ /* SET A SINGLE ENTRY */
+
+ WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
+ WRITE_VID32(RCDF_PALETTE_DATA, palette);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_palette_bypass
+ *
+ * This routine enables/disables the pallete RAM bypass.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_palette_bypass(int enable)
+#else
+int
+gfx_set_video_palette_bypass(int enable)
+#endif
+{
+ unsigned long misc;
+
+ misc = READ_VID32(RCDF_VID_MISC);
+
+ if (enable)
+ misc |= RCDF_GAMMA_BYPASS_BOTH;
+ else
+ misc &= ~RCDF_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32(RCDF_VID_MISC, misc);
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_request()
+ *
+ * This routine sets the horizontal (pixel) and vertical (line) video request
+ * values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_request(short x, short y)
+#else
+int
+gfx_set_video_request(short x, short y)
+#endif
+{
+ /* SET DISPLAY FILTER VIDEO REQUEST */
+
+ x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ if ((x < 0) || (x > RCDF_VIDEO_REQUEST_MASK) ||
+ (y < 0) || (y > RCDF_VIDEO_REQUEST_MASK))
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_VID32(RCDF_VIDEO_REQUEST,
+ ((unsigned long)x << RCDF_VIDEO_X_REQUEST_POS) | ((unsigned long)y <<
+ RCDF_VIDEO_Y_REQUEST_POS));
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_cursor()
+ *
+ * This routine configures the video hardware cursor.
+ * If the "mask"ed bits in the graphics pixel match "key", then either
+ * "color1" or "color2" will be used for this pixel, according to the value of
+ * bit number "select_color2" of the graphics pixel.
+ *
+ * key - 24 bit RGB value
+ * mask - 24 bit mask
+ * color1, color2 - RGB or YUV, depending on the current color space
+ * conversion select_color2 - value between 0 to 23
+ *
+ * To disable match, a "mask" and "key" value of 0xffffff should be set,
+ * because the graphics pixels incoming to the video processor have maximum 16
+ * bits set (0xF8FCF8).
+ *
+ * This feature is useful for disabling alpha blending of the cursor.
+ * Otherwise cursor image would be blurred (or completely invisible if video
+ * alpha is maximum value).
+ * Note: the cursor pixel replacements take place both inside and outside the
+ * video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2)
+#else
+int
+gfx_set_video_cursor(unsigned long key, unsigned long mask,
+ unsigned short select_color2, unsigned long color1, unsigned long color2)
+#endif
+{
+ if (select_color2 > RCDF_CURSOR_COLOR_BITS)
+ return GFX_STATUS_BAD_PARAMETER;
+ key =
+ (key & RCDF_COLOR_MASK) | ((unsigned long)select_color2 <<
+ RCDF_CURSOR_COLOR_KEY_OFFSET_POS);
+ WRITE_VID32(RCDF_CURSOR_COLOR_KEY, key);
+ WRITE_VID32(RCDF_CURSOR_COLOR_MASK, mask);
+ WRITE_VID32(RCDF_CURSOR_COLOR_1, color1);
+ WRITE_VID32(RCDF_CURSOR_COLOR_2, color2);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_video_cursor()
+ *
+ * This routine configures the video hardware cursor.
+ * If the "mask"ed bits in the graphics pixel match "key", then either
+ * "color1"or "color2" will be used for this pixel, according to the value of
+ * bit number "select_color2" of the graphics pixel.
+ *
+ * key - 24 bit RGB value
+ * mask - 24 bit mask
+ * color1, color2 - RGB or YUV, depending on the current color space
+ * conversion select_color2 - value between 0 to 23
+ *
+ * To disable match, a "mask" and "key" value of 0xffffff should be set,
+ * because the graphics pixels incoming to the video processor have maximum 16
+ * bits set (0xF8FCF8).
+ *
+ * This feature is useful for disabling alpha blending of the cursor.
+ * Otherwise cursor image would be blurred (or completely invisible if video
+ * alpha is maximum value).
+ * Note: the cursor pixel replacements take place both inside and outside the
+ * video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_video_cursor_enable(int enable)
+#else
+int
+gfx_set_video_cursor_enable(int enable)
+#endif
+{
+ unsigned long temp = READ_VID32(RCDF_CURSOR_COLOR_KEY);
+
+ if (enable)
+ temp |= RCDF_CURSOR_COLOR_KEY_ENABLE;
+ else
+ temp &= ~RCDF_CURSOR_COLOR_KEY_ENABLE;
+
+ WRITE_VID32(RCDF_CURSOR_COLOR_KEY, temp);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_enable
+ *
+ * This routine enables or disables the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_alpha_enable(int enable)
+#else
+int
+gfx_set_alpha_enable(int enable)
+#endif
+{
+ unsigned long address = 0, value = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = RCDF_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5);
+ value = READ_VID32(address);
+ if (enable)
+ value |= RCDF_ACTRL_WIN_ENABLE;
+ else
+ value &= ~(RCDF_ACTRL_WIN_ENABLE);
+ WRITE_VID32(address, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_window
+ *
+ * This routine sets the size of the currently selected alpha region.
+ * Note: "x" and "y" are signed to enable using negative values needed for
+ * implementing workarounds of hardware issues.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height)
+#else
+int
+gfx_set_alpha_window(short x, short y,
+ unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long address = 0;
+
+ /* CHECK FOR CLIPPING */
+
+ if ((x + width) > gfx_get_hactive())
+ width = gfx_get_hactive() - x;
+ if ((y + height) > gfx_get_vactive())
+ height = gfx_get_vactive() - y;
+
+ /* ADJUST POSITIONS */
+
+ x += gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ y += gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = RCDF_ALPHA_XPOS_1 + ((unsigned long)gfx_alpha_select << 5);
+
+ /* END POSITIONS IN REGISTERS ARE NON-INCLUSIVE (ONE MORE THAN ACTUAL END)
+ * */
+
+ WRITE_VID32(address, (unsigned long)x |
+ ((unsigned long)(x + width) << 16));
+ WRITE_VID32(address + 8, (unsigned long)y |
+ ((unsigned long)(y + height) << 16));
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_value
+ *
+ * This routine sets the alpha value for the currently selected alpha
+ * region. It also specifies an increment/decrement value for fading.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_alpha_value(unsigned char alpha, char delta)
+#else
+int
+gfx_set_alpha_value(unsigned char alpha, char delta)
+#endif
+{
+ unsigned long address = 0, value = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = RCDF_ALPHA_CONTROL_1 + ((unsigned long)gfx_alpha_select << 5);
+ value = READ_VID32(address);
+ value &= RCDF_ACTRL_WIN_ENABLE; /* keep only enable bit */
+ value |= (unsigned long)alpha;
+ value |= (((unsigned long)delta) & 0xff) << 8;
+ value |= RCDF_ACTRL_LOAD_ALPHA;
+ WRITE_VID32(address, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_priority
+ *
+ * This routine sets the priority of the currently selected alpha region.
+ * A higher value indicates a higher priority.
+ * Note: Priority of enabled alpha windows must be different.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_alpha_priority(int priority)
+#else
+int
+gfx_set_alpha_priority(int priority)
+#endif
+{
+ unsigned long pos = 0, value = 0;
+
+ if (priority > 3)
+ return (GFX_STATUS_BAD_PARAMETER);
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
+ pos = 16 + (gfx_alpha_select << 1);
+ value &= ~(0x03l << pos);
+ value |= (unsigned long)priority << pos;
+ WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color
+ *
+ * This routine sets the color to be displayed inside the currently selected
+ * alpha window when there is a color key match (when the alpha color
+ * mechanism is enabled).
+ * "color" is an RGB value (for RGB blending) or a YUV value (for YUV
+ * blending).
+ * In Interlaced YUV blending mode, Y/2 value should be used.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_alpha_color(unsigned long color)
+#else
+int
+gfx_set_alpha_color(unsigned long color)
+#endif
+{
+ unsigned long address = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = RCDF_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5);
+ WRITE_VID32(address, color);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_alpha_color_enable
+ *
+ * Enable or disable the color mechanism in the alpha window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_alpha_color_enable(int enable)
+#else
+int
+gfx_set_alpha_color_enable(int enable)
+#endif
+{
+ unsigned long color;
+ unsigned long address = 0;
+
+ if (gfx_alpha_select > 2)
+ return (GFX_STATUS_UNSUPPORTED);
+ address = RCDF_ALPHA_COLOR_1 + ((unsigned long)gfx_alpha_select << 5);
+ color = READ_VID32(address);
+ if (enable)
+ color |= RCDF_ALPHA_COLOR_ENABLE;
+ else
+ color &= ~RCDF_ALPHA_COLOR_ENABLE;
+ WRITE_VID32(address, color);
+ return (GFX_STATUS_OK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_no_ck_outside_alpha
+ *
+ * This function affects where inside the video window color key or chroma
+ * key comparison is done:
+ * If enable is TRUE, color/chroma key comparison is performed only inside
+ * the enabled alpha windows. Outside the (enabled) alpha windows, only video
+ * is displayed if color key is used, and only graphics is displayed if chroma
+ * key is used.
+ * If enable is FALSE, color/chroma key comparison is performed in all the
+ * video window area.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_set_no_ck_outside_alpha(int enable)
+#else
+int
+gfx_set_no_ck_outside_alpha(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
+ if (enable)
+ WRITE_VID32(RCDF_VID_ALPHA_CONTROL, value | RCDF_NO_CK_OUTSIDE_ALPHA);
+ else
+ WRITE_VID32(RCDF_VID_ALPHA_CONTROL,
+ value & ~RCDF_NO_CK_OUTSIDE_ALPHA);
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * 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
+redcloud_get_clock_frequency(void)
+#else
+unsigned long
+gfx_get_clock_frequency(void)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned int index;
+ unsigned long value, mask = 0x00001FFF;
+ unsigned long post_div3 = 0, pre_mult2 = 0;
+
+ /* READ PLL SETTING */
+
+ gfx_msr_read(RC_ID_MCP, MCP_DOTPLL, &msr_value);
+ value = msr_value.high & mask;
+
+ /* READ DIVISOR SETTINGS */
+
+ gfx_msr_read(RC_ID_MCP, MCP_SYS_RSTPLL, &msr_value);
+ post_div3 = (msr_value.low & MCP_DOTPOSTDIV3) ? 1 : 0;
+ pre_mult2 = (msr_value.low & MCP_DOTPREMULT2) ? 1 : 0;
+
+ /* SEARCH FOR A MATCH */
+
+ for (index = 0; index < NUM_RCDF_FREQUENCIES; index++) {
+ if ((RCDF_PLLtable[index].pll_value & mask) == value &&
+ post_div3 == RCDF_PLLtable[index].post_div3 &&
+ pre_mult2 == RCDF_PLLtable[index].pre_mul2)
+ return (RCDF_PLLtable[index].frequency);
+ }
+ 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
+redcloud_get_sync_polarities(void)
+#else
+int
+gfx_get_sync_polarities(void)
+#endif
+{
+ int polarities = 0;
+
+ if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_HSYNC_POL)
+ polarities |= 1;
+ if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_DCFG_CRT_VSYNC_POL)
+ polarities |= 2;
+ return (polarities);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_palette_entry
+ *
+ * This routine returns a single palette entry.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int
+gfx_get_video_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ /* READ A SINGLE ENTRY */
+
+ WRITE_VID32(RCDF_PALETTE_ADDRESS, index);
+ *palette = READ_VID32(RCDF_PALETTE_DATA);
+
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * 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
+redcloud_get_video_enable(void)
+#else
+int
+gfx_get_video_enable(void)
+#endif
+{
+ if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_VID_EN)
+ return (1);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_format
+ *
+ * This routine returns the current video overlay format.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_get_video_format(void)
+#else
+int
+gfx_get_video_format(void)
+#endif
+{
+ unsigned long ctrl, vcfg;
+
+ ctrl = READ_VID32(RCDF_VID_ALPHA_CONTROL);
+ vcfg = READ_VID32(RCDF_VIDEO_CONFIG);
+
+ if (ctrl & RCDF_VIDEO_INPUT_IS_RGB) {
+ switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
+ case RCDF_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_RGB;
+ case RCDF_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_P2M_P2L_P1M_P1L;
+ case RCDF_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_P1M_P1L_P2M_P2L;
+ case RCDF_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_P1M_P2L_P2M_P1L;
+ }
+ }
+
+ if (vcfg & RCDF_VCFG_4_2_0_MODE) {
+ switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
+ case RCDF_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_Y0Y1Y2Y3;
+ case RCDF_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_Y3Y2Y1Y0;
+ case RCDF_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_Y1Y0Y3Y2;
+ case RCDF_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_Y1Y2Y3Y0;
+ }
+ } else {
+ switch (vcfg & RCDF_VCFG_VID_INP_FORMAT) {
+ case RCDF_VCFG_UYVY_FORMAT:
+ return VIDEO_FORMAT_UYVY;
+ case RCDF_VCFG_Y2YU_FORMAT:
+ return VIDEO_FORMAT_Y2YU;
+ case RCDF_VCFG_YUYV_FORMAT:
+ return VIDEO_FORMAT_YUYV;
+ case RCDF_VCFG_YVYU_FORMAT:
+ return VIDEO_FORMAT_YVYU;
+ }
+ }
+ return (GFX_STATUS_ERROR);
+}
+
+/*----------------------------------------------------------------------------
+ * 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
+redcloud_get_video_src_size(void)
+#else
+unsigned long
+gfx_get_video_src_size(void)
+#endif
+{
+ unsigned long width, height, scale, delta;
+ int down_enable;
+
+ /* DETERMINE SOURCE WIDTH FROM THE DISPLAY FILTER VIDEO LINE SIZE */
+
+ width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+
+ /* DETERMINE SOURCE HEIGHT FROM THE DISPLAY FILTER HEIGHT AND SCALE VALUES
+ * There is no true "source buffer size" in Redcloud. Instead, the VG
+ * module provides video data as needed on a per-line basis. The source
+ * buffer size is always assumed to equal the amount of required video
+ * data. The returned height is equal to the height of the required video
+ * buffer data (before all scaling.)
+ * */
+
+ scale = (READ_VID32(RCDF_VIDEO_SCALE) >> 16) & 0x3FFF;
+ height = ((READ_VID32(RCDF_VIDEO_Y_POS) >> 16) & 0x7FF) -
+ (READ_VID32(RCDF_VIDEO_Y_POS) & 0x7FF);
+ delta = gfx_get_video_downscale_delta();
+ down_enable = gfx_get_video_vertical_downscale_enable();
+
+ /* REVERSE UPSCALING */
+
+ if (height)
+ height = ((scale * (height - 1l)) / 0x2000l) + 2l;
+
+ /* REVERSE DOWNSCALING */
+ /* Original lines = height * (0x3FFF + delta) / 0x3FFF */
+ /* As this may cause rounding errors, we add 1 to the */
+ /* returned source size. The return value of this */
+ /* function could thus be off by 1. */
+
+ if (down_enable && height)
+ height = ((height * (0x3FFFl + delta)) / 0x3FFFl) + 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
+redcloud_get_video_line_size(void)
+#else
+unsigned long
+gfx_get_video_line_size(void)
+#endif
+{
+ unsigned long width = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */
+
+ width = (READ_VID32(RCDF_VIDEO_CONFIG) >> 7) & 0x000001FE;
+ if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_LINE_SIZE_UPPER)
+ width += 512l;
+ 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
+redcloud_get_video_xclip(void)
+#else
+unsigned long
+gfx_get_video_xclip(void)
+#endif
+{
+ unsigned long clip = 0;
+
+ /* DETERMINE SOURCE WIDTH FROM THE RCDF VIDEO LINE SIZE */
+
+ clip = (READ_VID32(RCDF_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
+redcloud_get_video_offset(void)
+#else
+unsigned long
+gfx_get_video_offset(void)
+#endif
+{
+ return (gfx_get_display_video_offset());
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_yuv_offsets
+ *
+ * This routine returns the current offsets for the video overlay buffer when in 4:2:0.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
+ unsigned long *voffset)
+#else
+void
+gfx_get_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
+ unsigned long *voffset)
+#endif
+{
+ gfx_get_display_video_yuv_offsets(yoffset, uoffset, voffset);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_video_yuv_pitch
+ *
+ * This routine returns the current pitch values for the video overlay buffer.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#else
+void
+gfx_get_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#endif
+{
+ gfx_get_display_video_yuv_pitch(ypitch, uvpitch);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_scale
+ *
+ * This routine returns the scale factor for the video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+redcloud_get_video_scale(void)
+#else
+unsigned long
+gfx_get_video_scale(void)
+#endif
+{
+ return (READ_VID32(RCDF_VIDEO_SCALE));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_delta
+ *
+ * This routine returns the vertical downscale factor for the video overlay
+ * window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+redcloud_get_video_downscale_delta(void)
+#else
+unsigned long
+gfx_get_video_downscale_delta(void)
+#endif
+{
+ /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */
+
+ return (gfx_get_display_video_downscale_delta());
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_vertical_downscale_enable
+ *
+ * This routine returns the vertical downscale enable for the video overlay
+ * window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_get_video_vertical_downscale_enable(void)
+#else
+int
+gfx_get_video_vertical_downscale_enable(void)
+#endif
+{
+ /* USE PRIVATE ROUTINE TO ABSTRACT THE DIPSLAY CONTROLLER */
+
+ return (gfx_get_display_video_downscale_enable());
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_config
+ *
+ * This routine returns the current type and value of video downscaling.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_get_video_downscale_config(unsigned short *type, unsigned short *m)
+#else
+int
+gfx_get_video_downscale_config(unsigned short *type, unsigned short *m)
+#endif
+{
+ unsigned long downscale;
+
+ downscale = READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL);
+ *m = (unsigned short)((downscale & RCDF_VIDEO_DOWNSCALE_FACTOR_MASK) >>
+ RCDF_VIDEO_DOWNSCALE_FACTOR_POS) + 1;
+
+ switch (downscale & RCDF_VIDEO_DOWNSCALE_TYPE_MASK) {
+ case RCDF_VIDEO_DOWNSCALE_TYPE_A:
+ *type = VIDEO_DOWNSCALE_KEEP_1_OF;
+ break;
+ case RCDF_VIDEO_DOWNSCALE_TYPE_B:
+ *type = VIDEO_DOWNSCALE_DROP_1_OF;
+ break;
+ default:
+ return GFX_STATUS_ERROR;
+ break;
+ }
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_coefficients
+ *
+ * This routine returns the current video downscaling coefficients.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4)
+#else
+void
+gfx_get_video_downscale_coefficients(unsigned short *coef1,
+ unsigned short *coef2, unsigned short *coef3, unsigned short *coef4)
+#endif
+{
+ unsigned long coef;
+
+ coef = READ_VID32(RCDF_VIDEO_DOWNSCALER_COEFFICIENTS);
+ *coef1 =
+ (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF1_POS) &
+ RCDF_VIDEO_DOWNSCALER_COEF_MASK);
+ *coef2 =
+ (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF2_POS) &
+ RCDF_VIDEO_DOWNSCALER_COEF_MASK);
+ *coef3 =
+ (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF3_POS) &
+ RCDF_VIDEO_DOWNSCALER_COEF_MASK);
+ *coef4 =
+ (unsigned short)((coef >> RCDF_VIDEO_DOWNSCALER_COEF4_POS) &
+ RCDF_VIDEO_DOWNSCALER_COEF_MASK);
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_downscale_enable
+ *
+ * This routine returns 1 if video downscaling is currently enabled,
+ * or 0 if it is currently disabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_video_downscale_enable(int *enable)
+#else
+void
+gfx_get_video_downscale_enable(int *enable)
+#endif
+{
+ if (READ_VID32(RCDF_VIDEO_DOWNSCALER_CONTROL) &
+ RCDF_VIDEO_DOWNSCALE_ENABLE)
+ *enable = 1;
+ else
+ *enable = 0;
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_dst_size
+ *
+ * This routine returns the size of the displayed video overlay window.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+redcloud_get_video_dst_size(void)
+#else
+unsigned long
+gfx_get_video_dst_size(void)
+#endif
+{
+ unsigned long xsize, ysize;
+
+ xsize = READ_VID32(RCDF_VIDEO_X_POS);
+ xsize = ((xsize >> 16) & 0x7FF) - (xsize & 0x7FF);
+ ysize = READ_VID32(RCDF_VIDEO_Y_POS);
+ ysize = ((ysize >> 16) & 0x7FF) - (ysize & 0x7FF);
+ 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
+redcloud_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(RCDF_VIDEO_X_POS) & 0x000007FF;
+ ypos = READ_VID32(RCDF_VIDEO_Y_POS) & 0x000007FF;
+
+ /* GET ADJUSTMENT VALUES */
+ /* Use routines to abstract version of display controller. */
+
+ hadjust =
+ (unsigned long)gfx_get_htotal() - (unsigned long)gfx_get_hsync_end() -
+ 14l;
+ vadjust =
+ (unsigned long)gfx_get_vtotal() - (unsigned long)gfx_get_vsync_end() +
+ 1l;
+ 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
+redcloud_get_video_color_key(void)
+#else
+unsigned long
+gfx_get_video_color_key(void)
+#endif
+{
+ return (READ_VID32(RCDF_VIDEO_COLOR_KEY));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_color_key_mask
+ *
+ * This routine returns the current video color mask value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+redcloud_get_video_color_key_mask(void)
+#else
+unsigned long
+gfx_get_video_color_key_mask(void)
+#endif
+{
+ return (READ_VID32(RCDF_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
+redcloud_get_video_color_key_src(void)
+#else
+int
+gfx_get_video_color_key_src(void)
+#endif
+{
+ if (READ_VID32(RCDF_DISPLAY_CONFIG) & RCDF_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
+redcloud_get_video_filter(void)
+#else
+int
+gfx_get_video_filter(void)
+#endif
+{
+ int retval = 0;
+
+ if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_X_FILTER_EN)
+ retval |= 1;
+ if (READ_VID32(RCDF_VIDEO_CONFIG) & RCDF_VCFG_Y_FILTER_EN)
+ retval |= 2;
+ return (retval);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_request
+ *
+ * This routine returns the horizontal (pixel) and vertical (lines) video
+ * request values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_get_video_request(short *x, short *y)
+#else
+int
+gfx_get_video_request(short *x, short *y)
+#endif
+{
+ unsigned long request = 0;
+
+ request = (READ_VID32(RCDF_VIDEO_REQUEST));
+ *x = (short)((request >> RCDF_VIDEO_X_REQUEST_POS) &
+ RCDF_VIDEO_REQUEST_MASK);
+ *y = (short)((request >> RCDF_VIDEO_Y_REQUEST_POS) &
+ RCDF_VIDEO_REQUEST_MASK);
+
+ *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_video_cursor()
+ *
+ * This routine configures the video hardware cursor.
+ * If the "mask"ed bits in the graphics pixel match "key", then either
+ * "color1" or "color2" will be used for this pixel, according to the value of
+ * the bit in offset "select_color2".
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+int
+redcloud_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2)
+#else
+int
+gfx_get_video_cursor(unsigned long *key, unsigned long *mask,
+ unsigned short *select_color2, unsigned long *color1,
+ unsigned short *color2)
+#endif
+{
+ *select_color2 =
+ (unsigned short)(READ_VID32(RCDF_CURSOR_COLOR_KEY) >>
+ RCDF_CURSOR_COLOR_KEY_OFFSET_POS);
+ *key = READ_VID32(RCDF_CURSOR_COLOR_KEY) & RCDF_COLOR_MASK;
+ *mask = READ_VID32(RCDF_CURSOR_COLOR_MASK) & RCDF_COLOR_MASK;
+ *color1 = READ_VID32(RCDF_CURSOR_COLOR_1) & RCDF_COLOR_MASK;
+ *color2 =
+ (unsigned short)(READ_VID32(RCDF_CURSOR_COLOR_2) & RCDF_COLOR_MASK);
+ 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
+redcloud_read_crc(void)
+#else
+unsigned long
+gfx_read_crc(void)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned long crc = 0xFFFFFFFF;
+
+ /* DISABLE 32-BIT CRCS */
+ /* For GX1.x, this is a reserved bit, and is assumed to be a benign
+ * access */
+
+ gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
+ msr_value.low &= ~RCDF_DIAG_32BIT_CRC;
+ gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
+
+ if (gfx_test_timing_active()) {
+ /* WAIT UNTIL ACTIVE DISPLAY */
+
+ while (!gfx_test_vertical_active()) ;
+
+ /* RESET CRC DURING ACTIVE DISPLAY */
+
+ WRITE_VID32(RCDF_VID_CRC, 0);
+ WRITE_VID32(RCDF_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()) ;
+ while (!gfx_test_vertical_active()) ;
+ crc = READ_VID32(RCDF_VID_CRC) >> 8;
+ }
+ return (crc);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_read_crc32
+ *
+ * This routine returns the 32-bit 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
+redcloud_read_crc32(void)
+#else
+unsigned long
+gfx_read_crc32(void)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned long crc = 0xFFFFFFFF;
+
+ /* ENABLE 32-BIT CRCS */
+ /* For GX1.x, this is a reserved bit, and is assumed to be a benign
+ * access */
+
+ gfx_msr_read(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
+ msr_value.low |= RCDF_DIAG_32BIT_CRC;
+ gfx_msr_write(RC_ID_DF, RCDF_MBD_MSR_DIAG_DF, &msr_value);
+
+ if (gfx_test_timing_active()) {
+ /* WAIT UNTIL ACTIVE DISPLAY */
+
+ while (!gfx_test_vertical_active()) ;
+
+ /* RESET CRC DURING ACTIVE DISPLAY */
+
+ WRITE_VID32(RCDF_VID_CRC, 0);
+ WRITE_VID32(RCDF_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()) ;
+ while (!gfx_test_vertical_active()) ;
+ crc = READ_VID32(RCDF_VID_CRC32);
+ }
+ return (crc);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_read_window_crc
+ *
+ * This routine returns the hardware CRC value for a subsection of the display
+ * This value is used to debug whole-screen CRC failures.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+unsigned long
+redcloud_read_window_crc(int source, unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, int crc32)
+#else
+unsigned long
+gfx_read_window_crc(int source, unsigned short x, unsigned short y,
+ unsigned short width, unsigned short height, int crc32)
+#endif
+{
+ Q_WORD msr_value;
+ unsigned long xpos, ypos, crc = 0;
+ unsigned long old_fmt = 0;
+ unsigned int vsync_active_base, vsync_inactive_base, hsync_active_base;
+ unsigned int vsync_active_shift, vsync_inactive_shift, hsync_active_shift;
+ unsigned int vsync_bit, hsync_bit, sync_polarities = 0;
+
+ /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */
+
+ msr_value.high = 0;
+ msr_value.low =
+ (source == CRC_SOURCE_GFX_DATA) ? (RCDF_MBD_DIAG_EN0 | 0x0000000F)
+ : (RCDF_MBD_DIAG_EN0 | 0x0000000B);
+ gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
+
+ /* CONFIGURE DISPLAY FILTER FOR APPROPRIATE OUTPUT */
+
+ if (source != CRC_SOURCE_GFX_DATA) {
+ gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ old_fmt = msr_value.low;
+ msr_value.low &= ~(RCDF_CONFIG_FMT_MASK);
+ msr_value.low |=
+ ((source ==
+ CRC_SOURCE_FP_DATA) ? RCDF_CONFIG_FMT_FP :
+ RCDF_CONFIG_FMT_CRT);
+ gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ }
+
+ /* CONFIGURE MCP TO LOAD REGB DATA ONTO UPPER 32-BITS */
+
+ msr_value.low = MCP_MBD_DIAG_EN1 | 0x00050000;
+ gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
+
+ /* ENABLE HW CLOCK GATING AND SET MCP CLOCK TO DOT CLOCK */
+
+ msr_value.low = 1l;
+ gfx_msr_write(RC_ID_MCP, MBD_MSR_PM, &msr_value);
+ msr_value.low = 0;
+ gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
+ msr_value.low = 3;
+ gfx_msr_write(RC_ID_MCP, MCP_DBGCLKCTL, &msr_value);
+
+ /* DISABLE MCP ACTIONS */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
+
+ /* SET APPROPRIATE BASE ADDRESS */
+ /* M-Sets use normal diag bits, while N-Sets use inverted diag bits */
+ /* We thus use the M-sets when polling for a high signal and the N */
+ /* sets when polling for a low signal. */
+
+ if (source != CRC_SOURCE_GFX_DATA) {
+ sync_polarities = gfx_get_sync_polarities();
+ vsync_bit = 29;
+ hsync_bit = 30;
+ } else {
+ vsync_bit = 25;
+ hsync_bit = 26;
+ }
+
+ if (sync_polarities & 1) {
+ hsync_active_base = MCP_SETM0CTL;
+ hsync_active_shift = 2;
+ } else {
+ hsync_active_base = MCP_SETN0CTL;
+ hsync_active_shift = 1;
+ }
+ if (sync_polarities & 2) {
+ vsync_active_base = MCP_SETM0CTL;
+ vsync_inactive_base = MCP_SETN0CTL;
+ vsync_active_shift = 2;
+ vsync_inactive_shift = 1;
+ } else {
+ vsync_active_base = MCP_SETN0CTL;
+ vsync_inactive_base = MCP_SETM0CTL;
+ vsync_active_shift = 1;
+ vsync_inactive_shift = 2;
+ }
+
+ /* SET STATE TRANSITIONS */
+
+ /* STATE 0-1 TRANSITION (SET 0) */
+ /* XState = 00 and VSync Inactive */
+ /* Note: DF VSync = Diag Bus Bit 29 */
+ /* VG VSync = Diag Bus Bit 25 */
+
+ msr_value.low = 0x000000A0;
+ msr_value.high = 0x00008000 | ((unsigned long)vsync_bit << 16) |
+ ((unsigned long)vsync_bit << 21) | ((unsigned long)vsync_bit << 26);
+ gfx_msr_write(RC_ID_MCP, vsync_inactive_base, &msr_value);
+
+ /* STATE 1-2 TRANSITION (SET 4) */
+ /* XState = 01 and VSync Active */
+
+ msr_value.low = 0x000000C0;
+ gfx_msr_write(RC_ID_MCP, vsync_active_base + 4, &msr_value);
+
+ /* STATE 2-3 TRANSITION (SET 1) */
+ /* XState = 10 and VSync Inactive */
+
+ msr_value.low = 0x00000120;
+ gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 1, &msr_value);
+
+ /* HORIZONTAL COUNTER (SET 5) */
+ /* XState = 10 and HSync Active */
+ /* Notes: DF HSync = Diag Bus Bit 30 */
+ /* VG HSync = Diag Bus Bit 26 */
+
+ msr_value.high = 0x00008000 | ((unsigned long)hsync_bit << 16) |
+ ((unsigned long)hsync_bit << 21) | ((unsigned long)hsync_bit << 26);
+ msr_value.low = 0x00000120;
+ gfx_msr_write(RC_ID_MCP, hsync_active_base + 5, &msr_value);
+
+ /* HORIZONTAL COUNTER RESET (SET 4) */
+ /* XState = 10 and H. Counter = limit */
+ /* Note: H. Counter is lower 16-bits of */
+ /* RegB. */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000128;
+ gfx_msr_write(RC_ID_MCP, vsync_inactive_base + 4, &msr_value);
+
+ /* CRC TRIGGER (SET 0) */
+ /* Cmp0 <= xpos < Cmp1 */
+ /* Cmp2 <= ypos < Cmp2 */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x10C20120;
+ gfx_msr_write(RC_ID_MCP, vsync_active_base, &msr_value);
+
+ /* SET COMPARATOR VALUES */
+ /* Note: The VG data outputs from the DF are delayed by one pixel clock. */
+ /* In this mode, we thus add one to horizontal comparator limits. */
+
+ /* COMPARATOR 0 */
+ /* Lower limit = xpos + (h_blank_pixels - 1) - 3 */
+ /* Notes: */
+ /* 1. 3 is the pipeline delay for MCP register */
+ /* data to access the diag bus */
+ /* 2. h_blank_pixels = HTOTAL - HSYNC_END */
+
+ xpos = (unsigned long)x + ((unsigned long)gfx_get_htotal() -
+ (unsigned long)gfx_get_hsync_end() - 1l) - 3l;
+ if (source == CRC_SOURCE_GFX_DATA)
+ xpos++;
+ msr_value.high = 0x00000000;
+ msr_value.low = xpos;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0, &msr_value);
+
+ /* COMPARATOR 1 */
+ /* Upper limit = xpos + width + (h_blank_pixels - 1) - 3 */
+
+ msr_value.low = xpos + (unsigned long)width;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 2, &msr_value);
+
+ /* COMPARATOR 2 */
+ /* Lower limit = ypos + v_blank_pixels */
+ /* Notes: */
+ /* 1. v_blank_pixels = VTOTAL - VSYNC_END */
+
+ ypos =
+ (unsigned long)y + (unsigned long)gfx_get_vtotal() -
+ (unsigned long)gfx_get_vsync_end();
+ msr_value.low = ypos << 16;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 4, &msr_value);
+
+ /* COMPARATOR 3 */
+ /* Upper limit = ypos + height + v_blank_pixels */
+
+ msr_value.low = (ypos + (unsigned long)height) << 16;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPVAL0 + 6, &msr_value);
+
+ /* SET COMPARATOR MASKS */
+
+ /* COMPARATORS 0 AND 1 REFER TO LOWER 16 BITS OF REGB */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x0000FFFF;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 2, &msr_value);
+
+ /* COMPARATORS 2 AND 3 REFER TO UPPER 16 BITS OF REGB */
+
+ msr_value.low = 0xFFFF0000;
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 4, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_CMPMASK0 + 6, &msr_value);
+
+ /* SET REGA MASK TO CRC ONLY 24 BITS OF DATA */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00FFFFFF;
+ gfx_msr_write(RC_ID_MCP, MCP_REGAMASK, &msr_value);
+
+ /* SET REGB VALUE */
+ /* Lower 16 bits use HTOTAL - SYNC TIME - 1 to set the counter rollover
+ * limit. */
+ /* Upper 16 bits use 0xFFFF to remove auto-clear behavior. */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0xFFFF0000 |
+ ((gfx_get_htotal() - (gfx_get_hsync_end() - gfx_get_hsync_start()) -
+ 1) & 0xFFFF);
+ gfx_msr_write(RC_ID_MCP, MCP_REGBVAL, &msr_value);
+
+ /* PROGRAM ACTIONS */
+
+ /* GOTO STATE 01 */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000008 | (1l << vsync_inactive_shift);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 14, &msr_value);
+
+ /* GOTO STATE 10 */
+
+ msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 15, &msr_value);
+
+ /* GOTO STATE 11 */
+
+ msr_value.low = 0x00000080 | (1l << (vsync_inactive_shift + 4));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 16, &msr_value);
+
+ /* CLEAR REGB (COUNTERS) */
+ /* RegB is cleared upon transitioning to state 10 */
+ /* RegA is not cleared as the initial value must be 0x00000001 */
+
+ msr_value.low = 0x00080000 | (1l << (vsync_active_shift + 16));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0, &msr_value);
+
+ /* CRC INTO REGA */
+ /* INCREMENT H. COUNTER */
+ /* cmp0 <= xpos < cmp1 */
+ /* cmp2 <= ypos < cmp3 */
+ /* XState = 10 */
+
+ msr_value.low = 0x00000008 | (1l << vsync_active_shift) |
+ 0x00800000 | (1l << (hsync_active_shift + 20));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 1, &msr_value);
+
+ /* INCREMENT V. COUNTER */
+ /* V. Counter is incremented when the H. Counter */
+ /* rolls over. */
+
+ msr_value.low = 0x00080000 | (1l << (vsync_inactive_shift + 16));
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 2, &msr_value);
+
+ /* CLEAR ALL OTHER ACTIONS */
+ /* This prevents side-effects from previous accesses to the MCP */
+ /* debug logic. */
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 3, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 4, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 5, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 6, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 7, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 8, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 9, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 10, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 11, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 12, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 13, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 17, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 18, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 19, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MCP_ACTION0 + 20, &msr_value);
+
+ /* SET REGA CRC VALUE TO 1 OR 0 */
+
+ if (!crc32)
+ msr_value.low = 0x00000001;
+ gfx_msr_write(RC_ID_MCP, MCP_REGA, &msr_value);
+
+ /* SET XSTATE TO 0 */
+
+ msr_value.low = 0;
+ msr_value.high = 0;
+ gfx_msr_write(RC_ID_MCP, MCP_XSTATE, &msr_value);
+
+ /* CONFIGURE DIAG CONTROL */
+ /* Set all four comparators to watch the upper diag bus. */
+ /* Set REGA action1 to legacy CRC or 32-bit CRC. */
+ /* Set REGB action1 to increment lower 16 bits and clear at limit. */
+ /* Set REGB action2 to increment upper 16 bits. */
+ /* Enable all actions. */
+
+ if (crc32)
+ msr_value.low = 0x9A820055;
+ else
+ msr_value.low = 0x9A840055;
+ msr_value.high = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
+
+ /* DELAY TWO FRAMES */
+
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+ while (gfx_test_vertical_active()) ;
+ while (!gfx_test_vertical_active()) ;
+
+ /* VERIFY THAT XSTATE = 11 */
+
+ gfx_msr_read(RC_ID_MCP, MCP_XSTATE, &msr_value);
+ if ((msr_value.low & 3) == 3) {
+ gfx_msr_read(RC_ID_MCP, MCP_REGA, &msr_value);
+
+ crc = msr_value.low;
+ if (!crc32)
+ crc &= 0xFFFFFF;
+ }
+
+ /* DISABLE MCP AND DF DIAG BUS OUTPUTS */
+
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ gfx_msr_write(RC_ID_DF, MBD_MSR_DIAG, &msr_value);
+ gfx_msr_write(RC_ID_MCP, MBD_MSR_DIAG, &msr_value);
+
+ /* DISABLE MCP ACTIONS */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000000;
+ gfx_msr_write(RC_ID_MCP, MCP_DIAGCTL, &msr_value);
+
+ /* RESTORE PREVIOUS OUTPUT FORMAT */
+
+ if (source != CRC_SOURCE_GFX_DATA) {
+ gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ msr_value.low = old_fmt;
+ gfx_msr_write(RC_ID_DF, MBD_MSR_CONFIG, &msr_value);
+ }
+ return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_enable
+ *
+ * This routine returns 1 if the selected alpha window is currently
+ * enabled, or 0 if it is currently disabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_alpha_enable(int *enable)
+#else
+void
+gfx_get_alpha_enable(int *enable)
+#endif
+{
+ unsigned long value = 0;
+
+ *enable = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(RCDF_ALPHA_CONTROL_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ if (value & RCDF_ACTRL_WIN_ENABLE)
+ *enable = 1;
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_size
+ *
+ * This routine returns the size of the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height)
+#else
+void
+gfx_get_alpha_size(unsigned short *x, unsigned short *y,
+ unsigned short *width, unsigned short *height)
+#endif
+{
+ unsigned long value = 0;
+
+ *x = 0;
+ *y = 0;
+ *width = 0;
+ *height = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(RCDF_ALPHA_XPOS_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ *x = (unsigned short)(value & 0x000007FF);
+ *width = (unsigned short)((value >> 16) & 0x000007FF) - *x;
+ value =
+ READ_VID32(RCDF_ALPHA_YPOS_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ *y = (unsigned short)(value & 0x000007FF);
+ *height = (unsigned short)((value >> 16) & 0x000007FF) - *y;
+ }
+ *x -= gfx_get_htotal() - gfx_get_hsync_end() - 2;
+ *y -= gfx_get_vtotal() - gfx_get_vsync_end() + 1;
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_value
+ *
+ * This routine returns the alpha value and increment/decrement value of
+ * the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_alpha_value(unsigned char *alpha, char *delta)
+#else
+void
+gfx_get_alpha_value(unsigned char *alpha, char *delta)
+#endif
+{
+ unsigned long value = 0;
+
+ *alpha = 0;
+ *delta = 0;
+ if (gfx_alpha_select <= 2) {
+ value =
+ READ_VID32(RCDF_ALPHA_CONTROL_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ *alpha = (unsigned char)(value & 0x00FF);
+ *delta = (char)((value >> 8) & 0x00FF);
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_priority
+ *
+ * This routine returns the priority of the currently selected alpha region.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_alpha_priority(int *priority)
+#else
+void
+gfx_get_alpha_priority(int *priority)
+#endif
+{
+ unsigned long pos = 0, value = 0;
+
+ *priority = 0;
+ if (gfx_alpha_select <= 2) {
+ value = READ_VID32(RCDF_VID_ALPHA_CONTROL);
+ pos = 16 + (gfx_alpha_select << 1);
+ *priority = (int)((value >> pos) & 3);
+ }
+ return;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_alpha_color
+ *
+ * This routine returns the color register value for the currently selected
+ * alpha region. Bit 24 is set if the color register is enabled.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_VIDEO_DYNAMIC
+void
+redcloud_get_alpha_color(unsigned long *color)
+#else
+void
+gfx_get_alpha_color(unsigned long *color)
+#endif
+{
+ *color = 0;
+ if (gfx_alpha_select <= 2) {
+ *color =
+ READ_VID32(RCDF_ALPHA_COLOR_1 +
+ ((unsigned long)gfx_alpha_select << 5));
+ }
+ return;
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff --git a/src/gfx/vip_1200.c b/src/gfx/vip_1200.c
new file mode 100644
index 0000000..731e1b8
--- /dev/null
+++ b/src/gfx/vip_1200.c
@@ -0,0 +1,663 @@
+/* Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+
+/*
+ * This file contains routines to control the SC1200 video input port (VIP)
+ * hardware.
+ * */
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_enable
+ *
+ * This routine enables or disables the writes to memory from the video port.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vip_enable(int enable)
+#else
+int
+gfx_set_vip_enable(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VIP32(SC1200_VIP_CONTROL);
+ if (enable)
+ value |= SC1200_VIP_DATA_CAPTURE_EN;
+ else
+ value &= ~SC1200_VIP_DATA_CAPTURE_EN;
+ WRITE_VIP32(SC1200_VIP_CONTROL, value);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_capture_run_mode
+ *
+ * This routine selects VIP capture run mode.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vip_capture_run_mode(int mode)
+#else
+int
+gfx_set_vip_capture_run_mode(int mode)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VIP32(SC1200_VIP_CONTROL);
+ value &= ~SC1200_CAPTURE_RUN_MODE_MASK;
+ switch (mode) {
+ case VIP_CAPTURE_STOP_LINE:
+ value |= SC1200_CAPTURE_RUN_MODE_STOP_LINE;
+ break;
+ case VIP_CAPTURE_STOP_FIELD:
+ value |= SC1200_CAPTURE_RUN_MODE_STOP_FIELD;
+ break;
+ case VIP_CAPTURE_START_FIELD:
+ value |= SC1200_CAPTURE_RUN_MODE_START;
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ WRITE_VIP32(SC1200_VIP_CONTROL, value);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_base
+ *
+ * This routine sets the odd and even base address values for the VIP memory
+ * buffer.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vip_base(unsigned long even, unsigned long odd)
+#else
+int
+gfx_set_vip_base(unsigned long even, unsigned long odd)
+#endif
+{
+ /* TRUE OFFSET IS SPECIFIED, NEED TO SET BIT 23 FOR HARDWARE */
+
+ if (even)
+ WRITE_VIP32(SC1200_VIP_EVEN_BASE,
+ even + (unsigned long)gfx_phys_fbptr);
+ if (odd)
+ WRITE_VIP32(SC1200_VIP_ODD_BASE, odd + (unsigned long)gfx_phys_fbptr);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_pitch
+ *
+ * This routine sets the number of bytes between scanlines for the VIP data.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vip_pitch(unsigned long pitch)
+#else
+int
+gfx_set_vip_pitch(unsigned long pitch)
+#endif
+{
+ WRITE_VIP32(SC1200_VIP_PITCH, pitch & SC1200_VIP_PITCH_MASK);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_mode
+ *
+ * This routine sets the VIP operating mode.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vip_mode(int mode)
+#else
+int
+gfx_set_vip_mode(int mode)
+#endif
+{
+ unsigned long config;
+
+ config = READ_VIP32(SC1200_VIP_CONFIG);
+ config &= ~SC1200_VIP_MODE_MASK;
+ switch (mode) {
+ case VIP_MODE_C:
+ WRITE_VIP32(SC1200_VIP_CONFIG, config | SC1200_VIP_MODE_C);
+ break;
+ default:
+ return GFX_STATUS_BAD_PARAMETER;
+ }
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_enable
+ *
+ * This routine enables or disables the VBI data capture.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vbi_enable(int enable)
+#else
+int
+gfx_set_vbi_enable(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VIP32(SC1200_VIP_CONTROL);
+ if (enable)
+ value |= SC1200_VIP_VBI_CAPTURE_EN;
+ else
+ value &= ~SC1200_VIP_VBI_CAPTURE_EN;
+ WRITE_VIP32(SC1200_VIP_CONTROL, value);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_mode
+ *
+ * This routine sets the VBI data types captured to memory.
+ * It receives a mask of all enabled types.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vbi_mode(int mode)
+#else
+int
+gfx_set_vbi_mode(int mode)
+#endif
+{
+ unsigned long config;
+
+ config = READ_VIP32(SC1200_VIP_CONFIG);
+ config &=
+ ~(SC1200_VBI_ANCILLARY_TO_MEMORY | SC1200_VBI_TASK_A_TO_MEMORY |
+ SC1200_VBI_TASK_B_TO_MEMORY);
+
+ if (mode & VBI_ANCILLARY)
+ config |= SC1200_VBI_ANCILLARY_TO_MEMORY;
+ if (mode & VBI_TASK_A)
+ config |= SC1200_VBI_TASK_A_TO_MEMORY;
+ if (mode & VBI_TASK_B)
+ config |= SC1200_VBI_TASK_B_TO_MEMORY;
+ WRITE_VIP32(SC1200_VIP_CONFIG, config);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_base
+ *
+ * This routine sets the odd and even base address values for VBI capture.
+ *
+ * "even" and "odd" should contain 16-byte aligned physical addresses.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vbi_base(unsigned long even, unsigned long odd)
+#else
+int
+gfx_set_vbi_base(unsigned long even, unsigned long odd)
+#endif
+{
+ /* VIP HW REQUIRES THAT BASE ADDRESSES BE 16-BYTE ALIGNED */
+
+ if (even)
+ WRITE_VIP32(SC1200_VBI_EVEN_BASE, even & ~0xf);
+ if (odd)
+ WRITE_VIP32(SC1200_VBI_ODD_BASE, odd & ~0xf);
+
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_pitch
+ *
+ * This routine sets the number of bytes between scanlines for VBI capture.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vbi_pitch(unsigned long pitch)
+#else
+int
+gfx_set_vbi_pitch(unsigned long pitch)
+#endif
+{
+ WRITE_VIP32(SC1200_VBI_PITCH, pitch & SC1200_VBI_PITCH_MASK);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_direct
+ *
+ * This routine sets the VBI lines to be passed to the Direct VIP.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines)
+#else
+int
+gfx_set_vbi_direct(unsigned long even_lines, unsigned long odd_lines)
+#endif
+{
+ WRITE_VIP32(SC1200_EVEN_DIRECT_VBI_LINE_ENABLE,
+ even_lines & SC1200_DIRECT_VBI_LINE_ENABLE_MASK);
+ WRITE_VIP32(SC1200_ODD_DIRECT_VBI_LINE_ENABLE,
+ odd_lines & SC1200_DIRECT_VBI_LINE_ENABLE_MASK);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vbi_interrupt
+ *
+ * This routine enables or disables the VBI field interrupt.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vbi_interrupt(int enable)
+#else
+int
+gfx_set_vbi_interrupt(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VIP32(SC1200_VIP_CONTROL);
+ if (enable)
+ value |= SC1200_VIP_VBI_FIELD_INTERRUPT_EN;
+ else
+ value &= ~SC1200_VIP_VBI_FIELD_INTERRUPT_EN;
+ WRITE_VIP32(SC1200_VIP_CONTROL, value);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_bus_request_threshold_high
+ *
+ * This routine sets the VIP FIFO bus request threshold.
+ * If enable is TRUE, VIP FIFO will be set to issue a bus request when it
+ * filled with 64 bytes. If enable is FALSE, VIP FIFO will be set to issue a
+ * bus request when it filled with 32 bytes.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vip_bus_request_threshold_high(int enable)
+#else
+int
+gfx_set_vip_bus_request_threshold_high(int enable)
+#endif
+{
+ unsigned long value;
+
+ value = READ_VIP32(SC1200_VIP_CONFIG);
+ if (enable)
+ value &= ~SC1200_VIP_BUS_REQUEST_THRESHOLD;
+ else
+ value |= SC1200_VIP_BUS_REQUEST_THRESHOLD;
+ WRITE_VIP32(SC1200_VIP_CONFIG, value);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_vip_last_line
+ *
+ * This routine sets the maximum number of lines captured in each field.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_set_vip_last_line(int last_line)
+#else
+int
+gfx_set_vip_last_line(int last_line)
+#endif
+{
+ unsigned long value;
+
+ /* This feature is implemented in Rev C1 */
+ if (gfx_chip_revision < SC1200_REV_C1)
+ return (GFX_STATUS_OK);
+
+ value = READ_VIP32(SC1200_VIP_LINE_TARGET);
+ value &= ~SC1200_VIP_LAST_LINE_MASK;
+ value |= ((last_line & 0x3FF) << 16);
+ WRITE_VIP32(SC1200_VIP_LINE_TARGET, value);
+ return (GFX_STATUS_OK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_test_vip_odd_field
+ *
+ * This routine returns 1 if the current VIP field is odd. Otherwise returns 0
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_test_vip_odd_field(void)
+#else
+int
+gfx_test_vip_odd_field(void)
+#endif
+{
+ if (READ_VIP32(SC1200_VIP_STATUS) & SC1200_VIP_CURRENT_FIELD_ODD)
+ return (1);
+ else
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_test_vip_bases_updated
+ *
+ * This routine returns 1 if all of the VIP base registers have been updated,
+ * i.e. there is no base register which has been written with a new address,
+ * that VIP has not already captured or started capturing into the new address
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_test_vip_bases_updated(void)
+#else
+int
+gfx_test_vip_bases_updated(void)
+#endif
+{
+ if (READ_VIP32(SC1200_VIP_STATUS) & SC1200_VIP_BASE_NOT_UPDATED)
+ return (0);
+ else
+ return (1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_test_vip_fifo_overflow
+ *
+ * This routine returns 1 if an overflow occurred on the FIFO between the VIP
+ * and the fast X-bus, 0 otherwise.
+ * If an overflow occurred, the overflow status indication is reset.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_test_vip_fifo_overflow(void)
+#else
+int
+gfx_test_vip_fifo_overflow(void)
+#endif
+{
+ if (READ_VIP32(SC1200_VIP_STATUS) & SC1200_VIP_FIFO_OVERFLOW) {
+ /* Bits in vip status register are either read only or reset by
+ * writing 1 */
+ WRITE_VIP32(SC1200_VIP_STATUS, SC1200_VIP_FIFO_OVERFLOW);
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_line
+ *
+ * This routine returns the number of the current video line being
+ * received by the VIP interface.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_get_vip_line(void)
+#else
+int
+gfx_get_vip_line(void)
+#endif
+{
+ return (int)(READ_VIP32(SC1200_VIP_CURRENT_LINE) &
+ SC1200_VIP_CURRENT_LINE_MASK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_base
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+unsigned long
+sc1200_get_vip_base(int odd)
+#else
+unsigned long
+gfx_get_vip_base(int odd)
+#endif
+{
+ /* MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET */
+
+ if (odd)
+ return (READ_VIP32(SC1200_VIP_ODD_BASE));
+ return (READ_VIP32(SC1200_VIP_EVEN_BASE));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_pitch
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+unsigned long
+sc1200_get_vbi_pitch(void)
+#else
+unsigned long
+gfx_get_vbi_pitch(void)
+#endif
+{
+ return (READ_VIP32(SC1200_VBI_PITCH) & SC1200_VBI_PITCH_MASK);
+}
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+#if GFX_READ_ROUTINES
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_enable
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_get_vip_enable(void)
+#else
+int
+gfx_get_vip_enable(void)
+#endif
+{
+ if (READ_VIP32(SC1200_VIP_CONTROL) & SC1200_VIP_DATA_CAPTURE_EN)
+ return (1);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_pitch
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+unsigned long
+sc1200_get_vip_pitch(void)
+#else
+unsigned long
+gfx_get_vip_pitch(void)
+#endif
+{
+ return (READ_VIP32(SC1200_VIP_PITCH) & SC1200_VIP_PITCH_MASK);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_mode
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_get_vip_mode(void)
+#else
+int
+gfx_get_vip_mode(void)
+#endif
+{
+ switch (READ_VIP32(SC1200_VIP_CONFIG) & SC1200_VIP_MODE_MASK) {
+ case SC1200_VIP_MODE_C:
+ return VIP_MODE_C;
+ default:
+ return (0);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_enable
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_get_vbi_enable(void)
+#else
+int
+gfx_get_vbi_enable(void)
+#endif
+{
+ if (READ_VIP32(SC1200_VIP_CONTROL) & SC1200_VIP_VBI_CAPTURE_EN)
+ return (1);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_mode
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_get_vbi_mode(void)
+#else
+int
+gfx_get_vbi_mode(void)
+#endif
+{
+ int config;
+ int mode = 0;
+
+ config =
+ (int)(READ_VIP32(SC1200_VIP_CONFIG) & (SC1200_VBI_ANCILLARY_TO_MEMORY
+ | SC1200_VBI_TASK_A_TO_MEMORY | SC1200_VBI_TASK_B_TO_MEMORY));
+ if (config & SC1200_VBI_ANCILLARY_TO_MEMORY)
+ mode |= VBI_ANCILLARY;
+ if (config & SC1200_VBI_TASK_A_TO_MEMORY)
+ mode |= VBI_TASK_A;
+ if (config & SC1200_VBI_TASK_B_TO_MEMORY)
+ mode |= VBI_TASK_B;
+ return mode;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_base
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+unsigned long
+sc1200_get_vbi_base(int odd)
+#else
+unsigned long
+gfx_get_vbi_base(int odd)
+#endif
+{
+ /* MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET */
+
+ if (odd)
+ return (READ_VIP32(SC1200_VBI_ODD_BASE));
+ return (READ_VIP32(SC1200_VBI_EVEN_BASE));
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vbi_direct
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+unsigned long
+sc1200_get_vbi_direct(int odd)
+#else
+unsigned long
+gfx_get_vbi_direct(int odd)
+#endif
+{
+ /* MASK BIT 23 AND ABOVE TO MAKE IT A TRUE OFFSET */
+
+ if (odd)
+ return (READ_VIP32(SC1200_ODD_DIRECT_VBI_LINE_ENABLE) &
+ SC1200_DIRECT_VBI_LINE_ENABLE_MASK);
+ return (READ_VIP32(SC1200_EVEN_DIRECT_VBI_LINE_ENABLE) &
+ SC1200_DIRECT_VBI_LINE_ENABLE_MASK);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vbi_interrupt
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_get_vbi_interrupt(void)
+#else
+int
+gfx_get_vbi_interrupt(void)
+#endif
+{
+ if (READ_VIP32(SC1200_VIP_CONTROL) & SC1200_VIP_VBI_FIELD_INTERRUPT_EN)
+ return (1);
+ return (0);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_vip_bus_request_threshold_high
+ *----------------------------------------------------------------------------
+ */
+#if GFX_VIP_DYNAMIC
+int
+sc1200_get_vip_bus_request_threshold_high(void)
+#else
+int
+gfx_get_vip_bus_request_threshold_high(void)
+#endif
+{
+ if (READ_VIP32(SC1200_VIP_CONFIG) & SC1200_VIP_BUS_REQUEST_THRESHOLD)
+ return (1);
+ return (0);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */