8 #include "geode_modes.h"
16 DC_H_ACTIVE_TIMING = 16,
19 DC_V_ACTIVE_TIMING = 20,
26 DC_UNLOCK_VALUE = 0x4758,
29 VGAE = 1<<7, /* VGA enable */
30 DFLE = 1, /* display FIFO enable */
33 TGEN = 1, /* timing enable */
34 GDEN = 1<<3, /* graphics enable */
35 VDEN = 1<<4, /* video enable */
36 TRUP = 1<<6, /* timing register update */
37 PALB = 1<<25, /* palette bypass */
41 DISP_MODE32 = (1<<8) | (1<<9),
47 /* average bandwidth */
53 typedef struct Geode Geode;
62 snarf(Vga* vga, Ctlr* ctlr)
68 geode = alloc(sizeof(Geode));
69 geode->pci = vga->pci;
70 if(geode->pci == nil){
71 geode->pci = pcimatch(0, 0x1022, 0x2081);
72 if(!geode->pci) error("%s: not found\n", ctlr->name);
74 vgactlpci(geode->pci);
75 vgactlw("type", "geode");
76 geode->mmio = segattach(0, "geodemmio", 0, geode->pci->mem[2].size);
77 if(geode->mmio == (ulong*)-1) error("%s: can't attach mmio segment\n", ctlr->name);
80 else geode = vga->private;
82 for(i=0;i<Nregs;i++) geode->regs[i] = geode->mmio[i];
83 geode->clock = rdmsr(0x4C000015);
85 vga->crt[43] = vgaxi(Crtx, 43);
86 vga->crt[44] = vgaxi(Crtx, 44);
87 vga->crt[47] = vgaxi(Crtx, 47);
88 vga->crt[48] = vgaxi(Crtx, 48);
93 options(Vga* vga, Ctlr* ctlr)
96 ctlr->flag |= Foptions;
100 init(Vga* vga, Ctlr* ctlr)
106 geode = vga->private;
112 /* there has to be a better solution */
114 geode->regs[DC_GENERAL_CFG] = LBW_GENERAL;
115 geode->regs[DC_DISPLAY_CFG] = LBW_DISPLAY;
116 geode->regs[DC_ARB_CFG] = LBW_ARB;
118 geode->regs[DC_GENERAL_CFG] = ABW_GENERAL;
119 geode->regs[DC_DISPLAY_CFG] = ABW_DISPLAY;
120 geode->regs[DC_ARB_CFG] = ABW_ARB;
123 geode->regs[DC_GENERAL_CFG] |= DFLE;
124 geode->regs[DC_DISPLAY_CFG] |= GDEN | VDEN | TGEN | TRUP | PALB;
127 case 8: bpp = 1; break;
128 case 15: case 16: bpp = 2; geode->regs[DC_DISPLAY_CFG] |= DISP_MODE16; break;
129 case 24: bpp = 3; geode->regs[DC_DISPLAY_CFG] |= DISP_MODE24; break;
130 case 32: bpp = 4; geode->regs[DC_DISPLAY_CFG] |= DISP_MODE32; break;
131 default: error("%s: unknown bpp value\n", ctlr->name); bpp = 0;
134 geode->regs[DC_H_ACTIVE_TIMING] = (m->x - 1) | ((m->ht - 1) << 16);
135 geode->regs[DC_H_BLANK_TIMING] = (m->shb - 1) | ((m->ehb - 1) << 16);
136 geode->regs[DC_H_SYNC_TIMING] = (m->shs - 1) | ((m->ehs - 1) << 16);
137 geode->regs[DC_V_ACTIVE_TIMING] = (m->y - 1) | ((m->vt - 1) << 16);
138 geode->regs[DC_V_BLANK_TIMING] = (m->vrs - 1) | ((m->vre - 1) << 16);
139 geode->regs[DC_V_SYNC_TIMING] = (m->vbs - 1) | ((m->vbe - 1) << 16);
140 geode->regs[DC_FB_ACTIVE] = (m->x - 1) | ((m->y - 1) << 16);
141 geode->regs[DC_GFX_PITCH] = geode->regs[DC_LINE_SIZE] = (m->x >> 3) * bpp;
143 for(i=0;i<NumModes;i++)
144 if(geode_modes[i][1] == m->frequency)
146 error("%s: unknown clock value\n", ctlr->name);
148 geode->clock = ((uvlong)geode_modes[i][0] << 32);
154 load(Vga* vga, Ctlr* ctlr)
159 geode = vga->private;
160 wrmsr(0x4C000015, geode->clock);
161 geode->mmio[DC_UNLOCK] = DC_UNLOCK_VALUE;
162 for(i=4;i<Nregs;i++) geode->mmio[i] = geode->regs[i];
163 for(i=1;i<4;i++) geode->mmio[i] = geode->regs[i];
168 printreg32(ulong u) {
169 printreg((u>>24)&0xFF);
170 printreg((u>>16)&0xFF);
171 printreg((u>>8)&0xFF);
176 dump(Vga* vga, Ctlr* ctlr)
181 geode = vga->private;
182 printitem(ctlr->name, "configuration");
183 for(i=0;i<4;i++) printreg32(geode->regs[i]);
184 printitem(ctlr->name, "memory");
185 for(i=4;i<15;i++) printreg32(geode->regs[i]);
186 printitem(ctlr->name, "timing");
187 for(i=16;i<24;i++) printreg32(geode->regs[i]);
188 printitem(ctlr->name, "cursor");
189 for(i=24;i<28;i++) printreg32(geode->regs[i]);
191 printitem(ctlr->name, "ext");
192 printreg(vga->crt[43]);
193 printreg(vga->crt[44]);
194 printreg(vga->crt[47]);
195 printreg(vga->crt[48]);
197 printitem(ctlr->name, "clock");
198 printreg32((geode->clock >> 32) & 0xFFFFFFFF);
199 printreg32(geode->clock & 0xFFFFFFFF);
205 options, /* options */