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((implementation
== 0x0170) ||
149 (implementation
== 0x0180) ||
150 (implementation
== 0x01F0) ||
151 (implementation
>= 0x0250))
153 if(pNv
->PEXTDEV
[0x0000/4] & (1 << 22))
154 pNv
->CrystalFreqKHz
= 27000;
157 pNv
->CursorStart
= (pNv
->RamAmountKBytes
- 96) * 1024;
158 pNv
->CURSOR
= NULL
; /* can't set this here */
159 pNv
->MinVClockFreqKHz
= 12000;
160 pNv
->MaxVClockFreqKHz
= pNv
->twoStagePLL
? 400000 : 350000;
165 static inline void CRTC_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
167 VGA_WR08(sd
->Card
.PCIO
, 0x3d4, index
);
168 VGA_WR08(sd
->Card
.PCIO
, 0x3d5, val
);
171 static inline UBYTE
CRTC_in(struct staticdata
*sd
, UBYTE index
)
173 VGA_WR08(sd
->Card
.PCIO
, 0x3d4, index
);
174 return VGA_RD08(sd
->Card
.PCIO
, 0x3d5);
177 static inline void GRA_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
179 VGA_WR08(sd
->Card
.PVIO
, 0x3ce, index
);
180 VGA_WR08(sd
->Card
.PVIO
, 0x3cf, val
);
183 static inline UBYTE
GRA_in(struct staticdata
*sd
, UBYTE index
)
185 VGA_WR08(sd
->Card
.PVIO
, 0x3ce, index
);
186 return VGA_RD08(sd
->Card
.PVIO
, 0x3cf);
189 static inline void SEQ_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
191 VGA_WR08(sd
->Card
.PVIO
, 0x3c4, index
);
192 VGA_WR08(sd
->Card
.PVIO
, 0x3c5, val
);
195 static inline UBYTE
SEQ_in(struct staticdata
*sd
, UBYTE index
)
197 VGA_WR08(sd
->Card
.PVIO
, 0x3c4, index
);
198 return VGA_RD08(sd
->Card
.PVIO
, 0x3c5);
201 static inline void ATTR_out(struct staticdata
*sd
, UBYTE index
, UBYTE val
)
205 tmp
= VGA_RD08(sd
->Card
.PCIO
, 0x3da);
206 if (sd
->Card
.paletteEnabled
)
211 VGA_WR08(sd
->Card
.PCIO
, 0x3c0, index
);
212 VGA_WR08(sd
->Card
.PCIO
, 0x3c0, val
);
215 static inline UBYTE
ATTR_in(struct staticdata
*sd
, UBYTE index
)
219 tmp
= VGA_RD08(sd
->Card
.PCIO
, 0x3da);
220 if (sd
->Card
.paletteEnabled
)
224 VGA_WR08(sd
->Card
.PCIO
, 0x3c0, index
);
226 return VGA_RD08(sd
->Card
.PCIO
, 0x3c1);
229 static inline void MISC_out(struct staticdata
*sd
, UBYTE val
)
231 VGA_WR08(sd
->Card
.PVIO
, 0x3c2, val
);
234 static inline UBYTE
MISC_in(struct staticdata
*sd
)
236 return VGA_RD08(sd
->Card
.PVIO
, 0x3cc);
239 void NVLockUnlock(struct staticdata
*sd
, UBYTE Lock
)
243 ObtainSemaphore(&sd
->HWLock
);
244 VGA_WR08(sd
->Card
.PCIO
, 0x3D4, 0x1F);
245 VGA_WR08(sd
->Card
.PCIO
, 0x3D5, Lock
? 0x99 : 0x57);
247 VGA_WR08(sd
->Card
.PCIO
, 0x3D4, 0x11);
248 cr11
= VGA_RD08(sd
->Card
.PCIO
, 0x3D5);
249 if(Lock
) cr11
|= 0x80;
251 VGA_WR08(sd
->Card
.PCIO
, 0x3D5, cr11
);
252 ReleaseSemaphore(&sd
->HWLock
);
255 int NVShowHideCursor (struct staticdata
*sd
, UBYTE ShowHide
)
257 int current
= sd
->Card
.CurrentState
->cursor1
;
259 ObtainSemaphore(&sd
->HWLock
);
260 sd
->Card
.CurrentState
->cursor1
= (sd
->Card
.CurrentState
->cursor1
& 0xFE) |
262 VGA_WR08(sd
->Card
.PCIO
, 0x3D4, 0x31);
263 VGA_WR08(sd
->Card
.PCIO
, 0x3D5, sd
->Card
.CurrentState
->cursor1
);
265 if (sd
->Card
.Architecture
== NV_ARCH_40
) { /* HW bug */
266 volatile ULONG curpos
= sd
->Card
.PRAMDAC
[0x0300/4];
267 sd
->Card
.PRAMDAC
[0x0300/4] = curpos
;
270 ReleaseSemaphore(&sd
->HWLock
);
271 return (current
& 0x01);
274 /****************************************************************************\
276 * The video arbitration routines calculate some "magic" numbers. Fixes *
277 * the snow seen when accessing the framebuffer without it. *
278 * It just works (I hope). *
280 \****************************************************************************/
285 int graphics_burst_size
;
286 int video_burst_size
;
307 int graphics_burst_size
;
308 int video_burst_size
;
327 static void nvGetClocks(NVPtr pNv
, ULONG
*MClk
, ULONG
*NVClk
)
329 unsigned int pll
, N
, M
, MB
, NB
, P
;
331 if(pNv
->Architecture
>= NV_ARCH_40
) {
332 pll
= pNv
->PMC
[0x4020/4];
333 P
= (pll
>> 16) & 0x03;
334 pll
= pNv
->PMC
[0x4024/4];
336 N
= (pll
>> 8) & 0xFF;
337 MB
= (pll
>> 16) & 0xFF;
338 NB
= (pll
>> 24) & 0xFF;
339 *MClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
341 pll
= pNv
->PMC
[0x4000/4];
342 P
= (pll
>> 16) & 0x03;
343 pll
= pNv
->PMC
[0x4004/4];
345 N
= (pll
>> 8) & 0xFF;
346 MB
= (pll
>> 16) & 0xFF;
347 NB
= (pll
>> 24) & 0xFF;
349 *NVClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
351 if(pNv
->twoStagePLL
) {
352 pll
= pNv
->PRAMDAC0
[0x0504/4];
354 N
= (pll
>> 8) & 0xFF;
355 P
= (pll
>> 16) & 0x0F;
356 pll
= pNv
->PRAMDAC0
[0x0574/4];
357 if(pll
& 0x80000000) {
359 NB
= (pll
>> 8) & 0xFF;
364 *MClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
366 pll
= pNv
->PRAMDAC0
[0x0500/4];
368 N
= (pll
>> 8) & 0xFF;
369 P
= (pll
>> 16) & 0x0F;
370 pll
= pNv
->PRAMDAC0
[0x0570/4];
371 if(pll
& 0x80000000) {
373 NB
= (pll
>> 8) & 0xFF;
378 *NVClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
380 if(((pNv
->Chipset
& 0x0ff0) == 0x0300) ||
381 ((pNv
->Chipset
& 0x0ff0) == 0x0330))
383 pll
= pNv
->PRAMDAC0
[0x0504/4];
385 N
= (pll
>> 8) & 0xFF;
386 P
= (pll
>> 16) & 0x07;
387 if(pll
& 0x00000080) {
388 MB
= (pll
>> 4) & 0x07;
389 NB
= (pll
>> 19) & 0x1f;
394 *MClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
396 pll
= pNv
->PRAMDAC0
[0x0500/4];
398 N
= (pll
>> 8) & 0xFF;
399 P
= (pll
>> 16) & 0x07;
400 if(pll
& 0x00000080) {
401 MB
= (pll
>> 4) & 0x07;
402 NB
= (pll
>> 19) & 0x1f;
407 *NVClk
= ((N
* NB
* pNv
->CrystalFreqKHz
) / (M
* MB
)) >> P
;
409 pll
= pNv
->PRAMDAC0
[0x0504/4];
411 N
= (pll
>> 8) & 0xFF;
412 P
= (pll
>> 16) & 0x0F;
413 *MClk
= (N
* pNv
->CrystalFreqKHz
/ M
) >> P
;
415 pll
= pNv
->PRAMDAC0
[0x0500/4];
417 N
= (pll
>> 8) & 0xFF;
418 P
= (pll
>> 16) & 0x0F;
419 *NVClk
= (N
* pNv
->CrystalFreqKHz
/ M
) >> P
;
423 static void nv4CalcArbitration (
428 int data
, pagemiss
, cas
,width
, video_enable
, bpp
;
429 int nvclks
, mclks
, pclks
, vpagemiss
, crtpagemiss
, vbs
;
430 int found
, mclk_extra
, mclk_loop
, cbs
, m1
, p1
;
431 int mclk_freq
, pclk_freq
, nvclk_freq
, mp_enable
;
432 int us_m
, us_n
, us_p
, video_drain_rate
, crtc_drain_rate
;
433 int vpm_us
, us_video
, vlwm
, video_fill_us
, cpm_us
, us_crt
,clwm
;
436 pclk_freq
= arb
->pclk_khz
;
437 mclk_freq
= arb
->mclk_khz
;
438 nvclk_freq
= arb
->nvclk_khz
;
439 pagemiss
= arb
->mem_page_miss
;
440 cas
= arb
->mem_latency
;
441 width
= arb
->memory_width
>> 6;
442 video_enable
= arb
->enable_video
;
444 mp_enable
= arb
->enable_mp
;
475 mclk_loop
= mclks
+mclk_extra
;
476 us_m
= mclk_loop
*1000*1000 / mclk_freq
;
477 us_n
= nvclks
*1000*1000 / nvclk_freq
;
478 us_p
= nvclks
*1000*1000 / pclk_freq
;
481 video_drain_rate
= pclk_freq
* 2;
482 crtc_drain_rate
= pclk_freq
* bpp
/8;
486 vpm_us
= (vpagemiss
* pagemiss
)*1000*1000/mclk_freq
;
487 if (nvclk_freq
* 2 > mclk_freq
* width
)
488 video_fill_us
= cbs
*1000*1000 / 16 / nvclk_freq
;
490 video_fill_us
= cbs
*1000*1000 / (8 * width
) / mclk_freq
;
491 us_video
= vpm_us
+ us_m
+ us_n
+ us_p
+ video_fill_us
;
492 vlwm
= us_video
* video_drain_rate
/(1000*1000);
495 if (vlwm
> 128) vbs
= 64;
496 if (vlwm
> (256-64)) vbs
= 32;
497 if (nvclk_freq
* 2 > mclk_freq
* width
)
498 video_fill_us
= vbs
*1000*1000/ 16 / nvclk_freq
;
500 video_fill_us
= vbs
*1000*1000 / (8 * width
) / mclk_freq
;
501 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
508 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
513 crtc_drain_rate
= pclk_freq
* bpp
/8;
516 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
517 us_crt
= cpm_us
+ us_m
+ us_n
+ us_p
;
518 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
521 m1
= clwm
+ cbs
- 512;
522 p1
= m1
* pclk_freq
/ mclk_freq
;
524 if ((p1
< m1
) && (m1
> 0))
528 if (mclk_extra
==0) found
= 1;
531 else if (video_enable
)
533 if ((clwm
> 511) || (vlwm
> 255))
537 if (mclk_extra
==0) found
= 1;
547 if (mclk_extra
==0) found
= 1;
551 if (clwm
< 384) clwm
= 384;
552 if (vlwm
< 128) vlwm
= 128;
554 fifo
->graphics_lwm
= data
;
555 fifo
->graphics_burst_size
= 128;
556 data
= (int)((vlwm
+15));
557 fifo
->video_lwm
= data
;
558 fifo
->video_burst_size
= vbs
;
562 static void nv4UpdateArbitrationSettings (
570 nv4_fifo_info fifo_data
;
571 nv4_sim_state sim_data
;
572 ULONG MClk
, NVClk
, cfg1
;
574 nvGetClocks(pNv
, &MClk
, &NVClk
);
576 cfg1
= pNv
->PFB
[0x00000204/4];
577 sim_data
.pix_bpp
= (char)pixelDepth
;
578 sim_data
.enable_video
= 0;
579 sim_data
.enable_mp
= 0;
580 sim_data
.memory_width
= (pNv
->PEXTDEV
[0x0000/4] & 0x10) ? 128 : 64;
581 sim_data
.mem_latency
= (char)cfg1
& 0x0F;
582 sim_data
.mem_aligned
= 1;
583 sim_data
.mem_page_miss
= (char)(((cfg1
>> 4) &0x0F) + ((cfg1
>> 31) & 0x01));
584 sim_data
.gr_during_vid
= 0;
585 sim_data
.pclk_khz
= VClk
;
586 sim_data
.mclk_khz
= MClk
;
587 sim_data
.nvclk_khz
= NVClk
;
588 nv4CalcArbitration(&fifo_data
, &sim_data
);
591 int b
= fifo_data
.graphics_burst_size
>> 4;
593 while (b
>>= 1) (*burst
)++;
594 *lwm
= fifo_data
.graphics_lwm
>> 3;
598 static void nv10CalcArbitration (
599 nv10_fifo_info
*fifo
,
603 int data
, pagemiss
, width
, video_enable
, bpp
;
604 int nvclks
, mclks
, pclks
, vpagemiss
, crtpagemiss
;
606 int found
, mclk_extra
, mclk_loop
, cbs
, m1
;
607 int mclk_freq
, pclk_freq
, nvclk_freq
, mp_enable
;
608 int us_m
, us_m_min
, us_n
, us_p
, crtc_drain_rate
;
610 int vpm_us
, us_video
, cpm_us
, us_crt
,clwm
;
612 int m2us
, us_pipe_min
, p1clk
, p2
;
614 int us_min_mclk_extra
;
617 pclk_freq
= arb
->pclk_khz
; /* freq in KHz */
618 mclk_freq
= arb
->mclk_khz
;
619 nvclk_freq
= arb
->nvclk_khz
;
620 pagemiss
= arb
->mem_page_miss
;
621 width
= arb
->memory_width
/64;
622 video_enable
= arb
->enable_video
;
624 mp_enable
= arb
->enable_mp
;
629 pclks
= 4; /* lwm detect. */
631 nvclks
= 3; /* lwm -> sync. */
632 nvclks
+= 2; /* fbi bus cycles (1 req + 1 busy) */
634 mclks
= 1; /* 2 edge sync. may be very close to edge so just put one. */
636 mclks
+= 1; /* arb_hp_req */
637 mclks
+= 5; /* ap_hp_req tiling pipeline */
639 mclks
+= 2; /* tc_req latency fifo */
640 mclks
+= 2; /* fb_cas_n_ memory request to fbio block */
641 mclks
+= 7; /* sm_d_rdv data returned from fbio block */
643 /* fb.rd.d.Put_gc need to accumulate 256 bits for read */
644 if (arb
->memory_type
== 0)
645 if (arb
->memory_width
== 64) /* 64 bit bus */
650 if (arb
->memory_width
== 64) /* 64 bit bus */
655 if ((!video_enable
) && (arb
->memory_width
== 128))
657 mclk_extra
= (bpp
== 32) ? 31 : 42; /* Margin of error */
662 mclk_extra
= (bpp
== 32) ? 8 : 4; /* Margin of error */
663 /* mclk_extra = 4; */ /* Margin of error */
667 nvclks
+= 1; /* 2 edge sync. may be very close to edge so just put one. */
668 nvclks
+= 1; /* fbi_d_rdv_n */
669 nvclks
+= 1; /* Fbi_d_rdata */
670 nvclks
+= 1; /* crtfifo load */
673 mclks
+=4; /* Mp can get in with a burst of 8. */
674 /* Extra clocks determined by heuristics */
682 mclk_loop
= mclks
+mclk_extra
;
683 us_m
= mclk_loop
*1000*1000 / mclk_freq
; /* Mclk latency in us */
684 us_m_min
= mclks
* 1000*1000 / mclk_freq
; /* Minimum Mclk latency in us */
685 us_min_mclk_extra
= min_mclk_extra
*1000*1000 / mclk_freq
;
686 us_n
= nvclks
*1000*1000 / nvclk_freq
;/* nvclk latency in us */
687 us_p
= pclks
*1000*1000 / pclk_freq
;/* nvclk latency in us */
688 us_pipe_min
= us_m_min
+ us_n
+ us_p
;
690 vus_m
= mclk_loop
*1000*1000 / mclk_freq
; /* Mclk latency in us */
693 crtc_drain_rate
= pclk_freq
* bpp
/8; /* MB/s */
695 vpagemiss
= 1; /* self generating page miss */
696 vpagemiss
+= 1; /* One higher priority before */
698 crtpagemiss
= 2; /* self generating page miss */
700 crtpagemiss
+= 1; /* if MA0 conflict */
702 vpm_us
= (vpagemiss
* pagemiss
)*1000*1000/mclk_freq
;
704 us_video
= vpm_us
+ vus_m
; /* Video has separate read return path */
706 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
708 us_video
/* Wait for video */
709 +cpm_us
/* CRT Page miss */
710 +us_m
+ us_n
+us_p
/* other latency */
713 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
714 clwm
++; /* fixed point <= float_point - 1. Fixes that */
716 crtc_drain_rate
= pclk_freq
* bpp
/8; /* bpp * pclk/8 */
718 crtpagemiss
= 1; /* self generating page miss */
719 crtpagemiss
+= 1; /* MA0 page miss */
721 crtpagemiss
+= 1; /* if MA0 conflict */
722 cpm_us
= crtpagemiss
* pagemiss
*1000*1000/ mclk_freq
;
723 us_crt
= cpm_us
+ us_m
+ us_n
+ us_p
;
724 clwm
= us_crt
* crtc_drain_rate
/(1000*1000);
725 clwm
++; /* fixed point <= float_point - 1. Fixes that */
727 /* Finally, a heuristic check when width == 64 bits */
729 nvclk_fill
= nvclk_freq
* 8;
730 if(crtc_drain_rate
* 100 >= nvclk_fill
* 102)
731 clwm
= 0xfff; /*Large number to fail */
733 else if(crtc_drain_rate
* 100 >= nvclk_fill
* 98) {
746 clwm_rnd_down
= ((int)clwm
/8)*8;
747 if (clwm_rnd_down
< clwm
)
750 m1
= clwm
+ cbs
- 1024; /* Amount of overfill */
751 m2us
= us_pipe_min
+ us_min_mclk_extra
;
753 /* pclk cycles to drain */
754 p1clk
= m2us
* pclk_freq
/(1000*1000);
755 p2
= p1clk
* bpp
/ 8; /* bytes drained. */
757 if((p2
< m1
) && (m1
> 0)) {
760 if(min_mclk_extra
== 0) {
762 found
= 1; /* Can't adjust anymore! */
764 cbs
= cbs
/2; /* reduce the burst size */
770 if (clwm
> 1023){ /* Have some margin */
773 if(min_mclk_extra
== 0)
774 found
= 1; /* Can't adjust anymore! */
780 if(clwm
< (1024-cbs
+8)) clwm
= 1024-cbs
+8;
782 /* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
783 fifo
->graphics_lwm
= data
; fifo
->graphics_burst_size
= cbs
;
785 fifo
->video_lwm
= 1024; fifo
->video_burst_size
= 512;
789 static void nv10UpdateArbitrationSettings (
797 nv10_fifo_info fifo_data
;
798 nv10_sim_state sim_data
;
799 ULONG MClk
, NVClk
, cfg1
;
801 nvGetClocks(pNv
, &MClk
, &NVClk
);
803 cfg1
= pNv
->PFB
[0x0204/4];
804 sim_data
.pix_bpp
= (char)pixelDepth
;
805 sim_data
.enable_video
= 1;
806 sim_data
.enable_mp
= 0;
807 sim_data
.memory_type
= (pNv
->PFB
[0x0200/4] & 0x01) ? 1 : 0;
808 sim_data
.memory_width
= (pNv
->PEXTDEV
[0x0000/4] & 0x10) ? 128 : 64;
809 sim_data
.mem_latency
= (char)cfg1
& 0x0F;
810 sim_data
.mem_aligned
= 1;
811 sim_data
.mem_page_miss
= (char)(((cfg1
>>4) &0x0F) + ((cfg1
>>31) & 0x01));
812 sim_data
.gr_during_vid
= 0;
813 sim_data
.pclk_khz
= VClk
;
814 sim_data
.mclk_khz
= MClk
;
815 sim_data
.nvclk_khz
= NVClk
;
817 nv10CalcArbitration(&fifo_data
, &sim_data
);
818 if (fifo_data
.valid
) {
819 int b
= fifo_data
.graphics_burst_size
>> 4;
821 while (b
>>= 1) (*burst
)++;
822 *lwm
= fifo_data
.graphics_lwm
>> 3;
826 static void nv30UpdateArbitrationSettings (
833 unsigned int fifo_size
, burst_size
, graphics_lwm
;
837 graphics_lwm
= fifo_size
- burst_size
;
839 nvGetClocks(pNv
, &MClk
, &NVClk
);
843 while(burst_size
>>= 1) (*burst
)++;
844 *lwm
= graphics_lwm
>> 3;
847 static void nForceUpdateArbitrationSettings (
852 struct staticdata
*sd
,
856 nv10_fifo_info fifo_data
;
857 nv10_sim_state sim_data
;
858 unsigned int M
, N
, P
, pll
, MClk
, NVClk
, memctrl
;
860 if((pNv
->Chipset
& 0x0FF0) == 0x01A0) {
861 unsigned int uMClkPostDiv
;
863 uMClkPostDiv
= (pciReadLong(sd
, 0, 0, 3, 0x6C) >> 8) & 0xf;
864 if(!uMClkPostDiv
) uMClkPostDiv
= 4;
865 MClk
= 400000 / uMClkPostDiv
;
867 MClk
= pciReadLong(sd
, 0, 0, 5, 0x4C) / 1000;
870 pll
= pNv
->PRAMDAC0
[0x0500/4];
871 M
= (pll
>> 0) & 0xFF; N
= (pll
>> 8) & 0xFF; P
= (pll
>> 16) & 0x0F;
872 NVClk
= (N
* pNv
->CrystalFreqKHz
/ M
) >> P
;
873 sim_data
.pix_bpp
= (char)pixelDepth
;
874 sim_data
.enable_video
= 0;
875 sim_data
.enable_mp
= 0;
876 sim_data
.memory_type
= (pciReadLong(sd
, 0, 0, 1, 0x7C) >> 12) & 1;
877 sim_data
.memory_width
= 64;
879 memctrl
= pciReadLong(sd
, 0, 0, 3, 0x00) >> 16;
881 if((memctrl
== 0x1A9) || (memctrl
== 0x1AB) || (memctrl
== 0x1ED)) {
884 dimm
[0] = (pciReadLong(sd
, 0, 0, 2, 0x40) >> 8) & 0x4F;
885 dimm
[1] = (pciReadLong(sd
, 0, 0, 2, 0x44) >> 8) & 0x4F;
886 dimm
[2] = (pciReadLong(sd
, 0, 0, 2, 0x48) >> 8) & 0x4F;
888 if((dimm
[0] + dimm
[1]) != dimm
[2]) {
890 "your nForce DIMMs are not arranged in optimal banks!\n");
894 sim_data
.mem_latency
= 3;
895 sim_data
.mem_aligned
= 1;
896 sim_data
.mem_page_miss
= 10;
897 sim_data
.gr_during_vid
= 0;
898 sim_data
.pclk_khz
= VClk
;
899 sim_data
.mclk_khz
= MClk
;
900 sim_data
.nvclk_khz
= NVClk
;
901 nv10CalcArbitration(&fifo_data
, &sim_data
);
904 int b
= fifo_data
.graphics_burst_size
>> 4;
906 while (b
>>= 1) (*burst
)++;
907 *lwm
= fifo_data
.graphics_lwm
>> 3;
911 /****************************************************************************\
913 * RIVA Mode State Routines *
915 \****************************************************************************/
918 * Calculate the Video Clock parameters for the PLL.
920 static void CalcVClock (
927 unsigned lowM
, highM
;
928 unsigned DeltaNew
, DeltaOld
;
932 DeltaOld
= 0xFFFFFFFF;
934 VClk
= (unsigned)clockIn
;
936 if (pNv
->CrystalFreqKHz
== 13500) {
944 for (P
= 0; P
<= 4; P
++) {
946 if ((Freq
>= 128000) && (Freq
<= 350000)) {
947 for (M
= lowM
; M
<= highM
; M
++) {
948 N
= ((VClk
<< P
) * M
) / pNv
->CrystalFreqKHz
;
950 Freq
= ((pNv
->CrystalFreqKHz
* N
) / M
) >> P
;
952 DeltaNew
= Freq
- VClk
;
954 DeltaNew
= VClk
- Freq
;
955 if (DeltaNew
< DeltaOld
) {
956 *pllOut
= (P
<< 16) | (N
<< 8) | M
;
966 static void CalcVClock2Stage (
974 unsigned DeltaNew
, DeltaOld
;
978 DeltaOld
= 0xFFFFFFFF;
980 *pllBOut
= 0x80000401; /* fixed at x4 for now */
982 VClk
= (unsigned)clockIn
;
984 for (P
= 0; P
<= 6; P
++) {
986 if ((Freq
>= 400000) && (Freq
<= 1000000)) {
987 for (M
= 1; M
<= 13; M
++) {
988 N
= ((VClk
<< P
) * M
) / (pNv
->CrystalFreqKHz
<< 2);
989 if((N
>= 5) && (N
<= 255)) {
990 Freq
= (((pNv
->CrystalFreqKHz
<< 2) * N
) / M
) >> P
;
992 DeltaNew
= Freq
- VClk
;
994 DeltaNew
= VClk
- Freq
;
995 if (DeltaNew
< DeltaOld
) {
996 *pllOut
= (P
<< 16) | (N
<< 8) | M
;
1008 * Calculate extended mode parameters (SVGA) and save in a
1009 * mode state structure.
1011 void NVCalcStateExt (
1012 struct staticdata
*sd
,
1014 RIVA_HW_STATE
*state
,
1023 ULONG pixelDepth
, VClk
;
1025 * Save mode parameters.
1027 state
->bpp
= bpp
; /* this is not bitsPerPixel, it's 8,15,16,32 */
1028 state
->width
= width
;
1029 state
->height
= height
;
1031 * Extended RIVA registers.
1033 pixelDepth
= (bpp
+ 1)/8;
1035 if(pNv
->twoStagePLL
)
1036 CalcVClock2Stage(dotClock
, &VClk
, &state
->pll
, &state
->pllB
, pNv
);
1038 CalcVClock(dotClock
, &VClk
, &state
->pll
, pNv
);
1040 switch (pNv
->Architecture
)
1043 nv4UpdateArbitrationSettings(VClk
,
1045 &(state
->arbitration0
),
1046 &(state
->arbitration1
),
1048 state
->cursor0
= 0x00;
1049 state
->cursor1
= 0xbC;
1050 if (flags
& V_DBLSCAN
)
1051 state
->cursor1
|= 2;
1052 state
->cursor2
= 0x00000000;
1053 state
->pllsel
= 0x10000700;
1054 state
->config
= 0x00001114;
1055 state
->general
= bpp
== 16 ? 0x00101100 : 0x00100100;
1056 state
->repaint1
= hDisplaySize
< 1280 ? 0x04 : 0x00;
1062 if(((pNv
->Chipset
& 0xffff) == 0x01A0) ||
1063 ((pNv
->Chipset
& 0xffff) == 0x01f0))
1065 nForceUpdateArbitrationSettings(VClk
,
1067 &(state
->arbitration0
),
1068 &(state
->arbitration1
),
1071 } else if (pNv
->Architecture
< NV_ARCH_30
) {
1072 nv10UpdateArbitrationSettings(VClk
,
1074 &(state
->arbitration0
),
1075 &(state
->arbitration1
),
1078 nv30UpdateArbitrationSettings(pNv
,
1079 &(state
->arbitration0
),
1080 &(state
->arbitration1
));
1082 state
->cursor0
= 0x80 | (pNv
->CursorStart
>> 17);
1083 state
->cursor1
= (pNv
->CursorStart
>> 11) << 2;
1084 state
->cursor2
= pNv
->CursorStart
>> 24;
1085 if (flags
& V_DBLSCAN
)
1086 state
->cursor1
|= 2;
1087 state
->pllsel
= 0x10000700;
1088 state
->config
= pNv
->PFB
[0x00000200/4];
1089 state
->general
= bpp
== 16 ? 0x00101100 : 0x00100100;
1090 state
->repaint1
= hDisplaySize
< 1280 ? 0x04 : 0x00;
1093 if(bpp
!= 8) /* DirectColor */
1094 state
->general
|= 0x00000030;
1096 state
->repaint0
= (((width
/ 8) * pixelDepth
) & 0x700) >> 3;
1097 state
->pixel
= (pixelDepth
> 2) ? 3 : pixelDepth
;
1101 ** stegerg: Status NVLoadStateExt(): should "match" xfree nv NVLoadStateExt()
1102 ** in xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c version:
1103 ** 1.12 2004/11/30 23:50:26 mvojkovi
1105 ** Exception: some waitvsyncpossible stuff commented out
1108 void NVLoadStateExt (
1110 RIVA_HW_STATE
*state
1115 pNv
->PMC
[0x0140/4] = 0x00000000;
1116 pNv
->PMC
[0x0200/4] = 0xFFFF00FF;
1117 pNv
->PMC
[0x0200/4] = 0xFFFFFFFF;
1119 pNv
->PTIMER
[0x0200] = 0x00000008;
1120 pNv
->PTIMER
[0x0210] = 0x00000003;
1121 pNv
->PTIMER
[0x0140] = 0x00000000;
1122 pNv
->PTIMER
[0x0100] = 0xFFFFFFFF;
1124 if(pNv
->Architecture
== NV_ARCH_04
) {
1125 pNv
->PFB
[0x0200/4] = state
->config
;
1127 pNv
->PFB
[0x0240/4] = 0;
1128 pNv
->PFB
[0x0244/4] = pNv
->FrameBufferSize
- 1;
1129 pNv
->PFB
[0x0250/4] = 0;
1130 pNv
->PFB
[0x0254/4] = pNv
->FrameBufferSize
- 1;
1131 pNv
->PFB
[0x0260/4] = 0;
1132 pNv
->PFB
[0x0264/4] = pNv
->FrameBufferSize
- 1;
1133 pNv
->PFB
[0x0270/4] = 0;
1134 pNv
->PFB
[0x0274/4] = pNv
->FrameBufferSize
- 1;
1135 pNv
->PFB
[0x0280/4] = 0;
1136 pNv
->PFB
[0x0284/4] = pNv
->FrameBufferSize
- 1;
1137 pNv
->PFB
[0x0290/4] = 0;
1138 pNv
->PFB
[0x0294/4] = pNv
->FrameBufferSize
- 1;
1139 pNv
->PFB
[0x02A0/4] = 0;
1140 pNv
->PFB
[0x02A4/4] = pNv
->FrameBufferSize
- 1;
1141 pNv
->PFB
[0x02B0/4] = 0;
1142 pNv
->PFB
[0x02B4/4] = pNv
->FrameBufferSize
- 1;
1145 if(pNv
->Architecture
>= NV_ARCH_40
) {
1146 pNv
->PRAMIN
[0x0000] = 0x80000010;
1147 pNv
->PRAMIN
[0x0001] = 0x00101202;
1148 pNv
->PRAMIN
[0x0002] = 0x80000011;
1149 pNv
->PRAMIN
[0x0003] = 0x00101204;
1150 pNv
->PRAMIN
[0x0004] = 0x80000012;
1151 pNv
->PRAMIN
[0x0005] = 0x00101206;
1152 pNv
->PRAMIN
[0x0006] = 0x80000013;
1153 pNv
->PRAMIN
[0x0007] = 0x00101208;
1154 pNv
->PRAMIN
[0x0008] = 0x80000014;
1155 pNv
->PRAMIN
[0x0009] = 0x0010120A;
1156 pNv
->PRAMIN
[0x000A] = 0x80000015;
1157 pNv
->PRAMIN
[0x000B] = 0x0010120C;
1158 pNv
->PRAMIN
[0x000C] = 0x80000016;
1159 pNv
->PRAMIN
[0x000D] = 0x0010120E;
1160 pNv
->PRAMIN
[0x000E] = 0x80000017;
1161 pNv
->PRAMIN
[0x000F] = 0x00101210;
1162 pNv
->PRAMIN
[0x0800] = 0x00003000;
1163 pNv
->PRAMIN
[0x0801] = pNv
->FrameBufferSize
- 1;
1164 pNv
->PRAMIN
[0x0802] = 0x00000002;
1165 pNv
->PRAMIN
[0x0808] = 0x02080062;
1166 pNv
->PRAMIN
[0x0809] = 0x00000000;
1167 pNv
->PRAMIN
[0x080A] = 0x00001200;
1168 pNv
->PRAMIN
[0x080B] = 0x00001200;
1169 pNv
->PRAMIN
[0x080C] = 0x00000000;
1170 pNv
->PRAMIN
[0x080D] = 0x00000000;
1171 pNv
->PRAMIN
[0x0810] = 0x02080043;
1172 pNv
->PRAMIN
[0x0811] = 0x00000000;
1173 pNv
->PRAMIN
[0x0812] = 0x00000000;
1174 pNv
->PRAMIN
[0x0813] = 0x00000000;
1175 pNv
->PRAMIN
[0x0814] = 0x00000000;
1176 pNv
->PRAMIN
[0x0815] = 0x00000000;
1177 pNv
->PRAMIN
[0x0818] = 0x02080044;
1178 pNv
->PRAMIN
[0x0819] = 0x02000000;
1179 pNv
->PRAMIN
[0x081A] = 0x00000000;
1180 pNv
->PRAMIN
[0x081B] = 0x00000000;
1181 pNv
->PRAMIN
[0x081C] = 0x00000000;
1182 pNv
->PRAMIN
[0x081D] = 0x00000000;
1183 pNv
->PRAMIN
[0x0820] = 0x02080019;
1184 pNv
->PRAMIN
[0x0821] = 0x00000000;
1185 pNv
->PRAMIN
[0x0822] = 0x00000000;
1186 pNv
->PRAMIN
[0x0823] = 0x00000000;
1187 pNv
->PRAMIN
[0x0824] = 0x00000000;
1188 pNv
->PRAMIN
[0x0825] = 0x00000000;
1189 pNv
->PRAMIN
[0x0828] = 0x020A005C;
1190 pNv
->PRAMIN
[0x0829] = 0x00000000;
1191 pNv
->PRAMIN
[0x082A] = 0x00000000;
1192 pNv
->PRAMIN
[0x082B] = 0x00000000;
1193 pNv
->PRAMIN
[0x082C] = 0x00000000;
1194 pNv
->PRAMIN
[0x082D] = 0x00000000;
1195 pNv
->PRAMIN
[0x0830] = 0x0208009F;
1196 pNv
->PRAMIN
[0x0831] = 0x00000000;
1197 pNv
->PRAMIN
[0x0832] = 0x00001200;
1198 pNv
->PRAMIN
[0x0833] = 0x00001200;
1199 pNv
->PRAMIN
[0x0834] = 0x00000000;
1200 pNv
->PRAMIN
[0x0835] = 0x00000000;
1201 pNv
->PRAMIN
[0x0838] = 0x0208004A;
1202 pNv
->PRAMIN
[0x0839] = 0x02000000;
1203 pNv
->PRAMIN
[0x083A] = 0x00000000;
1204 pNv
->PRAMIN
[0x083B] = 0x00000000;
1205 pNv
->PRAMIN
[0x083C] = 0x00000000;
1206 pNv
->PRAMIN
[0x083D] = 0x00000000;
1207 pNv
->PRAMIN
[0x0840] = 0x02080077;
1208 pNv
->PRAMIN
[0x0841] = 0x00000000;
1209 pNv
->PRAMIN
[0x0842] = 0x00001200;
1210 pNv
->PRAMIN
[0x0843] = 0x00001200;
1211 pNv
->PRAMIN
[0x0844] = 0x00000000;
1212 pNv
->PRAMIN
[0x0845] = 0x00000000;
1213 pNv
->PRAMIN
[0x084C] = 0x00003002;
1214 pNv
->PRAMIN
[0x084D] = 0x00007FFF;
1215 pNv
->PRAMIN
[0x084E] = pNv
->FbUsableSize
| 0x00000002;
1218 pNv
->PRAMIN
[0x080A] |= 0x01000000;
1219 pNv
->PRAMIN
[0x0812] |= 0x01000000;
1220 pNv
->PRAMIN
[0x081A] |= 0x01000000;
1221 pNv
->PRAMIN
[0x0822] |= 0x01000000;
1222 pNv
->PRAMIN
[0x082A] |= 0x01000000;
1223 pNv
->PRAMIN
[0x0832] |= 0x01000000;
1224 pNv
->PRAMIN
[0x083A] |= 0x01000000;
1225 pNv
->PRAMIN
[0x0842] |= 0x01000000;
1226 pNv
->PRAMIN
[0x0819] = 0x01000000;
1227 pNv
->PRAMIN
[0x0839] = 0x01000000;
1231 pNv
->PRAMIN
[0x0000] = 0x80000010;
1232 pNv
->PRAMIN
[0x0001] = 0x80011201;
1233 pNv
->PRAMIN
[0x0002] = 0x80000011;
1234 pNv
->PRAMIN
[0x0003] = 0x80011202;
1235 pNv
->PRAMIN
[0x0004] = 0x80000012;
1236 pNv
->PRAMIN
[0x0005] = 0x80011203;
1237 pNv
->PRAMIN
[0x0006] = 0x80000013;
1238 pNv
->PRAMIN
[0x0007] = 0x80011204;
1239 pNv
->PRAMIN
[0x0008] = 0x80000014;
1240 pNv
->PRAMIN
[0x0009] = 0x80011205;
1241 pNv
->PRAMIN
[0x000A] = 0x80000015;
1242 pNv
->PRAMIN
[0x000B] = 0x80011206;
1243 pNv
->PRAMIN
[0x000C] = 0x80000016;
1244 pNv
->PRAMIN
[0x000D] = 0x80011207;
1245 pNv
->PRAMIN
[0x000E] = 0x80000017;
1246 pNv
->PRAMIN
[0x000F] = 0x80011208;
1247 pNv
->PRAMIN
[0x0800] = 0x00003000;
1248 pNv
->PRAMIN
[0x0801] = pNv
->FrameBufferSize
- 1;
1249 pNv
->PRAMIN
[0x0802] = 0x00000002;
1250 pNv
->PRAMIN
[0x0803] = 0x00000002;
1251 if(pNv
->Architecture
>= NV_ARCH_10
)
1252 pNv
->PRAMIN
[0x0804] = 0x01008062;
1254 pNv
->PRAMIN
[0x0804] = 0x01008042;
1255 pNv
->PRAMIN
[0x0805] = 0x00000000;
1256 pNv
->PRAMIN
[0x0806] = 0x12001200;
1257 pNv
->PRAMIN
[0x0807] = 0x00000000;
1258 pNv
->PRAMIN
[0x0808] = 0x01008043;
1259 pNv
->PRAMIN
[0x0809] = 0x00000000;
1260 pNv
->PRAMIN
[0x080A] = 0x00000000;
1261 pNv
->PRAMIN
[0x080B] = 0x00000000;
1262 pNv
->PRAMIN
[0x080C] = 0x01008044;
1263 pNv
->PRAMIN
[0x080D] = 0x00000002;
1264 pNv
->PRAMIN
[0x080E] = 0x00000000;
1265 pNv
->PRAMIN
[0x080F] = 0x00000000;
1266 pNv
->PRAMIN
[0x0810] = 0x01008019;
1267 pNv
->PRAMIN
[0x0811] = 0x00000000;
1268 pNv
->PRAMIN
[0x0812] = 0x00000000;
1269 pNv
->PRAMIN
[0x0813] = 0x00000000;
1270 pNv
->PRAMIN
[0x0814] = 0x0100A05C;
1271 pNv
->PRAMIN
[0x0815] = 0x00000000;
1272 pNv
->PRAMIN
[0x0816] = 0x00000000;
1273 pNv
->PRAMIN
[0x0817] = 0x00000000;
1274 // aros: commented out for now
1275 // if(pNv->WaitVSyncPossible)
1276 // pNv->PRAMIN[0x0818] = 0x0100809F;
1278 pNv
->PRAMIN
[0x0818] = 0x0100805F;
1279 pNv
->PRAMIN
[0x0819] = 0x00000000;
1280 pNv
->PRAMIN
[0x081A] = 0x12001200;
1281 pNv
->PRAMIN
[0x081B] = 0x00000000;
1282 pNv
->PRAMIN
[0x081C] = 0x0100804A;
1283 pNv
->PRAMIN
[0x081D] = 0x00000002;
1284 pNv
->PRAMIN
[0x081E] = 0x00000000;
1285 pNv
->PRAMIN
[0x081F] = 0x00000000;
1286 pNv
->PRAMIN
[0x0820] = 0x01018077;
1287 pNv
->PRAMIN
[0x0821] = 0x00000000;
1288 pNv
->PRAMIN
[0x0822] = 0x12001200;
1289 pNv
->PRAMIN
[0x0823] = 0x00000000;
1290 pNv
->PRAMIN
[0x0824] = 0x00003002;
1291 pNv
->PRAMIN
[0x0825] = 0x00007FFF;
1292 pNv
->PRAMIN
[0x0826] = pNv
->FbUsableSize
| 0x00000002;
1293 pNv
->PRAMIN
[0x0827] = 0x00000002;
1296 pNv
->PRAMIN
[0x0804] |= 0x00080000;
1297 pNv
->PRAMIN
[0x0808] |= 0x00080000;
1298 pNv
->PRAMIN
[0x080C] |= 0x00080000;
1299 pNv
->PRAMIN
[0x0810] |= 0x00080000;
1300 pNv
->PRAMIN
[0x0814] |= 0x00080000;
1301 pNv
->PRAMIN
[0x0818] |= 0x00080000;
1302 pNv
->PRAMIN
[0x081C] |= 0x00080000;
1303 pNv
->PRAMIN
[0x0820] |= 0x00080000;
1305 pNv
->PRAMIN
[0x080D] = 0x00000001;
1306 pNv
->PRAMIN
[0x081D] = 0x00000001;
1310 if(pNv
->Architecture
< NV_ARCH_10
) {
1311 if((pNv
->Chipset
& 0x0fff) == 0x0020) {
1312 pNv
->PRAMIN
[0x0824] |= 0x00020000;
1313 pNv
->PRAMIN
[0x0826] += (IPTR
)pNv
->FbAddress
;
1315 pNv
->PGRAPH
[0x0080/4] = 0x000001FF;
1316 pNv
->PGRAPH
[0x0080/4] = 0x1230C000;
1317 pNv
->PGRAPH
[0x0084/4] = 0x72111101;
1318 pNv
->PGRAPH
[0x0088/4] = 0x11D5F071;
1319 pNv
->PGRAPH
[0x008C/4] = 0x0004FF31; /* stegerg: strange but that's so in xfree nv driver sources */
1320 pNv
->PGRAPH
[0x008C/4] = 0x4004FF31; /* stegerg: strange but that's so in xfree nv driver sources */
1322 pNv
->PGRAPH
[0x0140/4] = 0x00000000;
1323 pNv
->PGRAPH
[0x0100/4] = 0xFFFFFFFF;
1324 pNv
->PGRAPH
[0x0170/4] = 0x10010100;
1325 pNv
->PGRAPH
[0x0710/4] = 0xFFFFFFFF;
1326 pNv
->PGRAPH
[0x0720/4] = 0x00000001;
1328 pNv
->PGRAPH
[0x0810/4] = 0x00000000;
1329 pNv
->PGRAPH
[0x0608/4] = 0xFFFFFFFF;
1331 pNv
->PGRAPH
[0x0080/4] = 0xFFFFFFFF;
1332 pNv
->PGRAPH
[0x0080/4] = 0x00000000;
1334 pNv
->PGRAPH
[0x0140/4] = 0x00000000;
1335 pNv
->PGRAPH
[0x0100/4] = 0xFFFFFFFF;
1336 pNv
->PGRAPH
[0x0144/4] = 0x10010100;
1337 pNv
->PGRAPH
[0x0714/4] = 0xFFFFFFFF;
1338 pNv
->PGRAPH
[0x0720/4] = 0x00000001;
1339 pNv
->PGRAPH
[0x0710/4] &= 0x0007ff00;
1340 pNv
->PGRAPH
[0x0710/4] |= 0x00020100;
1342 if(pNv
->Architecture
== NV_ARCH_10
) {
1343 pNv
->PGRAPH
[0x0084/4] = 0x00118700;
1344 pNv
->PGRAPH
[0x0088/4] = 0x24E00810;
1345 pNv
->PGRAPH
[0x008C/4] = 0x55DE0030;
1347 for(i
= 0; i
< 32; i
++)
1348 pNv
->PGRAPH
[(0x0B00/4) + i
] = pNv
->PFB
[(0x0240/4) + i
];
1350 pNv
->PGRAPH
[0x640/4] = 0;
1351 pNv
->PGRAPH
[0x644/4] = 0;
1352 pNv
->PGRAPH
[0x684/4] = pNv
->FrameBufferSize
- 1;
1353 pNv
->PGRAPH
[0x688/4] = pNv
->FrameBufferSize
- 1;
1355 pNv
->PGRAPH
[0x0810/4] = 0x00000000;
1356 pNv
->PGRAPH
[0x0608/4] = 0xFFFFFFFF;
1358 if(pNv
->Architecture
>= NV_ARCH_40
) {
1359 pNv
->PGRAPH
[0x0084/4] = 0x401287c0;
1360 pNv
->PGRAPH
[0x008C/4] = 0x60de8051;
1361 pNv
->PGRAPH
[0x0090/4] = 0x00008000;
1362 pNv
->PGRAPH
[0x0610/4] = 0x00be3c5f;
1364 if((pNv
->Chipset
& 0xfff0) == 0x0040) {
1365 pNv
->PGRAPH
[0x09b0/4] = 0x83280fff;
1366 pNv
->PGRAPH
[0x09b4/4] = 0x000000a0;
1368 pNv
->PGRAPH
[0x0820/4] = 0x83280eff;
1369 pNv
->PGRAPH
[0x0824/4] = 0x000000a0;
1372 switch(pNv
->Chipset
& 0xfff0) {
1374 pNv
->PGRAPH
[0x09b8/4] = 0x0078e366;
1375 pNv
->PGRAPH
[0x09bc/4] = 0x0000014c;
1376 pNv
->PFB
[0x033C/4] &= 0xffff7fff;
1379 pNv
->PGRAPH
[0x0828/4] = 0x007596ff;
1380 pNv
->PGRAPH
[0x082C/4] = 0x00000108;
1383 pNv
->PMC
[0x1700/4] = pNv
->PFB
[0x020C/4];
1384 pNv
->PMC
[0x1704/4] = 0;
1385 pNv
->PMC
[0x1708/4] = 0;
1386 pNv
->PMC
[0x170C/4] = pNv
->PFB
[0x020C/4];
1387 pNv
->PGRAPH
[0x0860/4] = 0;
1388 pNv
->PGRAPH
[0x0864/4] = 0;
1389 pNv
->PRAMDAC
[0x0608/4] |= 0x00100000;
1392 pNv
->PGRAPH
[0x0828/4] = 0x0072cb77;
1393 pNv
->PGRAPH
[0x082C/4] = 0x00000108;
1399 pNv
->PGRAPH
[0x0b38/4] = 0x2ffff800;
1400 pNv
->PGRAPH
[0x0b3c/4] = 0x00006000;
1401 pNv
->PGRAPH
[0x032C/4] = 0x01000000;
1402 pNv
->PGRAPH
[0x0220/4] = 0x00001200;
1404 if(pNv
->Architecture
== NV_ARCH_30
) {
1405 pNv
->PGRAPH
[0x0084/4] = 0x40108700;
1406 pNv
->PGRAPH
[0x0890/4] = 0x00140000;
1407 pNv
->PGRAPH
[0x008C/4] = 0xf00e0431;
1408 pNv
->PGRAPH
[0x0090/4] = 0x00008000;
1409 pNv
->PGRAPH
[0x0610/4] = 0xf04b1f36;
1410 pNv
->PGRAPH
[0x0B80/4] = 0x1002d888;
1411 pNv
->PGRAPH
[0x0B88/4] = 0x62ff007f;
1413 pNv
->PGRAPH
[0x0084/4] = 0x00118700;
1414 pNv
->PGRAPH
[0x008C/4] = 0xF20E0431;
1415 pNv
->PGRAPH
[0x0090/4] = 0x00000000;
1416 pNv
->PGRAPH
[0x009C/4] = 0x00000040;
1418 if((pNv
->Chipset
& 0x0ff0) >= 0x0250) {
1419 pNv
->PGRAPH
[0x0890/4] = 0x00080000;
1420 pNv
->PGRAPH
[0x0610/4] = 0x304B1FB6;
1421 pNv
->PGRAPH
[0x0B80/4] = 0x18B82880;
1422 pNv
->PGRAPH
[0x0B84/4] = 0x44000000;
1423 pNv
->PGRAPH
[0x0098/4] = 0x40000080;
1424 pNv
->PGRAPH
[0x0B88/4] = 0x000000ff;
1426 pNv
->PGRAPH
[0x0880/4] = 0x00080000;
1427 pNv
->PGRAPH
[0x0094/4] = 0x00000005;
1428 pNv
->PGRAPH
[0x0B80/4] = 0x45CAA208;
1429 pNv
->PGRAPH
[0x0B84/4] = 0x24000000;
1430 pNv
->PGRAPH
[0x0098/4] = 0x00000040;
1431 pNv
->PGRAPH
[0x0750/4] = 0x00E00038;
1432 pNv
->PGRAPH
[0x0754/4] = 0x00000030;
1433 pNv
->PGRAPH
[0x0750/4] = 0x00E10038;
1434 pNv
->PGRAPH
[0x0754/4] = 0x00000030;
1438 for(i
= 0; i
< 32; i
++)
1439 pNv
->PGRAPH
[(0x0900/4) + i
] = pNv
->PFB
[(0x0240/4) + i
];
1441 if(pNv
->Architecture
>= NV_ARCH_40
) {
1442 if((pNv
->Chipset
& 0xfff0) == 0x0040) {
1443 pNv
->PGRAPH
[0x09A4/4] = pNv
->PFB
[0x0200/4];
1444 pNv
->PGRAPH
[0x09A8/4] = pNv
->PFB
[0x0204/4];
1445 pNv
->PGRAPH
[0x69A4/4] = pNv
->PFB
[0x0200/4];
1446 pNv
->PGRAPH
[0x69A8/4] = pNv
->PFB
[0x0204/4];
1448 pNv
->PGRAPH
[0x0820/4] = 0;
1449 pNv
->PGRAPH
[0x0824/4] = 0;
1450 pNv
->PGRAPH
[0x0864/4] = pNv
->FrameBufferSize
- 1;
1451 pNv
->PGRAPH
[0x0868/4] = pNv
->FrameBufferSize
- 1;
1453 pNv
->PGRAPH
[0x09F0/4] = pNv
->PFB
[0x0200/4];
1454 pNv
->PGRAPH
[0x09F4/4] = pNv
->PFB
[0x0204/4];
1455 pNv
->PGRAPH
[0x69F0/4] = pNv
->PFB
[0x0200/4];
1456 pNv
->PGRAPH
[0x69F4/4] = pNv
->PFB
[0x0204/4];
1458 pNv
->PGRAPH
[0x0840/4] = 0;
1459 pNv
->PGRAPH
[0x0844/4] = 0;
1460 pNv
->PGRAPH
[0x08a0/4] = pNv
->FrameBufferSize
- 1;
1461 pNv
->PGRAPH
[0x08a4/4] = pNv
->FrameBufferSize
- 1;
1464 pNv
->PGRAPH
[0x09A4/4] = pNv
->PFB
[0x0200/4];
1465 pNv
->PGRAPH
[0x09A8/4] = pNv
->PFB
[0x0204/4];
1466 pNv
->PGRAPH
[0x0750/4] = 0x00EA0000;
1467 pNv
->PGRAPH
[0x0754/4] = pNv
->PFB
[0x0200/4];
1468 pNv
->PGRAPH
[0x0750/4] = 0x00EA0004;
1469 pNv
->PGRAPH
[0x0754/4] = pNv
->PFB
[0x0204/4];
1471 pNv
->PGRAPH
[0x0820/4] = 0;
1472 pNv
->PGRAPH
[0x0824/4] = 0;
1473 pNv
->PGRAPH
[0x0864/4] = pNv
->FrameBufferSize
- 1;
1474 pNv
->PGRAPH
[0x0868/4] = pNv
->FrameBufferSize
- 1;
1477 pNv
->PGRAPH
[0x0B20/4] = 0x00000000;
1478 pNv
->PGRAPH
[0x0B04/4] = 0xFFFFFFFF;
1481 pNv
->PGRAPH
[0x053C/4] = 0;
1482 pNv
->PGRAPH
[0x0540/4] = 0;
1483 pNv
->PGRAPH
[0x0544/4] = 0x00007FFF;
1484 pNv
->PGRAPH
[0x0548/4] = 0x00007FFF;
1486 pNv
->PFIFO
[0x0140] = 0x00000000;
1487 pNv
->PFIFO
[0x0141] = 0x00000001;
1488 pNv
->PFIFO
[0x0480] = 0x00000000;
1489 pNv
->PFIFO
[0x0494] = 0x00000000;
1490 if(pNv
->Architecture
>= NV_ARCH_40
)
1491 pNv
->PFIFO
[0x0481] = 0x00010000;
1493 pNv
->PFIFO
[0x0481] = 0x00000100;
1494 pNv
->PFIFO
[0x0490] = 0x00000000;
1495 pNv
->PFIFO
[0x0491] = 0x00000000;
1496 if(pNv
->Architecture
>= NV_ARCH_40
)
1497 pNv
->PFIFO
[0x048B] = 0x00001213;
1499 pNv
->PFIFO
[0x048B] = 0x00001209;
1500 pNv
->PFIFO
[0x0400] = 0x00000000;
1501 pNv
->PFIFO
[0x0414] = 0x00000000;
1502 pNv
->PFIFO
[0x0084] = 0x03000100;
1503 pNv
->PFIFO
[0x0085] = 0x00000110;
1504 pNv
->PFIFO
[0x0086] = 0x00000112;
1505 pNv
->PFIFO
[0x0143] = 0x0000FFFF;
1506 pNv
->PFIFO
[0x0496] = 0x0000FFFF;
1507 pNv
->PFIFO
[0x0050] = 0x00000000;
1508 pNv
->PFIFO
[0x0040] = 0xFFFFFFFF;
1509 pNv
->PFIFO
[0x0415] = 0x00000001;
1510 pNv
->PFIFO
[0x048C] = 0x00000000;
1511 pNv
->PFIFO
[0x04A0] = 0x00000000;
1513 pNv
->PFIFO
[0x0489] = 0x800F0078;
1515 pNv
->PFIFO
[0x0489] = 0x000F0078;
1517 pNv
->PFIFO
[0x0488] = 0x00000001;
1518 pNv
->PFIFO
[0x0480] = 0x00000001;
1519 pNv
->PFIFO
[0x0494] = 0x00000001;
1520 pNv
->PFIFO
[0x0495] = 0x00000001;
1521 pNv
->PFIFO
[0x0140] = 0x00000001;
1523 if(pNv
->Architecture
>= NV_ARCH_10
) {
1525 pNv
->PCRTC0
[0x0860/4] = state
->head
;
1526 pNv
->PCRTC0
[0x2860/4] = state
->head2
;
1528 pNv
->PRAMDAC
[0x0404/4] |= (1 << 25);
1530 pNv
->PMC
[0x8704/4] = 1;
1531 pNv
->PMC
[0x8140/4] = 0;
1532 pNv
->PMC
[0x8920/4] = 0;
1533 pNv
->PMC
[0x8924/4] = 0;
1534 pNv
->PMC
[0x8908/4] = pNv
->FrameBufferSize
- 1;
1535 pNv
->PMC
[0x890C/4] = pNv
->FrameBufferSize
- 1;
1536 pNv
->PMC
[0x1588/4] = 0;
1538 pNv
->PCRTC
[0x0810/4] = state
->cursorConfig
;
1539 pNv
->PCRTC
[0x0830/4] = state
->displayV
- 3;
1540 pNv
->PCRTC
[0x0834/4] = state
->displayV
- 1;
1542 if(pNv
->FlatPanel
) {
1543 if((pNv
->Chipset
& 0x0ff0) == 0x0110) {
1544 pNv
->PRAMDAC
[0x0528/4] = state
->dither
;
1547 pNv
->PRAMDAC
[0x083C/4] = state
->dither
;
1550 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x53);
1551 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->timingH
);
1552 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x54);
1553 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->timingV
);
1554 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x21);
1555 VGA_WR08(pNv
->PCIO
, 0x03D5, 0xfa);
1558 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x41);
1559 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->extra
);
1562 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x19);
1563 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->repaint0
);
1564 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1A);
1565 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->repaint1
);
1566 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x25);
1567 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->screen
);
1568 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x28);
1569 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->pixel
);
1570 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2D);
1571 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->horiz
);
1572 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1C);
1573 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->fifo
);
1574 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1B);
1575 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->arbitration0
);
1576 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x20);
1577 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->arbitration1
);
1578 if(pNv
->Architecture
>= NV_ARCH_30
) {
1579 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x47);
1580 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->arbitration1
>> 8);
1582 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x30);
1583 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->cursor0
);
1584 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x31);
1585 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->cursor1
);
1586 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2F);
1587 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->cursor2
);
1588 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x39);
1589 VGA_WR08(pNv
->PCIO
, 0x03D5, state
->interlace
);
1591 if(!pNv
->FlatPanel
) {
1592 pNv
->PRAMDAC0
[0x050C/4] = state
->pllsel
;
1593 pNv
->PRAMDAC0
[0x0508/4] = state
->vpll
;
1595 pNv
->PRAMDAC0
[0x0520/4] = state
->vpll2
;
1596 if(pNv
->twoStagePLL
) {
1597 pNv
->PRAMDAC0
[0x0578/4] = state
->vpllB
;
1598 pNv
->PRAMDAC0
[0x057C/4] = state
->vpll2B
;
1601 pNv
->PRAMDAC
[0x0848/4] = state
->scale
;
1604 /* begin flat panel hacks */
1605 /* This is unfortunate, but some chips need this register
1606 tweaked or else you get artifacts where adjacent pixels are
1607 swapped. There are no hard rules for what to set here so all
1608 we can do is experiment and apply hacks. */
1610 if(((pNv
->Chipset
& 0xffff) == 0x0328) && (state
->bpp
== 32)) {
1611 /* At least one NV34 laptop needs this workaround. */
1612 pNv
->PRAMDAC
[0x0828/4] &= ~1;
1615 if((pNv
->Chipset
& 0xfff0) == 0x0310) {
1616 pNv
->PRAMDAC
[0x0828/4] |= 1;
1619 /* end flat panel hacks */
1621 pNv
->PRAMDAC
[0x0600/4] = state
->general
;
1623 pNv
->PCRTC
[0x0140/4] = 0;
1624 pNv
->PCRTC
[0x0100/4] = 1;
1626 pNv
->CurrentState
= state
;
1630 ** stegerg: Status NVUnloadStateExt(): should "match" xfree nv NVUnloadStateExt()
1631 ** in xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c version:
1632 ** 1.12 2004/11/30 23:50:26 mvojkovi
1635 void NVUnloadStateExt
1638 RIVA_HW_STATE
*state
1641 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x19);
1642 state
->repaint0
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1643 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1A);
1644 state
->repaint1
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1645 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x25);
1646 state
->screen
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1647 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x28);
1648 state
->pixel
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1649 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2D);
1650 state
->horiz
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1651 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1C);
1652 state
->fifo
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1653 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x1B);
1654 state
->arbitration0
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1655 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x20);
1656 state
->arbitration1
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1657 if(pNv
->Architecture
>= NV_ARCH_30
) {
1658 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x47);
1659 state
->arbitration1
|= (VGA_RD08(pNv
->PCIO
, 0x03D5) & 1) << 8;
1661 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x30);
1662 state
->cursor0
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1663 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x31);
1664 state
->cursor1
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1665 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x2F);
1666 state
->cursor2
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1667 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x39);
1668 state
->interlace
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1669 state
->vpll
= pNv
->PRAMDAC0
[0x0508/4];
1671 state
->vpll2
= pNv
->PRAMDAC0
[0x0520/4];
1672 if(pNv
->twoStagePLL
) {
1673 state
->vpllB
= pNv
->PRAMDAC0
[0x0578/4];
1674 state
->vpll2B
= pNv
->PRAMDAC0
[0x057C/4];
1676 state
->pllsel
= pNv
->PRAMDAC0
[0x050C/4];
1677 state
->general
= pNv
->PRAMDAC
[0x0600/4];
1678 state
->scale
= pNv
->PRAMDAC
[0x0848/4];
1679 state
->config
= pNv
->PFB
[0x0200/4];
1681 if(pNv
->Architecture
>= NV_ARCH_10
) {
1683 state
->head
= pNv
->PCRTC0
[0x0860/4];
1684 state
->head2
= pNv
->PCRTC0
[0x2860/4];
1685 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x44);
1686 state
->crtcOwner
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1688 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x41);
1689 state
->extra
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1690 state
->cursorConfig
= pNv
->PCRTC
[0x0810/4];
1692 if((pNv
->Chipset
& 0x0ff0) == 0x0110) {
1693 state
->dither
= pNv
->PRAMDAC
[0x0528/4];
1696 state
->dither
= pNv
->PRAMDAC
[0x083C/4];
1699 if(pNv
->FlatPanel
) {
1700 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x53);
1701 state
->timingH
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1702 VGA_WR08(pNv
->PCIO
, 0x03D4, 0x54);
1703 state
->timingV
= VGA_RD08(pNv
->PCIO
, 0x03D5);
1708 void NVSetStartAddress (
1713 pNv
->PCRTC
[0x800/4] = start
;
1722 VGA_WR08(pNv
->PDIO
, 0x3c6, 0xff);
1723 VGA_WR08(pNv
->PDIO
, 0x3c8, 0);
1724 for (i
=0; i
< 768; i
++)
1725 VGA_WR08(pNv
->PDIO
, 0x3c9, pNv
->CurrentState
->Regs
.dac
[i
]);
1728 static void InitBaseRegs(struct staticdata
*sd
, struct CardState
*card
, Sync
*mode
)
1730 /* Determine sync polarity */
1731 if (mode
->VDisplay
< 400)
1732 card
->Regs
.misc
= 0xa3;
1733 else if (mode
->VDisplay
< 480)
1734 card
->Regs
.misc
= 0x63;
1735 else if (mode
->VDisplay
< 768)
1736 card
->Regs
.misc
= 0xe3;
1738 card
->Regs
.misc
= 0x23;
1740 card
->Regs
.seq
[0] = 0x03;
1741 card
->Regs
.seq
[1] = 0x01;
1742 card
->Regs
.seq
[2] = 0x0f;
1743 card
->Regs
.seq
[3] = 0x00;
1744 card
->Regs
.seq
[4] = 0x0e;
1746 card
->Regs
.crtc
[8] = 0;
1747 card
->Regs
.crtc
[10] = 0; //0x20;
1748 card
->Regs
.crtc
[14] = 0;
1749 card
->Regs
.crtc
[17] = (mode
->VSyncEnd
& 0x0f) | 0x20;
1750 card
->Regs
.crtc
[18] = (mode
->VDisplay
- 1) & 0xff;
1751 card
->Regs
.crtc
[19] = card
->width
>> 4;
1752 card
->Regs
.crtc
[20] = 0;
1753 card
->Regs
.crtc
[21] = (mode
->VSyncStart
- 1) & 0xff;
1754 card
->Regs
.crtc
[22] = (mode
->VSyncEnd
- 1) & 0xff;
1755 card
->Regs
.crtc
[23] = 0xc3; // 0xc3
1756 card
->Regs
.crtc
[24] = 0xff;
1757 card
->Regs
.crtc
[40] = 0x40;
1759 card
->Regs
.gra
[0] = 0x00;
1760 card
->Regs
.gra
[1] = 0x00;
1761 card
->Regs
.gra
[2] = 0x00;
1762 card
->Regs
.gra
[3] = 0x00;
1763 card
->Regs
.gra
[4] = 0x00;
1764 card
->Regs
.gra
[5] = 0x40;
1765 card
->Regs
.gra
[6] = 0x05;
1766 card
->Regs
.gra
[7] = 0x0f;
1767 card
->Regs
.gra
[8] = 0xff;
1769 card
->Regs
.attr
[0] = 0x00;
1770 card
->Regs
.attr
[1] = 0x01;
1771 card
->Regs
.attr
[2] = 0x02;
1772 card
->Regs
.attr
[3] = 0x03;
1773 card
->Regs
.attr
[4] = 0x04;
1774 card
->Regs
.attr
[5] = 0x05;
1775 card
->Regs
.attr
[6] = 0x06;
1776 card
->Regs
.attr
[7] = 0x07;
1777 card
->Regs
.attr
[8] = 0x08;
1778 card
->Regs
.attr
[9] = 0x09;
1779 card
->Regs
.attr
[10] = 0x0a;
1780 card
->Regs
.attr
[11] = 0x0b;
1781 card
->Regs
.attr
[12] = 0x0c;
1782 card
->Regs
.attr
[13] = 0x0d;
1783 card
->Regs
.attr
[14] = 0x0e;
1784 card
->Regs
.attr
[15] = 0x0f;
1785 card
->Regs
.attr
[16] = 0x41;
1786 card
->Regs
.attr
[17] = 0x01;
1787 card
->Regs
.attr
[18] = 0x0f;
1788 card
->Regs
.attr
[19] = 0x00;
1789 card
->Regs
.attr
[20] = 0x00;
1792 #define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b))
1793 #define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
1794 #define SetBF(mask,value) ((value) << (0?mask))
1795 #define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
1796 #define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
1797 #define SetBit(n) (1<<(n))
1798 #define Set8Bits(value) ((value)&0xff)
1800 void InitMode(struct staticdata
*sd
, struct CardState
*state
,
1801 ULONG width
, ULONG height
, UBYTE bpp
, ULONG pixelc
, ULONG base
,
1802 ULONG HDisplay
, ULONG VDisplay
,
1803 ULONG HSyncStart
, ULONG HSyncEnd
, ULONG HTotal
,
1804 ULONG VSyncStart
, ULONG VSyncEnd
, ULONG VTotal
)
1806 D(bug("[NVidia] Init %dx%dx%d @%x mode\n", width
, height
, bpp
, base
));
1808 ULONG HBlankStart
, HBlankEnd
, VBlankStart
, VBlankEnd
, OrgHDisplay
= HDisplay
;
1812 HDisplay
, HSyncStart
, HSyncEnd
, HTotal
,
1813 VDisplay
, VSyncStart
, VSyncEnd
, VTotal
1816 InitBaseRegs(sd
, state
, &mode
);
1818 HDisplay
= (HDisplay
>> 3) - 1;
1819 HSyncStart
= (HSyncStart
>> 3) - 1;
1820 HSyncEnd
= (HSyncEnd
>> 3) - 1;
1821 HTotal
= (HTotal
>> 3) - 5;
1822 HBlankStart
= HDisplay
;
1823 HBlankEnd
= HTotal
+ 4;
1829 VBlankStart
= VDisplay
;
1830 VBlankEnd
= VTotal
+ 1;
1833 state
->bitsPerPixel
= 8;
1835 state
->bitsPerPixel
= 16;
1837 state
->bitsPerPixel
= 32;
1839 if (sd
->Card
.FlatPanel
)
1841 VSyncStart
= VTotal
- 3;
1842 VSyncEnd
= VTotal
- 2;
1843 VBlankStart
= VSyncStart
;
1844 HSyncStart
= HTotal
- 5;
1845 HSyncEnd
= HTotal
- 2;
1846 HBlankEnd
= HTotal
+ 4;
1849 state
->Regs
.crtc
[0x00] = Set8Bits(HTotal
);
1850 state
->Regs
.crtc
[0x01] = Set8Bits(HDisplay
);
1851 state
->Regs
.crtc
[0x02] = Set8Bits(HBlankStart
);
1852 state
->Regs
.crtc
[0x03] = SetBitField(HBlankEnd
, 4:0, 4:0) | SetBit(7);
1853 state
->Regs
.crtc
[0x04] = Set8Bits(HSyncStart
);
1854 state
->Regs
.crtc
[0x05] = SetBitField(HBlankEnd
, 5:5, 7:7) |
1855 SetBitField(HSyncEnd
, 4:0, 4:0);
1856 state
->Regs
.crtc
[0x06] = SetBitField(VTotal
, 7:0, 7:0);
1857 state
->Regs
.crtc
[0x07] = SetBitField(VTotal
, 8:8, 0:0) |
1858 SetBitField(VDisplay
, 8:8, 1:1) |
1859 SetBitField(VSyncStart
, 8:8, 2:2) |
1860 SetBitField(VBlankStart
, 8:8, 3:3) |
1862 SetBitField(VTotal
, 9:9, 5:5) |
1863 SetBitField(VDisplay
, 9:9, 6:6) |
1864 SetBitField(VSyncStart
, 9:9, 7:7);
1865 state
->Regs
.crtc
[0x09] = SetBitField(VBlankStart
, 9:9, 5:5) | SetBit(6); // V_DOUBLESCAN?
1866 state
->Regs
.crtc
[0x10] = Set8Bits(VSyncStart
);
1867 state
->Regs
.crtc
[0x11] = SetBitField(VSyncEnd
, 3:0, 3:0) | SetBit(5);
1868 state
->Regs
.crtc
[0x12] = Set8Bits(VDisplay
);
1869 state
->Regs
.crtc
[0x13] = ((width
/ 8) * (state
->bitsPerPixel
/ 8));
1870 state
->Regs
.crtc
[0x15] = Set8Bits(VBlankStart
);
1871 state
->Regs
.crtc
[0x16] = Set8Bits(VBlankEnd
);
1873 state
->Regs
.attr
[0x10] = 0x01;
1876 SetBitField(HBlankEnd
, 6:6, 4:4) |
1877 SetBitField(VBlankStart
, 10:10, 3:3) |
1878 SetBitField(VSyncStart
, 10:10, 2:2) |
1879 SetBitField(VDisplay
, 10:10, 1:1) |
1880 SetBitField(VTotal
, 10:10, 0:0);
1883 SetBitField(HTotal
, 8:8, 0:0) |
1884 SetBitField(HDisplay
, 8:8, 1:1) |
1885 SetBitField(HBlankStart
, 8:8, 2:2) |
1886 SetBitField(HSyncStart
, 8:8, 3:3);
1889 SetBitField(VTotal
, 11:11, 0:0) |
1890 SetBitField(VDisplay
, 11:11, 2:2) |
1891 SetBitField(VSyncStart
, 11:11, 4:4) |
1892 SetBitField(VBlankStart
, 11:11, 6:6);
1894 state
->interlace
= 0xff;
1896 if (bpp
>= 24) bpp
= 32;
1898 if (sd
->Card
.Architecture
>= NV_ARCH_10
)
1899 sd
->Card
.CURSOR
= (ULONG
*)(sd
->Card
.FrameBuffer
+ sd
->Card
.CursorStart
);
1901 // NVLockUnlock(sd, 0);
1902 NVCalcStateExt(sd
, &sd
->Card
, state
, bpp
, width
, OrgHDisplay
, height
, pixelc
, 0);
1904 state
->scale
= sd
->Card
.PRAMDAC
[0x0848/4] & 0xfff000ff;
1905 if (sd
->Card
.FlatPanel
)
1907 state
->pixel
|= (1 << 7);
1908 if (!sd
->Card
.fpScaler
|| (sd
->Card
.fpWidth
<= mode
.HDisplay
)
1909 || (sd
->Card
.fpHeight
<= mode
.VDisplay
))
1911 state
->scale
|= (1 << 8);
1916 state
->cursorConfig
= 0x00000100;
1917 if (sd
->Card
.alphaCursor
)
1919 state
->cursorConfig
|= 0x04011000;
1920 state
->general
|= (1 << 29);
1922 if((sd
->Card
.Chipset
& 0x0ff0) == 0x0110) {
1923 state
->dither
= sd
->Card
.PRAMDAC
[0x0528/4] & ~0x00010000;
1924 if(0) //sd->Card.FPDither)
1925 state
->dither
|= 0x00010000;
1927 state
->cursorConfig
|= (1 << 28);
1929 if((sd
->Card
.Chipset
& 0x0ff0) >= 0x0170) {
1930 state
->dither
= sd
->Card
.PRAMDAC
[0x083C/4] & ~1;
1931 state
->cursorConfig
|= (1 << 28);
1932 if(0) //pNv->FPDither)
1935 state
->cursorConfig
|= (1 << 28);
1938 state
->cursorConfig
|= 0x02000000;
1945 for (i
=0; i
<256; i
++)
1947 state
->Regs
.dac
[i
*3+0] = i
;
1948 state
->Regs
.dac
[i
*3+1] = i
;
1949 state
->Regs
.dac
[i
*3+2] = i
;
1953 state
->offset
= base
;
1954 state
->vpll
= state
->pll
;
1955 state
->vpll2
= state
->pll
;
1956 state
->vpllB
= state
->pllB
;
1957 state
->vpll2B
= state
->pllB
;
1959 VGA_WR08(sd
->Card
.PCIO
, 0x03D4, 0x1C);
1960 state
->fifo
= VGA_RD08(sd
->Card
.PCIO
, 0x03D5) & ~(1<<5);
1962 if(sd
->Card
.CRTCnumber
) {
1963 state
->head
= sd
->Card
.PCRTC0
[0x00000860/4] & ~0x00001000;
1964 state
->head2
= sd
->Card
.PCRTC0
[0x00002860/4] | 0x00001000;
1965 state
->crtcOwner
= 3;
1966 state
->pllsel
|= 0x20000800;
1967 state
->vpll
= sd
->Card
.PRAMDAC0
[0x0508/4];
1968 if(sd
->Card
.twoStagePLL
)
1969 state
->vpllB
= sd
->Card
.PRAMDAC0
[0x0578/4];
1971 if(sd
->Card
.twoHeads
) {
1972 state
->head
= sd
->Card
.PCRTC0
[0x00000860/4] | 0x00001000;
1973 state
->head2
= sd
->Card
.PCRTC0
[0x00002860/4] & ~0x00001000;
1974 state
->crtcOwner
= 0;
1975 state
->vpll2
= sd
->Card
.PRAMDAC0
[0x0520/4];
1976 if(sd
->Card
.twoStagePLL
)
1977 state
->vpll2B
= sd
->Card
.PRAMDAC0
[0x057C/4];
1982 state
->displayV
= VDisplay
;
1985 void acc_reset(struct staticdata
*);
1987 void LoadState(struct staticdata
*sd
, struct CardState
*state
)
1991 ObtainSemaphore(&sd
->HWLock
);
1993 // CRTC_out(sd, 0x11, 0x00);
1995 NVLockUnlock(sd
, 0);
1996 NVLoadStateExt(&sd
->Card
, state
);
1998 MISC_out(sd
, sd
->Card
.CurrentState
->Regs
.misc
);
2000 for (i
=0; i
< 0x05; i
++)
2002 SEQ_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.seq
[i
]);
2005 CRTC_out(sd
, 17, sd
->Card
.CurrentState
->Regs
.crtc
[17] & ~0x80);
2006 for (i
=0; i
< 0x41; i
++)
2014 CRTC_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.crtc
[i
]);
2019 for (i
=0; i
< 0x15; i
++)
2020 ATTR_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.attr
[i
]);
2022 for (i
=0; i
< 0x09; i
++)
2023 GRA_out(sd
, i
, sd
->Card
.CurrentState
->Regs
.gra
[i
]);
2025 NVSetStartAddress(&sd
->Card
, sd
->Card
.CurrentState
->offset
);
2027 sd
->Card
.currentROP
= 0xffffffff;
2028 // VGA_WR08(sd->Card.PVIO, 0x3c3, 1);
2030 NVLoadDAC(&sd
->Card
);
2033 ReleaseSemaphore(&sd
->HWLock
);
2036 void DPMS(struct staticdata
*sd
, HIDDT_DPMSLevel state
)
2040 ObtainSemaphore(&sd
->HWLock
);
2043 reg
= CRTC_in(sd
, 0x1a) & ~0xc0;
2047 case vHidd_Gfx_DPMSLevel_Standby
:
2050 case vHidd_Gfx_DPMSLevel_Suspend
:
2053 case vHidd_Gfx_DPMSLevel_Off
:
2060 CRTC_out(sd
, 0x1a, reg
);
2062 ReleaseSemaphore(&sd
->HWLock
);
2065 void Protect(struct staticdata
*sd
, UBYTE protect
)
2067 ObtainSemaphore(&sd
->HWLock
);
2071 UBYTE tmp
= SEQ_in(sd
, 1);
2073 SEQ_out(sd
, 1, tmp
| 0x20);
2077 UBYTE tmp
= SEQ_in(sd
, 1);
2078 SEQ_out(sd
, 1, tmp
& ~0x20);
2082 ReleaseSemaphore(&sd
->HWLock
);
2085 static const UBYTE ROPTable
[] = {
2086 [vHidd_GC_DrawMode_Clear
] = 0x00,
2087 [vHidd_GC_DrawMode_And
] = 0x88,
2088 [vHidd_GC_DrawMode_AndReverse
] = 0x44,
2089 [vHidd_GC_DrawMode_Copy
] = 0xcc,
2090 [vHidd_GC_DrawMode_AndInverted
] = 0x22,
2091 [vHidd_GC_DrawMode_NoOp
] = 0xaa,
2092 [vHidd_GC_DrawMode_Xor
] = 0x66,
2093 [vHidd_GC_DrawMode_Or
] = 0xee,
2094 [vHidd_GC_DrawMode_Nor
] = 0x11,
2095 [vHidd_GC_DrawMode_Equiv
] = 0x99,
2096 [vHidd_GC_DrawMode_Invert
] = 0x55,
2097 [vHidd_GC_DrawMode_OrReverse
] = 0xdd,
2098 [vHidd_GC_DrawMode_CopyInverted
]= 0x33,
2099 [vHidd_GC_DrawMode_OrInverted
] = 0xbb,
2100 [vHidd_GC_DrawMode_Nand
] = 0x77,
2101 [vHidd_GC_DrawMode_Set
] = 0xff,
2104 void NVDmaKickoff(struct Card
*pNv
)
2106 if(pNv
->dmaCurrent
!= pNv
->dmaPut
) {
2107 pNv
->dmaPut
= pNv
->dmaCurrent
;
2108 WRITE_PUT(pNv
, pNv
->dmaPut
);
2112 /* There is a HW race condition with videoram command buffers.
2113 You can't jump to the location of your put offset. We write put
2114 at the jump offset + SKIPS dwords with noop padding in between
2115 to solve this problem */
2127 while(pNv
->dmaFree
< size
) {
2128 dmaGet
= READ_GET(pNv
);
2130 if(pNv
->dmaPut
>= dmaGet
) {
2131 pNv
->dmaFree
= pNv
->dmaMax
- pNv
->dmaCurrent
;
2132 if(pNv
->dmaFree
< size
) {
2133 NVDmaNext(pNv
, 0x20000000);
2134 if(dmaGet
<= SKIPS
) {
2135 if(pNv
->dmaPut
<= SKIPS
) /* corner case - will be idle */
2136 WRITE_PUT(pNv
, SKIPS
+ 1);
2137 do { dmaGet
= READ_GET(pNv
); }
2138 while(dmaGet
<= SKIPS
);
2140 WRITE_PUT(pNv
, SKIPS
);
2141 pNv
->dmaCurrent
= pNv
->dmaPut
= SKIPS
;
2142 pNv
->dmaFree
= dmaGet
- (SKIPS
+ 1);
2145 pNv
->dmaFree
= dmaGet
- pNv
->dmaCurrent
- 1;
2150 struct staticdata
*sd
,
2157 struct Card
*pNv
= &sd
->Card
;
2159 NVDmaStart(pNv
, PATTERN_COLOR_0
, 4);
2160 NVDmaNext (pNv
, clr0
);
2161 NVDmaNext (pNv
, clr1
);
2162 NVDmaNext (pNv
, pat0
);
2163 NVDmaNext (pNv
, pat1
);
2166 void NVSetRopSolid(struct staticdata
*sd
, ULONG rop
, ULONG planemask
)
2168 struct Card
*pNv
= &sd
->Card
;
2170 if(planemask
!= ~0) {
2171 NVSetPattern(sd
, 0, planemask
, ~0, ~0);
2172 if(pNv
->currentROP
!= (rop
+ 32)) {
2173 NVDmaStart(pNv
, ROP_SET
, 1);
2174 NVDmaNext (pNv
, ROPTable
[rop
]);
2175 pNv
->currentROP
= rop
+ 32;
2178 if (pNv
->currentROP
!= rop
) {
2179 if(pNv
->currentROP
>= 16)
2180 NVSetPattern(sd
, ~0, ~0, ~0, ~0);
2181 NVDmaStart(pNv
, ROP_SET
, 1);
2182 NVDmaNext (pNv
, ROPTable
[rop
]);
2183 pNv
->currentROP
= rop
;
2187 void acc_reset(struct staticdata
*sd
)
2189 struct Card
*pNv
= &sd
->Card
;
2194 pitch
= pNv
->CurrentState
->width
*
2195 (pNv
->CurrentState
->bitsPerPixel
>> 3);
2197 sd
->src_pitch
= pitch
;
2198 sd
->dst_pitch
= pitch
;
2199 sd
->src_offset
= pNv
->CurrentState
->offset
;
2200 sd
->dst_offset
= pNv
->CurrentState
->offset
;
2202 pNv
->dmaBase
= (ULONG
*)(&pNv
->FrameBuffer
[pNv
->FbUsableSize
]);
2204 for(i
= 0; i
< SKIPS
; i
++)
2205 pNv
->dmaBase
[i
] = 0x00000000;
2207 pNv
->dmaBase
[0x0 + SKIPS
] = 0x00040000;
2208 pNv
->dmaBase
[0x1 + SKIPS
] = 0x80000010;
2209 pNv
->dmaBase
[0x2 + SKIPS
] = 0x00042000;
2210 pNv
->dmaBase
[0x3 + SKIPS
] = 0x80000011;
2211 pNv
->dmaBase
[0x4 + SKIPS
] = 0x00044000;
2212 pNv
->dmaBase
[0x5 + SKIPS
] = 0x80000012;
2213 pNv
->dmaBase
[0x6 + SKIPS
] = 0x00046000;
2214 pNv
->dmaBase
[0x7 + SKIPS
] = 0x80000013;
2215 pNv
->dmaBase
[0x8 + SKIPS
] = 0x00048000;
2216 pNv
->dmaBase
[0x9 + SKIPS
] = 0x80000014;
2217 pNv
->dmaBase
[0xA + SKIPS
] = 0x0004A000;
2218 pNv
->dmaBase
[0xB + SKIPS
] = 0x80000015;
2219 pNv
->dmaBase
[0xC + SKIPS
] = 0x0004C000;
2220 pNv
->dmaBase
[0xD + SKIPS
] = 0x80000016;
2221 pNv
->dmaBase
[0xE + SKIPS
] = 0x0004E000;
2222 pNv
->dmaBase
[0xF + SKIPS
] = 0x80000017;
2225 pNv
->dmaCurrent
= 16 + SKIPS
;
2227 pNv
->dmaFree
= pNv
->dmaMax
- pNv
->dmaCurrent
;
2229 switch(pNv
->CurrentState
->bpp
) {
2232 sd
->surface_format
= SURFACE_FORMAT_DEPTH24
;
2233 sd
->pattern_format
= PATTERN_FORMAT_DEPTH24
;
2234 sd
->rect_format
= RECT_FORMAT_DEPTH24
;
2235 sd
->line_format
= LINE_FORMAT_DEPTH24
;
2239 sd
->surface_format
= SURFACE_FORMAT_DEPTH16
;
2240 sd
->pattern_format
= PATTERN_FORMAT_DEPTH16
;
2241 sd
->rect_format
= RECT_FORMAT_DEPTH16
;
2242 sd
->line_format
= LINE_FORMAT_DEPTH16
;
2245 sd
->surface_format
= SURFACE_FORMAT_DEPTH8
;
2246 sd
->pattern_format
= PATTERN_FORMAT_DEPTH8
;
2247 sd
->rect_format
= RECT_FORMAT_DEPTH8
;
2248 sd
->line_format
= LINE_FORMAT_DEPTH8
;
2252 NVDmaStart(pNv
, SURFACE_FORMAT
, 4);
2253 NVDmaNext (pNv
, sd
->surface_format
);
2254 NVDmaNext (pNv
, sd
->dst_pitch
| (sd
->src_pitch
<< 16));
2255 NVDmaNext (pNv
, sd
->src_offset
);
2256 NVDmaNext (pNv
, sd
->dst_offset
);
2258 NVDmaStart(pNv
, PATTERN_FORMAT
, 1);
2259 NVDmaNext (pNv
, sd
->pattern_format
);
2261 NVDmaStart(pNv
, RECT_FORMAT
, 1);
2262 NVDmaNext (pNv
, sd
->rect_format
);
2264 NVDmaStart(pNv
, LINE_FORMAT
, 1);
2265 NVDmaNext (pNv
, sd
->line_format
);
2267 NVSetRopSolid(sd
, vHidd_GC_DrawMode_Copy
, ~0);
2274 void NVSync(struct staticdata
*sd
)
2276 struct Card
*pNv
= &sd
->Card
;
2278 if(pNv
->DMAKickoffCallback
)
2279 (*pNv
->DMAKickoffCallback
)(sd
);
2281 while(READ_GET(pNv
) != pNv
->dmaPut
);
2283 while(pNv
->PGRAPH
[0x0700/4]);
2285 sd
->gpu_busy
= FALSE
;
2288 void NVDMAKickoffCallback(struct staticdata
*sd
)
2290 struct Card
*pNv
= &sd
->Card
;
2293 pNv
->DMAKickoffCallback
= NULL
;
2296 void NVSelectHead(struct staticdata
*sd
, UBYTE head
)
2300 sd
->Card
.PCIO
= sd
->Card
.PCIO0
+ 0x2000;
2301 sd
->Card
.PCRTC
= sd
->Card
.PCRTC0
+ 0x800;
2302 sd
->Card
.PRAMDAC
= sd
->Card
.PRAMDAC0
+ 0x800;
2303 sd
->Card
.PDIO
= sd
->Card
.PDIO0
+ 0x2000;
2307 sd
->Card
.PCIO
= sd
->Card
.PCIO0
;
2308 sd
->Card
.PCRTC
= sd
->Card
.PCRTC0
;
2309 sd
->Card
.PRAMDAC
= sd
->Card
.PRAMDAC0
;
2310 sd
->Card
.PDIO
= sd
->Card
.PDIO0
;
2314 BOOL
NVIsConnected (struct staticdata
*sd
, UBYTE output
)
2316 NVPtr pNv
= &sd
->Card
;
2317 volatile ULONG
*PRAMDAC
= pNv
->PRAMDAC0
;
2318 ULONG reg52C
, reg608
;
2322 if(output
) PRAMDAC
+= 0x800;
2324 reg52C
= PRAMDAC
[0x052C/4];
2325 reg608
= PRAMDAC
[0x0608/4];
2327 PRAMDAC
[0x0608/4] = reg608
& ~0x00010000;
2329 PRAMDAC
[0x052C/4] = reg52C
& 0x0000FEEE;
2332 for (i
=0; i
< 800000000; i
++)
2336 PRAMDAC
[0x052C/4] |= 1;
2338 pNv
->PRAMDAC0
[0x0610/4] = 0x94050140;
2339 pNv
->PRAMDAC0
[0x0608/4] |= 0x00001000;
2342 for (i
=0; i
< 800000000; i
++)
2346 present
= (PRAMDAC
[0x0608/4] & (1 << 28)) ? TRUE
: FALSE
;
2348 pNv
->PRAMDAC0
[0x0608/4] &= 0x0000EFFF;
2350 PRAMDAC
[0x052C/4] = reg52C
;
2351 PRAMDAC
[0x0608/4] = reg608
;