]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgaigfx.c
vgaigfx: remove #define MB, theres a MB enum in portdat.h
[plan9front.git] / sys / src / 9 / pc / vgaigfx.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/error.h"
8
9 #define Image   IMAGE
10 #include <draw.h>
11 #include <memdraw.h>
12 #include <cursor.h>
13 #include "screen.h"
14
15 static ulong
16 preallocsize(Pcidev *p)
17 {
18         switch(p->did){
19         case 0x0166:    /* Ivy Bridge */
20                 switch((pcicfgr16(p, 0x50) >> 3) & 0x1f){
21                 case 0x01:      return 32*MB    - 2*MB;
22                 case 0x02:      return 64*MB    - 2*MB;
23                 case 0x03:      return 96*MB    - 2*MB;
24                 case 0x04:      return 128*MB   - 2*MB;
25                 case 0x05:      return 32*MB    - 2*MB;
26                 case 0x06:      return 48*MB    - 2*MB;
27                 case 0x07:      return 64*MB    - 2*MB;
28                 case 0x08:      return 128*MB   - 2*MB;
29                 case 0x09:      return 256*MB   - 2*MB;
30                 case 0x0A:      return 96*MB    - 2*MB;
31                 case 0x0B:      return 160*MB   - 2*MB;
32                 case 0x0C:      return 224*MB   - 2*MB;
33                 case 0x0D:      return 352*MB   - 2*MB;
34                 case 0x0E:      return 448*MB   - 2*MB;
35                 case 0x0F:      return 480*MB   - 2*MB;
36                 case 0x10:      return 512*MB   - 2*MB;
37                 }
38                 break;
39         case 0x2a42:    /* X200 */
40                 switch((pcicfgr16(p, 0x52) >> 4) & 7){
41                 case 0x01:      return 1*MB;
42                 case 0x02:      return 4*MB;
43                 case 0x03:      return 8*MB;
44                 case 0x04:      return 16*MB;
45                 case 0x05:      return 32*MB;
46                 case 0x06:      return 48*MB;
47                 case 0x07:      return 64*MB;
48                 }
49                 break;
50         }
51         return 0;
52 }
53
54 static void
55 igfxenable(VGAscr* scr)
56 {
57         Pcidev *p;
58         
59         if(scr->mmio != nil)
60                 return;
61         p = scr->pci;
62         if(p == nil)
63                 return;
64         scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
65         if(scr->mmio == nil)
66                 return;
67         addvgaseg("igfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size);
68         if(scr->paddr == 0)
69                 vgalinearpci(scr);
70         if(scr->apsize){
71                 addvgaseg("igfxscreen", scr->paddr, scr->apsize);
72                 scr->storage = preallocsize(p);
73                 if(scr->storage > scr->apsize)
74                         scr->storage = scr->apsize;
75                 if(scr->storage != 0)
76                         scr->storage -= PGROUND(64*64*4);
77         }
78 }
79
80 VGAdev vgaigfxdev = {
81         "igfx",
82         igfxenable,
83 };
84
85 static void
86 igfxcurload(VGAscr* scr, Cursor* curs)
87 {
88         uchar set, clr;
89         u32int *p;
90         int i, j;
91
92         if(scr->storage == 0)
93                 return;
94         p = (u32int*)((uchar*)scr->vaddr + scr->storage);
95         memset(p, 0, 64*64*4);
96         for(i=0;i<32;i++) {
97                 set = curs->set[i];
98                 clr = curs->clr[i];
99                 for(j=0x80; j; j>>=1){
100                         if((set|clr)&j)
101                                 *p++ = (0xFF<<24) | (set&j ? 0x000000 : 0xFFFFFF);
102                         else
103                                 *p++ = 0;
104                 }
105                 if(i & 1)
106                         p += 64-16;
107         }
108         scr->offset = curs->offset;
109 }
110
111 enum {
112         CURCTL = 0,
113         CURBASE,
114         CURPOS,
115
116         NPIPE = 3,
117 };
118
119 static u32int*
120 igfxcurregs(VGAscr* scr, int pipe)
121 {
122         u32int o;
123
124         if(scr->mmio == nil || scr->storage == 0)
125                 return nil;
126         o = pipe*0x1000;
127         /* check PIPExCONF if enabled */
128         if((scr->mmio[(0x70008 | o)/4] & (1<<31)) == 0)
129                 return nil;
130         switch(scr->pci->did){
131         case 0x0116:    /* Ivy Bridge */
132                 if(pipe > 2)
133                         return nil;
134                 break;
135         case 0x2a42:    /* X200 */
136                 if(pipe > 1)
137                         return nil;
138                 o = pipe*0x40;
139                 break;
140         default:
141                 if(pipe > 0)
142                         return nil;
143         }
144         return (u32int*)((uchar*)scr->mmio + (0x70080 + o));
145 }
146
147 static int
148 igfxcurmove(VGAscr* scr, Point p)
149 {
150         int i, x, y;
151         u32int *r;
152
153         for(i=0; i<NPIPE; i++){
154                 if((r = igfxcurregs(scr, i)) != nil){
155                         x = p.x + scr->offset.x;
156                         if(x < 0) x = -x | 0x8000;
157                         y = p.y + scr->offset.y;
158                         if(y < 0) y = -y | 0x8000;
159                         r[CURPOS] = (y << 16) | x;
160                 }
161         }
162         return 0;
163 }
164
165 static void
166 igfxcurenable(VGAscr* scr)
167 {
168         u32int *r;
169         int i;
170
171         igfxenable(scr);
172         igfxcurload(scr, &arrow);
173         igfxcurmove(scr, ZP);
174
175         for(i=0; i<NPIPE; i++){
176                 if((r = igfxcurregs(scr, i)) != nil){
177                         r[CURCTL] = (r[CURCTL] & ~(3<<28 | 1<<5)) | (i<<28) | 7;
178                         r[CURBASE] = scr->storage;
179                 }
180         }
181 }
182
183 static void
184 igfxcurdisable(VGAscr* scr)
185 {
186         u32int *r;
187         int i;
188
189         for(i=0; i<NPIPE; i++){
190                 if((r = igfxcurregs(scr, i)) != nil){
191                         r[CURCTL] &= ~(1<<5 | 7);
192                         r[CURBASE] = 0;
193                 }
194         }
195 }
196
197 VGAcur vgaigfxcur = {
198         "igfxhwgc",
199         igfxcurenable,
200         igfxcurdisable,
201         igfxcurload,
202         igfxcurmove,
203 };