summaryrefslogtreecommitdiff
path: root/src/nouveau_hw.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/nouveau_hw.h')
-rw-r--r--src/nouveau_hw.h352
1 files changed, 0 insertions, 352 deletions
diff --git a/src/nouveau_hw.h b/src/nouveau_hw.h
deleted file mode 100644
index aa2a3b4..0000000
--- a/src/nouveau_hw.h
+++ /dev/null
@@ -1,352 +0,0 @@
1/*
2 * Copyright 2008 Stuart Bennett
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#ifndef __NOUVEAU_HW_H__
24#define __NOUVEAU_HW_H__
25
26#define MASK(field) ((0xffffffff >> (31 - ((1?field) - (0?field)))) << (0?field))
27#define XLATE(src, srclowbit, outfield) ((((src) >> (srclowbit)) << (0?outfield)) & MASK(outfield))
28
29#define nvReadMC(pNv, reg) DDXMMIOW("nvReadMC: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
30#define nvWriteMC(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteMC: reg %08x val %08x\n", reg, val))
31
32#define nvReadVIDEO(pNv, reg) DDXMMIOW("nvReadVIDEO: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
33#define nvWriteVIDEO(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteVIDEO: reg %08x val %08x\n", reg, val))
34
35#define nvReadFB(pNv, reg) DDXMMIOW("nvReadFB: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
36#define nvWriteFB(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteFB: reg %08x val %08x\n", reg, val))
37
38#define nvReadEXTDEV(pNv, reg) DDXMMIOW("nvReadEXTDEV: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
39#define nvWriteEXTDEV(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteEXTDEV: reg %08x val %08x\n", reg, val))
40
41static inline uint32_t NVRead(NVPtr pNv, uint32_t reg)
42{
43 DDXMMIOW("NVRead: reg %08x val %08x\n", reg, (uint32_t)NV_RD32(pNv->REGS, reg));
44 return NV_RD32(pNv->REGS, reg);
45}
46
47static inline void NVWrite(NVPtr pNv, uint32_t reg, uint32_t val)
48{
49 DDXMMIOW("NVWrite: reg %08x val %08x\n", reg, NV_WR32(pNv->REGS, reg, val));
50}
51
52static inline uint32_t NVReadCRTC(NVPtr pNv, int head, uint32_t reg)
53{
54 if (head)
55 reg += NV_PCRTC0_SIZE;
56 DDXMMIOH("NVReadCRTC: head %d reg %08x val %08x\n", head, reg, (uint32_t)NV_RD32(pNv->REGS, reg));
57 return NV_RD32(pNv->REGS, reg);
58}
59
60static inline void NVWriteCRTC(NVPtr pNv, int head, uint32_t reg, uint32_t val)
61{
62 if (head)
63 reg += NV_PCRTC0_SIZE;
64 DDXMMIOH("NVWriteCRTC: head %d reg %08x val %08x\n", head, reg, val);
65 NV_WR32(pNv->REGS, reg, val);
66}
67
68static inline uint32_t NVReadRAMDAC(NVPtr pNv, int head, uint32_t reg)
69{
70 if (head)
71 reg += NV_PRAMDAC0_SIZE;
72 DDXMMIOH("NVReadRamdac: head %d reg %08x val %08x\n", head, reg, (uint32_t)NV_RD32(pNv->REGS, reg));
73 return NV_RD32(pNv->REGS, reg);
74}
75
76static inline void
77NVWriteRAMDAC(NVPtr pNv, int head, uint32_t reg, uint32_t val)
78{
79 if (head)
80 reg += NV_PRAMDAC0_SIZE;
81 DDXMMIOH("NVWriteRamdac: head %d reg %08x val %08x\n", head, reg, val);
82 NV_WR32(pNv->REGS, reg, val);
83}
84
85static inline uint8_t nv_read_tmds(NVPtr pNv, int or, int dl, uint8_t address)
86{
87 int ramdac = (or & OUTPUT_C) >> 2;
88
89 NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8,
90 NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address);
91 return NVReadRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8);
92}
93
94static inline void
95nv_write_tmds(NVPtr pNv, int or, int dl, uint8_t address, uint8_t data)
96{
97 int ramdac = (or & OUTPUT_C) >> 2;
98
99 NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data);
100 NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address);
101}
102
103static inline void
104NVWriteVgaCrtc(NVPtr pNv, int head, uint8_t index, uint8_t value)
105{
106 DDXMMIOH("NVWriteVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, value);
107 NV_WR08(pNv->REGS, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
108 NV_WR08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value);
109}
110
111static inline uint8_t NVReadVgaCrtc(NVPtr pNv, int head, uint8_t index)
112{
113 NV_WR08(pNv->REGS, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
114 DDXMMIOH("NVReadVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE));
115 return NV_RD08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE);
116}
117
118/* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58
119 * I suspect they in fact do nothing, but are merely a way to carry useful
120 * per-head variables around
121 *
122 * Known uses:
123 * CR57 CR58
124 * 0x00 index to the appropriate dcb entry (or 7f for inactive)
125 * 0x02 dcb entry's "or" value (or 00 for inactive)
126 * 0x03 bit0 set for dual link (LVDS, possibly elsewhere too)
127 * 0x08 or 0x09 pxclk in MHz
128 * 0x0f laptop panel info - low nibble for PEXTDEV_BOOT_0 strap
129 * high nibble for xlat strap value
130 */
131
132static inline void
133NVWriteVgaCrtc5758(NVPtr pNv, int head, uint8_t index, uint8_t value)
134{
135 NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_57, index);
136 NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_58, value);
137}
138
139static inline uint8_t NVReadVgaCrtc5758(NVPtr pNv, int head, uint8_t index)
140{
141 NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_57, index);
142 return NVReadVgaCrtc(pNv, head, NV_CIO_CRE_58);
143}
144
145static inline uint8_t NVReadPRMVIO(NVPtr pNv, int head, uint32_t reg)
146{
147 /* Only NV4x have two pvio ranges; other twoHeads cards MUST call
148 * NVSetOwner for the relevant head to be programmed */
149 if (head && pNv->Architecture == NV_ARCH_40)
150 reg += NV_PRMVIO_SIZE;
151
152 DDXMMIOH("NVReadPRMVIO: head %d reg %08x val %02x\n", head, reg, NV_RD08(pNv->REGS, reg));
153 return NV_RD08(pNv->REGS, reg);
154}
155
156static inline void
157NVWritePRMVIO(NVPtr pNv, int head, uint32_t reg, uint8_t value)
158{
159 /* Only NV4x have two pvio ranges; other twoHeads cards MUST call
160 * NVSetOwner for the relevant head to be programmed */
161 if (head && pNv->Architecture == NV_ARCH_40)
162 reg += NV_PRMVIO_SIZE;
163
164 DDXMMIOH("NVWritePRMVIO: head %d reg %08x val %02x\n", head, reg, value);
165 NV_WR08(pNv->REGS, reg, value);
166}
167
168static inline void NVSetEnablePalette(NVPtr pNv, int head, bool enable)
169{
170 VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
171 VGA_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE,
172 enable ? 0 : 0x20);
173}
174
175static inline bool NVGetEnablePalette(NVPtr pNv, int head)
176{
177 VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
178 return !(VGA_RD08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) &
179 0x20);
180}
181
182static inline void NVWriteVgaAttr(NVPtr pNv, int head, uint8_t index, uint8_t value)
183{
184 if (NVGetEnablePalette(pNv, head))
185 index &= ~0x20;
186 else
187 index |= 0x20;
188
189 NV_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
190 DDXMMIOH("NVWriteVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, value);
191 NV_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
192 NV_WR08(pNv->REGS, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value);
193}
194
195static inline uint8_t NVReadVgaAttr(NVPtr pNv, int head, uint8_t index)
196{
197 if (NVGetEnablePalette(pNv, head))
198 index &= ~0x20;
199 else
200 index |= 0x20;
201
202 NV_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
203 NV_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
204 DDXMMIOH("NVReadVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE));
205 return NV_RD08(pNv->REGS, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE);
206}
207
208static inline void NVVgaSeqReset(NVPtr pNv, int head, bool start)
209{
210 NVWriteVgaSeq(pNv, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3);
211}
212
213static inline void NVVgaProtect(NVPtr pNv, int head, bool protect)
214{
215 uint8_t seq1 = NVReadVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX);
216
217 if (protect) {
218 NVVgaSeqReset(pNv, head, true);
219 NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
220 } else {
221 /* Reenable sequencer, then turn on screen */
222 NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */
223 NVVgaSeqReset(pNv, head, false);
224 }
225 NVSetEnablePalette(pNv, head, protect);
226}
227
228static inline bool nv_heads_tied(NVPtr pNv)
229{
230 if (pNv->NVArch == 0x11)
231 return !!(nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28));
232
233 return (NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_44) & 0x4);
234}
235
236/* makes cr0-7 on the specified head read-only */
237static inline bool nv_lock_vga_crtc_base(NVPtr pNv, int head, bool lock)
238{
239 uint8_t cr11 = NVReadVgaCrtc(pNv, head, NV_CIO_CR_VRE_INDEX);
240 bool waslocked = cr11 & 0x80;
241
242 if (lock)
243 cr11 |= 0x80;
244 else
245 cr11 &= ~0x80;
246 NVWriteVgaCrtc(pNv, head, NV_CIO_CR_VRE_INDEX, cr11);
247
248 return waslocked;
249}
250
251static inline void nv_lock_vga_crtc_shadow(NVPtr pNv, int head, int lock)
252{
253 /* shadow lock: connects 0x60?3d? regs to "real" 0x3d? regs
254 * bit7: unlocks HDT, HBS, HBE, HRS, HRE, HEB
255 * bit6: seems to have some effect on CR09 (double scan, VBS_9)
256 * bit5: unlocks HDE
257 * bit4: unlocks VDE
258 * bit3: unlocks VDT, OVL, VRS, ?VRE?, VBS, VBE, LSR, EBR
259 * bit2: same as bit 1 of 0x60?804
260 * bit0: same as bit 0 of 0x60?804
261 */
262
263 uint8_t cr21 = lock;
264
265 if (lock < 0)
266 /* 0xfa is generic "unlock all" mask */
267 cr21 = NVReadVgaCrtc(pNv, head, NV_CIO_CRE_21) | 0xfa;
268
269 NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_21, cr21);
270}
271
272/* renders the extended crtc regs (cr19+) on all crtcs impervious:
273 * immutable and unreadable
274 */
275static inline bool NVLockVgaCrtcs(NVPtr pNv, bool lock)
276{
277 bool waslocked = !NVReadVgaCrtc(pNv, 0, NV_CIO_SR_LOCK_INDEX);
278
279 NVWriteVgaCrtc(pNv, 0, NV_CIO_SR_LOCK_INDEX,
280 lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE);
281 /* NV11 has independently lockable extended crtcs, except when tied */
282 if (pNv->NVArch == 0x11 && !nv_heads_tied(pNv))
283 NVWriteVgaCrtc(pNv, 1, NV_CIO_SR_LOCK_INDEX,
284 lock ? NV_CIO_SR_LOCK_VALUE :
285 NV_CIO_SR_UNLOCK_RW_VALUE);
286
287 return waslocked;
288}
289
290/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
291#define NV04_CURSOR_SIZE 32
292/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
293#define NV10_CURSOR_SIZE 64
294
295static inline int nv_cursor_width(NVPtr pNv)
296{
297 return pNv->NVArch >= 0x10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
298}
299
300static inline int nv_cursor_pixels(NVPtr pNv)
301{
302 int width = nv_cursor_width(pNv);
303
304 return width * width;
305}
306
307static inline void nv_fix_nv40_hw_cursor(NVPtr pNv, int head)
308{
309 /* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40,
310 * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS
311 * for changes to the CRTC CURCTL regs to take effect, whether changing
312 * the pixmap location, or just showing/hiding the cursor
313 */
314 volatile uint32_t curpos = NVReadRAMDAC(pNv, head,
315 NV_PRAMDAC_CU_START_POS);
316 NVWriteRAMDAC(pNv, head, NV_PRAMDAC_CU_START_POS, curpos);
317}
318
319static inline void nv_show_cursor(NVPtr pNv, int head, bool show)
320{
321 uint8_t *curctl1 =
322 &pNv->set_state.head[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX];
323
324 if (show)
325 *curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
326 else
327 *curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
328 NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1);
329
330 if (pNv->Architecture == NV_ARCH_40)
331 nv_fix_nv40_hw_cursor(pNv, head);
332}
333
334static inline uint32_t nv_pitch_align(NVPtr pNv, uint32_t width, int bpp)
335{
336 int mask;
337
338 if (bpp == 15)
339 bpp = 16;
340 if (bpp == 24 || bpp == 30)
341 bpp = 8;
342
343 /* Alignment requirements taken from the Haiku driver */
344 if (pNv->Architecture == NV_ARCH_04)
345 mask = 128 / bpp - 1;
346 else
347 mask = 512 / bpp - 1;
348
349 return (width + mask) & ~mask;
350}
351
352#endif /* __NOUVEAU_HW_H__ */