2 Copyright © 2004-2006, The AROS Development Team. All rights reserved.
5 Desc: nvidia.hidd initialization
9 /***************************************************************************\
11 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
13 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
14 |* international laws. Users and possessors of this source code are *|
15 |* hereby granted a nonexclusive, royalty-free copyright license to *|
16 |* use this code in individual and commercial software. *|
18 |* Any use of this source code must include, in the user documenta- *|
19 |* tion and internal comments to the code, notices to the end user *|
22 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
24 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
25 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
26 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
27 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
28 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
29 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
30 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
31 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
32 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
33 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
34 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
36 |* U.S. Government End Users. This source code is a "commercial *|
37 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
38 |* consisting of "commercial computer software" and "commercial *|
39 |* computer software documentation," as such terms are used in *|
40 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
41 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
42 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
43 |* all U.S. Government End Users acquire the source code with only *|
44 |* those rights set forth herein. *|
46 \***************************************************************************/
49 #include <aros/libcall.h>
50 #include <aros/asmcall.h>
52 #include <exec/types.h>
53 #include <exec/nodes.h>
54 #include <exec/execbase.h>
55 #include <exec/resident.h>
56 #include <exec/libraries.h>
57 #include <exec/memory.h>
58 #include <exec/lists.h>
59 #include <exec/semaphores.h>
61 #include <utility/utility.h>
62 #include <utility/hooks.h>
63 #include <utility/tagitem.h>
68 #include <hidd/graphics.h>
71 #include <aros/debug.h>
73 #include <proto/exec.h>
74 #include <proto/oop.h>
81 static inline __attribute__((always_inline
))
82 ULONG
pciReadLong(struct staticdata
*sd
,
83 UBYTE bus
, UBYTE dev
, UBYTE sub
, UBYTE reg
)
85 struct pHidd_PCIDriver_ReadConfigLong __msg
= {
90 return (ULONG
)OOP_DoMethod(sd
->pcidriver
, (OOP_Msg
)msg
);
93 void nv4GetConfig(struct staticdata
*sd
)
95 struct Card
*pNv
= &sd
->Card
;
97 if (pNv
->PFB
[0x0000/4] & 0x00000100) {
98 pNv
->RamAmountKBytes
= ((pNv
->PFB
[0x0000/4] >> 12) & 0x0F) * 1024 * 2
101 switch (pNv
->PFB
[0x0000/4] & 0x00000003) {
103 pNv
->RamAmountKBytes
= 1024 * 32;
106 pNv
->RamAmountKBytes
= 1024 * 4;
109 pNv
->RamAmountKBytes
= 1024 * 8;
113 pNv
->RamAmountKBytes
= 1024 * 16;
117 pNv
->CrystalFreqKHz
= (pNv
->PEXTDEV
[0x0000/4] & 0x00000040) ? 14318 : 13500;
118 pNv
->CURSOR
= &(pNv
->PRAMIN
[0x1E00]);
119 pNv
->MinVClockFreqKHz
= 12000;
120 pNv
->MaxVClockFreqKHz
= 350000;
123 void nv10GetConfig (struct staticdata
*sd
)
125 struct Card
*pNv
= &sd
->Card
;
126 ULONG implementation
= pNv
->Chipset
& 0x0ff0;
129 /* turn on big endian register access */
130 if(!(pNv
->PMC
[0x0004/4] & 0x01000001)) {
131 pNv
->PMC
[0x0004/4] = 0x01000001;
136 if(implementation
== 0x01a0) {
137 int amt
= pciReadLong(sd
, 0, 0, 1, 0x7C);
138 pNv
->RamAmountKBytes
= (((amt
>> 6) & 31) + 1) * 1024;
139 } else if(implementation
== 0x01f0) {
140 int amt
= pciReadLong(sd
, 0, 0, 1, 0x84);
141 pNv
->RamAmountKBytes
= (((amt
>> 4) & 127) + 1) * 1024;
143 pNv
->RamAmountKBytes
= (pNv
->PFB
[0x020C/4] & 0xFFF00000) >> 10;
146 pNv
->CrystalFreqKHz
= (pNv
->PEXTDEV
[0x0000/4] & (1 << 6)) ? 14318 : 13500;
148 if(pNv
->twoHeads
&& (implementation
!= 0x0110))
150 if(pNv
->PEXTDEV
[0x0000/4] & (1 << 22))
151 pNv
->CrystalFreqKHz
= 27000;
154 pNv
->CursorStart
= (pNv
->RamAmountKBytes
- 96) * 1024;
155 pNv
->CURSOR
= NULL
; /* can't set this here */
156 pNv
->MinVClockFreqKHz
= 12000;
157 pNv
->MaxVClockFreqKHz
= pNv
->twoStagePLL
? 400000 : 350000;
162 static inline void CRTC_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
164 VGA_WR08(sd
->Card
.PCIO
, 0x3d4, index
);
165 VGA_WR08(sd
->Card
.PCIO
, 0x3d5, val
);
168 static inline UBYTE
CRTC_in(struct staticdata
*sd
, UBYTE index
)
170 VGA_WR08(sd
->Card
.PCIO
, 0x3d4, index
);
171 return VGA_RD08(sd
->Card
.PCIO
, 0x3d5);
174 static inline void GRA_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
176 VGA_WR08(sd
->Card
.PVIO
, 0x3ce, index
);
177 VGA_WR08(sd
->Card
.PVIO
, 0x3cf, val
);
180 static inline UBYTE
GRA_in(struct staticdata
*sd
, UBYTE index
)
182 VGA_WR08(sd
->Card
.PVIO
, 0x3ce, index
);
183 return VGA_RD08(sd
->Card
.PVIO
, 0x3cf);
186 static inline void SEQ_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
188 VGA_WR08(sd
->Card
.PVIO
, 0x3c4, index
);
189 VGA_WR08(sd
->Card
.PVIO
, 0x3c5, val
);
192 static inline UBYTE
SEQ_in(struct staticdata
*sd
, UBYTE index
)
194 VGA_WR08(sd
->Card
.PVIO
, 0x3c4, index
);
195 return VGA_RD08(sd
->Card
.PVIO
, 0x3c5);
198 static inline void ATTR_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
202 tmp
= VGA_RD08(sd
->Card
.PCIO
, 0x3da);
203 if (sd
->Card
.paletteEnabled
)
208 VGA_WR08(sd
->Card
.PCIO
, 0x3c0, index
);
209 VGA_WR08(sd
->Card
.PCIO
, 0x3c0, val
);
212 static inline UBYTE
ATTR_in(struct staticdata
*sd
, UBYTE index
)
216 tmp
= VGA_RD08(sd
->Card
.PCIO
, 0x3da);
217 if (sd
->Card
.paletteEnabled
)
221 VGA_WR08(sd
->Card
.PCIO
, 0x3c0, index
);
223 return VGA_RD08(sd
->Card
.PCIO
, 0x3c1);
226 static inline void MISC_out(struct staticdata
*sd
, UBYTE val
)
228 VGA_WR08(sd
->Card
.PVIO
, 0x3c2, val
);
231 static inline UBYTE
MISC_in(struct staticdata
*sd
)
233 return VGA_RD08(sd
->Card
.PVIO
, 0x3cc);
236 void NVLockUnlock(struct staticdata
*sd
, UBYTE Lock
)
240 ObtainSemaphore(&sd
->HWLock
);
241 VGA_WR08(sd
->Card
.PCIO
, 0x3D4, 0x1F);
242 VGA_WR08(sd
->Card
.PCIO
, 0x3D5, Lock
? 0x99 : 0x57);
244 VGA_WR08(sd
->Card
.PCIO
, 0x3D4, 0x11);
245 cr11
= VGA_RD08(sd
->Card
.PCIO
, 0x3D5);
246 if(Lock
) cr11
|= 0x80;
248 VGA_WR08(sd
->Card
.PCIO
, 0x3D5, cr11
);
249 ReleaseSemaphore(&sd
->HWLock
);
252 int NVShowHideCursor (struct staticdata
*sd
, UBYTE ShowHide
)
254 int current
= sd
->Card
.CurrentState
->cursor1
;
256 ObtainSemaphore(&sd
->HWLock
);
257 sd
->Card
.CurrentState
->cursor1
= (sd
->Card
.CurrentState
->cursor1
& 0xFE) |
259 VGA_WR08(sd
->Card
.PCIO
, 0x3D4, 0x31);
260 VGA_WR08(sd
->Card
.PCIO
, 0x3D5, sd
->Card
.CurrentState
->cursor1
);
262 if (sd
->Card
.Architecture
== NV_ARCH_40
) { /* HW bug */
263 volatile ULONG curpos
= sd
->Card
.PRAMDAC
[0x0300/4];
264 sd
->Card
.PRAMDAC
[0x0300/4] = curpos
;
267 ReleaseSemaphore(&sd
->HWLock
);
268 return (current
& 0x01);
271 /****************************************************************************\
273 * The video arbitration routines calculate some "magic" numbers. Fixes *
274 * the snow seen when accessing the framebuffer without it. *
275 * It just works (I hope). *
277 \****************************************************************************/
282 int graphics_burst_size
;
283 int video_burst_size
;
304 int graphics_burst_size
;
305 int video_burst_size
;
324 static void nvGetClocks(NVPtr pNv
, ULONG
*MClk
, ULONG
*NVClk
)
326 unsigned int pll
, N
, M
, MB
, NB
, P
;
328 if(pNv
->Architecture
>= NV_ARCH_40
) {
329 pll
= pNv
->PMC
[0x4020/4];
330 P
= (pll
>> 16) & 0x03;
331 pll
= pNv
->PMC
[0x4024/4];
333 N
= (pll
>> 8) & 0xFF;
334 MB
= (pll
>> 16) & 0xFF;
335 NB
= (pll
>> 24) & 0xFF;
336 *MClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
338 pll
= pNv
->PMC
[0x4000/4];
339 P
= (pll
>> 16) & 0x03;
340 pll
= pNv
->PMC
[0x4004/4];
342 N
= (pll
>> 8) & 0xFF;
343 MB
= (pll
>> 16) & 0xFF;
344 NB
= (pll
>> 24) & 0xFF;
346 *NVClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
348 if(pNv
->twoStagePLL
) {
349 pll
= pNv
->PRAMDAC0
[0x0504/4];
351 N
= (pll
>> 8) & 0xFF;
352 P
= (pll
>> 16) & 0x0F;
353 pll
= pNv
->PRAMDAC0
[0x0574/4];
354 if(pll
& 0x80000000) {
356 NB
= (pll
>> 8) & 0xFF;
361 *MClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
363 pll
= pNv
->PRAMDAC0
[0x0500/4];
365 N
= (pll
>> 8) & 0xFF;
366 P
= (pll
>> 16) & 0x0F;
367 pll
= pNv
->PRAMDAC0
[0x0570/4];
368 if(pll
& 0x80000000) {
370 NB
= (pll
>> 8) & 0xFF;
375 *NVClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
377 if(((pNv
->Chipset
& 0x0ff0) == 0x0300) ||
378 ((pNv
->Chipset
& 0x0ff0) == 0x0330))
380 pll
= pNv
->PRAMDAC0
[0x0504/4];
382 N
= (pll
>> 8) & 0xFF;
383 P
= (pll
>> 16) & 0x07;
384 if(pll
& 0x00000080) {
385 MB
= (pll
>> 4) & 0x07;
386 NB
= (pll
>> 19) & 0x1f;
391 *MClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
393 pll
= pNv
->PRAMDAC0
[0x0500/4];
395 N
= (pll
>> 8) & 0xFF;
396 P
= (pll
>> 16) & 0x07;
397 if(pll
& 0x00000080) {
398 MB
= (pll
>> 4) & 0x07;
399 NB
= (pll
>> 19) & 0x1f;
404 *NVClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
406 pll
= pNv
->PRAMDAC0
[0x0504/4];
408 N
= (pll
>> 8) & 0xFF;
409 P
= (pll
>> 16) & 0x0F;
410 *MClk
= (N
* pNv
->CrystalFreqKHz
/ M
) >> P
;
412 pll
= pNv
->PRAMDAC0
[0x0500/4];
414 N
= (pll
>> 8) & 0xFF;
415 P
= (pll
>> 16) & 0x0F;
416 *NVClk
= (N
* pNv
->CrystalFreqKHz
/ M
) >> P
;
420 static void nv4CalcArbitration (
425 int data
, pagemiss
, cas
,width
, video_enable
, bpp
;
426 int nvclks
, mclks
, pclks
, vpagemiss
, crtpagemiss
, vbs
;
427 int found
, mclk_extra
, mclk_loop
, cbs
, m1
, p1
;
428 int mclk_freq
, pclk_freq
, nvclk_freq
, mp_enable
;
429 int us_m
, us_n
, us_p
, video_drain_rate
, crtc_drain_rate
;
430 int vpm_us
, us_video
, vlwm
, video_fill_us
, cpm_us
, us_crt
,clwm
;
433 pclk_freq
= arb
->pclk_khz
;
434 mclk_freq
= arb
->mclk_khz
;
435 nvclk_freq
= arb
->nvclk_khz
;
436 pagemiss
= arb
->mem_page_miss
;
437 cas
= arb
->mem_latency
;
438 width
= arb
->memory_width
>> 6;
439 video_enable
= arb
->enable_video
;
441 mp_enable
= arb
->enable_mp
;
472 mclk_loop
= mclks
+mclk_extra
;
473 us_m
= mclk_loop
*1000*1000 / mclk_freq
;
474 us_n
= nvclks
*1000*1000 / nvclk_freq
;
475 us_p
= nvclks
*1000*1000 / pclk_freq
;
478 video_drain_rate
= pclk_freq
* 2;
479 crtc_drain_rate
= pclk_freq
* bpp
/8;
483 vpm_us
= (vpagemiss
* pagemiss
)*1000*1000/mclk_freq
;
484 if (nvclk_freq
* 2 > mclk_freq
* width
)
485 video_fill_us
= cbs
*1000*1000 / 16 / nvclk_freq
;
487 video_fill_us
= cbs
*1000*1000 / (8 * width
) / mclk_freq
;
488 us_video
= vpm_us
+ us_m
+ us_n
+ us_p
+ video_fill_us
;
489 vlwm
= us_video
* video_drain_rate
/(1000*1000);
492 if (vlwm
> 128) vbs
= 64;
493 if (vlwm
> (256-64)) vbs
= 32;
494 if (nvclk_freq
* 2 > mclk_freq
* width
)
495 video_fill_us
= vbs
*1000*1000/ 16 / nvclk_freq
;
497 video_fill_us
= vbs
*1000*1000 / (8 * width
) / mclk_freq
;
498 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
505 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
510 crtc_drain_rate
= pclk_freq
* bpp
/8;
513 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
514 us_crt
= cpm_us
+ us_m
+ us_n
+ us_p
;
515 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
518 m1
= clwm
+ cbs
- 512;
519 p1
= m1
* pclk_freq
/ mclk_freq
;
521 if ((p1
< m1
) && (m1
> 0))
525 if (mclk_extra
==0) found
= 1;
528 else if (video_enable
)
530 if ((clwm
> 511) || (vlwm
> 255))
534 if (mclk_extra
==0) found
= 1;
544 if (mclk_extra
==0) found
= 1;
548 if (clwm
< 384) clwm
= 384;
549 if (vlwm
< 128) vlwm
= 128;
551 fifo
->graphics_lwm
= data
;
552 fifo
->graphics_burst_size
= 128;
553 data
= (int)((vlwm
+15));
554 fifo
->video_lwm
= data
;
555 fifo
->video_burst_size
= vbs
;
559 static void nv4UpdateArbitrationSettings (
567 nv4_fifo_info fifo_data
;
568 nv4_sim_state sim_data
;
569 ULONG MClk
, NVClk
, cfg1
;
571 nvGetClocks(pNv
, &MClk
, &NVClk
);
573 cfg1
= pNv
->PFB
[0x00000204/4];
574 sim_data
.pix_bpp
= (char)pixelDepth
;
575 sim_data
.enable_video
= 0;
576 sim_data
.enable_mp
= 0;
577 sim_data
.memory_width
= (pNv
->PEXTDEV
[0x0000/4] & 0x10) ? 128 : 64;
578 sim_data
.mem_latency
= (char)cfg1
& 0x0F;
579 sim_data
.mem_aligned
= 1;
580 sim_data
.mem_page_miss
= (char)(((cfg1
>> 4) &0x0F) + ((cfg1
>> 31) & 0x01));
581 sim_data
.gr_during_vid
= 0;
582 sim_data
.pclk_khz
= VClk
;
583 sim_data
.mclk_khz
= MClk
;
584 sim_data
.nvclk_khz
= NVClk
;
585 nv4CalcArbitration(&fifo_data
, &sim_data
);
588 int b
= fifo_data
.graphics_burst_size
>> 4;
590 while (b
>>= 1) (*burst
)++;
591 *lwm
= fifo_data
.graphics_lwm
>> 3;
595 static void nv10CalcArbitration (
596 nv10_fifo_info
*fifo
,
600 int data
, pagemiss
, width
, video_enable
, bpp
;
601 int nvclks
, mclks
, pclks
, vpagemiss
, crtpagemiss
;
603 int found
, mclk_extra
, mclk_loop
, cbs
, m1
;
604 int mclk_freq
, pclk_freq
, nvclk_freq
, mp_enable
;
605 int us_m
, us_m_min
, us_n
, us_p
, crtc_drain_rate
;
607 int vpm_us
, us_video
, cpm_us
, us_crt
,clwm
;
609 int m2us
, us_pipe_min
, p1clk
, p2
;
611 int us_min_mclk_extra
;
614 pclk_freq
= arb
->pclk_khz
; /* freq in KHz */
615 mclk_freq
= arb
->mclk_khz
;
616 nvclk_freq
= arb
->nvclk_khz
;
617 pagemiss
= arb
->mem_page_miss
;
618 width
= arb
->memory_width
/64;
619 video_enable
= arb
->enable_video
;
621 mp_enable
= arb
->enable_mp
;
626 pclks
= 4; /* lwm detect. */
628 nvclks
= 3; /* lwm -> sync. */
629 nvclks
+= 2; /* fbi bus cycles (1 req + 1 busy) */
631 mclks
= 1; /* 2 edge sync. may be very close to edge so just put one. */
633 mclks
+= 1; /* arb_hp_req */
634 mclks
+= 5; /* ap_hp_req tiling pipeline */
636 mclks
+= 2; /* tc_req latency fifo */
637 mclks
+= 2; /* fb_cas_n_ memory request to fbio block */
638 mclks
+= 7; /* sm_d_rdv data returned from fbio block */
640 /* fb.rd.d.Put_gc need to accumulate 256 bits for read */
641 if (arb
->memory_type
== 0)
642 if (arb
->memory_width
== 64) /* 64 bit bus */
647 if (arb
->memory_width
== 64) /* 64 bit bus */
652 if ((!video_enable
) && (arb
->memory_width
== 128))
654 mclk_extra
= (bpp
== 32) ? 31 : 42; /* Margin of error */
659 mclk_extra
= (bpp
== 32) ? 8 : 4; /* Margin of error */
660 /* mclk_extra = 4; */ /* Margin of error */
664 nvclks
+= 1; /* 2 edge sync. may be very close to edge so just put one. */
665 nvclks
+= 1; /* fbi_d_rdv_n */
666 nvclks
+= 1; /* Fbi_d_rdata */
667 nvclks
+= 1; /* crtfifo load */
670 mclks
+=4; /* Mp can get in with a burst of 8. */
671 /* Extra clocks determined by heuristics */
679 mclk_loop
= mclks
+mclk_extra
;
680 us_m
= mclk_loop
*1000*1000 / mclk_freq
; /* Mclk latency in us */
681 us_m_min
= mclks
* 1000*1000 / mclk_freq
; /* Minimum Mclk latency in us */
682 us_min_mclk_extra
= min_mclk_extra
*1000*1000 / mclk_freq
;
683 us_n
= nvclks
*1000*1000 / nvclk_freq
;/* nvclk latency in us */
684 us_p
= pclks
*1000*1000 / pclk_freq
;/* nvclk latency in us */
685 us_pipe_min
= us_m_min
+ us_n
+ us_p
;
687 vus_m
= mclk_loop
*1000*1000 / mclk_freq
; /* Mclk latency in us */
690 crtc_drain_rate
= pclk_freq
* bpp
/8; /* MB/s */
692 vpagemiss
= 1; /* self generating page miss */
693 vpagemiss
+= 1; /* One higher priority before */
695 crtpagemiss
= 2; /* self generating page miss */
697 crtpagemiss
+= 1; /* if MA0 conflict */
699 vpm_us
= (vpagemiss
* pagemiss
)*1000*1000/mclk_freq
;
701 us_video
= vpm_us
+ vus_m
; /* Video has separate read return path */
703 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
705 us_video
/* Wait for video */
706 +cpm_us
/* CRT Page miss */
707 +us_m
+ us_n
+us_p
/* other latency */
710 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
711 clwm
++; /* fixed point <= float_point - 1. Fixes that */
713 crtc_drain_rate
= pclk_freq
* bpp
/8; /* bpp * pclk/8 */
715 crtpagemiss
= 1; /* self generating page miss */
716 crtpagemiss
+= 1; /* MA0 page miss */
718 crtpagemiss
+= 1; /* if MA0 conflict */
719 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
720 us_crt
= cpm_us
+ us_m
+ us_n
+ us_p
;
721 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
722 clwm
++; /* fixed point <= float_point - 1. Fixes that */
724 /* Finally, a heuristic check when width == 64 bits */
726 nvclk_fill
= nvclk_freq
* 8;
727 if(crtc_drain_rate
* 100 >= nvclk_fill
* 102)
728 clwm
= 0xfff; /*Large number to fail */
730 else if(crtc_drain_rate
* 100 >= nvclk_fill
* 98) {
743 clwm_rnd_down
= ((int)clwm
/8)*8;
744 if (clwm_rnd_down
< clwm
)
747 m1
= clwm
+ cbs
- 1024; /* Amount of overfill */
748 m2us
= us_pipe_min
+ us_min_mclk_extra
;
750 /* pclk cycles to drain */
751 p1clk
= m2us
* pclk_freq
/(1000*1000);
752 p2
= p1clk
* bpp
/ 8; /* bytes drained. */
754 if((p2
< m1
) && (m1
> 0)) {
757 if(min_mclk_extra
== 0) {
759 found
= 1; /* Can't adjust anymore! */
761 cbs
= cbs
/2; /* reduce the burst size */
767 if (clwm
> 1023){ /* Have some margin */
770 if(min_mclk_extra
== 0)
771 found
= 1; /* Can't adjust anymore! */
777 if(clwm
< (1024-cbs
+8)) clwm
= 1024-cbs
+8;
779 /* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
780 fifo
->graphics_lwm
= data
; fifo
->graphics_burst_size
= cbs
;
782 fifo
->video_lwm
= 1024; fifo
->video_burst_size
= 512;
786 static void nv10UpdateArbitrationSettings (
794 nv10_fifo_info fifo_data
;
795 nv10_sim_state sim_data
;
796 ULONG MClk
, NVClk
, cfg1
;
798 nvGetClocks(pNv
, &MClk
, &NVClk
);
800 cfg1
= pNv
->PFB
[0x0204/4];
801 sim_data
.pix_bpp
= (char)pixelDepth
;
802 sim_data
.enable_video
= 1;
803 sim_data
.enable_mp
= 0;
804 sim_data
.memory_type
= (pNv
->PFB
[0x0200/4] & 0x01) ? 1 : 0;
805 sim_data
.memory_width
= (pNv
->PEXTDEV
[0x0000/4] & 0x10) ? 128 : 64;
806 sim_data
.mem_latency
= (char)cfg1
& 0x0F;
807 sim_data
.mem_aligned
= 1;
808 sim_data
.mem_page_miss
= (char)(((cfg1
>>4) &0x0F) + ((cfg1
>>31) & 0x01));
809 sim_data
.gr_during_vid
= 0;
810 sim_data
.pclk_khz
= VClk
;
811 sim_data
.mclk_khz
= MClk
;
812 sim_data
.nvclk_khz
= NVClk
;
814 nv10CalcArbitration(&fifo_data
, &sim_data
);
815 if (fifo_data
.valid
) {
816 int b
= fifo_data
.graphics_burst_size
>> 4;
818 while (b
>>= 1) (*burst
)++;
819 *lwm
= fifo_data
.graphics_lwm
>> 3;
823 static void nv30UpdateArbitrationSettings (
830 unsigned int fifo_size
, burst_size
, graphics_lwm
;
834 graphics_lwm
= fifo_size
- burst_size
;
836 nvGetClocks(pNv
, &MClk
, &NVClk
);
840 while(burst_size
>>= 1) (*burst
)++;
841 *lwm
= graphics_lwm
>> 3;
844 static void nForceUpdateArbitrationSettings (
849 struct staticdata
*sd
,
853 nv10_fifo_info fifo_data
;
854 nv10_sim_state sim_data
;
855 unsigned int M
, N
, P
, pll
, MClk
, NVClk
, memctrl
;
857 if((pNv
->Chipset
& 0x0FF0) == 0x01A0) {
858 unsigned int uMClkPostDiv
;
860 uMClkPostDiv
= (pciReadLong(sd
, 0, 0, 3, 0x6C) >> 8) & 0xf;
861 if(!uMClkPostDiv
) uMClkPostDiv
= 4;
862 MClk
= 400000 / uMClkPostDiv
;
864 MClk
= pciReadLong(sd
, 0, 0, 5, 0x4C) / 1000;
867 pll
= pNv
->PRAMDAC0
[0x0500/4];
868 M
= (pll
>> 0) & 0xFF; N
= (pll
>> 8) & 0xFF; P
= (pll
>> 16) & 0x0F;
869 NVClk
= (N
* pNv
->CrystalFreqKHz
/ M
) >> P
;
870 sim_data
.pix_bpp
= (char)pixelDepth
;
871 sim_data
.enable_video
= 0;
872 sim_data
.enable_mp
= 0;
873 sim_data
.memory_type
= (pciReadLong(sd
, 0, 0, 1, 0x7C) >> 12) & 1;
874 sim_data
.memory_width
= 64;
876 memctrl
= pciReadLong(sd
, 0, 0, 3, 0x00) >> 16;
878 if((memctrl
== 0x1A9) || (memctrl
== 0x1AB) || (memctrl
== 0x1ED)) {
881 dimm
[0] = (pciReadLong(sd
, 0, 0, 2, 0x40) >> 8) & 0x4F;
882 dimm
[1] = (pciReadLong(sd
, 0, 0, 2, 0x44) >> 8) & 0x4F;
883 dimm
[2] = (pciReadLong(sd
, 0, 0, 2, 0x48) >> 8) & 0x4F;
885 if((dimm
[0] + dimm
[1]) != dimm
[2]) {
887 "your nForce DIMMs are not arranged in optimal banks!\n");
891 sim_data
.mem_latency
= 3;
892 sim_data
.mem_aligned
= 1;
893 sim_data
.mem_page_miss
= 10;
894 sim_data
.gr_during_vid
= 0;
895 sim_data
.pclk_khz
= VClk
;
896 sim_data
.mclk_khz
= MClk
;
897 sim_data
.nvclk_khz
= NVClk
;
898 nv10CalcArbitration(&fifo_data
, &sim_data
);
901 int b
= fifo_data
.graphics_burst_size
>> 4;
903 while (b
>>= 1) (*burst
)++;
904 *lwm
= fifo_data
.graphics_lwm
>> 3;
908 /****************************************************************************\
910 * RIVA Mode State Routines *
912 \****************************************************************************/
915 * Calculate the Video Clock parameters for the PLL.
917 static void CalcVClock (
924 unsigned lowM
, highM
;
925 unsigned DeltaNew
, DeltaOld
;
929 DeltaOld
= 0xFFFFFFFF;
931 VClk
= (unsigned)clockIn
;
933 if (pNv
->CrystalFreqKHz
== 13500) {
941 for (P
= 0; P
<= 4; P
++) {
943 if ((Freq
>= 128000) && (Freq
<= 350000)) {
944 for (M
= lowM
; M
<= highM
; M
++) {
945 N
= ((VClk
<< P
) * M
) / pNv
->CrystalFreqKHz
;
947 Freq
= ((pNv
->CrystalFreqKHz
* N
) / M
) >> P
;
949 DeltaNew
= Freq
- VClk
;
951 DeltaNew
= VClk
- Freq
;
952 if (DeltaNew
< DeltaOld
) {
953 *pllOut
= (P
<< 16) | (N
<< 8) | M
;
963 static void CalcVClock2Stage (
971 unsigned DeltaNew
, DeltaOld
;
975 DeltaOld
= 0xFFFFFFFF;
977 *pllBOut
= 0x80000401; /* fixed at x4 for now */
979 VClk
= (unsigned)clockIn
;
981 for (P
= 0; P
<= 6; P
++) {
983 if ((Freq
>= 400000) && (Freq
<= 1000000)) {
984 for (M
= 1; M
<= 13; M
++) {
985 N
= ((VClk
<< P
) * M
) / (pNv
->CrystalFreqKHz
<< 2);
986 if((N
>= 5) && (N
<= 255)) {
987 Freq
= (((pNv
->CrystalFreqKHz
<< 2) * N
) / M
) >> P
;
989 DeltaNew
= Freq
- VClk
;
991 DeltaNew
= VClk
- Freq
;
992 if (DeltaNew
< DeltaOld
) {
993 *pllOut
= (P
<< 16) | (N
<< 8) | M
;
1005 * Calculate extended mode parameters (SVGA) and save in a
1006 * mode state structure.
1008 void NVCalcStateExt (
1009 struct staticdata
*sd
,
1011 RIVA_HW_STATE
*state
,
1020 ULONG pixelDepth
, VClk
;
1022 * Save mode parameters.
1024 state
->bpp
= bpp
; /* this is not bitsPerPixel, it's 8,15,16,32 */
1025 state
->width
= width
;
1026 state
->height
= height
;
1028 * Extended RIVA registers.
1030 pixelDepth
= (bpp
+ 1)/8;
1032 if(pNv
->twoStagePLL
)
1033 CalcVClock2Stage(dotClock
, &VClk
, &state
->pll
, &state
->pllB
, pNv
);
1035 CalcVClock(dotClock
, &VClk
, &state
->pll
, pNv
);
1037 switch (pNv
->Architecture
)
1040 nv4UpdateArbitrationSettings(VClk
,
1042 &(state
->arbitration0
),
1043 &(state
->arbitration1
),
1045 state
->cursor0
= 0x00;
1046 state
->cursor1
= 0xbC;
1047 if (flags
& V_DBLSCAN
)
1048 state
->cursor1
|= 2;
1049 state
->cursor2
= 0x00000000;
1050 state
->pllsel
= 0x10000700;
1051 state
->config
= 0x00001114;
1052 state
->general
= bpp
== 16 ? 0x00101100 : 0x00100100;
1053 state
->repaint1
= hDisplaySize
< 1280 ? 0x04 : 0x00;
1059 if(((pNv
->Chipset
& 0xffff) == 0x01A0) ||
1060 ((pNv
->Chipset
& 0xffff) == 0x01f0))
1062 nForceUpdateArbitrationSettings(VClk
,
1064 &(state
->arbitration0
),
1065 &(state
->arbitration1
),
1068 } else if (pNv
->Architecture
< NV_ARCH_30
) {
1069 nv10UpdateArbitrationSettings(VClk
,
1071 &(state
->arbitration0
),
1072 &(state
->arbitration1
),
1075 nv30UpdateArbitrationSettings(pNv
,
1076 &(state
->arbitration0
),
1077 &(state
->arbitration1
));
1079 state
->cursor0
= 0x80 | (pNv
->CursorStart
>> 17);
1080 state
->cursor1
= (pNv
->CursorStart
>> 11) << 2;
1081 state
->cursor2
= pNv
->CursorStart
>> 24;
1082 if (flags
& V_DBLSCAN
)
1083 state
->cursor1
|= 2;
1084 state
->pllsel
= 0x10000700;
1085 state
->config
= pNv
->PFB
[0x00000200/4];
1086 state
->general
= bpp
== 16 ? 0x00101100 : 0x00100100;
1087 state
->repaint1
= hDisplaySize
< 1280 ? 0x04 : 0x00;
1090 if(bpp
!= 8) /* DirectColor */
1091 state
->general
|= 0x00000030;
1093 state
->repaint0
= (((width
/ 8) * pixelDepth
) & 0x700) >> 3;
1094 state
->pixel
= (pixelDepth
> 2) ? 3 : pixelDepth
;
1098 ** stegerg: Status NVLoadStateExt(): should "match" xfree nv NVLoadStateExt()
1099 ** in xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c version:
1100 ** 1.12 2004/11/30 23:50:26 mvojkovi
1102 ** Exception: some waitvsyncpossible stuff commented out
1105 void NVLoadStateExt (
1107 RIVA_HW_STATE
*state
1112 pNv
->PMC
[0x0140/4] = 0x00000000;
1113 pNv
->PMC
[0x0200/4] = 0xFFFF00FF;
1114 pNv
->PMC
[0x0200/4] = 0xFFFFFFFF;
1116 pNv
->PTIMER
[0x0200] = 0x00000008;
1117 pNv
->PTIMER
[0x0210] = 0x00000003;
1118 pNv
->PTIMER
[0x0140] = 0x00000000;
1119 pNv
->PTIMER
[0x0100] = 0xFFFFFFFF;
1121 if(pNv
->Architecture
== NV_ARCH_04
) {
1122 pNv
->PFB
[0x0200/4] = state
->config
;
1124 pNv
->PFB
[0x0240/4] = 0;
1125 pNv
->PFB
[0x0244/4] = pNv
->FrameBufferSize
- 1;
1126 pNv
->PFB
[0x0250/4] = 0;
1127 pNv
->PFB
[0x0254/4] = pNv
->FrameBufferSize
- 1;
1128 pNv
->PFB
[0x0260/4] = 0;
1129 pNv
->PFB
[0x0264/4] = pNv
->FrameBufferSize
- 1;
1130 pNv
->PFB
[0x0270/4] = 0;
1131 pNv
->PFB
[0x0274/4] = pNv
->FrameBufferSize
- 1;
1132 pNv
->PFB
[0x0280/4] = 0;
1133 pNv
->PFB
[0x0284/4] = pNv
->FrameBufferSize
- 1;
1134 pNv
->PFB
[0x0290/4] = 0;
1135 pNv
->PFB
[0x0294/4] = pNv
->FrameBufferSize
- 1;
1136 pNv
->PFB
[0x02A0/4] = 0;
1137 pNv
->PFB
[0x02A4/4] = pNv
->FrameBufferSize
- 1;
1138 pNv
->PFB
[0x02B0/4] = 0;
1139 pNv
->PFB
[0x02B4/4] = pNv
->FrameBufferSize
- 1;
1142 if(pNv
->Architecture
>= NV_ARCH_40
) {
1143 pNv
->PRAMIN
[0x0000] = 0x80000010;
1144 pNv
->PRAMIN
[0x0001] = 0x00101202;
1145 pNv
->PRAMIN
[0x0002] = 0x80000011;
1146 pNv
->PRAMIN
[0x0003] = 0x00101204;
1147 pNv
->PRAMIN
[0x0004] = 0x80000012;
1148 pNv
->PRAMIN
[0x0005] = 0x00101206;
1149 pNv
->PRAMIN
[0x0006] = 0x80000013;
1150 pNv
->PRAMIN
[0x0007] = 0x00101208;
1151 pNv
->PRAMIN
[0x0008] = 0x80000014;
1152 pNv
->PRAMIN
[0x0009] = 0x0010120A;
1153 pNv
->PRAMIN
[0x000A] = 0x80000015;
1154 pNv
->PRAMIN
[0x000B] = 0x0010120C;
1155 pNv
->PRAMIN
[0x000C] = 0x80000016;
1156 pNv
->PRAMIN
[0x000D] = 0x0010120E;
1157 pNv
->PRAMIN
[0x000E] = 0x80000017;
1158 pNv
->PRAMIN
[0x000F] = 0x00101210;
1159 pNv
->PRAMIN
[0x0800] = 0x00003000;
1160 pNv
->PRAMIN
[0x0801] = pNv
->FrameBufferSize
- 1;
1161 pNv
->PRAMIN
[0x0802] = 0x00000002;
1162 pNv
->PRAMIN
[0x0808] = 0x02080062;
1163 pNv
->PRAMIN
[0x0809] = 0x00000000;
1164 pNv
->PRAMIN
[0x080A] = 0x00001200;
1165 pNv
->PRAMIN
[0x080B] = 0x00001200;
1166 pNv
->PRAMIN
[0x080C] = 0x00000000;
1167 pNv
->PRAMIN
[0x080D] = 0x00000000;
1168 pNv
->PRAMIN
[0x0810] = 0x02080043;
1169 pNv
->PRAMIN
[0x0811] = 0x00000000;
1170 pNv
->PRAMIN
[0x0812] = 0x00000000;
1171 pNv
->PRAMIN
[0x0813] = 0x00000000;
1172 pNv
->PRAMIN
[0x0814] = 0x00000000;
1173 pNv
->PRAMIN
[0x0815] = 0x00000000;
1174 pNv
->PRAMIN
[0x0818] = 0x02080044;
1175 pNv
->PRAMIN
[0x0819] = 0x02000000;
1176 pNv
->PRAMIN
[0x081A] = 0x00000000;
1177 pNv
->PRAMIN
[0x081B] = 0x00000000;
1178 pNv
->PRAMIN
[0x081C] = 0x00000000;
1179 pNv
->PRAMIN
[0x081D] = 0x00000000;
1180 pNv
->PRAMIN
[0x0820] = 0x02080019;
1181 pNv
->PRAMIN
[0x0821] = 0x00000000;
1182 pNv
->PRAMIN
[0x0822] = 0x00000000;
1183 pNv
->PRAMIN
[0x0823] = 0x00000000;
1184 pNv
->PRAMIN
[0x0824] = 0x00000000;
1185 pNv
->PRAMIN
[0x0825] = 0x00000000;
1186 pNv
->PRAMIN
[0x0828] = 0x020A005C;
1187 pNv
->PRAMIN
[0x0829] = 0x00000000;
1188 pNv
->PRAMIN
[0x082A] = 0x00000000;
1189 pNv
->PRAMIN
[0x082B] = 0x00000000;
1190 pNv
->PRAMIN
[0x082C] = 0x00000000;
1191 pNv
->PRAMIN
[0x082D] = 0x00000000;
1192 pNv
->PRAMIN
[0x0830] = 0x0208009F;
1193 pNv
->PRAMIN
[0x0831] = 0x00000000;
1194 pNv
->PRAMIN
[0x0832] = 0x00001200;
1195 pNv
->PRAMIN
[0x0833] = 0x00001200;
1196 pNv
->PRAMIN
[0x0834] = 0x00000000;
1197 pNv
->PRAMIN
[0x0835] = 0x00000000;
1198 pNv
->PRAMIN
[0x0838] = 0x0208004A;
1199 pNv
->PRAMIN
[0x0839] = 0x02000000;
1200 pNv
->PRAMIN
[0x083A] = 0x00000000;
1201 pNv
->PRAMIN
[0x083B] = 0x00000000;
1202 pNv
->PRAMIN
[0x083C] = 0x00000000;
1203 pNv
->PRAMIN
[0x083D] = 0x00000000;
1204 pNv
->PRAMIN
[0x0840] = 0x02080077;
1205 pNv
->PRAMIN
[0x0841] = 0x00000000;
1206 pNv
->PRAMIN
[0x0842] = 0x00001200;
1207 pNv
->PRAMIN
[0x0843] = 0x00001200;
1208 pNv
->PRAMIN
[0x0844] = 0x00000000;
1209 pNv
->PRAMIN
[0x0845] = 0x00000000;
1210 pNv
->PRAMIN
[0x084C] = 0x00003002;
1211 pNv
->PRAMIN
[0x084D] = 0x00007FFF;
1212 pNv
->PRAMIN
[0x084E] = pNv
->FbUsableSize
| 0x00000002;
1215 pNv
->PRAMIN
[0x080A] |= 0x01000000;
1216 pNv
->PRAMIN
[0x0812] |= 0x01000000;
1217 pNv
->PRAMIN
[0x081A] |= 0x01000000;
1218 pNv
->PRAMIN
[0x0822] |= 0x01000000;
1219 pNv
->PRAMIN
[0x082A] |= 0x01000000;
1220 pNv
->PRAMIN
[0x0832] |= 0x01000000;
1221 pNv
->PRAMIN
[0x083A] |= 0x01000000;
1222 pNv
->PRAMIN
[0x0842] |= 0x01000000;
1223 pNv
->PRAMIN
[0x0819] = 0x01000000;
1224 pNv
->PRAMIN
[0x0839] = 0x01000000;
1228 pNv
->PRAMIN
[0x0000] = 0x80000010;
1229 pNv
->PRAMIN
[0x0001] = 0x80011201;
1230 pNv
->PRAMIN
[0x0002] = 0x80000011;
1231 pNv
->PRAMIN
[0x0003] = 0x80011202;
1232 pNv
->PRAMIN
[0x0004] = 0x80000012;
1233 pNv
->PRAMIN
[0x0005] = 0x80011203;
1234 pNv
->PRAMIN
[0x0006] = 0x80000013;
1235 pNv
->PRAMIN
[0x0007] = 0x80011204;
1236 pNv
->PRAMIN
[0x0008] = 0x80000014;
1237 pNv
->PRAMIN
[0x0009] = 0x80011205;
1238 pNv
->PRAMIN
[0x000A] = 0x80000015;
1239 pNv
->PRAMIN
[0x000B] = 0x80011206;
1240 pNv
->PRAMIN
[0x000C] = 0x80000016;
1241 pNv
->PRAMIN
[0x000D] = 0x80011207;
1242 pNv
->PRAMIN
[0x000E] = 0x80000017;
1243 pNv
->PRAMIN
[0x000F] = 0x80011208;
1244 pNv
->PRAMIN
[0x0800] = 0x00003000;
1245 pNv
->PRAMIN
[0x0801] = pNv
->FrameBufferSize
- 1;
1246 pNv
->PRAMIN
[0x0802] = 0x00000002;
1247 pNv
->PRAMIN
[0x0803] = 0x00000002;
1248 if(pNv
->Architecture
>= NV_ARCH_10
)
1249 pNv
->PRAMIN
[0x0804] = 0x01008062;
1251 pNv
->PRAMIN
[0x0804] = 0x01008042;
1252 pNv
->PRAMIN
[0x0805] = 0x00000000;
1253 pNv
->PRAMIN
[0x0806] = 0x12001200;
1254 pNv
->PRAMIN
[0x0807] = 0x00000000;
1255 pNv
->PRAMIN
[0x0808] = 0x01008043;
1256 pNv
->PRAMIN
[0x0809] = 0x00000000;
1257 pNv
->PRAMIN
[0x080A] = 0x00000000;
1258 pNv
->PRAMIN
[0x080B] = 0x00000000;
1259 pNv
->PRAMIN
[0x080C] = 0x01008044;
1260 pNv
->PRAMIN
[0x080D] = 0x00000002;
1261 pNv
->PRAMIN
[0x080E] = 0x00000000;
1262 pNv
->PRAMIN
[0x080F] = 0x00000000;
1263 pNv
->PRAMIN
[0x0810] = 0x01008019;
1264 pNv
->PRAMIN
[0x0811] = 0x00000000;
1265 pNv
->PRAMIN
[0x0812] = 0x00000000;
1266 pNv
->PRAMIN
[0x0813] = 0x00000000;
1267 pNv
->PRAMIN
[0x0814] = 0x0100A05C;
1268 pNv
->PRAMIN
[0x0815] = 0x00000000;
1269 pNv
->PRAMIN
[0x0816] = 0x00000000;
1270 pNv
->PRAMIN
[0x0817] = 0x00000000;
1271 // aros: commented out for now
1272 // if(pNv->WaitVSyncPossible)
1273 // pNv->PRAMIN[0x0818] = 0x0100809F;
1275 pNv
->PRAMIN
[0x0818] = 0x0100805F;
1276 pNv
->PRAMIN
[0x0819] = 0x00000000;
1277 pNv
->PRAMIN
[0x081A] = 0x12001200;
1278 pNv
->PRAMIN
[0x081B] = 0x00000000;
1279 pNv
->PRAMIN
[0x081C] = 0x0100804A;
1280 pNv
->PRAMIN
[0x081D] = 0x00000002;
1281 pNv
->PRAMIN
[0x081E] = 0x00000000;
1282 pNv
->PRAMIN
[0x081F] = 0x00000000;
1283 pNv
->PRAMIN
[0x0820] = 0x01018077;
1284 pNv
->PRAMIN
[0x0821] = 0x00000000;
1285 pNv
->PRAMIN
[0x0822] = 0x12001200;
1286 pNv
->PRAMIN
[0x0823] = 0x00000000;
1287 pNv
->PRAMIN
[0x0824] = 0x00003002;
1288 pNv
->PRAMIN
[0x0825] = 0x00007FFF;
1289 pNv
->PRAMIN
[0x0826] = pNv
->FbUsableSize
| 0x00000002;
1290 pNv
->PRAMIN
[0x0827] = 0x00000002;
1293 pNv
->PRAMIN
[0x0804] |= 0x00080000;
1294 pNv
->PRAMIN
[0x0808] |= 0x00080000;
1295 pNv
->PRAMIN
[0x080C] |= 0x00080000;
1296 pNv
->PRAMIN
[0x0810] |= 0x00080000;
1297 pNv
->PRAMIN
[0x0814] |= 0x00080000;
1298 pNv
->PRAMIN
[0x0818] |= 0x00080000;
1299 pNv
->PRAMIN
[0x081C] |= 0x00080000;
1300 pNv
->PRAMIN
[0x0820] |= 0x00080000;
1302 pNv
->PRAMIN
[0x080D] = 0x00000001;
1303 pNv
->PRAMIN
[0x081D] = 0x00000001;
1307 if(pNv
->Architecture
< NV_ARCH_10
) {
1308 if((pNv
->Chipset
& 0x0fff) == 0x0020) {
1309 pNv
->PRAMIN
[0x0824] |= 0x00020000;
1310 pNv
->PRAMIN
[0x0826] += (IPTR
)pNv
->FbAddress
;
1312 pNv
->PGRAPH
[0x0080/4] = 0x000001FF;
1313 pNv
->PGRAPH
[0x0080/4] = 0x1230C000;
1314 pNv
->PGRAPH
[0x0084/4] = 0x72111101;
1315 pNv
->PGRAPH
[0x0088/4] = 0x11D5F071;
1316 pNv
->PGRAPH
[0x008C/4] = 0x0004FF31; /* stegerg: strange but that's so in xfree nv driver sources */
1317 pNv
->PGRAPH
[0x008C/4] = 0x4004FF31; /* stegerg: strange but that's so in xfree nv driver sources */
1319 pNv
->PGRAPH
[0x0140/4] = 0x00000000;
1320 pNv
->PGRAPH
[0x0100/4] = 0xFFFFFFFF;
1321 pNv
->PGRAPH
[0x0170/4] = 0x10010100;
1322 pNv
->PGRAPH
[0x0710/4] = 0xFFFFFFFF;
1323 pNv
->PGRAPH
[0x0720/4] = 0x00000001;
1325 pNv
->PGRAPH
[0x0810/4] = 0x00000000;
1326 pNv
->PGRAPH
[0x0608/4] = 0xFFFFFFFF;
1328 pNv
->PGRAPH
[0x0080/4] = 0xFFFFFFFF;
1329 pNv
->PGRAPH
[0x0080/4] = 0x00000000;
1331 pNv
->PGRAPH
[0x0140/4] = 0x00000000;
1332 pNv
->PGRAPH
[0x0100/4] = 0xFFFFFFFF;
1333 pNv
->PGRAPH
[0x0144/4] = 0x10010100;
1334 pNv
->PGRAPH
[0x0714/4] = 0xFFFFFFFF;
1335 pNv
->PGRAPH
[0x0720/4] = 0x00000001;
1336 pNv
->PGRAPH
[0x0710/4] &= 0x0007ff00;
1337 pNv
->PGRAPH
[0x0710/4] |= 0x00020100;
1339 if(pNv
->Architecture
== NV_ARCH_10
) {
1340 pNv
->PGRAPH
[0x0084/4] = 0x00118700;
1341 pNv
->PGRAPH
[0x0088/4] = 0x24E00810;
1342 pNv
->PGRAPH
[0x008C/4] = 0x55DE0030;
1344 for(i
= 0; i
< 32; i
++)
1345 pNv
->PGRAPH
[(0x0B00/4) + i
] = pNv
->PFB
[(0x0240/4) + i
];
1347 pNv
->PGRAPH
[0x640/4] = 0;
1348 pNv
->PGRAPH
[0x644/4] = 0;
1349 pNv
->PGRAPH
[0x684/4] = pNv
->FrameBufferSize
- 1;
1350 pNv
->PGRAPH
[0x688/4] = pNv
->FrameBufferSize
- 1;
1352 pNv
->PGRAPH
[0x0810/4] = 0x00000000;
1353 pNv
->PGRAPH
[0x0608/4] = 0xFFFFFFFF;
1355 if(pNv
->Architecture
>= NV_ARCH_40
) {
1356 pNv
->PGRAPH
[0x0084/4] = 0x401287c0;
1357 pNv
->PGRAPH
[0x008C/4] = 0x60de8051;
1358 pNv
->PGRAPH
[0x0090/4] = 0x00008000;
1359 pNv
->PGRAPH
[0x0610/4] = 0x00be3c5f;
1361 if((pNv
->Chipset
& 0xfff0) == 0x0040) {
1362 pNv
->PGRAPH
[0x09b0/4] = 0x83280fff;
1363 pNv
->PGRAPH
[0x09b4/4] = 0x000000a0;
1365 pNv
->PGRAPH
[0x0820/4] = 0x83280eff;
1366 pNv
->PGRAPH
[0x0824/4] = 0x000000a0;
1369 switch(pNv
->Chipset
& 0xfff0) {
1371 pNv
->PGRAPH
[0x09b8/4] = 0x0078e366;
1372 pNv
->PGRAPH
[0x09bc/4] = 0x0000014c;
1373 pNv
->PFB
[0x033C/4] &= 0xffff7fff;
1376 pNv
->PGRAPH
[0x0828/4] = 0x007596ff;
1377 pNv
->PGRAPH
[0x082C/4] = 0x00000108;
1380 pNv
->PMC
[0x1700/4] = pNv
->PFB
[0x020C/4];
1381 pNv
->PMC
[0x1704/4] = 0;
1382 pNv
->PMC
[0x1708/4] = 0;
1383 pNv
->PMC
[0x170C/4] = pNv
->PFB
[0x020C/4];
1384 pNv
->PGRAPH
[0x0860/4] = 0;
1385 pNv
->PGRAPH
[0x0864/4] = 0;
1386 pNv
->PRAMDAC
[0x0608/4] |= 0x00100000;
1389 pNv
->PGRAPH
[0x0828/4] = 0x0072cb77;
1390 pNv
->PGRAPH
[0x082C/4] = 0x00000108;
1396 pNv
->PGRAPH
[0x0b38/4] = 0x2ffff800;
1397 pNv
->PGRAPH
[0x0b3c/4] = 0x00006000;
1398 pNv
->PGRAPH
[0x032C/4] = 0x01000000;
1399 pNv
->PGRAPH
[0x0220/4] = 0x00001200;
1401 if(pNv
->Architecture
== NV_ARCH_30
) {
1402 pNv
->PGRAPH
[0x0084/4] = 0x40108700;
1403 pNv
->PGRAPH
[0x0890/4] = 0x00140000;
1404 pNv
->PGRAPH
[0x008C/4] = 0xf00e0431;
1405 pNv
->PGRAPH
[0x0090/4] = 0x00008000;
1406 pNv
->PGRAPH
[0x0610/4] = 0xf04b1f36;
1407 pNv
->PGRAPH
[0x0B80/4] = 0x1002d888;
1408 pNv
->PGRAPH
[0x0B88/4] = 0x62ff007f;
1410 pNv
->PGRAPH
[0x0084/4] = 0x00118700;
1411 pNv
->PGRAPH
[0x008C/4] = 0xF20E0431;
1412 pNv
->PGRAPH
[0x0090/4] = 0x00000000;
1413 pNv
->PGRAPH
[0x009C/4] = 0x00000040;
1415 if((pNv
->Chipset
& 0x0ff0) >= 0x0250) {
1416 pNv
->PGRAPH
[0x0890/4] = 0x00080000;
1417 pNv
->PGRAPH
[0x0610/4] = 0x304B1FB6;
1418 pNv
->PGRAPH
[0x0B80/4] = 0x18B82880;
1419 pNv
->PGRAPH
[0x0B84/4] = 0x44000000;
1420 pNv
->PGRAPH
[0x0098/4] = 0x40000080;
1421 pNv
->PGRAPH
[0x0B88/4] = 0x000000ff;
1423 pNv
->PGRAPH
[0x0880/4] = 0x00080000;
1424 pNv
->PGRAPH
[0x0094/4] = 0x00000005;
1425 pNv
->PGRAPH
[0x0B80/4] = 0x45CAA208;
1426 pNv
->PGRAPH
[0x0B84/4] = 0x24000000;
1427 pNv
->PGRAPH
[0x0098/4] = 0x00000040;
1428 pNv
->PGRAPH
[0x0750/4] = 0x00E00038;
1429 pNv
->PGRAPH
[0x0754/4] = 0x00000030;
1430 pNv
->PGRAPH
[0x0750/4] = 0x00E10038;
1431 pNv
->PGRAPH
[0x0754/4] = 0x00000030;
1435 for(i
= 0; i
< 32; i
++)
1436 pNv
->PGRAPH
[(0x0900/4) + i
] = pNv
->PFB
[(0x0240/4) + i
];
1438 if(pNv
->Architecture
>= NV_ARCH_40
) {
1439 if((pNv
->Chipset
& 0xfff0) == 0x0040) {
1440 pNv
->PGRAPH
[0x09A4/4] = pNv
->PFB
[0x0200/4];
1441 pNv
->PGRAPH
[0x09A8/4] = pNv
->PFB
[0x0204/4];
1442 pNv
->PGRAPH
[0x69A4/4] = pNv
->PFB
[0x0200/4];
1443 pNv
->PGRAPH
[0x69A8/4] = pNv
->PFB
[0x0204/4];
1445 pNv
->PGRAPH
[0x0820/4] = 0;
1446 pNv
->PGRAPH
[0x0824/4] = 0;
1447 pNv
->PGRAPH
[0x0864/4] = pNv
->FrameBufferSize
- 1;
1448 pNv
->PGRAPH
[0x0868/4] = pNv
->FrameBufferSize
- 1;
1450 pNv
->PGRAPH
[0x09F0/4] = pNv
->PFB
[0x0200/4];
1451 pNv
->PGRAPH
[0x09F4/4] = pNv
->PFB
[0x0204/4];
1452 pNv
->PGRAPH
[0x69F0/4] = pNv
->PFB
[0x0200/4];
1453 pNv
->PGRAPH
[0x69F4/4] = pNv
->PFB
[0x0204/4];
1455 pNv
->PGRAPH
[0x0840/4] = 0;
1456 pNv
->PGRAPH
[0x0844/4] = 0;
1457 pNv
->PGRAPH
[0x08a0/4] = pNv
->FrameBufferSize
- 1;
1458 pNv
->PGRAPH
[0x08a4/4] = pNv
->FrameBufferSize
- 1;
1461 pNv
->PGRAPH
[0x09A4/4] = pNv
->PFB
[0x0200/4];
1462 pNv
->PGRAPH
[0x09A8/4] = pNv
->PFB
[0x0204/4];
1463 pNv
->PGRAPH
[0x0750/4] = 0x00EA0000;
1464 pNv
->PGRAPH
[0x0754/4] = pNv
->PFB
[0x0200/4];
1465 pNv
->PGRAPH
[0x0750/4] = 0x00EA0004;
1466 pNv
->PGRAPH
[0x0754/4] = pNv
->PFB
[0x0204/4];
1468 pNv
->PGRAPH
[0x0820/4] = 0;
1469 pNv
->PGRAPH
[0x0824/4] = 0;
1470 pNv
->PGRAPH
[0x0864/4] = pNv
->FrameBufferSize
- 1;
1471 pNv
->PGRAPH
[0x0868/4] = pNv
->FrameBufferSize
- 1;
1474 pNv
->PGRAPH
[0x0B20/4] = 0x00000000;
1475 pNv
->PGRAPH
[0x0B04/4] = 0xFFFFFFFF;
1478 pNv
->PGRAPH
[0x053C/4] = 0;
1479 pNv
->PGRAPH
[0x0540/4] = 0;
1480 pNv
->PGRAPH
[0x0544/4] = 0x00007FFF;
1481 pNv
->PGRAPH
[0x0548/4] = 0x00007FFF;
1483 pNv
->PFIFO
[0x0140] = 0x00000000;
1484 pNv
->PFIFO
[0x0141] = 0x00000001;
1485 pNv
->PFIFO
[0x0480] = 0x00000000;
1486 pNv
->PFIFO
[0x0494] = 0x00000000;
1487 if(pNv
->Architecture
>= NV_ARCH_40
)
1488 pNv
->PFIFO
[0x0481] = 0x00010000;
1490 pNv
->PFIFO
[0x0481] = 0x00000100;
1491 pNv
->PFIFO
[0x0490] = 0x00000000;
1492 pNv
->PFIFO
[0x0491] = 0x00000000;
1493 if(pNv
->Architecture
>= NV_ARCH_40
)
1494 pNv
->PFIFO
[0x048B] = 0x00001213;
1496 pNv
->PFIFO
[0x048B] = 0x00001209;
1497 pNv
->PFIFO
[0x0400] = 0x00000000;
1498 pNv
->PFIFO
[0x0414] = 0x00000000;
1499 pNv
->PFIFO
[0x0084] = 0x03000100;
1500 pNv
->PFIFO
[0x0085] = 0x00000110;
1501 pNv
->PFIFO
[0x0086] = 0x00000112;
1502 pNv
->PFIFO
[0x0143] = 0x0000FFFF;
1503 pNv
->PFIFO
[0x0496] = 0x0000FFFF;
1504 pNv
->PFIFO
[0x0050] = 0x00000000;
1505 pNv
->PFIFO
[0x0040] = 0xFFFFFFFF;
1506 pNv
->PFIFO
[0x0415] = 0x00000001;
1507 pNv
->PFIFO
[0x048C] = 0x00000000;
1508 pNv
->PFIFO
[0x04A0] = 0x00000000;
1510 pNv
->PFIFO
[0x0489] = 0x800F0078;
1512 pNv
->PFIFO
[0x0489] = 0x000F0078;
1514 pNv
->PFIFO
[0x0488] = 0x00000001;
1515 pNv
->PFIFO
[0x0480] = 0x00000001;
1516 pNv
->PFIFO
[0x0494] = 0x00000001;
1517 pNv
->PFIFO
[0x0495] = 0x00000001;
1518 pNv
->PFIFO
[0x0140] = 0x00000001;
1520 if(pNv
->Architecture
>= NV_ARCH_10
) {
1522 pNv
->PCRTC0
[0x0860/4] = state
->head
;
1523 pNv
->PCRTC0
[0x2860/4] = state
->head2
;
1525 pNv
->PRAMDAC
[0x0404/4] |= (1 << 25);
1527 pNv
->PMC
[0x8704/4] = 1;
1528 pNv
->PMC
[0x8140/4] = 0;
1529 pNv
->PMC
[0x8920/4] = 0;
1530 pNv
->PMC
[0x8924/4] = 0;
1531 pNv
->PMC
[0x8908/4] = pNv
->FrameBufferSize
- 1;
1532 pNv
->PMC
[0x890C/4] = pNv
->FrameBufferSize
- 1;
1533 pNv
->PMC
[0x1588/4] = 0;
1535 pNv
->PCRTC
[0x0810/4] = state
->cursorConfig
;
1536 pNv
->PCRTC
[0x0830/4] = state
->displayV
- 3;
1537 pNv
->PCRTC
[0x0834/4] = state
->displayV
- 1;
1539 if(pNv
->FlatPanel
) {
1540 if((pNv
->Chipset
& 0x0ff0) == 0x0110) {
1541 pNv
->PRAMDAC
[0x0528/4] = state
->dither
;
1544 pNv
->PRAMDAC
[0x083C/4] = state
->dither
;
1547 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x53);
1548 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->timingH
);
1549 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x54);
1550 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->timingV
);
1551 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x21);
1552 VGA_WR08(pNv
->PCIO
, 0x03D5, 0xfa);
1555 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x41);
1556 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->extra
);
1559 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x19);
1560 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->repaint0
);
1561 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1A);
1562 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->repaint1
);
1563 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x25);
1564 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->screen
);
1565 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x28);
1566 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->pixel
);
1567 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2D);
1568 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->horiz
);
1569 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1C);
1570 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->fifo
);
1571 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1B);
1572 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->arbitration0
);
1573 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x20);
1574 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->arbitration1
);
1575 if(pNv
->Architecture
>= NV_ARCH_30
) {
1576 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x47);
1577 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->arbitration1
>> 8);
1579 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x30);
1580 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->cursor0
);
1581 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x31);
1582 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->cursor1
);
1583 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2F);
1584 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->cursor2
);
1585 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x39);
1586 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->interlace
);
1588 if(!pNv
->FlatPanel
) {
1589 pNv
->PRAMDAC0
[0x050C/4] = state
->pllsel
;
1590 pNv
->PRAMDAC0
[0x0508/4] = state
->vpll
;
1592 pNv
->PRAMDAC0
[0x0520/4] = state
->vpll2
;
1593 if(pNv
->twoStagePLL
) {
1594 pNv
->PRAMDAC0
[0x0578/4] = state
->vpllB
;
1595 pNv
->PRAMDAC0
[0x057C/4] = state
->vpll2B
;
1598 pNv
->PRAMDAC
[0x0848/4] = state
->scale
;
1601 /* begin flat panel hacks */
1602 /* This is unfortunate, but some chips need this register
1603 tweaked or else you get artifacts where adjacent pixels are
1604 swapped. There are no hard rules for what to set here so all
1605 we can do is experiment and apply hacks. */
1607 if(((pNv
->Chipset
& 0xffff) == 0x0328) && (state
->bpp
== 32)) {
1608 /* At least one NV34 laptop needs this workaround. */
1609 pNv
->PRAMDAC
[0x0828/4] &= ~1;
1612 if((pNv
->Chipset
& 0xfff0) == 0x0310) {
1613 pNv
->PRAMDAC
[0x0828/4] |= 1;
1616 /* end flat panel hacks */
1618 pNv
->PRAMDAC
[0x0600/4] = state
->general
;
1620 pNv
->PCRTC
[0x0140/4] = 0;
1621 pNv
->PCRTC
[0x0100/4] = 1;
1623 pNv
->CurrentState
= state
;
1627 ** stegerg: Status NVUnloadStateExt(): should "match" xfree nv NVUnloadStateExt()
1628 ** in xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c version:
1629 ** 1.12 2004/11/30 23:50:26 mvojkovi
1632 void NVUnloadStateExt
1635 RIVA_HW_STATE
*state
1638 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x19);
1639 state
->repaint0
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1640 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1A);
1641 state
->repaint1
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1642 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x25);
1643 state
->screen
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1644 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x28);
1645 state
->pixel
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1646 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2D);
1647 state
->horiz
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1648 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1C);
1649 state
->fifo
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1650 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1B);
1651 state
->arbitration0
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1652 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x20);
1653 state
->arbitration1
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1654 if(pNv
->Architecture
>= NV_ARCH_30
) {
1655 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x47);
1656 state
->arbitration1
|= (VGA_RD08(pNv
->PCIO
, 0x03D5) & 1) << 8;
1658 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x30);
1659 state
->cursor0
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1660 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x31);
1661 state
->cursor1
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1662 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2F);
1663 state
->cursor2
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1664 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x39);
1665 state
->interlace
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1666 state
->vpll
= pNv
->PRAMDAC0
[0x0508/4];
1668 state
->vpll2
= pNv
->PRAMDAC0
[0x0520/4];
1669 if(pNv
->twoStagePLL
) {
1670 state
->vpllB
= pNv
->PRAMDAC0
[0x0578/4];
1671 state
->vpll2B
= pNv
->PRAMDAC0
[0x057C/4];
1673 state
->pllsel
= pNv
->PRAMDAC0
[0x050C/4];
1674 state
->general
= pNv
->PRAMDAC
[0x0600/4];
1675 state
->scale
= pNv
->PRAMDAC
[0x0848/4];
1676 state
->config
= pNv
->PFB
[0x0200/4];
1678 if(pNv
->Architecture
>= NV_ARCH_10
) {
1680 state
->head
= pNv
->PCRTC0
[0x0860/4];
1681 state
->head2
= pNv
->PCRTC0
[0x2860/4];
1682 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x44);
1683 state
->crtcOwner
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1685 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x41);
1686 state
->extra
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1687 state
->cursorConfig
= pNv
->PCRTC
[0x0810/4];
1689 if((pNv
->Chipset
& 0x0ff0) == 0x0110) {
1690 state
->dither
= pNv
->PRAMDAC
[0x0528/4];
1693 state
->dither
= pNv
->PRAMDAC
[0x083C/4];
1696 if(pNv
->FlatPanel
) {
1697 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x53);
1698 state
->timingH
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1699 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x54);
1700 state
->timingV
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1705 void NVSetStartAddress (
1710 pNv
->PCRTC
[0x800/4] = start
;
1719 VGA_WR08(pNv
->PDIO
, 0x3c6, 0xff);
1720 VGA_WR08(pNv
->PDIO
, 0x3c8, 0);
1721 for (i
=0; i
< 768; i
++)
1722 VGA_WR08(pNv
->PDIO
, 0x3c9, pNv
->CurrentState
->Regs
.dac
[i
]);
1725 static void InitBaseRegs(struct staticdata
*sd
, struct CardState
*card
, Sync
*mode
)
1727 /* Determine sync polarity */
1728 if (mode
->VDisplay
< 400)
1729 card
->Regs
.misc
= 0xa3;
1730 else if (mode
->VDisplay
< 480)
1731 card
->Regs
.misc
= 0x63;
1732 else if (mode
->VDisplay
< 768)
1733 card
->Regs
.misc
= 0xe3;
1735 card
->Regs
.misc
= 0x23;
1737 card
->Regs
.seq
[0] = 0x03;
1738 card
->Regs
.seq
[1] = 0x01;
1739 card
->Regs
.seq
[2] = 0x0f;
1740 card
->Regs
.seq
[3] = 0x00;
1741 card
->Regs
.seq
[4] = 0x0e;
1743 card
->Regs
.crtc
[8] = 0;
1744 card
->Regs
.crtc
[10] = 0; //0x20;
1745 card
->Regs
.crtc
[14] = 0;
1746 card
->Regs
.crtc
[17] = (mode
->VSyncEnd
& 0x0f) | 0x20;
1747 card
->Regs
.crtc
[18] = (mode
->VDisplay
- 1) & 0xff;
1748 card
->Regs
.crtc
[19] = card
->width
>> 4;
1749 card
->Regs
.crtc
[20] = 0;
1750 card
->Regs
.crtc
[21] = (mode
->VSyncStart
- 1) & 0xff;
1751 card
->Regs
.crtc
[22] = (mode
->VSyncEnd
- 1) & 0xff;
1752 card
->Regs
.crtc
[23] = 0xc3; // 0xc3
1753 card
->Regs
.crtc
[24] = 0xff;
1754 card
->Regs
.crtc
[40] = 0x40;
1756 card
->Regs
.gra
[0] = 0x00;
1757 card
->Regs
.gra
[1] = 0x00;
1758 card
->Regs
.gra
[2] = 0x00;
1759 card
->Regs
.gra
[3] = 0x00;
1760 card
->Regs
.gra
[4] = 0x00;
1761 card
->Regs
.gra
[5] = 0x40;
1762 card
->Regs
.gra
[6] = 0x05;
1763 card
->Regs
.gra
[7] = 0x0f;
1764 card
->Regs
.gra
[8] = 0xff;
1766 card
->Regs
.attr
[0] = 0x00;
1767 card
->Regs
.attr
[1] = 0x01;
1768 card
->Regs
.attr
[2] = 0x02;
1769 card
->Regs
.attr
[3] = 0x03;
1770 card
->Regs
.attr
[4] = 0x04;
1771 card
->Regs
.attr
[5] = 0x05;
1772 card
->Regs
.attr
[6] = 0x06;
1773 card
->Regs
.attr
[7] = 0x07;
1774 card
->Regs
.attr
[8] = 0x08;
1775 card
->Regs
.attr
[9] = 0x09;
1776 card
->Regs
.attr
[10] = 0x0a;
1777 card
->Regs
.attr
[11] = 0x0b;
1778 card
->Regs
.attr
[12] = 0x0c;
1779 card
->Regs
.attr
[13] = 0x0d;
1780 card
->Regs
.attr
[14] = 0x0e;
1781 card
->Regs
.attr
[15] = 0x0f;
1782 card
->Regs
.attr
[16] = 0x41;
1783 card
->Regs
.attr
[17] = 0x01;
1784 card
->Regs
.attr
[18] = 0x0f;
1785 card
->Regs
.attr
[19] = 0x00;
1786 card
->Regs
.attr
[20] = 0x00;
1789 #define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b))
1790 #define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
1791 #define SetBF(mask,value) ((value) << (0?mask))
1792 #define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
1793 #define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
1794 #define SetBit(n) (1<<(n))
1795 #define Set8Bits(value) ((value)&0xff)
1797 void InitMode(struct staticdata
*sd
, struct CardState
*state
,
1798 ULONG width
, ULONG height
, UBYTE bpp
, ULONG pixelc
, ULONG base
,
1799 ULONG HDisplay
, ULONG VDisplay
,
1800 ULONG HSyncStart
, ULONG HSyncEnd
, ULONG HTotal
,
1801 ULONG VSyncStart
, ULONG VSyncEnd
, ULONG VTotal
)
1803 D(bug("[NVidia] Init %dx%dx%d @%x mode\n", width
, height
, bpp
, base
));
1805 ULONG HBlankStart
, HBlankEnd
, VBlankStart
, VBlankEnd
, OrgHDisplay
= HDisplay
;
1809 HDisplay
, HSyncStart
, HSyncEnd
, HTotal
,
1810 VDisplay
, VSyncStart
, VSyncEnd
, VTotal
1813 InitBaseRegs(sd
, state
, &mode
);
1815 HDisplay
= (HDisplay
>> 3) - 1;
1816 HSyncStart
= (HSyncStart
>> 3) - 1;
1817 HSyncEnd
= (HSyncEnd
>> 3) - 1;
1818 HTotal
= (HTotal
>> 3) - 5;
1819 HBlankStart
= HDisplay
;
1820 HBlankEnd
= HTotal
+ 4;
1826 VBlankStart
= VDisplay
;
1827 VBlankEnd
= VTotal
+ 1;
1830 state
->bitsPerPixel
= 8;
1832 state
->bitsPerPixel
= 16;
1834 state
->bitsPerPixel
= 32;
1836 if (sd
->Card
.FlatPanel
)
1838 VSyncStart
= VTotal
- 3;
1839 VSyncEnd
= VTotal
- 2;
1840 VBlankStart
= VSyncStart
;
1841 HSyncStart
= HTotal
- 5;
1842 HSyncEnd
= HTotal
- 2;
1843 HBlankEnd
= HTotal
+ 4;
1846 state
->Regs
.crtc
[0x00] = Set8Bits(HTotal
);
1847 state
->Regs
.crtc
[0x01] = Set8Bits(HDisplay
);
1848 state
->Regs
.crtc
[0x02] = Set8Bits(HBlankStart
);
1849 state
->Regs
.crtc
[0x03] = SetBitField(HBlankEnd
, 4:0, 4:0) | SetBit(7);
1850 state
->Regs
.crtc
[0x04] = Set8Bits(HSyncStart
);
1851 state
->Regs
.crtc
[0x05] = SetBitField(HBlankEnd
, 5:5, 7:7) |
1852 SetBitField(HSyncEnd
, 4:0, 4:0);
1853 state
->Regs
.crtc
[0x06] = SetBitField(VTotal
, 7:0, 7:0);
1854 state
->Regs
.crtc
[0x07] = SetBitField(VTotal
, 8:8, 0:0) |
1855 SetBitField(VDisplay
, 8:8, 1:1) |
1856 SetBitField(VSyncStart
, 8:8, 2:2) |
1857 SetBitField(VBlankStart
, 8:8, 3:3) |
1859 SetBitField(VTotal
, 9:9, 5:5) |
1860 SetBitField(VDisplay
, 9:9, 6:6) |
1861 SetBitField(VSyncStart
, 9:9, 7:7);
1862 state
->Regs
.crtc
[0x09] = SetBitField(VBlankStart
, 9:9, 5:5) | SetBit(6); // V_DOUBLESCAN?
1863 state
->Regs
.crtc
[0x10] = Set8Bits(VSyncStart
);
1864 state
->Regs
.crtc
[0x11] = SetBitField(VSyncEnd
, 3:0, 3:0) | SetBit(5);
1865 state
->Regs
.crtc
[0x12] = Set8Bits(VDisplay
);
1866 state
->Regs
.crtc
[0x13] = ((width
/ 8) * (state
->bitsPerPixel
/ 8));
1867 state
->Regs
.crtc
[0x15] = Set8Bits(VBlankStart
);
1868 state
->Regs
.crtc
[0x16] = Set8Bits(VBlankEnd
);
1870 state
->Regs
.attr
[0x10] = 0x01;
1873 SetBitField(HBlankEnd
, 6:6, 4:4) |
1874 SetBitField(VBlankStart
, 10:10, 3:3) |
1875 SetBitField(VSyncStart
, 10:10, 2:2) |
1876 SetBitField(VDisplay
, 10:10, 1:1) |
1877 SetBitField(VTotal
, 10:10, 0:0);
1880 SetBitField(HTotal
, 8:8, 0:0) |
1881 SetBitField(HDisplay
, 8:8, 1:1) |
1882 SetBitField(HBlankStart
, 8:8, 2:2) |
1883 SetBitField(HSyncStart
, 8:8, 3:3);
1886 SetBitField(VTotal
, 11:11, 0:0) |
1887 SetBitField(VDisplay
, 11:11, 2:2) |
1888 SetBitField(VSyncStart
, 11:11, 4:4) |
1889 SetBitField(VBlankStart
, 11:11, 6:6);
1891 state
->interlace
= 0xff;
1893 if (bpp
>= 24) bpp
= 32;
1895 if (sd
->Card
.Architecture
>= NV_ARCH_10
)
1896 sd
->Card
.CURSOR
= (ULONG
*)(sd
->Card
.FrameBuffer
+ sd
->Card
.CursorStart
);
1898 // NVLockUnlock(sd, 0);
1899 NVCalcStateExt(sd
, &sd
->Card
, state
, bpp
, width
, OrgHDisplay
, height
, pixelc
, 0);
1901 state
->scale
= sd
->Card
.PRAMDAC
[0x0848/4] & 0xfff000ff;
1902 if (sd
->Card
.FlatPanel
)
1904 state
->pixel
|= (1 << 7);
1905 if (!sd
->Card
.fpScaler
|| (sd
->Card
.fpWidth
<= mode
.HDisplay
)
1906 || (sd
->Card
.fpHeight
<= mode
.VDisplay
))
1908 state
->scale
|= (1 << 8);
1913 state
->cursorConfig
= 0x00000100;
1914 if (sd
->Card
.alphaCursor
)
1916 state
->cursorConfig
|= 0x04011000;
1917 state
->general
|= (1 << 29);
1919 if((sd
->Card
.Chipset
& 0x0ff0) == 0x0110) {
1920 state
->dither
= sd
->Card
.PRAMDAC
[0x0528/4] & ~0x00010000;
1921 if(0) //sd->Card.FPDither)
1922 state
->dither
|= 0x00010000;
1924 state
->cursorConfig
|= (1 << 28);
1926 if((sd
->Card
.Chipset
& 0x0ff0) >= 0x0170) {
1927 state
->dither
= sd
->Card
.PRAMDAC
[0x083C/4] & ~1;
1928 state
->cursorConfig
|= (1 << 28);
1929 if(0) //pNv->FPDither)
1932 state
->cursorConfig
|= (1 << 28);
1935 state
->cursorConfig
|= 0x02000000;
1942 for (i
=0; i
<256; i
++)
1944 state
->Regs
.dac
[i
*3+0] = i
;
1945 state
->Regs
.dac
[i
*3+1] = i
;
1946 state
->Regs
.dac
[i
*3+2] = i
;
1950 state
->offset
= base
;
1951 state
->vpll
= state
->pll
;
1952 state
->vpll2
= state
->pll
;
1953 state
->vpllB
= state
->pllB
;
1954 state
->vpll2B
= state
->pllB
;
1956 VGA_WR08(sd
->Card
.PCIO
, 0x03D4, 0x1C);
1957 state
->fifo
= VGA_RD08(sd
->Card
.PCIO
, 0x03D5) & ~(1<<5);
1959 if(sd
->Card
.CRTCnumber
) {
1960 state
->head
= sd
->Card
.PCRTC0
[0x00000860/4] & ~0x00001000;
1961 state
->head2
= sd
->Card
.PCRTC0
[0x00002860/4] | 0x00001000;
1962 state
->crtcOwner
= 3;
1963 state
->pllsel
|= 0x20000800;
1964 state
->vpll
= sd
->Card
.PRAMDAC0
[0x0508/4];
1965 if(sd
->Card
.twoStagePLL
)
1966 state
->vpllB
= sd
->Card
.PRAMDAC0
[0x0578/4];
1968 if(sd
->Card
.twoHeads
) {
1969 state
->head
= sd
->Card
.PCRTC0
[0x00000860/4] | 0x00001000;
1970 state
->head2
= sd
->Card
.PCRTC0
[0x00002860/4] & ~0x00001000;
1971 state
->crtcOwner
= 0;
1972 state
->vpll2
= sd
->Card
.PRAMDAC0
[0x0520/4];
1973 if(sd
->Card
.twoStagePLL
)
1974 state
->vpll2B
= sd
->Card
.PRAMDAC0
[0x057C/4];
1979 state
->displayV
= VDisplay
;
1982 void acc_reset(struct staticdata
*);
1984 void LoadState(struct staticdata
*sd
, struct CardState
*state
)
1988 ObtainSemaphore(&sd
->HWLock
);
1990 // CRTC_out(sd, 0x11, 0x00);
1992 NVLockUnlock(sd
, 0);
1993 NVLoadStateExt(&sd
->Card
, state
);
1995 MISC_out(sd
, sd
->Card
.CurrentState
->Regs
.misc
);
1997 for (i
=0; i
< 0x05; i
++)
1999 SEQ_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.seq
[i
]);
2002 CRTC_out(sd
, 17, sd
->Card
.CurrentState
->Regs
.crtc
[17] & ~0x80);
2003 for (i
=0; i
< 0x41; i
++)
2011 CRTC_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.crtc
[i
]);
2016 for (i
=0; i
< 0x15; i
++)
2017 ATTR_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.attr
[i
]);
2019 for (i
=0; i
< 0x09; i
++)
2020 GRA_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.gra
[i
]);
2022 NVSetStartAddress(&sd
->Card
, sd
->Card
.CurrentState
->offset
);
2024 sd
->Card
.currentROP
= 0xffffffff;
2025 // VGA_WR08(sd->Card.PVIO, 0x3c3, 1);
2027 NVLoadDAC(&sd
->Card
);
2030 ReleaseSemaphore(&sd
->HWLock
);
2033 void DPMS(struct staticdata
*sd
, HIDDT_DPMSLevel state
)
2037 ObtainSemaphore(&sd
->HWLock
);
2040 reg
= CRTC_in(sd
, 0x1a) & ~0xc0;
2044 case vHidd_Gfx_DPMSLevel_Standby
:
2047 case vHidd_Gfx_DPMSLevel_Suspend
:
2050 case vHidd_Gfx_DPMSLevel_Off
:
2057 CRTC_out(sd
, 0x1a, reg
);
2059 ReleaseSemaphore(&sd
->HWLock
);
2062 void Protect(struct staticdata
*sd
, UBYTE protect
)
2064 ObtainSemaphore(&sd
->HWLock
);
2068 UBYTE tmp
= SEQ_in(sd
, 1);
2070 SEQ_out(sd
, 1, tmp
| 0x20);
2074 UBYTE tmp
= SEQ_in(sd
, 1);
2075 SEQ_out(sd
, 1, tmp
& ~0x20);
2079 ReleaseSemaphore(&sd
->HWLock
);
2082 static const UBYTE ROPTable
[] = {
2083 [vHidd_GC_DrawMode_Clear
] = 0x00,
2084 [vHidd_GC_DrawMode_And
] = 0x88,
2085 [vHidd_GC_DrawMode_AndReverse
] = 0x44,
2086 [vHidd_GC_DrawMode_Copy
] = 0xcc,
2087 [vHidd_GC_DrawMode_AndInverted
] = 0x22,
2088 [vHidd_GC_DrawMode_NoOp
] = 0xaa,
2089 [vHidd_GC_DrawMode_Xor
] = 0x66,
2090 [vHidd_GC_DrawMode_Or
] = 0xee,
2091 [vHidd_GC_DrawMode_Nor
] = 0x11,
2092 [vHidd_GC_DrawMode_Equiv
] = 0x99,
2093 [vHidd_GC_DrawMode_Invert
] = 0x55,
2094 [vHidd_GC_DrawMode_OrReverse
] = 0xdd,
2095 [vHidd_GC_DrawMode_CopyInverted
]= 0x33,
2096 [vHidd_GC_DrawMode_OrInverted
] = 0xbb,
2097 [vHidd_GC_DrawMode_Nand
] = 0x77,
2098 [vHidd_GC_DrawMode_Set
] = 0xff,
2101 void NVDmaKickoff(struct Card
*pNv
)
2103 if(pNv
->dmaCurrent
!= pNv
->dmaPut
) {
2104 pNv
->dmaPut
= pNv
->dmaCurrent
;
2105 WRITE_PUT(pNv
, pNv
->dmaPut
);
2109 /* There is a HW race condition with videoram command buffers.
2110 You can't jump to the location of your put offset. We write put
2111 at the jump offset + SKIPS dwords with noop padding in between
2112 to solve this problem */
2124 while(pNv
->dmaFree
< size
) {
2125 dmaGet
= READ_GET(pNv
);
2127 if(pNv
->dmaPut
>= dmaGet
) {
2128 pNv
->dmaFree
= pNv
->dmaMax
- pNv
->dmaCurrent
;
2129 if(pNv
->dmaFree
< size
) {
2130 NVDmaNext(pNv
, 0x20000000);
2131 if(dmaGet
<= SKIPS
) {
2132 if(pNv
->dmaPut
<= SKIPS
) /* corner case - will be idle */
2133 WRITE_PUT(pNv
, SKIPS
+ 1);
2134 do { dmaGet
= READ_GET(pNv
); }
2135 while(dmaGet
<= SKIPS
);
2137 WRITE_PUT(pNv
, SKIPS
);
2138 pNv
->dmaCurrent
= pNv
->dmaPut
= SKIPS
;
2139 pNv
->dmaFree
= dmaGet
- (SKIPS
+ 1);
2142 pNv
->dmaFree
= dmaGet
- pNv
->dmaCurrent
- 1;
2147 struct staticdata
*sd
,
2154 struct Card
*pNv
= &sd
->Card
;
2156 NVDmaStart(pNv
, PATTERN_COLOR_0
, 4);
2157 NVDmaNext (pNv
, clr0
);
2158 NVDmaNext (pNv
, clr1
);
2159 NVDmaNext (pNv
, pat0
);
2160 NVDmaNext (pNv
, pat1
);
2163 void NVSetRopSolid(struct staticdata
*sd
, ULONG rop
, ULONG planemask
)
2165 struct Card
*pNv
= &sd
->Card
;
2167 if(planemask
!= ~0) {
2168 NVSetPattern(sd
, 0, planemask
, ~0, ~0);
2169 if(pNv
->currentROP
!= (rop
+ 32)) {
2170 NVDmaStart(pNv
, ROP_SET
, 1);
2171 NVDmaNext (pNv
, ROPTable
[rop
]);
2172 pNv
->currentROP
= rop
+ 32;
2175 if (pNv
->currentROP
!= rop
) {
2176 if(pNv
->currentROP
>= 16)
2177 NVSetPattern(sd
, ~0, ~0, ~0, ~0);
2178 NVDmaStart(pNv
, ROP_SET
, 1);
2179 NVDmaNext (pNv
, ROPTable
[rop
]);
2180 pNv
->currentROP
= rop
;
2184 void acc_reset(struct staticdata
*sd
)
2186 struct Card
*pNv
= &sd
->Card
;
2191 pitch
= pNv
->CurrentState
->width
*
2192 (pNv
->CurrentState
->bitsPerPixel
>> 3);
2194 sd
->src_pitch
= pitch
;
2195 sd
->dst_pitch
= pitch
;
2196 sd
->src_offset
= pNv
->CurrentState
->offset
;
2197 sd
->dst_offset
= pNv
->CurrentState
->offset
;
2199 pNv
->dmaBase
= (ULONG
*)(&pNv
->FrameBuffer
[pNv
->FbUsableSize
]);
2201 for(i
= 0; i
< SKIPS
; i
++)
2202 pNv
->dmaBase
[i
] = 0x00000000;
2204 pNv
->dmaBase
[0x0 + SKIPS
] = 0x00040000;
2205 pNv
->dmaBase
[0x1 + SKIPS
] = 0x80000010;
2206 pNv
->dmaBase
[0x2 + SKIPS
] = 0x00042000;
2207 pNv
->dmaBase
[0x3 + SKIPS
] = 0x80000011;
2208 pNv
->dmaBase
[0x4 + SKIPS
] = 0x00044000;
2209 pNv
->dmaBase
[0x5 + SKIPS
] = 0x80000012;
2210 pNv
->dmaBase
[0x6 + SKIPS
] = 0x00046000;
2211 pNv
->dmaBase
[0x7 + SKIPS
] = 0x80000013;
2212 pNv
->dmaBase
[0x8 + SKIPS
] = 0x00048000;
2213 pNv
->dmaBase
[0x9 + SKIPS
] = 0x80000014;
2214 pNv
->dmaBase
[0xA + SKIPS
] = 0x0004A000;
2215 pNv
->dmaBase
[0xB + SKIPS
] = 0x80000015;
2216 pNv
->dmaBase
[0xC + SKIPS
] = 0x0004C000;
2217 pNv
->dmaBase
[0xD + SKIPS
] = 0x80000016;
2218 pNv
->dmaBase
[0xE + SKIPS
] = 0x0004E000;
2219 pNv
->dmaBase
[0xF + SKIPS
] = 0x80000017;
2222 pNv
->dmaCurrent
= 16 + SKIPS
;
2224 pNv
->dmaFree
= pNv
->dmaMax
- pNv
->dmaCurrent
;
2226 switch(pNv
->CurrentState
->bpp
) {
2229 sd
->surface_format
= SURFACE_FORMAT_DEPTH24
;
2230 sd
->pattern_format
= PATTERN_FORMAT_DEPTH24
;
2231 sd
->rect_format
= RECT_FORMAT_DEPTH24
;
2232 sd
->line_format
= LINE_FORMAT_DEPTH24
;
2236 sd
->surface_format
= SURFACE_FORMAT_DEPTH16
;
2237 sd
->pattern_format
= PATTERN_FORMAT_DEPTH16
;
2238 sd
->rect_format
= RECT_FORMAT_DEPTH16
;
2239 sd
->line_format
= LINE_FORMAT_DEPTH16
;
2242 sd
->surface_format
= SURFACE_FORMAT_DEPTH8
;
2243 sd
->pattern_format
= PATTERN_FORMAT_DEPTH8
;
2244 sd
->rect_format
= RECT_FORMAT_DEPTH8
;
2245 sd
->line_format
= LINE_FORMAT_DEPTH8
;
2249 NVDmaStart(pNv
, SURFACE_FORMAT
, 4);
2250 NVDmaNext (pNv
, sd
->surface_format
);
2251 NVDmaNext (pNv
, sd
->dst_pitch
| (sd
->src_pitch
<< 16));
2252 NVDmaNext (pNv
, sd
->src_offset
);
2253 NVDmaNext (pNv
, sd
->dst_offset
);
2255 NVDmaStart(pNv
, PATTERN_FORMAT
, 1);
2256 NVDmaNext (pNv
, sd
->pattern_format
);
2258 NVDmaStart(pNv
, RECT_FORMAT
, 1);
2259 NVDmaNext (pNv
, sd
->rect_format
);
2261 NVDmaStart(pNv
, LINE_FORMAT
, 1);
2262 NVDmaNext (pNv
, sd
->line_format
);
2264 NVSetRopSolid(sd
, vHidd_GC_DrawMode_Copy
, ~0);
2271 void NVSync(struct staticdata
*sd
)
2273 struct Card
*pNv
= &sd
->Card
;
2275 if(pNv
->DMAKickoffCallback
)
2276 (*pNv
->DMAKickoffCallback
)(sd
);
2278 while(READ_GET(pNv
) != pNv
->dmaPut
);
2280 while(pNv
->PGRAPH
[0x0700/4]);
2282 sd
->gpu_busy
= FALSE
;
2285 void NVDMAKickoffCallback(struct staticdata
*sd
)
2287 struct Card
*pNv
= &sd
->Card
;
2290 pNv
->DMAKickoffCallback
= NULL
;
2293 void NVSelectHead(struct staticdata
*sd
, UBYTE head
)
2297 sd
->Card
.PCIO
= sd
->Card
.PCIO0
+ 0x2000;
2298 sd
->Card
.PCRTC
= sd
->Card
.PCRTC0
+ 0x800;
2299 sd
->Card
.PRAMDAC
= sd
->Card
.PRAMDAC0
+ 0x800;
2300 sd
->Card
.PDIO
= sd
->Card
.PDIO0
+ 0x2000;
2304 sd
->Card
.PCIO
= sd
->Card
.PCIO0
;
2305 sd
->Card
.PCRTC
= sd
->Card
.PCRTC0
;
2306 sd
->Card
.PRAMDAC
= sd
->Card
.PRAMDAC0
;
2307 sd
->Card
.PDIO
= sd
->Card
.PDIO0
;
2311 BOOL
NVIsConnected (struct staticdata
*sd
, UBYTE output
)
2313 NVPtr pNv
= &sd
->Card
;
2314 volatile ULONG
*PRAMDAC
= pNv
->PRAMDAC0
;
2315 ULONG reg52C
, reg608
;
2319 if(output
) PRAMDAC
+= 0x800;
2321 reg52C
= PRAMDAC
[0x052C/4];
2322 reg608
= PRAMDAC
[0x0608/4];
2324 PRAMDAC
[0x0608/4] = reg608
& ~0x00010000;
2326 PRAMDAC
[0x052C/4] = reg52C
& 0x0000FEEE;
2329 for (i
=0; i
< 800000000; i
++)
2333 PRAMDAC
[0x052C/4] |= 1;
2335 pNv
->PRAMDAC0
[0x0610/4] = 0x94050140;
2336 pNv
->PRAMDAC0
[0x0608/4] |= 0x00001000;
2339 for (i
=0; i
< 800000000; i
++)
2343 present
= (PRAMDAC
[0x0608/4] & (1 << 28)) ? TRUE
: FALSE
;
2345 pNv
->PRAMDAC0
[0x0608/4] &= 0x0000EFFF;
2347 PRAMDAC
[0x052C/4] = reg52C
;
2348 PRAMDAC
[0x0608/4] = reg608
;