1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu2.c,v 1.4 2003/02/06 17:46:02 alanh Exp $ */
2/*
3 * $Workfile: disp_gu2.c $
4 *
5 * This file contains routines for the second 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 gu2_enable_compression(void);	/* private routine definition */
132void gu2_disable_compression(void);	/* private routine definition */
133int gu2_set_display_bpp(unsigned short bpp);
134int gu2_is_display_mode_supported(int xres, int yres, int bpp, int hz);
135int gu2_set_display_mode(int xres, int yres, int bpp, int hz);
136int gu2_set_display_timings(unsigned short bpp, unsigned short flags,
137			    unsigned short hactive,
138			    unsigned short hblank_start,
139			    unsigned short hsync_start,
140			    unsigned short hsync_end,
141			    unsigned short hblank_end, unsigned short htotal,
142			    unsigned short vactive,
143			    unsigned short vblank_start,
144			    unsigned short vsync_start,
145			    unsigned short vsync_end,
146			    unsigned short vblank_end, unsigned short vtotal,
147			    unsigned long frequency);
148int gu2_set_vtotal(unsigned short vtotal);
149void gu2_set_display_pitch(unsigned short pitch);
150void gu2_set_display_offset(unsigned long offset);
151int gu2_set_display_palette_entry(unsigned long index, unsigned long palette);
152int gu2_set_display_palette(unsigned long *palette);
153void gu2_video_shutdown(void);
154void gu2_set_clock_frequency(unsigned long frequency);
155int gu2_set_crt_enable(int enable);
156void gu2_set_cursor_enable(int enable);
157void gu2_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor);
158void gu2_set_cursor_position(unsigned long memoffset,
159			     unsigned short xpos, unsigned short ypos,
160			     unsigned short xhotspot,
161			     unsigned short yhotspot);
162void gu2_set_cursor_shape32(unsigned long memoffset, unsigned long *andmask,
163			    unsigned long *xormask);
164void gu2_set_cursor_shape64(unsigned long memoffset, unsigned long *andmask,
165			    unsigned long *xormask);
166void gu2_set_icon_enable(int enable);
167void gu2_set_icon_colors(unsigned long color0, unsigned long color1,
168			 unsigned long color2);
169void gu2_set_icon_position(unsigned long memoffset, unsigned short xpos);
170void gu2_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
171			  unsigned long *xormask, unsigned int lines);
172
173int gu2_set_compression_enable(int enable);
174int gu2_set_compression_offset(unsigned long offset);
175int gu2_set_compression_pitch(unsigned short pitch);
176int gu2_set_compression_size(unsigned short size);
177void gu2_set_display_priority_high(int enable);
178int gu2_test_timing_active(void);
179int gu2_test_vertical_active(void);
180int gu2_wait_vertical_blank(void);
181void gu2_delay_milliseconds(unsigned long milliseconds);
182void gu2_delay_microseconds(unsigned long microseconds);
183void gu2_enable_panning(int x, int y);
184int gu2_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
185			  unsigned short height, unsigned short bpp);
186int gu2_set_panel_present(int panelResX, int panelResY, unsigned short width,
187			  unsigned short height, unsigned short bpp);
188void gu2_reset_timing_lock(void);
189
190int gu2_get_display_details(unsigned int mode, int *xres, int *yres, int *hz);
191unsigned short gu2_get_display_pitch(void);
192int gu2_get_vsa2_softvga_enable(void);
193int gu2_get_sync_polarities(void);
194unsigned long gu2_get_clock_frequency(void);
195unsigned long gu2_get_max_supported_pixel_clock(void);
196int gu2_mode_frequency_supported(int xres, int yres, int bpp,
197				 unsigned long frequency);
198int gu2_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
199				       unsigned long frequency);
200int gu2_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
201				  unsigned long frequency);
202int gu2_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
203				       int *frequency);
204int gu2_get_display_mode_count(void);
205int gu2_get_display_mode(int *xres, int *yres, int *bpp, int *hz);
206unsigned long gu2_get_frame_buffer_line_size(void);
207unsigned short gu2_get_hactive(void);
208unsigned short gu2_get_hblank_start(void);
209unsigned short gu2_get_hsync_start(void);
210unsigned short gu2_get_hsync_end(void);
211unsigned short gu2_get_hblank_end(void);
212unsigned short gu2_get_htotal(void);
213unsigned short gu2_get_vactive(void);
214unsigned short gu2_get_vline(void);
215unsigned short gu2_get_vblank_start(void);
216unsigned short gu2_get_vsync_start(void);
217unsigned short gu2_get_vsync_end(void);
218unsigned short gu2_get_vblank_end(void);
219unsigned short gu2_get_vtotal(void);
220unsigned short gu2_get_display_bpp(void);
221unsigned long gu2_get_display_offset(void);
222int gu2_get_display_palette_entry(unsigned long index,
223				  unsigned long *palette);
224void gu2_get_display_palette(unsigned long *palette);
225unsigned long gu2_get_cursor_enable(void);
226unsigned long gu2_get_cursor_offset(void);
227unsigned long gu2_get_cursor_position(void);
228unsigned long gu2_get_cursor_clip(void);
229unsigned long gu2_get_cursor_color(int color);
230unsigned long gu2_get_icon_enable(void);
231unsigned long gu2_get_icon_offset(void);
232unsigned long gu2_get_icon_position(void);
233unsigned long gu2_get_icon_color(int color);
234int gu2_get_compression_enable(void);
235unsigned long gu2_get_compression_offset(void);
236unsigned short gu2_get_compression_pitch(void);
237unsigned short gu2_get_compression_size(void);
238int gu2_get_display_priority_high(void);
239int gu2_get_valid_bit(int line);
240int gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp);
241void gu2_set_display_video_size(unsigned short width, unsigned short height);
242void gu2_set_display_video_offset(unsigned long offset);
243unsigned long gu2_get_display_video_offset(void);
244unsigned long gu2_get_display_video_size(void);
245void gu2_get_display_video_yuv_pitch(unsigned long *ypitch,
246				     unsigned long *uvpitch);
247int gu2_get_display_video_downscale_enable(void);
248void gu2_set_display_video_format(unsigned long format);
249void gu2_set_display_video_enable(int enable);
250void gu2_set_display_video_yuv_offsets(unsigned long yoffset,
251				       unsigned long uoffset,
252				       unsigned long voffset);
253void gu2_set_display_video_yuv_pitch(unsigned long ypitch,
254				     unsigned long uvpitch);
255void gu2_set_display_video_downscale(unsigned short srch,
256				     unsigned short dsth);
257void gu2_set_display_video_vertical_downscale_enable(int enable);
258void gu2_get_display_video_yuv_offsets(unsigned long *yoffset,
259				       unsigned long *uoffset,
260				       unsigned long *voffset);
261unsigned long gu2_get_display_video_downscale_delta(void);
262
263 /*-----------------------------------------------------------------------------
264 * WARNING!!!! INACCURATE DELAY MECHANISM
265 *
266 * In an effort to keep the code self contained and operating system
267 * independent, the delay loop just performs reads of a display controller
268 * register.  This time will vary for faster processors.  The delay can always
269 * be longer than intended, only effecting the time of the mode switch
270 * (obviously want it to still be under a second).  Problems with the hardware
271 * only arise if the delay is not long enough.
272 *-----------------------------------------------------------------------------
273 */
274#if GFX_DISPLAY_DYNAMIC
275void
276gu2_delay_milliseconds(unsigned long milliseconds)
277#else
278void
279gfx_delay_milliseconds(unsigned long milliseconds)
280#endif
281{
282   /* ASSUME 300 MHZ 20 CLOCKS PER READ */
283
284#	define RC_READS_PER_MILLISECOND 15000L
285
286   unsigned long loop;
287
288   loop = milliseconds * RC_READS_PER_MILLISECOND;
289   while (loop-- > 0) {
290      READ_REG32(MDC_UNLOCK);
291   }
292}
293
294#if GFX_DISPLAY_DYNAMIC
295void
296gu2_delay_microseconds(unsigned long microseconds)
297#else
298void
299gfx_delay_microseconds(unsigned long microseconds)
300#endif
301{
302   /* ASSUME 400 MHz, 2 CLOCKS PER INCREMENT */
303
304   unsigned long loop_count = microseconds * 15;
305
306   while (loop_count-- > 0) {
307      READ_REG32(MDC_UNLOCK);
308   }
309}
310
311/*-----------------------------------------------------------------------------
312 * GFX_SET_DISPLAY_BPP
313 *
314 * This routine programs the bpp in the display controller.
315 *-----------------------------------------------------------------------------
316 */
317#if GFX_DISPLAY_DYNAMIC
318int
319gu2_set_display_bpp(unsigned short bpp)
320#else
321int
322gfx_set_display_bpp(unsigned short bpp)
323#endif
324{
325   unsigned long dcfg, lock;
326
327   dcfg = READ_REG32(MDC_DISPLAY_CFG) & ~(MDC_DCFG_DISP_MODE_MASK |
328					  MDC_DCFG_16BPP_MODE_MASK);
329   lock = READ_REG32(MDC_UNLOCK);
330
331   switch (bpp) {
332   case 12:
333      dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_12BPP);
334      break;
335   case 15:
336      dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_15BPP);
337      break;
338   case 16:
339      dcfg |= (MDC_DCFG_DISP_MODE_16BPP | MDC_DCFG_16BPP);
340      break;
341   case 32:
342      dcfg |= (MDC_DCFG_DISP_MODE_24BPP);
343      break;
344   case 8:
345      dcfg |= (MDC_DCFG_DISP_MODE_8BPP);
346      break;
347   default:
348      return GFX_STATUS_BAD_PARAMETER;
349   }
350
351   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
352   WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
353   WRITE_REG32(MDC_UNLOCK, lock);
354
355   /* SET BPP IN GRAPHICS PIPELINE */
356
357   gfx_set_bpp(bpp);
358
359   return 0;
360}
361
362/*-----------------------------------------------------------------------------
363 * gu2_set_specified_mode (private routine)
364 * This routine uses the parameters in the specified display mode structure
365 * to program the display controller hardware.
366 *-----------------------------------------------------------------------------
367 */
368int
369gu2_set_specified_mode(DISPLAYMODE * pMode, int bpp)
370{
371   unsigned long unlock, value;
372   unsigned long gcfg, dcfg;
373   unsigned long size, pitch;
374   unsigned long vid_buf_size;
375   unsigned long bpp_mask, temp, dv_size;
376
377   /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
378   /* Flag used for locking also overrides timing change restriction */
379
380   if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
381      return GFX_STATUS_ERROR;
382
383   /* CLEAR PANNING OFFSETS */
384
385   DeltaX = 0;
386   DeltaY = 0;
387   panelLeft = 0;
388   panelTop = 0;
389
390   /* SET GLOBAL FLAG */
391
392   if (pMode->flags & GFX_MODE_LOCK_TIMING)
393      gfx_timing_lock = 1;
394
395   /* CHECK FOR VALID BPP                          */
396   /* As this function can be called directly from */
397   /* gfx_set_display_timings, we must correct any */
398   /* invalid bpp settings.                        */
399
400   switch (bpp) {
401   case 12:
402      bpp_mask = 0x00000900;
403      break;
404   case 15:
405      bpp_mask = 0x00000500;
406      break;
407   case 16:
408      bpp_mask = 0x00000100;
409      break;
410   case 32:
411      bpp_mask = 0x00000200;
412      break;
413   default:
414      bpp_mask = 0x00000000;
415      bpp = 8;
416      break;
417   }
418
419   gbpp = bpp;
420
421   /* DISABLE COMPRESSION */
422
423   gu2_disable_compression();
424
425   /* ALSO DISABLE VIDEO */
426   /* Use private "reset video" routine to do all that is needed. */
427   /* SC1200, for example, also disables the alpha blending regions. */
428
429   gfx_reset_video();
430
431   /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
432
433   unlock = READ_REG32(MDC_UNLOCK);
434   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
435
436   /* READ THE CURRENT REGISTER VALUES */
437
438   gcfg = READ_REG32(MDC_GENERAL_CFG);
439   dcfg = READ_REG32(MDC_DISPLAY_CFG);
440
441   /* BLANK THE DISPLAY IN THE DISPLAY FILTER */
442
443   gfx_set_crt_enable(0);
444
445   /* DISABLE THE TIMING GENERATOR */
446
447   dcfg &= ~(unsigned long)MDC_DCFG_TGEN;
448   WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
449
450   /* DELAY: WAIT FOR PENDING MEMORY REQUESTS                            */
451   /* This delay is used to make sure that all pending requests to the   */
452   /* memory controller have completed before disabling the FIFO load.   */
453
454   gfx_delay_milliseconds(5);
455
456   /* DISABLE DISPLAY FIFO LOAD */
457
458   gcfg &= ~(unsigned long)MDC_GCFG_DFLE;
459   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
460
461   /* PRESERVE VIDEO INFORMATION */
462
463   gcfg &= (unsigned long)(MDC_GCFG_YUVM | MDC_GCFG_VDSE);
464   dcfg = 0;
465
466   /* SET THE DOT CLOCK FREQUENCY             */
467   /* Mask off the divide by two bit (bit 31) */
468
469   gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
470
471   /* DELAY: WAIT FOR THE PLL TO SETTLE */
472   /* This allows the dot clock frequency that was just set to settle. */
473
474   gfx_delay_milliseconds(10);
475
476   /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
477
478   WRITE_REG32(MDC_FB_ST_OFFSET, 0);
479   WRITE_REG32(MDC_CB_ST_OFFSET, 0);
480   WRITE_REG32(MDC_CURS_ST_OFFSET, 0);
481   WRITE_REG32(MDC_ICON_ST_OFFSET, 0);
482
483   /* SET LINE SIZE AND PITCH */
484   /* 1. Flat Panels must use the mode width and not  */
485   /*    the timing width to set the pitch.           */
486   /* 2. Mode sets will use a pitch that is aligned   */
487   /*    on a 1K boundary to preserve legacy.  The    */
488   /*    pitch can be overridden by a subsequent call */
489   /*    to gfx_set_display_pitch.                    */
490
491   if (PanelEnable)
492      size = ModeWidth;
493   else
494      size = pMode->hactive;
495
496   if (bpp > 8)
497      size <<= 1;
498   if (bpp > 16)
499      size <<= 1;
500
501   pitch = 1024;
502   dv_size = MDC_DV_LINE_SIZE_1024;
503
504   if (size > 1024) {
505      pitch = 2048;
506      dv_size = MDC_DV_LINE_SIZE_2048;
507   }
508   if (size > 2048) {
509      pitch = 4096;
510      dv_size = MDC_DV_LINE_SIZE_4096;
511   }
512   if (size > 4096) {
513      pitch = 8192;
514      dv_size = MDC_DV_LINE_SIZE_8192;
515   }
516   WRITE_REG32(MDC_GFX_PITCH, pitch >> 3);
517
518   /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */
519
520   temp = READ_REG32(MDC_DV_CTL);
521   WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size);
522
523   if (PanelEnable) {
524      size = pMode->hactive;
525      if (bpp > 8)
526	 size <<= 1;
527      if (bpp > 16)
528	 size <<= 1;
529   }
530
531   /* SAVE PREVIOUSLY STORED VIDEO LINE SIZE */
532
533   vid_buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF000000;
534
535   /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */
536
537   WRITE_REG32(MDC_LINE_SIZE, ((size >> 3) + 2) | vid_buf_size);
538
539   /* ALWAYS ENABLE VIDEO AND GRAPHICS DATA            */
540   /* These bits are relics from a previous design and */
541   /* should always be enabled.                        */
542
543   dcfg |= (unsigned long)(MDC_DCFG_VDEN | MDC_DCFG_GDEN);
544
545   /* SET PIXEL FORMAT */
546
547   dcfg |= bpp_mask;
548
549   /* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
550   /* AND VERT. INT. SELECT                                      */
551
552   dcfg |=
553	 (unsigned long)(MDC_DCFG_TGEN | MDC_DCFG_TRUP | MDC_DCFG_PALB |
554			 MDC_DCFG_VISL);
555
556   /* DISABLE ADDRESS MASKS */
557
558   dcfg |= MDC_DCFG_A20M;
559   dcfg |= MDC_DCFG_A18M;
560
561   /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE     */
562   /* Set the priorities higher for high resolution modes. */
563
564   if (pMode->hactive > 1024 || bpp == 32)
565      gcfg |= 0x000A901;
566   else
567      gcfg |= 0x0006501;
568
569   /* ENABLE FLAT PANEL CENTERING                          */
570   /* For panel modes having a resolution smaller than the */
571   /* panel resolution, turn on data centering.            */
572
573   if (PanelEnable && ModeWidth < PanelWidth)
574      dcfg |= MDC_DCFG_DCEN;
575
576   /* COMBINE AND SET TIMING VALUES */
577
578   value = (unsigned long)(pMode->hactive - 1) |
579	 (((unsigned long)(pMode->htotal - 1)) << 16);
580   WRITE_REG32(MDC_H_ACTIVE_TIMING, value);
581   value = (unsigned long)(pMode->hblankstart - 1) |
582	 (((unsigned long)(pMode->hblankend - 1)) << 16);
583   WRITE_REG32(MDC_H_BLANK_TIMING, value);
584   value = (unsigned long)(pMode->hsyncstart - 1) |
585	 (((unsigned long)(pMode->hsyncend - 1)) << 16);
586   WRITE_REG32(MDC_H_SYNC_TIMING, value);
587   value = (unsigned long)(pMode->vactive - 1) |
588	 (((unsigned long)(pMode->vtotal - 1)) << 16);
589   WRITE_REG32(MDC_V_ACTIVE_TIMING, value);
590   value = (unsigned long)(pMode->vblankstart - 1) |
591	 (((unsigned long)(pMode->vblankend - 1)) << 16);
592   WRITE_REG32(MDC_V_BLANK_TIMING, value);
593   value = (unsigned long)(pMode->vsyncstart - 1) |
594	 (((unsigned long)(pMode->vsyncend - 1)) << 16);
595   WRITE_REG32(MDC_V_SYNC_TIMING, value);
596
597   WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
598   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
599
600   /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
601
602   gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
603			   ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
604
605   /* RESTORE VALUE OF MDC_UNLOCK */
606
607   WRITE_REG32(MDC_UNLOCK, unlock);
608
609   /* RESET THE PITCH VALUES IN THE GP */
610
611   gfx_reset_pitch((unsigned short)pitch);
612
613   gfx_set_bpp((unsigned short)bpp);
614
615   return GFX_STATUS_OK;
616}
617
618 /*----------------------------------------------------------------------------
619 * GFX_IS_DISPLAY_MODE_SUPPORTED
620 *
621 * This routine sets the specified display mode.
622 *
623 * Returns 1 if successful, 0 if mode could not be set.
624 *----------------------------------------------------------------------------
625 */
626#if GFX_DISPLAY_DYNAMIC
627int
628gu2_is_display_mode_supported(int xres, int yres, int bpp, int hz)
629#else
630int
631gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
632#endif
633{
634   unsigned int mode;
635   unsigned long hz_flag = 0, bpp_flag = 0;
636
637   /* SET FLAGS TO MATCH REFRESH RATE */
638
639   if (hz == 56)
640      hz_flag = GFX_MODE_56HZ;
641   if (hz == 60)
642      hz_flag = GFX_MODE_60HZ;
643   if (hz == 70)
644      hz_flag = GFX_MODE_70HZ;
645   if (hz == 72)
646      hz_flag = GFX_MODE_72HZ;
647   if (hz == 75)
648      hz_flag = GFX_MODE_75HZ;
649   if (hz == 85)
650      hz_flag = GFX_MODE_85HZ;
651
652   /* SET BPP FLAGS TO LIMIT MODE SELECTION */
653
654   switch (bpp) {
655   case 8:
656      bpp_flag = GFX_MODE_8BPP;
657      break;
658   case 12:
659      bpp_flag = GFX_MODE_12BPP;
660      break;
661   case 15:
662      bpp_flag = GFX_MODE_15BPP;
663      break;
664   case 16:
665      bpp_flag = GFX_MODE_16BPP;
666      break;
667   case 32:
668      bpp_flag = GFX_MODE_24BPP;
669      break;
670   default:
671      return (-1);
672   }
673
674   /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
675
676   for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
677      if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
678	  (DisplayParams[mode].vactive == (unsigned short)yres) &&
679	  (DisplayParams[mode].flags & hz_flag) &&
680	  (DisplayParams[mode].flags & bpp_flag)) {
681
682	 /* REDCLOUD DOES NOT SUPPORT EMULATED VGA MODES */
683
684	 if ((DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) ||
685	     (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE))
686	    continue;
687
688	 /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
689
690	 return (mode);
691      }
692   }
693   return (-1);
694}
695
696/*----------------------------------------------------------------------------
697 * gfx_set_display_mode
698 *
699 * This routine sets the specified display mode.
700 *
701 * Returns 1 if successful, 0 if mode could not be set.
702 *----------------------------------------------------------------------------
703 */
704#if GFX_DISPLAY_DYNAMIC
705int
706gu2_set_display_mode(int xres, int yres, int bpp, int hz)
707#else
708int
709gfx_set_display_mode(int xres, int yres, int bpp, int hz)
710#endif
711{
712   int mode;
713
714   /* DISABLE FLAT PANEL */
715   /* Flat Panel settings are enabled by the function gfx_set_fixed_timings */
716   /* and disabled by gfx_set_display_mode.                                 */
717
718   PanelEnable = 0;
719
720   mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
721   if (mode >= 0) {
722      if (gu2_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK)
723	 return (1);
724   }
725   return (0);
726}
727
728/*----------------------------------------------------------------------------
729 * GFX_SET_DISPLAY_TIMINGS
730 *
731 * This routine sets the display controller mode using the specified timing
732 * values (as opposed to using the tables internal to Durango).
733 *
734 * Returns GFX_STATUS_OK ON SUCCESS, GFX_STATUS_ERROR otherwise.
735 *----------------------------------------------------------------------------
736 */
737#if GFX_DISPLAY_DYNAMIC
738int
739gu2_set_display_timings(unsigned short bpp, unsigned short flags,
740			unsigned short hactive, unsigned short hblankstart,
741			unsigned short hsyncstart, unsigned short hsyncend,
742			unsigned short hblankend, unsigned short htotal,
743			unsigned short vactive, unsigned short vblankstart,
744			unsigned short vsyncstart, unsigned short vsyncend,
745			unsigned short vblankend, unsigned short vtotal,
746			unsigned long frequency)
747#else
748int
749gfx_set_display_timings(unsigned short bpp, unsigned short flags,
750			unsigned short hactive, unsigned short hblankstart,
751			unsigned short hsyncstart, unsigned short hsyncend,
752			unsigned short hblankend, unsigned short htotal,
753			unsigned short vactive, unsigned short vblankstart,
754			unsigned short vsyncstart, unsigned short vsyncend,
755			unsigned short vblankend, unsigned short vtotal,
756			unsigned long frequency)
757#endif
758{
759   /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
760
761   gfx_display_mode.flags = 0;
762   if (flags & 1)
763      gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
764   if (flags & 2)
765      gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
766   if (flags & 0x1000)
767      gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
768   gfx_display_mode.hactive = hactive;
769   gfx_display_mode.hblankstart = hblankstart;
770   gfx_display_mode.hsyncstart = hsyncstart;
771   gfx_display_mode.hsyncend = hsyncend;
772   gfx_display_mode.hblankend = hblankend;
773   gfx_display_mode.htotal = htotal;
774   gfx_display_mode.vactive = vactive;
775   gfx_display_mode.vblankstart = vblankstart;
776   gfx_display_mode.vsyncstart = vsyncstart;
777   gfx_display_mode.vsyncend = vsyncend;
778   gfx_display_mode.vblankend = vblankend;
779   gfx_display_mode.vtotal = vtotal;
780   gfx_display_mode.frequency = frequency;
781
782   /* CALL ROUTINE TO SET MODE */
783
784   return (gu2_set_specified_mode(&gfx_display_mode, bpp));
785}
786
787/*----------------------------------------------------------------------------
788 * GFX_SET_VTOTAL
789 *
790 * This routine sets the display controller vertical total to
791 * "vtotal". As a side effect it also sets vertical blank end.
792 * It should be used when only this value needs to be changed,
793 * due to speed considerations.
794 *
795 * Note: it is the caller's responsibility to make sure that
796 * a legal vtotal is used, i.e. that "vtotal" is greater than or
797 * equal to vsync end.
798 *
799 * Always returns 0.
800 *----------------------------------------------------------------------------
801 */
802#if GFX_DISPLAY_DYNAMIC
803int
804gu2_set_vtotal(unsigned short vtotal)
805#else
806int
807gfx_set_vtotal(unsigned short vtotal)
808#endif
809{
810   unsigned long unlock, dcfg, vactive, vblank;
811
812   /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
813
814   unlock = READ_REG32(MDC_UNLOCK);
815   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
816
817   /* READ THE CURRENT RC VALUES */
818
819   dcfg = READ_REG32(MDC_DISPLAY_CFG);
820   vactive = READ_REG32(MDC_V_ACTIVE_TIMING);
821   vblank = READ_REG32(MDC_V_BLANK_TIMING);
822
823   /* DISABLE TIMING REGISTER UPDATES */
824
825   WRITE_REG32(MDC_DISPLAY_CFG, dcfg & ~(unsigned long)MDC_DCFG_TRUP);
826
827   /* WRITE NEW TIMING VALUES */
828
829   WRITE_REG32(MDC_V_ACTIVE_TIMING,
830	       (vactive & MDC_VAT_VA_MASK) | (unsigned long)(vtotal -
831							     1) << 16);
832   WRITE_REG32(MDC_V_BLANK_TIMING,
833	       (vblank & MDC_VBT_VBS_MASK) | (unsigned long)(vtotal -
834							     1) << 16);
835
836   /* RESTORE OLD RC VALUES */
837
838   WRITE_REG32(MDC_DISPLAY_CFG, dcfg);
839   WRITE_REG32(MDC_UNLOCK, unlock);
840
841   return (0);
842}
843
844/*---------------------------------------------------------------------------
845 * gfx_set_display_pitch
846 *
847 * This routine sets the pitch of the frame buffer to the specified value.
848 *---------------------------------------------------------------------------
849 */
850#if GFX_DISPLAY_DYNAMIC
851void
852gu2_set_display_pitch(unsigned short pitch)
853#else
854void
855gfx_set_display_pitch(unsigned short pitch)
856#endif
857{
858   unsigned long value = 0;
859   unsigned long lock = READ_REG32(MDC_UNLOCK);
860
861   value = READ_REG32(MDC_GFX_PITCH) & 0xFFFF0000;
862   value |= (pitch >> 3);
863   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
864   WRITE_REG32(MDC_GFX_PITCH, value);
865
866   /* SET RENDERING PITCHES TO MATCH */
867
868   gfx_reset_pitch(pitch);
869
870   /* SET THE FRAME DIRTY MODE                  */
871   /* Non-standard pitches, i.e. pitches that   */
872   /* are not 1K, 2K or 4K must mark the entire */
873   /* frame as dirty when writing to the frame  */
874   /* buffer.                                   */
875
876   value = READ_REG32(MDC_GENERAL_CFG);
877
878   if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
879      value &= ~(unsigned long)(MDC_GCFG_FDTY);
880   else
881      value |= (unsigned long)(MDC_GCFG_FDTY);
882
883   WRITE_REG32(MDC_GENERAL_CFG, value);
884   WRITE_REG32(MDC_UNLOCK, lock);
885}
886
887/*---------------------------------------------------------------------------
888 * gfx_set_display_offset
889 *
890 * This routine sets the start address of the frame buffer.  It is
891 * typically used to pan across a virtual desktop (frame buffer larger than
892 * the displayed screen) or to flip the display between multiple buffers.
893 *---------------------------------------------------------------------------
894 */
895#if GFX_DISPLAY_DYNAMIC
896void
897gu2_set_display_offset(unsigned long offset)
898#else
899void
900gfx_set_display_offset(unsigned long offset)
901#endif
902{
903   /* UPDATE FRAME BUFFER OFFSET */
904   unsigned long lock;
905
906   lock = READ_REG32(MDC_UNLOCK);
907   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
908
909   /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
910   /* Disable compression for non-zero start addresss values.            */
911   /* Enable compression if offset is zero and comression is intended to */
912   /* be enabled from a previous call to "gfx_set_compression_enable".   */
913   /* Compression should be disabled BEFORE the offset is changed        */
914   /* and enabled AFTER the offset is changed.                           */
915
916   if (offset == 0) {
917      WRITE_REG32(MDC_FB_ST_OFFSET, offset);
918      if (gfx_compression_enabled) {
919	 /* WAIT FOR THE OFFSET TO BE LATCHED */
920	 gfx_wait_vertical_blank();
921	 gu2_enable_compression();
922      }
923   } else {
924      /* ONLY DISABLE COMPRESSION ONCE */
925
926      if (gfx_compression_active)
927	 gu2_disable_compression();
928
929      WRITE_REG32(MDC_FB_ST_OFFSET, offset);
930   }
931
932   WRITE_REG32(MDC_UNLOCK, lock);
933}
934
935/*---------------------------------------------------------------------------
936 * gfx_set_display_palette_entry
937 *
938 * This routine sets an palette entry in the display controller.
939 * A 32-bit X:R:G:B value.
940 *---------------------------------------------------------------------------
941 */
942#if GFX_DISPLAY_DYNAMIC
943int
944gu2_set_display_palette_entry(unsigned long index, unsigned long palette)
945#else
946int
947gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
948#endif
949{
950   if (index > 0xFF)
951      return GFX_STATUS_BAD_PARAMETER;
952
953   WRITE_REG32(MDC_PAL_ADDRESS, index);
954   WRITE_REG32(MDC_PAL_DATA, palette);
955
956   return (0);
957}
958
959/*---------------------------------------------------------------------------
960 * gfx_set_display_palette
961 *
962 * This routine sets the entire palette in the display controller.
963 * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
964 *---------------------------------------------------------------------------
965 */
966#if GFX_DISPLAY_DYNAMIC
967int
968gu2_set_display_palette(unsigned long *palette)
969#else
970int
971gfx_set_display_palette(unsigned long *palette)
972#endif
973{
974   unsigned long i;
975
976   WRITE_REG32(MDC_PAL_ADDRESS, 0);
977
978   if (palette) {
979      for (i = 0; i < 256; i++) {
980	 WRITE_REG32(MDC_PAL_DATA, palette[i]);
981      }
982   }
983   return (0);
984}
985
986/*---------------------------------------------------------------------------
987 * gfx_set_cursor_enable
988 *
989 * This routine enables or disables the hardware cursor.
990 *
991 * WARNING: The cursor start offset must be set by setting the cursor
992 * position before calling this routine to assure that memory reads do not
993 * go past the end of graphics memory (this can hang GXm).
994 *---------------------------------------------------------------------------
995 */
996#if GFX_DISPLAY_DYNAMIC
997void
998gu2_set_cursor_enable(int enable)
999#else
1000void
1001gfx_set_cursor_enable(int enable)
1002#endif
1003{
1004   unsigned long unlock, gcfg;
1005
1006   /* SET OR CLEAR CURSOR ENABLE BIT */
1007
1008   unlock = READ_REG32(MDC_UNLOCK);
1009   gcfg = READ_REG32(MDC_GENERAL_CFG);
1010   if (enable)
1011      gcfg |= MDC_GCFG_CURE;
1012   else
1013      gcfg &= ~(MDC_GCFG_CURE);
1014
1015   /* WRITE NEW REGISTER VALUE */
1016
1017   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1018   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1019   WRITE_REG32(MDC_UNLOCK, unlock);
1020}
1021
1022/*---------------------------------------------------------------------------
1023 * gfx_set_cursor_colors
1024 *
1025 * This routine sets the colors of the hardware cursor.
1026 *---------------------------------------------------------------------------
1027 */
1028#if GFX_DISPLAY_DYNAMIC
1029void
1030gu2_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
1031#else
1032void
1033gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
1034#endif
1035{
1036   /* SET CURSOR COLORS */
1037
1038   WRITE_REG32(MDC_PAL_ADDRESS, 0x100);
1039   WRITE_REG32(MDC_PAL_DATA, bkcolor);
1040   WRITE_REG32(MDC_PAL_DATA, fgcolor);
1041}
1042
1043/*---------------------------------------------------------------------------
1044 * gfx_set_cursor_position
1045 *
1046 * This routine sets the position of the hardware cusror.  The starting
1047 * offset of the cursor buffer must be specified so that the routine can
1048 * properly clip scanlines if the cursor is off the top of the screen.
1049 *---------------------------------------------------------------------------
1050 */
1051#if GFX_DISPLAY_DYNAMIC
1052void
1053gu2_set_cursor_position(unsigned long memoffset,
1054			unsigned short xpos, unsigned short ypos,
1055			unsigned short xhotspot, unsigned short yhotspot)
1056#else
1057void
1058gfx_set_cursor_position(unsigned long memoffset,
1059			unsigned short xpos, unsigned short ypos,
1060			unsigned short xhotspot, unsigned short yhotspot)
1061#endif
1062{
1063   unsigned long unlock;
1064
1065   short x = (short)xpos - (short)xhotspot;
1066   short y = (short)ypos - (short)yhotspot;
1067   short xoffset = 0;
1068   short yoffset = 0;
1069
1070   if (x < -63)
1071      return;
1072   if (y < -63)
1073      return;
1074
1075   if (PanelEnable) {
1076      if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) {
1077	 gfx_enable_panning(xpos, ypos);
1078	 x = x - (unsigned short)panelLeft;
1079	 y = y - (unsigned short)panelTop;
1080      }
1081   }
1082
1083   /* ADJUST OFFSETS */
1084   /* Cursor movement and panning work as follows:  The cursor position   */
1085   /* refers to where the hotspot of the cursor is located.  However, for */
1086   /* non-zero hotspots, the cursor buffer actually begins before the     */
1087   /* specified position.                                                 */
1088
1089   if (x < 0) {
1090      xoffset = -x;
1091      x = 0;
1092   }
1093   if (y < 0) {
1094      yoffset = -y;
1095      y = 0;
1096   }
1097   memoffset += (unsigned long)yoffset << 4;
1098
1099   /* SET CURSOR POSITION */
1100
1101   unlock = READ_REG32(MDC_UNLOCK);
1102   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1103   WRITE_REG32(MDC_CURS_ST_OFFSET, memoffset);
1104   WRITE_REG32(MDC_CURSOR_X, (unsigned long)x |
1105	       (((unsigned long)xoffset) << 11));
1106   WRITE_REG32(MDC_CURSOR_Y, (unsigned long)y |
1107	       (((unsigned long)yoffset) << 11));
1108   WRITE_REG32(MDC_UNLOCK, unlock);
1109}
1110
1111/*---------------------------------------------------------------------------
1112 * gfx_set_cursor_shape32
1113 *
1114 * This routine loads 32x32 cursor data into the cursor buffer in graphics memory.
1115 * As the Redcloud cursor is actually 64x64, we must pad the outside of the
1116 * cursor data with transparent pixels.
1117 *---------------------------------------------------------------------------
1118 */
1119#if GFX_DISPLAY_DYNAMIC
1120void
1121gu2_set_cursor_shape32(unsigned long memoffset,
1122		       unsigned long *andmask, unsigned long *xormask)
1123#else
1124void
1125gfx_set_cursor_shape32(unsigned long memoffset,
1126		       unsigned long *andmask, unsigned long *xormask)
1127#endif
1128{
1129   int i;
1130
1131   for (i = 0; i < 32; i++) {
1132      /* EVEN QWORDS CONTAIN THE AND MASK */
1133
1134      WRITE_FB32(memoffset, 0xFFFFFFFF);
1135      WRITE_FB32(memoffset + 4, andmask[i]);
1136
1137      /* ODD QWORDS CONTAIN THE XOR MASK  */
1138
1139      WRITE_FB32(memoffset + 8, 0x00000000);
1140      WRITE_FB32(memoffset + 12, xormask[i]);
1141
1142      memoffset += 16;
1143   }
1144
1145   /* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
1146
1147   for (i = 0; i < 32; i++) {
1148      WRITE_FB32(memoffset, 0xFFFFFFFF);
1149      WRITE_FB32(memoffset + 4, 0xFFFFFFFF);
1150      WRITE_FB32(memoffset + 8, 0x00000000);
1151      WRITE_FB32(memoffset + 12, 0x00000000);
1152
1153      memoffset += 16;
1154   }
1155}
1156
1157/*---------------------------------------------------------------------------
1158 * gfx_set_cursor_shape64
1159 *
1160 * This routine loads 64x64 cursor data into the cursor buffer in graphics memory.
1161 *---------------------------------------------------------------------------
1162 */
1163#if GFX_DISPLAY_DYNAMIC
1164void
1165gu2_set_cursor_shape64(unsigned long memoffset,
1166		       unsigned long *andmask, unsigned long *xormask)
1167#else
1168void
1169gfx_set_cursor_shape64(unsigned long memoffset,
1170		       unsigned long *andmask, unsigned long *xormask)
1171#endif
1172{
1173   int i;
1174
1175   for (i = 0; i < 128; i += 2) {
1176      /* EVEN QWORDS CONTAIN THE AND MASK */
1177      /* We invert the dwords to prevent the calling            */
1178      /* application from having to think in terms of Qwords.   */
1179      /* The hardware data order is actually 63:0, or 31:0 of   */
1180      /* the second dword followed by 31:0 of the first dword.  */
1181
1182      WRITE_FB32(memoffset, andmask[i + 1]);
1183      WRITE_FB32(memoffset + 4, andmask[i]);
1184
1185      /* ODD QWORDS CONTAIN THE XOR MASK  */
1186
1187      WRITE_FB32(memoffset + 8, xormask[i + 1]);
1188      WRITE_FB32(memoffset + 12, xormask[i]);
1189
1190      memoffset += 16;
1191   }
1192}
1193
1194/*---------------------------------------------------------------------------
1195 * gfx_set_icon_enable
1196 *
1197 * This routine enables or disables the hardware icon.  The icon position
1198 * and colors should be programmed prior to calling this routine for the
1199 * first time.
1200 *---------------------------------------------------------------------------
1201 */
1202#if GFX_DISPLAY_DYNAMIC
1203void
1204gu2_set_icon_enable(int enable)
1205#else
1206void
1207gfx_set_icon_enable(int enable)
1208#endif
1209{
1210   unsigned long unlock, gcfg;
1211
1212   /* SET OR CLEAR ICON ENABLE BIT */
1213
1214   unlock = READ_REG32(MDC_UNLOCK);
1215   gcfg = READ_REG32(MDC_GENERAL_CFG);
1216   if (enable)
1217      gcfg |= MDC_GCFG_ICNE;
1218   else
1219      gcfg &= ~(MDC_GCFG_ICNE);
1220
1221   /* WRITE NEW REGISTER VALUE */
1222
1223   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1224   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1225   WRITE_REG32(MDC_UNLOCK, unlock);
1226}
1227
1228/*---------------------------------------------------------------------------
1229 * gfx_set_icon_colors
1230 *
1231 * This routine sets the three icon colors.
1232 *---------------------------------------------------------------------------
1233 */
1234#if GFX_DISPLAY_DYNAMIC
1235void
1236gu2_set_icon_colors(unsigned long color0, unsigned long color1,
1237		    unsigned long color2)
1238#else
1239void
1240gfx_set_icon_colors(unsigned long color0, unsigned long color1,
1241		    unsigned long color2)
1242#endif
1243{
1244   /* ICON COLORS LOCATED AT PALETTE INDEXES 102-104h */
1245
1246   WRITE_REG32(MDC_PAL_ADDRESS, 0x102);
1247
1248   WRITE_REG32(MDC_PAL_DATA, color0);
1249   WRITE_REG32(MDC_PAL_DATA, color1);
1250   WRITE_REG32(MDC_PAL_DATA, color2);
1251}
1252
1253/*---------------------------------------------------------------------------
1254 * gfx_set_icon_position
1255 *
1256 * This routine sets the starting X coordinate for the hardware icon and the
1257 * memory offset for the icon buffer.
1258 *---------------------------------------------------------------------------
1259 */
1260#if GFX_DISPLAY_DYNAMIC
1261void
1262gu2_set_icon_position(unsigned long memoffset, unsigned short xpos)
1263#else
1264void
1265gfx_set_icon_position(unsigned long memoffset, unsigned short xpos)
1266#endif
1267{
1268   unsigned long lock = READ_REG32(MDC_UNLOCK);
1269
1270   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1271
1272   /* PROGRAM THE MEMORY OFFSET */
1273
1274   WRITE_REG32(MDC_ICON_ST_OFFSET, memoffset & 0x0FFFFFFF);
1275
1276   /* PROGRAM THE XCOORDINATE */
1277
1278   WRITE_REG32(MDC_ICON_X, (unsigned long)(xpos & 0x07FF));
1279
1280   WRITE_REG32(MDC_UNLOCK, lock);
1281}
1282
1283/*---------------------------------------------------------------------------
1284 * gfx_set_icon_shape64
1285 *
1286 * This routine initializes the icon buffer according to the current mode.
1287 *---------------------------------------------------------------------------
1288 */
1289#if GFX_DISPLAY_DYNAMIC
1290void
1291gu2_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
1292		     unsigned long *xormask, unsigned int lines)
1293#else
1294void
1295gfx_set_icon_shape64(unsigned long memoffset, unsigned long *andmask,
1296		     unsigned long *xormask, unsigned int lines)
1297#endif
1298{
1299   unsigned short i, height;
1300
1301   height = lines << 1;
1302
1303   for (i = 0; i < height; i += 2) {
1304      /* EVEN QWORDS CONTAIN THE AND MASK     */
1305      /* Swap dwords to hide qword constraint */
1306
1307      WRITE_FB32(memoffset, andmask[i + 1]);
1308      WRITE_FB32(memoffset + 4, andmask[i]);
1309
1310      /* ODD QWORDS CONTAIN THE XOR MASK */
1311
1312      WRITE_FB32(memoffset + 8, xormask[i + 1]);
1313      WRITE_FB32(memoffset + 12, xormask[i]);
1314
1315      memoffset += 16;
1316   }
1317}
1318
1319/*---------------------------------------------------------------------------
1320 * gu2_enable_compression
1321 *
1322 * This is a private routine to this module (not exposed in the Durango API).
1323 * It enables display compression.
1324 *---------------------------------------------------------------------------
1325 */
1326void
1327gu2_enable_compression(void)
1328{
1329   unsigned long unlock, gcfg, temp;
1330
1331   /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
1332
1333   if (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF)
1334      return;
1335
1336   /* SET GLOBAL INDICATOR */
1337
1338   gfx_compression_active = 1;
1339
1340   /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
1341   /* Software is required to do this before enabling compression.   */
1342   /* Don't want controller to think that old lines are still valid. */
1343   /* Writing a 1 to bit 0 of the DV Control register will force the */
1344   /* hardware to clear all the valid bits.                          */
1345
1346   temp = READ_REG32(MDC_DV_CTL);
1347   WRITE_REG32(MDC_DV_CTL, temp | 0x00000001);
1348
1349   /* TURN ON COMPRESSION CONTROL BITS */
1350
1351   unlock = READ_REG32(MDC_UNLOCK);
1352   gcfg = READ_REG32(MDC_GENERAL_CFG);
1353   gcfg |= MDC_GCFG_CMPE | MDC_GCFG_DECE;
1354   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1355   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1356   WRITE_REG32(MDC_UNLOCK, unlock);
1357}
1358
1359/*---------------------------------------------------------------------------
1360 * gu2_disable_compression
1361 *
1362 * This is a private routine to this module (not exposed in the Durango API).
1363 * It disables display compression.
1364 *---------------------------------------------------------------------------
1365 */
1366void
1367gu2_disable_compression(void)
1368{
1369   unsigned long unlock, gcfg;
1370
1371   /* SET GLOBAL INDICATOR */
1372
1373   gfx_compression_active = 0;
1374
1375   /* TURN OFF COMPRESSION CONTROL BITS */
1376
1377   unlock = READ_REG32(MDC_UNLOCK);
1378   gcfg = READ_REG32(MDC_GENERAL_CFG);
1379   gcfg &= ~(MDC_GCFG_CMPE | MDC_GCFG_DECE);
1380   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1381   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1382   WRITE_REG32(MDC_UNLOCK, unlock);
1383}
1384
1385/*---------------------------------------------------------------------------
1386 * gfx_set_compression_enable
1387 *
1388 * This routine enables or disables display compression.
1389 *---------------------------------------------------------------------------
1390 */
1391#if GFX_DISPLAY_DYNAMIC
1392int
1393gu2_set_compression_enable(int enable)
1394#else
1395int
1396gfx_set_compression_enable(int enable)
1397#endif
1398{
1399   /* SET GLOBAL VARIABLE FOR INDENDED STATE */
1400   /* Compression can only be enabled for non-zero start address values. */
1401   /* Keep state to enable compression on start address changes. */
1402
1403   gfx_compression_enabled = enable;
1404   if (enable)
1405      gu2_enable_compression();
1406   else
1407      gu2_disable_compression();
1408   return (0);
1409}
1410
1411/*---------------------------------------------------------------------------
1412 * gfx_set_compression_offset
1413 *
1414 * This routine sets the base offset for the compression buffer.
1415 *---------------------------------------------------------------------------
1416 */
1417#if GFX_DISPLAY_DYNAMIC
1418int
1419gu2_set_compression_offset(unsigned long offset)
1420#else
1421int
1422gfx_set_compression_offset(unsigned long offset)
1423#endif
1424{
1425   unsigned long lock;
1426
1427   /* MUST BE 16-BYTE ALIGNED FOR REDCLOUD */
1428
1429   if (offset & 0x0F)
1430      return (1);
1431
1432   /* SET REGISTER VALUE */
1433
1434   lock = READ_REG32(MDC_UNLOCK);
1435   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1436   WRITE_REG32(MDC_CB_ST_OFFSET, offset & 0x0FFFFFFF);
1437   WRITE_REG32(MDC_UNLOCK, lock);
1438
1439   return (0);
1440}
1441
1442/*---------------------------------------------------------------------------
1443 * gfx_set_compression_pitch
1444 *
1445 * This routine sets the pitch, in bytes, of the compression buffer.
1446 *---------------------------------------------------------------------------
1447 */
1448#if GFX_DISPLAY_DYNAMIC
1449int
1450gu2_set_compression_pitch(unsigned short pitch)
1451#else
1452int
1453gfx_set_compression_pitch(unsigned short pitch)
1454#endif
1455{
1456   unsigned long lock, line_delta;
1457
1458   lock = READ_REG32(MDC_UNLOCK);
1459
1460   /* SET REGISTER VALUE */
1461
1462   line_delta = READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF;
1463   line_delta |= (((unsigned long)pitch << 13) & 0xFFFF0000);
1464   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1465   WRITE_REG32(MDC_GFX_PITCH, line_delta);
1466   WRITE_REG32(MDC_UNLOCK, lock);
1467   return (0);
1468}
1469
1470/*---------------------------------------------------------------------------
1471 * gfx_set_compression_size
1472 *
1473 * This routine sets the line size of the compression buffer, which is the
1474 * maximum number of bytes allowed to store a compressed line.
1475 *---------------------------------------------------------------------------
1476 */
1477#if GFX_DISPLAY_DYNAMIC
1478int
1479gu2_set_compression_size(unsigned short size)
1480#else
1481int
1482gfx_set_compression_size(unsigned short size)
1483#endif
1484{
1485   unsigned long lock, buf_size;
1486
1487   /* SUBTRACT 32 FROM SIZE                          */
1488   /* The display controller will actually write     */
1489   /* 4 extra QWords.  So, if we assume that "size"  */
1490   /* refers to the allocated size, we must subtract */
1491   /* 32 bytes.                                      */
1492
1493   size -= 32;
1494
1495   /* SET REGISTER VALUE */
1496
1497   lock = READ_REG32(MDC_UNLOCK);
1498   buf_size = READ_REG32(MDC_LINE_SIZE) & 0xFF80FFFF;
1499   buf_size |= ((((unsigned long)size >> 3) + 1) & 0x7F) << 16;
1500   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1501   WRITE_REG32(MDC_LINE_SIZE, buf_size);
1502   WRITE_REG32(MDC_UNLOCK, lock);
1503   return (0);
1504}
1505
1506/*---------------------------------------------------------------------------
1507 * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API)
1508 *
1509 * This routine is called by "gfx_set_video_format".  It abstracts the
1510 * version of the display controller from the video overlay routines.
1511 *---------------------------------------------------------------------------
1512 */
1513#if GFX_DISPLAY_DYNAMIC
1514void
1515gu2_set_display_video_format(unsigned long format)
1516#else
1517void
1518gfx_set_display_video_format(unsigned long format)
1519#endif
1520{
1521   unsigned long gcfg, lock;
1522
1523   lock = READ_REG32(MDC_UNLOCK);
1524   gcfg = READ_REG32(MDC_GENERAL_CFG);
1525
1526   switch (format) {
1527   case VIDEO_FORMAT_Y0Y1Y2Y3:
1528   case VIDEO_FORMAT_Y3Y2Y1Y0:
1529   case VIDEO_FORMAT_Y1Y0Y3Y2:
1530   case VIDEO_FORMAT_Y1Y2Y3Y0:
1531
1532      gcfg |= MDC_GCFG_YUVM;
1533      break;
1534
1535   default:
1536
1537      gcfg &= ~MDC_GCFG_YUVM;
1538      break;
1539   }
1540
1541   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1542   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1543   WRITE_REG32(MDC_UNLOCK, lock);
1544}
1545
1546/*---------------------------------------------------------------------------
1547 * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
1548 *
1549 * This routine is called by "gfx_set_video_enable".  It abstracts the
1550 * version of the display controller from the video overlay routines.
1551 *---------------------------------------------------------------------------
1552 */
1553#if GFX_DISPLAY_DYNAMIC
1554void
1555gu2_set_display_video_enable(int enable)
1556#else
1557void
1558gfx_set_display_video_enable(int enable)
1559#endif
1560{
1561   unsigned long lock, gcfg, dcfg;
1562
1563   /* READ CURRENT VALUES */
1564
1565   lock = READ_REG32(MDC_UNLOCK);
1566   gcfg = READ_REG32(MDC_GENERAL_CFG);
1567   dcfg = READ_REG32(MDC_DISPLAY_CFG);
1568
1569   /* SET OR CLEAR VIDEO ENABLE IN GENERAL_CFG */
1570
1571   if (enable)
1572      gcfg |= MDC_GCFG_VIDE;
1573   else
1574      gcfg &= ~MDC_GCFG_VIDE;
1575
1576   /* WRITE REGISTER */
1577
1578   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1579   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1580   WRITE_REG32(MDC_UNLOCK, lock);
1581}
1582
1583/*---------------------------------------------------------------------------
1584 * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
1585 *
1586 * This routine is called by "gfx_set_video_size".  It abstracts the
1587 * version of the display controller from the video overlay routines.
1588 *---------------------------------------------------------------------------
1589 */
1590#if GFX_DISPLAY_DYNAMIC
1591void
1592gu2_set_display_video_size(unsigned short width, unsigned short height)
1593#else
1594void
1595gfx_set_display_video_size(unsigned short width, unsigned short height)
1596#endif
1597{
1598   unsigned long lock, value, yuv_420;
1599
1600   /* READ CURRENT VALUES */
1601
1602   lock = READ_REG32(MDC_UNLOCK);
1603   value = READ_REG32(MDC_LINE_SIZE) & 0x00FFFFFF;
1604   yuv_420 = READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_YUVM;
1605
1606   /* LINE WIDTH IS 1/4 FOR 4:2:0 VIDEO */
1607   /* All data must be 32-byte aligned. */
1608
1609   if (yuv_420) {
1610      width >>= 1;
1611      width = (width + 7) & 0xFFF8;
1612   } else {
1613      width <<= 1;
1614      width = (width + 31) & 0xFFE0;
1615   }
1616
1617   /* ONLY THE LINE SIZE IS PROGRAMMED IN THE DISPLAY CONTROLLER */
1618
1619   value |= ((unsigned long)width << 21);
1620
1621   /* WRITE THE REGISTER */
1622
1623   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1624   WRITE_REG32(MDC_LINE_SIZE, value);
1625   WRITE_REG32(MDC_UNLOCK, lock);
1626}
1627
1628/*---------------------------------------------------------------------------
1629 * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
1630 *
1631 * This routine is called by "gfx_set_video_offset".  It abstracts the
1632 * version of the display controller from the video overlay routines.
1633 *---------------------------------------------------------------------------
1634 */
1635#if GFX_DISPLAY_DYNAMIC
1636void
1637gu2_set_display_video_offset(unsigned long offset)
1638#else
1639void
1640gfx_set_display_video_offset(unsigned long offset)
1641#endif
1642{
1643   unsigned long lock;
1644
1645   lock = READ_REG32(MDC_UNLOCK);
1646   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1647   offset &= 0x0FFFFFF0;
1648   WRITE_REG32(MDC_VID_Y_ST_OFFSET, offset);
1649   WRITE_REG32(MDC_UNLOCK, lock);
1650}
1651
1652/*---------------------------------------------------------------------------
1653 * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
1654 *
1655 * This routine is called by gfx_set_video_yuv_offsets.  It abstracts the version
1656 * of the display controller from the video overlay routines.
1657 *---------------------------------------------------------------------------
1658 */
1659#if GFX_DISPLAY_DYNAMIC
1660void
1661gu2_set_display_video_yuv_offsets(unsigned long yoffset,
1662				  unsigned long uoffset,
1663				  unsigned long voffset)
1664#else
1665void
1666gfx_set_display_video_yuv_offsets(unsigned long yoffset,
1667				  unsigned long uoffset,
1668				  unsigned long voffset)
1669#endif
1670{
1671   unsigned long lock;
1672
1673   lock = READ_REG32(MDC_UNLOCK);
1674
1675   yoffset &= 0x0FFFFFF0;
1676   uoffset &= 0x0FFFFFF8;
1677   voffset &= 0x0FFFFFF8;
1678
1679   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1680   WRITE_REG32(MDC_VID_Y_ST_OFFSET, yoffset);
1681   WRITE_REG32(MDC_VID_U_ST_OFFSET, uoffset);
1682   WRITE_REG32(MDC_VID_V_ST_OFFSET, voffset);
1683   WRITE_REG32(MDC_UNLOCK, lock);
1684}
1685
1686/*---------------------------------------------------------------------------
1687 * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
1688 *
1689 * This routine is called by gfx_set_video_yuv_pitch.  It abstracts the version
1690 * of the display controller from the video overlay routines.
1691 *---------------------------------------------------------------------------
1692 */
1693#if GFX_DISPLAY_DYNAMIC
1694void
1695gu2_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
1696#else
1697void
1698gfx_set_display_video_yuv_pitch(unsigned long ypitch, unsigned long uvpitch)
1699#endif
1700{
1701   unsigned long lock, pitch;
1702
1703   lock = READ_REG32(MDC_UNLOCK);
1704
1705   pitch = ((uvpitch << 13) & 0xFFFF0000) | ((ypitch >> 3) & 0xFFFF);
1706
1707   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1708   WRITE_REG32(MDC_VID_YUV_PITCH, pitch);
1709   WRITE_REG32(MDC_UNLOCK, lock);
1710}
1711
1712/*---------------------------------------------------------------------------
1713 * gfx_set_display_video_downscale (PRIVATE ROUTINE - NOT PART OF API)
1714 *
1715 * This routine is called by gfx_set_video_vertical_downscale.  It abstracts the version
1716 * of the display controller from the video overlay routines.
1717 *---------------------------------------------------------------------------
1718 */
1719#if GFX_DISPLAY_DYNAMIC
1720void
1721gu2_set_display_video_downscale(unsigned short srch, unsigned short dsth)
1722#else
1723void
1724gfx_set_display_video_downscale(unsigned short srch, unsigned short dsth)
1725#endif
1726{
1727   unsigned long lock, delta;
1728
1729   lock = READ_REG32(MDC_UNLOCK);
1730
1731   /* CLIP SCALING LIMITS */
1732   /* Upscaling is performed in a separate function. */
1733   /* Maximum scale ratio is 1/2.                    */
1734
1735   if (dsth > srch || dsth <= (srch >> 1))
1736      delta = 0;
1737   else
1738      delta = (((unsigned long)srch << 14) / (unsigned long)dsth) << 18;
1739
1740   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1741   WRITE_REG32(MDC_VID_DS_DELTA, delta);
1742   WRITE_REG32(MDC_UNLOCK, lock);
1743}
1744
1745/*---------------------------------------------------------------------------
1746 * gfx_set_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API)
1747 *
1748 * This routine is called by "gfx_set_video_vertical_downscale_enable".  It abstracts the
1749 * version of the display controller from the video overlay routines.
1750 *---------------------------------------------------------------------------
1751 */
1752#if GFX_DISPLAY_DYNAMIC
1753void
1754gu2_set_display_video_vertical_downscale_enable(int enable)
1755#else
1756void
1757gfx_set_display_video_vertical_downscale_enable(int enable)
1758#endif
1759{
1760   unsigned long gcfg, unlock;
1761
1762   unlock = READ_REG32(MDC_UNLOCK);
1763   gcfg = READ_REG32(MDC_GENERAL_CFG);
1764
1765   if (enable)
1766      gcfg |= MDC_GCFG_VDSE;
1767   else
1768      gcfg &= ~MDC_GCFG_VDSE;
1769
1770   WRITE_REG32(MDC_UNLOCK, MDC_UNLOCK_VALUE);
1771   WRITE_REG32(MDC_GENERAL_CFG, gcfg);
1772   WRITE_REG32(MDC_UNLOCK, unlock);
1773}
1774
1775/*---------------------------------------------------------------------------
1776 * gfx_test_timing_active
1777 *---------------------------------------------------------------------------
1778 */
1779#if GFX_DISPLAY_DYNAMIC
1780int
1781gu2_test_timing_active(void)
1782#else
1783int
1784gfx_test_timing_active(void)
1785#endif
1786{
1787   if (READ_REG32(MDC_DISPLAY_CFG) & MDC_DCFG_TGEN)
1788      return (1);
1789   else
1790      return (0);
1791}
1792
1793/*---------------------------------------------------------------------------
1794 * gfx_test_vertical_active
1795 *---------------------------------------------------------------------------
1796 */
1797#if GFX_DISPLAY_DYNAMIC
1798int
1799gu2_test_vertical_active(void)
1800#else
1801int
1802gfx_test_vertical_active(void)
1803#endif
1804{
1805   if (READ_REG32(MDC_LINE_CNT_STATUS) & MDC_LNCNT_VNA)
1806      return (0);
1807
1808   return (1);
1809}
1810
1811/*---------------------------------------------------------------------------
1812 * gfx_wait_vertical_blank
1813 *---------------------------------------------------------------------------
1814 */
1815#if GFX_DISPLAY_DYNAMIC
1816int
1817gu2_wait_vertical_blank(void)
1818#else
1819int
1820gfx_wait_vertical_blank(void)
1821#endif
1822{
1823   if (gfx_test_timing_active()) {
1824      while (!gfx_test_vertical_active()) ;
1825      while (gfx_test_vertical_active()) ;
1826   }
1827   return (0);
1828}
1829
1830/*---------------------------------------------------------------------------
1831 * gfx_enable_panning
1832 *
1833 * This routine  enables the panning when the Mode is bigger than the panel
1834 * size.
1835 *---------------------------------------------------------------------------
1836 */
1837
1838#if GFX_DISPLAY_DYNAMIC
1839void
1840gu2_enable_panning(int x, int y)
1841#else
1842void
1843gfx_enable_panning(int x, int y)
1844#endif
1845{
1846   unsigned long modeBytesPerPixel;
1847   unsigned long modeBytesPerScanline = 0;
1848   unsigned long startAddress = 0;
1849
1850   modeBytesPerPixel = (gbpp + 7) / 8;
1851   modeBytesPerScanline = (READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3;
1852
1853   /* TEST FOR NO-WORK */
1854
1855   if (x >= DeltaX && x < ((int)PanelWidth + DeltaX) &&
1856       y >= DeltaY && y < ((int)PanelHeight + DeltaY))
1857      return;
1858
1859   /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY       */
1860   /* Test the boundary conditions for each coordinate and update */
1861   /* all variables and the starting offset accordingly.          */
1862
1863   if (x < DeltaX)
1864      DeltaX = x;
1865
1866   else if (x >= (DeltaX + (int)PanelWidth))
1867      DeltaX = x - (int)PanelWidth + 1;
1868
1869   if (y < DeltaY)
1870      DeltaY = y;
1871
1872   else if (y >= (DeltaY + (int)PanelHeight))
1873      DeltaY = y - (int)PanelHeight + 1;
1874
1875   /* CALCULATE THE START OFFSET */
1876
1877   startAddress =
1878	 (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
1879
1880   gfx_set_display_offset(startAddress);
1881
1882   /* SET PANEL COORDINATES                    */
1883   /* Panel's x position must be DWORD aligned */
1884
1885   panelTop = DeltaY;
1886   panelLeft = DeltaX * modeBytesPerPixel;
1887
1888   if (panelLeft & 3)
1889      panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
1890
1891   panelLeft /= modeBytesPerPixel;
1892}
1893
1894/*---------------------------------------------------------------------------
1895 * gfx_set_fixed_timings
1896 *---------------------------------------------------------------------------
1897 */
1898
1899#if GFX_DISPLAY_DYNAMIC
1900int
1901gu2_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1902		      unsigned short height, unsigned short bpp)
1903#else
1904int
1905gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width,
1906		      unsigned short height, unsigned short bpp)
1907#endif
1908{
1909   unsigned int mode;
1910
1911   ModeWidth = width;
1912   ModeHeight = height;
1913   PanelWidth = (unsigned short)panelResX;
1914   PanelHeight = (unsigned short)panelResY;
1915   PanelEnable = 1;
1916
1917   /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
1918   for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
1919      if ((FixedParams[mode].xres == width) &&
1920	  (FixedParams[mode].yres == height) &&
1921	  (FixedParams[mode].panelresx == panelResX) &&
1922	  (FixedParams[mode].panelresy == panelResY)) {
1923
1924	 /* SET THE 92xx FOR THE SELECTED MODE */
1925	 FIXEDTIMINGS *fmode = &FixedParams[mode];
1926
1927	 gfx_set_display_timings(bpp, 3, fmode->hactive, fmode->hblankstart,
1928				 fmode->hsyncstart, fmode->hsyncend,
1929				 fmode->hblankend, fmode->htotal,
1930				 fmode->vactive, fmode->vblankstart,
1931				 fmode->vsyncstart, fmode->vsyncend,
1932				 fmode->vblankend, fmode->vtotal,
1933				 fmode->frequency);
1934
1935	 return (1);
1936      }					/* end if() */
1937   }					/* end for() */
1938
1939   return (-1);
1940}
1941
1942/*---------------------------------------------------------------------------
1943 * gfx_set_panel_present
1944 *---------------------------------------------------------------------------
1945 */
1946#if GFX_DISPLAY_DYNAMIC
1947int
1948gu2_set_panel_present(int panelResX, int panelResY, unsigned short width,
1949		      unsigned short height, unsigned short bpp)
1950#else
1951int
1952gfx_set_panel_present(int panelResX, int panelResY, unsigned short width,
1953		      unsigned short height, unsigned short bpp)
1954#endif
1955{
1956   /* SET VALID BPP         */
1957   /* 16BPP is the default. */
1958
1959   if (bpp != 8 && bpp != 12 && bpp != 15 && bpp != 16 && bpp != 32)
1960      bpp = 16;
1961
1962   /* RECORD PANEL PARAMETERS */
1963   /* This routine does not touch any panel timings.  It is used when custom panel */
1964   /* settings are set up in advance by the BIOS or an application, but the        */
1965   /* application still requires access to other panel functionality provided by   */
1966   /* Durango (i.e. panning).                                                      */
1967
1968   ModeWidth = width;
1969   ModeHeight = height;
1970   PanelWidth = (unsigned short)panelResX;
1971   PanelHeight = (unsigned short)panelResY;
1972   PanelEnable = 1;
1973   gbpp = bpp;
1974
1975   /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
1976
1977   gfx_set_display_bpp(bpp);
1978
1979   return (GFX_STATUS_OK);
1980}
1981
1982/* THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: */
1983
1984/*---------------------------------------------------------------------------
1985 * gfx_get_display_pitch
1986 *
1987 * This routine returns the current pitch of the frame buffer, in bytes.
1988 *---------------------------------------------------------------------------
1989 */
1990#if GFX_DISPLAY_DYNAMIC
1991unsigned short
1992gu2_get_display_pitch(void)
1993#else
1994unsigned short
1995gfx_get_display_pitch(void)
1996#endif
1997{
1998   return ((unsigned short)(READ_REG32(MDC_GFX_PITCH) & 0x0000FFFF) << 3);
1999}
2000
2001/*----------------------------------------------------------------------------
2002 * gfx_mode_frequency_supported
2003 *
2004 * This routine examines if the requested mode with pixel frequency is supported.
2005 *
2006 * Returns >0 if successful , <0 if freq. could not be found and matched.
2007 *----------------------------------------------------------------------------
2008 */
2009#if GFX_DISPLAY_DYNAMIC
2010int
2011gu2_mode_frequency_supported(int xres, int yres, int bpp,
2012			     unsigned long frequency)
2013#else
2014int
2015gfx_mode_frequency_supported(int xres, int yres, int bpp,
2016			     unsigned long frequency)
2017#endif
2018{
2019   unsigned int index;
2020   unsigned long value;
2021   unsigned long bpp_flag = 0;
2022
2023   switch (bpp) {
2024   case 8:
2025      bpp_flag = GFX_MODE_8BPP;
2026      break;
2027   case 12:
2028      bpp_flag = GFX_MODE_12BPP;
2029      break;
2030   case 15:
2031      bpp_flag = GFX_MODE_15BPP;
2032      break;
2033   case 16:
2034      bpp_flag = GFX_MODE_16BPP;
2035      break;
2036   case 32:
2037      bpp_flag = GFX_MODE_24BPP;
2038      break;
2039   default:
2040      bpp_flag = GFX_MODE_8BPP;
2041      break;
2042   }
2043
2044   for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
2045      if ((DisplayParams[index].hactive == (unsigned int)xres) &&
2046	  (DisplayParams[index].vactive == (unsigned int)yres) &&
2047	  (DisplayParams[index].flags & bpp_flag) &&
2048	  (DisplayParams[index].frequency == frequency)) {
2049	 int hz = 0;
2050
2051	 value = DisplayParams[index].flags;
2052
2053	 if (value & GFX_MODE_60HZ)
2054	    hz = 60;
2055	 else if (value & GFX_MODE_70HZ)
2056	    hz = 70;
2057	 else if (value & GFX_MODE_72HZ)
2058	    hz = 72;
2059	 else if (value & GFX_MODE_75HZ)
2060	    hz = 75;
2061	 else if (value & GFX_MODE_85HZ)
2062	    hz = 85;
2063	 return (hz);
2064      }
2065   }
2066
2067   return (-1);
2068}
2069
2070/*----------------------------------------------------------------------------
2071 * gfx_refreshrate_from_frequency
2072 *
2073 * This routine maps the frequency to close match refresh rate
2074 *
2075 * Returns .
2076 *----------------------------------------------------------------------------
2077 */
2078#if GFX_DISPLAY_DYNAMIC
2079int
2080gu2_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
2081				   unsigned long frequency)
2082#else
2083int
2084gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz,
2085				   unsigned long frequency)
2086#endif
2087{
2088   unsigned int index, closematch = 0;
2089   unsigned long value;
2090   unsigned long bpp_flag = 0;
2091   long min, diff;
2092
2093   *hz = 60;
2094
2095   switch (bpp) {
2096   case 8:
2097      bpp_flag = GFX_MODE_8BPP;
2098      break;
2099   case 12:
2100      bpp_flag = GFX_MODE_12BPP;
2101      break;
2102   case 15:
2103      bpp_flag = GFX_MODE_15BPP;
2104      break;
2105   case 16:
2106      bpp_flag = GFX_MODE_16BPP;
2107      break;
2108   case 32:
2109      bpp_flag = GFX_MODE_24BPP;
2110      break;
2111   default:
2112      bpp_flag = GFX_MODE_8BPP;
2113      break;
2114   }
2115
2116   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
2117   /* Search the table for the closest frequency (16.16 format). */
2118
2119   min = 0x7fffffff;
2120   for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
2121      if ((DisplayParams[index].htotal == (unsigned int)xres) &&
2122	  (DisplayParams[index].vtotal == (unsigned int)yres) &&
2123	  (DisplayParams[index].flags & bpp_flag)) {
2124	 diff = (long)frequency - (long)DisplayParams[index].frequency;
2125	 if (diff < 0)
2126	    diff = -diff;
2127
2128	 if (diff < min) {
2129	    min = diff;
2130	    closematch = index;
2131	 }
2132      }
2133   }
2134
2135   value = DisplayParams[closematch].flags;
2136
2137   if (value & GFX_MODE_56HZ)
2138      *hz = 56;
2139   else if (value & GFX_MODE_60HZ)
2140      *hz = 60;
2141   else if (value & GFX_MODE_70HZ)
2142      *hz = 70;
2143   else if (value & GFX_MODE_72HZ)
2144      *hz = 72;
2145   else if (value & GFX_MODE_75HZ)
2146      *hz = 75;
2147   else if (value & GFX_MODE_85HZ)
2148      *hz = 85;
2149
2150   return (1);
2151}
2152
2153/*----------------------------------------------------------------------------
2154 * gfx_refreshrate_from_mode
2155 *
2156 * This routine is identical to the gfx_get_refreshrate_from_frequency,
2157 * except that the active timing values are compared instead of the total
2158 * values.  Some modes (such as 70Hz and 72Hz) may be confused in this routine.
2159 *
2160 * Returns .
2161 *----------------------------------------------------------------------------
2162 */
2163#if GFX_DISPLAY_DYNAMIC
2164int
2165gu2_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
2166			      unsigned long frequency)
2167#else
2168int
2169gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz,
2170			      unsigned long frequency)
2171#endif
2172{
2173   unsigned int index, closematch = 0;
2174   unsigned long value;
2175   unsigned long bpp_flag = 0;
2176   long min, diff;
2177
2178   *hz = 60;
2179
2180   switch (bpp) {
2181   case 8:
2182      bpp_flag = GFX_MODE_8BPP;
2183      break;
2184   case 12:
2185      bpp_flag = GFX_MODE_12BPP;
2186      break;
2187   case 15:
2188      bpp_flag = GFX_MODE_15BPP;
2189      break;
2190   case 16:
2191      bpp_flag = GFX_MODE_16BPP;
2192      break;
2193   case 32:
2194      bpp_flag = GFX_MODE_24BPP;
2195      break;
2196   default:
2197      bpp_flag = GFX_MODE_8BPP;
2198      break;
2199   }
2200
2201   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
2202   /* Search the table for the closest frequency (16.16 format). */
2203
2204   min = 0x7fffffff;
2205   for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
2206      if ((DisplayParams[index].hactive == (unsigned int)xres) &&
2207	  (DisplayParams[index].vactive == (unsigned int)yres) &&
2208	  (DisplayParams[index].flags & bpp_flag)) {
2209	 diff = (long)frequency - (long)DisplayParams[index].frequency;
2210	 if (diff < 0)
2211	    diff = -diff;
2212
2213	 if (diff < min) {
2214	    min = diff;
2215	    closematch = index;
2216	 }
2217      }
2218   }
2219
2220   value = DisplayParams[closematch].flags;
2221
2222   if (value & GFX_MODE_56HZ)
2223      *hz = 56;
2224   else if (value & GFX_MODE_60HZ)
2225      *hz = 60;
2226   else if (value & GFX_MODE_70HZ)
2227      *hz = 70;
2228   else if (value & GFX_MODE_72HZ)
2229      *hz = 72;
2230   else if (value & GFX_MODE_75HZ)
2231      *hz = 75;
2232   else if (value & GFX_MODE_85HZ)
2233      *hz = 85;
2234
2235   return (1);
2236}
2237
2238/*----------------------------------------------------------------------------
2239 * gfx_get_frequency_from_refreshrate
2240 *
2241 * This routine maps the refresh rate to the closest matching PLL frequency.
2242 *----------------------------------------------------------------------------
2243 */
2244#if GFX_DISPLAY_DYNAMIC
2245int
2246gu2_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
2247				   int *frequency)
2248#else
2249int
2250gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz,
2251				   int *frequency)
2252#endif
2253{
2254   int retval = -1;
2255   unsigned long hz_flag = 0;
2256   unsigned long index, bpp_flag = 0;
2257
2258   *frequency = 0;
2259
2260   if (hz == 60)
2261      hz_flag = GFX_MODE_60HZ;
2262   else if (hz == 70)
2263      hz_flag = GFX_MODE_70HZ;
2264   else if (hz == 72)
2265      hz_flag = GFX_MODE_72HZ;
2266   else if (hz == 75)
2267      hz_flag = GFX_MODE_75HZ;
2268   else if (hz == 85)
2269      hz_flag = GFX_MODE_85HZ;
2270
2271   switch (bpp) {
2272   case 8:
2273      bpp_flag = GFX_MODE_8BPP;
2274      break;
2275   case 12:
2276      bpp_flag = GFX_MODE_12BPP;
2277      break;
2278   case 15:
2279      bpp_flag = GFX_MODE_15BPP;
2280      break;
2281   case 16:
2282      bpp_flag = GFX_MODE_16BPP;
2283      break;
2284   case 32:
2285      bpp_flag = GFX_MODE_24BPP;
2286      break;
2287   default:
2288      bpp_flag = GFX_MODE_8BPP;
2289      break;
2290   }
2291
2292   /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
2293   /* Search the table for the closest frequency (16.16 format). */
2294
2295   for (index = 0; index < NUM_RC_DISPLAY_MODES; index++) {
2296      if ((DisplayParams[index].hactive == (unsigned short)xres) &&
2297	  (DisplayParams[index].vactive == (unsigned short)yres) &&
2298	  (DisplayParams[index].flags & bpp_flag) &&
2299	  (DisplayParams[index].flags & hz_flag)) {
2300	 *frequency = DisplayParams[index].frequency;
2301	 retval = 1;
2302      }
2303   }
2304   return retval;
2305}
2306
2307/*---------------------------------------------------------------------------
2308 * gfx_get_max_supported_pixel_clock
2309 *
2310 * This routine returns the maximum recommended speed for the pixel clock.  The
2311 * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum
2312 * floating point pixel clock speed.
2313 *---------------------------------------------------------------------------
2314 */
2315#if GFX_DISPLAY_DYNAMIC
2316unsigned long
2317gu2_get_max_supported_pixel_clock(void)
2318#else
2319unsigned long
2320gfx_get_max_supported_pixel_clock(void)
2321#endif
2322{
2323   return 229500;
2324}
2325
2326/*----------------------------------------------------------------------------
2327 * gfx_get_display_mode
2328 *
2329 * This routine gets the specified display mode.
2330 *
2331 * Returns >0 if successful and mode returned, <0 if mode could not be found.
2332 *----------------------------------------------------------------------------
2333 */
2334#if GFX_DISPLAY_DYNAMIC
2335int
2336gu2_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
2337#else
2338int
2339gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
2340#endif
2341{
2342   unsigned int mode = 0;
2343   unsigned long pll_freq = 0, bpp_flag = 0;
2344
2345   *xres = gfx_get_hactive();
2346   *yres = gfx_get_vactive();
2347   *bpp = gfx_get_display_bpp();
2348   pll_freq = gfx_get_clock_frequency();
2349
2350   /* SET BPP FLAGS TO LIMIT MODE SELECTION */
2351
2352   switch (*bpp) {
2353   case 8:
2354      bpp_flag = GFX_MODE_8BPP;
2355      break;
2356   case 12:
2357      bpp_flag = GFX_MODE_12BPP;
2358      break;
2359   case 15:
2360      bpp_flag = GFX_MODE_15BPP;
2361      break;
2362   case 16:
2363      bpp_flag = GFX_MODE_16BPP;
2364      break;
2365   case 32:
2366      bpp_flag = GFX_MODE_24BPP;
2367      break;
2368   default:
2369      bpp_flag = GFX_MODE_8BPP;
2370      break;
2371   }
2372
2373   for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
2374      if ((DisplayParams[mode].hactive == (unsigned int)*xres) &&
2375	  (DisplayParams[mode].vactive == (unsigned int)*yres) &&
2376	  (DisplayParams[mode].frequency == pll_freq) &&
2377	  (DisplayParams[mode].flags & bpp_flag)) {
2378
2379	 pll_freq = DisplayParams[mode].flags;
2380
2381	 if (pll_freq & GFX_MODE_56HZ)
2382	    *hz = 56;
2383	 else if (pll_freq & GFX_MODE_60HZ)
2384	    *hz = 60;
2385	 else if (pll_freq & GFX_MODE_70HZ)
2386	    *hz = 70;
2387	 else if (pll_freq & GFX_MODE_72HZ)
2388	    *hz = 72;
2389	 else if (pll_freq & GFX_MODE_75HZ)
2390	    *hz = 75;
2391	 else if (pll_freq & GFX_MODE_85HZ)
2392	    *hz = 85;
2393
2394	 return (1);
2395      }
2396   }
2397   return (-1);
2398}
2399
2400/*----------------------------------------------------------------------------
2401 * GFX_GET_DISPLAY_DETAILS
2402 *
2403 * This routine gets the specified display mode.
2404 *
2405 * Returns 1 if successful, 0 if mode could not be get.
2406 *----------------------------------------------------------------------------
2407 */
2408#if GFX_DISPLAY_DYNAMIC
2409int
2410gu2_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
2411#else
2412int
2413gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
2414#endif
2415{
2416   if (mode < NUM_RC_DISPLAY_MODES) {
2417      if (DisplayParams[mode].flags & GFX_MODE_56HZ)
2418	 *hz = 56;
2419      else if (DisplayParams[mode].flags & GFX_MODE_60HZ)
2420	 *hz = 60;
2421      else if (DisplayParams[mode].flags & GFX_MODE_70HZ)
2422	 *hz = 70;
2423      else if (DisplayParams[mode].flags & GFX_MODE_72HZ)
2424	 *hz = 72;
2425      else if (DisplayParams[mode].flags & GFX_MODE_75HZ)
2426	 *hz = 75;
2427      else if (DisplayParams[mode].flags & GFX_MODE_85HZ)
2428	 *hz = 85;
2429
2430      *xres = DisplayParams[mode].hactive;
2431      *yres = DisplayParams[mode].vactive;
2432
2433      if (DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE)
2434	 *xres >>= 1;
2435      if (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE)
2436	 *yres >>= 1;
2437
2438      return (1);
2439   }
2440   return (0);
2441}
2442
2443/*----------------------------------------------------------------------------
2444 * GFX_GET_DISPLAY_MODE_COUNT
2445 *
2446 * This routine gets the number of available display modes.
2447 *----------------------------------------------------------------------------
2448 */
2449#if GFX_DISPLAY_DYNAMIC
2450int
2451gu2_get_display_mode_count(void)
2452#else
2453int
2454gfx_get_display_mode_count(void)
2455#endif
2456{
2457   return (NUM_RC_DISPLAY_MODES);
2458}
2459
2460/*----------------------------------------------------------------------------
2461 * gfx_get_frame_buffer_line_size
2462 *
2463 * Returns the current frame buffer line size, in bytes
2464 *----------------------------------------------------------------------------
2465 */
2466#if GFX_DISPLAY_DYNAMIC
2467unsigned long
2468gu2_get_frame_buffer_line_size(void)
2469#else
2470unsigned long
2471gfx_get_frame_buffer_line_size(void)
2472#endif
2473{
2474   return ((READ_REG32(MDC_LINE_SIZE) & 0x7FF) << 3);
2475}
2476
2477/*---------------------------------------------------------------------------
2478 * gfx_get_hactive
2479 *---------------------------------------------------------------------------
2480 */
2481#if GFX_DISPLAY_DYNAMIC
2482unsigned short
2483gu2_get_hactive(void)
2484#else
2485unsigned short
2486gfx_get_hactive(void)
2487#endif
2488{
2489   return ((unsigned short)((READ_REG32(MDC_H_ACTIVE_TIMING) & 0x0FF8) + 8));
2490}
2491
2492/*---------------------------------------------------------------------------
2493 * gfx_get_hsync_start
2494 *---------------------------------------------------------------------------
2495 */
2496#if GFX_DISPLAY_DYNAMIC
2497unsigned short
2498gu2_get_hsync_start(void)
2499#else
2500unsigned short
2501gfx_get_hsync_start(void)
2502#endif
2503{
2504   return ((unsigned short)((READ_REG32(MDC_H_SYNC_TIMING) & 0x0FF8) + 8));
2505}
2506
2507/*---------------------------------------------------------------------------
2508 * gfx_get_hsync_end
2509 *---------------------------------------------------------------------------
2510 */
2511#if GFX_DISPLAY_DYNAMIC
2512unsigned short
2513gu2_get_hsync_end(void)
2514#else
2515unsigned short
2516gfx_get_hsync_end(void)
2517#endif
2518{
2519   return ((unsigned short)(((READ_REG32(MDC_H_SYNC_TIMING) >> 16) & 0x0FF8) +
2520			    8));
2521}
2522
2523/*---------------------------------------------------------------------------
2524 * gfx_get_htotal
2525 *---------------------------------------------------------------------------
2526 */
2527#if GFX_DISPLAY_DYNAMIC
2528unsigned short
2529gu2_get_htotal(void)
2530#else
2531unsigned short
2532gfx_get_htotal(void)
2533#endif
2534{
2535   return ((unsigned short)(((READ_REG32(MDC_H_ACTIVE_TIMING) >> 16) & 0x0FF8)
2536			    + 8));
2537}
2538
2539/*---------------------------------------------------------------------------
2540 * gfx_get_vactive
2541 *---------------------------------------------------------------------------
2542 */
2543#if GFX_DISPLAY_DYNAMIC
2544unsigned short
2545gu2_get_vactive(void)
2546#else
2547unsigned short
2548gfx_get_vactive(void)
2549#endif
2550{
2551   return ((unsigned short)((READ_REG32(MDC_V_ACTIVE_TIMING) & 0x07FF) + 1));
2552}
2553
2554/*---------------------------------------------------------------------------
2555 * gfx_get_vsync_end
2556 *---------------------------------------------------------------------------
2557 */
2558#if GFX_DISPLAY_DYNAMIC
2559unsigned short
2560gu2_get_vsync_end(void)
2561#else
2562unsigned short
2563gfx_get_vsync_end(void)
2564#endif
2565{
2566   return ((unsigned short)(((READ_REG32(MDC_V_SYNC_TIMING) >> 16) & 0x07FF) +
2567			    1));
2568}
2569
2570/*---------------------------------------------------------------------------
2571 * gfx_get_vtotal
2572 *---------------------------------------------------------------------------
2573 */
2574#if GFX_DISPLAY_DYNAMIC
2575unsigned short
2576gu2_get_vtotal(void)
2577#else
2578unsigned short
2579gfx_get_vtotal(void)
2580#endif
2581{
2582   return ((unsigned short)(((READ_REG32(MDC_V_ACTIVE_TIMING) >> 16) & 0x07FF)
2583			    + 1));
2584}
2585
2586/*-----------------------------------------------------------------------------
2587 * gfx_get_display_bpp
2588 *
2589 * This routine returns the current color depth of the active display.
2590 *-----------------------------------------------------------------------------
2591 */
2592#if GFX_DISPLAY_DYNAMIC
2593unsigned short
2594gu2_get_display_bpp(void)
2595#else
2596unsigned short
2597gfx_get_display_bpp(void)
2598#endif
2599{
2600   unsigned long dcfg = READ_REG32(MDC_DISPLAY_CFG);
2601
2602   switch ((dcfg & MDC_DCFG_DISP_MODE_MASK) >> 8) {
2603   case 0:
2604      return (8);
2605   case 2:
2606      return (32);
2607
2608   case 1:
2609
2610      switch ((dcfg & MDC_DCFG_16BPP_MODE_MASK) >> 10) {
2611      case 0:
2612	 return (16);
2613      case 1:
2614	 return (15);
2615      case 2:
2616	 return (12);
2617      default:
2618	 return (0);
2619      }
2620   }
2621
2622   /* INVALID SETTING */
2623
2624   return (0);
2625}
2626
2627/*---------------------------------------------------------------------------
2628 * gfx_get_vline
2629 *---------------------------------------------------------------------------
2630 */
2631#if GFX_DISPLAY_DYNAMIC
2632unsigned short
2633gu2_get_vline(void)
2634#else
2635unsigned short
2636gfx_get_vline(void)
2637#endif
2638{
2639   unsigned short current_scan_line;
2640
2641   /* Read similar value twice to ensure that the value is not transitioning */
2642
2643   do
2644      current_scan_line =
2645	    (unsigned short)(READ_REG32(MDC_LINE_CNT_STATUS) &
2646			     MDC_LNCNT_V_LINE_CNT);
2647   while (current_scan_line !=
2648	  (unsigned short)(READ_REG32(MDC_LINE_CNT_STATUS) &
2649			   MDC_LNCNT_V_LINE_CNT));
2650
2651   return (current_scan_line >> 16);
2652}
2653
2654/*-----------------------------------------------------------------------------
2655 * gfx_get_display_offset
2656 *-----------------------------------------------------------------------------
2657 */
2658#if GFX_DISPLAY_DYNAMIC
2659unsigned long
2660gu2_get_display_offset(void)
2661#else
2662unsigned long
2663gfx_get_display_offset(void)
2664#endif
2665{
2666   return (READ_REG32(MDC_FB_ST_OFFSET) & 0x0FFFFFFF);
2667}
2668
2669/*-----------------------------------------------------------------------------
2670 * gfx_get_cursor_offset
2671 *-----------------------------------------------------------------------------
2672 */
2673#if GFX_DISPLAY_DYNAMIC
2674unsigned long
2675gu2_get_cursor_offset(void)
2676#else
2677unsigned long
2678gfx_get_cursor_offset(void)
2679#endif
2680{
2681   return (READ_REG32(MDC_CURS_ST_OFFSET) & 0x0FFFFFFF);
2682}
2683
2684#if GFX_READ_ROUTINES
2685
2686/*************************************************************/
2687/*  READ ROUTINES  |  INCLUDED FOR DIAGNOSTIC PURPOSES ONLY  */
2688/*************************************************************/
2689
2690/*---------------------------------------------------------------------------
2691 * gfx_get_hblank_start
2692 *---------------------------------------------------------------------------
2693 */
2694#if GFX_DISPLAY_DYNAMIC
2695unsigned short
2696gu2_get_hblank_start(void)
2697#else
2698unsigned short
2699gfx_get_hblank_start(void)
2700#endif
2701{
2702   return ((unsigned short)((READ_REG32(MDC_H_BLANK_TIMING) & 0x0FF8) + 8));
2703}
2704
2705/*---------------------------------------------------------------------------
2706 * gfx_get_hblank_end
2707 *---------------------------------------------------------------------------
2708 */
2709#if GFX_DISPLAY_DYNAMIC
2710unsigned short
2711gu2_get_hblank_end(void)
2712#else
2713unsigned short
2714gfx_get_hblank_end(void)
2715#endif
2716{
2717   return ((unsigned short)(((READ_REG32(MDC_H_BLANK_TIMING) >> 16) & 0x0FF8)
2718			    + 8));
2719}
2720
2721/*---------------------------------------------------------------------------
2722 * gfx_get_vblank_start
2723 *---------------------------------------------------------------------------
2724 */
2725#if GFX_DISPLAY_DYNAMIC
2726unsigned short
2727gu2_get_vblank_start(void)
2728#else
2729unsigned short
2730gfx_get_vblank_start(void)
2731#endif
2732{
2733   return ((unsigned short)((READ_REG32(MDC_V_BLANK_TIMING) & 0x07FF) + 1));
2734}
2735
2736/*---------------------------------------------------------------------------
2737 * gfx_get_vsync_start
2738 *---------------------------------------------------------------------------
2739 */
2740#if GFX_DISPLAY_DYNAMIC
2741unsigned short
2742gu2_get_vsync_start(void)
2743#else
2744unsigned short
2745gfx_get_vsync_start(void)
2746#endif
2747{
2748   return ((unsigned short)((READ_REG32(MDC_V_SYNC_TIMING) & 0x07FF) + 1));
2749}
2750
2751/*---------------------------------------------------------------------------
2752 * gfx_get_vblank_end
2753 *---------------------------------------------------------------------------
2754 */
2755#if GFX_DISPLAY_DYNAMIC
2756unsigned short
2757gu2_get_vblank_end(void)
2758#else
2759unsigned short
2760gfx_get_vblank_end(void)
2761#endif
2762{
2763   return ((unsigned short)(((READ_REG32(MDC_V_BLANK_TIMING) >> 16) & 0x07FF)
2764			    + 1));
2765}
2766
2767/*-----------------------------------------------------------------------------
2768 * gfx_get_display_palette_entry
2769 *-----------------------------------------------------------------------------
2770 */
2771#if GFX_DISPLAY_DYNAMIC
2772int
2773gu2_get_display_palette_entry(unsigned long index, unsigned long *palette)
2774#else
2775int
2776gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
2777#endif
2778{
2779   if (index > 0xFF)
2780      return GFX_STATUS_BAD_PARAMETER;
2781
2782   WRITE_REG32(MDC_PAL_ADDRESS, index);
2783   *palette = READ_REG32(MDC_PAL_DATA);
2784
2785   return 0;
2786}
2787
2788/*-----------------------------------------------------------------------------
2789 * gfx_get_display_palette
2790 *-----------------------------------------------------------------------------
2791 */
2792#if GFX_DISPLAY_DYNAMIC
2793void
2794gu2_get_display_palette(unsigned long *palette)
2795#else
2796void
2797gfx_get_display_palette(unsigned long *palette)
2798#endif
2799{
2800   unsigned long i;
2801
2802   WRITE_REG32(MDC_PAL_ADDRESS, 0);
2803   for (i = 0; i < 256; i++) {
2804      palette[i] = READ_REG32(MDC_PAL_DATA);
2805   }
2806}
2807
2808/*-----------------------------------------------------------------------------
2809 * gfx_get_cursor_enable
2810 *-----------------------------------------------------------------------------
2811 */
2812#if GFX_DISPLAY_DYNAMIC
2813unsigned long
2814gu2_get_cursor_enable(void)
2815#else
2816unsigned long
2817gfx_get_cursor_enable(void)
2818#endif
2819{
2820   return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CURE);
2821}
2822
2823/*-----------------------------------------------------------------------------
2824 * gfx_get_cursor_position
2825 *-----------------------------------------------------------------------------
2826 */
2827#if GFX_DISPLAY_DYNAMIC
2828unsigned long
2829gu2_get_cursor_position(void)
2830#else
2831unsigned long
2832gfx_get_cursor_position(void)
2833#endif
2834{
2835   return ((READ_REG32(MDC_CURSOR_X) & 0x07FF) |
2836	   ((READ_REG32(MDC_CURSOR_Y) << 16) & 0x03FF0000));
2837}
2838
2839/*-----------------------------------------------------------------------------
2840 * gfx_get_cursor_offset
2841 *-----------------------------------------------------------------------------
2842 */
2843#if GFX_DISPLAY_DYNAMIC
2844unsigned long
2845gu2_get_cursor_clip(void)
2846#else
2847unsigned long
2848gfx_get_cursor_clip(void)
2849#endif
2850{
2851   return (((READ_REG32(MDC_CURSOR_X) >> 11) & 0x03F) |
2852	   ((READ_REG32(MDC_CURSOR_Y) << 5) & 0x3F0000));
2853}
2854
2855/*-----------------------------------------------------------------------------
2856 * gfx_get_cursor_color
2857 *-----------------------------------------------------------------------------
2858 */
2859#if GFX_DISPLAY_DYNAMIC
2860unsigned long
2861gu2_get_cursor_color(int color)
2862#else
2863unsigned long
2864gfx_get_cursor_color(int color)
2865#endif
2866{
2867   if (color) {
2868      WRITE_REG32(MDC_PAL_ADDRESS, 0x101);
2869   } else {
2870      WRITE_REG32(MDC_PAL_ADDRESS, 0x100);
2871   }
2872   return READ_REG32(MDC_PAL_DATA);
2873}
2874
2875/*-----------------------------------------------------------------------------
2876 * gfx_get_icon_enable
2877 *-----------------------------------------------------------------------------
2878 */
2879#if GFX_DISPLAY_DYNAMIC
2880unsigned long
2881gu2_get_icon_enable(void)
2882#else
2883unsigned long
2884gfx_get_icon_enable(void)
2885#endif
2886{
2887   return (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_ICNE);
2888}
2889
2890/*-----------------------------------------------------------------------------
2891 * gfx_get_icon_offset
2892 *-----------------------------------------------------------------------------
2893 */
2894#if GFX_DISPLAY_DYNAMIC
2895unsigned long
2896gu2_get_icon_offset(void)
2897#else
2898unsigned long
2899gfx_get_icon_offset(void)
2900#endif
2901{
2902   return (READ_REG32(MDC_ICON_ST_OFFSET) & 0x0FFFFFFF);
2903}
2904
2905/*-----------------------------------------------------------------------------
2906 * gfx_get_icon_position
2907 *-----------------------------------------------------------------------------
2908 */
2909#if GFX_DISPLAY_DYNAMIC
2910unsigned long
2911gu2_get_icon_position(void)
2912#else
2913unsigned long
2914gfx_get_icon_position(void)
2915#endif
2916{
2917   return (READ_REG32(MDC_ICON_X) & 0x07FF);
2918}
2919
2920/*-----------------------------------------------------------------------------
2921 * gfx_get_icon_color
2922 *-----------------------------------------------------------------------------
2923 */
2924#if GFX_DISPLAY_DYNAMIC
2925unsigned long
2926gu2_get_icon_color(int color)
2927#else
2928unsigned long
2929gfx_get_icon_color(int color)
2930#endif
2931{
2932   if (color >= 3)
2933      return 0;
2934
2935   WRITE_REG32(MDC_PAL_ADDRESS, 0x102 + color);
2936
2937   return READ_REG32(MDC_PAL_DATA);
2938}
2939
2940/*-----------------------------------------------------------------------------
2941 * gfx_get_compression_enable
2942 *-----------------------------------------------------------------------------
2943 */
2944#if GFX_DISPLAY_DYNAMIC
2945int
2946gu2_get_compression_enable(void)
2947#else
2948int
2949gfx_get_compression_enable(void)
2950#endif
2951{
2952   if (READ_REG32(MDC_GENERAL_CFG) & MDC_GCFG_CMPE)
2953      return (1);
2954
2955   return (0);
2956}
2957
2958/*-----------------------------------------------------------------------------
2959 * gfx_get_compression_offset
2960 *-----------------------------------------------------------------------------
2961 */
2962#if GFX_DISPLAY_DYNAMIC
2963unsigned long
2964gu2_get_compression_offset(void)
2965#else
2966unsigned long
2967gfx_get_compression_offset(void)
2968#endif
2969{
2970   return (READ_REG32(MDC_CB_ST_OFFSET) & 0x007FFFFF);
2971}
2972
2973/*-----------------------------------------------------------------------------
2974 * gfx_get_compression_pitch
2975 *-----------------------------------------------------------------------------
2976 */
2977#if GFX_DISPLAY_DYNAMIC
2978unsigned short
2979gu2_get_compression_pitch(void)
2980#else
2981unsigned short
2982gfx_get_compression_pitch(void)
2983#endif
2984{
2985   unsigned short pitch;
2986
2987   pitch = (unsigned short)(READ_REG32(MDC_GFX_PITCH) >> 16);
2988   return (pitch << 3);
2989}
2990
2991/*-----------------------------------------------------------------------------
2992 * gfx_get_compression_size
2993 *-----------------------------------------------------------------------------
2994 */
2995#if GFX_DISPLAY_DYNAMIC
2996unsigned short
2997gu2_get_compression_size(void)
2998#else
2999unsigned short
3000gfx_get_compression_size(void)
3001#endif
3002{
3003   unsigned short size;
3004
3005   size = (unsigned short)((READ_REG32(MDC_LINE_SIZE) >> 16) & 0x7F) - 1;
3006   return ((size << 3) + 32);
3007}
3008
3009/*-----------------------------------------------------------------------------
3010 * gfx_get_valid_bit
3011 *-----------------------------------------------------------------------------
3012 */
3013#if GFX_DISPLAY_DYNAMIC
3014int
3015gu2_get_valid_bit(int line)
3016#else
3017int
3018gfx_get_valid_bit(int line)
3019#endif
3020{
3021   unsigned long offset;
3022   int valid;
3023
3024   offset = READ_REG32(MDC_PHY_MEM_OFFSET) & 0xFF000000;
3025   offset |= line;
3026
3027   WRITE_REG32(MDC_PHY_MEM_OFFSET, offset);
3028   valid = (int)READ_REG32(MDC_DV_ACC) & 2;
3029
3030   if (valid)
3031      return 1;
3032   return 0;
3033}
3034
3035/*---------------------------------------------------------------------------
3036 * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
3037 *
3038 * This routine is called by "gfx_get_video_offset".  It abstracts the
3039 * version of the display controller from the video overlay routines.
3040 *---------------------------------------------------------------------------
3041 */
3042#if GFX_DISPLAY_DYNAMIC
3043unsigned long
3044gu2_get_display_video_offset(void)
3045#else
3046unsigned long
3047gfx_get_display_video_offset(void)
3048#endif
3049{
3050   return (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
3051}
3052
3053/*---------------------------------------------------------------------------
3054 * gfx_get_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
3055 *
3056 * This routine is called by "gfx_get_video_yuv_offsets".  It abstracts the
3057 * version of the display controller from the video overlay routines.
3058 *---------------------------------------------------------------------------
3059 */
3060#if GFX_DISPLAY_DYNAMIC
3061void
3062gu2_get_display_video_yuv_offsets(unsigned long *yoffset,
3063				  unsigned long *uoffset,
3064				  unsigned long *voffset)
3065#else
3066void
3067gfx_get_display_video_yuv_offsets(unsigned long *yoffset,
3068				  unsigned long *uoffset,
3069				  unsigned long *voffset)
3070#endif
3071{
3072   *yoffset = (READ_REG32(MDC_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
3073   *uoffset = (READ_REG32(MDC_VID_U_ST_OFFSET) & 0x0FFFFFFF);
3074   *voffset = (READ_REG32(MDC_VID_V_ST_OFFSET) & 0x0FFFFFFF);
3075}
3076
3077/*---------------------------------------------------------------------------
3078 * gfx_get_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
3079 *
3080 * This routine is called by "gfx_get_video_yuv_pitch".  It abstracts the
3081 * version of the display controller from the video overlay routines.
3082 *---------------------------------------------------------------------------
3083 */
3084#if GFX_DISPLAY_DYNAMIC
3085void
3086gu2_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
3087#else
3088void
3089gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
3090#endif
3091{
3092   unsigned long pitch = READ_REG32(MDC_VID_YUV_PITCH);
3093
3094   *ypitch = ((pitch & 0xFFFF) << 3);
3095   *uvpitch = (pitch >> 13) & 0x7FFF8;
3096}
3097
3098/*---------------------------------------------------------------------------
3099 * gfx_get_display_video_downscale_delta (PRIVATE ROUTINE - NOT PART OF API)
3100 *
3101 * This routine is called by "gfx_get_video_downscale_delta".  It abstracts the
3102 * version of the display controller from the video overlay routines.
3103 *---------------------------------------------------------------------------
3104 */
3105#if GFX_DISPLAY_DYNAMIC
3106unsigned long
3107gu2_get_display_video_downscale_delta(void)
3108#else
3109unsigned long
3110gfx_get_display_video_downscale_delta(void)
3111#endif
3112{
3113   return (READ_REG32(MDC_VID_DS_DELTA) >> 18);
3114}
3115
3116/*---------------------------------------------------------------------------
3117 * gfx_get_display_video_downscale_enable (PRIVATE ROUTINE - NOT PART OF API)
3118 *
3119 * This routine is called by "gfx_get_video_vertical_downscale_enable".  It abstracts the
3120 * version of the display controller from the video overlay routines.
3121 *---------------------------------------------------------------------------
3122 */
3123#if GFX_DISPLAY_DYNAMIC
3124int
3125gu2_get_display_video_downscale_enable(void)
3126#else
3127int
3128gfx_get_display_video_downscale_enable(void)
3129#endif
3130{
3131   return ((int)((READ_REG32(MDC_GENERAL_CFG) >> 19) & 1));
3132}
3133
3134/*---------------------------------------------------------------------------
3135 * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
3136 *
3137 * This routine is called by "gfx_get_video_size".  It abstracts the
3138 * version of the display controller from the video overlay routines.
3139 *---------------------------------------------------------------------------
3140 */
3141#if GFX_DISPLAY_DYNAMIC
3142unsigned long
3143gu2_get_display_video_size(void)
3144#else
3145unsigned long
3146gfx_get_display_video_size(void)
3147#endif
3148{
3149   /* RETURN THE LINE SIZE, AS THIS IS ALL THAT IS AVAILABLE */
3150
3151   return ((READ_REG32(MDC_LINE_SIZE) >> 21) & 0x000007FF);
3152}
3153
3154#endif /* GFX_READ_ROUTINES */
3155
3156/* END OF FILE */
3157