changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/aux/vga/geode.c

changeset 4350: 1f9d7811d546
parent: d16d837b898c
author: cinap_lenrek@felloff.net
date: Mon, 16 Mar 2015 05:46:08 +0100
permissions: -rw-r--r--
description: kernel: get rid of auxpage() and preserve cache index bits in Page.va in mount cache

the mount cache uses Page.va to store cached range offset and
limit, but mips kernel uses cache index bits from Page.va to
maintain page coloring. Page.va was not initialized by auxpage().

this change removes auxpage() which was primarily used only
by the mount cache and use newpage() with cache file offset
page as va so we will get a page of the right color.

mount cache keeps the index bits intact by only using the top
and buttom PGSHIFT bits of Page.va for the range offset/limit.
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 
5 #include "pci.h"
6 #include "vga.h"
7 
8 #include "geode_modes.h"
9 
10 enum {
11  Nregs = 28,
12  DC_UNLOCK = 0,
13  DC_GENERAL_CFG,
14  DC_DISPLAY_CFG,
15  DC_ARB_CFG,
16  DC_H_ACTIVE_TIMING = 16,
17  DC_H_BLANK_TIMING,
18  DC_H_SYNC_TIMING,
19  DC_V_ACTIVE_TIMING = 20,
20  DC_V_BLANK_TIMING,
21  DC_V_SYNC_TIMING,
22  DC_FB_ACTIVE,
23  DC_LINE_SIZE = 12,
24  DC_GFX_PITCH,
25 
26  DC_UNLOCK_VALUE = 0x4758,
27 
28  /* DC_GENERAL_CFG */
29  VGAE = 1<<7, /* VGA enable */
30  DFLE = 1, /* display FIFO enable */
31 
32  /* DC_DISPLAY_CFG */
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 */
38  DISP_MODE8 = 0,
39  DISP_MODE16 = 1<<8,
40  DISP_MODE24 = 1<<9,
41  DISP_MODE32 = (1<<8) | (1<<9),
42 
43  /* low bandwidth */
44  LBW_GENERAL = 0x9500,
45  LBW_DISPLAY = 0x8000,
46  LBW_ARB = 0x150001,
47  /* average bandwidth */
48  ABW_GENERAL = 0xB600,
49  ABW_DISPLAY = 0x9000,
50  ABW_ARB = 0x160001,
51 };
52 
53 typedef struct Geode Geode;
54 struct Geode {
55  ulong *mmio;
56  Pcidev *pci;
57  ulong regs[Nregs];
58  uvlong clock;
59 };
60 
61 static void
62 snarf(Vga* vga, Ctlr* ctlr)
63 {
64  Geode *geode;
65  int i;
66 
67  if(!vga->private) {
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);
73  }
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);
78  vga->private = geode;
79  }
80  else geode = vga->private;
81 
82  for(i=0;i<Nregs;i++) geode->regs[i] = geode->mmio[i];
83  geode->clock = rdmsr(0x4C000015);
84 
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);
89  ctlr->flag |= Fsnarf;
90 }
91 
92 static void
93 options(Vga* vga, Ctlr* ctlr)
94 {
95  USED(vga);
96  ctlr->flag |= Foptions;
97 }
98 
99 static void
100 init(Vga* vga, Ctlr* ctlr)
101 {
102  Geode *geode;
103  Mode *m;
104  int i, bpp;
105 
106  geode = vga->private;
107  m = vga->mode;
108 
109  /* there has to be a better solution */
110  if(m->x < 1024) {
111  geode->regs[DC_GENERAL_CFG] = LBW_GENERAL;
112  geode->regs[DC_DISPLAY_CFG] = LBW_DISPLAY;
113  geode->regs[DC_ARB_CFG] = LBW_ARB;
114  } else {
115  geode->regs[DC_GENERAL_CFG] = ABW_GENERAL;
116  geode->regs[DC_DISPLAY_CFG] = ABW_DISPLAY;
117  geode->regs[DC_ARB_CFG] = ABW_ARB;
118  }
119 
120  geode->regs[DC_GENERAL_CFG] |= DFLE;
121  geode->regs[DC_DISPLAY_CFG] |= GDEN | VDEN | TGEN | TRUP | PALB;
122 
123  switch(m->z) {
124  case 8: bpp = 1; break;
125  case 15: case 16: bpp = 2; geode->regs[DC_DISPLAY_CFG] |= DISP_MODE16; break;
126  case 24: bpp = 3; geode->regs[DC_DISPLAY_CFG] |= DISP_MODE24; break;
127  case 32: bpp = 4; geode->regs[DC_DISPLAY_CFG] |= DISP_MODE32; break;
128  default: error("%s: unknown bpp value\n", ctlr->name); bpp = 0;
129  }
130 
131  geode->regs[DC_H_ACTIVE_TIMING] = (m->x - 1) | ((m->ht - 1) << 16);
132  geode->regs[DC_H_BLANK_TIMING] = (m->shb - 1) | ((m->ehb - 1) << 16);
133  geode->regs[DC_H_SYNC_TIMING] = (m->shs - 1) | ((m->ehs - 1) << 16);
134  geode->regs[DC_V_ACTIVE_TIMING] = (m->y - 1) | ((m->vt - 1) << 16);
135  geode->regs[DC_V_BLANK_TIMING] = (m->vrs - 1) | ((m->vre - 1) << 16);
136  geode->regs[DC_V_SYNC_TIMING] = (m->vrs - 1) | ((m->vre - 1) << 16);
137  geode->regs[DC_FB_ACTIVE] = (m->x - 1) | ((m->y - 1) << 16);
138  geode->regs[DC_GFX_PITCH] = geode->regs[DC_LINE_SIZE] = (m->x >> 3) * bpp;
139 
140  for(i=0;i<NumModes;i++)
141  if(geode_modes[i][1] == m->frequency)
142  goto modefound;
143  error("%s: unknown clock value\n", ctlr->name);
144 modefound:
145  geode->clock = ((uvlong)geode_modes[i][0] << 32);
146 
147  ctlr->flag |= Finit;
148 }
149 
150 static void
151 load(Vga* vga, Ctlr* ctlr)
152 {
153  Geode *geode;
154  int i;
155 
156  geode = vga->private;
157  wrmsr(0x4C000015, geode->clock);
158  geode->mmio[DC_UNLOCK] = DC_UNLOCK_VALUE;
159  for(i=4;i<Nregs;i++) geode->mmio[i] = geode->regs[i];
160  for(i=1;i<4;i++) geode->mmio[i] = geode->regs[i];
161  ctlr->flag |= Fload;
162 }
163 
164 static void
165 printreg32(ulong u) {
166  printreg((u>>24)&0xFF);
167  printreg((u>>16)&0xFF);
168  printreg((u>>8)&0xFF);
169  printreg(u&0xFF);
170 }
171 
172 static void
173 dump(Vga* vga, Ctlr* ctlr)
174 {
175  int i;
176  Geode *geode;
177 
178  geode = vga->private;
179  printitem(ctlr->name, "configuration");
180  for(i=0;i<4;i++) printreg32(geode->regs[i]);
181  printitem(ctlr->name, "memory");
182  for(i=4;i<15;i++) printreg32(geode->regs[i]);
183  printitem(ctlr->name, "timing");
184  for(i=16;i<24;i++) printreg32(geode->regs[i]);
185  printitem(ctlr->name, "cursor");
186  for(i=24;i<28;i++) printreg32(geode->regs[i]);
187 
188  printitem(ctlr->name, "ext");
189  printreg(vga->crt[43]);
190  printreg(vga->crt[44]);
191  printreg(vga->crt[47]);
192  printreg(vga->crt[48]);
193 
194  printitem(ctlr->name, "clock");
195  printreg32((geode->clock >> 32) & 0xFFFFFFFF);
196  printreg32(geode->clock & 0xFFFFFFFF);
197 }
198 
199 Ctlr geode = {
200  "geode", /* name */
201  snarf, /* snarf */
202  options, /* options */
203  init, /* init */
204  load, /* load */
205  dump, /* dump */
206 };
207 
208 Ctlr geodehwgc = {
209  "geodehwgc",
210  0,
211  0,
212  0,
213  0,
214  0,
215 };