geode_common.c revision f29dbc25
1/*
2 * Copyright (c) 2007 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *
22 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
23 * contributors may be used to endorse or promote products derived from this
24 * software without specific prior written permission.
25 */
26
27/* We want to share as much code between GX and LX as we possibly can for obvious reasons */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <string.h>		       /* memcmp() */
34#include <unistd.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <fcntl.h>
38#include <sys/ioctl.h>
39
40#include "xf86.h"
41#include "geode.h"
42
43#define move0(d,s,n) \
44  __asm__ __volatile__( \
45  "   rep; movsl\n" \
46  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
47  : "0" (n), "1" (s), "2" (d) \
48  : "memory")
49
50#define move1(d,s,n) \
51  __asm__ __volatile__( \
52  "   rep; movsl\n" \
53  "   movsb\n" \
54  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
55  : "0" (n), "1" (s), "2" (d) \
56  : "memory")
57
58#define move2(d,s,n) \
59  __asm__ __volatile__( \
60  "   rep; movsl\n" \
61  "   movsw\n" \
62  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
63  : "0" (n), "1" (s), "2" (d) \
64  : "memory")
65
66#define move3(d,s,n) \
67  __asm__ __volatile__( \
68  "   rep; movsl\n" \
69  "   movsw\n" \
70  "   movsb\n" \
71  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
72  : "0" (n), "1" (s), "2" (d) \
73  : "memory")
74
75void
76geode_memory_to_screen_blt(unsigned long src, unsigned long dst,
77    unsigned long sp, unsigned long dp, long w, long h, int bpp)
78{
79    int d0, d1, d2;
80    int n = w * (bpp >> 3);
81    int m = n >> 2;
82
83    switch (n & 3) {
84    case 0:
85	while (--h >= 0) {
86	    move0(dst, src, m);
87	    src += sp;
88	    dst += dp;
89	}
90	break;
91    case 1:
92	while (--h >= 0) {
93	    move1(dst, src, m);
94	    src += sp;
95	    dst += dp;
96	}
97	break;
98    case 2:
99	while (--h >= 0) {
100	    move2(dst, src, m);
101	    src += sp;
102	    dst += dp;
103	}
104	break;
105    case 3:
106	while (--h >= 0) {
107	    move3(dst, src, m);
108	    src += sp;
109	    dst += dp;
110	}
111	break;
112    }
113}
114
115/* I borrowed this function from the i830 driver - its much better
116   then what we had before
117*/
118
119int
120GeodeGetRefreshRate(DisplayModePtr pMode)
121{
122    if (pMode->VRefresh)
123	return (int)(pMode->VRefresh + 0.5);
124
125    return (int)(pMode->Clock * 1000.0 / pMode->HTotal / pMode->VTotal + 0.5);
126}
127
128/* This is used by both GX and LX.  It could be accelerated for LX, probably, but
129   that would involve a two pass blt, the first to copy the data, and the second
130   to copy the grey (using a pattern).  That seems like a bit of work for a
131   very underused format - so we'll just use the slow version.
132*/
133
134void
135GeodeCopyGreyscale(unsigned char *src, unsigned char *dst,
136    int dstPitch, int srcPitch, int h, int w)
137{
138    int i;
139    unsigned char *src2 = src;
140    unsigned char *dst2 = dst;
141    unsigned char *dst3;
142    unsigned char *src3;
143
144    dstPitch <<= 1;
145
146    while (h--) {
147	dst3 = dst2;
148	src3 = src2;
149	for (i = 0; i < w; i++) {
150	    *dst3++ = *src3++;	       /* Copy Y data */
151	    *dst3++ = 0x80;	       /* Fill UV with 0x80 - greyscale */
152	}
153
154	src3 = src2;
155	for (i = 0; i < w; i++) {
156	    *dst3++ = *src3++;	       /* Copy Y data */
157	    *dst3++ = 0x80;	       /* Fill UV with 0x80 - greyscale */
158	}
159
160	dst2 += dstPitch;
161	src2 += srcPitch;
162    }
163}
164
165#if defined(linux)
166
167#include <linux/fb.h>
168
169int
170GeodeGetSizeFromFB(unsigned int *size)
171{
172    struct fb_fix_screeninfo fix;
173    int ret;
174    int fd = open("/dev/fb0", O_RDONLY);
175
176    if (fd == -1)
177	return -1;
178
179    ret = ioctl(fd, FBIOGET_FSCREENINFO, &fix);
180    close(fd);
181
182    if (!ret) {
183	if (!memcmp(fix.id, "Geode", 5)) {
184	    *size = fix.smem_len;
185	    return 0;
186	}
187    }
188
189    return -1;
190}
191
192#else
193
194int
195GeodeGetSizeFromFB(unsigned int *size)
196{
197    return -1;
198}
199
200#endif
201