]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgageode.c
[9front] [PATCH] audiohda: add PCI ID for Intel C610/X99
[plan9front.git] / sys / src / 9 / pc / vgageode.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/pci.h"
8 #include "../port/error.h"
9
10 #define Image   IMAGE
11 #include <draw.h>
12 #include <memdraw.h>
13 #include <cursor.h>
14 #include "screen.h"
15
16 enum {
17         DC_UNLOCK = 0,
18         DC_UNLOCKVALUE = 0x4758,
19         DC_GENERAL_CFG = 1,
20         CURE = 2,
21         DC_CURS_ST_OFFSET = 6,
22         DC_CURSOR_X = 24,
23         DC_CURSOR_Y = 25,
24         DC_PAL_ADDRESS = 28,
25         DC_PAL_DATA
26 };
27
28 static void
29 geodeenable(VGAscr* scr)
30 {
31         Pcidev *p;
32         
33         if(scr->mmio)
34                 return;
35         p = scr->pci;
36         if(p == nil)
37                 return;
38         if((p->mem[1].bar | p->mem[2].bar | p->mem[3].bar) & 1)
39                 return;
40         scr->mmio = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
41         if(scr->mmio == nil)
42                 return;
43         addvgaseg("geodegp", p->mem[1].bar&~0x0F, p->mem[1].size);
44         addvgaseg("geodemmio", p->mem[2].bar&~0x0F, p->mem[2].size);
45         addvgaseg("geodevid", p->mem[3].bar&~0x0F, p->mem[3].size);
46         vgalinearpci(scr);
47         if(scr->apsize)
48                 addvgaseg("geodescreen", scr->paddr, scr->apsize);
49         scr->storage = 0x800000;
50 }
51
52 static void
53 geodelinear(VGAscr*, int, int)
54 {
55 }
56
57 static void
58 geodecurload(VGAscr* scr, Cursor* curs)
59 {
60         uvlong *p, and1, xor1, and2, xor2;
61         int i;
62         uchar *c, *s;
63
64         if(!scr->mmio) return;
65         p = (uvlong*)((uchar*)scr->vaddr + scr->storage);
66         c = curs->clr;
67         s = curs->set;
68         for(i=0;i<16;i++) {
69                 and1 = 0xFF ^ (*s ^ *c++);
70                 xor1 = *s++;
71                 and1 &= ~xor1;
72                 and2 = 0xFF ^ (*s ^ *c++);
73                 xor2 = *s++;
74                 and2 &= ~xor2;
75                 *p++ = (and1 << 56) | (and2 << 48) | 0xFFFFFFFFFFFFLL;
76                 *p++ = (xor1 << 56) | (xor2 << 48);
77         }
78         for(;i<128;i++) {
79                 *p++ = -1;
80                 *p++ = 0;
81         }
82         scr->offset = curs->offset;
83 }
84
85 static int
86 geodecurmove(VGAscr* scr, Point p) {
87         if(!scr->mmio) return 1;
88         ((ulong*)scr->mmio)[DC_UNLOCK] = DC_UNLOCKVALUE;
89         ((ulong*)scr->mmio)[DC_CURSOR_X] = p.x + scr->offset.x;
90         ((ulong*)scr->mmio)[DC_CURSOR_Y] = p.y + scr->offset.y;
91         return 0;
92 }
93
94 static void
95 geodecurenable(VGAscr* scr)
96 {
97         geodeenable(scr);
98         if(!scr->mmio) return;
99         geodecurload(scr, &cursor);
100         geodecurmove(scr, ZP);
101         ((ulong*)scr->mmio)[DC_UNLOCK] = DC_UNLOCKVALUE;
102         ((ulong*)scr->mmio)[DC_CURS_ST_OFFSET] = scr->storage;
103         ((ulong*)scr->mmio)[DC_GENERAL_CFG] |= CURE;
104         /* set cursor colours */
105         ((ulong*)scr->mmio)[DC_PAL_ADDRESS] = 0x100;
106         ((ulong*)scr->mmio)[DC_PAL_DATA] = -1;
107         ((ulong*)scr->mmio)[DC_PAL_DATA] = 0;
108 }
109
110 static void
111 geodecurdisable(VGAscr* scr)
112 {
113         if(!scr->mmio) return;
114         ((ulong*)scr->mmio)[DC_UNLOCK] = DC_UNLOCKVALUE;
115         ((ulong*)scr->mmio)[DC_GENERAL_CFG] &= ~CURE;
116 }
117
118 VGAdev vgageodedev = {
119         "geode",
120         geodeenable,
121         .linear = geodelinear,
122 };
123
124
125 VGAcur vgageodecur = {
126         "geodehwgc",
127         geodecurenable,
128         geodecurdisable,
129         geodecurload,
130         geodecurmove,
131 };