1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu1.c,v 1.4 2003/02/06 17:46:02 alanh Exp $ */
2/*
3 * $Workfile: disp_gu1.c $
4 *
5 * This file contains routines for the first generation display controller.
6 *
7 * NSC_LIC_ALTERNATIVE_PREAMBLE
8 *
9 * Revision 1.0
10 *
11 * National Semiconductor Alternative GPL-BSD License
12 *
13 * National Semiconductor Corporation licenses this software
14 * ("Software"):
15 *
16 *      Durango
17 *
18 * under one of the two following licenses, depending on how the
19 * Software is received by the Licensee.
20 *
21 * If this Software is received as part of the Linux Framebuffer or
22 * other GPL licensed software, then the GPL license designated
23 * NSC_LIC_GPL applies to this Software; in all other circumstances
24 * then the BSD-style license designated NSC_LIC_BSD shall apply.
25 *
26 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
27
28/* NSC_LIC_BSD
29 *
30 * National Semiconductor Corporation Open Source License for Durango
31 *
32 * (BSD License with Export Notice)
33 *
34 * Copyright (c) 1999-2001
35 * National Semiconductor Corporation.
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 *
42 *   * Redistributions of source code must retain the above copyright
43 *     notice, this list of conditions and the following disclaimer.
44 *
45 *   * Redistributions in binary form must reproduce the above
46 *     copyright notice, this list of conditions and the following
47 *     disclaimer in the documentation and/or other materials provided
48 *     with the distribution.
49 *
50 *   * Neither the name of the National Semiconductor Corporation nor
51 *     the names of its contributors may be used to endorse or promote
52 *     products derived from this software without specific prior
53 *     written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
56 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
57 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
58 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
59 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
60 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
62 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
64 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
65 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
67 * OF SUCH DAMAGE.
68 *
69 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
70 * YOUR JURISDICTION. It is licensee's responsibility to comply with
71 * any export regulations applicable in licensee's jurisdiction. Under
72 * CURRENT (2001) U.S. export regulations this software
73 * is eligible for export from the U.S. and can be downloaded by or
74 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
75 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
76 * Syria, Sudan, Afghanistan and any other country to which the U.S.
77 * has embargoed goods and services.
78 *
79 * END_NSC_LIC_BSD */
80
81/* NSC_LIC_GPL
82 *
83 * National Semiconductor Corporation Gnu General Public License for Durango
84 *
85 * (GPL License with Export Notice)
86 *
87 * Copyright (c) 1999-2001
88 * National Semiconductor Corporation.
89 * All rights reserved.
90 *
91 * Redistribution and use in source and binary forms, with or without
92 * modification, are permitted under the terms of the GNU General
93 * Public License as published by the Free Software Foundation; either
94 * version 2 of the License, or (at your option) any later version
95 *
96 * In addition to the terms of the GNU General Public License, neither
97 * the name of the National Semiconductor Corporation nor the names of
98 * its contributors may be used to endorse or promote products derived
99 * from this software without specific prior written permission.
100 *
101 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
102 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
103 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
104 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
105 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
106 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
107 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
108 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
109 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
110 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
111 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
112 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
113 * OF SUCH DAMAGE. See the GNU General Public License for more details.
114 *
115 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
116 * YOUR JURISDICTION. It is licensee's responsibility to comply with
117 * any export regulations applicable in licensee's jurisdiction. Under
118 * CURRENT (2001) U.S. export regulations this software
119 * is eligible for export from the U.S. and can be downloaded by or
120 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
121 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
122 * Syria, Sudan, Afghanistan and any other country to which the U.S.
123 * has embargoed goods and services.
124 *
125 * You should have received a copy of the GNU General Public License
126 * along with this file; if not, write to the Free Software Foundation,
127 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
128 *
129 * END_NSC_LIC_GPL */
130
131void gu1_enable_compression(void);	/* private routine definition */
132void gu1_disable_compression(void);	/* private routine definition */
133void gfx_reset_video(void);		/* private routine definition */
134int gfx_set_display_control(int sync_polarities);	/* private routine definition */
135void gu1_delay_approximate(unsigned long milliseconds);
136void gu1_delay_precise(unsigned long milliseconds);
137int gu1_set_display_bpp(unsigned short bpp);
138int gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz);
139int gu1_set_display_mode(int xres, int yres, int bpp, int hz);
140int gu1_set_display_timings(unsigned short bpp, unsigned short flags,
141			    unsigned short hactive,
142			    unsigned short hblank_start,
143			    unsigned short hsync_start,
144			    unsigned short hsync_end,
145			    unsigned short hblank_end, unsigned short htotal,
146			    unsigned short vactive,
147			    unsigned short vblank_start,
148			    unsigned short vsync_start,
149			    unsigned short vsync_end,
150			    unsigned short vblank_end, unsigned short vtotal,
151			    unsigned long frequency);
152int gu1_set_vtotal(unsigned short vtotal);
153void gu1_set_display_pitch(unsigned short pitch);
154void gu1_set_display_offset(unsigned long offset);
155int gu1_set_display_palette_entry(unsigned long index, unsigned long palette);
156int gu1_set_display_palette(unsigned long *palette);
157void gu1_video_shutdown(void);
158void gu1_set_clock_frequency(unsigned long frequency);
159int gu1_set_crt_enable(int enable);
160void gu1_set_cursor_enable(int enable);
161void gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor);
162void gu1_set_cursor_position(unsigned long memoffset,
163			     unsigned short xpos, unsigned short ypos,
164			     unsigned short xhotspot,
165			     unsigned short yhotspot);
166void gu1_set_cursor_shape32(unsigned long memoffset, unsigned long *andmask,
167			    unsigned long *xormask);
168void gu1_set_cursor_shape64(unsigned long memoffset, unsigned long *andmask,
169			    unsigned long *xormask);
170void gu1_set_icon_enable(int enable);
171void gu1_set_icon_colors(unsigned long color0, unsigned long color1,
172			 unsigned long color2);
173void gu1_set_icon_position(unsigned long memoffset, unsigned short xpos);
174void gu1_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
175			  unsigned long *xormask, unsigned int lines);
176
177int gu1_set_compression_enable(int enable);
178int gu1_set_compression_offset(unsigned long offset);
179int gu1_set_compression_pitch(unsigned short pitch);
180int gu1_set_compression_size(unsigned short size);
181void gu1_set_display_priority_high(int enable);
182int gu1_test_timing_active(void);
183int gu1_test_vertical_active(void);
184int gu1_wait_vertical_blank(void);
185void gu1_delay_milliseconds(unsigned long milliseconds);
186void gu1_delay_microseconds(unsigned long microseconds);
187void gu1_enable_panning(int x, int y);
188int gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
189			  unsigned short height, unsigned short bpp);
190int gu1_set_panel_present(int panelResX, int panelResY, unsigned short width,
191			  unsigned short height, unsigned short bpp);
192void gu1_reset_timing_lock(void);
193
194int gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz);
195unsigned short gu1_get_display_pitch(void);
196int gu1_get_vsa2_softvga_enable(void);
197int gu1_get_sync_polarities(void);
198unsigned long gu1_get_clock_frequency(void);
199unsigned long gu1_get_max_supported_pixel_clock(void);
200int gu1_mode_frequency_supported(int xres, int yres, int bpp,
201				 unsigned long frequency);
202int gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
203				       unsigned long frequency);
204int gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
205				  unsigned long frequency);
206int gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
207				       int *frequency);
208int gu1_get_display_mode_count(void);
209int gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz);
210unsigned long gu1_get_frame_buffer_line_size(void);
211unsigned short gu1_get_hactive(void);
212unsigned short gu1_get_hblank_start(void);
213unsigned short gu1_get_hsync_start(void);
214unsigned short gu1_get_hsync_end(void);
215unsigned short gu1_get_hblank_end(void);
216unsigned short gu1_get_htotal(void);
217unsigned short gu1_get_vactive(void);
218unsigned short gu1_get_vline(void);
219unsigned short gu1_get_vblank_start(void);
220unsigned short gu1_get_vsync_start(void);
221unsigned short gu1_get_vsync_end(void);
222unsigned short gu1_get_vblank_end(void);
223unsigned short gu1_get_vtotal(void);
224unsigned short gu1_get_display_bpp(void);
225unsigned long gu1_get_display_offset(void);
226int gu1_get_display_palette_entry(unsigned long index,
227				  unsigned long *palette);
228void gu1_get_display_palette(unsigned long *palette);
229unsigned long gu1_get_cursor_enable(void);
230unsigned long gu1_get_cursor_offset(void);
231unsigned long gu1_get_cursor_position(void);
232unsigned long gu1_get_cursor_clip(void);
233unsigned long gu1_get_cursor_color(int color);
234unsigned long gu1_get_icon_enable(void);
235unsigned long gu1_get_icon_offset(void);
236unsigned long gu1_get_icon_position(void);
237unsigned long gu1_get_icon_color(int color);
238int gu1_get_compression_enable(void);
239unsigned long gu1_get_compression_offset(void);
240unsigned short gu1_get_compression_pitch(void);
241unsigned short gu1_get_compression_size(void);
242int gu1_get_display_priority_high(void);
243int gu1_get_valid_bit(int line);
244void gu1_set_display_video_enable(int enable);
245int gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp);
246void gu1_set_display_video_size(unsigned short width, unsigned short height);
247void gu1_set_display_video_offset(unsigned long offset);
248unsigned long gu1_get_display_video_offset(void);
249unsigned long gu1_get_display_video_size(void);
250
251/* VIDEO BUFFER SIZE */
252
253unsigned long vid_buf_size = 0;
254int vid_enabled = 0;
255
256/*-----------------------------------------------------------------------------
257 * GU1_DELAY_APPROXIMATE (PRIVATE ROUTINE - NOT PART OF DURANGO API)
258 *
259 * Delay the requested number of milliseconds by reading a register.  This function
260 * generally takes longer than the requested time.
261 *-----------------------------------------------------------------------------*/
262void
263gu1_delay_approximate(unsigned long milliseconds)
264{
265   /* ASSUME 300 MHz, 5 CLOCKS PER READ */
266
267#	define READS_PER_MILLISECOND 60000L
268
269   unsigned long loop;
270
271   loop = milliseconds * READS_PER_MILLISECOND;
272   while (loop-- > 0) {
273      READ_REG32(DC_UNLOCK);
274   }
275}
276
277/*-----------------------------------------------------------------------------
278 * GU1_DELAY_PRECISE (PRIVATE ROUTINE - NOT PART OF DURANGO API)
279 *
280 * Delay the number of milliseconds on a more precise level, varying only by
281 * 1/10 of a ms.  This function should only be called if an SC1200 is present.
282 *-----------------------------------------------------------------------------*/
283void
284gu1_delay_precise(unsigned long milliseconds)
285{
286#if GFX_VIDEO_SC1200
287
288#define LOOP 1000
289   unsigned long i, timer_start, timer_end, total_ticks, previous_ticks,
290	 temp_ticks;
291
292   /* Get current time */
293   timer_start = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE);
294
295   /* Calculate expected end time */
296   if (INB(SC1200_CB_BASE_ADDR + SC1200_CB_TMCNFG) & SC1200_TMCLKSEL_27MHZ)
297      total_ticks = 27000 * milliseconds;	/* timer resolution is 27 MHz */
298   else
299      total_ticks = 1000 * milliseconds;	/* timer resolution is 1 MHz */
300
301   if (total_ticks > ((unsigned long)0xffffffff - timer_start))	/* wrap-around */
302      timer_end = total_ticks - ((unsigned long)0xffffffff - timer_start);
303   else
304      timer_end = timer_start + total_ticks;
305
306   /* in case of wrap around */
307   if (timer_end < timer_start) {
308      previous_ticks = timer_start;
309      while (1) {
310	 temp_ticks = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE);
311	 if (temp_ticks < previous_ticks)
312	    break;
313	 else
314	    previous_ticks = temp_ticks;
315	 for (i = 0; i < LOOP; i++)
316	    READ_REG32(DC_UNLOCK);
317      }
318   }
319   /* now the non-wrap around part */
320   while (1) {
321      for (i = 0; i < LOOP; i++)
322	 READ_REG32(DC_UNLOCK);
323      if (IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE) > timer_end)
324	 break;
325   }
326
327#endif /* GFX_VIDEO_SC1200 */
328}
329
330/*-----------------------------------------------------------------------------
331 * WARNING!!!! INACCURATE DELAY MECHANISM
332 *
333 * In an effort to keep the code self contained and operating system
334 * independent, the delay loop just performs reads of a display controller
335 * register.  This time will vary for faster processors.  The delay can always
336 * be longer than intended, only effecting the time of the mode switch
337 * (obviously want it to still be under a second).  Problems with the hardware
338 * only arise if the delay is not long enough.
339 *
340 * For the SC1200, the high resolution timer can be used as an accurate mechanism
341 * for keeping time. However, in order to avoid a busy loop of IO reads, the
342 * timer is polled in-between busy loops, and therefore the actual delay might
343 * be longer than the requested delay by the time of one busy loop
344 * (which on a 200 MHz system took 95 us)
345 *
346 * There are thus two delay functions which are called from the main API routine.
347 * One is meant to be more precise and should only called if an SC1200 is present.
348 *-----------------------------------------------------------------------------
349 */
350#if GFX_DISPLAY_DYNAMIC
351void
352gu1_delay_milliseconds(unsigned long milliseconds)
353#else
354void
355gfx_delay_milliseconds(unsigned long milliseconds)
356#endif
357{
358#if GFX_VIDEO_SC1200
359
360#if GFX_VIDEO_DYNAMIC
361   if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) {
362#endif
363      gu1_delay_precise(milliseconds);
364      return;
365#if GFX_VIDEO_DYNAMIC
366   }
367#endif
368
369#endif /* GFX_VIDEO_SC1200 */
370
371   gu1_delay_approximate(milliseconds);
372}
373
374#if GFX_DISPLAY_DYNAMIC
375void
376gu1_delay_microseconds(unsigned long microseconds)
377#else
378void
379gfx_delay_microseconds(unsigned long microseconds)
380#endif
381{
382   /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */
383
384   unsigned long loop_count = microseconds * 150;
385
386   while (loop_count-- > 0) {
387      ;
388   }
389}
390
391/*-----------------------------------------------------------------------------
392 * GFX_VIDEO_SHUTDOWN
393 *
394 * This routine disables the display controller output.
395 *-----------------------------------------------------------------------------
396 */
397void
398gu1_video_shutdown(void)
399{
400   unsigned long unlock;
401   unsigned long gcfg, tcfg;
402
403   /* DISABLE COMPRESSION */
404
405   gu1_disable_compression();
406
407   /* ALSO DISABLE VIDEO */
408   /* Use private "reset video" routine to do all that is needed. */
409   /* SC1200, for example, also disables the alpha blending regions. */
410
411   gfx_reset_video();
412
413   /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
414
415   unlock = READ_REG32(DC_UNLOCK);
416   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
417
418   /* READ THE CURRENT GX VALUES */
419
420   gcfg = READ_REG32(DC_GENERAL_CFG);
421   tcfg = READ_REG32(DC_TIMING_CFG);
422
423   /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */
424
425   tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN);
426   WRITE_REG32(DC_TIMING_CFG, tcfg);
427
428   /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */
429   /* This delay is used to make sure that all pending requests to the */
430   /* memory controller have completed before disabling the FIFO load. */
431
432   gfx_delay_milliseconds(1);
433
434   /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */
435
436   gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
437   WRITE_REG32(DC_GENERAL_CFG, gcfg);
438   WRITE_REG32(DC_UNLOCK, unlock);
439   return;
440}
441
442/*-----------------------------------------------------------------------------
443 * GFX_SET_DISPLAY_BPP
444 *
445 * This routine programs the bpp in the display controller.
446 *-----------------------------------------------------------------------------
447 */
448#if GFX_DISPLAY_DYNAMIC
449int
450gu1_set_display_bpp(unsigned short bpp)
451#else
452int
453gfx_set_display_bpp(unsigned short bpp)
454#endif
455{
456   unsigned long ocfg, lock;
457
458   lock = READ_REG32(DC_UNLOCK);
459   ocfg = READ_REG32(DC_OUTPUT_CFG) & ~(DC_OCFG_8BPP | DC_OCFG_555);
460
461   /* SET DC PIXEL FORMAT */
462
463   if (bpp == 8)
464      ocfg |= DC_OCFG_8BPP;
465   else if (bpp == 15)
466      ocfg |= DC_OCFG_555;
467   else if (bpp != 16)
468      return GFX_STATUS_BAD_PARAMETER;
469
470   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
471   WRITE_REG32(DC_OUTPUT_CFG, ocfg);
472   WRITE_REG32(DC_UNLOCK, lock);
473
474   /* SET BPP IN GRAPHICS PIPELINE */
475
476   gfx_set_bpp(bpp);
477
478   return 0;
479}
480
481/*-----------------------------------------------------------------------------
482 * GFX_SET_SPECIFIED_MODE
483 * This routine uses the parameters in the specified display mode structure
484 * to program the display controller hardware.
485 *-----------------------------------------------------------------------------
486 */
487int
488gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp)
489{
490   unsigned long unlock, value;
491   unsigned long gcfg, tcfg, ocfg;
492   unsigned long size, pitch;
493   unsigned long vid_buffer_size;
494   unsigned long hactive, vactive;
495
496   gbpp = bpp;
497
498   /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
499   /* Flag used for locking also overrides timing change restriction */
500
501   if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
502      return GFX_STATUS_ERROR;
503
504   /* SET GLOBAL FLAG */
505
506   if (pMode->flags & GFX_MODE_LOCK_TIMING)
507      gfx_timing_lock = 1;
508
509   /* DISABLE COMPRESSION */
510
511   gu1_disable_compression();
512
513   /* ALSO DISABLE VIDEO */
514   /* Use private "reset video" routine to do all that is needed. */
515   /* SC1200, for example, also disables the alpha blending regions. */
516
517   gfx_reset_video();
518
519   /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
520
521   unlock = READ_REG32(DC_UNLOCK);
522   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
523
524   /* READ THE CURRENT GX VALUES */
525
526   gcfg = READ_REG32(DC_GENERAL_CFG);
527   tcfg = READ_REG32(DC_TIMING_CFG);
528
529   /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */
530
531   tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN);
532   WRITE_REG32(DC_TIMING_CFG, tcfg);
533
534   /* DELAY: WAIT FOR PENDING MEMORY REQUESTS
535    * This delay is used to make sure that all pending requests to the
536    * memory controller have completed before disabling the FIFO load.
537    */
538
539   gfx_delay_milliseconds(1);
540
541   /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */
542
543   gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
544   WRITE_REG32(DC_GENERAL_CFG, gcfg);
545
546   /* CLEAR THE "DCLK_MUL" FIELD */
547
548   gcfg &= ~(unsigned long)(DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK);
549   gcfg &= ~(unsigned long)DC_GCFG_DCLK_MASK;
550   WRITE_REG32(DC_GENERAL_CFG, gcfg);
551
552   /* SET THE DOT CLOCK FREQUENCY */
553   /* Mask off the divide by two bit (bit 31) */
554
555   gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
556
557   /* DELAY: WAIT FOR THE PLL TO SETTLE */
558   /* This allows the dot clock frequency that was just set to settle. */
559
560   gfx_delay_milliseconds(1);
561
562   /* SET THE "DCLK_MUL" FIELD OF DC_GENERAL_CFG */
563   /* The GX hardware divides the dot clock, so 2x really means that the */
564   /* internal dot clock equals the external dot clock. */
565
566   if (pMode->frequency & 0x80000000)
567      gcfg |= 0x0040;
568   else
569      gcfg |= 0x0080;
570   WRITE_REG32(DC_GENERAL_CFG, gcfg);
571
572   /* DELAY: WAIT FOR THE ADL TO LOCK */
573   /* This allows the clock generatation within GX to settle.  This is */
574   /* needed since some of the register writes that follow require that */
575   /* clock to be present. */
576
577   /* We do a few to ensure we're synced */
578   gfx_delay_milliseconds(1);
579   gfx_delay_milliseconds(1);
580   gfx_delay_milliseconds(1);
581   gfx_delay_milliseconds(1);
582   gfx_delay_milliseconds(1);
583   gfx_delay_milliseconds(1);
584
585   /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
586
587   WRITE_REG32(DC_FB_ST_OFFSET, 0);
588   WRITE_REG32(DC_CB_ST_OFFSET, 0);
589   WRITE_REG32(DC_CURS_ST_OFFSET, 0);
590
591   /* SET LINE SIZE AND PITCH */
592   /* Flat panels use the current flat panel line size to    */
593   /* calculate the pitch, but load the true line size       */
594   /* for the mode into the "Frame Buffer Line Size" field   */
595   /* of DC_BUF_SIZE.                                        */
596
597   if (PanelEnable)
598      size = ModeWidth;
599   else
600      size = pMode->hactive;
601
602   if (bpp > 8)
603      size <<= 1;
604
605   /* ONLY PYRAMID SUPPORTS 4K LINE SIZE */
606
607   if (size <= 1024) {
608      pitch = 1024;
609
610      /* SPECIAL CASE  */
611      /* Graphics acceleration in 16-bit pixel line double modes */
612      /* requires a pitch of 2048.                               */
613
614      if ((pMode->flags & GFX_MODE_LINE_DOUBLE) && bpp > 8)
615	 pitch <<= 1;
616   } else {
617      if (gfx_cpu_version == GFX_CPU_PYRAMID)
618	 pitch = (size <= 2048) ? 2048 : 4096;
619      else
620	 pitch = 2048;
621   }
622   WRITE_REG32(DC_LINE_DELTA, pitch >> 2);
623
624   if (PanelEnable) {
625      size = pMode->hactive;
626      if (bpp > 8)
627	 size <<= 1;
628   }
629
630   /* SAVE PREVIOUSLY STORED VIDEO BUFFER SIZE */
631
632   vid_buffer_size = READ_REG32(DC_BUF_SIZE) & 0x3FFF0000;
633
634   /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */
635
636   WRITE_REG32(DC_BUF_SIZE, ((size >> 3) + 2) | vid_buffer_size);
637
638   /* ALWAYS ENABLE "PANEL" DATA FROM MEDIAGX */
639   /* That is really just the 18 BPP data bus to the companion chip */
640
641   ocfg = DC_OCFG_PCKE | DC_OCFG_PDEL | DC_OCFG_PDEH;
642
643   /* SET PIXEL FORMAT */
644
645   if (bpp == 8)
646      ocfg |= DC_OCFG_8BPP;
647   else if (bpp == 15)
648      ocfg |= DC_OCFG_555;
649
650   /* ENABLE TIMING GENERATOR, SYNCS, AND FP DATA */
651
652   tcfg = DC_TCFG_FPPE | DC_TCFG_HSYE | DC_TCFG_VSYE | DC_TCFG_BLKE |
653	 DC_TCFG_TGEN;
654
655   /* SET FIFO PRIORITY, DCLK MULTIPLIER, AND FIFO ENABLE */
656   /* Default 6/5 for FIFO, 2x for DCLK multiplier. */
657
658   gcfg = (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) |
659	 DC_GCFG_DFLE;
660
661   /* INCREASE FIFO PRIORITY FOR LARGE MODES */
662
663   if (pMode->hactive == 1280 && pMode->vactive == 1024) {
664      if ((bpp == 8) && (pMode->flags & GFX_MODE_85HZ))
665	 gcfg = (8l << DC_GCFG_DFHPEL_POS) | (7l << DC_GCFG_DFHPSL_POS) |
666	       DC_GCFG_DFLE;
667      if ((bpp > 8) && (pMode->flags & GFX_MODE_75HZ))
668	 gcfg = (7l << DC_GCFG_DFHPEL_POS) | (6l << DC_GCFG_DFHPSL_POS) |
669	       DC_GCFG_DFLE;
670      if ((bpp > 8) && (pMode->flags & GFX_MODE_85HZ))
671	 gcfg = (9l << DC_GCFG_DFHPEL_POS) | (8l << DC_GCFG_DFHPSL_POS) |
672	       DC_GCFG_DFLE;
673   }
674
675   /* SET DOT CLOCK MULTIPLIER */
676   /* Bit 31 of frequency indicates divide frequency by two */
677
678   if (pMode->frequency & 0x80000000)
679      gcfg |= (1l << DC_GCFG_DCLK_POS);
680   else
681      gcfg |= (2l << DC_GCFG_DCLK_POS);
682
683   /* DIVIDE VIDEO CLOCK */
684   /* CPU core frequencies above 266 MHz will divide the video */
685   /* clock by 4 to ensure that we are running below 150 MHz.  */
686
687   if (gfx_cpu_frequency > 266)
688      gcfg |= DC_GCFG_VCLK_DIV;
689
690   /* SET THE PIXEL AND LINE DOUBLE BITS IF NECESSARY */
691
692   hactive = pMode->hactive;
693   vactive = pMode->vactive;
694   gfx_line_double = 0;
695   gfx_pixel_double = 0;
696
697   if (pMode->flags & GFX_MODE_LINE_DOUBLE) {
698      gcfg |= DC_GCFG_LDBL;
699      hactive <<= 1;
700
701      /* SET GLOBAL FLAG */
702
703      gfx_line_double = 1;
704   }
705
706   if (pMode->flags & GFX_MODE_PIXEL_DOUBLE) {
707      tcfg |= DC_TCFG_PXDB;
708      vactive <<= 1;
709
710      /* SET GLOBAL FLAG */
711
712      gfx_pixel_double = 1;
713   }
714
715   /* COMBINE AND SET TIMING VALUES */
716
717   value = (unsigned long)(hactive - 1) |
718	 (((unsigned long)(pMode->htotal - 1)) << 16);
719   WRITE_REG32(DC_H_TIMING_1, value);
720   value = (unsigned long)(pMode->hblankstart - 1) |
721	 (((unsigned long)(pMode->hblankend - 1)) << 16);
722   WRITE_REG32(DC_H_TIMING_2, value);
723   value = (unsigned long)(pMode->hsyncstart - 1) |
724	 (((unsigned long)(pMode->hsyncend - 1)) << 16);
725   WRITE_REG32(DC_H_TIMING_3, value);
726   WRITE_REG32(DC_FP_H_TIMING, value);
727   value = (unsigned long)(vactive - 1) |
728	 (((unsigned long)(pMode->vtotal - 1)) << 16);
729   WRITE_REG32(DC_V_TIMING_1, value);
730   value = (unsigned long)(pMode->vblankstart - 1) |
731	 (((unsigned long)(pMode->vblankend - 1)) << 16);
732   WRITE_REG32(DC_V_TIMING_2, value);
733   value = (unsigned long)(pMode->vsyncstart - 1) |
734	 (((unsigned long)(pMode->vsyncend - 1)) << 16);
735   WRITE_REG32(DC_V_TIMING_3, value);
736   value = (unsigned long)(pMode->vsyncstart - 2) |
737	 (((unsigned long)(pMode->vsyncend - 2)) << 16);
738   WRITE_REG32(DC_FP_V_TIMING, value);
739
740   WRITE_REG32(DC_OUTPUT_CFG, ocfg);
741   WRITE_REG32(DC_TIMING_CFG, tcfg);
742   gfx_delay_milliseconds(1);		/* delay after TIMING_CFG */
743   WRITE_REG32(DC_GENERAL_CFG, gcfg);
744
745   /* ENABLE FLAT PANEL CENTERING */
746   /* For 640x480 modes displayed with the 9211 within a 800x600 */
747   /* flat panel display, turn on flat panel centering.          */
748
749   if (PanelEnable) {
750      if (ModeWidth < PanelWidth) {
751	 tcfg = READ_REG32(DC_TIMING_CFG);
752	 tcfg = tcfg | DC_TCFG_FCEN;
753	 WRITE_REG32(DC_TIMING_CFG, tcfg);
754	 gfx_delay_milliseconds(1);	/* delay after TIMING_CFG */
755      }
756   }
757
758   /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
759
760   gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
761			   ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
762
763   /* RESTORE VALUE OF DC_UNLOCK */
764
765   WRITE_REG32(DC_UNLOCK, unlock);
766
767   /* ALSO WRITE GP_BLIT_STATUS FOR PITCH AND 8/18 BPP */
768   /* Remember, only Pyramid supports 4K line pitch    */
769
770   value = 0;
771   if (bpp > 8)
772      value |= BC_16BPP;
773   if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048))
774      value |= BC_FB_WIDTH_4096;
775   else if (pitch > 1024)
776      value |= BC_FB_WIDTH_2048;
777   WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value);
778
779   return GFX_STATUS_OK;
780
781}					/* end gfx_set_specified_mode() */
782
783/*----------------------------------------------------------------------------
784 * GFX_IS_DISPLAY_MODE_SUPPORTED
785 *
786 * This routine sets the specified display mode.
787 *
788 * Returns the index of the mode if successful and mode returned, -1 if the mode
789 * could not be found.
790 *----------------------------------------------------------------------------
791 */
792#if GFX_DISPLAY_DYNAMIC
793int
794gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz)
795#else
796int
797gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
798#endif
799{
800   unsigned int mode = 0;
801   unsigned long hz_flag = 0, bpp_flag = 0;
802
803   /* SET FLAGS TO MATCH REFRESH RATE */
804
805   if (hz == 56)
806      hz_flag = GFX_MODE_56HZ;
807   else if (hz == 60)
808      hz_flag = GFX_MODE_60HZ;
809   else if (hz == 70)
810      hz_flag = GFX_MODE_70HZ;
811   else if (hz == 72)
812      hz_flag = GFX_MODE_72HZ;
813   else if (hz == 75)
814      hz_flag = GFX_MODE_75HZ;
815   else if (hz == 85)
816      hz_flag = GFX_MODE_85HZ;
817   else
818      return -1;
819
820   /* SET BPP FLAGS TO LIMIT MODE SELECTION */
821
822   if (bpp == 8)
823      bpp_flag = GFX_MODE_8BPP;
824   else if (bpp == 15)
825      bpp_flag = GFX_MODE_15BPP;
826   else if (bpp == 16)
827      bpp_flag = GFX_MODE_16BPP;
828   else
829      return -1;
830
831   /* ONLY PYRAMID SUPPORTS 4K PITCH */
832
833   if (gfx_cpu_version != GFX_CPU_PYRAMID && xres > 1024) {
834      if (bpp > 8)
835	 return (-1);			/* return with mode not found */
836   }
837
838   /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
839
840   for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) {
841      if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
842	  (DisplayParams[mode].vactive == (unsigned short)yres) &&
843	  (DisplayParams[mode].flags & hz_flag) &&
844	  (DisplayParams[mode].flags & bpp_flag)) {
845
846	 /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
847
848	 return (mode);
849      }
850   }
851   return (-1);
852}
853
854/*----------------------------------------------------------------------------
855 * GFX_SET_DISPLAY_MODE
856 *
857 * This routine sets the specified display mode.
858 *
859 * Returns 1 if successful, 0 if mode could not be set.
860 *----------------------------------------------------------------------------
861 */
862#if GFX_DISPLAY_DYNAMIC
863int
864gu1_set_display_mode(int xres, int yres, int bpp, int hz)
865#else
866int
867gfx_set_display_mode(int xres, int yres, int bpp, int hz)
868#endif
869{
870   int mode;
871
872   /* DISABLE FLAT PANEL */
873   /* Flat Panel settings are enabled by the function gfx_set_fixed_timings */
874   /* and disabled by gfx_set_display_mode.                                 */
875
876   PanelEnable = 0;
877
878   mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
879   if (mode >= 0) {
880      if (gu1_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK)
881	 return (1);
882   }
883   return (0);
884}
885
886/*----------------------------------------------------------------------------
887 * GFX_SET_DISPLAY_TIMINGS
888 *
889 * This routine sets the display controller mode using the specified timing
890 * values (as opposed to using the tables internal to Durango).
891 *
892 * Returns GFX_STATUS_OK on success, GFX_STATUS_ERROR otherwise.
893 *----------------------------------------------------------------------------
894 */
895#if GFX_DISPLAY_DYNAMIC
896int
897gu1_set_display_timings(unsigned short bpp, unsigned short flags,
898			unsigned short hactive, unsigned short hblankstart,
899			unsigned short hsyncstart, unsigned short hsyncend,
900			unsigned short hblankend, unsigned short htotal,
901			unsigned short vactive, unsigned short vblankstart,
902			unsigned short vsyncstart, unsigned short vsyncend,
903			unsigned short vblankend, unsigned short vtotal,
904			unsigned long frequency)
905#else
906int
907gfx_set_display_timings(unsigned short bpp, unsigned short flags,
908			unsigned short hactive, unsigned short hblankstart,
909			unsigned short hsyncstart, unsigned short hsyncend,
910			unsigned short hblankend, unsigned short htotal,
911			unsigned short vactive, unsigned short vblankstart,
912			unsigned short vsyncstart, unsigned short vsyncend,
913			unsigned short vblankend, unsigned short vtotal,
914			unsigned long frequency)
915#endif
916{
917   /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
918
919   gfx_display_mode.flags = 0;
920   if (flags & 1)
921      gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
922   if (flags & 2)
923      gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
924   if (flags & 0x1000)
925      gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
926   gfx_display_mode.hactive = hactive;
927   gfx_display_mode.hblankstart = hblankstart;
928   gfx_display_mode.hsyncstart = hsyncstart;
929   gfx_display_mode.hsyncend = hsyncend;
930   gfx_display_mode.hblankend = hblankend;
931   gfx_display_mode.htotal = htotal;
932   gfx_display_mode.vactive = vactive;
933   gfx_display_mode.vblankstart = vblankstart;
934   gfx_display_mode.vsyncstart = vsyncstart;
935   gfx_display_mode.vsyncend = vsyncend;
936   gfx_display_mode.vblankend = vblankend;
937   gfx_display_mode.vtotal = vtotal;
938   gfx_display_mode.frequency = frequency;
939
940   /* CALL ROUTINE TO SET MODE */
941
942   return (gu1_set_specified_mode(&gfx_display_mode, bpp));
943}
944
945/*----------------------------------------------------------------------------
946 * GFX_SET_VTOTAL
947 *
948 * This routine sets the display controller vertical total to
949 * "vtotal". As a side effect it also sets vertical blank end.
950 * It should be used when only this value needs to be changed,
951 * due to speed considerations.
952 *
953 * Note: it is the caller's responsibility to make sure that
954 * a legal vtotal is used, i.e. that "vtotal" is greater than or
955 * equal to vsync end.
956 *
957 * Always returns 0.
958 *----------------------------------------------------------------------------
959 */
960#if GFX_DISPLAY_DYNAMIC
961int
962gu1_set_vtotal(unsigned short vtotal)
963#else
964int
965gfx_set_vtotal(unsigned short vtotal)
966#endif
967{
968   unsigned long unlock, tcfg, timing1, timing2;
969
970   /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
971
972   unlock = READ_REG32(DC_UNLOCK);
973   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
974
975   /* READ THE CURRENT GX VALUES */
976
977   tcfg = READ_REG32(DC_TIMING_CFG);
978   timing1 = READ_REG32(DC_V_TIMING_1);
979   timing2 = READ_REG32(DC_V_TIMING_2);
980
981   /* DISABLE THE TIMING GENERATOR */
982
983   WRITE_REG32(DC_TIMING_CFG, tcfg & ~(unsigned long)DC_TCFG_TGEN);
984
985   /* WRITE NEW TIMING VALUES */
986
987   WRITE_REG32(DC_V_TIMING_1,
988	       (timing1 & 0xffff) | (unsigned long)(vtotal - 1) << 16);
989   WRITE_REG32(DC_V_TIMING_2,
990	       (timing2 & 0xffff) | (unsigned long)(vtotal - 1) << 16);
991
992   /* RESTORE GX VALUES */
993
994   WRITE_REG32(DC_TIMING_CFG, tcfg);
995   WRITE_REG32(DC_UNLOCK, unlock);
996
997   return (0);
998}
999
1000/*---------------------------------------------------------------------------
1001 * gfx_set_display_pitch
1002 *
1003 * This routine sets the pitch of the frame buffer to the specified value.
1004 *---------------------------------------------------------------------------
1005 */
1006#if GFX_DISPLAY_DYNAMIC
1007void
1008gu1_set_display_pitch(unsigned short pitch)
1009#else
1010void
1011gfx_set_display_pitch(unsigned short pitch)
1012#endif
1013{
1014   unsigned long value = 0;
1015   unsigned long lock = READ_REG32(DC_UNLOCK);
1016
1017   value = READ_REG32(DC_LINE_DELTA) & 0xFFFFF000;
1018   value |= (pitch >> 2);
1019   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1020   WRITE_REG32(DC_LINE_DELTA, value);
1021   WRITE_REG32(DC_UNLOCK, lock);
1022
1023   /* ALSO UPDATE PITCH IN GRAPHICS ENGINE */
1024   /* Pyramid alone supports 4K line pitch */
1025
1026   value = (unsigned long)READ_REG16(GP_BLIT_STATUS);
1027   value &= ~(BC_FB_WIDTH_2048 | BC_FB_WIDTH_4096);
1028
1029   if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048))
1030      value |= BC_FB_WIDTH_4096;
1031
1032   else if (pitch > 1024)
1033      value |= BC_FB_WIDTH_2048;
1034
1035   WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value);
1036   return;
1037}
1038
1039/*---------------------------------------------------------------------------
1040 * gfx_set_display_offset
1041 *
1042 * This routine sets the start address of the frame buffer.  It is
1043 * typically used to pan across a virtual desktop (frame buffer larger than
1044 * the displayed screen) or to flip the display between multiple buffers.
1045 *---------------------------------------------------------------------------
1046 */
1047#if GFX_DISPLAY_DYNAMIC
1048void
1049gu1_set_display_offset(unsigned long offset)
1050#else
1051void
1052gfx_set_display_offset(unsigned long offset)
1053#endif
1054{
1055   /* UPDATE FRAME BUFFER OFFSET */
1056
1057   unsigned long lock;
1058
1059   lock = READ_REG32(DC_UNLOCK);
1060   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1061
1062   /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
1063   /* Disable compression for non-zero start addresss values.            */
1064   /* Enable compression if offset is zero and comression is intended to */
1065   /* be enabled from a previous call to "gfx_set_compression_enable".   */
1066   /* Compression should be disabled BEFORE the offset is changed        */
1067   /* and enabled AFTER the offset is changed.                           */
1068
1069   if (offset == 0) {
1070      WRITE_REG32(DC_FB_ST_OFFSET, offset);
1071      if (gfx_compression_enabled) {
1072	 /* WAIT FOR THE OFFSET TO BE LATCHED */
1073	 gfx_wait_vertical_blank();
1074	 gu1_enable_compression();
1075      }
1076   } else {
1077      /* ONLY DISABLE COMPRESSION ONCE */
1078
1079      if (gfx_compression_active)
1080	 gu1_disable_compression();
1081
1082      WRITE_REG32(DC_FB_ST_OFFSET, offset);
1083   }
1084
1085   WRITE_REG32(DC_UNLOCK, lock);
1086}
1087
1088/*---------------------------------------------------------------------------
1089 * gfx_set_display_palette_entry
1090 *
1091 * This routine sets an palette entry in the display controller.
1092 * A 32-bit X:R:G:B value.
1093 *---------------------------------------------------------------------------
1094 */
1095#if GFX_DISPLAY_DYNAMIC
1096int
1097gu1_set_display_palette_entry(unsigned long index, unsigned long palette)
1098#else
1099int
1100gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
1101#endif
1102{
1103   unsigned long data;
1104
1105   if (index > 0xFF)
1106      return GFX_STATUS_BAD_PARAMETER;
1107
1108   WRITE_REG32(DC_PAL_ADDRESS, index);
1109   data = ((palette >> 2) & 0x0003F) |
1110	 ((palette >> 4) & 0x00FC0) | ((palette >> 6) & 0x3F000);
1111   WRITE_REG32(DC_PAL_DATA, data);
1112
1113   return (0);
1114}
1115
1116/*---------------------------------------------------------------------------
1117 * gfx_set_display_palette
1118 *
1119 * This routine sets the entire palette in the display controller.
1120 * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
1121 * Restriction:
1122 * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
1123 * when DCLK is active, i.e PLL is already powered up and genlock is not active.
1124 *---------------------------------------------------------------------------
1125 */
1126#if GFX_DISPLAY_DYNAMIC
1127int
1128gu1_set_display_palette(unsigned long *palette)
1129#else
1130int
1131gfx_set_display_palette(unsigned long *palette)
1132#endif
1133{
1134   unsigned long data, i;
1135
1136   WRITE_REG32(DC_PAL_ADDRESS, 0);
1137   if (palette) {
1138      for (i = 0; i < 256; i++) {
1139	 /* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */
1140
1141	 data = ((palette[i] >> 2) & 0x0003F) |
1142	       ((palette[i] >> 4) & 0x00FC0) | ((palette[i] >> 6) & 0x3F000);
1143	 WRITE_REG32(DC_PAL_DATA, data);
1144      }
1145   }
1146   return (0);
1147}
1148
1149/*---------------------------------------------------------------------------
1150 * gfx_set_cursor_enable
1151 *
1152 * This routine enables or disables the hardware cursor.
1153 *
1154 * WARNING: The cusrsor start offset must be set by setting the cursor
1155 * position before calling this routine to assure that memory reads do not
1156 * go past the end of graphics memory (this can hang GXm).
1157 *---------------------------------------------------------------------------
1158 */
1159#if GFX_DISPLAY_DYNAMIC
1160void
1161gu1_set_cursor_enable(int enable)
1162#else
1163void
1164gfx_set_cursor_enable(int enable)
1165#endif
1166{
1167   unsigned long unlock, gcfg;
1168
1169   /* SET OR CLEAR CURSOR ENABLE BIT */
1170
1171   unlock = READ_REG32(DC_UNLOCK);
1172   gcfg = READ_REG32(DC_GENERAL_CFG);
1173   if (enable)
1174      gcfg |= DC_GCFG_CURE;
1175   else
1176      gcfg &= ~(DC_GCFG_CURE);
1177
1178   /* WRITE NEW REGISTER VALUE */
1179
1180   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1181   WRITE_REG32(DC_GENERAL_CFG, gcfg);
1182   WRITE_REG32(DC_UNLOCK, unlock);
1183}
1184
1185/*---------------------------------------------------------------------------
1186 * gfx_set_cursor_colors
1187 *
1188 * This routine sets the colors of the hardware cursor.
1189 * Restriction:
1190 * Due to SC1200 Issue #748 (in Notes DB) this function should be called only
1191 * when DCLK is active, i.e PLL is already powered up.
1192 *---------------------------------------------------------------------------
1193 */
1194#if GFX_DISPLAY_DYNAMIC
1195void
1196gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
1197#else
1198void
1199gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
1200#endif
1201{
1202   unsigned long value;
1203
1204   /* If genlock is enabled DCLK might be disabled in vertical blank. */
1205   /* Due to SC1200 Issue #748 in Notes DB this would fail the cursor color settings */
1206   /* So Wait for vertical blank to end */
1207
1208#if GFX_VIDEO_SC1200
1209   if (gfx_test_timing_active())
1210      while ((gfx_get_vline()) > gfx_get_vactive()) ;
1211#endif
1212
1213   /* SET CURSOR COLORS */
1214
1215   WRITE_REG32(DC_PAL_ADDRESS, 0x100);
1216   value = ((bkcolor & 0x000000FC) >> 2) |
1217	 ((bkcolor & 0x0000FC00) >> (2 + 8 - 6)) |
1218	 ((bkcolor & 0x00FC0000) >> (2 + 16 - 12));
1219   WRITE_REG32(DC_PAL_DATA, value);
1220   value = ((fgcolor & 0x000000FC) >> 2) |
1221	 ((fgcolor & 0x0000FC00) >> (2 + 8 - 6)) |
1222	 ((fgcolor & 0x00FC0000) >> (2 + 16 - 12));
1223   WRITE_REG32(DC_PAL_DATA, value);
1224}
1225
1226/*---------------------------------------------------------------------------
1227 * gfx_set_cursor_position
1228 *
1229 * This routine sets the position of the hardware cusror.  The starting
1230 * offset of the cursor buffer must be specified so that the routine can
1231 * properly clip scanlines if the cursor is off the top of the screen.
1232 *---------------------------------------------------------------------------
1233 */
1234#if GFX_DISPLAY_DYNAMIC
1235void
1236gu1_set_cursor_position(unsigned long memoffset,
1237			unsigned short xpos, unsigned short ypos,
1238			unsigned short xhotspot, unsigned short yhotspot)
1239#else
1240void
1241gfx_set_cursor_position(unsigned long memoffset,
1242			unsigned short xpos, unsigned short ypos,
1243			unsigned short xhotspot, unsigned short yhotspot)
1244#endif
1245{
1246   unsigned long unlock;
1247
1248   short x, y;
1249   short xoffset = 0;
1250   short yoffset = 0;
1251
1252   /* SUPPORT CURSOR IN EMULATED VGA MODES */
1253   /* Timings are for twice the resolution */
1254
1255   if (gfx_pixel_double)
1256      xpos <<= 1;
1257   if (gfx_line_double)
1258      ypos <<= 1;
1259
1260   x = (short)xpos - (short)xhotspot;
1261   y = (short)ypos - (short)yhotspot;
1262   if (x < -31)
1263      return;
1264   if (y < -31)
1265      return;
1266   if (x < 0) {
1267      xoffset = -x;
1268      x = 0;
1269   }
1270   if (y < 0) {
1271      yoffset = -y;
1272      y = 0;
1273   }
1274   memoffset += (unsigned long)yoffset << 3;
1275
1276   if (PanelEnable) {
1277      if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
1278	 gfx_enable_panning(xpos, ypos);
1279	 x = x - (short)panelLeft;
1280	 y = y - (short)panelTop;
1281      }
1282   }
1283
1284   /* SET CURSOR POSITION */
1285
1286   unlock = READ_REG32(DC_UNLOCK);
1287   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1288   WRITE_REG32(DC_CURS_ST_OFFSET, memoffset);
1289   WRITE_REG32(DC_CURSOR_X, (unsigned long)x |
1290	       (((unsigned long)xoffset) << 11));
1291   WRITE_REG32(DC_CURSOR_Y, (unsigned long)y |
1292	       (((unsigned long)yoffset) << 11));
1293   WRITE_REG32(DC_UNLOCK, unlock);
1294}
1295
1296/*---------------------------------------------------------------------------
1297 * gfx_set_cursor_shape32
1298 *
1299 * This routine loads 32x32 cursor data into the specified location in
1300 * graphics memory.
1301 *---------------------------------------------------------------------------
1302 */
1303#if GFX_DISPLAY_DYNAMIC
1304void
1305gu1_set_cursor_shape32(unsigned long memoffset,
1306		       unsigned long *andmask, unsigned long *xormask)
1307#else
1308void
1309gfx_set_cursor_shape32(unsigned long memoffset,
1310		       unsigned long *andmask, unsigned long *xormask)
1311#endif
1312{
1313   int i;
1314   unsigned long value;
1315
1316   for (i = 0; i < 32; i++) {
1317      /* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */
1318
1319      value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16);
1320      WRITE_FB32(memoffset, value);
1321      memoffset += 4;
1322      value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF);
1323      WRITE_FB32(memoffset, value);
1324      memoffset += 4;
1325   }
1326}
1327
1328/*---------------------------------------------------------------------------
1329 * gu1_enable_compression
1330 *
1331 * This is a private routine to this module (not exposed in the Durango API).
1332 * It enables display compression.
1333 *---------------------------------------------------------------------------
1334 */
1335void
1336gu1_enable_compression(void)
1337{
1338   int i;
1339   unsigned long unlock, gcfg, offset;
1340
1341   /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
1342
1343   offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF;
1344   if (offset != 0)
1345      return;
1346
1347   /* DO NOT ENABLE IF WE ARE WITHIN AN EMULATED VGA MODE */
1348
1349   if (gfx_line_double || gfx_pixel_double)
1350      return;
1351
1352   /* SET GLOBAL INDICATOR */
1353
1354   gfx_compression_active = 1;
1355
1356   /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
1357   /* Software is required to do this before enabling compression. */
1358   /* Don't want controller to think that old lines are still valid. */
1359
1360   for (i = 0; i < 1024; i++) {
1361      WRITE_REG32(MC_DR_ADD, i);
1362      WRITE_REG32(MC_DR_ACC, 0);
1363   }
1364
1365   /* TURN ON COMPRESSION CONTROL BITS */
1366
1367   unlock = READ_REG32(DC_UNLOCK);
1368   gcfg = READ_REG32(DC_GENERAL_CFG);
1369   gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE;
1370   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1371   WRITE_REG32(DC_GENERAL_CFG, gcfg);
1372   WRITE_REG32(DC_UNLOCK, unlock);
1373}
1374
1375/*---------------------------------------------------------------------------
1376 * gu1_disable_compression
1377 *
1378 * This is a private routine to this module (not exposed in the Durango API).
1379 * It disables display compression.
1380 *---------------------------------------------------------------------------
1381 */
1382void
1383gu1_disable_compression(void)
1384{
1385   unsigned long unlock, gcfg;
1386
1387   /* SET GLOBAL INDICATOR */
1388
1389   gfx_compression_active = 0;
1390
1391   /* TURN OFF COMPRESSION CONTROL BITS */
1392
1393   unlock = READ_REG32(DC_UNLOCK);
1394   gcfg = READ_REG32(DC_GENERAL_CFG);
1395   gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE);
1396   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1397   WRITE_REG32(DC_GENERAL_CFG, gcfg);
1398   WRITE_REG32(DC_UNLOCK, unlock);
1399}
1400
1401/*---------------------------------------------------------------------------
1402 * gfx_set_compression_enable
1403 *
1404 * This routine enables or disables display compression.
1405 *---------------------------------------------------------------------------
1406 */
1407#if GFX_DISPLAY_DYNAMIC
1408int
1409gu1_set_compression_enable(int enable)
1410#else
1411int
1412gfx_set_compression_enable(int enable)
1413#endif
1414{
1415   /* SET GLOBAL VARIABLE FOR INTENDED STATE */
1416   /* Compression can only be enabled for non-zero start address values. */
1417   /* Keep state to enable compression on start address changes. */
1418
1419   gfx_compression_enabled = enable;
1420   if (enable)
1421      gu1_enable_compression();
1422   else
1423      gu1_disable_compression();
1424   return (0);
1425}
1426
1427/*---------------------------------------------------------------------------
1428 * gfx_set_compression_offset
1429 *
1430 * This routine sets the base offset for the compression buffer.
1431 *---------------------------------------------------------------------------
1432 */
1433#if GFX_DISPLAY_DYNAMIC
1434int
1435gu1_set_compression_offset(unsigned long offset)
1436#else
1437int
1438gfx_set_compression_offset(unsigned long offset)
1439#endif
1440{
1441   unsigned long lock;
1442
1443   /* MUST BE 16-BYTE ALIGNED FOR GXLV */
1444
1445   if (offset & 0x0F)
1446      return (1);
1447
1448   /* SET REGISTER VALUE */
1449
1450   lock = READ_REG32(DC_UNLOCK);
1451   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1452   WRITE_REG32(DC_CB_ST_OFFSET, offset);
1453   WRITE_REG32(DC_UNLOCK, lock);
1454   return (0);
1455}
1456
1457/*---------------------------------------------------------------------------
1458 * gfx_set_compression_pitch
1459 *
1460 * This routine sets the pitch, in bytes, of the compression buffer.
1461 *---------------------------------------------------------------------------
1462 */
1463#if GFX_DISPLAY_DYNAMIC
1464int
1465gu1_set_compression_pitch(unsigned short pitch)
1466#else
1467int
1468gfx_set_compression_pitch(unsigned short pitch)
1469#endif
1470{
1471   unsigned long lock, line_delta;
1472
1473   /* SET REGISTER VALUE */
1474
1475   lock = READ_REG32(DC_UNLOCK);
1476   line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF;
1477   line_delta |= ((unsigned long)pitch << 10l) & 0x007FF000;
1478   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1479   WRITE_REG32(DC_LINE_DELTA, line_delta);
1480   WRITE_REG32(DC_UNLOCK, lock);
1481   return (0);
1482}
1483
1484/*---------------------------------------------------------------------------
1485 * gfx_set_compression_size
1486 *
1487 * This routine sets the line size of the compression buffer, which is the
1488 * maximum number of bytes allowed to store a compressed line.
1489 *---------------------------------------------------------------------------
1490 */
1491#if GFX_DISPLAY_DYNAMIC
1492int
1493gu1_set_compression_size(unsigned short size)
1494#else
1495int
1496gfx_set_compression_size(unsigned short size)
1497#endif
1498{
1499   unsigned long lock, buf_size;
1500
1501   /* SUBTRACT 16 FROM SIZE                          */
1502   /* The display controller will actually write     */
1503   /* 2 extra QWords.  So, if we assume that "size"  */
1504   /* refers to the allocated size, we must subtract */
1505   /* 16 bytes.                                      */
1506
1507   size -= 16;
1508
1509   /* SET REGISTER VALUE */
1510
1511   lock = READ_REG32(DC_UNLOCK);
1512   buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF;
1513   buf_size |= (((size >> 2) + 1) & 0x7F) << 9;
1514   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1515   WRITE_REG32(DC_BUF_SIZE, buf_size);
1516   WRITE_REG32(DC_UNLOCK, lock);
1517   return (0);
1518}
1519
1520/*---------------------------------------------------------------------------
1521 * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
1522 *
1523 * This routine enables/disables video on GX.
1524 *---------------------------------------------------------------------------
1525 */
1526#if GFX_DISPLAY_DYNAMIC
1527void
1528gu1_set_display_video_enable(int enable)
1529#else
1530void
1531gfx_set_display_video_enable(int enable)
1532#endif
1533{
1534   unsigned long lock, gcfg, buf_size;
1535
1536   lock = READ_REG32(DC_UNLOCK);
1537   gcfg = READ_REG32(DC_GENERAL_CFG);
1538   buf_size = READ_REG32(DC_BUF_SIZE);
1539
1540   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1541
1542   vid_enabled = enable;
1543
1544   /* SET THE BUFFER SIZE TO A NON-ZERO VALUE ONLY WHEN */
1545   /* ENABLING VIDEO                                    */
1546
1547   if (enable) {
1548      gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY);
1549      WRITE_REG32(DC_GENERAL_CFG, gcfg);
1550
1551      WRITE_REG32(DC_BUF_SIZE, (buf_size & 0x0000FFFFl) | vid_buf_size);
1552   }
1553
1554   /* CLEAR THE VIDEO BUFFER SIZE WHEN DISABLING VIDEO  */
1555
1556   else {
1557      gcfg &= ~(DC_GCFG_VIDE);
1558      WRITE_REG32(DC_GENERAL_CFG, gcfg);
1559
1560      vid_buf_size = buf_size & 0xFFFF0000l;
1561      WRITE_REG32(DC_BUF_SIZE, buf_size & 0x0000FFFFl);
1562   }
1563
1564   WRITE_REG32(DC_UNLOCK, lock);
1565   return;
1566}
1567
1568/*---------------------------------------------------------------------------
1569 * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
1570 *
1571 * This routine is called by "gfx_set_video_size".  It abstracts the
1572 * version of the display controller from the video overlay routines.
1573 *---------------------------------------------------------------------------
1574 */
1575#if GFX_DISPLAY_DYNAMIC
1576void
1577gu1_set_display_video_size(unsigned short width, unsigned short height)
1578#else
1579void
1580gfx_set_display_video_size(unsigned short width, unsigned short height)
1581#endif
1582{
1583   unsigned long lock, size, value;
1584
1585   size = (unsigned long)(width << 1) * (unsigned long)height;
1586
1587   /* STORE THE VIDEO BUFFER SIZE AS A GLOBAL */
1588
1589   vid_buf_size = ((size + 63) >> 6) << 16;
1590
1591   /* DO NOT SET THE VIDEO SIZE IF VIDEO IS DISABLED */
1592
1593   if (!vid_enabled)
1594      return;
1595
1596   lock = READ_REG32(DC_UNLOCK);
1597   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1598   value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF;
1599   value |= vid_buf_size;
1600   WRITE_REG32(DC_BUF_SIZE, value);
1601   WRITE_REG32(DC_UNLOCK, lock);
1602}
1603
1604/*---------------------------------------------------------------------------
1605 * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
1606 *
1607 * This routine is called by "gfx_set_video_offset".  It abstracts the
1608 * version of the display controller from the video overlay routines.
1609 *---------------------------------------------------------------------------
1610 */
1611#if GFX_DISPLAY_DYNAMIC
1612void
1613gu1_set_display_video_offset(unsigned long offset)
1614#else
1615void
1616gfx_set_display_video_offset(unsigned long offset)
1617#endif
1618{
1619   unsigned long lock;
1620
1621   lock = READ_REG32(DC_UNLOCK);
1622   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1623   offset &= 0x003FFFFF;
1624   WRITE_REG32(DC_VID_ST_OFFSET, offset);
1625   WRITE_REG32(DC_UNLOCK, lock);
1626}
1627
1628/*---------------------------------------------------------------------------
1629 * gfx_set_display_priority_high
1630 *
1631 * This routine controls the x-bus round robin arbitration mechanism.
1632 * When enable is TRUE, graphics pipeline requests and non-critical display
1633 * controller requests are arbitrated at the same priority as processor
1634 * requests. When FALSE processor requests are arbitrated at a higher priority.
1635 *---------------------------------------------------------------------------
1636 */
1637#if GFX_DISPLAY_DYNAMIC
1638void
1639gu1_set_display_priority_high(int enable)
1640#else
1641void
1642gfx_set_display_priority_high(int enable)
1643#endif
1644{
1645   unsigned long lock, control;
1646
1647   lock = READ_REG32(DC_UNLOCK);
1648   control = READ_REG32(MC_MEM_CNTRL1);
1649   WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE);
1650   if (enable)
1651      control |= MC_XBUSARB;
1652   else
1653      control &= ~(MC_XBUSARB);
1654   WRITE_REG32(MC_MEM_CNTRL1, control);
1655   WRITE_REG32(DC_UNLOCK, lock);
1656   return;
1657}
1658
1659/*---------------------------------------------------------------------------
1660 * gfx_test_timing_active
1661 *---------------------------------------------------------------------------
1662 */
1663#if GFX_DISPLAY_DYNAMIC
1664int
1665gu1_test_timing_active(void)
1666#else
1667int
1668gfx_test_timing_active(void)
1669#endif
1670{
1671   if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN)
1672      return (1);
1673   else
1674      return (0);
1675}
1676
1677/*---------------------------------------------------------------------------
1678 * gfx_test_vertical_active
1679 *---------------------------------------------------------------------------
1680 */
1681#if GFX_DISPLAY_DYNAMIC
1682int
1683gu1_test_vertical_active(void)
1684#else
1685int
1686gfx_test_vertical_active(void)
1687#endif
1688{
1689   if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_VNA)
1690      return (0);
1691   else
1692      return (1);
1693}
1694
1695/*---------------------------------------------------------------------------
1696 * gfx_wait_vertical_blank
1697 *---------------------------------------------------------------------------
1698 */
1699#if GFX_DISPLAY_DYNAMIC
1700int
1701gu1_wait_vertical_blank(void)
1702#else
1703int
1704gfx_wait_vertical_blank(void)
1705#endif
1706{
1707   if (gfx_test_timing_active()) {
1708      while (!gfx_test_vertical_active()) ;
1709      while (gfx_test_vertical_active()) ;
1710   }
1711   return (0);
1712}
1713
1714/*---------------------------------------------------------------------------
1715 * gfx_enable_panning
1716 *
1717 * This routine  enables the panning when the Mode is bigger than the panel
1718 * size.
1719 *---------------------------------------------------------------------------
1720 */
1721#if GFX_DISPLAY_DYNAMIC
1722void
1723gu1_enable_panning(int x, int y)
1724#else
1725void
1726gfx_enable_panning(int x, int y)
1727#endif
1728{
1729   unsigned long modeBytesPerPixel;
1730   unsigned long modeBytesPerScanline = 0;
1731   unsigned long startAddress = 0;
1732
1733   modeBytesPerPixel = (gbpp + 7) / 8;
1734   modeBytesPerScanline =
1735	 (((ModeWidth + 1023) / 1024) * 1024) * modeBytesPerPixel;
1736
1737   /* TEST FOR NO-WORK */
1738
1739   if (x >= DeltaX && (unsigned short)x < (PanelWidth + DeltaX) &&
1740       y >= DeltaY && (unsigned short)y < (PanelHeight + DeltaY))
1741      return;
1742
1743   /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY       */
1744   /* Test the boundary conditions for each coordinate and update */
1745   /* all variables and the starting offset accordingly.          */
1746
1747   if (x < DeltaX)
1748      DeltaX = x;
1749
1750   else if ((unsigned short)x >= (DeltaX + PanelWidth))
1751      DeltaX = x - PanelWidth + 1;
1752
1753   if (y < DeltaY)
1754      DeltaY = y;
1755
1756   else if ((unsigned short)y >= (DeltaY + PanelHeight))
1757      DeltaY = y - PanelHeight + 1;
1758
1759   /* CALCULATE THE START OFFSET */
1760
1761   startAddress =
1762	 (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
1763
1764   gfx_set_display_offset(startAddress);
1765
1766   /* SET PANEL COORDINATES                    */
1767   /* Panel's x position must be DWORD aligned */
1768
1769   panelTop = DeltaY;
1770   panelLeft = DeltaX * modeBytesPerPixel;
1771
1772   if (panelLeft & 3)
1773      panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
1774
1775   panelLeft /= modeBytesPerPixel;
1776
1777}
1778
1779/*---------------------------------------------------------------------------
1780 * gfx_set_fixed_timings
1781 *---------------------------------------------------------------------------
1782 */
1783#if GFX_DISPLAY_DYNAMIC
1784int
1785gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1786		      unsigned short height, unsigned short bpp)
1787#else
1788int
1789gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1790		      unsigned short height, unsigned short bpp)
1791#endif
1792{
1793   unsigned int mode;
1794
1795   ModeWidth = width;
1796   ModeHeight = height;
1797   PanelWidth = (unsigned short)panelResX;
1798   PanelHeight = (unsigned short)panelResY;
1799   PanelEnable = 1;
1800
1801   /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
1802   for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
1803      if ((FixedParams[mode].xres == width) &&
1804	  (FixedParams[mode].yres == height) &&
1805	  (FixedParams[mode].panelresx == panelResX) &&
1806	  (FixedParams[mode].panelresy == panelResY)) {
1807
1808	 /* SET THE 92xx FOR THE SELECTED MODE */
1809	 FIXEDTIMINGS *fmode = &FixedParams[mode];
1810
1811	 gfx_set_display_timings(bpp, 3, fmode->hactive, fmode->hblankstart,
1812				 fmode->hsyncstart, fmode->hsyncend,
1813				 fmode->hblankend, fmode->htotal,
1814				 fmode->vactive, fmode->vblankstart,
1815				 fmode->vsyncstart, fmode->vsyncend,
1816				 fmode->vblankend, fmode->vtotal,
1817				 fmode->frequency);
1818
1819	 return (1);
1820      }					/* end if() */
1821   }					/* end for() */
1822
1823   return (-1);
1824}
1825
1826/*---------------------------------------------------------------------------
1827 * gfx_set_panel_present
1828 *---------------------------------------------------------------------------
1829 */
1830#if GFX_DISPLAY_DYNAMIC
1831int
1832gu1_set_panel_present(int panelResX, int panelResY, unsigned short width,
1833		      unsigned short height, unsigned short bpp)
1834#else
1835int
1836gfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
1837		      unsigned short height, unsigned short bpp)
1838#endif
1839{
1840   /* SET VALID BPP         */
1841   /* 16BPP is the default. */
1842
1843   if (bpp != 8 && bpp != 15 && bpp != 16)
1844      bpp = 16;
1845
1846   /* RECORD PANEL PARAMETERS */
1847   /* This routine does not touch any panel timings.  It is used when custom panel */
1848   /* settings are set up in advance by the BIOS or an application, but the        */
1849   /* application still requires access to other panel functionality provided by   */
1850   /* Durango (i.e. panning).                                                      */
1851
1852   ModeWidth = width;
1853   ModeHeight = height;
1854   PanelWidth = (unsigned short)panelResX;
1855   PanelHeight = (unsigned short)panelResY;
1856   PanelEnable = 1;
1857   gbpp = bpp;
1858
1859   /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
1860
1861   gfx_set_display_bpp(bpp);
1862
1863   return (GFX_STATUS_OK);
1864}
1865
1866/*-----------------------------------------------------------------------*
1867 * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED:                      *
1868 * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal  *
1869 * are used by the video overlay routines.                               *
1870 *                                                                       *
1871 * gfx_get_vline and gfx_vactive are used to prevent an issue for the    *
1872 * SC1200.                                                               *
1873 *                                                                       *
1874 * The others are part of the Durango API.                               *
1875 *-----------------------------------------------------------------------*/
1876
1877/*---------------------------------------------------------------------------
1878 * gfx_get_display_pitch
1879 *
1880 * This routine returns the current pitch of the frame buffer, in bytes.
1881 *---------------------------------------------------------------------------
1882 */
1883#if GFX_DISPLAY_DYNAMIC
1884unsigned short
1885gu1_get_display_pitch(void)
1886#else
1887unsigned short
1888gfx_get_display_pitch(void)
1889#endif
1890{
1891   unsigned long value;
1892
1893   if (gfx_cpu_version == GFX_CPU_PYRAMID) {	/* Pyramid update for 4KB line pitch */
1894      value = (READ_REG32(DC_LINE_DELTA) & 0x07FF) << 2;
1895   } else {
1896      value = (READ_REG32(DC_LINE_DELTA) & 0x03FF) << 2;
1897   }
1898
1899   return ((unsigned short)value);
1900}
1901
1902/*----------------------------------------------------------------------------
1903 * GFX_GET_DISPLAY_DETAILS
1904 *
1905 * This routine gets the specified display mode.
1906 *
1907 * Returns 1 if successful, 0 if mode could not be get.
1908 *----------------------------------------------------------------------------
1909 */
1910#if GFX_DISPLAY_DYNAMIC
1911int
1912gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
1913#else
1914int
1915gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
1916#endif
1917{
1918   if (mode < NUM_GX_DISPLAY_MODES) {
1919      if (DisplayParams[mode].flags & GFX_MODE_56HZ)
1920	 *hz = 56;
1921      else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
1922	 *hz = 60;
1923      else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
1924	 *hz = 70;
1925      else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
1926	 *hz = 72;
1927      else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
1928	 *hz = 75;
1929      else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
1930	 *hz = 85;
1931
1932      *xres = DisplayParams[mode].hactive;
1933      *yres = DisplayParams[mode].vactive;
1934
1935      return (1);
1936   }
1937   return (0);
1938}
1939
1940/*----------------------------------------------------------------------------
1941 * GFX_GET_DISPLAY_MODE_COUNT
1942 *
1943 * Returns number of modes supported.
1944 *----------------------------------------------------------------------------
1945 */
1946#if GFX_DISPLAY_DYNAMIC
1947int
1948gu1_get_display_mode_count(void)
1949#else
1950int
1951gfx_get_display_mode_count(void)
1952#endif
1953{
1954   return (NUM_GX_DISPLAY_MODES);
1955}
1956
1957/*----------------------------------------------------------------------------
1958 * gfx_get_frame_buffer_line_size
1959 *
1960 * Returns the current frame buffer line size, in bytes
1961 *----------------------------------------------------------------------------
1962 */
1963#if GFX_DISPLAY_DYNAMIC
1964unsigned long
1965gu1_get_frame_buffer_line_size(void)
1966#else
1967unsigned long
1968gfx_get_frame_buffer_line_size(void)
1969#endif
1970{
1971   return ((READ_REG32(DC_BUF_SIZE) & 0x1FF) << 3);
1972}
1973
1974/*----------------------------------------------------------------------------
1975 * gfx_mode_frequency_supported
1976 *
1977 * This routine examines if the requested mode with pixel frequency is supported.
1978 *
1979 * Returns >0 if successful , <0 if freq. could not be found and matched.
1980 *----------------------------------------------------------------------------
1981 */
1982#if GFX_DISPLAY_DYNAMIC
1983int
1984gu1_mode_frequency_supported(int xres, int yres, int bpp,
1985			     unsigned long frequency)
1986#else
1987int
1988gfx_mode_frequency_supported(int xres, int yres, int bpp,
1989			     unsigned long frequency)
1990#endif
1991{
1992   unsigned int index;
1993   unsigned long value;
1994   unsigned long bpp_flag = 0;
1995
1996   bpp_flag = GFX_MODE_8BPP;
1997   if (bpp > 8)
1998      bpp_flag = GFX_MODE_16BPP;
1999
2000   for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
2001      if ((DisplayParams[index].hactive == (unsigned short)xres) &&
2002	  (DisplayParams[index].vactive == (unsigned short)yres) &&
2003	  (DisplayParams[index].flags & bpp_flag) &&
2004	  (DisplayParams[index].frequency == frequency)) {
2005	 int hz = 0;
2006
2007	 value = DisplayParams[index].flags;
2008
2009	 if (value & GFX_MODE_60HZ)
2010	    hz = 60;
2011	 else if (value & GFX_MODE_70HZ)
2012	    hz = 70;
2013	 else if (value & GFX_MODE_72HZ)
2014	    hz = 72;
2015	 else if (value & GFX_MODE_75HZ)
2016	    hz = 75;
2017	 else if (value & GFX_MODE_85HZ)
2018	    hz = 85;
2019	 return (hz);
2020      }
2021   }
2022   return (-1);
2023}
2024
2025/*----------------------------------------------------------------------------
2026 * gfx_refreshrate_from_frequency
2027 *
2028 * This routine maps the frequency to close match refresh rate
2029 *
2030 * Returns .
2031 *----------------------------------------------------------------------------
2032 */
2033#if GFX_DISPLAY_DYNAMIC
2034int
2035gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
2036				   unsigned long frequency)
2037#else
2038int
2039gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
2040				   unsigned long frequency)
2041#endif
2042{
2043   unsigned int index, closematch = 0;
2044   unsigned long value;
2045   unsigned long bpp_flag = 0;
2046   long min, diff;
2047
2048   *hz = 60;
2049
2050   bpp_flag = GFX_MODE_8BPP;
2051   if (bpp > 8)
2052      bpp_flag = GFX_MODE_16BPP;
2053
2054   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
2055   /* Search the table for the closest frequency (16.16 format). */
2056
2057   min = 0x7fffffff;
2058   for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
2059      if ((DisplayParams[index].htotal == (unsigned short)xres) &&
2060	  (DisplayParams[index].vtotal == (unsigned short)yres) &&
2061	  (DisplayParams[index].flags & bpp_flag)) {
2062	 diff = (long)frequency - (long)DisplayParams[index].frequency;
2063	 if (diff < 0)
2064	    diff = -diff;
2065
2066	 if (diff < min) {
2067	    min = diff;
2068	    closematch = index;
2069	 }
2070      }
2071   }
2072
2073   value = DisplayParams[closematch].flags;
2074
2075   if (value & GFX_MODE_60HZ)
2076      *hz = 60;
2077   else if (value & GFX_MODE_70HZ)
2078      *hz = 70;
2079   else if (value & GFX_MODE_72HZ)
2080      *hz = 72;
2081   else if (value & GFX_MODE_75HZ)
2082      *hz = 75;
2083   else if (value & GFX_MODE_85HZ)
2084      *hz = 85;
2085
2086   return (1);
2087}
2088
2089/*----------------------------------------------------------------------------
2090 * gfx_refreshrate_from_mode
2091 *
2092 * This routine is identical to the gfx_get_refreshrate_from_frequency,
2093 * except that the active timing values are compared instead of the total
2094 * values.  Some modes (such as 70Hz and 72Hz) may be confused in this routine.
2095 *
2096 * Returns .
2097 *----------------------------------------------------------------------------
2098 */
2099#if GFX_DISPLAY_DYNAMIC
2100int
2101gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
2102			      unsigned long frequency)
2103#else
2104int
2105gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
2106			      unsigned long frequency)
2107#endif
2108{
2109   unsigned int index, closematch = 0;
2110   unsigned long value;
2111   unsigned long bpp_flag = 0;
2112   long min, diff;
2113
2114   *hz = 60;
2115
2116   bpp_flag = GFX_MODE_8BPP;
2117   if (bpp > 8)
2118      bpp_flag = GFX_MODE_16BPP;
2119
2120   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
2121   /* Search the table for the closest frequency (16.16 format). */
2122
2123   min = 0x7fffffff;
2124   for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
2125      if ((DisplayParams[index].hactive == (unsigned short)xres) &&
2126	  (DisplayParams[index].vactive == (unsigned short)yres) &&
2127	  (DisplayParams[index].flags & bpp_flag)) {
2128	 diff = (long)frequency - (long)DisplayParams[index].frequency;
2129	 if (diff < 0)
2130	    diff = -diff;
2131
2132	 if (diff < min) {
2133	    min = diff;
2134	    closematch = index;
2135	 }
2136      }
2137   }
2138
2139   value = DisplayParams[closematch].flags;
2140
2141   if (value & GFX_MODE_60HZ)
2142      *hz = 60;
2143   else if (value & GFX_MODE_70HZ)
2144      *hz = 70;
2145   else if (value & GFX_MODE_72HZ)
2146      *hz = 72;
2147   else if (value & GFX_MODE_75HZ)
2148      *hz = 75;
2149   else if (value & GFX_MODE_85HZ)
2150      *hz = 85;
2151
2152   return (1);
2153}
2154
2155/*----------------------------------------------------------------------------
2156 * gfx_get_frequency_from_refreshrate
2157 *
2158 * This routine maps the refresh rate to the closest matching PLL frequency.
2159 *----------------------------------------------------------------------------
2160 */
2161#if GFX_DISPLAY_DYNAMIC
2162int
2163gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
2164				   int *frequency)
2165#else
2166int
2167gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
2168				   int *frequency)
2169#endif
2170{
2171   int retval = -1;
2172   unsigned long hz_flag = 0;
2173   unsigned long index, bpp_flag = 0;
2174
2175   *frequency = 0;
2176
2177   if (hz == 60)
2178      hz_flag = GFX_MODE_60HZ;
2179   else if (hz == 70)
2180      hz_flag = GFX_MODE_70HZ;
2181   else if (hz == 72)
2182      hz_flag = GFX_MODE_72HZ;
2183   else if (hz == 75)
2184      hz_flag = GFX_MODE_75HZ;
2185   else if (hz == 85)
2186      hz_flag = GFX_MODE_85HZ;
2187
2188   bpp_flag = GFX_MODE_8BPP;
2189   if (bpp > 8)
2190      bpp_flag = GFX_MODE_16BPP;
2191
2192   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
2193
2194   for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) {
2195      if ((DisplayParams[index].hactive == (unsigned short)xres) &&
2196	  (DisplayParams[index].vactive == (unsigned short)yres) &&
2197	  (DisplayParams[index].flags & bpp_flag) &&
2198	  (DisplayParams[index].flags & hz_flag)) {
2199	 *frequency = DisplayParams[index].frequency;
2200	 retval = 1;
2201      }
2202   }
2203   return retval;
2204}
2205
2206/*---------------------------------------------------------------------------
2207 * gfx_get_max_supported_pixel_clock
2208 *
2209 * This routine returns the maximum recommended speed for the pixel clock.  The
2210 * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum
2211 * floating point pixel clock speed.
2212 *---------------------------------------------------------------------------
2213 */
2214#if GFX_DISPLAY_DYNAMIC
2215unsigned long
2216gu1_get_max_supported_pixel_clock(void)
2217#else
2218unsigned long
2219gfx_get_max_supported_pixel_clock(void)
2220#endif
2221{
2222   /* ALL CHIPS CAN HANDLE 1280X1024@85HZ - 157.5 MHz */
2223
2224   return 157500;
2225}
2226
2227/*----------------------------------------------------------------------------
2228 * gfx_get_display_mode
2229 *
2230 * This routine gets the specified display mode.
2231 *
2232 * Returns >0 if successful and mode returned, <0 if mode could not be found.
2233 *----------------------------------------------------------------------------
2234 */
2235#if GFX_DISPLAY_DYNAMIC
2236int
2237gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
2238#else
2239int
2240gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
2241#endif
2242{
2243   unsigned int mode = 0;
2244   unsigned long pll_freq = 0, bpp_flag = 0;
2245
2246   *xres = gfx_get_hactive();
2247   *yres = gfx_get_vactive();
2248   *bpp = gfx_get_display_bpp();
2249   pll_freq = gfx_get_clock_frequency();
2250
2251   /* SUPPORT EMULATED VGA MODES */
2252
2253   if (gfx_pixel_double)
2254      *xres >>= 1;
2255
2256   if (gfx_line_double)
2257      *yres >>= 1;
2258
2259   /* SET BPP FLAGS TO LIMIT MODE SELECTION */
2260
2261   bpp_flag = GFX_MODE_8BPP;
2262   if (*bpp > 8)
2263      bpp_flag = GFX_MODE_16BPP;
2264
2265   for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) {
2266      if ((DisplayParams[mode].hactive == (unsigned short)*xres) &&
2267	  (DisplayParams[mode].vactive == (unsigned short)*yres) &&
2268	  (DisplayParams[mode].frequency == pll_freq) &&
2269	  (DisplayParams[mode].flags & bpp_flag)) {
2270
2271	 pll_freq = DisplayParams[mode].flags;
2272
2273	 if (pll_freq & GFX_MODE_56HZ)
2274	    *hz = 56;
2275	 else if (pll_freq & GFX_MODE_60HZ)
2276	    *hz = 60;
2277	 else if (pll_freq & GFX_MODE_70HZ)
2278	    *hz = 70;
2279	 else if (pll_freq & GFX_MODE_72HZ)
2280	    *hz = 72;
2281	 else if (pll_freq & GFX_MODE_75HZ)
2282	    *hz = 75;
2283	 else if (pll_freq & GFX_MODE_85HZ)
2284	    *hz = 85;
2285
2286	 return (1);
2287      }
2288   }
2289   return (-1);
2290}
2291
2292/*---------------------------------------------------------------------------
2293 * gfx_get_hactive
2294 *---------------------------------------------------------------------------
2295 */
2296#if GFX_DISPLAY_DYNAMIC
2297unsigned short
2298gu1_get_hactive(void)
2299#else
2300unsigned short
2301gfx_get_hactive(void)
2302#endif
2303{
2304   return ((unsigned short)((READ_REG32(DC_H_TIMING_1) & 0x07F8) + 8));
2305}
2306
2307/*---------------------------------------------------------------------------
2308 * gfx_get_hsync_start
2309 *---------------------------------------------------------------------------
2310 */
2311#if GFX_DISPLAY_DYNAMIC
2312unsigned short
2313gu1_get_hsync_start(void)
2314#else
2315unsigned short
2316gfx_get_hsync_start(void)
2317#endif
2318{
2319   return ((unsigned short)((READ_REG32(DC_H_TIMING_3) & 0x07F8) + 8));
2320}
2321
2322/*---------------------------------------------------------------------------
2323 * gfx_get_hsync_end
2324 *---------------------------------------------------------------------------
2325 */
2326#if GFX_DISPLAY_DYNAMIC
2327unsigned short
2328gu1_get_hsync_end(void)
2329#else
2330unsigned short
2331gfx_get_hsync_end(void)
2332#endif
2333{
2334   return ((unsigned short)(((READ_REG32(DC_H_TIMING_3) >> 16) & 0x07F8) +
2335			    8));
2336}
2337
2338/*---------------------------------------------------------------------------
2339 * gfx_get_htotal
2340 *---------------------------------------------------------------------------
2341 */
2342#if GFX_DISPLAY_DYNAMIC
2343unsigned short
2344gu1_get_htotal(void)
2345#else
2346unsigned short
2347gfx_get_htotal(void)
2348#endif
2349{
2350   return ((unsigned short)(((READ_REG32(DC_H_TIMING_1) >> 16) & 0x07F8) +
2351			    8));
2352}
2353
2354/*---------------------------------------------------------------------------
2355 * gfx_get_vactive
2356 *---------------------------------------------------------------------------
2357 */
2358#if GFX_DISPLAY_DYNAMIC
2359unsigned short
2360gu1_get_vactive(void)
2361#else
2362unsigned short
2363gfx_get_vactive(void)
2364#endif
2365{
2366   return ((unsigned short)((READ_REG32(DC_V_TIMING_1) & 0x07FF) + 1));
2367}
2368
2369/*---------------------------------------------------------------------------
2370 * gfx_get_vsync_end
2371 *---------------------------------------------------------------------------
2372 */
2373#if GFX_DISPLAY_DYNAMIC
2374unsigned short
2375gu1_get_vsync_end(void)
2376#else
2377unsigned short
2378gfx_get_vsync_end(void)
2379#endif
2380{
2381   return ((unsigned short)(((READ_REG32(DC_V_TIMING_3) >> 16) & 0x07FF) +
2382			    1));
2383}
2384
2385/*---------------------------------------------------------------------------
2386 * gfx_get_vtotal
2387 *---------------------------------------------------------------------------
2388 */
2389#if GFX_DISPLAY_DYNAMIC
2390unsigned short
2391gu1_get_vtotal(void)
2392#else
2393unsigned short
2394gfx_get_vtotal(void)
2395#endif
2396{
2397   return ((unsigned short)(((READ_REG32(DC_V_TIMING_1) >> 16) & 0x07FF) +
2398			    1));
2399}
2400
2401/*-----------------------------------------------------------------------------
2402 * gfx_get_display_bpp
2403 *
2404 * This routine returns the current color depth of the active display.
2405 *-----------------------------------------------------------------------------
2406 */
2407#if GFX_DISPLAY_DYNAMIC
2408unsigned short
2409gu1_get_display_bpp(void)
2410#else
2411unsigned short
2412gfx_get_display_bpp(void)
2413#endif
2414{
2415   switch (READ_REG32(DC_OUTPUT_CFG) & 3) {
2416   case 0:
2417      return (16);
2418   case 2:
2419      return (15);
2420   }
2421   return (8);
2422}
2423
2424/*---------------------------------------------------------------------------
2425 * gfx_get_vline
2426 *---------------------------------------------------------------------------
2427 */
2428#if GFX_DISPLAY_DYNAMIC
2429unsigned short
2430gu1_get_vline(void)
2431#else
2432unsigned short
2433gfx_get_vline(void)
2434#endif
2435{
2436   unsigned short current_scan_line;
2437
2438   /* Read similar value twice to ensure that the value is not transitioning */
2439
2440   do
2441      current_scan_line = (unsigned short)READ_REG32(DC_V_LINE_CNT) & 0x07FF;
2442   while (current_scan_line !=
2443	  (unsigned short)(READ_REG32(DC_V_LINE_CNT) & 0x07FF));
2444
2445   return (current_scan_line);
2446}
2447
2448/*-----------------------------------------------------------------------------
2449 * gfx_get_display_offset
2450 *-----------------------------------------------------------------------------
2451 */
2452#if GFX_DISPLAY_DYNAMIC
2453unsigned long
2454gu1_get_display_offset(void)
2455#else
2456unsigned long
2457gfx_get_display_offset(void)
2458#endif
2459{
2460   return (READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF);
2461}
2462
2463/*-----------------------------------------------------------------------------
2464 * gfx_get_cursor_offset
2465 *-----------------------------------------------------------------------------
2466 */
2467#if GFX_DISPLAY_DYNAMIC
2468unsigned long
2469gu1_get_cursor_offset(void)
2470#else
2471unsigned long
2472gfx_get_cursor_offset(void)
2473#endif
2474{
2475   return (READ_REG32(DC_CURS_ST_OFFSET) & 0x003FFFFF);
2476}
2477
2478#if GFX_READ_ROUTINES
2479
2480/*************************************************************/
2481/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
2482/*************************************************************/
2483
2484/*---------------------------------------------------------------------------
2485 * gfx_get_hblank_start
2486 *---------------------------------------------------------------------------
2487 */
2488#if GFX_DISPLAY_DYNAMIC
2489unsigned short
2490gu1_get_hblank_start(void)
2491#else
2492unsigned short
2493gfx_get_hblank_start(void)
2494#endif
2495{
2496   return ((unsigned short)((READ_REG32(DC_H_TIMING_2) & 0x07F8) + 8));
2497}
2498
2499/*---------------------------------------------------------------------------
2500 * gfx_get_hblank_end
2501 *---------------------------------------------------------------------------
2502 */
2503#if GFX_DISPLAY_DYNAMIC
2504unsigned short
2505gu1_get_hblank_end(void)
2506#else
2507unsigned short
2508gfx_get_hblank_end(void)
2509#endif
2510{
2511   return ((unsigned short)(((READ_REG32(DC_H_TIMING_2) >> 16) & 0x07F8) +
2512			    8));
2513}
2514
2515/*---------------------------------------------------------------------------
2516 * gfx_get_vblank_start
2517 *---------------------------------------------------------------------------
2518 */
2519#if GFX_DISPLAY_DYNAMIC
2520unsigned short
2521gu1_get_vblank_start(void)
2522#else
2523unsigned short
2524gfx_get_vblank_start(void)
2525#endif
2526{
2527   return ((unsigned short)((READ_REG32(DC_V_TIMING_2) & 0x07FF) + 1));
2528}
2529
2530/*---------------------------------------------------------------------------
2531 * gfx_get_vsync_start
2532 *---------------------------------------------------------------------------
2533 */
2534#if GFX_DISPLAY_DYNAMIC
2535unsigned short
2536gu1_get_vsync_start(void)
2537#else
2538unsigned short
2539gfx_get_vsync_start(void)
2540#endif
2541{
2542   return ((unsigned short)((READ_REG32(DC_V_TIMING_3) & 0x07FF) + 1));
2543}
2544
2545/*---------------------------------------------------------------------------
2546 * gfx_get_vblank_end
2547 *---------------------------------------------------------------------------
2548 */
2549#if GFX_DISPLAY_DYNAMIC
2550unsigned short
2551gu1_get_vblank_end(void)
2552#else
2553unsigned short
2554gfx_get_vblank_end(void)
2555#endif
2556{
2557   return ((unsigned short)(((READ_REG32(DC_V_TIMING_2) >> 16) & 0x07FF) +
2558			    1));
2559}
2560
2561/*-----------------------------------------------------------------------------
2562 * gfx_get_display_palette_entry
2563 *-----------------------------------------------------------------------------
2564 */
2565#if GFX_DISPLAY_DYNAMIC
2566int
2567gu1_get_display_palette_entry(unsigned long index, unsigned long *palette)
2568#else
2569int
2570gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
2571#endif
2572{
2573   unsigned long data;
2574
2575   if (index > 0xFF)
2576      return GFX_STATUS_BAD_PARAMETER;
2577
2578   WRITE_REG32(DC_PAL_ADDRESS, index);
2579   data = READ_REG32(DC_PAL_DATA);
2580   data = ((data << 2) & 0x000000FC) |
2581	 ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
2582
2583   *palette = data;
2584
2585   return 0;
2586}
2587
2588/*-----------------------------------------------------------------------------
2589 * gfx_get_display_palette
2590 *-----------------------------------------------------------------------------
2591 */
2592#if GFX_DISPLAY_DYNAMIC
2593void
2594gu1_get_display_palette(unsigned long *palette)
2595#else
2596void
2597gfx_get_display_palette(unsigned long *palette)
2598#endif
2599{
2600   unsigned long i, data;
2601
2602   WRITE_REG32(DC_PAL_ADDRESS, 0);
2603   for (i = 0; i < 256; i++) {
2604      data = READ_REG32(DC_PAL_DATA);
2605      data = ((data << 2) & 0x000000FC) |
2606	    ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000);
2607      palette[i] = data;
2608   }
2609}
2610
2611/*-----------------------------------------------------------------------------
2612 * gfx_get_cursor_enable
2613 *-----------------------------------------------------------------------------
2614 */
2615#if GFX_DISPLAY_DYNAMIC
2616unsigned long
2617gu1_get_cursor_enable(void)
2618#else
2619unsigned long
2620gfx_get_cursor_enable(void)
2621#endif
2622{
2623   return (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_CURE);
2624}
2625
2626/*-----------------------------------------------------------------------------
2627 * gfx_get_cursor_position
2628 *-----------------------------------------------------------------------------
2629 */
2630#if GFX_DISPLAY_DYNAMIC
2631unsigned long
2632gu1_get_cursor_position(void)
2633#else
2634unsigned long
2635gfx_get_cursor_position(void)
2636#endif
2637{
2638   return ((READ_REG32(DC_CURSOR_X) & 0x07FF) |
2639	   ((READ_REG32(DC_CURSOR_Y) << 16) & 0x03FF0000));
2640}
2641
2642/*-----------------------------------------------------------------------------
2643 * gfx_get_cursor_clip
2644 *-----------------------------------------------------------------------------
2645 */
2646#if GFX_DISPLAY_DYNAMIC
2647unsigned long
2648gu1_get_cursor_clip(void)
2649#else
2650unsigned long
2651gfx_get_cursor_clip(void)
2652#endif
2653{
2654   return (((READ_REG32(DC_CURSOR_X) >> 11) & 0x01F) |
2655	   ((READ_REG32(DC_CURSOR_Y) << 5) & 0x1F0000));
2656}
2657
2658/*-----------------------------------------------------------------------------
2659 * gfx_get_cursor_color
2660 *-----------------------------------------------------------------------------
2661 */
2662#if GFX_DISPLAY_DYNAMIC
2663unsigned long
2664gu1_get_cursor_color(int color)
2665#else
2666unsigned long
2667gfx_get_cursor_color(int color)
2668#endif
2669{
2670   unsigned long data;
2671
2672   if (color) {
2673      WRITE_REG32(DC_PAL_ADDRESS, 0x101);
2674   } else {
2675      WRITE_REG32(DC_PAL_ADDRESS, 0x100);
2676   }
2677   data = READ_REG32(DC_PAL_DATA);
2678   data = ((data << 6) & 0x00FC0000) |
2679	 ((data << 4) & 0x0000FC00) | ((data << 2) & 0x000000FC);
2680   return (data);
2681}
2682
2683/*-----------------------------------------------------------------------------
2684 * gfx_get_compression_enable
2685 *-----------------------------------------------------------------------------
2686 */
2687#if GFX_DISPLAY_DYNAMIC
2688int
2689gu1_get_compression_enable(void)
2690#else
2691int
2692gfx_get_compression_enable(void)
2693#endif
2694{
2695   unsigned long gcfg;
2696
2697   gcfg = READ_REG32(DC_GENERAL_CFG);
2698   if (gcfg & DC_GCFG_CMPE)
2699      return (1);
2700   else
2701      return (0);
2702}
2703
2704/*-----------------------------------------------------------------------------
2705 * gfx_get_compression_offset
2706 *-----------------------------------------------------------------------------
2707 */
2708#if GFX_DISPLAY_DYNAMIC
2709unsigned long
2710gu1_get_compression_offset(void)
2711#else
2712unsigned long
2713gfx_get_compression_offset(void)
2714#endif
2715{
2716   unsigned long offset;
2717
2718   offset = READ_REG32(DC_CB_ST_OFFSET) & 0x003FFFFF;
2719   return (offset);
2720}
2721
2722/*-----------------------------------------------------------------------------
2723 * gfx_get_compression_pitch
2724 *-----------------------------------------------------------------------------
2725 */
2726#if GFX_DISPLAY_DYNAMIC
2727unsigned short
2728gu1_get_compression_pitch(void)
2729#else
2730unsigned short
2731gfx_get_compression_pitch(void)
2732#endif
2733{
2734   unsigned short pitch;
2735
2736   pitch = (unsigned short)(READ_REG32(DC_LINE_DELTA) >> 12) & 0x07FF;
2737   return (pitch << 2);
2738}
2739
2740/*-----------------------------------------------------------------------------
2741 * gfx_get_compression_size
2742 *-----------------------------------------------------------------------------
2743 */
2744#if GFX_DISPLAY_DYNAMIC
2745unsigned short
2746gu1_get_compression_size(void)
2747#else
2748unsigned short
2749gfx_get_compression_size(void)
2750#endif
2751{
2752   unsigned short size;
2753
2754   size = (unsigned short)((READ_REG32(DC_BUF_SIZE) >> 9) & 0x7F) - 1;
2755   return ((size << 2) + 16);
2756}
2757
2758/*-----------------------------------------------------------------------------
2759 * gfx_get_valid_bit
2760 *-----------------------------------------------------------------------------
2761 */
2762#if GFX_DISPLAY_DYNAMIC
2763int
2764gu1_get_valid_bit(int line)
2765#else
2766int
2767gfx_get_valid_bit(int line)
2768#endif
2769{
2770   int valid;
2771
2772   WRITE_REG32(MC_DR_ADD, line);
2773   valid = (int)READ_REG32(MC_DR_ACC) & 1;
2774   return (valid);
2775}
2776
2777/*---------------------------------------------------------------------------
2778 * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
2779 *
2780 * This routine is called by "gfx_get_video_offset".  It abstracts the
2781 * version of the display controller from the video overlay routines.
2782 *---------------------------------------------------------------------------
2783 */
2784#if GFX_DISPLAY_DYNAMIC
2785unsigned long
2786gu1_get_display_video_offset(void)
2787#else
2788unsigned long
2789gfx_get_display_video_offset(void)
2790#endif
2791{
2792   return (READ_REG32(DC_VID_ST_OFFSET) & 0x003FFFFF);
2793}
2794
2795/*---------------------------------------------------------------------------
2796 * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
2797 *
2798 * This routine is called by "gfx_get_video_size".  It abstracts the
2799 * version of the display controller from the video overlay routines.
2800 *---------------------------------------------------------------------------
2801 */
2802#if GFX_DISPLAY_DYNAMIC
2803unsigned long
2804gu1_get_display_video_size(void)
2805#else
2806unsigned long
2807gfx_get_display_video_size(void)
2808#endif
2809{
2810   /* RETURN TOTAL SIZE, IN BYTES */
2811
2812   return ((READ_REG32(DC_BUF_SIZE) >> 10) & 0x000FFFC0);
2813}
2814
2815/*-----------------------------------------------------------------------------
2816 * gfx_get_display_priority_high
2817 *-----------------------------------------------------------------------------
2818 */
2819#if GFX_DISPLAY_DYNAMIC
2820int
2821gu1_get_display_priority_high(void)
2822#else
2823int
2824gfx_get_display_priority_high(void)
2825#endif
2826{
2827   if (READ_REG32(MC_MEM_CNTRL1) & MC_XBUSARB)
2828      return (1);
2829   else
2830      return (0);
2831}
2832
2833#endif /* GFX_READ_ROUTINES */
2834
2835/* END OF FILE */
2836