171d7fec4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu1.c,v 1.4 2003/02/06 17:46:02 alanh Exp $ */ 271d7fec4Smrg/* 371d7fec4Smrg * $Workfile: disp_gu1.c $ 471d7fec4Smrg * 571d7fec4Smrg * This file contains routines for the first generation display controller. 671d7fec4Smrg * 771d7fec4Smrg * NSC_LIC_ALTERNATIVE_PREAMBLE 871d7fec4Smrg * 971d7fec4Smrg * Revision 1.0 1071d7fec4Smrg * 1171d7fec4Smrg * National Semiconductor Alternative GPL-BSD License 1271d7fec4Smrg * 1371d7fec4Smrg * National Semiconductor Corporation licenses this software 1471d7fec4Smrg * ("Software"): 1571d7fec4Smrg * 1671d7fec4Smrg * Durango 1771d7fec4Smrg * 1871d7fec4Smrg * under one of the two following licenses, depending on how the 1971d7fec4Smrg * Software is received by the Licensee. 2071d7fec4Smrg * 2171d7fec4Smrg * If this Software is received as part of the Linux Framebuffer or 2271d7fec4Smrg * other GPL licensed software, then the GPL license designated 2371d7fec4Smrg * NSC_LIC_GPL applies to this Software; in all other circumstances 2471d7fec4Smrg * then the BSD-style license designated NSC_LIC_BSD shall apply. 2571d7fec4Smrg * 2671d7fec4Smrg * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 2771d7fec4Smrg 2871d7fec4Smrg/* NSC_LIC_BSD 2971d7fec4Smrg * 3071d7fec4Smrg * National Semiconductor Corporation Open Source License for Durango 3171d7fec4Smrg * 3271d7fec4Smrg * (BSD License with Export Notice) 3371d7fec4Smrg * 3471d7fec4Smrg * Copyright (c) 1999-2001 3571d7fec4Smrg * National Semiconductor Corporation. 3671d7fec4Smrg * All rights reserved. 3771d7fec4Smrg * 3871d7fec4Smrg * Redistribution and use in source and binary forms, with or without 3971d7fec4Smrg * modification, are permitted provided that the following conditions 4071d7fec4Smrg * are met: 4171d7fec4Smrg * 4271d7fec4Smrg * * Redistributions of source code must retain the above copyright 4371d7fec4Smrg * notice, this list of conditions and the following disclaimer. 4471d7fec4Smrg * 4571d7fec4Smrg * * Redistributions in binary form must reproduce the above 4671d7fec4Smrg * copyright notice, this list of conditions and the following 4771d7fec4Smrg * disclaimer in the documentation and/or other materials provided 4871d7fec4Smrg * with the distribution. 4971d7fec4Smrg * 5071d7fec4Smrg * * Neither the name of the National Semiconductor Corporation nor 5171d7fec4Smrg * the names of its contributors may be used to endorse or promote 5271d7fec4Smrg * products derived from this software without specific prior 5371d7fec4Smrg * written permission. 5471d7fec4Smrg * 5571d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 5671d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 5771d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 5871d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5971d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 6071d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 6171d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 6271d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6371d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 6471d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 6571d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 6671d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 6771d7fec4Smrg * OF SUCH DAMAGE. 6871d7fec4Smrg * 6971d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 7071d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 7171d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 7271d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 7371d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 7471d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 7571d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 7671d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 7771d7fec4Smrg * has embargoed goods and services. 7871d7fec4Smrg * 7971d7fec4Smrg * END_NSC_LIC_BSD */ 8071d7fec4Smrg 8171d7fec4Smrg/* NSC_LIC_GPL 8271d7fec4Smrg * 8371d7fec4Smrg * National Semiconductor Corporation Gnu General Public License for Durango 8471d7fec4Smrg * 8571d7fec4Smrg * (GPL License with Export Notice) 8671d7fec4Smrg * 8771d7fec4Smrg * Copyright (c) 1999-2001 8871d7fec4Smrg * National Semiconductor Corporation. 8971d7fec4Smrg * All rights reserved. 9071d7fec4Smrg * 9171d7fec4Smrg * Redistribution and use in source and binary forms, with or without 9271d7fec4Smrg * modification, are permitted under the terms of the GNU General 9371d7fec4Smrg * Public License as published by the Free Software Foundation; either 9471d7fec4Smrg * version 2 of the License, or (at your option) any later version 9571d7fec4Smrg * 9671d7fec4Smrg * In addition to the terms of the GNU General Public License, neither 9771d7fec4Smrg * the name of the National Semiconductor Corporation nor the names of 9871d7fec4Smrg * its contributors may be used to endorse or promote products derived 9971d7fec4Smrg * from this software without specific prior written permission. 10071d7fec4Smrg * 10171d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 10271d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 10371d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 10471d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 10571d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 10671d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 10771d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 10871d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 10971d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 11071d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 11171d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 11271d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 11371d7fec4Smrg * OF SUCH DAMAGE. See the GNU General Public License for more details. 11471d7fec4Smrg * 11571d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 11671d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 11771d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 11871d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 11971d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 12071d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 12171d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 12271d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 12371d7fec4Smrg * has embargoed goods and services. 12471d7fec4Smrg * 12571d7fec4Smrg * You should have received a copy of the GNU General Public License 12671d7fec4Smrg * along with this file; if not, write to the Free Software Foundation, 12771d7fec4Smrg * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 12871d7fec4Smrg * 12971d7fec4Smrg * END_NSC_LIC_GPL */ 13071d7fec4Smrg 13171d7fec4Smrgvoid gu1_enable_compression(void); /* private routine definition */ 13271d7fec4Smrgvoid gu1_disable_compression(void); /* private routine definition */ 13371d7fec4Smrgvoid gfx_reset_video(void); /* private routine definition */ 13471d7fec4Smrgint gfx_set_display_control(int sync_polarities); /* private routine definition */ 13571d7fec4Smrgvoid gu1_delay_approximate(unsigned long milliseconds); 13671d7fec4Smrgvoid gu1_delay_precise(unsigned long milliseconds); 13771d7fec4Smrgint gu1_set_display_bpp(unsigned short bpp); 13871d7fec4Smrgint gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz); 13971d7fec4Smrgint gu1_set_display_mode(int xres, int yres, int bpp, int hz); 14071d7fec4Smrgint gu1_set_display_timings(unsigned short bpp, unsigned short flags, 14171d7fec4Smrg unsigned short hactive, 14271d7fec4Smrg unsigned short hblank_start, 14371d7fec4Smrg unsigned short hsync_start, 14471d7fec4Smrg unsigned short hsync_end, 14571d7fec4Smrg unsigned short hblank_end, unsigned short htotal, 14671d7fec4Smrg unsigned short vactive, 14771d7fec4Smrg unsigned short vblank_start, 14871d7fec4Smrg unsigned short vsync_start, 14971d7fec4Smrg unsigned short vsync_end, 15071d7fec4Smrg unsigned short vblank_end, unsigned short vtotal, 15171d7fec4Smrg unsigned long frequency); 15271d7fec4Smrgint gu1_set_vtotal(unsigned short vtotal); 15371d7fec4Smrgvoid gu1_set_display_pitch(unsigned short pitch); 15471d7fec4Smrgvoid gu1_set_display_offset(unsigned long offset); 15571d7fec4Smrgint gu1_set_display_palette_entry(unsigned long index, unsigned long palette); 15671d7fec4Smrgint gu1_set_display_palette(unsigned long *palette); 15771d7fec4Smrgvoid gu1_video_shutdown(void); 15871d7fec4Smrgvoid gu1_set_clock_frequency(unsigned long frequency); 15971d7fec4Smrgint gu1_set_crt_enable(int enable); 16071d7fec4Smrgvoid gu1_set_cursor_enable(int enable); 16171d7fec4Smrgvoid gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor); 16271d7fec4Smrgvoid gu1_set_cursor_position(unsigned long memoffset, 16371d7fec4Smrg unsigned short xpos, unsigned short ypos, 16471d7fec4Smrg unsigned short xhotspot, 16571d7fec4Smrg unsigned short yhotspot); 16671d7fec4Smrgvoid gu1_set_cursor_shape32(unsigned long memoffset, unsigned long *andmask, 16771d7fec4Smrg unsigned long *xormask); 16871d7fec4Smrgvoid gu1_set_cursor_shape64(unsigned long memoffset, unsigned long *andmask, 16971d7fec4Smrg unsigned long *xormask); 17071d7fec4Smrgvoid gu1_set_icon_enable(int enable); 17171d7fec4Smrgvoid gu1_set_icon_colors(unsigned long color0, unsigned long color1, 17271d7fec4Smrg unsigned long color2); 17371d7fec4Smrgvoid gu1_set_icon_position(unsigned long memoffset, unsigned short xpos); 17471d7fec4Smrgvoid gu1_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, 17571d7fec4Smrg unsigned long *xormask, unsigned int lines); 17671d7fec4Smrg 17771d7fec4Smrgint gu1_set_compression_enable(int enable); 17871d7fec4Smrgint gu1_set_compression_offset(unsigned long offset); 17971d7fec4Smrgint gu1_set_compression_pitch(unsigned short pitch); 18071d7fec4Smrgint gu1_set_compression_size(unsigned short size); 18171d7fec4Smrgvoid gu1_set_display_priority_high(int enable); 18271d7fec4Smrgint gu1_test_timing_active(void); 18371d7fec4Smrgint gu1_test_vertical_active(void); 18471d7fec4Smrgint gu1_wait_vertical_blank(void); 18571d7fec4Smrgvoid gu1_delay_milliseconds(unsigned long milliseconds); 18671d7fec4Smrgvoid gu1_delay_microseconds(unsigned long microseconds); 18771d7fec4Smrgvoid gu1_enable_panning(int x, int y); 18871d7fec4Smrgint gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width, 18971d7fec4Smrg unsigned short height, unsigned short bpp); 19071d7fec4Smrgint gu1_set_panel_present(int panelResX, int panelResY, unsigned short width, 19171d7fec4Smrg unsigned short height, unsigned short bpp); 19271d7fec4Smrgvoid gu1_reset_timing_lock(void); 19371d7fec4Smrg 19471d7fec4Smrgint gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz); 19571d7fec4Smrgunsigned short gu1_get_display_pitch(void); 19671d7fec4Smrgint gu1_get_vsa2_softvga_enable(void); 19771d7fec4Smrgint gu1_get_sync_polarities(void); 19871d7fec4Smrgunsigned long gu1_get_clock_frequency(void); 19971d7fec4Smrgunsigned long gu1_get_max_supported_pixel_clock(void); 20071d7fec4Smrgint gu1_mode_frequency_supported(int xres, int yres, int bpp, 20171d7fec4Smrg unsigned long frequency); 20271d7fec4Smrgint gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, 20371d7fec4Smrg unsigned long frequency); 20471d7fec4Smrgint gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, 20571d7fec4Smrg unsigned long frequency); 20671d7fec4Smrgint gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, 20771d7fec4Smrg int *frequency); 20871d7fec4Smrgint gu1_get_display_mode_count(void); 20971d7fec4Smrgint gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz); 21071d7fec4Smrgunsigned long gu1_get_frame_buffer_line_size(void); 21171d7fec4Smrgunsigned short gu1_get_hactive(void); 21271d7fec4Smrgunsigned short gu1_get_hblank_start(void); 21371d7fec4Smrgunsigned short gu1_get_hsync_start(void); 21471d7fec4Smrgunsigned short gu1_get_hsync_end(void); 21571d7fec4Smrgunsigned short gu1_get_hblank_end(void); 21671d7fec4Smrgunsigned short gu1_get_htotal(void); 21771d7fec4Smrgunsigned short gu1_get_vactive(void); 21871d7fec4Smrgunsigned short gu1_get_vline(void); 21971d7fec4Smrgunsigned short gu1_get_vblank_start(void); 22071d7fec4Smrgunsigned short gu1_get_vsync_start(void); 22171d7fec4Smrgunsigned short gu1_get_vsync_end(void); 22271d7fec4Smrgunsigned short gu1_get_vblank_end(void); 22371d7fec4Smrgunsigned short gu1_get_vtotal(void); 22471d7fec4Smrgunsigned short gu1_get_display_bpp(void); 22571d7fec4Smrgunsigned long gu1_get_display_offset(void); 22671d7fec4Smrgint gu1_get_display_palette_entry(unsigned long index, 22771d7fec4Smrg unsigned long *palette); 22871d7fec4Smrgvoid gu1_get_display_palette(unsigned long *palette); 22971d7fec4Smrgunsigned long gu1_get_cursor_enable(void); 23071d7fec4Smrgunsigned long gu1_get_cursor_offset(void); 23171d7fec4Smrgunsigned long gu1_get_cursor_position(void); 23271d7fec4Smrgunsigned long gu1_get_cursor_clip(void); 23371d7fec4Smrgunsigned long gu1_get_cursor_color(int color); 23471d7fec4Smrgunsigned long gu1_get_icon_enable(void); 23571d7fec4Smrgunsigned long gu1_get_icon_offset(void); 23671d7fec4Smrgunsigned long gu1_get_icon_position(void); 23771d7fec4Smrgunsigned long gu1_get_icon_color(int color); 23871d7fec4Smrgint gu1_get_compression_enable(void); 23971d7fec4Smrgunsigned long gu1_get_compression_offset(void); 24071d7fec4Smrgunsigned short gu1_get_compression_pitch(void); 24171d7fec4Smrgunsigned short gu1_get_compression_size(void); 24271d7fec4Smrgint gu1_get_display_priority_high(void); 24371d7fec4Smrgint gu1_get_valid_bit(int line); 24471d7fec4Smrgvoid gu1_set_display_video_enable(int enable); 24571d7fec4Smrgint gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp); 24671d7fec4Smrgvoid gu1_set_display_video_size(unsigned short width, unsigned short height); 24771d7fec4Smrgvoid gu1_set_display_video_offset(unsigned long offset); 24871d7fec4Smrgunsigned long gu1_get_display_video_offset(void); 24971d7fec4Smrgunsigned long gu1_get_display_video_size(void); 25071d7fec4Smrg 25171d7fec4Smrg/* VIDEO BUFFER SIZE */ 25271d7fec4Smrg 25371d7fec4Smrgunsigned long vid_buf_size = 0; 25471d7fec4Smrgint vid_enabled = 0; 25571d7fec4Smrg 25671d7fec4Smrg/*----------------------------------------------------------------------------- 25771d7fec4Smrg * GU1_DELAY_APPROXIMATE (PRIVATE ROUTINE - NOT PART OF DURANGO API) 25871d7fec4Smrg * 25971d7fec4Smrg * Delay the requested number of milliseconds by reading a register. This function 26071d7fec4Smrg * generally takes longer than the requested time. 26171d7fec4Smrg *-----------------------------------------------------------------------------*/ 26271d7fec4Smrgvoid 26371d7fec4Smrggu1_delay_approximate(unsigned long milliseconds) 26471d7fec4Smrg{ 26571d7fec4Smrg /* ASSUME 300 MHz, 5 CLOCKS PER READ */ 26671d7fec4Smrg 26771d7fec4Smrg# define READS_PER_MILLISECOND 60000L 26871d7fec4Smrg 26971d7fec4Smrg unsigned long loop; 27071d7fec4Smrg 27171d7fec4Smrg loop = milliseconds * READS_PER_MILLISECOND; 27271d7fec4Smrg while (loop-- > 0) { 27371d7fec4Smrg READ_REG32(DC_UNLOCK); 27471d7fec4Smrg } 27571d7fec4Smrg} 27671d7fec4Smrg 27771d7fec4Smrg/*----------------------------------------------------------------------------- 27871d7fec4Smrg * GU1_DELAY_PRECISE (PRIVATE ROUTINE - NOT PART OF DURANGO API) 27971d7fec4Smrg * 28071d7fec4Smrg * Delay the number of milliseconds on a more precise level, varying only by 28171d7fec4Smrg * 1/10 of a ms. This function should only be called if an SC1200 is present. 28271d7fec4Smrg *-----------------------------------------------------------------------------*/ 28371d7fec4Smrgvoid 28471d7fec4Smrggu1_delay_precise(unsigned long milliseconds) 28571d7fec4Smrg{ 28671d7fec4Smrg#if GFX_VIDEO_SC1200 28771d7fec4Smrg 28871d7fec4Smrg#define LOOP 1000 28971d7fec4Smrg unsigned long i, timer_start, timer_end, total_ticks, previous_ticks, 29071d7fec4Smrg temp_ticks; 29171d7fec4Smrg 29271d7fec4Smrg /* Get current time */ 29371d7fec4Smrg timer_start = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE); 29471d7fec4Smrg 29571d7fec4Smrg /* Calculate expected end time */ 29671d7fec4Smrg if (INB(SC1200_CB_BASE_ADDR + SC1200_CB_TMCNFG) & SC1200_TMCLKSEL_27MHZ) 29771d7fec4Smrg total_ticks = 27000 * milliseconds; /* timer resolution is 27 MHz */ 29871d7fec4Smrg else 29971d7fec4Smrg total_ticks = 1000 * milliseconds; /* timer resolution is 1 MHz */ 30071d7fec4Smrg 30171d7fec4Smrg if (total_ticks > ((unsigned long)0xffffffff - timer_start)) /* wrap-around */ 30271d7fec4Smrg timer_end = total_ticks - ((unsigned long)0xffffffff - timer_start); 30371d7fec4Smrg else 30471d7fec4Smrg timer_end = timer_start + total_ticks; 30571d7fec4Smrg 30671d7fec4Smrg /* in case of wrap around */ 30771d7fec4Smrg if (timer_end < timer_start) { 30871d7fec4Smrg previous_ticks = timer_start; 30971d7fec4Smrg while (1) { 31071d7fec4Smrg temp_ticks = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE); 31171d7fec4Smrg if (temp_ticks < previous_ticks) 31271d7fec4Smrg break; 31371d7fec4Smrg else 31471d7fec4Smrg previous_ticks = temp_ticks; 31571d7fec4Smrg for (i = 0; i < LOOP; i++) 31671d7fec4Smrg READ_REG32(DC_UNLOCK); 31771d7fec4Smrg } 31871d7fec4Smrg } 31971d7fec4Smrg /* now the non-wrap around part */ 32071d7fec4Smrg while (1) { 32171d7fec4Smrg for (i = 0; i < LOOP; i++) 32271d7fec4Smrg READ_REG32(DC_UNLOCK); 32371d7fec4Smrg if (IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE) > timer_end) 32471d7fec4Smrg break; 32571d7fec4Smrg } 32671d7fec4Smrg 32771d7fec4Smrg#endif /* GFX_VIDEO_SC1200 */ 32871d7fec4Smrg} 32971d7fec4Smrg 33071d7fec4Smrg/*----------------------------------------------------------------------------- 33171d7fec4Smrg * WARNING!!!! INACCURATE DELAY MECHANISM 33271d7fec4Smrg * 33371d7fec4Smrg * In an effort to keep the code self contained and operating system 33471d7fec4Smrg * independent, the delay loop just performs reads of a display controller 33571d7fec4Smrg * register. This time will vary for faster processors. The delay can always 33671d7fec4Smrg * be longer than intended, only effecting the time of the mode switch 33771d7fec4Smrg * (obviously want it to still be under a second). Problems with the hardware 33871d7fec4Smrg * only arise if the delay is not long enough. 33971d7fec4Smrg * 34071d7fec4Smrg * For the SC1200, the high resolution timer can be used as an accurate mechanism 34171d7fec4Smrg * for keeping time. However, in order to avoid a busy loop of IO reads, the 34271d7fec4Smrg * timer is polled in-between busy loops, and therefore the actual delay might 34371d7fec4Smrg * be longer than the requested delay by the time of one busy loop 34471d7fec4Smrg * (which on a 200 MHz system took 95 us) 34571d7fec4Smrg * 34671d7fec4Smrg * There are thus two delay functions which are called from the main API routine. 34771d7fec4Smrg * One is meant to be more precise and should only called if an SC1200 is present. 34871d7fec4Smrg *----------------------------------------------------------------------------- 34971d7fec4Smrg */ 35071d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 35171d7fec4Smrgvoid 35271d7fec4Smrggu1_delay_milliseconds(unsigned long milliseconds) 35371d7fec4Smrg#else 35471d7fec4Smrgvoid 35571d7fec4Smrggfx_delay_milliseconds(unsigned long milliseconds) 35671d7fec4Smrg#endif 35771d7fec4Smrg{ 35871d7fec4Smrg#if GFX_VIDEO_SC1200 35971d7fec4Smrg 36071d7fec4Smrg#if GFX_VIDEO_DYNAMIC 36171d7fec4Smrg if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) { 36271d7fec4Smrg#endif 36371d7fec4Smrg gu1_delay_precise(milliseconds); 36471d7fec4Smrg return; 36571d7fec4Smrg#if GFX_VIDEO_DYNAMIC 36671d7fec4Smrg } 36771d7fec4Smrg#endif 36871d7fec4Smrg 36971d7fec4Smrg#endif /* GFX_VIDEO_SC1200 */ 37071d7fec4Smrg 37171d7fec4Smrg gu1_delay_approximate(milliseconds); 37271d7fec4Smrg} 37371d7fec4Smrg 37471d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 37571d7fec4Smrgvoid 37671d7fec4Smrggu1_delay_microseconds(unsigned long microseconds) 37771d7fec4Smrg#else 37871d7fec4Smrgvoid 37971d7fec4Smrggfx_delay_microseconds(unsigned long microseconds) 38071d7fec4Smrg#endif 38171d7fec4Smrg{ 38271d7fec4Smrg /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */ 38371d7fec4Smrg 38471d7fec4Smrg unsigned long loop_count = microseconds * 150; 38571d7fec4Smrg 38671d7fec4Smrg while (loop_count-- > 0) { 38771d7fec4Smrg ; 38871d7fec4Smrg } 38971d7fec4Smrg} 39071d7fec4Smrg 39171d7fec4Smrg/*----------------------------------------------------------------------------- 39271d7fec4Smrg * GFX_VIDEO_SHUTDOWN 39371d7fec4Smrg * 39471d7fec4Smrg * This routine disables the display controller output. 39571d7fec4Smrg *----------------------------------------------------------------------------- 39671d7fec4Smrg */ 39771d7fec4Smrgvoid 39871d7fec4Smrggu1_video_shutdown(void) 39971d7fec4Smrg{ 40071d7fec4Smrg unsigned long unlock; 40171d7fec4Smrg unsigned long gcfg, tcfg; 40271d7fec4Smrg 40371d7fec4Smrg /* DISABLE COMPRESSION */ 40471d7fec4Smrg 40571d7fec4Smrg gu1_disable_compression(); 40671d7fec4Smrg 40771d7fec4Smrg /* ALSO DISABLE VIDEO */ 40871d7fec4Smrg /* Use private "reset video" routine to do all that is needed. */ 40971d7fec4Smrg /* SC1200, for example, also disables the alpha blending regions. */ 41071d7fec4Smrg 41171d7fec4Smrg gfx_reset_video(); 41271d7fec4Smrg 41371d7fec4Smrg /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ 41471d7fec4Smrg 41571d7fec4Smrg unlock = READ_REG32(DC_UNLOCK); 41671d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 41771d7fec4Smrg 41871d7fec4Smrg /* READ THE CURRENT GX VALUES */ 41971d7fec4Smrg 42071d7fec4Smrg gcfg = READ_REG32(DC_GENERAL_CFG); 42171d7fec4Smrg tcfg = READ_REG32(DC_TIMING_CFG); 42271d7fec4Smrg 42371d7fec4Smrg /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */ 42471d7fec4Smrg 42571d7fec4Smrg tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN); 42671d7fec4Smrg WRITE_REG32(DC_TIMING_CFG, tcfg); 42771d7fec4Smrg 42871d7fec4Smrg /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */ 42971d7fec4Smrg /* This delay is used to make sure that all pending requests to the */ 43071d7fec4Smrg /* memory controller have completed before disabling the FIFO load. */ 43171d7fec4Smrg 43271d7fec4Smrg gfx_delay_milliseconds(1); 43371d7fec4Smrg 43471d7fec4Smrg /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */ 43571d7fec4Smrg 43671d7fec4Smrg gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); 43771d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 43871d7fec4Smrg WRITE_REG32(DC_UNLOCK, unlock); 43971d7fec4Smrg return; 44071d7fec4Smrg} 44171d7fec4Smrg 44271d7fec4Smrg/*----------------------------------------------------------------------------- 44371d7fec4Smrg * GFX_SET_DISPLAY_BPP 44471d7fec4Smrg * 44571d7fec4Smrg * This routine programs the bpp in the display controller. 44671d7fec4Smrg *----------------------------------------------------------------------------- 44771d7fec4Smrg */ 44871d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 44971d7fec4Smrgint 45071d7fec4Smrggu1_set_display_bpp(unsigned short bpp) 45171d7fec4Smrg#else 45271d7fec4Smrgint 45371d7fec4Smrggfx_set_display_bpp(unsigned short bpp) 45471d7fec4Smrg#endif 45571d7fec4Smrg{ 45671d7fec4Smrg unsigned long ocfg, lock; 45771d7fec4Smrg 45871d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 45971d7fec4Smrg ocfg = READ_REG32(DC_OUTPUT_CFG) & ~(DC_OCFG_8BPP | DC_OCFG_555); 46071d7fec4Smrg 46171d7fec4Smrg /* SET DC PIXEL FORMAT */ 46271d7fec4Smrg 46371d7fec4Smrg if (bpp == 8) 46471d7fec4Smrg ocfg |= DC_OCFG_8BPP; 46571d7fec4Smrg else if (bpp == 15) 46671d7fec4Smrg ocfg |= DC_OCFG_555; 46771d7fec4Smrg else if (bpp != 16) 46871d7fec4Smrg return GFX_STATUS_BAD_PARAMETER; 46971d7fec4Smrg 47071d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 47171d7fec4Smrg WRITE_REG32(DC_OUTPUT_CFG, ocfg); 47271d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 47371d7fec4Smrg 47471d7fec4Smrg /* SET BPP IN GRAPHICS PIPELINE */ 47571d7fec4Smrg 47671d7fec4Smrg gfx_set_bpp(bpp); 47771d7fec4Smrg 47871d7fec4Smrg return 0; 47971d7fec4Smrg} 48071d7fec4Smrg 48171d7fec4Smrg/*----------------------------------------------------------------------------- 48271d7fec4Smrg * GFX_SET_SPECIFIED_MODE 48371d7fec4Smrg * This routine uses the parameters in the specified display mode structure 48471d7fec4Smrg * to program the display controller hardware. 48571d7fec4Smrg *----------------------------------------------------------------------------- 48671d7fec4Smrg */ 48771d7fec4Smrgint 48871d7fec4Smrggu1_set_specified_mode(DISPLAYMODE * pMode, int bpp) 48971d7fec4Smrg{ 49071d7fec4Smrg unsigned long unlock, value; 49171d7fec4Smrg unsigned long gcfg, tcfg, ocfg; 49271d7fec4Smrg unsigned long size, pitch; 49371d7fec4Smrg unsigned long vid_buffer_size; 49471d7fec4Smrg unsigned long hactive, vactive; 49571d7fec4Smrg 49671d7fec4Smrg gbpp = bpp; 49771d7fec4Smrg 49871d7fec4Smrg /* CHECK WHETHER TIMING CHANGE IS ALLOWED */ 49971d7fec4Smrg /* Flag used for locking also overrides timing change restriction */ 50071d7fec4Smrg 50171d7fec4Smrg if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING)) 50271d7fec4Smrg return GFX_STATUS_ERROR; 50371d7fec4Smrg 50471d7fec4Smrg /* SET GLOBAL FLAG */ 50571d7fec4Smrg 50671d7fec4Smrg if (pMode->flags & GFX_MODE_LOCK_TIMING) 50771d7fec4Smrg gfx_timing_lock = 1; 50871d7fec4Smrg 50971d7fec4Smrg /* DISABLE COMPRESSION */ 51071d7fec4Smrg 51171d7fec4Smrg gu1_disable_compression(); 51271d7fec4Smrg 51371d7fec4Smrg /* ALSO DISABLE VIDEO */ 51471d7fec4Smrg /* Use private "reset video" routine to do all that is needed. */ 51571d7fec4Smrg /* SC1200, for example, also disables the alpha blending regions. */ 51671d7fec4Smrg 51771d7fec4Smrg gfx_reset_video(); 51871d7fec4Smrg 51971d7fec4Smrg /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ 52071d7fec4Smrg 52171d7fec4Smrg unlock = READ_REG32(DC_UNLOCK); 52271d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 52371d7fec4Smrg 52471d7fec4Smrg /* READ THE CURRENT GX VALUES */ 52571d7fec4Smrg 52671d7fec4Smrg gcfg = READ_REG32(DC_GENERAL_CFG); 52771d7fec4Smrg tcfg = READ_REG32(DC_TIMING_CFG); 52871d7fec4Smrg 52971d7fec4Smrg /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */ 53071d7fec4Smrg 53171d7fec4Smrg tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN); 53271d7fec4Smrg WRITE_REG32(DC_TIMING_CFG, tcfg); 53371d7fec4Smrg 53471d7fec4Smrg /* DELAY: WAIT FOR PENDING MEMORY REQUESTS 53571d7fec4Smrg * This delay is used to make sure that all pending requests to the 53671d7fec4Smrg * memory controller have completed before disabling the FIFO load. 53771d7fec4Smrg */ 53871d7fec4Smrg 53971d7fec4Smrg gfx_delay_milliseconds(1); 54071d7fec4Smrg 54171d7fec4Smrg /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */ 54271d7fec4Smrg 54371d7fec4Smrg gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); 54471d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 54571d7fec4Smrg 54671d7fec4Smrg /* CLEAR THE "DCLK_MUL" FIELD */ 54771d7fec4Smrg 54871d7fec4Smrg gcfg &= ~(unsigned long)(DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK); 54971d7fec4Smrg gcfg &= ~(unsigned long)DC_GCFG_DCLK_MASK; 55071d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 55171d7fec4Smrg 55271d7fec4Smrg /* SET THE DOT CLOCK FREQUENCY */ 55371d7fec4Smrg /* Mask off the divide by two bit (bit 31) */ 55471d7fec4Smrg 55571d7fec4Smrg gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF); 55671d7fec4Smrg 55771d7fec4Smrg /* DELAY: WAIT FOR THE PLL TO SETTLE */ 55871d7fec4Smrg /* This allows the dot clock frequency that was just set to settle. */ 55971d7fec4Smrg 56071d7fec4Smrg gfx_delay_milliseconds(1); 56171d7fec4Smrg 56271d7fec4Smrg /* SET THE "DCLK_MUL" FIELD OF DC_GENERAL_CFG */ 56371d7fec4Smrg /* The GX hardware divides the dot clock, so 2x really means that the */ 56471d7fec4Smrg /* internal dot clock equals the external dot clock. */ 56571d7fec4Smrg 56671d7fec4Smrg if (pMode->frequency & 0x80000000) 56771d7fec4Smrg gcfg |= 0x0040; 56871d7fec4Smrg else 56971d7fec4Smrg gcfg |= 0x0080; 57071d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 57171d7fec4Smrg 57271d7fec4Smrg /* DELAY: WAIT FOR THE ADL TO LOCK */ 57371d7fec4Smrg /* This allows the clock generatation within GX to settle. This is */ 57471d7fec4Smrg /* needed since some of the register writes that follow require that */ 57571d7fec4Smrg /* clock to be present. */ 57671d7fec4Smrg 57771d7fec4Smrg /* We do a few to ensure we're synced */ 57871d7fec4Smrg gfx_delay_milliseconds(1); 57971d7fec4Smrg gfx_delay_milliseconds(1); 58071d7fec4Smrg gfx_delay_milliseconds(1); 58171d7fec4Smrg gfx_delay_milliseconds(1); 58271d7fec4Smrg gfx_delay_milliseconds(1); 58371d7fec4Smrg gfx_delay_milliseconds(1); 58471d7fec4Smrg 58571d7fec4Smrg /* SET THE GX DISPLAY CONTROLLER PARAMETERS */ 58671d7fec4Smrg 58771d7fec4Smrg WRITE_REG32(DC_FB_ST_OFFSET, 0); 58871d7fec4Smrg WRITE_REG32(DC_CB_ST_OFFSET, 0); 58971d7fec4Smrg WRITE_REG32(DC_CURS_ST_OFFSET, 0); 59071d7fec4Smrg 59171d7fec4Smrg /* SET LINE SIZE AND PITCH */ 59271d7fec4Smrg /* Flat panels use the current flat panel line size to */ 59371d7fec4Smrg /* calculate the pitch, but load the true line size */ 59471d7fec4Smrg /* for the mode into the "Frame Buffer Line Size" field */ 59571d7fec4Smrg /* of DC_BUF_SIZE. */ 59671d7fec4Smrg 59771d7fec4Smrg if (PanelEnable) 59871d7fec4Smrg size = ModeWidth; 59971d7fec4Smrg else 60071d7fec4Smrg size = pMode->hactive; 60171d7fec4Smrg 60271d7fec4Smrg if (bpp > 8) 60371d7fec4Smrg size <<= 1; 60471d7fec4Smrg 60571d7fec4Smrg /* ONLY PYRAMID SUPPORTS 4K LINE SIZE */ 60671d7fec4Smrg 60771d7fec4Smrg if (size <= 1024) { 60871d7fec4Smrg pitch = 1024; 60971d7fec4Smrg 61071d7fec4Smrg /* SPECIAL CASE */ 61171d7fec4Smrg /* Graphics acceleration in 16-bit pixel line double modes */ 61271d7fec4Smrg /* requires a pitch of 2048. */ 61371d7fec4Smrg 61471d7fec4Smrg if ((pMode->flags & GFX_MODE_LINE_DOUBLE) && bpp > 8) 61571d7fec4Smrg pitch <<= 1; 61671d7fec4Smrg } else { 61771d7fec4Smrg if (gfx_cpu_version == GFX_CPU_PYRAMID) 61871d7fec4Smrg pitch = (size <= 2048) ? 2048 : 4096; 61971d7fec4Smrg else 62071d7fec4Smrg pitch = 2048; 62171d7fec4Smrg } 62271d7fec4Smrg WRITE_REG32(DC_LINE_DELTA, pitch >> 2); 62371d7fec4Smrg 62471d7fec4Smrg if (PanelEnable) { 62571d7fec4Smrg size = pMode->hactive; 62671d7fec4Smrg if (bpp > 8) 62771d7fec4Smrg size <<= 1; 62871d7fec4Smrg } 62971d7fec4Smrg 63071d7fec4Smrg /* SAVE PREVIOUSLY STORED VIDEO BUFFER SIZE */ 63171d7fec4Smrg 63271d7fec4Smrg vid_buffer_size = READ_REG32(DC_BUF_SIZE) & 0x3FFF0000; 63371d7fec4Smrg 63471d7fec4Smrg /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */ 63571d7fec4Smrg 63671d7fec4Smrg WRITE_REG32(DC_BUF_SIZE, ((size >> 3) + 2) | vid_buffer_size); 63771d7fec4Smrg 63871d7fec4Smrg /* ALWAYS ENABLE "PANEL" DATA FROM MEDIAGX */ 63971d7fec4Smrg /* That is really just the 18 BPP data bus to the companion chip */ 64071d7fec4Smrg 64171d7fec4Smrg ocfg = DC_OCFG_PCKE | DC_OCFG_PDEL | DC_OCFG_PDEH; 64271d7fec4Smrg 64371d7fec4Smrg /* SET PIXEL FORMAT */ 64471d7fec4Smrg 64571d7fec4Smrg if (bpp == 8) 64671d7fec4Smrg ocfg |= DC_OCFG_8BPP; 64771d7fec4Smrg else if (bpp == 15) 64871d7fec4Smrg ocfg |= DC_OCFG_555; 64971d7fec4Smrg 65071d7fec4Smrg /* ENABLE TIMING GENERATOR, SYNCS, AND FP DATA */ 65171d7fec4Smrg 65271d7fec4Smrg tcfg = DC_TCFG_FPPE | DC_TCFG_HSYE | DC_TCFG_VSYE | DC_TCFG_BLKE | 65371d7fec4Smrg DC_TCFG_TGEN; 65471d7fec4Smrg 65571d7fec4Smrg /* SET FIFO PRIORITY, DCLK MULTIPLIER, AND FIFO ENABLE */ 65671d7fec4Smrg /* Default 6/5 for FIFO, 2x for DCLK multiplier. */ 65771d7fec4Smrg 65871d7fec4Smrg gcfg = (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | 65971d7fec4Smrg DC_GCFG_DFLE; 66071d7fec4Smrg 66171d7fec4Smrg /* INCREASE FIFO PRIORITY FOR LARGE MODES */ 66271d7fec4Smrg 66371d7fec4Smrg if (pMode->hactive == 1280 && pMode->vactive == 1024) { 66471d7fec4Smrg if ((bpp == 8) && (pMode->flags & GFX_MODE_85HZ)) 66571d7fec4Smrg gcfg = (8l << DC_GCFG_DFHPEL_POS) | (7l << DC_GCFG_DFHPSL_POS) | 66671d7fec4Smrg DC_GCFG_DFLE; 66771d7fec4Smrg if ((bpp > 8) && (pMode->flags & GFX_MODE_75HZ)) 66871d7fec4Smrg gcfg = (7l << DC_GCFG_DFHPEL_POS) | (6l << DC_GCFG_DFHPSL_POS) | 66971d7fec4Smrg DC_GCFG_DFLE; 67071d7fec4Smrg if ((bpp > 8) && (pMode->flags & GFX_MODE_85HZ)) 67171d7fec4Smrg gcfg = (9l << DC_GCFG_DFHPEL_POS) | (8l << DC_GCFG_DFHPSL_POS) | 67271d7fec4Smrg DC_GCFG_DFLE; 67371d7fec4Smrg } 67471d7fec4Smrg 67571d7fec4Smrg /* SET DOT CLOCK MULTIPLIER */ 67671d7fec4Smrg /* Bit 31 of frequency indicates divide frequency by two */ 67771d7fec4Smrg 67871d7fec4Smrg if (pMode->frequency & 0x80000000) 67971d7fec4Smrg gcfg |= (1l << DC_GCFG_DCLK_POS); 68071d7fec4Smrg else 68171d7fec4Smrg gcfg |= (2l << DC_GCFG_DCLK_POS); 68271d7fec4Smrg 68371d7fec4Smrg /* DIVIDE VIDEO CLOCK */ 68471d7fec4Smrg /* CPU core frequencies above 266 MHz will divide the video */ 68571d7fec4Smrg /* clock by 4 to ensure that we are running below 150 MHz. */ 68671d7fec4Smrg 68771d7fec4Smrg if (gfx_cpu_frequency > 266) 68871d7fec4Smrg gcfg |= DC_GCFG_VCLK_DIV; 68971d7fec4Smrg 69071d7fec4Smrg /* SET THE PIXEL AND LINE DOUBLE BITS IF NECESSARY */ 69171d7fec4Smrg 69271d7fec4Smrg hactive = pMode->hactive; 69371d7fec4Smrg vactive = pMode->vactive; 69471d7fec4Smrg gfx_line_double = 0; 69571d7fec4Smrg gfx_pixel_double = 0; 69671d7fec4Smrg 69771d7fec4Smrg if (pMode->flags & GFX_MODE_LINE_DOUBLE) { 69871d7fec4Smrg gcfg |= DC_GCFG_LDBL; 69971d7fec4Smrg hactive <<= 1; 70071d7fec4Smrg 70171d7fec4Smrg /* SET GLOBAL FLAG */ 70271d7fec4Smrg 70371d7fec4Smrg gfx_line_double = 1; 70471d7fec4Smrg } 70571d7fec4Smrg 70671d7fec4Smrg if (pMode->flags & GFX_MODE_PIXEL_DOUBLE) { 70771d7fec4Smrg tcfg |= DC_TCFG_PXDB; 70871d7fec4Smrg vactive <<= 1; 70971d7fec4Smrg 71071d7fec4Smrg /* SET GLOBAL FLAG */ 71171d7fec4Smrg 71271d7fec4Smrg gfx_pixel_double = 1; 71371d7fec4Smrg } 71471d7fec4Smrg 71571d7fec4Smrg /* COMBINE AND SET TIMING VALUES */ 71671d7fec4Smrg 71771d7fec4Smrg value = (unsigned long)(hactive - 1) | 71871d7fec4Smrg (((unsigned long)(pMode->htotal - 1)) << 16); 71971d7fec4Smrg WRITE_REG32(DC_H_TIMING_1, value); 72071d7fec4Smrg value = (unsigned long)(pMode->hblankstart - 1) | 72171d7fec4Smrg (((unsigned long)(pMode->hblankend - 1)) << 16); 72271d7fec4Smrg WRITE_REG32(DC_H_TIMING_2, value); 72371d7fec4Smrg value = (unsigned long)(pMode->hsyncstart - 1) | 72471d7fec4Smrg (((unsigned long)(pMode->hsyncend - 1)) << 16); 72571d7fec4Smrg WRITE_REG32(DC_H_TIMING_3, value); 72671d7fec4Smrg WRITE_REG32(DC_FP_H_TIMING, value); 72771d7fec4Smrg value = (unsigned long)(vactive - 1) | 72871d7fec4Smrg (((unsigned long)(pMode->vtotal - 1)) << 16); 72971d7fec4Smrg WRITE_REG32(DC_V_TIMING_1, value); 73071d7fec4Smrg value = (unsigned long)(pMode->vblankstart - 1) | 73171d7fec4Smrg (((unsigned long)(pMode->vblankend - 1)) << 16); 73271d7fec4Smrg WRITE_REG32(DC_V_TIMING_2, value); 73371d7fec4Smrg value = (unsigned long)(pMode->vsyncstart - 1) | 73471d7fec4Smrg (((unsigned long)(pMode->vsyncend - 1)) << 16); 73571d7fec4Smrg WRITE_REG32(DC_V_TIMING_3, value); 73671d7fec4Smrg value = (unsigned long)(pMode->vsyncstart - 2) | 73771d7fec4Smrg (((unsigned long)(pMode->vsyncend - 2)) << 16); 73871d7fec4Smrg WRITE_REG32(DC_FP_V_TIMING, value); 73971d7fec4Smrg 74071d7fec4Smrg WRITE_REG32(DC_OUTPUT_CFG, ocfg); 74171d7fec4Smrg WRITE_REG32(DC_TIMING_CFG, tcfg); 74271d7fec4Smrg gfx_delay_milliseconds(1); /* delay after TIMING_CFG */ 74371d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 74471d7fec4Smrg 74571d7fec4Smrg /* ENABLE FLAT PANEL CENTERING */ 74671d7fec4Smrg /* For 640x480 modes displayed with the 9211 within a 800x600 */ 74771d7fec4Smrg /* flat panel display, turn on flat panel centering. */ 74871d7fec4Smrg 74971d7fec4Smrg if (PanelEnable) { 75071d7fec4Smrg if (ModeWidth < PanelWidth) { 75171d7fec4Smrg tcfg = READ_REG32(DC_TIMING_CFG); 75271d7fec4Smrg tcfg = tcfg | DC_TCFG_FCEN; 75371d7fec4Smrg WRITE_REG32(DC_TIMING_CFG, tcfg); 75471d7fec4Smrg gfx_delay_milliseconds(1); /* delay after TIMING_CFG */ 75571d7fec4Smrg } 75671d7fec4Smrg } 75771d7fec4Smrg 75871d7fec4Smrg /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ 75971d7fec4Smrg 76071d7fec4Smrg gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) | 76171d7fec4Smrg ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0)); 76271d7fec4Smrg 76371d7fec4Smrg /* RESTORE VALUE OF DC_UNLOCK */ 76471d7fec4Smrg 76571d7fec4Smrg WRITE_REG32(DC_UNLOCK, unlock); 76671d7fec4Smrg 76771d7fec4Smrg /* ALSO WRITE GP_BLIT_STATUS FOR PITCH AND 8/18 BPP */ 76871d7fec4Smrg /* Remember, only Pyramid supports 4K line pitch */ 76971d7fec4Smrg 77071d7fec4Smrg value = 0; 77171d7fec4Smrg if (bpp > 8) 77271d7fec4Smrg value |= BC_16BPP; 77371d7fec4Smrg if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) 77471d7fec4Smrg value |= BC_FB_WIDTH_4096; 77571d7fec4Smrg else if (pitch > 1024) 77671d7fec4Smrg value |= BC_FB_WIDTH_2048; 77771d7fec4Smrg WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value); 77871d7fec4Smrg 77971d7fec4Smrg return GFX_STATUS_OK; 78071d7fec4Smrg 78171d7fec4Smrg} /* end gfx_set_specified_mode() */ 78271d7fec4Smrg 78371d7fec4Smrg/*---------------------------------------------------------------------------- 78471d7fec4Smrg * GFX_IS_DISPLAY_MODE_SUPPORTED 78571d7fec4Smrg * 78671d7fec4Smrg * This routine sets the specified display mode. 78771d7fec4Smrg * 78871d7fec4Smrg * Returns the index of the mode if successful and mode returned, -1 if the mode 78971d7fec4Smrg * could not be found. 79071d7fec4Smrg *---------------------------------------------------------------------------- 79171d7fec4Smrg */ 79271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 79371d7fec4Smrgint 79471d7fec4Smrggu1_is_display_mode_supported(int xres, int yres, int bpp, int hz) 79571d7fec4Smrg#else 79671d7fec4Smrgint 79771d7fec4Smrggfx_is_display_mode_supported(int xres, int yres, int bpp, int hz) 79871d7fec4Smrg#endif 79971d7fec4Smrg{ 80071d7fec4Smrg unsigned int mode = 0; 80171d7fec4Smrg unsigned long hz_flag = 0, bpp_flag = 0; 80271d7fec4Smrg 80371d7fec4Smrg /* SET FLAGS TO MATCH REFRESH RATE */ 80471d7fec4Smrg 80571d7fec4Smrg if (hz == 56) 80671d7fec4Smrg hz_flag = GFX_MODE_56HZ; 80771d7fec4Smrg else if (hz == 60) 80871d7fec4Smrg hz_flag = GFX_MODE_60HZ; 80971d7fec4Smrg else if (hz == 70) 81071d7fec4Smrg hz_flag = GFX_MODE_70HZ; 81171d7fec4Smrg else if (hz == 72) 81271d7fec4Smrg hz_flag = GFX_MODE_72HZ; 81371d7fec4Smrg else if (hz == 75) 81471d7fec4Smrg hz_flag = GFX_MODE_75HZ; 81571d7fec4Smrg else if (hz == 85) 81671d7fec4Smrg hz_flag = GFX_MODE_85HZ; 81771d7fec4Smrg else 81871d7fec4Smrg return -1; 81971d7fec4Smrg 82071d7fec4Smrg /* SET BPP FLAGS TO LIMIT MODE SELECTION */ 82171d7fec4Smrg 82271d7fec4Smrg if (bpp == 8) 82371d7fec4Smrg bpp_flag = GFX_MODE_8BPP; 82471d7fec4Smrg else if (bpp == 15) 82571d7fec4Smrg bpp_flag = GFX_MODE_15BPP; 82671d7fec4Smrg else if (bpp == 16) 82771d7fec4Smrg bpp_flag = GFX_MODE_16BPP; 82871d7fec4Smrg else 82971d7fec4Smrg return -1; 83071d7fec4Smrg 83171d7fec4Smrg /* ONLY PYRAMID SUPPORTS 4K PITCH */ 83271d7fec4Smrg 83371d7fec4Smrg if (gfx_cpu_version != GFX_CPU_PYRAMID && xres > 1024) { 83471d7fec4Smrg if (bpp > 8) 83571d7fec4Smrg return (-1); /* return with mode not found */ 83671d7fec4Smrg } 83771d7fec4Smrg 83871d7fec4Smrg /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ 83971d7fec4Smrg 84071d7fec4Smrg for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) { 84171d7fec4Smrg if ((DisplayParams[mode].hactive == (unsigned short)xres) && 84271d7fec4Smrg (DisplayParams[mode].vactive == (unsigned short)yres) && 84371d7fec4Smrg (DisplayParams[mode].flags & hz_flag) && 84471d7fec4Smrg (DisplayParams[mode].flags & bpp_flag)) { 84571d7fec4Smrg 84671d7fec4Smrg /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */ 84771d7fec4Smrg 84871d7fec4Smrg return (mode); 84971d7fec4Smrg } 85071d7fec4Smrg } 85171d7fec4Smrg return (-1); 85271d7fec4Smrg} 85371d7fec4Smrg 85471d7fec4Smrg/*---------------------------------------------------------------------------- 85571d7fec4Smrg * GFX_SET_DISPLAY_MODE 85671d7fec4Smrg * 85771d7fec4Smrg * This routine sets the specified display mode. 85871d7fec4Smrg * 85971d7fec4Smrg * Returns 1 if successful, 0 if mode could not be set. 86071d7fec4Smrg *---------------------------------------------------------------------------- 86171d7fec4Smrg */ 86271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 86371d7fec4Smrgint 86471d7fec4Smrggu1_set_display_mode(int xres, int yres, int bpp, int hz) 86571d7fec4Smrg#else 86671d7fec4Smrgint 86771d7fec4Smrggfx_set_display_mode(int xres, int yres, int bpp, int hz) 86871d7fec4Smrg#endif 86971d7fec4Smrg{ 87071d7fec4Smrg int mode; 87171d7fec4Smrg 87271d7fec4Smrg /* DISABLE FLAT PANEL */ 87371d7fec4Smrg /* Flat Panel settings are enabled by the function gfx_set_fixed_timings */ 87471d7fec4Smrg /* and disabled by gfx_set_display_mode. */ 87571d7fec4Smrg 87671d7fec4Smrg PanelEnable = 0; 87771d7fec4Smrg 87871d7fec4Smrg mode = gfx_is_display_mode_supported(xres, yres, bpp, hz); 87971d7fec4Smrg if (mode >= 0) { 88071d7fec4Smrg if (gu1_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK) 88171d7fec4Smrg return (1); 88271d7fec4Smrg } 88371d7fec4Smrg return (0); 88471d7fec4Smrg} 88571d7fec4Smrg 88671d7fec4Smrg/*---------------------------------------------------------------------------- 88771d7fec4Smrg * GFX_SET_DISPLAY_TIMINGS 88871d7fec4Smrg * 88971d7fec4Smrg * This routine sets the display controller mode using the specified timing 89071d7fec4Smrg * values (as opposed to using the tables internal to Durango). 89171d7fec4Smrg * 89271d7fec4Smrg * Returns GFX_STATUS_OK on success, GFX_STATUS_ERROR otherwise. 89371d7fec4Smrg *---------------------------------------------------------------------------- 89471d7fec4Smrg */ 89571d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 89671d7fec4Smrgint 89771d7fec4Smrggu1_set_display_timings(unsigned short bpp, unsigned short flags, 89871d7fec4Smrg unsigned short hactive, unsigned short hblankstart, 89971d7fec4Smrg unsigned short hsyncstart, unsigned short hsyncend, 90071d7fec4Smrg unsigned short hblankend, unsigned short htotal, 90171d7fec4Smrg unsigned short vactive, unsigned short vblankstart, 90271d7fec4Smrg unsigned short vsyncstart, unsigned short vsyncend, 90371d7fec4Smrg unsigned short vblankend, unsigned short vtotal, 90471d7fec4Smrg unsigned long frequency) 90571d7fec4Smrg#else 90671d7fec4Smrgint 90771d7fec4Smrggfx_set_display_timings(unsigned short bpp, unsigned short flags, 90871d7fec4Smrg unsigned short hactive, unsigned short hblankstart, 90971d7fec4Smrg unsigned short hsyncstart, unsigned short hsyncend, 91071d7fec4Smrg unsigned short hblankend, unsigned short htotal, 91171d7fec4Smrg unsigned short vactive, unsigned short vblankstart, 91271d7fec4Smrg unsigned short vsyncstart, unsigned short vsyncend, 91371d7fec4Smrg unsigned short vblankend, unsigned short vtotal, 91471d7fec4Smrg unsigned long frequency) 91571d7fec4Smrg#endif 91671d7fec4Smrg{ 91771d7fec4Smrg /* SET MODE STRUCTURE WITH SPECIFIED VALUES */ 91871d7fec4Smrg 91971d7fec4Smrg gfx_display_mode.flags = 0; 92071d7fec4Smrg if (flags & 1) 92171d7fec4Smrg gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC; 92271d7fec4Smrg if (flags & 2) 92371d7fec4Smrg gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC; 92471d7fec4Smrg if (flags & 0x1000) 92571d7fec4Smrg gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING; 92671d7fec4Smrg gfx_display_mode.hactive = hactive; 92771d7fec4Smrg gfx_display_mode.hblankstart = hblankstart; 92871d7fec4Smrg gfx_display_mode.hsyncstart = hsyncstart; 92971d7fec4Smrg gfx_display_mode.hsyncend = hsyncend; 93071d7fec4Smrg gfx_display_mode.hblankend = hblankend; 93171d7fec4Smrg gfx_display_mode.htotal = htotal; 93271d7fec4Smrg gfx_display_mode.vactive = vactive; 93371d7fec4Smrg gfx_display_mode.vblankstart = vblankstart; 93471d7fec4Smrg gfx_display_mode.vsyncstart = vsyncstart; 93571d7fec4Smrg gfx_display_mode.vsyncend = vsyncend; 93671d7fec4Smrg gfx_display_mode.vblankend = vblankend; 93771d7fec4Smrg gfx_display_mode.vtotal = vtotal; 93871d7fec4Smrg gfx_display_mode.frequency = frequency; 93971d7fec4Smrg 94071d7fec4Smrg /* CALL ROUTINE TO SET MODE */ 94171d7fec4Smrg 94271d7fec4Smrg return (gu1_set_specified_mode(&gfx_display_mode, bpp)); 94371d7fec4Smrg} 94471d7fec4Smrg 94571d7fec4Smrg/*---------------------------------------------------------------------------- 94671d7fec4Smrg * GFX_SET_VTOTAL 94771d7fec4Smrg * 94871d7fec4Smrg * This routine sets the display controller vertical total to 94971d7fec4Smrg * "vtotal". As a side effect it also sets vertical blank end. 95071d7fec4Smrg * It should be used when only this value needs to be changed, 95171d7fec4Smrg * due to speed considerations. 95271d7fec4Smrg * 95371d7fec4Smrg * Note: it is the caller's responsibility to make sure that 95471d7fec4Smrg * a legal vtotal is used, i.e. that "vtotal" is greater than or 95571d7fec4Smrg * equal to vsync end. 95671d7fec4Smrg * 95771d7fec4Smrg * Always returns 0. 95871d7fec4Smrg *---------------------------------------------------------------------------- 95971d7fec4Smrg */ 96071d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 96171d7fec4Smrgint 96271d7fec4Smrggu1_set_vtotal(unsigned short vtotal) 96371d7fec4Smrg#else 96471d7fec4Smrgint 96571d7fec4Smrggfx_set_vtotal(unsigned short vtotal) 96671d7fec4Smrg#endif 96771d7fec4Smrg{ 96871d7fec4Smrg unsigned long unlock, tcfg, timing1, timing2; 96971d7fec4Smrg 97071d7fec4Smrg /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ 97171d7fec4Smrg 97271d7fec4Smrg unlock = READ_REG32(DC_UNLOCK); 97371d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 97471d7fec4Smrg 97571d7fec4Smrg /* READ THE CURRENT GX VALUES */ 97671d7fec4Smrg 97771d7fec4Smrg tcfg = READ_REG32(DC_TIMING_CFG); 97871d7fec4Smrg timing1 = READ_REG32(DC_V_TIMING_1); 97971d7fec4Smrg timing2 = READ_REG32(DC_V_TIMING_2); 98071d7fec4Smrg 98171d7fec4Smrg /* DISABLE THE TIMING GENERATOR */ 98271d7fec4Smrg 98371d7fec4Smrg WRITE_REG32(DC_TIMING_CFG, tcfg & ~(unsigned long)DC_TCFG_TGEN); 98471d7fec4Smrg 98571d7fec4Smrg /* WRITE NEW TIMING VALUES */ 98671d7fec4Smrg 98771d7fec4Smrg WRITE_REG32(DC_V_TIMING_1, 98871d7fec4Smrg (timing1 & 0xffff) | (unsigned long)(vtotal - 1) << 16); 98971d7fec4Smrg WRITE_REG32(DC_V_TIMING_2, 99071d7fec4Smrg (timing2 & 0xffff) | (unsigned long)(vtotal - 1) << 16); 99171d7fec4Smrg 99271d7fec4Smrg /* RESTORE GX VALUES */ 99371d7fec4Smrg 99471d7fec4Smrg WRITE_REG32(DC_TIMING_CFG, tcfg); 99571d7fec4Smrg WRITE_REG32(DC_UNLOCK, unlock); 99671d7fec4Smrg 99771d7fec4Smrg return (0); 99871d7fec4Smrg} 99971d7fec4Smrg 100071d7fec4Smrg/*--------------------------------------------------------------------------- 100171d7fec4Smrg * gfx_set_display_pitch 100271d7fec4Smrg * 100371d7fec4Smrg * This routine sets the pitch of the frame buffer to the specified value. 100471d7fec4Smrg *--------------------------------------------------------------------------- 100571d7fec4Smrg */ 100671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 100771d7fec4Smrgvoid 100871d7fec4Smrggu1_set_display_pitch(unsigned short pitch) 100971d7fec4Smrg#else 101071d7fec4Smrgvoid 101171d7fec4Smrggfx_set_display_pitch(unsigned short pitch) 101271d7fec4Smrg#endif 101371d7fec4Smrg{ 101471d7fec4Smrg unsigned long value = 0; 101571d7fec4Smrg unsigned long lock = READ_REG32(DC_UNLOCK); 101671d7fec4Smrg 101771d7fec4Smrg value = READ_REG32(DC_LINE_DELTA) & 0xFFFFF000; 101871d7fec4Smrg value |= (pitch >> 2); 101971d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 102071d7fec4Smrg WRITE_REG32(DC_LINE_DELTA, value); 102171d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 102271d7fec4Smrg 102371d7fec4Smrg /* ALSO UPDATE PITCH IN GRAPHICS ENGINE */ 102471d7fec4Smrg /* Pyramid alone supports 4K line pitch */ 102571d7fec4Smrg 102671d7fec4Smrg value = (unsigned long)READ_REG16(GP_BLIT_STATUS); 102771d7fec4Smrg value &= ~(BC_FB_WIDTH_2048 | BC_FB_WIDTH_4096); 102871d7fec4Smrg 102971d7fec4Smrg if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) 103071d7fec4Smrg value |= BC_FB_WIDTH_4096; 103171d7fec4Smrg 103271d7fec4Smrg else if (pitch > 1024) 103371d7fec4Smrg value |= BC_FB_WIDTH_2048; 103471d7fec4Smrg 103571d7fec4Smrg WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value); 103671d7fec4Smrg return; 103771d7fec4Smrg} 103871d7fec4Smrg 103971d7fec4Smrg/*--------------------------------------------------------------------------- 104071d7fec4Smrg * gfx_set_display_offset 104171d7fec4Smrg * 104271d7fec4Smrg * This routine sets the start address of the frame buffer. It is 104371d7fec4Smrg * typically used to pan across a virtual desktop (frame buffer larger than 104471d7fec4Smrg * the displayed screen) or to flip the display between multiple buffers. 104571d7fec4Smrg *--------------------------------------------------------------------------- 104671d7fec4Smrg */ 104771d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 104871d7fec4Smrgvoid 104971d7fec4Smrggu1_set_display_offset(unsigned long offset) 105071d7fec4Smrg#else 105171d7fec4Smrgvoid 105271d7fec4Smrggfx_set_display_offset(unsigned long offset) 105371d7fec4Smrg#endif 105471d7fec4Smrg{ 105571d7fec4Smrg /* UPDATE FRAME BUFFER OFFSET */ 105671d7fec4Smrg 105771d7fec4Smrg unsigned long lock; 105871d7fec4Smrg 105971d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 106071d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 106171d7fec4Smrg 106271d7fec4Smrg /* START ADDRESS EFFECTS DISPLAY COMPRESSION */ 106371d7fec4Smrg /* Disable compression for non-zero start addresss values. */ 106471d7fec4Smrg /* Enable compression if offset is zero and comression is intended to */ 106571d7fec4Smrg /* be enabled from a previous call to "gfx_set_compression_enable". */ 106671d7fec4Smrg /* Compression should be disabled BEFORE the offset is changed */ 106771d7fec4Smrg /* and enabled AFTER the offset is changed. */ 106871d7fec4Smrg 106971d7fec4Smrg if (offset == 0) { 107071d7fec4Smrg WRITE_REG32(DC_FB_ST_OFFSET, offset); 107171d7fec4Smrg if (gfx_compression_enabled) { 107271d7fec4Smrg /* WAIT FOR THE OFFSET TO BE LATCHED */ 107371d7fec4Smrg gfx_wait_vertical_blank(); 107471d7fec4Smrg gu1_enable_compression(); 107571d7fec4Smrg } 107671d7fec4Smrg } else { 107771d7fec4Smrg /* ONLY DISABLE COMPRESSION ONCE */ 107871d7fec4Smrg 107971d7fec4Smrg if (gfx_compression_active) 108071d7fec4Smrg gu1_disable_compression(); 108171d7fec4Smrg 108271d7fec4Smrg WRITE_REG32(DC_FB_ST_OFFSET, offset); 108371d7fec4Smrg } 108471d7fec4Smrg 108571d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 108671d7fec4Smrg} 108771d7fec4Smrg 108871d7fec4Smrg/*--------------------------------------------------------------------------- 108971d7fec4Smrg * gfx_set_display_palette_entry 109071d7fec4Smrg * 109171d7fec4Smrg * This routine sets an palette entry in the display controller. 109271d7fec4Smrg * A 32-bit X:R:G:B value. 109371d7fec4Smrg *--------------------------------------------------------------------------- 109471d7fec4Smrg */ 109571d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 109671d7fec4Smrgint 109771d7fec4Smrggu1_set_display_palette_entry(unsigned long index, unsigned long palette) 109871d7fec4Smrg#else 109971d7fec4Smrgint 110071d7fec4Smrggfx_set_display_palette_entry(unsigned long index, unsigned long palette) 110171d7fec4Smrg#endif 110271d7fec4Smrg{ 110371d7fec4Smrg unsigned long data; 110471d7fec4Smrg 110571d7fec4Smrg if (index > 0xFF) 110671d7fec4Smrg return GFX_STATUS_BAD_PARAMETER; 110771d7fec4Smrg 110871d7fec4Smrg WRITE_REG32(DC_PAL_ADDRESS, index); 110971d7fec4Smrg data = ((palette >> 2) & 0x0003F) | 111071d7fec4Smrg ((palette >> 4) & 0x00FC0) | ((palette >> 6) & 0x3F000); 111171d7fec4Smrg WRITE_REG32(DC_PAL_DATA, data); 111271d7fec4Smrg 111371d7fec4Smrg return (0); 111471d7fec4Smrg} 111571d7fec4Smrg 111671d7fec4Smrg/*--------------------------------------------------------------------------- 111771d7fec4Smrg * gfx_set_display_palette 111871d7fec4Smrg * 111971d7fec4Smrg * This routine sets the entire palette in the display controller. 112071d7fec4Smrg * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values. 112171d7fec4Smrg * Restriction: 112271d7fec4Smrg * Due to SC1200 Issue #748 (in Notes DB) this function should be called only 112371d7fec4Smrg * when DCLK is active, i.e PLL is already powered up and genlock is not active. 112471d7fec4Smrg *--------------------------------------------------------------------------- 112571d7fec4Smrg */ 112671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 112771d7fec4Smrgint 112871d7fec4Smrggu1_set_display_palette(unsigned long *palette) 112971d7fec4Smrg#else 113071d7fec4Smrgint 113171d7fec4Smrggfx_set_display_palette(unsigned long *palette) 113271d7fec4Smrg#endif 113371d7fec4Smrg{ 113471d7fec4Smrg unsigned long data, i; 113571d7fec4Smrg 113671d7fec4Smrg WRITE_REG32(DC_PAL_ADDRESS, 0); 113771d7fec4Smrg if (palette) { 113871d7fec4Smrg for (i = 0; i < 256; i++) { 113971d7fec4Smrg /* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */ 114071d7fec4Smrg 114171d7fec4Smrg data = ((palette[i] >> 2) & 0x0003F) | 114271d7fec4Smrg ((palette[i] >> 4) & 0x00FC0) | ((palette[i] >> 6) & 0x3F000); 114371d7fec4Smrg WRITE_REG32(DC_PAL_DATA, data); 114471d7fec4Smrg } 114571d7fec4Smrg } 114671d7fec4Smrg return (0); 114771d7fec4Smrg} 114871d7fec4Smrg 114971d7fec4Smrg/*--------------------------------------------------------------------------- 115071d7fec4Smrg * gfx_set_cursor_enable 115171d7fec4Smrg * 115271d7fec4Smrg * This routine enables or disables the hardware cursor. 115371d7fec4Smrg * 115471d7fec4Smrg * WARNING: The cusrsor start offset must be set by setting the cursor 115571d7fec4Smrg * position before calling this routine to assure that memory reads do not 115671d7fec4Smrg * go past the end of graphics memory (this can hang GXm). 115771d7fec4Smrg *--------------------------------------------------------------------------- 115871d7fec4Smrg */ 115971d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 116071d7fec4Smrgvoid 116171d7fec4Smrggu1_set_cursor_enable(int enable) 116271d7fec4Smrg#else 116371d7fec4Smrgvoid 116471d7fec4Smrggfx_set_cursor_enable(int enable) 116571d7fec4Smrg#endif 116671d7fec4Smrg{ 116771d7fec4Smrg unsigned long unlock, gcfg; 116871d7fec4Smrg 116971d7fec4Smrg /* SET OR CLEAR CURSOR ENABLE BIT */ 117071d7fec4Smrg 117171d7fec4Smrg unlock = READ_REG32(DC_UNLOCK); 117271d7fec4Smrg gcfg = READ_REG32(DC_GENERAL_CFG); 117371d7fec4Smrg if (enable) 117471d7fec4Smrg gcfg |= DC_GCFG_CURE; 117571d7fec4Smrg else 117671d7fec4Smrg gcfg &= ~(DC_GCFG_CURE); 117771d7fec4Smrg 117871d7fec4Smrg /* WRITE NEW REGISTER VALUE */ 117971d7fec4Smrg 118071d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 118171d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 118271d7fec4Smrg WRITE_REG32(DC_UNLOCK, unlock); 118371d7fec4Smrg} 118471d7fec4Smrg 118571d7fec4Smrg/*--------------------------------------------------------------------------- 118671d7fec4Smrg * gfx_set_cursor_colors 118771d7fec4Smrg * 118871d7fec4Smrg * This routine sets the colors of the hardware cursor. 118971d7fec4Smrg * Restriction: 119071d7fec4Smrg * Due to SC1200 Issue #748 (in Notes DB) this function should be called only 119171d7fec4Smrg * when DCLK is active, i.e PLL is already powered up. 119271d7fec4Smrg *--------------------------------------------------------------------------- 119371d7fec4Smrg */ 119471d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 119571d7fec4Smrgvoid 119671d7fec4Smrggu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) 119771d7fec4Smrg#else 119871d7fec4Smrgvoid 119971d7fec4Smrggfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) 120071d7fec4Smrg#endif 120171d7fec4Smrg{ 120271d7fec4Smrg unsigned long value; 120371d7fec4Smrg 120471d7fec4Smrg /* If genlock is enabled DCLK might be disabled in vertical blank. */ 120571d7fec4Smrg /* Due to SC1200 Issue #748 in Notes DB this would fail the cursor color settings */ 120671d7fec4Smrg /* So Wait for vertical blank to end */ 120771d7fec4Smrg 120871d7fec4Smrg#if GFX_VIDEO_SC1200 120971d7fec4Smrg if (gfx_test_timing_active()) 121071d7fec4Smrg while ((gfx_get_vline()) > gfx_get_vactive()) ; 121171d7fec4Smrg#endif 121271d7fec4Smrg 121371d7fec4Smrg /* SET CURSOR COLORS */ 121471d7fec4Smrg 121571d7fec4Smrg WRITE_REG32(DC_PAL_ADDRESS, 0x100); 121671d7fec4Smrg value = ((bkcolor & 0x000000FC) >> 2) | 121771d7fec4Smrg ((bkcolor & 0x0000FC00) >> (2 + 8 - 6)) | 121871d7fec4Smrg ((bkcolor & 0x00FC0000) >> (2 + 16 - 12)); 121971d7fec4Smrg WRITE_REG32(DC_PAL_DATA, value); 122071d7fec4Smrg value = ((fgcolor & 0x000000FC) >> 2) | 122171d7fec4Smrg ((fgcolor & 0x0000FC00) >> (2 + 8 - 6)) | 122271d7fec4Smrg ((fgcolor & 0x00FC0000) >> (2 + 16 - 12)); 122371d7fec4Smrg WRITE_REG32(DC_PAL_DATA, value); 122471d7fec4Smrg} 122571d7fec4Smrg 122671d7fec4Smrg/*--------------------------------------------------------------------------- 122771d7fec4Smrg * gfx_set_cursor_position 122871d7fec4Smrg * 122971d7fec4Smrg * This routine sets the position of the hardware cusror. The starting 123071d7fec4Smrg * offset of the cursor buffer must be specified so that the routine can 123171d7fec4Smrg * properly clip scanlines if the cursor is off the top of the screen. 123271d7fec4Smrg *--------------------------------------------------------------------------- 123371d7fec4Smrg */ 123471d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 123571d7fec4Smrgvoid 123671d7fec4Smrggu1_set_cursor_position(unsigned long memoffset, 123771d7fec4Smrg unsigned short xpos, unsigned short ypos, 123871d7fec4Smrg unsigned short xhotspot, unsigned short yhotspot) 123971d7fec4Smrg#else 124071d7fec4Smrgvoid 124171d7fec4Smrggfx_set_cursor_position(unsigned long memoffset, 124271d7fec4Smrg unsigned short xpos, unsigned short ypos, 124371d7fec4Smrg unsigned short xhotspot, unsigned short yhotspot) 124471d7fec4Smrg#endif 124571d7fec4Smrg{ 124671d7fec4Smrg unsigned long unlock; 124771d7fec4Smrg 124871d7fec4Smrg short x, y; 124971d7fec4Smrg short xoffset = 0; 125071d7fec4Smrg short yoffset = 0; 125171d7fec4Smrg 125271d7fec4Smrg /* SUPPORT CURSOR IN EMULATED VGA MODES */ 125371d7fec4Smrg /* Timings are for twice the resolution */ 125471d7fec4Smrg 125571d7fec4Smrg if (gfx_pixel_double) 125671d7fec4Smrg xpos <<= 1; 125771d7fec4Smrg if (gfx_line_double) 125871d7fec4Smrg ypos <<= 1; 125971d7fec4Smrg 126071d7fec4Smrg x = (short)xpos - (short)xhotspot; 126171d7fec4Smrg y = (short)ypos - (short)yhotspot; 126271d7fec4Smrg if (x < -31) 126371d7fec4Smrg return; 126471d7fec4Smrg if (y < -31) 126571d7fec4Smrg return; 126671d7fec4Smrg if (x < 0) { 126771d7fec4Smrg xoffset = -x; 126871d7fec4Smrg x = 0; 126971d7fec4Smrg } 127071d7fec4Smrg if (y < 0) { 127171d7fec4Smrg yoffset = -y; 127271d7fec4Smrg y = 0; 127371d7fec4Smrg } 127471d7fec4Smrg memoffset += (unsigned long)yoffset << 3; 127571d7fec4Smrg 127671d7fec4Smrg if (PanelEnable) { 127771d7fec4Smrg if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) { 127871d7fec4Smrg gfx_enable_panning(xpos, ypos); 127971d7fec4Smrg x = x - (short)panelLeft; 128071d7fec4Smrg y = y - (short)panelTop; 128171d7fec4Smrg } 128271d7fec4Smrg } 128371d7fec4Smrg 128471d7fec4Smrg /* SET CURSOR POSITION */ 128571d7fec4Smrg 128671d7fec4Smrg unlock = READ_REG32(DC_UNLOCK); 128771d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 128871d7fec4Smrg WRITE_REG32(DC_CURS_ST_OFFSET, memoffset); 128971d7fec4Smrg WRITE_REG32(DC_CURSOR_X, (unsigned long)x | 129071d7fec4Smrg (((unsigned long)xoffset) << 11)); 129171d7fec4Smrg WRITE_REG32(DC_CURSOR_Y, (unsigned long)y | 129271d7fec4Smrg (((unsigned long)yoffset) << 11)); 129371d7fec4Smrg WRITE_REG32(DC_UNLOCK, unlock); 129471d7fec4Smrg} 129571d7fec4Smrg 129671d7fec4Smrg/*--------------------------------------------------------------------------- 129771d7fec4Smrg * gfx_set_cursor_shape32 129871d7fec4Smrg * 129971d7fec4Smrg * This routine loads 32x32 cursor data into the specified location in 130071d7fec4Smrg * graphics memory. 130171d7fec4Smrg *--------------------------------------------------------------------------- 130271d7fec4Smrg */ 130371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 130471d7fec4Smrgvoid 130571d7fec4Smrggu1_set_cursor_shape32(unsigned long memoffset, 130671d7fec4Smrg unsigned long *andmask, unsigned long *xormask) 130771d7fec4Smrg#else 130871d7fec4Smrgvoid 130971d7fec4Smrggfx_set_cursor_shape32(unsigned long memoffset, 131071d7fec4Smrg unsigned long *andmask, unsigned long *xormask) 131171d7fec4Smrg#endif 131271d7fec4Smrg{ 131371d7fec4Smrg int i; 131471d7fec4Smrg unsigned long value; 131571d7fec4Smrg 131671d7fec4Smrg for (i = 0; i < 32; i++) { 131771d7fec4Smrg /* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */ 131871d7fec4Smrg 131971d7fec4Smrg value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16); 132071d7fec4Smrg WRITE_FB32(memoffset, value); 132171d7fec4Smrg memoffset += 4; 132271d7fec4Smrg value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF); 132371d7fec4Smrg WRITE_FB32(memoffset, value); 132471d7fec4Smrg memoffset += 4; 132571d7fec4Smrg } 132671d7fec4Smrg} 132771d7fec4Smrg 132871d7fec4Smrg/*--------------------------------------------------------------------------- 132971d7fec4Smrg * gu1_enable_compression 133071d7fec4Smrg * 133171d7fec4Smrg * This is a private routine to this module (not exposed in the Durango API). 133271d7fec4Smrg * It enables display compression. 133371d7fec4Smrg *--------------------------------------------------------------------------- 133471d7fec4Smrg */ 133571d7fec4Smrgvoid 133671d7fec4Smrggu1_enable_compression(void) 133771d7fec4Smrg{ 133871d7fec4Smrg int i; 133971d7fec4Smrg unsigned long unlock, gcfg, offset; 134071d7fec4Smrg 134171d7fec4Smrg /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */ 134271d7fec4Smrg 134371d7fec4Smrg offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF; 134471d7fec4Smrg if (offset != 0) 134571d7fec4Smrg return; 134671d7fec4Smrg 134771d7fec4Smrg /* DO NOT ENABLE IF WE ARE WITHIN AN EMULATED VGA MODE */ 134871d7fec4Smrg 134971d7fec4Smrg if (gfx_line_double || gfx_pixel_double) 135071d7fec4Smrg return; 135171d7fec4Smrg 135271d7fec4Smrg /* SET GLOBAL INDICATOR */ 135371d7fec4Smrg 135471d7fec4Smrg gfx_compression_active = 1; 135571d7fec4Smrg 135671d7fec4Smrg /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */ 135771d7fec4Smrg /* Software is required to do this before enabling compression. */ 135871d7fec4Smrg /* Don't want controller to think that old lines are still valid. */ 135971d7fec4Smrg 136071d7fec4Smrg for (i = 0; i < 1024; i++) { 136171d7fec4Smrg WRITE_REG32(MC_DR_ADD, i); 136271d7fec4Smrg WRITE_REG32(MC_DR_ACC, 0); 136371d7fec4Smrg } 136471d7fec4Smrg 136571d7fec4Smrg /* TURN ON COMPRESSION CONTROL BITS */ 136671d7fec4Smrg 136771d7fec4Smrg unlock = READ_REG32(DC_UNLOCK); 136871d7fec4Smrg gcfg = READ_REG32(DC_GENERAL_CFG); 136971d7fec4Smrg gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE; 137071d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 137171d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 137271d7fec4Smrg WRITE_REG32(DC_UNLOCK, unlock); 137371d7fec4Smrg} 137471d7fec4Smrg 137571d7fec4Smrg/*--------------------------------------------------------------------------- 137671d7fec4Smrg * gu1_disable_compression 137771d7fec4Smrg * 137871d7fec4Smrg * This is a private routine to this module (not exposed in the Durango API). 137971d7fec4Smrg * It disables display compression. 138071d7fec4Smrg *--------------------------------------------------------------------------- 138171d7fec4Smrg */ 138271d7fec4Smrgvoid 138371d7fec4Smrggu1_disable_compression(void) 138471d7fec4Smrg{ 138571d7fec4Smrg unsigned long unlock, gcfg; 138671d7fec4Smrg 138771d7fec4Smrg /* SET GLOBAL INDICATOR */ 138871d7fec4Smrg 138971d7fec4Smrg gfx_compression_active = 0; 139071d7fec4Smrg 139171d7fec4Smrg /* TURN OFF COMPRESSION CONTROL BITS */ 139271d7fec4Smrg 139371d7fec4Smrg unlock = READ_REG32(DC_UNLOCK); 139471d7fec4Smrg gcfg = READ_REG32(DC_GENERAL_CFG); 139571d7fec4Smrg gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE); 139671d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 139771d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 139871d7fec4Smrg WRITE_REG32(DC_UNLOCK, unlock); 139971d7fec4Smrg} 140071d7fec4Smrg 140171d7fec4Smrg/*--------------------------------------------------------------------------- 140271d7fec4Smrg * gfx_set_compression_enable 140371d7fec4Smrg * 140471d7fec4Smrg * This routine enables or disables display compression. 140571d7fec4Smrg *--------------------------------------------------------------------------- 140671d7fec4Smrg */ 140771d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 140871d7fec4Smrgint 140971d7fec4Smrggu1_set_compression_enable(int enable) 141071d7fec4Smrg#else 141171d7fec4Smrgint 141271d7fec4Smrggfx_set_compression_enable(int enable) 141371d7fec4Smrg#endif 141471d7fec4Smrg{ 141571d7fec4Smrg /* SET GLOBAL VARIABLE FOR INTENDED STATE */ 141671d7fec4Smrg /* Compression can only be enabled for non-zero start address values. */ 141771d7fec4Smrg /* Keep state to enable compression on start address changes. */ 141871d7fec4Smrg 141971d7fec4Smrg gfx_compression_enabled = enable; 142071d7fec4Smrg if (enable) 142171d7fec4Smrg gu1_enable_compression(); 142271d7fec4Smrg else 142371d7fec4Smrg gu1_disable_compression(); 142471d7fec4Smrg return (0); 142571d7fec4Smrg} 142671d7fec4Smrg 142771d7fec4Smrg/*--------------------------------------------------------------------------- 142871d7fec4Smrg * gfx_set_compression_offset 142971d7fec4Smrg * 143071d7fec4Smrg * This routine sets the base offset for the compression buffer. 143171d7fec4Smrg *--------------------------------------------------------------------------- 143271d7fec4Smrg */ 143371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 143471d7fec4Smrgint 143571d7fec4Smrggu1_set_compression_offset(unsigned long offset) 143671d7fec4Smrg#else 143771d7fec4Smrgint 143871d7fec4Smrggfx_set_compression_offset(unsigned long offset) 143971d7fec4Smrg#endif 144071d7fec4Smrg{ 144171d7fec4Smrg unsigned long lock; 144271d7fec4Smrg 144371d7fec4Smrg /* MUST BE 16-BYTE ALIGNED FOR GXLV */ 144471d7fec4Smrg 144571d7fec4Smrg if (offset & 0x0F) 144671d7fec4Smrg return (1); 144771d7fec4Smrg 144871d7fec4Smrg /* SET REGISTER VALUE */ 144971d7fec4Smrg 145071d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 145171d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 145271d7fec4Smrg WRITE_REG32(DC_CB_ST_OFFSET, offset); 145371d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 145471d7fec4Smrg return (0); 145571d7fec4Smrg} 145671d7fec4Smrg 145771d7fec4Smrg/*--------------------------------------------------------------------------- 145871d7fec4Smrg * gfx_set_compression_pitch 145971d7fec4Smrg * 146071d7fec4Smrg * This routine sets the pitch, in bytes, of the compression buffer. 146171d7fec4Smrg *--------------------------------------------------------------------------- 146271d7fec4Smrg */ 146371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 146471d7fec4Smrgint 146571d7fec4Smrggu1_set_compression_pitch(unsigned short pitch) 146671d7fec4Smrg#else 146771d7fec4Smrgint 146871d7fec4Smrggfx_set_compression_pitch(unsigned short pitch) 146971d7fec4Smrg#endif 147071d7fec4Smrg{ 147171d7fec4Smrg unsigned long lock, line_delta; 147271d7fec4Smrg 147371d7fec4Smrg /* SET REGISTER VALUE */ 147471d7fec4Smrg 147571d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 147671d7fec4Smrg line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF; 147771d7fec4Smrg line_delta |= ((unsigned long)pitch << 10l) & 0x007FF000; 147871d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 147971d7fec4Smrg WRITE_REG32(DC_LINE_DELTA, line_delta); 148071d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 148171d7fec4Smrg return (0); 148271d7fec4Smrg} 148371d7fec4Smrg 148471d7fec4Smrg/*--------------------------------------------------------------------------- 148571d7fec4Smrg * gfx_set_compression_size 148671d7fec4Smrg * 148771d7fec4Smrg * This routine sets the line size of the compression buffer, which is the 148871d7fec4Smrg * maximum number of bytes allowed to store a compressed line. 148971d7fec4Smrg *--------------------------------------------------------------------------- 149071d7fec4Smrg */ 149171d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 149271d7fec4Smrgint 149371d7fec4Smrggu1_set_compression_size(unsigned short size) 149471d7fec4Smrg#else 149571d7fec4Smrgint 149671d7fec4Smrggfx_set_compression_size(unsigned short size) 149771d7fec4Smrg#endif 149871d7fec4Smrg{ 149971d7fec4Smrg unsigned long lock, buf_size; 150071d7fec4Smrg 150171d7fec4Smrg /* SUBTRACT 16 FROM SIZE */ 150271d7fec4Smrg /* The display controller will actually write */ 150371d7fec4Smrg /* 2 extra QWords. So, if we assume that "size" */ 150471d7fec4Smrg /* refers to the allocated size, we must subtract */ 150571d7fec4Smrg /* 16 bytes. */ 150671d7fec4Smrg 150771d7fec4Smrg size -= 16; 150871d7fec4Smrg 150971d7fec4Smrg /* SET REGISTER VALUE */ 151071d7fec4Smrg 151171d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 151271d7fec4Smrg buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF; 151371d7fec4Smrg buf_size |= (((size >> 2) + 1) & 0x7F) << 9; 151471d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 151571d7fec4Smrg WRITE_REG32(DC_BUF_SIZE, buf_size); 151671d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 151771d7fec4Smrg return (0); 151871d7fec4Smrg} 151971d7fec4Smrg 152071d7fec4Smrg/*--------------------------------------------------------------------------- 152171d7fec4Smrg * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API) 152271d7fec4Smrg * 152371d7fec4Smrg * This routine enables/disables video on GX. 152471d7fec4Smrg *--------------------------------------------------------------------------- 152571d7fec4Smrg */ 152671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 152771d7fec4Smrgvoid 152871d7fec4Smrggu1_set_display_video_enable(int enable) 152971d7fec4Smrg#else 153071d7fec4Smrgvoid 153171d7fec4Smrggfx_set_display_video_enable(int enable) 153271d7fec4Smrg#endif 153371d7fec4Smrg{ 153471d7fec4Smrg unsigned long lock, gcfg, buf_size; 153571d7fec4Smrg 153671d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 153771d7fec4Smrg gcfg = READ_REG32(DC_GENERAL_CFG); 153871d7fec4Smrg buf_size = READ_REG32(DC_BUF_SIZE); 153971d7fec4Smrg 154071d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 154171d7fec4Smrg 154271d7fec4Smrg vid_enabled = enable; 154371d7fec4Smrg 154471d7fec4Smrg /* SET THE BUFFER SIZE TO A NON-ZERO VALUE ONLY WHEN */ 154571d7fec4Smrg /* ENABLING VIDEO */ 154671d7fec4Smrg 154771d7fec4Smrg if (enable) { 154871d7fec4Smrg gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY); 154971d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 155071d7fec4Smrg 155171d7fec4Smrg WRITE_REG32(DC_BUF_SIZE, (buf_size & 0x0000FFFFl) | vid_buf_size); 155271d7fec4Smrg } 155371d7fec4Smrg 155471d7fec4Smrg /* CLEAR THE VIDEO BUFFER SIZE WHEN DISABLING VIDEO */ 155571d7fec4Smrg 155671d7fec4Smrg else { 155771d7fec4Smrg gcfg &= ~(DC_GCFG_VIDE); 155871d7fec4Smrg WRITE_REG32(DC_GENERAL_CFG, gcfg); 155971d7fec4Smrg 156071d7fec4Smrg vid_buf_size = buf_size & 0xFFFF0000l; 156171d7fec4Smrg WRITE_REG32(DC_BUF_SIZE, buf_size & 0x0000FFFFl); 156271d7fec4Smrg } 156371d7fec4Smrg 156471d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 156571d7fec4Smrg return; 156671d7fec4Smrg} 156771d7fec4Smrg 156871d7fec4Smrg/*--------------------------------------------------------------------------- 156971d7fec4Smrg * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API) 157071d7fec4Smrg * 157171d7fec4Smrg * This routine is called by "gfx_set_video_size". It abstracts the 157271d7fec4Smrg * version of the display controller from the video overlay routines. 157371d7fec4Smrg *--------------------------------------------------------------------------- 157471d7fec4Smrg */ 157571d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 157671d7fec4Smrgvoid 157771d7fec4Smrggu1_set_display_video_size(unsigned short width, unsigned short height) 157871d7fec4Smrg#else 157971d7fec4Smrgvoid 158071d7fec4Smrggfx_set_display_video_size(unsigned short width, unsigned short height) 158171d7fec4Smrg#endif 158271d7fec4Smrg{ 158371d7fec4Smrg unsigned long lock, size, value; 158471d7fec4Smrg 158571d7fec4Smrg size = (unsigned long)(width << 1) * (unsigned long)height; 158671d7fec4Smrg 158771d7fec4Smrg /* STORE THE VIDEO BUFFER SIZE AS A GLOBAL */ 158871d7fec4Smrg 158971d7fec4Smrg vid_buf_size = ((size + 63) >> 6) << 16; 159071d7fec4Smrg 159171d7fec4Smrg /* DO NOT SET THE VIDEO SIZE IF VIDEO IS DISABLED */ 159271d7fec4Smrg 159371d7fec4Smrg if (!vid_enabled) 159471d7fec4Smrg return; 159571d7fec4Smrg 159671d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 159771d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 159871d7fec4Smrg value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF; 159971d7fec4Smrg value |= vid_buf_size; 160071d7fec4Smrg WRITE_REG32(DC_BUF_SIZE, value); 160171d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 160271d7fec4Smrg} 160371d7fec4Smrg 160471d7fec4Smrg/*--------------------------------------------------------------------------- 160571d7fec4Smrg * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) 160671d7fec4Smrg * 160771d7fec4Smrg * This routine is called by "gfx_set_video_offset". It abstracts the 160871d7fec4Smrg * version of the display controller from the video overlay routines. 160971d7fec4Smrg *--------------------------------------------------------------------------- 161071d7fec4Smrg */ 161171d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 161271d7fec4Smrgvoid 161371d7fec4Smrggu1_set_display_video_offset(unsigned long offset) 161471d7fec4Smrg#else 161571d7fec4Smrgvoid 161671d7fec4Smrggfx_set_display_video_offset(unsigned long offset) 161771d7fec4Smrg#endif 161871d7fec4Smrg{ 161971d7fec4Smrg unsigned long lock; 162071d7fec4Smrg 162171d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 162271d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 162371d7fec4Smrg offset &= 0x003FFFFF; 162471d7fec4Smrg WRITE_REG32(DC_VID_ST_OFFSET, offset); 162571d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 162671d7fec4Smrg} 162771d7fec4Smrg 162871d7fec4Smrg/*--------------------------------------------------------------------------- 162971d7fec4Smrg * gfx_set_display_priority_high 163071d7fec4Smrg * 163171d7fec4Smrg * This routine controls the x-bus round robin arbitration mechanism. 163271d7fec4Smrg * When enable is TRUE, graphics pipeline requests and non-critical display 163371d7fec4Smrg * controller requests are arbitrated at the same priority as processor 163471d7fec4Smrg * requests. When FALSE processor requests are arbitrated at a higher priority. 163571d7fec4Smrg *--------------------------------------------------------------------------- 163671d7fec4Smrg */ 163771d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 163871d7fec4Smrgvoid 163971d7fec4Smrggu1_set_display_priority_high(int enable) 164071d7fec4Smrg#else 164171d7fec4Smrgvoid 164271d7fec4Smrggfx_set_display_priority_high(int enable) 164371d7fec4Smrg#endif 164471d7fec4Smrg{ 164571d7fec4Smrg unsigned long lock, control; 164671d7fec4Smrg 164771d7fec4Smrg lock = READ_REG32(DC_UNLOCK); 164871d7fec4Smrg control = READ_REG32(MC_MEM_CNTRL1); 164971d7fec4Smrg WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 165071d7fec4Smrg if (enable) 165171d7fec4Smrg control |= MC_XBUSARB; 165271d7fec4Smrg else 165371d7fec4Smrg control &= ~(MC_XBUSARB); 165471d7fec4Smrg WRITE_REG32(MC_MEM_CNTRL1, control); 165571d7fec4Smrg WRITE_REG32(DC_UNLOCK, lock); 165671d7fec4Smrg return; 165771d7fec4Smrg} 165871d7fec4Smrg 165971d7fec4Smrg/*--------------------------------------------------------------------------- 166071d7fec4Smrg * gfx_test_timing_active 166171d7fec4Smrg *--------------------------------------------------------------------------- 166271d7fec4Smrg */ 166371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 166471d7fec4Smrgint 166571d7fec4Smrggu1_test_timing_active(void) 166671d7fec4Smrg#else 166771d7fec4Smrgint 166871d7fec4Smrggfx_test_timing_active(void) 166971d7fec4Smrg#endif 167071d7fec4Smrg{ 167171d7fec4Smrg if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN) 167271d7fec4Smrg return (1); 167371d7fec4Smrg else 167471d7fec4Smrg return (0); 167571d7fec4Smrg} 167671d7fec4Smrg 167771d7fec4Smrg/*--------------------------------------------------------------------------- 167871d7fec4Smrg * gfx_test_vertical_active 167971d7fec4Smrg *--------------------------------------------------------------------------- 168071d7fec4Smrg */ 168171d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 168271d7fec4Smrgint 168371d7fec4Smrggu1_test_vertical_active(void) 168471d7fec4Smrg#else 168571d7fec4Smrgint 168671d7fec4Smrggfx_test_vertical_active(void) 168771d7fec4Smrg#endif 168871d7fec4Smrg{ 168971d7fec4Smrg if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_VNA) 169071d7fec4Smrg return (0); 169171d7fec4Smrg else 169271d7fec4Smrg return (1); 169371d7fec4Smrg} 169471d7fec4Smrg 169571d7fec4Smrg/*--------------------------------------------------------------------------- 169671d7fec4Smrg * gfx_wait_vertical_blank 169771d7fec4Smrg *--------------------------------------------------------------------------- 169871d7fec4Smrg */ 169971d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 170071d7fec4Smrgint 170171d7fec4Smrggu1_wait_vertical_blank(void) 170271d7fec4Smrg#else 170371d7fec4Smrgint 170471d7fec4Smrggfx_wait_vertical_blank(void) 170571d7fec4Smrg#endif 170671d7fec4Smrg{ 170771d7fec4Smrg if (gfx_test_timing_active()) { 170871d7fec4Smrg while (!gfx_test_vertical_active()) ; 170971d7fec4Smrg while (gfx_test_vertical_active()) ; 171071d7fec4Smrg } 171171d7fec4Smrg return (0); 171271d7fec4Smrg} 171371d7fec4Smrg 171471d7fec4Smrg/*--------------------------------------------------------------------------- 171571d7fec4Smrg * gfx_enable_panning 171671d7fec4Smrg * 171771d7fec4Smrg * This routine enables the panning when the Mode is bigger than the panel 171871d7fec4Smrg * size. 171971d7fec4Smrg *--------------------------------------------------------------------------- 172071d7fec4Smrg */ 172171d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 172271d7fec4Smrgvoid 172371d7fec4Smrggu1_enable_panning(int x, int y) 172471d7fec4Smrg#else 172571d7fec4Smrgvoid 172671d7fec4Smrggfx_enable_panning(int x, int y) 172771d7fec4Smrg#endif 172871d7fec4Smrg{ 172971d7fec4Smrg unsigned long modeBytesPerPixel; 173071d7fec4Smrg unsigned long modeBytesPerScanline = 0; 173171d7fec4Smrg unsigned long startAddress = 0; 173271d7fec4Smrg 173371d7fec4Smrg modeBytesPerPixel = (gbpp + 7) / 8; 173471d7fec4Smrg modeBytesPerScanline = 173571d7fec4Smrg (((ModeWidth + 1023) / 1024) * 1024) * modeBytesPerPixel; 173671d7fec4Smrg 173771d7fec4Smrg /* TEST FOR NO-WORK */ 173871d7fec4Smrg 173971d7fec4Smrg if (x >= DeltaX && (unsigned short)x < (PanelWidth + DeltaX) && 174071d7fec4Smrg y >= DeltaY && (unsigned short)y < (PanelHeight + DeltaY)) 174171d7fec4Smrg return; 174271d7fec4Smrg 174371d7fec4Smrg /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */ 174471d7fec4Smrg /* Test the boundary conditions for each coordinate and update */ 174571d7fec4Smrg /* all variables and the starting offset accordingly. */ 174671d7fec4Smrg 174771d7fec4Smrg if (x < DeltaX) 174871d7fec4Smrg DeltaX = x; 174971d7fec4Smrg 175071d7fec4Smrg else if ((unsigned short)x >= (DeltaX + PanelWidth)) 175171d7fec4Smrg DeltaX = x - PanelWidth + 1; 175271d7fec4Smrg 175371d7fec4Smrg if (y < DeltaY) 175471d7fec4Smrg DeltaY = y; 175571d7fec4Smrg 175671d7fec4Smrg else if ((unsigned short)y >= (DeltaY + PanelHeight)) 175771d7fec4Smrg DeltaY = y - PanelHeight + 1; 175871d7fec4Smrg 175971d7fec4Smrg /* CALCULATE THE START OFFSET */ 176071d7fec4Smrg 176171d7fec4Smrg startAddress = 176271d7fec4Smrg (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline); 176371d7fec4Smrg 176471d7fec4Smrg gfx_set_display_offset(startAddress); 176571d7fec4Smrg 176671d7fec4Smrg /* SET PANEL COORDINATES */ 176771d7fec4Smrg /* Panel's x position must be DWORD aligned */ 176871d7fec4Smrg 176971d7fec4Smrg panelTop = DeltaY; 177071d7fec4Smrg panelLeft = DeltaX * modeBytesPerPixel; 177171d7fec4Smrg 177271d7fec4Smrg if (panelLeft & 3) 177371d7fec4Smrg panelLeft = (panelLeft & 0xFFFFFFFC) + 4; 177471d7fec4Smrg 177571d7fec4Smrg panelLeft /= modeBytesPerPixel; 177671d7fec4Smrg 177771d7fec4Smrg} 177871d7fec4Smrg 177971d7fec4Smrg/*--------------------------------------------------------------------------- 178071d7fec4Smrg * gfx_set_fixed_timings 178171d7fec4Smrg *--------------------------------------------------------------------------- 178271d7fec4Smrg */ 178371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 178471d7fec4Smrgint 178571d7fec4Smrggu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width, 178671d7fec4Smrg unsigned short height, unsigned short bpp) 178771d7fec4Smrg#else 178871d7fec4Smrgint 178971d7fec4Smrggfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width, 179071d7fec4Smrg unsigned short height, unsigned short bpp) 179171d7fec4Smrg#endif 179271d7fec4Smrg{ 179371d7fec4Smrg unsigned int mode; 179471d7fec4Smrg 179571d7fec4Smrg ModeWidth = width; 179671d7fec4Smrg ModeHeight = height; 179771d7fec4Smrg PanelWidth = (unsigned short)panelResX; 179871d7fec4Smrg PanelHeight = (unsigned short)panelResY; 179971d7fec4Smrg PanelEnable = 1; 180071d7fec4Smrg 180171d7fec4Smrg /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ 180271d7fec4Smrg for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) { 180371d7fec4Smrg if ((FixedParams[mode].xres == width) && 180471d7fec4Smrg (FixedParams[mode].yres == height) && 180571d7fec4Smrg (FixedParams[mode].panelresx == panelResX) && 180671d7fec4Smrg (FixedParams[mode].panelresy == panelResY)) { 180771d7fec4Smrg 180871d7fec4Smrg /* SET THE 92xx FOR THE SELECTED MODE */ 180971d7fec4Smrg FIXEDTIMINGS *fmode = &FixedParams[mode]; 181071d7fec4Smrg 181171d7fec4Smrg gfx_set_display_timings(bpp, 3, fmode->hactive, fmode->hblankstart, 181271d7fec4Smrg fmode->hsyncstart, fmode->hsyncend, 181371d7fec4Smrg fmode->hblankend, fmode->htotal, 181471d7fec4Smrg fmode->vactive, fmode->vblankstart, 181571d7fec4Smrg fmode->vsyncstart, fmode->vsyncend, 181671d7fec4Smrg fmode->vblankend, fmode->vtotal, 181771d7fec4Smrg fmode->frequency); 181871d7fec4Smrg 181971d7fec4Smrg return (1); 182071d7fec4Smrg } /* end if() */ 182171d7fec4Smrg } /* end for() */ 182271d7fec4Smrg 182371d7fec4Smrg return (-1); 182471d7fec4Smrg} 182571d7fec4Smrg 182671d7fec4Smrg/*--------------------------------------------------------------------------- 182771d7fec4Smrg * gfx_set_panel_present 182871d7fec4Smrg *--------------------------------------------------------------------------- 182971d7fec4Smrg */ 183071d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 183171d7fec4Smrgint 183271d7fec4Smrggu1_set_panel_present(int panelResX, int panelResY, unsigned short width, 183371d7fec4Smrg unsigned short height, unsigned short bpp) 183471d7fec4Smrg#else 183571d7fec4Smrgint 183671d7fec4Smrggfx_set_panel_present(int panelResX, int panelResY, unsigned short width, 183771d7fec4Smrg unsigned short height, unsigned short bpp) 183871d7fec4Smrg#endif 183971d7fec4Smrg{ 184071d7fec4Smrg /* SET VALID BPP */ 184171d7fec4Smrg /* 16BPP is the default. */ 184271d7fec4Smrg 184371d7fec4Smrg if (bpp != 8 && bpp != 15 && bpp != 16) 184471d7fec4Smrg bpp = 16; 184571d7fec4Smrg 184671d7fec4Smrg /* RECORD PANEL PARAMETERS */ 184771d7fec4Smrg /* This routine does not touch any panel timings. It is used when custom panel */ 184871d7fec4Smrg /* settings are set up in advance by the BIOS or an application, but the */ 184971d7fec4Smrg /* application still requires access to other panel functionality provided by */ 185071d7fec4Smrg /* Durango (i.e. panning). */ 185171d7fec4Smrg 185271d7fec4Smrg ModeWidth = width; 185371d7fec4Smrg ModeHeight = height; 185471d7fec4Smrg PanelWidth = (unsigned short)panelResX; 185571d7fec4Smrg PanelHeight = (unsigned short)panelResY; 185671d7fec4Smrg PanelEnable = 1; 185771d7fec4Smrg gbpp = bpp; 185871d7fec4Smrg 185971d7fec4Smrg /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */ 186071d7fec4Smrg 186171d7fec4Smrg gfx_set_display_bpp(bpp); 186271d7fec4Smrg 186371d7fec4Smrg return (GFX_STATUS_OK); 186471d7fec4Smrg} 186571d7fec4Smrg 186671d7fec4Smrg/*-----------------------------------------------------------------------* 186771d7fec4Smrg * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: * 186871d7fec4Smrg * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal * 186971d7fec4Smrg * are used by the video overlay routines. * 187071d7fec4Smrg * * 187171d7fec4Smrg * gfx_get_vline and gfx_vactive are used to prevent an issue for the * 187271d7fec4Smrg * SC1200. * 187371d7fec4Smrg * * 187471d7fec4Smrg * The others are part of the Durango API. * 187571d7fec4Smrg *-----------------------------------------------------------------------*/ 187671d7fec4Smrg 187771d7fec4Smrg/*--------------------------------------------------------------------------- 187871d7fec4Smrg * gfx_get_display_pitch 187971d7fec4Smrg * 188071d7fec4Smrg * This routine returns the current pitch of the frame buffer, in bytes. 188171d7fec4Smrg *--------------------------------------------------------------------------- 188271d7fec4Smrg */ 188371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 188471d7fec4Smrgunsigned short 188571d7fec4Smrggu1_get_display_pitch(void) 188671d7fec4Smrg#else 188771d7fec4Smrgunsigned short 188871d7fec4Smrggfx_get_display_pitch(void) 188971d7fec4Smrg#endif 189071d7fec4Smrg{ 189171d7fec4Smrg unsigned long value; 189271d7fec4Smrg 189371d7fec4Smrg if (gfx_cpu_version == GFX_CPU_PYRAMID) { /* Pyramid update for 4KB line pitch */ 189471d7fec4Smrg value = (READ_REG32(DC_LINE_DELTA) & 0x07FF) << 2; 189571d7fec4Smrg } else { 189671d7fec4Smrg value = (READ_REG32(DC_LINE_DELTA) & 0x03FF) << 2; 189771d7fec4Smrg } 189871d7fec4Smrg 189971d7fec4Smrg return ((unsigned short)value); 190071d7fec4Smrg} 190171d7fec4Smrg 190271d7fec4Smrg/*---------------------------------------------------------------------------- 190371d7fec4Smrg * GFX_GET_DISPLAY_DETAILS 190471d7fec4Smrg * 190571d7fec4Smrg * This routine gets the specified display mode. 190671d7fec4Smrg * 190771d7fec4Smrg * Returns 1 if successful, 0 if mode could not be get. 190871d7fec4Smrg *---------------------------------------------------------------------------- 190971d7fec4Smrg */ 191071d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 191171d7fec4Smrgint 191271d7fec4Smrggu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) 191371d7fec4Smrg#else 191471d7fec4Smrgint 191571d7fec4Smrggfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) 191671d7fec4Smrg#endif 191771d7fec4Smrg{ 191871d7fec4Smrg if (mode < NUM_GX_DISPLAY_MODES) { 191971d7fec4Smrg if (DisplayParams[mode].flags & GFX_MODE_56HZ) 192071d7fec4Smrg *hz = 56; 192171d7fec4Smrg else if (DisplayParams[mode].flags & GFX_MODE_60HZ) 192271d7fec4Smrg *hz = 60; 192371d7fec4Smrg else if (DisplayParams[mode].flags & GFX_MODE_70HZ) 192471d7fec4Smrg *hz = 70; 192571d7fec4Smrg else if (DisplayParams[mode].flags & GFX_MODE_72HZ) 192671d7fec4Smrg *hz = 72; 192771d7fec4Smrg else if (DisplayParams[mode].flags & GFX_MODE_75HZ) 192871d7fec4Smrg *hz = 75; 192971d7fec4Smrg else if (DisplayParams[mode].flags & GFX_MODE_85HZ) 193071d7fec4Smrg *hz = 85; 193171d7fec4Smrg 193271d7fec4Smrg *xres = DisplayParams[mode].hactive; 193371d7fec4Smrg *yres = DisplayParams[mode].vactive; 193471d7fec4Smrg 193571d7fec4Smrg return (1); 193671d7fec4Smrg } 193771d7fec4Smrg return (0); 193871d7fec4Smrg} 193971d7fec4Smrg 194071d7fec4Smrg/*---------------------------------------------------------------------------- 194171d7fec4Smrg * GFX_GET_DISPLAY_MODE_COUNT 194271d7fec4Smrg * 194371d7fec4Smrg * Returns number of modes supported. 194471d7fec4Smrg *---------------------------------------------------------------------------- 194571d7fec4Smrg */ 194671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 194771d7fec4Smrgint 194871d7fec4Smrggu1_get_display_mode_count(void) 194971d7fec4Smrg#else 195071d7fec4Smrgint 195171d7fec4Smrggfx_get_display_mode_count(void) 195271d7fec4Smrg#endif 195371d7fec4Smrg{ 195471d7fec4Smrg return (NUM_GX_DISPLAY_MODES); 195571d7fec4Smrg} 195671d7fec4Smrg 195771d7fec4Smrg/*---------------------------------------------------------------------------- 195871d7fec4Smrg * gfx_get_frame_buffer_line_size 195971d7fec4Smrg * 196071d7fec4Smrg * Returns the current frame buffer line size, in bytes 196171d7fec4Smrg *---------------------------------------------------------------------------- 196271d7fec4Smrg */ 196371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 196471d7fec4Smrgunsigned long 196571d7fec4Smrggu1_get_frame_buffer_line_size(void) 196671d7fec4Smrg#else 196771d7fec4Smrgunsigned long 196871d7fec4Smrggfx_get_frame_buffer_line_size(void) 196971d7fec4Smrg#endif 197071d7fec4Smrg{ 197171d7fec4Smrg return ((READ_REG32(DC_BUF_SIZE) & 0x1FF) << 3); 197271d7fec4Smrg} 197371d7fec4Smrg 197471d7fec4Smrg/*---------------------------------------------------------------------------- 197571d7fec4Smrg * gfx_mode_frequency_supported 197671d7fec4Smrg * 197771d7fec4Smrg * This routine examines if the requested mode with pixel frequency is supported. 197871d7fec4Smrg * 197971d7fec4Smrg * Returns >0 if successful , <0 if freq. could not be found and matched. 198071d7fec4Smrg *---------------------------------------------------------------------------- 198171d7fec4Smrg */ 198271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 198371d7fec4Smrgint 198471d7fec4Smrggu1_mode_frequency_supported(int xres, int yres, int bpp, 198571d7fec4Smrg unsigned long frequency) 198671d7fec4Smrg#else 198771d7fec4Smrgint 198871d7fec4Smrggfx_mode_frequency_supported(int xres, int yres, int bpp, 198971d7fec4Smrg unsigned long frequency) 199071d7fec4Smrg#endif 199171d7fec4Smrg{ 199271d7fec4Smrg unsigned int index; 199371d7fec4Smrg unsigned long value; 199471d7fec4Smrg unsigned long bpp_flag = 0; 199571d7fec4Smrg 199671d7fec4Smrg bpp_flag = GFX_MODE_8BPP; 199771d7fec4Smrg if (bpp > 8) 199871d7fec4Smrg bpp_flag = GFX_MODE_16BPP; 199971d7fec4Smrg 200071d7fec4Smrg for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 200171d7fec4Smrg if ((DisplayParams[index].hactive == (unsigned short)xres) && 200271d7fec4Smrg (DisplayParams[index].vactive == (unsigned short)yres) && 200371d7fec4Smrg (DisplayParams[index].flags & bpp_flag) && 200471d7fec4Smrg (DisplayParams[index].frequency == frequency)) { 200571d7fec4Smrg int hz = 0; 200671d7fec4Smrg 200771d7fec4Smrg value = DisplayParams[index].flags; 200871d7fec4Smrg 200971d7fec4Smrg if (value & GFX_MODE_60HZ) 201071d7fec4Smrg hz = 60; 201171d7fec4Smrg else if (value & GFX_MODE_70HZ) 201271d7fec4Smrg hz = 70; 201371d7fec4Smrg else if (value & GFX_MODE_72HZ) 201471d7fec4Smrg hz = 72; 201571d7fec4Smrg else if (value & GFX_MODE_75HZ) 201671d7fec4Smrg hz = 75; 201771d7fec4Smrg else if (value & GFX_MODE_85HZ) 201871d7fec4Smrg hz = 85; 201971d7fec4Smrg return (hz); 202071d7fec4Smrg } 202171d7fec4Smrg } 202271d7fec4Smrg return (-1); 202371d7fec4Smrg} 202471d7fec4Smrg 202571d7fec4Smrg/*---------------------------------------------------------------------------- 202671d7fec4Smrg * gfx_refreshrate_from_frequency 202771d7fec4Smrg * 202871d7fec4Smrg * This routine maps the frequency to close match refresh rate 202971d7fec4Smrg * 203071d7fec4Smrg * Returns . 203171d7fec4Smrg *---------------------------------------------------------------------------- 203271d7fec4Smrg */ 203371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 203471d7fec4Smrgint 203571d7fec4Smrggu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, 203671d7fec4Smrg unsigned long frequency) 203771d7fec4Smrg#else 203871d7fec4Smrgint 203971d7fec4Smrggfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, 204071d7fec4Smrg unsigned long frequency) 204171d7fec4Smrg#endif 204271d7fec4Smrg{ 204371d7fec4Smrg unsigned int index, closematch = 0; 204471d7fec4Smrg unsigned long value; 204571d7fec4Smrg unsigned long bpp_flag = 0; 204671d7fec4Smrg long min, diff; 204771d7fec4Smrg 204871d7fec4Smrg *hz = 60; 204971d7fec4Smrg 205071d7fec4Smrg bpp_flag = GFX_MODE_8BPP; 205171d7fec4Smrg if (bpp > 8) 205271d7fec4Smrg bpp_flag = GFX_MODE_16BPP; 205371d7fec4Smrg 205471d7fec4Smrg /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 205571d7fec4Smrg /* Search the table for the closest frequency (16.16 format). */ 205671d7fec4Smrg 205771d7fec4Smrg min = 0x7fffffff; 205871d7fec4Smrg for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 205971d7fec4Smrg if ((DisplayParams[index].htotal == (unsigned short)xres) && 206071d7fec4Smrg (DisplayParams[index].vtotal == (unsigned short)yres) && 206171d7fec4Smrg (DisplayParams[index].flags & bpp_flag)) { 206271d7fec4Smrg diff = (long)frequency - (long)DisplayParams[index].frequency; 206371d7fec4Smrg if (diff < 0) 206471d7fec4Smrg diff = -diff; 206571d7fec4Smrg 206671d7fec4Smrg if (diff < min) { 206771d7fec4Smrg min = diff; 206871d7fec4Smrg closematch = index; 206971d7fec4Smrg } 207071d7fec4Smrg } 207171d7fec4Smrg } 207271d7fec4Smrg 207371d7fec4Smrg value = DisplayParams[closematch].flags; 207471d7fec4Smrg 207571d7fec4Smrg if (value & GFX_MODE_60HZ) 207671d7fec4Smrg *hz = 60; 207771d7fec4Smrg else if (value & GFX_MODE_70HZ) 207871d7fec4Smrg *hz = 70; 207971d7fec4Smrg else if (value & GFX_MODE_72HZ) 208071d7fec4Smrg *hz = 72; 208171d7fec4Smrg else if (value & GFX_MODE_75HZ) 208271d7fec4Smrg *hz = 75; 208371d7fec4Smrg else if (value & GFX_MODE_85HZ) 208471d7fec4Smrg *hz = 85; 208571d7fec4Smrg 208671d7fec4Smrg return (1); 208771d7fec4Smrg} 208871d7fec4Smrg 208971d7fec4Smrg/*---------------------------------------------------------------------------- 209071d7fec4Smrg * gfx_refreshrate_from_mode 209171d7fec4Smrg * 209271d7fec4Smrg * This routine is identical to the gfx_get_refreshrate_from_frequency, 209371d7fec4Smrg * except that the active timing values are compared instead of the total 209471d7fec4Smrg * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine. 209571d7fec4Smrg * 209671d7fec4Smrg * Returns . 209771d7fec4Smrg *---------------------------------------------------------------------------- 209871d7fec4Smrg */ 209971d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 210071d7fec4Smrgint 210171d7fec4Smrggu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, 210271d7fec4Smrg unsigned long frequency) 210371d7fec4Smrg#else 210471d7fec4Smrgint 210571d7fec4Smrggfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, 210671d7fec4Smrg unsigned long frequency) 210771d7fec4Smrg#endif 210871d7fec4Smrg{ 210971d7fec4Smrg unsigned int index, closematch = 0; 211071d7fec4Smrg unsigned long value; 211171d7fec4Smrg unsigned long bpp_flag = 0; 211271d7fec4Smrg long min, diff; 211371d7fec4Smrg 211471d7fec4Smrg *hz = 60; 211571d7fec4Smrg 211671d7fec4Smrg bpp_flag = GFX_MODE_8BPP; 211771d7fec4Smrg if (bpp > 8) 211871d7fec4Smrg bpp_flag = GFX_MODE_16BPP; 211971d7fec4Smrg 212071d7fec4Smrg /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 212171d7fec4Smrg /* Search the table for the closest frequency (16.16 format). */ 212271d7fec4Smrg 212371d7fec4Smrg min = 0x7fffffff; 212471d7fec4Smrg for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 212571d7fec4Smrg if ((DisplayParams[index].hactive == (unsigned short)xres) && 212671d7fec4Smrg (DisplayParams[index].vactive == (unsigned short)yres) && 212771d7fec4Smrg (DisplayParams[index].flags & bpp_flag)) { 212871d7fec4Smrg diff = (long)frequency - (long)DisplayParams[index].frequency; 212971d7fec4Smrg if (diff < 0) 213071d7fec4Smrg diff = -diff; 213171d7fec4Smrg 213271d7fec4Smrg if (diff < min) { 213371d7fec4Smrg min = diff; 213471d7fec4Smrg closematch = index; 213571d7fec4Smrg } 213671d7fec4Smrg } 213771d7fec4Smrg } 213871d7fec4Smrg 213971d7fec4Smrg value = DisplayParams[closematch].flags; 214071d7fec4Smrg 214171d7fec4Smrg if (value & GFX_MODE_60HZ) 214271d7fec4Smrg *hz = 60; 214371d7fec4Smrg else if (value & GFX_MODE_70HZ) 214471d7fec4Smrg *hz = 70; 214571d7fec4Smrg else if (value & GFX_MODE_72HZ) 214671d7fec4Smrg *hz = 72; 214771d7fec4Smrg else if (value & GFX_MODE_75HZ) 214871d7fec4Smrg *hz = 75; 214971d7fec4Smrg else if (value & GFX_MODE_85HZ) 215071d7fec4Smrg *hz = 85; 215171d7fec4Smrg 215271d7fec4Smrg return (1); 215371d7fec4Smrg} 215471d7fec4Smrg 215571d7fec4Smrg/*---------------------------------------------------------------------------- 215671d7fec4Smrg * gfx_get_frequency_from_refreshrate 215771d7fec4Smrg * 215871d7fec4Smrg * This routine maps the refresh rate to the closest matching PLL frequency. 215971d7fec4Smrg *---------------------------------------------------------------------------- 216071d7fec4Smrg */ 216171d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 216271d7fec4Smrgint 216371d7fec4Smrggu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, 216471d7fec4Smrg int *frequency) 216571d7fec4Smrg#else 216671d7fec4Smrgint 216771d7fec4Smrggfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, 216871d7fec4Smrg int *frequency) 216971d7fec4Smrg#endif 217071d7fec4Smrg{ 217171d7fec4Smrg int retval = -1; 217271d7fec4Smrg unsigned long hz_flag = 0; 217371d7fec4Smrg unsigned long index, bpp_flag = 0; 217471d7fec4Smrg 217571d7fec4Smrg *frequency = 0; 217671d7fec4Smrg 217771d7fec4Smrg if (hz == 60) 217871d7fec4Smrg hz_flag = GFX_MODE_60HZ; 217971d7fec4Smrg else if (hz == 70) 218071d7fec4Smrg hz_flag = GFX_MODE_70HZ; 218171d7fec4Smrg else if (hz == 72) 218271d7fec4Smrg hz_flag = GFX_MODE_72HZ; 218371d7fec4Smrg else if (hz == 75) 218471d7fec4Smrg hz_flag = GFX_MODE_75HZ; 218571d7fec4Smrg else if (hz == 85) 218671d7fec4Smrg hz_flag = GFX_MODE_85HZ; 218771d7fec4Smrg 218871d7fec4Smrg bpp_flag = GFX_MODE_8BPP; 218971d7fec4Smrg if (bpp > 8) 219071d7fec4Smrg bpp_flag = GFX_MODE_16BPP; 219171d7fec4Smrg 219271d7fec4Smrg /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 219371d7fec4Smrg 219471d7fec4Smrg for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 219571d7fec4Smrg if ((DisplayParams[index].hactive == (unsigned short)xres) && 219671d7fec4Smrg (DisplayParams[index].vactive == (unsigned short)yres) && 219771d7fec4Smrg (DisplayParams[index].flags & bpp_flag) && 219871d7fec4Smrg (DisplayParams[index].flags & hz_flag)) { 219971d7fec4Smrg *frequency = DisplayParams[index].frequency; 220071d7fec4Smrg retval = 1; 220171d7fec4Smrg } 220271d7fec4Smrg } 220371d7fec4Smrg return retval; 220471d7fec4Smrg} 220571d7fec4Smrg 220671d7fec4Smrg/*--------------------------------------------------------------------------- 220771d7fec4Smrg * gfx_get_max_supported_pixel_clock 220871d7fec4Smrg * 220971d7fec4Smrg * This routine returns the maximum recommended speed for the pixel clock. The 221071d7fec4Smrg * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum 221171d7fec4Smrg * floating point pixel clock speed. 221271d7fec4Smrg *--------------------------------------------------------------------------- 221371d7fec4Smrg */ 221471d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 221571d7fec4Smrgunsigned long 221671d7fec4Smrggu1_get_max_supported_pixel_clock(void) 221771d7fec4Smrg#else 221871d7fec4Smrgunsigned long 221971d7fec4Smrggfx_get_max_supported_pixel_clock(void) 222071d7fec4Smrg#endif 222171d7fec4Smrg{ 222271d7fec4Smrg /* ALL CHIPS CAN HANDLE 1280X1024@85HZ - 157.5 MHz */ 222371d7fec4Smrg 222471d7fec4Smrg return 157500; 222571d7fec4Smrg} 222671d7fec4Smrg 222771d7fec4Smrg/*---------------------------------------------------------------------------- 222871d7fec4Smrg * gfx_get_display_mode 222971d7fec4Smrg * 223071d7fec4Smrg * This routine gets the specified display mode. 223171d7fec4Smrg * 223271d7fec4Smrg * Returns >0 if successful and mode returned, <0 if mode could not be found. 223371d7fec4Smrg *---------------------------------------------------------------------------- 223471d7fec4Smrg */ 223571d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 223671d7fec4Smrgint 223771d7fec4Smrggu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz) 223871d7fec4Smrg#else 223971d7fec4Smrgint 224071d7fec4Smrggfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz) 224171d7fec4Smrg#endif 224271d7fec4Smrg{ 224371d7fec4Smrg unsigned int mode = 0; 224471d7fec4Smrg unsigned long pll_freq = 0, bpp_flag = 0; 224571d7fec4Smrg 224671d7fec4Smrg *xres = gfx_get_hactive(); 224771d7fec4Smrg *yres = gfx_get_vactive(); 224871d7fec4Smrg *bpp = gfx_get_display_bpp(); 224971d7fec4Smrg pll_freq = gfx_get_clock_frequency(); 225071d7fec4Smrg 225171d7fec4Smrg /* SUPPORT EMULATED VGA MODES */ 225271d7fec4Smrg 225371d7fec4Smrg if (gfx_pixel_double) 225471d7fec4Smrg *xres >>= 1; 225571d7fec4Smrg 225671d7fec4Smrg if (gfx_line_double) 225771d7fec4Smrg *yres >>= 1; 225871d7fec4Smrg 225971d7fec4Smrg /* SET BPP FLAGS TO LIMIT MODE SELECTION */ 226071d7fec4Smrg 226171d7fec4Smrg bpp_flag = GFX_MODE_8BPP; 226271d7fec4Smrg if (*bpp > 8) 226371d7fec4Smrg bpp_flag = GFX_MODE_16BPP; 226471d7fec4Smrg 226571d7fec4Smrg for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) { 226671d7fec4Smrg if ((DisplayParams[mode].hactive == (unsigned short)*xres) && 226771d7fec4Smrg (DisplayParams[mode].vactive == (unsigned short)*yres) && 226871d7fec4Smrg (DisplayParams[mode].frequency == pll_freq) && 226971d7fec4Smrg (DisplayParams[mode].flags & bpp_flag)) { 227071d7fec4Smrg 227171d7fec4Smrg pll_freq = DisplayParams[mode].flags; 227271d7fec4Smrg 227371d7fec4Smrg if (pll_freq & GFX_MODE_56HZ) 227471d7fec4Smrg *hz = 56; 227571d7fec4Smrg else if (pll_freq & GFX_MODE_60HZ) 227671d7fec4Smrg *hz = 60; 227771d7fec4Smrg else if (pll_freq & GFX_MODE_70HZ) 227871d7fec4Smrg *hz = 70; 227971d7fec4Smrg else if (pll_freq & GFX_MODE_72HZ) 228071d7fec4Smrg *hz = 72; 228171d7fec4Smrg else if (pll_freq & GFX_MODE_75HZ) 228271d7fec4Smrg *hz = 75; 228371d7fec4Smrg else if (pll_freq & GFX_MODE_85HZ) 228471d7fec4Smrg *hz = 85; 228571d7fec4Smrg 228671d7fec4Smrg return (1); 228771d7fec4Smrg } 228871d7fec4Smrg } 228971d7fec4Smrg return (-1); 229071d7fec4Smrg} 229171d7fec4Smrg 229271d7fec4Smrg/*--------------------------------------------------------------------------- 229371d7fec4Smrg * gfx_get_hactive 229471d7fec4Smrg *--------------------------------------------------------------------------- 229571d7fec4Smrg */ 229671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 229771d7fec4Smrgunsigned short 229871d7fec4Smrggu1_get_hactive(void) 229971d7fec4Smrg#else 230071d7fec4Smrgunsigned short 230171d7fec4Smrggfx_get_hactive(void) 230271d7fec4Smrg#endif 230371d7fec4Smrg{ 230471d7fec4Smrg return ((unsigned short)((READ_REG32(DC_H_TIMING_1) & 0x07F8) + 8)); 230571d7fec4Smrg} 230671d7fec4Smrg 230771d7fec4Smrg/*--------------------------------------------------------------------------- 230871d7fec4Smrg * gfx_get_hsync_start 230971d7fec4Smrg *--------------------------------------------------------------------------- 231071d7fec4Smrg */ 231171d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 231271d7fec4Smrgunsigned short 231371d7fec4Smrggu1_get_hsync_start(void) 231471d7fec4Smrg#else 231571d7fec4Smrgunsigned short 231671d7fec4Smrggfx_get_hsync_start(void) 231771d7fec4Smrg#endif 231871d7fec4Smrg{ 231971d7fec4Smrg return ((unsigned short)((READ_REG32(DC_H_TIMING_3) & 0x07F8) + 8)); 232071d7fec4Smrg} 232171d7fec4Smrg 232271d7fec4Smrg/*--------------------------------------------------------------------------- 232371d7fec4Smrg * gfx_get_hsync_end 232471d7fec4Smrg *--------------------------------------------------------------------------- 232571d7fec4Smrg */ 232671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 232771d7fec4Smrgunsigned short 232871d7fec4Smrggu1_get_hsync_end(void) 232971d7fec4Smrg#else 233071d7fec4Smrgunsigned short 233171d7fec4Smrggfx_get_hsync_end(void) 233271d7fec4Smrg#endif 233371d7fec4Smrg{ 233471d7fec4Smrg return ((unsigned short)(((READ_REG32(DC_H_TIMING_3) >> 16) & 0x07F8) + 233571d7fec4Smrg 8)); 233671d7fec4Smrg} 233771d7fec4Smrg 233871d7fec4Smrg/*--------------------------------------------------------------------------- 233971d7fec4Smrg * gfx_get_htotal 234071d7fec4Smrg *--------------------------------------------------------------------------- 234171d7fec4Smrg */ 234271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 234371d7fec4Smrgunsigned short 234471d7fec4Smrggu1_get_htotal(void) 234571d7fec4Smrg#else 234671d7fec4Smrgunsigned short 234771d7fec4Smrggfx_get_htotal(void) 234871d7fec4Smrg#endif 234971d7fec4Smrg{ 235071d7fec4Smrg return ((unsigned short)(((READ_REG32(DC_H_TIMING_1) >> 16) & 0x07F8) + 235171d7fec4Smrg 8)); 235271d7fec4Smrg} 235371d7fec4Smrg 235471d7fec4Smrg/*--------------------------------------------------------------------------- 235571d7fec4Smrg * gfx_get_vactive 235671d7fec4Smrg *--------------------------------------------------------------------------- 235771d7fec4Smrg */ 235871d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 235971d7fec4Smrgunsigned short 236071d7fec4Smrggu1_get_vactive(void) 236171d7fec4Smrg#else 236271d7fec4Smrgunsigned short 236371d7fec4Smrggfx_get_vactive(void) 236471d7fec4Smrg#endif 236571d7fec4Smrg{ 236671d7fec4Smrg return ((unsigned short)((READ_REG32(DC_V_TIMING_1) & 0x07FF) + 1)); 236771d7fec4Smrg} 236871d7fec4Smrg 236971d7fec4Smrg/*--------------------------------------------------------------------------- 237071d7fec4Smrg * gfx_get_vsync_end 237171d7fec4Smrg *--------------------------------------------------------------------------- 237271d7fec4Smrg */ 237371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 237471d7fec4Smrgunsigned short 237571d7fec4Smrggu1_get_vsync_end(void) 237671d7fec4Smrg#else 237771d7fec4Smrgunsigned short 237871d7fec4Smrggfx_get_vsync_end(void) 237971d7fec4Smrg#endif 238071d7fec4Smrg{ 238171d7fec4Smrg return ((unsigned short)(((READ_REG32(DC_V_TIMING_3) >> 16) & 0x07FF) + 238271d7fec4Smrg 1)); 238371d7fec4Smrg} 238471d7fec4Smrg 238571d7fec4Smrg/*--------------------------------------------------------------------------- 238671d7fec4Smrg * gfx_get_vtotal 238771d7fec4Smrg *--------------------------------------------------------------------------- 238871d7fec4Smrg */ 238971d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 239071d7fec4Smrgunsigned short 239171d7fec4Smrggu1_get_vtotal(void) 239271d7fec4Smrg#else 239371d7fec4Smrgunsigned short 239471d7fec4Smrggfx_get_vtotal(void) 239571d7fec4Smrg#endif 239671d7fec4Smrg{ 239771d7fec4Smrg return ((unsigned short)(((READ_REG32(DC_V_TIMING_1) >> 16) & 0x07FF) + 239871d7fec4Smrg 1)); 239971d7fec4Smrg} 240071d7fec4Smrg 240171d7fec4Smrg/*----------------------------------------------------------------------------- 240271d7fec4Smrg * gfx_get_display_bpp 240371d7fec4Smrg * 240471d7fec4Smrg * This routine returns the current color depth of the active display. 240571d7fec4Smrg *----------------------------------------------------------------------------- 240671d7fec4Smrg */ 240771d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 240871d7fec4Smrgunsigned short 240971d7fec4Smrggu1_get_display_bpp(void) 241071d7fec4Smrg#else 241171d7fec4Smrgunsigned short 241271d7fec4Smrggfx_get_display_bpp(void) 241371d7fec4Smrg#endif 241471d7fec4Smrg{ 241571d7fec4Smrg switch (READ_REG32(DC_OUTPUT_CFG) & 3) { 241671d7fec4Smrg case 0: 241771d7fec4Smrg return (16); 241871d7fec4Smrg case 2: 241971d7fec4Smrg return (15); 242071d7fec4Smrg } 242171d7fec4Smrg return (8); 242271d7fec4Smrg} 242371d7fec4Smrg 242471d7fec4Smrg/*--------------------------------------------------------------------------- 242571d7fec4Smrg * gfx_get_vline 242671d7fec4Smrg *--------------------------------------------------------------------------- 242771d7fec4Smrg */ 242871d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 242971d7fec4Smrgunsigned short 243071d7fec4Smrggu1_get_vline(void) 243171d7fec4Smrg#else 243271d7fec4Smrgunsigned short 243371d7fec4Smrggfx_get_vline(void) 243471d7fec4Smrg#endif 243571d7fec4Smrg{ 243671d7fec4Smrg unsigned short current_scan_line; 243771d7fec4Smrg 243871d7fec4Smrg /* Read similar value twice to ensure that the value is not transitioning */ 243971d7fec4Smrg 244071d7fec4Smrg do 244171d7fec4Smrg current_scan_line = (unsigned short)READ_REG32(DC_V_LINE_CNT) & 0x07FF; 244271d7fec4Smrg while (current_scan_line != 244371d7fec4Smrg (unsigned short)(READ_REG32(DC_V_LINE_CNT) & 0x07FF)); 244471d7fec4Smrg 244571d7fec4Smrg return (current_scan_line); 244671d7fec4Smrg} 244771d7fec4Smrg 244871d7fec4Smrg/*----------------------------------------------------------------------------- 244971d7fec4Smrg * gfx_get_display_offset 245071d7fec4Smrg *----------------------------------------------------------------------------- 245171d7fec4Smrg */ 245271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 245371d7fec4Smrgunsigned long 245471d7fec4Smrggu1_get_display_offset(void) 245571d7fec4Smrg#else 245671d7fec4Smrgunsigned long 245771d7fec4Smrggfx_get_display_offset(void) 245871d7fec4Smrg#endif 245971d7fec4Smrg{ 246071d7fec4Smrg return (READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF); 246171d7fec4Smrg} 246271d7fec4Smrg 246371d7fec4Smrg/*----------------------------------------------------------------------------- 246471d7fec4Smrg * gfx_get_cursor_offset 246571d7fec4Smrg *----------------------------------------------------------------------------- 246671d7fec4Smrg */ 246771d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 246871d7fec4Smrgunsigned long 246971d7fec4Smrggu1_get_cursor_offset(void) 247071d7fec4Smrg#else 247171d7fec4Smrgunsigned long 247271d7fec4Smrggfx_get_cursor_offset(void) 247371d7fec4Smrg#endif 247471d7fec4Smrg{ 247571d7fec4Smrg return (READ_REG32(DC_CURS_ST_OFFSET) & 0x003FFFFF); 247671d7fec4Smrg} 247771d7fec4Smrg 247871d7fec4Smrg#if GFX_READ_ROUTINES 247971d7fec4Smrg 248071d7fec4Smrg/*************************************************************/ 248171d7fec4Smrg/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ 248271d7fec4Smrg/*************************************************************/ 248371d7fec4Smrg 248471d7fec4Smrg/*--------------------------------------------------------------------------- 248571d7fec4Smrg * gfx_get_hblank_start 248671d7fec4Smrg *--------------------------------------------------------------------------- 248771d7fec4Smrg */ 248871d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 248971d7fec4Smrgunsigned short 249071d7fec4Smrggu1_get_hblank_start(void) 249171d7fec4Smrg#else 249271d7fec4Smrgunsigned short 249371d7fec4Smrggfx_get_hblank_start(void) 249471d7fec4Smrg#endif 249571d7fec4Smrg{ 249671d7fec4Smrg return ((unsigned short)((READ_REG32(DC_H_TIMING_2) & 0x07F8) + 8)); 249771d7fec4Smrg} 249871d7fec4Smrg 249971d7fec4Smrg/*--------------------------------------------------------------------------- 250071d7fec4Smrg * gfx_get_hblank_end 250171d7fec4Smrg *--------------------------------------------------------------------------- 250271d7fec4Smrg */ 250371d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 250471d7fec4Smrgunsigned short 250571d7fec4Smrggu1_get_hblank_end(void) 250671d7fec4Smrg#else 250771d7fec4Smrgunsigned short 250871d7fec4Smrggfx_get_hblank_end(void) 250971d7fec4Smrg#endif 251071d7fec4Smrg{ 251171d7fec4Smrg return ((unsigned short)(((READ_REG32(DC_H_TIMING_2) >> 16) & 0x07F8) + 251271d7fec4Smrg 8)); 251371d7fec4Smrg} 251471d7fec4Smrg 251571d7fec4Smrg/*--------------------------------------------------------------------------- 251671d7fec4Smrg * gfx_get_vblank_start 251771d7fec4Smrg *--------------------------------------------------------------------------- 251871d7fec4Smrg */ 251971d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 252071d7fec4Smrgunsigned short 252171d7fec4Smrggu1_get_vblank_start(void) 252271d7fec4Smrg#else 252371d7fec4Smrgunsigned short 252471d7fec4Smrggfx_get_vblank_start(void) 252571d7fec4Smrg#endif 252671d7fec4Smrg{ 252771d7fec4Smrg return ((unsigned short)((READ_REG32(DC_V_TIMING_2) & 0x07FF) + 1)); 252871d7fec4Smrg} 252971d7fec4Smrg 253071d7fec4Smrg/*--------------------------------------------------------------------------- 253171d7fec4Smrg * gfx_get_vsync_start 253271d7fec4Smrg *--------------------------------------------------------------------------- 253371d7fec4Smrg */ 253471d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 253571d7fec4Smrgunsigned short 253671d7fec4Smrggu1_get_vsync_start(void) 253771d7fec4Smrg#else 253871d7fec4Smrgunsigned short 253971d7fec4Smrggfx_get_vsync_start(void) 254071d7fec4Smrg#endif 254171d7fec4Smrg{ 254271d7fec4Smrg return ((unsigned short)((READ_REG32(DC_V_TIMING_3) & 0x07FF) + 1)); 254371d7fec4Smrg} 254471d7fec4Smrg 254571d7fec4Smrg/*--------------------------------------------------------------------------- 254671d7fec4Smrg * gfx_get_vblank_end 254771d7fec4Smrg *--------------------------------------------------------------------------- 254871d7fec4Smrg */ 254971d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 255071d7fec4Smrgunsigned short 255171d7fec4Smrggu1_get_vblank_end(void) 255271d7fec4Smrg#else 255371d7fec4Smrgunsigned short 255471d7fec4Smrggfx_get_vblank_end(void) 255571d7fec4Smrg#endif 255671d7fec4Smrg{ 255771d7fec4Smrg return ((unsigned short)(((READ_REG32(DC_V_TIMING_2) >> 16) & 0x07FF) + 255871d7fec4Smrg 1)); 255971d7fec4Smrg} 256071d7fec4Smrg 256171d7fec4Smrg/*----------------------------------------------------------------------------- 256271d7fec4Smrg * gfx_get_display_palette_entry 256371d7fec4Smrg *----------------------------------------------------------------------------- 256471d7fec4Smrg */ 256571d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 256671d7fec4Smrgint 256771d7fec4Smrggu1_get_display_palette_entry(unsigned long index, unsigned long *palette) 256871d7fec4Smrg#else 256971d7fec4Smrgint 257071d7fec4Smrggfx_get_display_palette_entry(unsigned long index, unsigned long *palette) 257171d7fec4Smrg#endif 257271d7fec4Smrg{ 257371d7fec4Smrg unsigned long data; 257471d7fec4Smrg 257571d7fec4Smrg if (index > 0xFF) 257671d7fec4Smrg return GFX_STATUS_BAD_PARAMETER; 257771d7fec4Smrg 257871d7fec4Smrg WRITE_REG32(DC_PAL_ADDRESS, index); 257971d7fec4Smrg data = READ_REG32(DC_PAL_DATA); 258071d7fec4Smrg data = ((data << 2) & 0x000000FC) | 258171d7fec4Smrg ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000); 258271d7fec4Smrg 258371d7fec4Smrg *palette = data; 258471d7fec4Smrg 258571d7fec4Smrg return 0; 258671d7fec4Smrg} 258771d7fec4Smrg 258871d7fec4Smrg/*----------------------------------------------------------------------------- 258971d7fec4Smrg * gfx_get_display_palette 259071d7fec4Smrg *----------------------------------------------------------------------------- 259171d7fec4Smrg */ 259271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 259371d7fec4Smrgvoid 259471d7fec4Smrggu1_get_display_palette(unsigned long *palette) 259571d7fec4Smrg#else 259671d7fec4Smrgvoid 259771d7fec4Smrggfx_get_display_palette(unsigned long *palette) 259871d7fec4Smrg#endif 259971d7fec4Smrg{ 260071d7fec4Smrg unsigned long i, data; 260171d7fec4Smrg 260271d7fec4Smrg WRITE_REG32(DC_PAL_ADDRESS, 0); 260371d7fec4Smrg for (i = 0; i < 256; i++) { 260471d7fec4Smrg data = READ_REG32(DC_PAL_DATA); 260571d7fec4Smrg data = ((data << 2) & 0x000000FC) | 260671d7fec4Smrg ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000); 260771d7fec4Smrg palette[i] = data; 260871d7fec4Smrg } 260971d7fec4Smrg} 261071d7fec4Smrg 261171d7fec4Smrg/*----------------------------------------------------------------------------- 261271d7fec4Smrg * gfx_get_cursor_enable 261371d7fec4Smrg *----------------------------------------------------------------------------- 261471d7fec4Smrg */ 261571d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 261671d7fec4Smrgunsigned long 261771d7fec4Smrggu1_get_cursor_enable(void) 261871d7fec4Smrg#else 261971d7fec4Smrgunsigned long 262071d7fec4Smrggfx_get_cursor_enable(void) 262171d7fec4Smrg#endif 262271d7fec4Smrg{ 262371d7fec4Smrg return (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_CURE); 262471d7fec4Smrg} 262571d7fec4Smrg 262671d7fec4Smrg/*----------------------------------------------------------------------------- 262771d7fec4Smrg * gfx_get_cursor_position 262871d7fec4Smrg *----------------------------------------------------------------------------- 262971d7fec4Smrg */ 263071d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 263171d7fec4Smrgunsigned long 263271d7fec4Smrggu1_get_cursor_position(void) 263371d7fec4Smrg#else 263471d7fec4Smrgunsigned long 263571d7fec4Smrggfx_get_cursor_position(void) 263671d7fec4Smrg#endif 263771d7fec4Smrg{ 263871d7fec4Smrg return ((READ_REG32(DC_CURSOR_X) & 0x07FF) | 263971d7fec4Smrg ((READ_REG32(DC_CURSOR_Y) << 16) & 0x03FF0000)); 264071d7fec4Smrg} 264171d7fec4Smrg 264271d7fec4Smrg/*----------------------------------------------------------------------------- 264371d7fec4Smrg * gfx_get_cursor_clip 264471d7fec4Smrg *----------------------------------------------------------------------------- 264571d7fec4Smrg */ 264671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 264771d7fec4Smrgunsigned long 264871d7fec4Smrggu1_get_cursor_clip(void) 264971d7fec4Smrg#else 265071d7fec4Smrgunsigned long 265171d7fec4Smrggfx_get_cursor_clip(void) 265271d7fec4Smrg#endif 265371d7fec4Smrg{ 265471d7fec4Smrg return (((READ_REG32(DC_CURSOR_X) >> 11) & 0x01F) | 265571d7fec4Smrg ((READ_REG32(DC_CURSOR_Y) << 5) & 0x1F0000)); 265671d7fec4Smrg} 265771d7fec4Smrg 265871d7fec4Smrg/*----------------------------------------------------------------------------- 265971d7fec4Smrg * gfx_get_cursor_color 266071d7fec4Smrg *----------------------------------------------------------------------------- 266171d7fec4Smrg */ 266271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 266371d7fec4Smrgunsigned long 266471d7fec4Smrggu1_get_cursor_color(int color) 266571d7fec4Smrg#else 266671d7fec4Smrgunsigned long 266771d7fec4Smrggfx_get_cursor_color(int color) 266871d7fec4Smrg#endif 266971d7fec4Smrg{ 267071d7fec4Smrg unsigned long data; 267171d7fec4Smrg 267271d7fec4Smrg if (color) { 267371d7fec4Smrg WRITE_REG32(DC_PAL_ADDRESS, 0x101); 267471d7fec4Smrg } else { 267571d7fec4Smrg WRITE_REG32(DC_PAL_ADDRESS, 0x100); 267671d7fec4Smrg } 267771d7fec4Smrg data = READ_REG32(DC_PAL_DATA); 267871d7fec4Smrg data = ((data << 6) & 0x00FC0000) | 267971d7fec4Smrg ((data << 4) & 0x0000FC00) | ((data << 2) & 0x000000FC); 268071d7fec4Smrg return (data); 268171d7fec4Smrg} 268271d7fec4Smrg 268371d7fec4Smrg/*----------------------------------------------------------------------------- 268471d7fec4Smrg * gfx_get_compression_enable 268571d7fec4Smrg *----------------------------------------------------------------------------- 268671d7fec4Smrg */ 268771d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 268871d7fec4Smrgint 268971d7fec4Smrggu1_get_compression_enable(void) 269071d7fec4Smrg#else 269171d7fec4Smrgint 269271d7fec4Smrggfx_get_compression_enable(void) 269371d7fec4Smrg#endif 269471d7fec4Smrg{ 269571d7fec4Smrg unsigned long gcfg; 269671d7fec4Smrg 269771d7fec4Smrg gcfg = READ_REG32(DC_GENERAL_CFG); 269871d7fec4Smrg if (gcfg & DC_GCFG_CMPE) 269971d7fec4Smrg return (1); 270071d7fec4Smrg else 270171d7fec4Smrg return (0); 270271d7fec4Smrg} 270371d7fec4Smrg 270471d7fec4Smrg/*----------------------------------------------------------------------------- 270571d7fec4Smrg * gfx_get_compression_offset 270671d7fec4Smrg *----------------------------------------------------------------------------- 270771d7fec4Smrg */ 270871d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 270971d7fec4Smrgunsigned long 271071d7fec4Smrggu1_get_compression_offset(void) 271171d7fec4Smrg#else 271271d7fec4Smrgunsigned long 271371d7fec4Smrggfx_get_compression_offset(void) 271471d7fec4Smrg#endif 271571d7fec4Smrg{ 271671d7fec4Smrg unsigned long offset; 271771d7fec4Smrg 271871d7fec4Smrg offset = READ_REG32(DC_CB_ST_OFFSET) & 0x003FFFFF; 271971d7fec4Smrg return (offset); 272071d7fec4Smrg} 272171d7fec4Smrg 272271d7fec4Smrg/*----------------------------------------------------------------------------- 272371d7fec4Smrg * gfx_get_compression_pitch 272471d7fec4Smrg *----------------------------------------------------------------------------- 272571d7fec4Smrg */ 272671d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 272771d7fec4Smrgunsigned short 272871d7fec4Smrggu1_get_compression_pitch(void) 272971d7fec4Smrg#else 273071d7fec4Smrgunsigned short 273171d7fec4Smrggfx_get_compression_pitch(void) 273271d7fec4Smrg#endif 273371d7fec4Smrg{ 273471d7fec4Smrg unsigned short pitch; 273571d7fec4Smrg 273671d7fec4Smrg pitch = (unsigned short)(READ_REG32(DC_LINE_DELTA) >> 12) & 0x07FF; 273771d7fec4Smrg return (pitch << 2); 273871d7fec4Smrg} 273971d7fec4Smrg 274071d7fec4Smrg/*----------------------------------------------------------------------------- 274171d7fec4Smrg * gfx_get_compression_size 274271d7fec4Smrg *----------------------------------------------------------------------------- 274371d7fec4Smrg */ 274471d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 274571d7fec4Smrgunsigned short 274671d7fec4Smrggu1_get_compression_size(void) 274771d7fec4Smrg#else 274871d7fec4Smrgunsigned short 274971d7fec4Smrggfx_get_compression_size(void) 275071d7fec4Smrg#endif 275171d7fec4Smrg{ 275271d7fec4Smrg unsigned short size; 275371d7fec4Smrg 275471d7fec4Smrg size = (unsigned short)((READ_REG32(DC_BUF_SIZE) >> 9) & 0x7F) - 1; 275571d7fec4Smrg return ((size << 2) + 16); 275671d7fec4Smrg} 275771d7fec4Smrg 275871d7fec4Smrg/*----------------------------------------------------------------------------- 275971d7fec4Smrg * gfx_get_valid_bit 276071d7fec4Smrg *----------------------------------------------------------------------------- 276171d7fec4Smrg */ 276271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 276371d7fec4Smrgint 276471d7fec4Smrggu1_get_valid_bit(int line) 276571d7fec4Smrg#else 276671d7fec4Smrgint 276771d7fec4Smrggfx_get_valid_bit(int line) 276871d7fec4Smrg#endif 276971d7fec4Smrg{ 277071d7fec4Smrg int valid; 277171d7fec4Smrg 277271d7fec4Smrg WRITE_REG32(MC_DR_ADD, line); 277371d7fec4Smrg valid = (int)READ_REG32(MC_DR_ACC) & 1; 277471d7fec4Smrg return (valid); 277571d7fec4Smrg} 277671d7fec4Smrg 277771d7fec4Smrg/*--------------------------------------------------------------------------- 277871d7fec4Smrg * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) 277971d7fec4Smrg * 278071d7fec4Smrg * This routine is called by "gfx_get_video_offset". It abstracts the 278171d7fec4Smrg * version of the display controller from the video overlay routines. 278271d7fec4Smrg *--------------------------------------------------------------------------- 278371d7fec4Smrg */ 278471d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 278571d7fec4Smrgunsigned long 278671d7fec4Smrggu1_get_display_video_offset(void) 278771d7fec4Smrg#else 278871d7fec4Smrgunsigned long 278971d7fec4Smrggfx_get_display_video_offset(void) 279071d7fec4Smrg#endif 279171d7fec4Smrg{ 279271d7fec4Smrg return (READ_REG32(DC_VID_ST_OFFSET) & 0x003FFFFF); 279371d7fec4Smrg} 279471d7fec4Smrg 279571d7fec4Smrg/*--------------------------------------------------------------------------- 279671d7fec4Smrg * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API) 279771d7fec4Smrg * 279871d7fec4Smrg * This routine is called by "gfx_get_video_size". It abstracts the 279971d7fec4Smrg * version of the display controller from the video overlay routines. 280071d7fec4Smrg *--------------------------------------------------------------------------- 280171d7fec4Smrg */ 280271d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 280371d7fec4Smrgunsigned long 280471d7fec4Smrggu1_get_display_video_size(void) 280571d7fec4Smrg#else 280671d7fec4Smrgunsigned long 280771d7fec4Smrggfx_get_display_video_size(void) 280871d7fec4Smrg#endif 280971d7fec4Smrg{ 281071d7fec4Smrg /* RETURN TOTAL SIZE, IN BYTES */ 281171d7fec4Smrg 281271d7fec4Smrg return ((READ_REG32(DC_BUF_SIZE) >> 10) & 0x000FFFC0); 281371d7fec4Smrg} 281471d7fec4Smrg 281571d7fec4Smrg/*----------------------------------------------------------------------------- 281671d7fec4Smrg * gfx_get_display_priority_high 281771d7fec4Smrg *----------------------------------------------------------------------------- 281871d7fec4Smrg */ 281971d7fec4Smrg#if GFX_DISPLAY_DYNAMIC 282071d7fec4Smrgint 282171d7fec4Smrggu1_get_display_priority_high(void) 282271d7fec4Smrg#else 282371d7fec4Smrgint 282471d7fec4Smrggfx_get_display_priority_high(void) 282571d7fec4Smrg#endif 282671d7fec4Smrg{ 282771d7fec4Smrg if (READ_REG32(MC_MEM_CNTRL1) & MC_XBUSARB) 282871d7fec4Smrg return (1); 282971d7fec4Smrg else 283071d7fec4Smrg return (0); 283171d7fec4Smrg} 283271d7fec4Smrg 283371d7fec4Smrg#endif /* GFX_READ_ROUTINES */ 283471d7fec4Smrg 283571d7fec4Smrg/* END OF FILE */ 2836