]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgaigfx.c
usbehci: catch interrupt in tsleep
[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 uintptr
16 igfxcuralloc(Pcidev *pci, void *mmio, int apsize)
17 {
18         int n;
19         u32int pa, *buf, *p, *e;
20
21         buf = mallocalign(64*64*4, BY2PG, 0, 0);
22         if(buf == nil){
23                 print("igfx: no memory for cursor image\n");
24                 return 0;
25         }
26         n = (apsize > 128*MB ? 128*1024 : apsize/1024) / 4 - 4;
27         p = (u32int*)((uchar*)mmio + pci->mem[0].size/2) + n;
28         *(u32int*)((uchar*)mmio + 0x2170) = 0;  /* flush write buffers */
29         for(e=p+4, pa=PADDR(buf); p<e; p++, pa+=1<<12)
30                 *p = pa | 1;
31         *(u32int*)((uchar*)mmio + 0x2170) = 0;  /* flush write buffers */
32         return (uintptr)n << 12;
33 }
34
35 static void
36 igfxenable(VGAscr* scr)
37 {
38         Pcidev *p;
39         
40         if(scr->mmio != nil)
41                 return;
42         p = scr->pci;
43         if(p == nil)
44                 return;
45         scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
46         if(scr->mmio == nil)
47                 return;
48         addvgaseg("igfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size);
49         if(scr->paddr == 0)
50                 vgalinearpci(scr);
51         if(scr->apsize){
52                 addvgaseg("igfxscreen", scr->paddr, scr->apsize);
53                 scr->storage = igfxcuralloc(p, scr->mmio, scr->apsize);
54         }
55         scr->softscreen = 1;
56 }
57
58 VGAdev vgaigfxdev = {
59         "igfx",
60         igfxenable,
61 };
62
63 static void
64 igfxcurload(VGAscr* scr, Cursor* curs)
65 {
66         uchar set, clr;
67         u32int *p;
68         int i, j;
69
70         if(scr->storage == 0)
71                 return;
72         p = (u32int*)((uchar*)scr->vaddr + scr->storage);
73         memset(p, 0, 64*64*4);
74         for(i=0;i<32;i++) {
75                 set = curs->set[i];
76                 clr = curs->clr[i];
77                 for(j=0x80; j; j>>=1){
78                         if((set|clr)&j)
79                                 *p++ = (0xFF<<24) | (set&j ? 0x000000 : 0xFFFFFF);
80                         else
81                                 *p++ = 0;
82                 }
83                 if(i & 1)
84                         p += 64-16;
85         }
86         scr->offset = curs->offset;
87 }
88
89 enum {
90         CURCTL = 0,
91         CURBASE,
92         CURPOS,
93
94         NPIPE = 4,
95 };
96
97 static u32int*
98 igfxcurregs(VGAscr* scr, int pipe)
99 {
100         u32int o;
101
102         if(scr->mmio == nil || scr->storage == 0)
103                 return nil;
104         o = pipe == 3 ? 0xf000 : pipe*0x1000;
105         /* check PIPExCONF if enabled */
106         if((scr->mmio[(0x70008 | o)/4] & (1<<31)) == 0)
107                 return nil;
108         switch(scr->pci->did){
109         case 0x0412:    /* Haswell HD Graphics 4600 */
110         case 0x0a16:    /* Haswell HD Graphics 4400 */
111                 if(pipe > 3)
112                         return nil;
113                 if(pipe == 3)
114                         o = 0;
115                 break;
116         case 0x0166:    /* Ivy Bridge */
117         case 0x0152:    /* Core-i3 */
118         case 0x0126:    /* Sandy Bridge HD Graphics 3000 */
119                 if(pipe > 2)
120                         return nil;
121                 break;
122         case 0x2a42:    /* X200 */
123         case 0x29a2:    /* 82P965/G965 HECI desktop */
124         case 0x2a02:    /* CF-R7 */
125         case 0x0102:    /* Sndy Bridge */
126                 if(pipe > 1)
127                         return nil;
128                 o = pipe*0x40;
129                 break;
130         default:
131                 if(pipe > 0)
132                         return nil;
133         }
134         return (u32int*)((uchar*)scr->mmio + (0x70080 + o));
135 }
136
137 static int
138 igfxcurmove(VGAscr* scr, Point p)
139 {
140         int i, x, y;
141         u32int *r;
142
143         for(i=0; i<NPIPE; i++){
144                 if((r = igfxcurregs(scr, i)) != nil){
145                         x = p.x + scr->offset.x;
146                         if(x < 0) x = -x | 0x8000;
147                         y = p.y + scr->offset.y;
148                         if(y < 0) y = -y | 0x8000;
149                         r[CURPOS] = (y << 16) | x;
150                 }
151         }
152         return 0;
153 }
154
155 static void
156 igfxcurenable(VGAscr* scr)
157 {
158         u32int *r;
159         int i;
160
161         igfxenable(scr);
162         igfxcurload(scr, &arrow);
163         igfxcurmove(scr, ZP);
164
165         for(i=0; i<NPIPE; i++){
166                 if((r = igfxcurregs(scr, i)) != nil){
167                         r[CURCTL] = (r[CURCTL] & ~(3<<28 | 1<<5)) | (i<<28) | 7;
168                         r[CURBASE] = scr->storage;
169                 }
170         }
171 }
172
173 static void
174 igfxcurdisable(VGAscr* scr)
175 {
176         u32int *r;
177         int i;
178
179         for(i=0; i<NPIPE; i++){
180                 if((r = igfxcurregs(scr, i)) != nil){
181                         r[CURCTL] &= ~(1<<5 | 7);
182                         r[CURBASE] = 0;
183                 }
184         }
185 }
186
187 VGAcur vgaigfxcur = {
188         "igfxhwgc",
189         igfxcurenable,
190         igfxcurdisable,
191         igfxcurload,
192         igfxcurmove,
193 };