geode_common.c revision 04007eba
1f29dbc25Smrg/*
2f29dbc25Smrg * Copyright (c) 2007 Advanced Micro Devices, Inc.
3f29dbc25Smrg *
4f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5f29dbc25Smrg * copy of this software and associated documentation files (the "Software"),
6f29dbc25Smrg * to deal in the Software without restriction, including without limitation
7f29dbc25Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f29dbc25Smrg * and/or sell copies of the Software, and to permit persons to whom the
9f29dbc25Smrg * Software is furnished to do so, subject to the following conditions:
10f29dbc25Smrg *
11f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
12f29dbc25Smrg * all copies or substantial portions of the Software.
13f29dbc25Smrg *
14f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20f29dbc25Smrg * DEALINGS IN THE SOFTWARE.
21f29dbc25Smrg *
22f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
23f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
24f29dbc25Smrg * software without specific prior written permission.
25f29dbc25Smrg */
26f29dbc25Smrg
27f29dbc25Smrg/* We want to share as much code between GX and LX as we possibly can for obvious reasons */
28f29dbc25Smrg
29f29dbc25Smrg#ifdef HAVE_CONFIG_H
30f29dbc25Smrg#include "config.h"
31f29dbc25Smrg#endif
32f29dbc25Smrg
3304007ebaSmrg#include <string.h>             /* memcmp() */
34f29dbc25Smrg#include <unistd.h>
35f29dbc25Smrg#include <sys/types.h>
36f29dbc25Smrg#include <sys/stat.h>
37f29dbc25Smrg#include <fcntl.h>
38f29dbc25Smrg#include <sys/ioctl.h>
39f29dbc25Smrg
40f29dbc25Smrg#include "xf86.h"
41f29dbc25Smrg#include "geode.h"
42f29dbc25Smrg
43f29dbc25Smrg#define move0(d,s,n) \
44f29dbc25Smrg  __asm__ __volatile__( \
45f29dbc25Smrg  "   rep; movsl\n" \
46f29dbc25Smrg  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
47f29dbc25Smrg  : "0" (n), "1" (s), "2" (d) \
48f29dbc25Smrg  : "memory")
49f29dbc25Smrg
50f29dbc25Smrg#define move1(d,s,n) \
51f29dbc25Smrg  __asm__ __volatile__( \
52f29dbc25Smrg  "   rep; movsl\n" \
53f29dbc25Smrg  "   movsb\n" \
54f29dbc25Smrg  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
55f29dbc25Smrg  : "0" (n), "1" (s), "2" (d) \
56f29dbc25Smrg  : "memory")
57f29dbc25Smrg
58f29dbc25Smrg#define move2(d,s,n) \
59f29dbc25Smrg  __asm__ __volatile__( \
60f29dbc25Smrg  "   rep; movsl\n" \
61f29dbc25Smrg  "   movsw\n" \
62f29dbc25Smrg  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
63f29dbc25Smrg  : "0" (n), "1" (s), "2" (d) \
64f29dbc25Smrg  : "memory")
65f29dbc25Smrg
66f29dbc25Smrg#define move3(d,s,n) \
67f29dbc25Smrg  __asm__ __volatile__( \
68f29dbc25Smrg  "   rep; movsl\n" \
69f29dbc25Smrg  "   movsw\n" \
70f29dbc25Smrg  "   movsb\n" \
71f29dbc25Smrg  : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
72f29dbc25Smrg  : "0" (n), "1" (s), "2" (d) \
73f29dbc25Smrg  : "memory")
74f29dbc25Smrg
75f29dbc25Smrgvoid
76f29dbc25Smrggeode_memory_to_screen_blt(unsigned long src, unsigned long dst,
7704007ebaSmrg                           unsigned long sp, unsigned long dp, long w, long h,
7804007ebaSmrg                           int bpp)
79f29dbc25Smrg{
80f29dbc25Smrg    int d0, d1, d2;
81f29dbc25Smrg    int n = w * (bpp >> 3);
82f29dbc25Smrg    int m = n >> 2;
83f29dbc25Smrg
84f29dbc25Smrg    switch (n & 3) {
85f29dbc25Smrg    case 0:
8604007ebaSmrg        while (--h >= 0) {
8704007ebaSmrg            move0(dst, src, m);
8804007ebaSmrg            src += sp;
8904007ebaSmrg            dst += dp;
9004007ebaSmrg        }
9104007ebaSmrg        break;
92f29dbc25Smrg    case 1:
9304007ebaSmrg        while (--h >= 0) {
9404007ebaSmrg            move1(dst, src, m);
9504007ebaSmrg            src += sp;
9604007ebaSmrg            dst += dp;
9704007ebaSmrg        }
9804007ebaSmrg        break;
99f29dbc25Smrg    case 2:
10004007ebaSmrg        while (--h >= 0) {
10104007ebaSmrg            move2(dst, src, m);
10204007ebaSmrg            src += sp;
10304007ebaSmrg            dst += dp;
10404007ebaSmrg        }
10504007ebaSmrg        break;
106f29dbc25Smrg    case 3:
10704007ebaSmrg        while (--h >= 0) {
10804007ebaSmrg            move3(dst, src, m);
10904007ebaSmrg            src += sp;
11004007ebaSmrg            dst += dp;
11104007ebaSmrg        }
11204007ebaSmrg        break;
113f29dbc25Smrg    }
114f29dbc25Smrg}
115f29dbc25Smrg
116f29dbc25Smrg/* I borrowed this function from the i830 driver - its much better
117f29dbc25Smrg   then what we had before
118f29dbc25Smrg*/
119f29dbc25Smrg
120f29dbc25Smrgint
121f29dbc25SmrgGeodeGetRefreshRate(DisplayModePtr pMode)
122f29dbc25Smrg{
123f29dbc25Smrg    if (pMode->VRefresh)
12404007ebaSmrg        return (int) (pMode->VRefresh + 0.5);
125f29dbc25Smrg
12604007ebaSmrg    return (int) (pMode->Clock * 1000.0 / pMode->HTotal / pMode->VTotal + 0.5);
127f29dbc25Smrg}
128f29dbc25Smrg
129f29dbc25Smrg/* This is used by both GX and LX.  It could be accelerated for LX, probably, but
130f29dbc25Smrg   that would involve a two pass blt, the first to copy the data, and the second
131f29dbc25Smrg   to copy the grey (using a pattern).  That seems like a bit of work for a
132f29dbc25Smrg   very underused format - so we'll just use the slow version.
133f29dbc25Smrg*/
134f29dbc25Smrg
135f29dbc25Smrgvoid
136f29dbc25SmrgGeodeCopyGreyscale(unsigned char *src, unsigned char *dst,
13704007ebaSmrg                   int dstPitch, int srcPitch, int h, int w)
138f29dbc25Smrg{
139f29dbc25Smrg    int i;
140f29dbc25Smrg    unsigned char *src2 = src;
141f29dbc25Smrg    unsigned char *dst2 = dst;
142f29dbc25Smrg    unsigned char *dst3;
143f29dbc25Smrg    unsigned char *src3;
144f29dbc25Smrg
145f29dbc25Smrg    dstPitch <<= 1;
146f29dbc25Smrg
147f29dbc25Smrg    while (h--) {
14804007ebaSmrg        dst3 = dst2;
14904007ebaSmrg        src3 = src2;
15004007ebaSmrg        for (i = 0; i < w; i++) {
15104007ebaSmrg            *dst3++ = *src3++;  /* Copy Y data */
15204007ebaSmrg            *dst3++ = 0x80;     /* Fill UV with 0x80 - greyscale */
15304007ebaSmrg        }
15404007ebaSmrg
15504007ebaSmrg        src3 = src2;
15604007ebaSmrg        for (i = 0; i < w; i++) {
15704007ebaSmrg            *dst3++ = *src3++;  /* Copy Y data */
15804007ebaSmrg            *dst3++ = 0x80;     /* Fill UV with 0x80 - greyscale */
15904007ebaSmrg        }
16004007ebaSmrg
16104007ebaSmrg        dst2 += dstPitch;
16204007ebaSmrg        src2 += srcPitch;
163f29dbc25Smrg    }
164f29dbc25Smrg}
165f29dbc25Smrg
166f29dbc25Smrg#if defined(linux)
167f29dbc25Smrg
168f29dbc25Smrg#include <linux/fb.h>
169f29dbc25Smrg
170f29dbc25Smrgint
171f29dbc25SmrgGeodeGetSizeFromFB(unsigned int *size)
172f29dbc25Smrg{
173f29dbc25Smrg    struct fb_fix_screeninfo fix;
174f29dbc25Smrg    int ret;
175f29dbc25Smrg    int fd = open("/dev/fb0", O_RDONLY);
176f29dbc25Smrg
177f29dbc25Smrg    if (fd == -1)
17804007ebaSmrg        return -1;
179f29dbc25Smrg
180f29dbc25Smrg    ret = ioctl(fd, FBIOGET_FSCREENINFO, &fix);
181f29dbc25Smrg    close(fd);
182f29dbc25Smrg
183f29dbc25Smrg    if (!ret) {
18404007ebaSmrg        if (!memcmp(fix.id, "Geode", 5)) {
18504007ebaSmrg            *size = fix.smem_len;
18604007ebaSmrg            return 0;
18704007ebaSmrg        }
188f29dbc25Smrg    }
189f29dbc25Smrg
190f29dbc25Smrg    return -1;
191f29dbc25Smrg}
192f29dbc25Smrg
193f29dbc25Smrg#else
194f29dbc25Smrg
195f29dbc25Smrgint
196f29dbc25SmrgGeodeGetSizeFromFB(unsigned int *size)
197f29dbc25Smrg{
198f29dbc25Smrg    return -1;
199f29dbc25Smrg}
200f29dbc25Smrg
201f29dbc25Smrg#endif
202