1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/gx2_9211.c,v 1.3 2003/01/14 09:34:35 alanh Exp $ */
2/*
3 * $Workfile: gx2_9211.c $
4 *
5 * This header file defines the pneumonics used when calling Durango routines.
6 * This file is automatically included by gfx_rtns.h
7 *
8 * NSC_LIC_ALTERNATIVE_PREAMBLE
9 *
10 * Revision 1.0
11 *
12 * National Semiconductor Alternative GPL-BSD License
13 *
14 * National Semiconductor Corporation licenses this software
15 * ("Software"):
16 *
17 *      Panel Library
18 *
19 * under one of the two following licenses, depending on how the
20 * Software is received by the Licensee.
21 *
22 * If this Software is received as part of the Linux Framebuffer or
23 * other GPL licensed software, then the GPL license designated
24 * NSC_LIC_GPL applies to this Software; in all other circumstances
25 * then the BSD-style license designated NSC_LIC_BSD shall apply.
26 *
27 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
28
29/* NSC_LIC_BSD
30 *
31 * National Semiconductor Corporation Open Source License for Durango
32 *
33 * (BSD License with Export Notice)
34 *
35 * Copyright (c) 1999-2001
36 * National Semiconductor Corporation.
37 * All rights reserved.
38 *
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 *
43 *   * Redistributions of source code must retain the above copyright
44 *     notice, this list of conditions and the following disclaimer.
45 *
46 *   * Redistributions in binary form must reproduce the above
47 *     copyright notice, this list of conditions and the following
48 *     disclaimer in the documentation and/or other materials provided
49 *     with the distribution.
50 *
51 *   * Neither the name of the National Semiconductor Corporation nor
52 *     the names of its contributors may be used to endorse or promote
53 *     products derived from this software without specific prior
54 *     written permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
57 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
58 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
59 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
60 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
61 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
63 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
64 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
65 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
66 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
68 * OF SUCH DAMAGE.
69 *
70 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
71 * YOUR JURISDICTION. It is licensee's responsibility to comply with
72 * any export regulations applicable in licensee's jurisdiction. Under
73 * CURRENT (2001) U.S. export regulations this software
74 * is eligible for export from the U.S. and can be downloaded by or
75 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
76 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
77 * Syria, Sudan, Afghanistan and any other country to which the U.S.
78 * has embargoed goods and services.
79 *
80 * END_NSC_LIC_BSD */
81
82/* NSC_LIC_GPL
83 *
84 * National Semiconductor Corporation Gnu General Public License for Durango
85 *
86 * (GPL License with Export Notice)
87 *
88 * Copyright (c) 1999-2001
89 * National Semiconductor Corporation.
90 * All rights reserved.
91 *
92 * Redistribution and use in source and binary forms, with or without
93 * modification, are permitted under the terms of the GNU General
94 * Public License as published by the Free Software Foundation; either
95 * version 2 of the License, or (at your option) any later version
96 *
97 * In addition to the terms of the GNU General Public License, neither
98 * the name of the National Semiconductor Corporation nor the names of
99 * its contributors may be used to endorse or promote products derived
100 * from this software without specific prior written permission.
101 *
102 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
103 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
104 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
105 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
106 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
107 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
108 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
109 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
110 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
111 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
112 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
113 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
114 * OF SUCH DAMAGE. See the GNU General Public License for more details.
115 *
116 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
117 * YOUR JURISDICTION. It is licensee's responsibility to comply with
118 * any export regulations applicable in licensee's jurisdiction. Under
119 * CURRENT (2001) U.S. export regulations this software
120 * is eligible for export from the U.S. and can be downloaded by or
121 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
122 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
123 * Syria, Sudan, Afghanistan and any other country to which the U.S.
124 * has embargoed goods and services.
125 *
126 * You should have received a copy of the GNU General Public License
127 * along with this file; if not, write to the Free Software Foundation,
128 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
129 *
130 * END_NSC_LIC_GPL */
131
132#include "92xx.h"
133#include "gx2_9211.h"
134#include "pnl_defs.h"
135
136#if defined(_WIN32)			/*windows */
137#include "gfx_defs.h"
138
139extern DEV_STATUS gfx_msr_read(unsigned int device, unsigned int msrRegister,
140			       Q_WORD * msrValue);
141extern DEV_STATUS gfx_msr_write(unsigned int device, unsigned int msrRegister,
142				Q_WORD * msrValue);
143#endif
144
145static unsigned long FPBaseAddr;
146
147void
148SetFPBaseAddr(unsigned long addr)
149{
150
151   FPBaseAddr = addr;
152}
153
154/****************************************************************************
155 * protected_mode_access( unsigned long mode, unsigned long width,
156 * unsigned long addr, unsigned char* pdata )
157 * This function provides access to physical memory at the requested address.
158 * mode is:
159 *        GX2_READ or GX2_WRITE (accesses a single byte, word or double
160 *        word depending on the value of "width".  Only 1, 2 or 4 supported).
161 *        READ_BYTES, WRITE_BYTES accesses "width" number of bytes (8 bits)
162 *        READ_WORDS, WRITE_WORDS accesses "width" number of words (16 bits)
163 *        READ_DWORDS, WRITE_DWORDS accesses "width" number of dwords (32 bits)
164 * width is: The size of the access.  For READ or WRITE, only 1, 2 and 4 are
165 *        supported.  For other modes, width is not limited but will cause
166 *        paging if the block traverses page boundaries.
167 * addr is: The physical address being accessed
168 * pdata is: A pointer to the data to be read or written into.
169 * NOTE! WORD or DWORD accesses can only be made on WORD or DWORD boundaries!
170 ****************************************************************************/
171void
172protected_mode_access(unsigned long mode,
173		      unsigned long width, unsigned long addr, char *pdata)
174{
175   void *ptr = (void *)(FPBaseAddr + addr);
176
177   /* type specific buffer pointers */
178   char *byte_data = (char *)pdata;
179   unsigned long *word_data = (unsigned long *)pdata;
180   unsigned long *dword_data = (unsigned long *)pdata;
181
182   if (mode == GX2_READ) {
183      switch (width) {
184      case FOUR_BYTES:
185	 *(dword_data) = (unsigned long)(*(unsigned long *)ptr);
186	 break;
187      case TWO_BYTES:
188	 *(word_data) = (unsigned long)(*(unsigned long *)ptr);
189	 break;
190      default:
191	 *(byte_data) = (char)(*(char *)ptr);
192	 break;
193      }
194   } /* end  GX2_READ */
195   else if (mode == GX2_WRITE) {
196      switch (width) {
197      case FOUR_BYTES:
198	 *(unsigned long *)ptr = *dword_data;
199	 break;
200      case TWO_BYTES:
201	 *(unsigned long *)ptr = *word_data;
202	 break;
203      default:
204	 *(char *)ptr = *byte_data;
205	 break;
206      }					/* end switch(mode) */
207   }
208   /* end case GX2_WRITE */
209   return;
210
211}					/* End of protected_mode_access. */
212
213/*************************************************************************
214 * void write_video_reg64_low( unsigned long offset, unsigned long value )
215 * Writes value to the low 32 bits of the 64 bit memory mapped video
216 * register indicated by offset.
217 * This function uses Sys_info.video_reg_base as the base address, so
218 * the value of offset should be with respect to this base.
219 *************************************************************************/
220void
221write_video_reg64_low(unsigned long offset, unsigned long value)
222{
223   protected_mode_access(GX2_WRITE, FOUR_BYTES,
224			 FPBaseAddr + offset, (char *)&value);
225}					/*end write_video_reg64_low() */
226
227/*************************************************************************
228 * unsigned long read_video_reg64_low( unsigned long offset )
229 * Returns the contents of the low 32 bits of the 64 bit memory mapped
230 * video register indicated by offset.
231 * This function uses Sys_info.video_reg_base as the base address, so
232 * the value of offset should be with respect to this base.
233 *************************************************************************/
234unsigned long
235read_video_reg64_low(unsigned long offset)
236{
237   unsigned long data;
238
239   protected_mode_access(GX2_READ, FOUR_BYTES,
240			 FPBaseAddr + offset, (char *)&data);
241   return (data);
242}					/*end read_video_reg64_low() */
243
244/*******************************************************************************
245 * void Redcloud_fp_reg( int mode, unsigned long address, unsigned long *data )
246 *
247 * Writes and reads dwords to the Redcloud flat panel registers in the Redcloud
248 * Display Filter.  There's no clock control, chip select or timing to deal with.
249 * This routine expects the actual GX2 macro definitions for the address.
250 *
251 * Parameters:
252 *			mode:		An integer value for a GX2_READ or GX2_WRITE operation
253 *						0 = GX2_Read and 1 = GX2_Write
254 *			address:	A dword value representing the offset of the register.
255 *			data:		A pointer to a dword value that is to be written in to
256 *						the required register.  In case of a Read operation this
257 *						will point to the result of the Read operation.
258 *
259 *******************************************************************************/
260void
261Redcloud_fp_reg(int mode, unsigned long address, unsigned long *data)
262{
263   if (mode == GX2_READ) {
264      *data = read_video_reg64_low(address);
265   } else {
266      write_video_reg64_low(address, *data);
267   }
268
269}					/* End of Redcloud_fp_reg() */
270
271/*-------------------------------------------------------------------
272 *
273 * SET_92XX_MODE_PARAMS
274 * This routine sets the 9211 mode parameters.
275 *
276 *-------------------------------------------------------------------*/
277
278void
279set_Redcloud_92xx_mode_params(int mode)
280{
281   CS92xx_MODE *pMode = &FPModeParams[mode];
282   unsigned long temp_data = 0;
283   unsigned long base_data;
284   Q_WORD msrValue;
285
286   /* on a Redcloud, we need to set up the DF pad select MSR */
287   if (gfx_msr_read(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue) == FOUND) {
288      msrValue.low &= ~GX2_VP_PAD_SELECT_MASK;
289      if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) {
290	 msrValue.low = GX2_VP_PAD_SELECT_TFT;
291      } else {
292	 msrValue.low = GX2_VP_PAD_SELECT_DSTN;
293      }
294      gfx_msr_write(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue);
295   }
296
297   /* Turn the 92xx power off before setting any new parameters. */
298   temp_data = pMode->power_management & ~GX2_FP_PM_PWR_ON;
299   Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN, (unsigned long *)&temp_data);
300
301   /* Set 9211 registers using the desired panel settings */
302
303   Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING1,
304		   (unsigned long *)&pMode->panel_timing1);
305
306   /* On Redcloud, bit 31 is now reserved. */
307   temp_data = pMode->panel_timing2 & 0x7FFFFFFF;
308   Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING2,
309		   (unsigned long *)&temp_data);
310
311   /* On Redcloud TFT parts, set this to 0x70 so all 8 bits per color run
312    * thru fp crc but only non-TFT parts.  Otherwise, set it to be 0x50.
313    * (source: Larry G.).
314    */
315   if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) {
316      temp_data = GX2_FP_CRC_PASS_THRU_MASK;
317   } else {
318      temp_data = pMode->rev_C_dither_frc;
319   }
320   Redcloud_fp_reg(GX2_WRITE, GX2_FP_DITH_FR_CNTRL,
321		   (unsigned long *)&temp_data);
322   Redcloud_fp_reg(GX2_WRITE, GX2_FP_BLFSR,
323		   (unsigned long *)&pMode->blue_lsfr_seed);
324   Redcloud_fp_reg(GX2_WRITE, GX2_FP_RLFSR,
325		   (unsigned long *)&pMode->red_green_lsfr_seed);
326
327   /* Set the memory information, then the power register last.
328    * This will turn the panel on at the 9211.
329    */
330
331   Redcloud_fp_reg(GX2_READ, GX2_FP_FBB, (unsigned long *)&base_data);
332   if (base_data != 0x41780000) {
333      base_data = 0x41780000;
334      Redcloud_fp_reg(GX2_WRITE, GX2_FP_FBB, (unsigned long *)&base_data);
335   }
336
337   Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN,
338		   (unsigned long *)&pMode->power_management);
339
340}					/*end set_92xx_mode_params() */
341
342/* -----------------------------------------------------------------------
343 *
344 * SET_FLAT_PANEL_MODE
345 *
346 * This routine sets the specified flat panel moden parameters in
347 * the 9211.
348 * Returns PASS if successful, FAIL if the mode parameters could
349 * not be set.
350 *
351 *------------------------------------------------------------------------*/
352
353unsigned char
354set_Redcloud_92xx_mode(Pnl_PanelStat * pstat)
355{
356   int mode;
357
358   /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
359
360   for (mode = 0; mode < NUM_92XX_MODES; mode++) {
361      if ((FPModeParams[mode].xres == pstat->XRes) &&
362	  (FPModeParams[mode].yres == pstat->YRes) &&
363	  (FPModeParams[mode].bpp == pstat->Depth) &&
364	  (FPModeParams[mode].panel_type == pstat->Type) &&
365	  (FPModeParams[mode].color_type == pstat->MonoColor)) {
366
367	 /* SET THE 92xx FOR THE SELECTED MODE */
368	 set_Redcloud_92xx_mode_params(mode);
369	 return TRUE;
370      }					/* end if() */
371   }					/* end for() */
372   return FALSE;
373
374}					/* end set_Centaurus_92xx_mode() */
375
376void
377Redcloud_9211init(Pnl_PanelStat * pstat)
378{
379
380   set_Redcloud_92xx_mode(pstat);
381
382}
383