1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/panel/cen9211.c,v 1.1 2002/12/10 15:12:28 alanh Exp $ */
2/*
3 * $Workfile: cen9211.c $
4 *
5 * File Contents: 	This file contains panel functions to interface with
6 *                  the centaraus platform.
7 *
8 * SubModule:       Geode FlatPanel library
9 *
10 */
11
12/*
13 * NSC_LIC_ALTERNATIVE_PREAMBLE
14 *
15 * Revision 1.0
16 *
17 * National Semiconductor Alternative GPL-BSD License
18 *
19 * National Semiconductor Corporation licenses this software
20 * ("Software"):
21 *
22 *     Geode graphics driver for panel support
23 * under one of the two following licenses, depending on how the
24 * Software is received by the Licensee.
25 *
26 * If this Software is received as part of the Linux Framebuffer or
27 * other GPL licensed software, then the GPL license designated
28 * NSC_LIC_GPL applies to this Software; in all other circumstances
29 * then the BSD-style license designated NSC_LIC_BSD shall apply.
30 *
31 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
32
33/* NSC_LIC_BSD
34 *
35 * National Semiconductor Corporation Open Source License for Durango
36 *
37 * (BSD License with Export Notice)
38 *
39 * Copyright (c) 1999-2001
40 * National Semiconductor Corporation.
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 *
47 *   * Redistributions of source code must retain the above copyright
48 *     notice, this list of conditions and the following disclaimer.
49 *
50 *   * Redistributions in binary form must reproduce the above
51 *     copyright notice, this list of conditions and the following
52 *     disclaimer in the documentation and/or other materials provided
53 *     with the distribution.
54 *
55 *   * Neither the name of the National Semiconductor Corporation nor
56 *     the names of its contributors may be used to endorse or promote
57 *     products derived from this software without specific prior
58 *     written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
61 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
62 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
63 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
64 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
65 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
67 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
68 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
69 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
70 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
72 * OF SUCH DAMAGE.
73 *
74 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
75 * YOUR JURISDICTION. It is licensee's responsibility to comply with
76 * any export regulations applicable in licensee's jurisdiction. Under
77 * CURRENT (2001) U.S. export regulations this software
78 * is eligible for export from the U.S. and can be downloaded by or
79 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
80 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
81 * Syria, Sudan, Afghanistan and any other country to which the U.S.
82 * has embargoed goods and services.
83 *
84 * END_NSC_LIC_BSD */
85
86/* NSC_LIC_GPL
87 *
88 * National Semiconductor Corporation Gnu General Public License for Durango
89 *
90 * (GPL License with Export Notice)
91 *
92 * Copyright (c) 1999-2001
93 * National Semiconductor Corporation.
94 * All rights reserved.
95 *
96 * Redistribution and use in source and binary forms, with or without
97 * modification, are permitted under the terms of the GNU General
98 * Public License as published by the Free Software Foundation; either
99 * version 2 of the License, or (at your option) any later version
100 *
101 * In addition to the terms of the GNU General Public License, neither
102 * the name of the National Semiconductor Corporation nor the names of
103 * its contributors may be used to endorse or promote products derived
104 * from this software without specific prior written permission.
105 *
106 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
107 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
108 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
109 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
110 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
111 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
112 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
113 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
114 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
115 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
116 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
117 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
118 * OF SUCH DAMAGE. See the GNU General Public License for more details.
119 *
120 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
121 * YOUR JURISDICTION. It is licensee's responsibility to comply with
122 * any export regulations applicable in licensee's jurisdiction. Under
123 * CURRENT (2001) U.S. export regulations this software
124 * is eligible for export from the U.S. and can be downloaded by or
125 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
126 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
127 * Syria, Sudan, Afghanistan and any other country to which the U.S.
128 * has embargoed goods and services.
129 *
130 * You should have received a copy of the GNU General Public License
131 * along with this file; if not, write to the Free Software Foundation,
132 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
133 *
134 * END_NSC_LIC_GPL */
135
136#include "cen9211.h"
137
138static unsigned char sioc2_orig_val;
139static unsigned char must_restore_97317 = FALSE;
140
141/********************************************************************
142 *
143 * PASS_FAIL init_GPIO(void);
144 * Initializes the GPIO pins in the Cx5530 or the National PC97317
145 * for use with a 9211 on a Marmot or Centaurus board. Uses
146 * the global variables RdPCIVal and sioc2_orig_val.
147 *
148 *********************************************************************/
149
150unsigned char
151init_Centaurus_GPIO(void)
152{
153   unsigned char reg_val;
154   static unsigned char first_time = TRUE;
155
156   /* The Centaurus board uses ports 1 and 2 of the 97317 for GPIO.
157    * These ports require bank 0 to be active. The first thing we will
158    * do is verify that bank 0 is active and set it if it is not.
159    */
160
161   /* set the index for access to the configuration register */
162   gfx_outb(CENT_CONFIG_INDEX, CENT_SIOC2);
163   reg_val = gfx_inb(CENT_CONFIG_DATA);
164
165   /* set to bank 0 */
166   if (reg_val & CENT_GPIO_BANK_SELECT) {
167      gfx_outb(CENT_CONFIG_DATA,
168	       (unsigned char)(reg_val & ~CENT_GPIO_BANK_SELECT));
169   }
170
171   /* If this is the first time we have modified sioc2, we must
172    * save the current value (set by the BIOS) for restoration by
173    * the calling program, set the global flag must_restore_97317, and set
174    * first_time to FALSE.
175    */
176
177   if (first_time == TRUE) {
178      sioc2_orig_val = reg_val;
179      must_restore_97317 = TRUE;
180      first_time = FALSE;
181   }
182
183   /* set port 1 direction */
184   reg_val = gfx_inb(CENT_PORT1_DIRECTION);
185
186   /* make GPIO 14 and 17 outputs  */
187   reg_val |= CENT_97317_CLOCK_MASK | CENT_97317_DATA_OUT_MASK;
188   gfx_outb(CENT_PORT1_DIRECTION, reg_val);
189
190   /* set port 2 direction */
191   reg_val = gfx_inb(CENT_PORT2_DIRECTION);
192
193   /* make GPIO 20 an output */
194
195   reg_val |= CENT_97317_CHIP_SEL_MASK;
196
197   /* make GPIO 21 an input */
198
199   reg_val &= ~CENT_97317_DATA_IN_MASK;
200   gfx_outb(CENT_PORT2_DIRECTION, reg_val);
201
202   /* make GPIO 14 and 17 push-pull */
203
204   reg_val = gfx_inb(CENT_PORT1_OUTPUT_TYPE);
205   reg_val |= CENT_97317_CLOCK_MASK | CENT_97317_DATA_OUT_MASK;
206   gfx_outb(CENT_PORT1_OUTPUT_TYPE, reg_val);
207
208   /* make GPIO 20 and 21 push-pull */
209   reg_val = gfx_inb(CENT_PORT2_OUTPUT_TYPE);
210   reg_val |= CENT_97317_CHIP_SEL_MASK | CENT_97317_DATA_IN_MASK;
211   gfx_outb(CENT_PORT2_OUTPUT_TYPE, reg_val);
212   return CENT_PASS;
213
214}					/* end init_GPIO() */
215
216/*********************************************************************
217 *
218 * PASS_FAIL init_9211(void);
219 * Initializes (sets to 0) the clock, chip select, and data pins
220 * of the Cx9211 on a Marmot or Centaurus board.
221 *
222 **********************************************************************/
223
224unsigned char
225init_Centaurus_9211(void)
226{
227   unsigned char ReadData;
228
229   /* Uses the 97317 for GPIO.
230    * we will use the clock port define for port 1
231    */
232   ReadData = gfx_inb(CENT_97317_CLOCK_PORT);
233   ReadData &= ~CENT_97317_CLOCK_MASK & ~CENT_97317_DATA_OUT_MASK;
234   gfx_outb(CENT_97317_CLOCK_PORT, ReadData);
235   /* we will use the chip select port define for port 2 */
236   ReadData = gfx_inb(CENT_97317_CHIP_SELECT);
237   ReadData &= ~CENT_97317_CHIP_SEL_MASK & ~CENT_97317_DATA_IN_MASK;
238   gfx_outb(CENT_97317_CHIP_SELECT, ReadData);
239   return (CENT_PASS);
240
241}					/*end init_9211() */
242
243/******************************************************************
244 *
245 * PASS_FAIL restore_97317_SIOC2(void);
246 * Restores the original value to the 97317 SIOC2 register using
247 * the global variable sioc2_orig_val. Returns PASS if the value
248 * was written, FAIL if not.
249 *
250 *******************************************************************/
251
252unsigned char
253restore_Centaurus_97317_SIOC2(void)
254{
255   /* set the global flag */
256   if (must_restore_97317 == TRUE) {
257      unsigned char cfg;
258
259      /* set the index for access to the configuration register */
260      gfx_outb(CENT_CONFIG_INDEX, CENT_SIOC2);
261
262      /* restore the value */
263      gfx_outb(CENT_CONFIG_DATA, sioc2_orig_val);
264
265      /* now read and verify */
266      cfg = gfx_inb(CENT_CONFIG_DATA);
267      if (cfg == sioc2_orig_val)
268	 return (CENT_PASS);
269      else
270	 return (CENT_FAIL);
271
272   }					/* end if() */
273   return (CENT_FAIL);
274
275}					/* end restore_97317_SIOC2bank() */
276
277/* -----------------------------------------------------------------------
278 *
279 * SET_FLAT_PANEL_MODE
280 *
281 * This routine sets the specified flat panel moden parameters in
282 * the 9211.
283 * Returns PASS if successful, FAIL if the mode parameters could
284 * not be set.
285 *
286 *------------------------------------------------------------------------*/
287
288unsigned char
289set_Centaurus_92xx_mode(Pnl_PanelStat * pstat)
290{
291   int mode;
292
293   /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
294
295   for (mode = 0; mode < NUM_92XX_MODES; mode++) {
296      if ((FPModeParams[mode].xres == pstat->XRes) &&
297	  (FPModeParams[mode].yres == pstat->YRes) &&
298	  (FPModeParams[mode].bpp == pstat->Depth) &&
299	  (FPModeParams[mode].panel_type == pstat->Type) &&
300	  (FPModeParams[mode].color_type == pstat->MonoColor)) {
301
302	 /* SET THE 92xx FOR THE SELECTED MODE */
303	 set_Centaurus_92xx_mode_params(mode);
304	 return (CENT_PASS);
305      }					/* end if() */
306   }					/* end for() */
307   return (CENT_FAIL);
308
309}					/* end set_Centaurus_92xx_mode() */
310
311/*-------------------------------------------------------------------
312 *
313 * SET_92XX_MODE_PARAMS
314 * This routine sets the 9211 mode parameters.
315 *
316 *-------------------------------------------------------------------*/
317
318void
319set_Centaurus_92xx_mode_params(int mode)
320{
321   CS92xx_MODE *pMode = &FPModeParams[mode];
322   unsigned long off_data = 0;
323
324   /* Turn the 92xx power off before setting any new parameters.
325    * Since we are going to reset all the power bit positions, we will
326    * force the power register to 0.
327    */
328
329   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data);
330
331   /* set 9211 registers using the desired panel settings */
332
333   Centaurus_write_gpio(FOUR_BYTES,
334			CS92xx_LCD_PAN_TIMING1, pMode->panel_timing1);
335
336   Centaurus_write_gpio(FOUR_BYTES,
337			CS92xx_LCD_PAN_TIMING2, pMode->panel_timing2);
338
339   if (Pnl_Rev_ID == PNL_9211_C) {
340
341      /* load the LSFR seeds */
342      Centaurus_write_gpio(FOUR_BYTES,
343			   CS92xx_LCD_DITH_FR_CNTRL, pMode->rev_C_dither_frc);
344
345      Centaurus_write_gpio(FOUR_BYTES,
346			   CS92xx_BLUE_LSFR_SEED, pMode->blue_lsfr_seed);
347
348      Centaurus_write_gpio(FOUR_BYTES,
349			   CS92xx_RED_GREEN_LSFR_SEED,
350			   pMode->red_green_lsfr_seed);
351   } else {
352
353      Centaurus_write_gpio(FOUR_BYTES,
354			   CS92xx_LCD_DITH_FR_CNTRL, pMode->pre_C_dither_frc);
355
356      Centaurus_write_gpio(FOUR_BYTES,
357			   CS92xx_LCD_BLOCK_SEL1, pMode->block_select1);
358
359      Centaurus_write_gpio(FOUR_BYTES,
360			   CS92xx_LCD_BLOCK_SEL2, pMode->block_select2);
361
362      Centaurus_write_gpio(FOUR_BYTES,
363			   CS92xx_LCD_DISPER1, pMode->dispersion1);
364
365      Centaurus_write_gpio(FOUR_BYTES,
366			   CS92xx_LCD_DISPER2, pMode->dispersion2);
367
368      CentaurusProgramFRMload();
369   }
370
371   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_MEM_CNTRL,
372			pMode->memory_control);
373
374   /* Set the power register last. This will turn the panel on at the 9211. */
375
376   Centaurus_write_gpio(FOUR_BYTES,
377			CS92xx_LCD_PWR_MAN, pMode->power_management);
378
379}					/* end set_Centaurus_92xx_mode_params() */
380
381void
382Centaurus_write_gpio(int width, ULONG address, unsigned long data)
383{
384   int num_clock_toggles;
385   int count;
386   unsigned long Addr = address;
387
388   enable_Centaurus_9211_chip_select();
389
390   /* Write 1 Clock period of no valid transfer */
391   write_Centaurus_CX9211_GPIO(CENT_NO_DATA);
392
393   /* Write 1 control bit (the data book calls this the control bar write) */
394   write_Centaurus_CX9211_GPIO(0x1);
395
396   /* Write the 12-bit address */
397   for (count = 0; count < 12; count++) {
398      write_Centaurus_CX9211_GPIO((unsigned char)(Addr & 0x01));
399      /*the 9211 expects data LSB->MSB */
400      Addr = Addr >> 1;
401   }
402
403   /* write */
404   write_Centaurus_CX9211_DWdata(data);
405
406   /* a write will require four toggles after disabling CS */
407   num_clock_toggles = CENT_NUM_WRITE_CLOCK_TOGGLES;
408   disable_Centaurus_9211_chip_select();
409
410   /* now toggle the clock */
411   for (count = 0; count < num_clock_toggles; count++) {
412      toggle_Centaurus_9211_clock();
413   }
414   return;
415
416}					/* end Centaurus_write_gpio() */
417
418unsigned long
419Centaurus_read_gpio(int width, unsigned long address)
420{
421   int num_clock_toggles;
422   int count;
423   unsigned long Addr = address;
424   unsigned long data;
425
426   enable_Centaurus_9211_chip_select();
427
428   /* Write 1 Clock period of no valid transfer */
429   write_Centaurus_CX9211_GPIO(CENT_NO_DATA);
430
431   /* Write 1 control bit (the data book calls this the control bar write) */
432   write_Centaurus_CX9211_GPIO(0x1);
433
434   /* Write the 12-bit address */
435   for (count = 0; count < 12; count++) {
436      write_Centaurus_CX9211_GPIO((unsigned char)(Addr & 0x01));
437
438      /*the 9211 expects data LSB->MSB */
439      Addr = Addr >> 1;
440   }
441
442   data = read_Centaurus_CX9211_DWdata();
443
444   /* a read will require one toggle after disabling CS */
445   num_clock_toggles = CENT_NUM_READ_CLOCK_TOGGLES;
446   disable_Centaurus_9211_chip_select();
447
448   /* now toggle the clock */
449   for (count = 0; count < num_clock_toggles; count++) {
450      toggle_Centaurus_9211_clock();
451   }
452   return data;
453
454}					/* end Centaurus_read_gpio() */
455
456/*******************************************************************
457 *
458 * void enable_Centaurus_9211_chip_select(void);
459 * Enables the chip select of the CX9211 using the National 97317
460 * on a Centaurus board.
461 *
462 *******************************************************************/
463
464void
465enable_Centaurus_9211_chip_select(void)
466{
467   unsigned char cs_port_val;
468
469   /* Set the chip select (GPIO20) high */
470   cs_port_val = gfx_inb(CENT_97317_CHIP_SELECT);
471   gfx_outb(CENT_97317_CHIP_SELECT,
472	    (unsigned char)(cs_port_val | CENT_97317_CHIP_SEL_MASK));
473   return;
474
475}					/* end enable_Centaurus_9211_chip_select() */
476
477/********************************************************************
478 *
479 * void disable_Centaurus_9211_chip_select(void);
480 * Disables the chip select of the CX9211 using the National 97317
481 * on a Centaurus board.
482 *
483 *******************************************************************/
484
485void
486disable_Centaurus_9211_chip_select(void)
487{
488   unsigned char cs_port_val;
489
490   /* Set the chip select (GPIO20) low */
491   cs_port_val = gfx_inb(CENT_97317_CHIP_SELECT);
492   gfx_outb(CENT_97317_CHIP_SELECT,
493	    (unsigned char)(cs_port_val & ~CENT_97317_CHIP_SEL_MASK));
494   return;
495
496}					/* end disable_Centaurus_9211_chip_select() */
497
498/**********************************************************************
499 *
500 * void toggle_Centaurus_9211_clock(void);
501 * Toggles the clock bit of the CX9211 using the National 97317 on a
502 * Centaurus board. Assumes the 9211 clock bit has previously been
503 * initialized to 0 (this way we do not have to waste GPIO cycles
504 * windowing the clock pulse).
505 *
506 **********************************************************************/
507
508void
509toggle_Centaurus_9211_clock(void)
510{
511   unsigned char port_val;
512
513   /* get the 97317 GPIO port contents for the 9211 clock */
514
515   port_val = gfx_inb(CENT_97317_CLOCK_PORT);
516   /* set the clock bit high */
517   gfx_outb(CENT_97317_CLOCK_PORT,
518	    (unsigned char)(port_val | CENT_97317_CLOCK_MASK));
519
520   /* set the clock bit low */
521   gfx_outb(CENT_97317_CLOCK_PORT,
522	    (unsigned char)(port_val & ~CENT_97317_CLOCK_MASK));
523
524}					/* end toggle_Centaurus_9211_clock() */
525
526/********************************************************************
527 *
528 * void write_Centaurus_CX9211_GPIO(unsigned char databit);
529 * Writes the value in bit 0 of the value passed in databit to
530 * the 9211 through the GPIO interface of the National 97317 on a
531 * Centaurus board.
532 * NOTE: This function does not set or reset the chip select line!
533 *
534 *******************************************************************/
535
536void
537write_Centaurus_CX9211_GPIO(unsigned char databit)
538{
539   unsigned char data_port_val;
540
541   /* Set the data bit for (GPIO17) */
542   databit <<= 7;
543
544   /* read the value of the other bits in the 97317 data port */
545   data_port_val = gfx_inb(CENT_97317_DATA_OUTPORT);
546
547   /* set the bit accordingly */
548   data_port_val &= ~CENT_97317_DATA_OUT_MASK;
549   data_port_val |= databit;
550   gfx_outb(CENT_97317_DATA_OUTPORT, data_port_val);
551
552   /* clock the data */
553   toggle_Centaurus_9211_clock();
554   return;
555
556}					/* end write_Centaurus_CX9211_GPIO() */
557
558/*****************************************************************
559 *
560 * void write_Centaurus_CX9211_DWdata(unsigned long data);
561 * Writes the doubleword value passed in data to the CX9211
562 * using GPIO Pins of the National 97317 on a Centaurus board.
563 * This function assumes the Direction register of the 97317
564 * and the address register of the CX9211 have been previously set.
565 * Uses the global variable count.
566 * NOTE: This function does not set or reset the chip select line!
567 *
568 ******************************************************************/
569
570void
571write_Centaurus_CX9211_DWdata(unsigned long data)
572{
573   int count;
574
575   /* Send the read/write command to the 9211 first. */
576
577   write_Centaurus_CX9211_GPIO(CENT_WRITE);
578
579   /* Now write the 32-bit Data */
580   for (count = 0; count < 32; count++) {
581      write_Centaurus_CX9211_GPIO((unsigned char)(data & 0x01));
582
583      /* the 9211 expects the data LSB->MSB */
584      data >>= 1;
585   }
586   return;
587
588}					/* end write_Centaurus_CX9211_DWdata() */
589
590/*********************************************************************
591 *
592 * unsigned char read_Centaurus_CX9211_GPIO(void);
593 * Returns the current value of the databit of the 9211 in bit 0
594 * using the GPIO interface of the National 97317 on a Centaurus board.
595 * NOTE: This function does not set or reset the chip select line!
596 *
597 *********************************************************************/
598
599unsigned char
600read_Centaurus_CX9211_GPIO(void)
601{
602   unsigned char data_port_val;
603
604   toggle_Centaurus_9211_clock();
605
606   /* read the data */
607   data_port_val = gfx_inb(CENT_97317_DATA_INPORT);
608
609   /* Save the data from (GPIO21) as bit 0 */
610   data_port_val >>= 1;
611   return (data_port_val & 0x1);
612
613}					/* end read_Centaurus_CX9211_GPIO() */
614
615/**********************************************************************
616 *
617 * void read_Centaurus_CX9211_DWdata(unsigned long *data);
618 * Reads a doubleword value from the CX9211 using GPIO Pins of
619 * the National 97317 on a Centaurus board.
620 * This function assumes the Direction register of the 97317 and
621 * the address register of the CX9211 have been previously set.
622 * NOTE: This function does not set or reset the chip select line!
623 *
624 ***********************************************************************/
625
626unsigned long
627read_Centaurus_CX9211_DWdata(void)
628{
629   unsigned char ReadData;
630   int count;
631   unsigned long Data;
632
633   /* Send read/write command word to the 9211 first. */
634   write_Centaurus_CX9211_GPIO(CENT_READ);
635
636   /* The data book (revision 0.1) states 8 clock periods of no valid data.
637    *   However, the data becomes valid on the eighth clock, making the eighth
638    *   clock valid. Since read_Centaurus_GPIO() toggles the clock before
639    *   reading, we will only toggle the clock 7 times here.
640    */
641   for (count = 0; count < 7; count++)	/* works */
642      toggle_Centaurus_9211_clock();
643
644   /* Now read the 32-bit Data, bit by bit in a single loop. */
645   Data = 0;
646   for (count = 0; count < 32; count++) {
647      ReadData = read_Centaurus_CX9211_GPIO();
648      /* 9211 sends data  LSB->MSB */
649      Data = Data | (((unsigned long)ReadData) << count);
650   }					/* end for() */
651
652   return Data;
653
654}					/* end read_Centaurus_CX9211_DWdata() */
655
656void
657Centaurus_Get_9211_Details(unsigned long flags, PPnl_PanelParams pParam)
658{
659   unsigned long PanelType;
660   int i;
661
662   for (i = 0; i < 0x7fff; i++) {
663   }
664
665   init_Centaurus_GPIO();
666
667   for (i = 0; i < 5; i++)
668      toggle_Centaurus_9211_clock();
669
670   if (flags & PNL_PANELCHIP) {
671
672      PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x430);
673      PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x430);
674      if ((PanelType & 0xFFFF0000) == 0x92110000) {
675
676	 /* found 9211 */
677	 /* check the values for revision ID */
678	 if (PanelType >= 0x92110301)
679	    pParam->PanelChip = PNL_9211_C;
680	 else if ((PanelType >= 0x92110101) && (PanelType < 0x92110301))
681	    pParam->PanelChip = PNL_9211_A;
682	 else
683	    pParam->PanelChip = PNL_UNKNOWN_CHIP;
684      } else {				/* no 9211 present */
685	 pParam->PanelChip = PNL_UNKNOWN_CHIP;
686      }
687      Pnl_Rev_ID = pParam->PanelChip;
688   }
689   /* if end */
690   if ((pParam->PanelChip != PNL_UNKNOWN_CHIP) && (flags & PNL_PANELSTAT)) {
691      PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x438);
692      PanelType &= 0x00f8f8f8;
693      PanelType |= 0x00070000;
694      Centaurus_write_gpio(FOUR_BYTES, 0x438, PanelType);
695      PanelType = 0;
696      PanelType = Centaurus_read_gpio(FOUR_BYTES, 0x434);
697      PanelType = (PanelType >> 8);
698      PanelType &= 0x7;
699
700      switch (PanelType) {
701      case 0:
702	 pParam->PanelStat.XRes = 800;
703	 pParam->PanelStat.YRes = 600;
704	 pParam->PanelStat.Depth = 18;
705	 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL;
706	 pParam->PanelStat.Type = PNL_TFT;
707	 break;
708      case 1:
709	 pParam->PanelStat.XRes = 640;
710	 pParam->PanelStat.YRes = 480;
711	 pParam->PanelStat.Depth = 8;
712	 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL;
713	 pParam->PanelStat.Type = PNL_SSTN;
714	 break;
715      case 2:
716	 pParam->PanelStat.XRes = 1024;
717	 pParam->PanelStat.YRes = 768;
718	 pParam->PanelStat.Depth = 18;
719	 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL;
720	 pParam->PanelStat.Type = PNL_TFT;
721	 break;
722      case 3:
723	 pParam->PanelStat.XRes = 640;
724	 pParam->PanelStat.YRes = 480;
725	 pParam->PanelStat.Depth = 16;
726	 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL;
727	 pParam->PanelStat.Type = PNL_DSTN;
728	 break;
729      case 4:
730	 pParam->PanelStat.XRes = 640;
731	 pParam->PanelStat.YRes = 480;
732	 pParam->PanelStat.Depth = 18;
733	 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL;
734	 pParam->PanelStat.Type = PNL_TFT;
735	 break;
736      case 5:
737	 pParam->PanelStat.XRes = 1024;
738	 pParam->PanelStat.YRes = 768;
739	 pParam->PanelStat.Depth = 24;
740	 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL;
741	 pParam->PanelStat.Type = PNL_DSTN;
742	 break;
743      case 6:
744	 pParam->PanelStat.XRes = 640;
745	 pParam->PanelStat.YRes = 480;
746	 pParam->PanelStat.Depth = 8;
747	 pParam->PanelStat.MonoColor = PNL_MONO_PANEL;
748	 pParam->PanelStat.Type = PNL_DSTN;
749	 break;
750      case 7:
751	 pParam->PanelStat.XRes = 800;
752	 pParam->PanelStat.YRes = 600;
753	 pParam->PanelStat.Depth = 16;
754	 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL;
755	 pParam->PanelStat.Type = PNL_DSTN;
756	 break;
757      default:
758	 break;
759      }
760   }
761
762}
763
764void
765CentaurusProgramFRMload(void)
766{
767   unsigned long CentaurusFRMtable[] = {
768      0x00000000,
769      0x00000000,
770      0x01000100,
771      0x01000100,
772      0x01010101,
773      0x01010101,
774      0x02081041,
775      0x02081041,
776      0x10111111,
777      0x11111101,
778      0x49249241,
779      0x12412492,
780      0x92244891,
781      0x92244891,
782      0x22252525,
783      0x22252525,
784      0x528294a5,
785      0x2528494a,
786      0x294a5295,
787      0x294a5295,
788      0x54a54a95,
789      0x2952a52a,
790      0x2a552a55,
791      0x2a552a55,
792      0x554aa955,
793      0x2a9552aa,
794      0x2aaa5555,
795      0x2aaa5555,
796      0x55555555,
797      0x2aaaaaaa,
798      0x55555555,
799      0x55555555,
800      0xaaaaaaab,
801      0x55555555,
802      0x5555aaab,
803      0x5555aaab,
804      0xaab556ab,
805      0x556aad55,
806      0x55ab55ab,
807      0x55ab55ab,
808      0xab5ab56b,
809      0x56ad5ad5,
810      0x56b5ad6b,
811      0x56b5ad6b,
812      0xad6d6b5b,
813      0x5ad6b6b6,
814      0x5b5b5b5b,
815      0x5b5b5b5b,
816      0x5F6db6db,
817      0x5F6db6db,
818      0xF776F776,
819      0xF776F776,
820      0xFBDEFBDE,
821      0xFBDEFBDE,
822      0x7eFFBFF7,
823      0x7eFFBFF7,
824      0xFF7FF7F7,
825      0xFF7FF7F7,
826      0xFF7FFF7F,
827      0xFF7FFF7F,
828      0xFFF7FFFF,
829      0xFFF7FFFF,
830      0xFFFFFFFF,
831      0xFFFFFFFF,
832   };
833
834   unsigned char i;
835   unsigned short index;
836   unsigned long data;
837
838   Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_INDEX, 0);
839   index = CS92xx_FRM_MEMORY_DATA;
840   for (i = 0; i < 64; i += 2) {
841      data = CentaurusFRMtable[i];
842      Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, data);
843      data = CentaurusFRMtable[i + 1];
844      Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, data);
845   }
846
847   /*
848    * The first FRM location (64 bits) does not program correctly.
849    * This location always reads back with the last value programmed.
850    * ie. If 32 64-bit values are programmed, location 0 reads
851    * back as the 32nd If 30 locations are programmed, location 0
852    * reads back as the 30th, etc.
853    * Fix this by re-writing location 0 after programming all 64 in
854    * the writeFRM loop in RevCFrmload() in CS9211.
855    */
856
857   Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_INDEX, 0);
858   Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, 0);
859   Centaurus_write_gpio(FOUR_BYTES, CS92xx_FRM_MEMORY_DATA, 0);
860}
861
862/********************************************************************
863 *
864 * void Centaurus_Enable_Power((void);
865 * Enables the power of the CX9211 using the National 97317 on
866 * a Centaurus board.
867 *
868 ********************************************************************/
869
870void
871Centaurus_Power_Up(void)
872{
873   unsigned long off_data = 0x01000000;
874
875   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data);
876   return;
877
878}					/* Centaurus_Disable_Power */
879
880/***********************************************************************
881 *
882 * void Centaurus_Disable_Power((void);
883 * Disables the power of the CX9211 using the National 97317
884 * on a Centaurus board.
885 *
886 **********************************************************************/
887
888void
889Centaurus_Power_Down(void)
890{
891   unsigned long off_data = 0;
892
893   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data);
894   return;
895
896}					/* Centaurus_Disable_Power */
897
898void
899Centaurus_9211init(Pnl_PanelStat * pstat)
900{
901   init_Centaurus_GPIO();
902   init_Centaurus_9211();
903   set_Centaurus_92xx_mode(pstat);
904   restore_Centaurus_97317_SIOC2();
905}
906
907void
908Centaurus_Save_Panel_State(void)
909{
910   /* set 9211 registers using the desired panel settings */
911
912   cs9211_regs.panel_timing1 =
913	 Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING1);
914   cs9211_regs.panel_timing2 =
915	 Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING2);
916   cs9211_regs.dither_frc_ctrl =
917	 Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_DITH_FR_CNTRL);
918   cs9211_regs.blue_lsfr_seed =
919	 Centaurus_read_gpio(FOUR_BYTES, CS92xx_BLUE_LSFR_SEED);
920
921   cs9211_regs.red_green_lsfr_seed =
922	 Centaurus_read_gpio(FOUR_BYTES, CS92xx_RED_GREEN_LSFR_SEED);
923   /* CentaurusProgramFRMload(); */
924
925   cs9211_regs.memory_control =
926	 Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_MEM_CNTRL);
927
928   /* Set the power register last.
929    * This will turn the panel on at the 9211.
930    */
931   cs9211_regs.power_management =
932	 Centaurus_read_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN);
933}
934
935void
936Centaurus_Restore_Panel_State(void)
937{
938
939   unsigned long off_data = 0;
940
941   /* Before restoring the 9211 registers, power off the 9211. */
942   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN, off_data);
943
944   /* set 9211 registers using the desired panel settings */
945
946   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING1,
947			cs9211_regs.panel_timing1);
948
949   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PAN_TIMING2,
950			cs9211_regs.panel_timing2);
951
952   /* load the LSFR seeds */
953
954   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_DITH_FR_CNTRL,
955			cs9211_regs.dither_frc_ctrl);
956
957   Centaurus_write_gpio(FOUR_BYTES, CS92xx_BLUE_LSFR_SEED,
958			cs9211_regs.blue_lsfr_seed);
959
960   Centaurus_write_gpio(FOUR_BYTES, CS92xx_RED_GREEN_LSFR_SEED,
961			cs9211_regs.red_green_lsfr_seed);
962
963   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_MEM_CNTRL,
964			cs9211_regs.memory_control);
965
966   /* Set the power register last. This will turn the panel on at the 9211. */
967
968   Centaurus_write_gpio(FOUR_BYTES, CS92xx_LCD_PWR_MAN,
969			cs9211_regs.power_management);
970
971}
972