]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgacyber938x.c
[9front] [PATCH] audiohda: add PCI ID for Intel C610/X99
[plan9front.git] / sys / src / 9 / pc / vgacyber938x.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         CursorON        = 0xC8,
18         CursorOFF       = 0x00,
19 };
20
21 static int
22 cyber938xpageset(VGAscr*, int page)
23 {
24         int opage;
25
26         opage = inb(0x3D8);
27
28         outb(0x3D8, page);
29         outb(0x3D9, page);
30
31         return opage;
32 }
33
34 static void
35 cyber938xpage(VGAscr* scr, int page)
36 {
37         lock(&scr->devlock);
38         cyber938xpageset(scr, page);
39         unlock(&scr->devlock);
40 }
41
42 static void
43 cyber938xlinear(VGAscr* scr, int, int)
44 {
45         Pcidev *p;
46
47         if(scr->vaddr)
48                 return;
49         
50         p = scr->pci;
51         if(p == nil)
52                 return;
53
54         vgalinearpci(scr);
55
56         /*
57          * Heuristic to detect the MMIO space.  We're flying blind
58          * here, with only the XFree86 source to guide us.
59          */
60         if(p->mem[1].size == 0x20000 && (p->mem[1].bar & 1) == 0)
61                 scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
62
63         if(scr->apsize)
64                 addvgaseg("cyber938xscreen", scr->paddr, scr->apsize);
65         if(scr->mmio)
66                 addvgaseg("cyber938xmmio", p->mem[1].bar&~0x0F, 0x20000);
67 }
68
69 static void
70 cyber938xcurdisable(VGAscr*)
71 {
72         vgaxo(Crtx, 0x50, CursorOFF);
73 }
74
75 static void
76 cyber938xcurload(VGAscr* scr, Cursor* curs)
77 {
78         uchar *p;
79         int islinear, opage, y;
80
81         cyber938xcurdisable(scr);
82
83         opage = 0;
84         p = scr->vaddr;
85         islinear = vgaxi(Crtx, 0x21) & 0x20;
86         if(!islinear){
87                 lock(&scr->devlock);
88                 opage = cyber938xpageset(scr, scr->storage>>16);
89                 p += (scr->storage & 0xFFFF);
90         }
91         else
92                 p += scr->storage;
93
94         for(y = 0; y < 16; y++){
95                 *p++ = curs->set[2*y]|curs->clr[2*y];
96                 *p++ = curs->set[2*y + 1]|curs->clr[2*y + 1];
97                 *p++ = 0x00;
98                 *p++ = 0x00;
99                 *p++ = curs->set[2*y];
100                 *p++ = curs->set[2*y + 1];
101                 *p++ = 0x00;
102                 *p++ = 0x00;
103         }
104         memset(p, 0, (32-y)*8);
105
106         if(!islinear){
107                 cyber938xpageset(scr, opage);
108                 unlock(&scr->devlock);
109         }
110
111         /*
112          * Save the cursor hotpoint and enable the cursor.
113          */
114         scr->offset = curs->offset;
115         vgaxo(Crtx, 0x50, CursorON);
116 }
117
118 static int
119 cyber938xcurmove(VGAscr* scr, Point p)
120 {
121         int x, xo, y, yo;
122
123         /*
124          * Mustn't position the cursor offscreen even partially,
125          * or it might disappear. Therefore, if x or y is -ve, adjust the
126          * cursor origins instead.
127          */
128         if((x = p.x+scr->offset.x) < 0){
129                 xo = -x;
130                 x = 0;
131         }
132         else
133                 xo = 0;
134         if((y = p.y+scr->offset.y) < 0){
135                 yo = -y;
136                 y = 0;
137         }
138         else
139                 yo = 0;
140
141         /*
142          * Load the new values.
143          */
144         vgaxo(Crtx, 0x46, xo);
145         vgaxo(Crtx, 0x47, yo);
146         vgaxo(Crtx, 0x40, x & 0xFF);
147         vgaxo(Crtx, 0x41, (x>>8) & 0xFF);
148         vgaxo(Crtx, 0x42, y & 0xFF);
149         vgaxo(Crtx, 0x43, (y>>8) & 0xFF);
150
151         return 0;
152 }
153
154 static void
155 cyber938xcurenable(VGAscr* scr)
156 {
157         int i;
158         ulong storage;
159
160         cyber938xcurdisable(scr);
161
162         /*
163          * Cursor colours.
164          */
165         for(i = 0x48; i < 0x4C; i++)
166                 vgaxo(Crtx, i, 0x00);
167         for(i = 0x4C; i < 0x50; i++)
168                 vgaxo(Crtx, i, 0xFF);
169
170         /*
171          * Find a place for the cursor data in display memory.
172          */
173         storage = ((scr->pitch*scr->height+1023)/1024);
174         vgaxo(Crtx, 0x44, storage & 0xFF);
175         vgaxo(Crtx, 0x45, (storage>>8) & 0xFF);
176         storage *= 1024;
177         scr->storage = storage;
178
179         /*
180          * Load, locate and enable the 32x32 cursor.
181          * (64x64 is bit 0, X11 format is bit 6 and cursor
182          * enable is bit 7). Bit 3 needs to be set on 9382
183          * chips otherwise even the white bits are black.
184          */
185         cyber938xcurload(scr, &cursor);
186         cyber938xcurmove(scr, ZP);
187         vgaxo(Crtx, 0x50, CursorON);
188 }
189
190 VGAdev vgacyber938xdev = {
191         "cyber938x",
192
193         nil,                            /* enable */
194         nil,                            /* disable */
195         cyber938xpage,                  /* page */
196         cyber938xlinear,                /* linear */
197         nil,                            /* drawinit */
198 };
199
200 VGAcur vgacyber938xcur = {
201         "cyber938xhwgc",
202
203         cyber938xcurenable,             /* enable */
204         cyber938xcurdisable,            /* disable */
205         cyber938xcurload,               /* load */
206         cyber938xcurmove,               /* move */
207 };