1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_shadow.c,v 1.1 2002/12/10 15:12:24 alanh Exp $ */
2/*
3 * $Workfile: nsc_gx2_shadow.c $
4 * $Revision: 1.1.1.1 $
5 * $Author: mrg $
6 *
7 * File Contents: Direct graphics display routines are implemented and
8 *                graphics rendering are all done in memory.
9 *
10 * Project:       Geode Xfree Frame buffer device driver.
11 *
12 *
13 */
14
15/*
16 * NSC_LIC_ALTERNATIVE_PREAMBLE
17 *
18 * Revision 1.0
19 *
20 * National Semiconductor Alternative GPL-BSD License
21 *
22 * National Semiconductor Corporation licenses this software
23 * ("Software"):
24 *
25 * National Xfree frame buffer driver
26 *
27 * under one of the two following licenses, depending on how the
28 * Software is received by the Licensee.
29 *
30 * If this Software is received as part of the Linux Framebuffer or
31 * other GPL licensed software, then the GPL license designated
32 * NSC_LIC_GPL applies to this Software; in all other circumstances
33 * then the BSD-style license designated NSC_LIC_BSD shall apply.
34 *
35 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
36
37/* NSC_LIC_BSD
38 *
39 * National Semiconductor Corporation Open Source License for
40 *
41 * National Xfree frame buffer driver
42 *
43 * (BSD License with Export Notice)
44 *
45 * Copyright (c) 1999-2001
46 * National Semiconductor Corporation.
47 * All rights reserved.
48 *
49 * Redistribution and use in source and binary forms, with or without
50 * modification, are permitted provided that the following conditions
51 * are met:
52 *
53 *   * Redistributions of source code must retain the above copyright
54 *     notice, this list of conditions and the following disclaimer.
55 *
56 *   * Redistributions in binary form must reproduce the above
57 *     copyright notice, this list of conditions and the following
58 *     disclaimer in the documentation and/or other materials provided
59 *     with the distribution.
60 *
61 *   * Neither the name of the National Semiconductor Corporation nor
62 *     the names of its contributors may be used to endorse or promote
63 *     products derived from this software without specific prior
64 *     written permission.
65 *
66 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
67 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
68 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
69 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
70 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
71 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
72 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
73 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
74 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
75 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
76 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
77 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
78 * OF SUCH DAMAGE.
79 *
80 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
81 * YOUR JURISDICTION. It is licensee's responsibility to comply with
82 * any export regulations applicable in licensee's jurisdiction. Under
83 * CURRENT (2001) U.S. export regulations this software
84 * is eligible for export from the U.S. and can be downloaded by or
85 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
86 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
87 * Syria, Sudan, Afghanistan and any other country to which the U.S.
88 * has embargoed goods and services.
89 *
90 * END_NSC_LIC_BSD */
91
92/* NSC_LIC_GPL
93 *
94 * National Semiconductor Corporation Gnu General Public License for
95 *
96 * National Xfree frame buffer driver
97 *
98 * (GPL License with Export Notice)
99 *
100 * Copyright (c) 1999-2001
101 * National Semiconductor Corporation.
102 * All rights reserved.
103 *
104 * Redistribution and use in source and binary forms, with or without
105 * modification, are permitted under the terms of the GNU General
106 * Public License as published by the Free Software Foundation; either
107 * version 2 of the License, or (at your option) any later version
108 *
109 * In addition to the terms of the GNU General Public License, neither
110 * the name of the National Semiconductor Corporation nor the names of
111 * its contributors may be used to endorse or promote products derived
112 * from this software without specific prior written permission.
113 *
114 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
115 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
116 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
117 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
118 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
119 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
120 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
121 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
122 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
123 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
124 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
125 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
126 * OF SUCH DAMAGE. See the GNU General Public License for more details.
127 *
128 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
129 * YOUR JURISDICTION. It is licensee's responsibility to comply with
130 * any export regulations applicable in licensee's jurisdiction. Under
131 * CURRENT (2001) U.S. export regulations this software
132 * is eligible for export from the U.S. and can be downloaded by or
133 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
134 * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
135 * Syria, Sudan, Afghanistan and any other country to which the U.S.
136 * has embargoed goods and services.
137 *
138 * You should have received a copy of the GNU General Public License
139 * along with this file; if not, write to the Free Software Foundation,
140 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
141 *
142 * END_NSC_LIC_GPL */
143
144#ifdef HAVE_CONFIG_H
145#include "config.h"
146#endif
147
148#include "xf86.h"
149#include "xf86_OSproc.h"
150#include "xf86Resources.h"
151#include "xf86PciInfo.h"
152#include "xf86Pci.h"
153#include "nsc.h"
154#include "shadowfb.h"
155#include "servermd.h"
156
157void GX2RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
158void GX2PointerMoved(int index, int x, int y);
159void GX2RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
160void GX2RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
161void GX2RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
162void GX2RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
163
164/*----------------------------------------------------------------------------
165 * GX2RefreshArea.
166 *
167 * Description	:This function  copies the memory to be displayed from the
168 *               shadow pointer.
169 * Parameters.
170 *    pScrn		:Pointer to screen structure.
171 *    num		:Specifies the num of squarebox area to be displayed.
172 *    pbox		:Points to square of memory to be displayed.
173 * Returns		:none
174 *
175 * Comments		: none
176 *
177*----------------------------------------------------------------------------
178*/
179void
180GX2RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
181{
182   GeodePtr pGeode = GEODEPTR(pScrn);
183   int width, height, Bpp, FBPitch;
184   unsigned char *src, *dst;
185
186   Bpp = pScrn->bitsPerPixel >> 3;
187   FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
188   while (num--) {
189      width = (pbox->x2 - pbox->x1) * Bpp;
190      height = pbox->y2 - pbox->y1;
191      src = pGeode->ShadowPtr + (pbox->y1 * pGeode->ShadowPitch) +
192	    (pbox->x1 * Bpp);
193      dst = pGeode->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
194      while (height--) {
195	 memcpy(dst, src, width);
196	 dst += FBPitch;
197	 src += pGeode->ShadowPitch;
198      }
199
200      pbox++;
201   }
202}
203
204/*----------------------------------------------------------------------------
205 * GX2PointerMoved.
206 *
207 * Description	:This function moves one screen memory from one area to other.
208 *
209 * Parameters.
210 *    index		:Pointer to screen index.
211 *     x		:Specifies the new x co-ordinates of new area.
212 *     y		:Specifies the new y co-ordinates of new area.
213 * Returns		:none
214 *
215 * Comments		:none
216 *
217*----------------------------------------------------------------------------
218*/
219void
220GX2PointerMoved(int index, int x, int y)
221{
222   ScrnInfoPtr pScrn = xf86Screens[index];
223   GeodePtr pGeode = GEODEPTR(pScrn);
224   int newX, newY;
225
226   if (pGeode->Rotate == 1) {
227      newX = pScrn->pScreen->height - y - 1;
228      newY = x;
229   } else {
230      newX = y;
231      newY = pScrn->pScreen->width - x - 1;
232   }
233   (*pGeode->PointerMoved) (index, newX, newY);
234}
235
236/*----------------------------------------------------------------------------
237 * GX2RefreshArea8.
238 *
239 * Description	:This function  copies the memory to be displayed from the
240 *                 shadow pointer by 8bpp.
241 * Parameters.
242 *    pScrn		:Pointer to screen structure.
243 *    num		:Specifies the num of squarebox area to be displayed.
244 *    pbox		:Points to square of memory to be displayed.
245 * Returns		:none
246 *
247 * Comments		:none
248 *
249*----------------------------------------------------------------------------
250*/
251void
252GX2RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
253{
254   GeodePtr pGeode = GEODEPTR(pScrn);
255   int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2,
256	 srcPitch3, srcPitch4;
257   CARD8 *dstPtr, *srcPtr, *src;
258   CARD32 *dst;
259
260   dstPitch = pScrn->displayWidth;
261   srcPitch = -pGeode->Rotate * pGeode->ShadowPitch;
262   srcPitch2 = srcPitch * 2;
263   srcPitch3 = srcPitch * 3;
264   srcPitch4 = srcPitch * 4;
265   while (num--) {
266      width = pbox->x2 - pbox->x1;
267      y1 = pbox->y1 & ~3;
268      y2 = (pbox->y2 + 3) & ~3;
269      height = (y2 - y1) >> 2;		/* in dwords */
270
271      if (pGeode->Rotate == 1) {
272	 dstPtr = pGeode->FBBase +
273	       (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
274	 srcPtr = pGeode->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
275      } else {
276	 dstPtr = pGeode->FBBase +
277	       ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
278	 srcPtr = pGeode->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
279      }
280      while (width--) {
281	 src = srcPtr;
282	 dst = (CARD32 *) dstPtr;
283	 count = height;
284	 while (count--) {
285	    *(dst++) = src[0] | (src[srcPitch] << 8) |
286		  (src[srcPitch2] << 16) | (src[srcPitch3] << 24);
287	    src += srcPitch4;
288	 }
289	 srcPtr += pGeode->Rotate;
290	 dstPtr += dstPitch;
291      }
292      pbox++;
293   }
294}
295
296/*----------------------------------------------------------------------------
297 * GX2RefreshArea16.
298 *
299 * Description	:This function  copies the memory to be displayed from the
300 *               shadow pointer by 16bpp.
301 * Parameters:
302 *    pScrn		:Pointer to screen structure.
303 *    num       :Specifies the num of squarebox area to be displayed.
304 *    pbox      :Points to square of memory to be displayed.
305 * Returns		:none
306 *
307 * Comments     :none
308 *
309*----------------------------------------------------------------------------
310*/
311void
312GX2RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
313{
314   GeodePtr pGeode = GEODEPTR(pScrn);
315   int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2;
316   CARD16 *dstPtr, *srcPtr, *src;
317   CARD32 *dst;
318
319   dstPitch = pScrn->displayWidth;
320   srcPitch = -pGeode->Rotate * pGeode->ShadowPitch >> 1;
321   srcPitch2 = srcPitch * 2;
322   while (num--) {
323      width = pbox->x2 - pbox->x1;
324      y1 = pbox->y1 & ~1;
325      y2 = (pbox->y2 + 1) & ~1;
326      height = (y2 - y1) >> 1;		/* in dwords */
327      if (pGeode->Rotate == 1) {
328	 dstPtr = (CARD16 *) pGeode->FBBase +
329	       (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
330	 srcPtr = (CARD16 *) pGeode->ShadowPtr +
331	       ((1 - y2) * srcPitch) + pbox->x1;
332      } else {
333	 dstPtr = (CARD16 *) pGeode->FBBase +
334	       ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
335	 srcPtr = (CARD16 *) pGeode->ShadowPtr +
336	       (y1 * srcPitch) + pbox->x2 - 1;
337      }
338
339      while (width--) {
340	 src = srcPtr;
341	 dst = (CARD32 *) dstPtr;
342	 count = height;
343	 while (count--) {
344	    *(dst++) = src[0] | (src[srcPitch] << 16);
345	    src += srcPitch2;
346	 }
347	 srcPtr += pGeode->Rotate;
348	 dstPtr += dstPitch;
349      }
350
351      pbox++;
352   }
353}
354
355/*----------------------------------------------------------------------------
356 * GX2RefreshArea24.
357 *
358 * Description	:This function  copies the memory to be displayed from the
359 *               shadow pointer by 24bpp.
360 * Parameters.
361 *    pScrn		:Pointer to screen structure.
362 *    num		:Specifies the num of squarebox area to be displayed.
363 *    pbox      :Points to square of memory to be displayed.
364 * Returns		:none
365 *
366 * Comments		:none
367 *
368*----------------------------------------------------------------------------
369*/
370void
371GX2RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
372{
373   GeodePtr pGeode = GEODEPTR(pScrn);
374   int count, width, height, y1, y2, dstPitch, srcPitch, srcPitch2, srcPitch3;
375   CARD8 *dstPtr, *srcPtr, *src;
376   CARD32 *dst;
377
378   dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
379   srcPitch = -pGeode->Rotate * pGeode->ShadowPitch;
380   srcPitch2 = srcPitch * 2;
381   srcPitch3 = srcPitch * 3;
382   while (num--) {
383      width = pbox->x2 - pbox->x1;
384      y1 = pbox->y1 & ~3;
385      y2 = (pbox->y2 + 3) & ~3;
386      height = (y2 - y1) >> 2;		/* blocks of 3 dwords */
387      if (pGeode->Rotate == 1) {
388	 dstPtr = pGeode->FBBase +
389	       (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
390	 srcPtr = pGeode->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
391      } else {
392	 dstPtr = pGeode->FBBase +
393	       ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
394	 srcPtr = pGeode->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
395      }
396      while (width--) {
397	 src = srcPtr;
398	 dst = (CARD32 *) dstPtr;
399	 count = height;
400	 while (count--) {
401	    dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
402		  (src[srcPitch] << 24);
403	    dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
404		  (src[srcPitch2] << 16) | (src[srcPitch2 + 1] << 24);
405	    dst[2] = src[srcPitch2 + 2] | (src[srcPitch3] << 8) |
406		  (src[srcPitch3 + 1] << 16) | (src[srcPitch3 + 2] << 24);
407	    dst += 3;
408	    src += srcPitch << 2;
409	 }
410	 srcPtr += pGeode->Rotate * 3;
411	 dstPtr += dstPitch;
412      }
413      pbox++;
414   }
415}
416
417/*----------------------------------------------------------------------------
418 * GX2RefreshArea32.
419 *
420 * Description	:This function  copies the memory to be displayed from the
421 *                    shadow pointer by 32bpp.
422 * Parameters:
423 *    pScrn		:Pointer to screen structure.
424 *    num		:Specifies the num of squarebox area to be displayed.
425 *    pbox		:Points to square of memory to be displayed.
426 * Returns		: none
427 *
428 * Comments		:none
429 *
430*----------------------------------------------------------------------------
431*/
432void
433GX2RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
434{
435   GeodePtr pGeode = GEODEPTR(pScrn);
436   int count, width, height, dstPitch, srcPitch;
437   CARD32 *dstPtr, *srcPtr, *src, *dst;
438
439   dstPitch = pScrn->displayWidth;
440   srcPitch = -pGeode->Rotate * pGeode->ShadowPitch >> 2;
441   while (num--) {
442      width = pbox->x2 - pbox->x1;
443      height = pbox->y2 - pbox->y1;
444
445      if (pGeode->Rotate == 1) {
446	 dstPtr = (CARD32 *) pGeode->FBBase +
447	       (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
448	 srcPtr = (CARD32 *) pGeode->ShadowPtr +
449	       ((1 - pbox->y2) * srcPitch) + pbox->x1;
450      } else {
451	 dstPtr = (CARD32 *) pGeode->FBBase +
452	       ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
453	 srcPtr = (CARD32 *) pGeode->ShadowPtr +
454	       (pbox->y1 * srcPitch) + pbox->x2 - 1;
455      }
456      while (width--) {
457	 src = srcPtr;
458	 dst = dstPtr;
459	 count = height;
460	 while (count--) {
461	    *(dst++) = *src;
462	    src += srcPitch;
463	 }
464	 srcPtr += pGeode->Rotate;
465	 dstPtr += dstPitch;
466      }
467      pbox++;
468   }
469}
470
471/* End of file */
472