diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_hw.h')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_hw.h | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h new file mode 100644 index 000000000000..869130f83602 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_hw.h | |||
@@ -0,0 +1,455 @@ | |||
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 | #include "drmP.h" | ||
27 | #include "nouveau_drv.h" | ||
28 | |||
29 | #define MASK(field) ( \ | ||
30 | (0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field)) | ||
31 | |||
32 | #define XLATE(src, srclowbit, outfield) ( \ | ||
33 | (((src) >> (srclowbit)) << (0 ? outfield)) & MASK(outfield)) | ||
34 | |||
35 | void NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value); | ||
36 | uint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index); | ||
37 | void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value); | ||
38 | uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index); | ||
39 | void NVSetOwner(struct drm_device *, int owner); | ||
40 | void NVBlankScreen(struct drm_device *, int head, bool blank); | ||
41 | void nouveau_hw_setpll(struct drm_device *, uint32_t reg1, | ||
42 | struct nouveau_pll_vals *pv); | ||
43 | int nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype, | ||
44 | struct nouveau_pll_vals *pllvals); | ||
45 | int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals); | ||
46 | int nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype); | ||
47 | void nouveau_hw_save_vga_fonts(struct drm_device *, bool save); | ||
48 | void nouveau_hw_save_state(struct drm_device *, int head, | ||
49 | struct nv04_mode_state *state); | ||
50 | void nouveau_hw_load_state(struct drm_device *, int head, | ||
51 | struct nv04_mode_state *state); | ||
52 | void nouveau_hw_load_state_palette(struct drm_device *, int head, | ||
53 | struct nv04_mode_state *state); | ||
54 | |||
55 | /* nouveau_calc.c */ | ||
56 | extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp, | ||
57 | int *burst, int *lwm); | ||
58 | extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim, | ||
59 | int clk, struct nouveau_pll_vals *pv); | ||
60 | |||
61 | static inline uint32_t | ||
62 | nvReadMC(struct drm_device *dev, uint32_t reg) | ||
63 | { | ||
64 | uint32_t val = nv_rd32(dev, reg); | ||
65 | NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); | ||
66 | return val; | ||
67 | } | ||
68 | |||
69 | static inline void | ||
70 | nvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val) | ||
71 | { | ||
72 | NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); | ||
73 | nv_wr32(dev, reg, val); | ||
74 | } | ||
75 | |||
76 | static inline uint32_t | ||
77 | nvReadVIDEO(struct drm_device *dev, uint32_t reg) | ||
78 | { | ||
79 | uint32_t val = nv_rd32(dev, reg); | ||
80 | NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); | ||
81 | return val; | ||
82 | } | ||
83 | |||
84 | static inline void | ||
85 | nvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val) | ||
86 | { | ||
87 | NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); | ||
88 | nv_wr32(dev, reg, val); | ||
89 | } | ||
90 | |||
91 | static inline uint32_t | ||
92 | nvReadFB(struct drm_device *dev, uint32_t reg) | ||
93 | { | ||
94 | uint32_t val = nv_rd32(dev, reg); | ||
95 | NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); | ||
96 | return val; | ||
97 | } | ||
98 | |||
99 | static inline void | ||
100 | nvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val) | ||
101 | { | ||
102 | NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); | ||
103 | nv_wr32(dev, reg, val); | ||
104 | } | ||
105 | |||
106 | static inline uint32_t | ||
107 | nvReadEXTDEV(struct drm_device *dev, uint32_t reg) | ||
108 | { | ||
109 | uint32_t val = nv_rd32(dev, reg); | ||
110 | NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); | ||
111 | return val; | ||
112 | } | ||
113 | |||
114 | static inline void | ||
115 | nvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val) | ||
116 | { | ||
117 | NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); | ||
118 | nv_wr32(dev, reg, val); | ||
119 | } | ||
120 | |||
121 | static inline uint32_t NVReadCRTC(struct drm_device *dev, | ||
122 | int head, uint32_t reg) | ||
123 | { | ||
124 | uint32_t val; | ||
125 | if (head) | ||
126 | reg += NV_PCRTC0_SIZE; | ||
127 | val = nv_rd32(dev, reg); | ||
128 | NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); | ||
129 | return val; | ||
130 | } | ||
131 | |||
132 | static inline void NVWriteCRTC(struct drm_device *dev, | ||
133 | int head, uint32_t reg, uint32_t val) | ||
134 | { | ||
135 | if (head) | ||
136 | reg += NV_PCRTC0_SIZE; | ||
137 | NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); | ||
138 | nv_wr32(dev, reg, val); | ||
139 | } | ||
140 | |||
141 | static inline uint32_t NVReadRAMDAC(struct drm_device *dev, | ||
142 | int head, uint32_t reg) | ||
143 | { | ||
144 | uint32_t val; | ||
145 | if (head) | ||
146 | reg += NV_PRAMDAC0_SIZE; | ||
147 | val = nv_rd32(dev, reg); | ||
148 | NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", | ||
149 | head, reg, val); | ||
150 | return val; | ||
151 | } | ||
152 | |||
153 | static inline void NVWriteRAMDAC(struct drm_device *dev, | ||
154 | int head, uint32_t reg, uint32_t val) | ||
155 | { | ||
156 | if (head) | ||
157 | reg += NV_PRAMDAC0_SIZE; | ||
158 | NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", | ||
159 | head, reg, val); | ||
160 | nv_wr32(dev, reg, val); | ||
161 | } | ||
162 | |||
163 | static inline uint8_t nv_read_tmds(struct drm_device *dev, | ||
164 | int or, int dl, uint8_t address) | ||
165 | { | ||
166 | int ramdac = (or & OUTPUT_C) >> 2; | ||
167 | |||
168 | NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, | ||
169 | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address); | ||
170 | return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8); | ||
171 | } | ||
172 | |||
173 | static inline void nv_write_tmds(struct drm_device *dev, | ||
174 | int or, int dl, uint8_t address, | ||
175 | uint8_t data) | ||
176 | { | ||
177 | int ramdac = (or & OUTPUT_C) >> 2; | ||
178 | |||
179 | NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data); | ||
180 | NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address); | ||
181 | } | ||
182 | |||
183 | static inline void NVWriteVgaCrtc(struct drm_device *dev, | ||
184 | int head, uint8_t index, uint8_t value) | ||
185 | { | ||
186 | NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", | ||
187 | head, index, value); | ||
188 | nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); | ||
189 | nv_wr08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value); | ||
190 | } | ||
191 | |||
192 | static inline uint8_t NVReadVgaCrtc(struct drm_device *dev, | ||
193 | int head, uint8_t index) | ||
194 | { | ||
195 | uint8_t val; | ||
196 | nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); | ||
197 | val = nv_rd08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE); | ||
198 | NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", | ||
199 | head, index, val); | ||
200 | return val; | ||
201 | } | ||
202 | |||
203 | /* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58 | ||
204 | * I suspect they in fact do nothing, but are merely a way to carry useful | ||
205 | * per-head variables around | ||
206 | * | ||
207 | * Known uses: | ||
208 | * CR57 CR58 | ||
209 | * 0x00 index to the appropriate dcb entry (or 7f for inactive) | ||
210 | * 0x02 dcb entry's "or" value (or 00 for inactive) | ||
211 | * 0x03 bit0 set for dual link (LVDS, possibly elsewhere too) | ||
212 | * 0x08 or 0x09 pxclk in MHz | ||
213 | * 0x0f laptop panel info - low nibble for PEXTDEV_BOOT_0 strap | ||
214 | * high nibble for xlat strap value | ||
215 | */ | ||
216 | |||
217 | static inline void | ||
218 | NVWriteVgaCrtc5758(struct drm_device *dev, int head, uint8_t index, uint8_t value) | ||
219 | { | ||
220 | NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); | ||
221 | NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value); | ||
222 | } | ||
223 | |||
224 | static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index) | ||
225 | { | ||
226 | NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); | ||
227 | return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58); | ||
228 | } | ||
229 | |||
230 | static inline uint8_t NVReadPRMVIO(struct drm_device *dev, | ||
231 | int head, uint32_t reg) | ||
232 | { | ||
233 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
234 | uint8_t val; | ||
235 | |||
236 | /* Only NV4x have two pvio ranges; other twoHeads cards MUST call | ||
237 | * NVSetOwner for the relevant head to be programmed */ | ||
238 | if (head && dev_priv->card_type == NV_40) | ||
239 | reg += NV_PRMVIO_SIZE; | ||
240 | |||
241 | val = nv_rd08(dev, reg); | ||
242 | NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", head, reg, val); | ||
243 | return val; | ||
244 | } | ||
245 | |||
246 | static inline void NVWritePRMVIO(struct drm_device *dev, | ||
247 | int head, uint32_t reg, uint8_t value) | ||
248 | { | ||
249 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
250 | |||
251 | /* Only NV4x have two pvio ranges; other twoHeads cards MUST call | ||
252 | * NVSetOwner for the relevant head to be programmed */ | ||
253 | if (head && dev_priv->card_type == NV_40) | ||
254 | reg += NV_PRMVIO_SIZE; | ||
255 | |||
256 | NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", | ||
257 | head, reg, value); | ||
258 | nv_wr08(dev, reg, value); | ||
259 | } | ||
260 | |||
261 | static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable) | ||
262 | { | ||
263 | nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); | ||
264 | nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20); | ||
265 | } | ||
266 | |||
267 | static inline bool NVGetEnablePalette(struct drm_device *dev, int head) | ||
268 | { | ||
269 | nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); | ||
270 | return !(nv_rd08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20); | ||
271 | } | ||
272 | |||
273 | static inline void NVWriteVgaAttr(struct drm_device *dev, | ||
274 | int head, uint8_t index, uint8_t value) | ||
275 | { | ||
276 | if (NVGetEnablePalette(dev, head)) | ||
277 | index &= ~0x20; | ||
278 | else | ||
279 | index |= 0x20; | ||
280 | |||
281 | nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); | ||
282 | NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", | ||
283 | head, index, value); | ||
284 | nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); | ||
285 | nv_wr08(dev, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value); | ||
286 | } | ||
287 | |||
288 | static inline uint8_t NVReadVgaAttr(struct drm_device *dev, | ||
289 | int head, uint8_t index) | ||
290 | { | ||
291 | uint8_t val; | ||
292 | if (NVGetEnablePalette(dev, head)) | ||
293 | index &= ~0x20; | ||
294 | else | ||
295 | index |= 0x20; | ||
296 | |||
297 | nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); | ||
298 | nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); | ||
299 | val = nv_rd08(dev, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE); | ||
300 | NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", | ||
301 | head, index, val); | ||
302 | return val; | ||
303 | } | ||
304 | |||
305 | static inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start) | ||
306 | { | ||
307 | NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3); | ||
308 | } | ||
309 | |||
310 | static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect) | ||
311 | { | ||
312 | uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); | ||
313 | |||
314 | if (protect) { | ||
315 | NVVgaSeqReset(dev, head, true); | ||
316 | NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); | ||
317 | } else { | ||
318 | /* Reenable sequencer, then turn on screen */ | ||
319 | NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */ | ||
320 | NVVgaSeqReset(dev, head, false); | ||
321 | } | ||
322 | NVSetEnablePalette(dev, head, protect); | ||
323 | } | ||
324 | |||
325 | static inline bool | ||
326 | nv_heads_tied(struct drm_device *dev) | ||
327 | { | ||
328 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
329 | |||
330 | if (dev_priv->chipset == 0x11) | ||
331 | return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)); | ||
332 | |||
333 | return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4; | ||
334 | } | ||
335 | |||
336 | /* makes cr0-7 on the specified head read-only */ | ||
337 | static inline bool | ||
338 | nv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock) | ||
339 | { | ||
340 | uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX); | ||
341 | bool waslocked = cr11 & 0x80; | ||
342 | |||
343 | if (lock) | ||
344 | cr11 |= 0x80; | ||
345 | else | ||
346 | cr11 &= ~0x80; | ||
347 | NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11); | ||
348 | |||
349 | return waslocked; | ||
350 | } | ||
351 | |||
352 | static inline void | ||
353 | nv_lock_vga_crtc_shadow(struct drm_device *dev, int head, int lock) | ||
354 | { | ||
355 | /* shadow lock: connects 0x60?3d? regs to "real" 0x3d? regs | ||
356 | * bit7: unlocks HDT, HBS, HBE, HRS, HRE, HEB | ||
357 | * bit6: seems to have some effect on CR09 (double scan, VBS_9) | ||
358 | * bit5: unlocks HDE | ||
359 | * bit4: unlocks VDE | ||
360 | * bit3: unlocks VDT, OVL, VRS, ?VRE?, VBS, VBE, LSR, EBR | ||
361 | * bit2: same as bit 1 of 0x60?804 | ||
362 | * bit0: same as bit 0 of 0x60?804 | ||
363 | */ | ||
364 | |||
365 | uint8_t cr21 = lock; | ||
366 | |||
367 | if (lock < 0) | ||
368 | /* 0xfa is generic "unlock all" mask */ | ||
369 | cr21 = NVReadVgaCrtc(dev, head, NV_CIO_CRE_21) | 0xfa; | ||
370 | |||
371 | NVWriteVgaCrtc(dev, head, NV_CIO_CRE_21, cr21); | ||
372 | } | ||
373 | |||
374 | /* renders the extended crtc regs (cr19+) on all crtcs impervious: | ||
375 | * immutable and unreadable | ||
376 | */ | ||
377 | static inline bool | ||
378 | NVLockVgaCrtcs(struct drm_device *dev, bool lock) | ||
379 | { | ||
380 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
381 | bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX); | ||
382 | |||
383 | NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX, | ||
384 | lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE); | ||
385 | /* NV11 has independently lockable extended crtcs, except when tied */ | ||
386 | if (dev_priv->chipset == 0x11 && !nv_heads_tied(dev)) | ||
387 | NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX, | ||
388 | lock ? NV_CIO_SR_LOCK_VALUE : | ||
389 | NV_CIO_SR_UNLOCK_RW_VALUE); | ||
390 | |||
391 | return waslocked; | ||
392 | } | ||
393 | |||
394 | /* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */ | ||
395 | #define NV04_CURSOR_SIZE 32 | ||
396 | /* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */ | ||
397 | #define NV10_CURSOR_SIZE 64 | ||
398 | |||
399 | static inline int nv_cursor_width(struct drm_device *dev) | ||
400 | { | ||
401 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
402 | |||
403 | return dev_priv->card_type >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE; | ||
404 | } | ||
405 | |||
406 | static inline void | ||
407 | nv_fix_nv40_hw_cursor(struct drm_device *dev, int head) | ||
408 | { | ||
409 | /* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40, | ||
410 | * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS | ||
411 | * for changes to the CRTC CURCTL regs to take effect, whether changing | ||
412 | * the pixmap location, or just showing/hiding the cursor | ||
413 | */ | ||
414 | uint32_t curpos = NVReadRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS); | ||
415 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos); | ||
416 | } | ||
417 | |||
418 | static inline void | ||
419 | nv_show_cursor(struct drm_device *dev, int head, bool show) | ||
420 | { | ||
421 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
422 | uint8_t *curctl1 = | ||
423 | &dev_priv->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX]; | ||
424 | |||
425 | if (show) | ||
426 | *curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); | ||
427 | else | ||
428 | *curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); | ||
429 | NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1); | ||
430 | |||
431 | if (dev_priv->card_type == NV_40) | ||
432 | nv_fix_nv40_hw_cursor(dev, head); | ||
433 | } | ||
434 | |||
435 | static inline uint32_t | ||
436 | nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp) | ||
437 | { | ||
438 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
439 | int mask; | ||
440 | |||
441 | if (bpp == 15) | ||
442 | bpp = 16; | ||
443 | if (bpp == 24) | ||
444 | bpp = 8; | ||
445 | |||
446 | /* Alignment requirements taken from the Haiku driver */ | ||
447 | if (dev_priv->card_type == NV_04) | ||
448 | mask = 128 / bpp - 1; | ||
449 | else | ||
450 | mask = 512 / bpp - 1; | ||
451 | |||
452 | return (width + mask) & ~mask; | ||
453 | } | ||
454 | |||
455 | #endif /* __NOUVEAU_HW_H__ */ | ||