1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_regacc.c,v 1.1 2002/12/10 15:12:25 alanh Exp $ */
2/*
3 * $Workfile: nsc_regacc.c $
4 * $Revision: 1.1.1.1 $
5 * $Author: mrg $
6 *
7 * This is the main file used to add Durango graphics support to a software
8 * project.  The main reason to have a single file include the other files
9 * is that it centralizes the location of the compiler options.  This file
10 * should be tuned for a specific implementation, and then modified as needed
11 * for new Durango releases.  The releases.txt file indicates any updates to
12 * this main file, such as a new definition for a new hardware platform.
13 *
14 * In other words, this file should be copied from the Durango source files
15 * once when a software project starts, and then maintained as necessary.
16 * It should not be recopied with new versions of Durango unless the
17 * developer is willing to tune the file again for the specific project.
18 */
19
20/*
21 * NSC_LIC_ALTERNATIVE_PREAMBLE
22 *
23 * Revision 1.0
24 *
25 * National Semiconductor Alternative GPL-BSD License
26 *
27 * National Semiconductor Corporation licenses this software
28 * ("Software"):
29 *
30 *      Durango
31 *
32 * under one of the two following licenses, depending on how the
33 * Software is received by the Licensee.
34 *
35 * If this Software is received as part of the Linux Framebuffer or
36 * other GPL licensed software, then the GPL license designated
37 * NSC_LIC_GPL applies to this Software; in all other circumstances
38 * then the BSD-style license designated NSC_LIC_BSD shall apply.
39 *
40 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
41
42/* NSC_LIC_BSD
43 *
44 * National Semiconductor Corporation Open Source License for Durango
45 *
46 * (BSD License with Export Notice)
47 *
48 * Copyright (c) 1999-2001
49 * National Semiconductor Corporation.
50 * All rights reserved.
51 *
52 * Redistribution and use in source and binary forms, with or without
53 * modification, are permitted provided that the following conditions
54 * are met:
55 *
56 *   * Redistributions of source code must retain the above copyright
57 *     notice, this list of conditions and the following disclaimer.
58 *
59 *   * Redistributions in binary form must reproduce the above
60 *     copyright notice, this list of conditions and the following
61 *     disclaimer in the documentation and/or other materials provided
62 *     with the distribution.
63 *
64 *   * Neither the name of the National Semiconductor Corporation nor
65 *     the names of its contributors may be used to endorse or promote
66 *     products derived from this software without specific prior
67 *     written permission.
68 *
69 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
70 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
71 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
72 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
73 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
74 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
76 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
77 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
78 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
79 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
80 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
81 * OF SUCH DAMAGE.
82 *
83 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
84 * YOUR JURISDICTION. It is licensee's responsibility to comply with
85 * any export regulations applicable in licensee's jurisdiction. Under
86 * CURRENT (2001) U.S. export regulations this software
87 * is eligible for export from the U.S. and can be downloaded by or
88 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
89 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
90 * Syria, Sudan, Afghanistan and any other country to which the U.S.
91 * has embargoed goods and services.
92 *
93 * END_NSC_LIC_BSD */
94
95/* NSC_LIC_GPL
96 *
97 * National Semiconductor Corporation Gnu General Public License for Durango
98 *
99 * (GPL License with Export Notice)
100 *
101 * Copyright (c) 1999-2001
102 * National Semiconductor Corporation.
103 * All rights reserved.
104 *
105 * Redistribution and use in source and binary forms, with or without
106 * modification, are permitted under the terms of the GNU General
107 * Public License as published by the Free Software Foundation; either
108 * version 2 of the License, or (at your option) any later version
109 *
110 * In addition to the terms of the GNU General Public License, neither
111 * the name of the National Semiconductor Corporation nor the names of
112 * its contributors may be used to endorse or promote products derived
113 * from this software without specific prior written permission.
114 *
115 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
116 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
117 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
118 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
119 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
120 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
121 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
122 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
123 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
124 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
125 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
126 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
127 * OF SUCH DAMAGE. See the GNU General Public License for more details.
128 *
129 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
130 * YOUR JURISDICTION. It is licensee's responsibility to comply with
131 * any export regulations applicable in licensee's jurisdiction. Under
132 * CURRENT (2001) U.S. export regulations this software
133 * is eligible for export from the U.S. and can be downloaded by or
134 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
135 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
136 * Syria, Sudan, Afghanistan and any other country to which the U.S.
137 * has embargoed goods and services.
138 *
139 * You should have received a copy of the GNU General Public License
140 * along with this file; if not, write to the Free Software Foundation,
141 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
142 *
143 * END_NSC_LIC_GPL */
144
145#ifdef HAVE_CONFIG_H
146#include "config.h"
147#endif
148
149void gfx_write_reg8(unsigned long offset, unsigned char value);
150void gfx_write_reg16(unsigned long offset, unsigned short value);
151void gfx_write_reg32(unsigned long offset, unsigned long value);
152unsigned short gfx_read_reg16(unsigned long offset);
153unsigned long gfx_read_reg32(unsigned long offset);
154void gfx_write_vid32(unsigned long offset, unsigned long value);
155unsigned long gfx_read_vid32(unsigned long offset);
156unsigned long gfx_read_vip32(unsigned long offset);
157void gfx_write_vip32(unsigned long offset, unsigned long value);
158void gfx_mono_bitmap_to_screen_blt_swp(unsigned short srcx,
159				       unsigned short srcy,
160				       unsigned short dstx,
161				       unsigned short dsty,
162				       unsigned short width,
163				       unsigned short height,
164				       unsigned char *data, short pitch);
165unsigned int GetVideoMemSize(void);
166
167/* ROUTINES added accessing hardware reg */
168void
169gfx_write_reg8(unsigned long offset, unsigned char value)
170{
171   WRITE_REG8(offset, value);
172}
173
174void
175gfx_write_reg16(unsigned long offset, unsigned short value)
176{
177   WRITE_REG16(offset, value);
178}
179
180void
181gfx_write_reg32(unsigned long offset, unsigned long value)
182{
183   WRITE_REG32(offset, value);
184}
185unsigned short
186gfx_read_reg16(unsigned long offset)
187{
188   unsigned short value;
189
190   value = READ_REG16(offset);
191   return value;
192}
193unsigned long
194gfx_read_reg32(unsigned long offset)
195{
196   unsigned long value;
197
198   value = READ_REG32(offset);
199   return value;
200}
201
202void
203gfx_write_vid32(unsigned long offset, unsigned long value)
204{
205   WRITE_VID32(offset, value);
206}
207unsigned long
208gfx_read_vid32(unsigned long offset)
209{
210   unsigned long value;
211
212   value = READ_VID32(offset);
213   return value;
214}
215
216/*Addition for the VIP code */
217unsigned long
218gfx_read_vip32(unsigned long offset)
219{
220   unsigned long value;
221
222   value = READ_VIP32(offset);
223   return value;
224}
225
226void
227gfx_write_vip32(unsigned long offset, unsigned long value)
228{
229   WRITE_VIP32(offset, value);
230}
231
232#define SWAP_BITS_IN_BYTES(v) \
233 (((0x01010101 & (v)) << 7) | ((0x02020202 & (v)) << 5) | \
234  ((0x04040404 & (v)) << 3) | ((0x08080808 & (v)) << 1) | \
235  ((0x10101010 & (v)) >> 1) | ((0x20202020 & (v)) >> 3) | \
236  ((0x40404040 & (v)) >> 5) | ((0x80808080 & (v)) >> 7))
237
238#define WRITE_GPREG_STRING32_SWP(regoffset, dwords, counter, array, array_offset, temp) \
239{                                                                                       \
240	temp = (unsigned long)array + (array_offset);                                       \
241	for (counter = 0; counter < dwords; counter++)                                      \
242		WRITE_GP32 (regoffset, SWAP_BITS_IN_BYTES(*((unsigned long *)temp + counter))); \
243}
244
245void
246gfx_mono_bitmap_to_screen_blt_swp(unsigned short srcx, unsigned short srcy,
247				  unsigned short dstx, unsigned short dsty,
248				  unsigned short width, unsigned short height,
249				  unsigned char *data, short pitch)
250{
251   unsigned long dstoffset, size, bytes;
252   unsigned long offset, temp_offset, temp1 = 0, temp2 = 0;
253   unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
254   unsigned long shift = 0;
255
256   size = (((unsigned long)width) << 16) | height;
257
258   /* CALCULATE STARTING OFFSETS */
259
260   offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3);
261
262   dstoffset = (unsigned long)dsty *gu2_pitch +
263	 (((unsigned long)dstx) << gu2_xshift);
264
265   /* CHECK IF PATTERN ORIGINS NEED TO BE SET */
266
267   if (GFXpatternFlags) {
268      /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
269
270      dstoffset |= ((unsigned long)(dstx & 7)) << 26;
271      dstoffset |= ((unsigned long)(dsty & 7)) << 29;
272   }
273
274   bytes = ((srcx & 7) + width + 7) >> 3;
275   fifo_lines = bytes >> 5;
276   dwords_extra = (bytes & 0x0000001Cl) >> 2;
277   bytes_extra = bytes & 0x00000003l;
278
279   /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
280   /* Put off poll for as long as possible (do most calculations first).   */
281   /* The source offset is always 0 since we allow misaligned dword reads. */
282   /* Need to wait for busy instead of pending, since hardware clears      */
283   /* the host data FIFO at the beginning of a BLT.                        */
284
285   GU2_WAIT_PENDING;
286   WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
287   WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26);
288   WRITE_GP32(MGP_DST_OFFSET, dstoffset);
289   WRITE_GP32(MGP_WID_HEIGHT, size);
290   WRITE_GP32(MGP_STRIDE, gu2_pitch);
291   WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | MGP_BM_SRC_MONO);
292
293   /* WAIT FOR BLT TO BE LATCHED */
294
295   GU2_WAIT_PENDING;
296
297   /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */
298
299   while (height--) {
300      temp_offset = offset;
301
302      /* WRITE ALL FULL FIFO LINES */
303
304      for (i = 0; i < fifo_lines; i++) {
305	 GU2_WAIT_HALF_EMPTY;
306	 WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, 8, j, data, temp_offset,
307				  temp1);
308	 temp_offset += 32;
309      }
310
311      /* WRITE ALL FULL DWORDS */
312
313      GU2_WAIT_HALF_EMPTY;
314      if (dwords_extra) {
315	 WRITE_GPREG_STRING32_SWP(MGP_HST_SOURCE, dwords_extra, i, data,
316				  temp_offset, temp1);
317	 temp_offset += (dwords_extra << 2);
318      }
319
320      /* WRITE REMAINING BYTES */
321
322      shift = 0;
323      if (bytes_extra)
324	 WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
325			     temp_offset, temp1, temp2);
326
327      offset += pitch;
328   }
329}
330unsigned int
331GetVideoMemSize(void)
332{
333   unsigned int graphicsMemBaseAddr;
334   unsigned int totalMem = 0;
335   int i;
336   unsigned int graphicsMemMask, graphicsMemShift;
337
338   /* Read graphics base address. */
339
340   graphicsMemBaseAddr = gfx_read_reg32(0x8414);
341
342   if (1) {
343      unsigned int mcBankCfg = gfx_read_reg32(0x8408);
344      unsigned int dimmShift = 4;
345
346      graphicsMemMask = 0x7FF;
347      graphicsMemShift = 19;
348
349      /* Calculate total memory size for GXm. */
350
351      for (i = 0; i < 2; i++) {
352	 if (((mcBankCfg >> dimmShift) & 0x7) != 0x7) {
353	    switch ((mcBankCfg >> (dimmShift + 4)) & 0x7) {
354	    case 0:
355	       totalMem += 0x400000;
356	       break;
357	    case 1:
358	       totalMem += 0x800000;
359	       break;
360	    case 2:
361	       totalMem += 0x1000000;
362	       break;
363	    case 3:
364	       totalMem += 0x2000000;
365	       break;
366	    case 4:
367	       totalMem += 0x4000000;
368	       break;
369	    case 5:
370	       totalMem += 0x8000000;
371	       break;
372	    case 6:
373	       totalMem += 0x10000000;
374	       break;
375	    case 7:
376	       totalMem += 0x20000000;
377	       break;
378	    default:
379	       break;
380	    }
381	 }
382	 dimmShift += 16;
383      }
384   } else {
385      unsigned int mcMemCntrl1 = gfx_read_reg32(0x8400);
386      unsigned int bankSizeShift = 12;
387
388      graphicsMemMask = 0x3FF;
389      graphicsMemShift = 17;
390
391      /* Calculate total memory size for GX. */
392
393      for (i = 0; i < 4; i++) {
394	 switch ((mcMemCntrl1 >> bankSizeShift) & 0x7) {
395	 case 1:
396	    totalMem += 0x200000;
397	    break;
398	 case 2:
399	    totalMem += 0x400000;
400	    break;
401	 case 3:
402	    totalMem += 0x800000;
403	    break;
404	 case 4:
405	    totalMem += 0x1000000;
406	    break;
407	 case 5:
408	    totalMem += 0x2000000;
409	    break;
410	 default:
411	    break;
412	 }
413	 bankSizeShift += 3;
414      }
415   }
416
417   /* Calculate graphics memory base address */
418
419   graphicsMemBaseAddr &= graphicsMemMask;
420   graphicsMemBaseAddr <<= graphicsMemShift;
421
422   return (totalMem - graphicsMemBaseAddr);
423}
424
425/* END OF FILE */
426