2 * Copyright (c) 2007 NVIDIA, Corporation
3 * Copyright (c) 2008 Maarten Maathuis
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include "nv_include.h"
33 NV50DispPreInit(ScrnInfoPtr pScrn)
35 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DispPreInit is called.\n");
37 NVPtr pNv = NVPTR(pScrn);
39 * I get the strange feeling that the 0x006101XX range is some kind of master modesetting control.
40 * Maybe this what triggers it to be enabled.
42 NVWrite(pNv, 0x00610184, NVRead(pNv, 0x00614004));
44 NVWrite(pNv, 0x00610190 + 0 * 0x10, NVRead(pNv, 0x00616100 + 0 * 0x800));
45 NVWrite(pNv, 0x00610190 + 1 * 0x10, NVRead(pNv, 0x00616100 + 1 * 0x800));
46 NVWrite(pNv, 0x00610194 + 0 * 0x10, NVRead(pNv, 0x00616104 + 0 * 0x800));
47 NVWrite(pNv, 0x00610194 + 1 * 0x10, NVRead(pNv, 0x00616104 + 1 * 0x800));
48 NVWrite(pNv, 0x00610198 + 0 * 0x10, NVRead(pNv, 0x00616108 + 0 * 0x800));
49 NVWrite(pNv, 0x00610198 + 1 * 0x10, NVRead(pNv, 0x00616108 + 1 * 0x800));
50 NVWrite(pNv, 0x0061019c + 0 * 0x10, NVRead(pNv, 0x0061610c + 0 * 0x800));
51 NVWrite(pNv, 0x0061019c + 1 * 0x10, NVRead(pNv, 0x0061610c + 1 * 0x800));
52 NVWrite(pNv, 0x006101d0 + DAC0 * 0x4, NVRead(pNv, 0x0061a000 + DAC0 * 0x800));
53 NVWrite(pNv, 0x006101d0 + DAC1 * 0x4, NVRead(pNv, 0x0061a000 + DAC1 * 0x800));
54 NVWrite(pNv, 0x006101d0 + DAC2 * 0x4, NVRead(pNv, 0x0061a000 + DAC2 * 0x800));
55 NVWrite(pNv, 0x006101e0 + SOR0 * 0x4, NVRead(pNv, 0x0061c000 + SOR0 * 0x800));
56 NVWrite(pNv, 0x006101e0 + SOR1 * 0x4, NVRead(pNv, 0x0061c000 + SOR1 * 0x800));
57 /* Maybe TV-out related, or something more generic? */
58 /* These are not in nv, so it must be something nv does not use. */
59 NVWrite(pNv, 0x006101f0 + 0 * 0x4, NVRead(pNv, 0x0061e000 + 0 * 0x800));
60 NVWrite(pNv, 0x006101f0 + 1 * 0x4, NVRead(pNv, 0x0061e000 + 1 * 0x800));
61 NVWrite(pNv, 0x006101f0 + 2 * 0x4, NVRead(pNv, 0x0061e000 + 2 * 0x800));
62 /* 0x00150000 seems to be the default state on many cards. why the extra bit is needed on some is unknown. */
63 NVWrite(pNv, NV50_DAC0_DPMS_CTRL, 0x00400000 | NV50_DAC_DPMS_CTRL_DEFAULT_STATE | NV50_DAC_DPMS_CTRL_PENDING);
64 NVWrite(pNv, NV50_DAC0_CLK_CTRL1, 0x00000001);
65 NVWrite(pNv, NV50_DAC1_DPMS_CTRL, 0x00400000 | NV50_DAC_DPMS_CTRL_DEFAULT_STATE | NV50_DAC_DPMS_CTRL_PENDING);
66 NVWrite(pNv, NV50_DAC1_CLK_CTRL1, 0x00000001);
67 NVWrite(pNv, NV50_DAC2_DPMS_CTRL, 0x00400000 | NV50_DAC_DPMS_CTRL_DEFAULT_STATE | NV50_DAC_DPMS_CTRL_PENDING);
68 NVWrite(pNv, NV50_DAC2_CLK_CTRL1, 0x00000001);
74 NV50DispInit(ScrnInfoPtr pScrn)
76 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DispInit is called.\n");
78 NVPtr pNv = NVPTR(pScrn);
80 if (NVRead(pNv, NV50_DISPLAY_SUPERVISOR) & 0x100) {
81 NVWrite(pNv, NV50_DISPLAY_SUPERVISOR, 0x100);
82 NVWrite(pNv, 0x006194e8, NVRead(pNv, 0x006194e8) & ~1);
83 while (NVRead(pNv, 0x006194e8) & 2);
86 NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, 0x2b00);
87 /* A bugfix (#12637) from the nv driver, to unlock the driver if it's left in a poor state */
89 val = NVRead(pNv, NV50_DISPLAY_UNK200_CTRL);
90 if ((val & 0x9f0000) == 0x20000)
91 NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, val | 0x800000);
93 if ((val & 0x3f0000) == 0x30000)
94 NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, val | 0x200000);
95 } while ((val & 0x1e0000) != 0);
96 NVWrite(pNv, NV50_DISPLAY_CTRL_STATE, NV50_DISPLAY_CTRL_STATE_ENABLE);
97 NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, 0x1000b03);
98 while (!(NVRead(pNv, NV50_DISPLAY_UNK200_CTRL) & 0x40000000));
100 NV50DisplayCommand(pScrn, NV50_UNK84, 0);
101 NV50DisplayCommand(pScrn, NV50_UNK88, 0);
102 /* The GetLVDSNativeMode() function is proof that more than crtc0 is used by the bios. */
103 NV50DisplayCommand(pScrn, NV50_CRTC0_BLANK_CTRL, NV50_CRTC0_BLANK_CTRL_BLANK);
104 NV50DisplayCommand(pScrn, NV50_CRTC0_UNK800, 0);
105 NV50DisplayCommand(pScrn, NV50_CRTC0_DISPLAY_START, 0);
106 NV50DisplayCommand(pScrn, NV50_CRTC0_UNK82C, 0);
112 NV50DispShutdown(ScrnInfoPtr pScrn)
114 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DispShutdown is called.\n");
115 NVPtr pNv = NVPTR(pScrn);
118 for(i = 0; i < 2; i++) {
119 nouveauCrtcPtr crtc = pNv->crtc[i];
121 crtc->Blank(crtc, TRUE);
124 NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
126 for(i = 0; i < 2; i++) {
127 nouveauCrtcPtr crtc = pNv->crtc[i];
129 /* This is like acknowledging a vblank, maybe this is in the spirit of cleaning up? */
130 /* The blob doesn't do it quite this way, it seems to do 0x30C as init and end. */
131 /* It doesn't wait for a non-zero value either. */
134 if (crtc->index == 1)
135 mask = NV50_DISPLAY_SUPERVISOR_CRTC1;
137 mask = NV50_DISPLAY_SUPERVISOR_CRTC0;
139 NVWrite(pNv, NV50_DISPLAY_SUPERVISOR, mask);
140 while(!(NVRead(pNv, NV50_DISPLAY_SUPERVISOR) & mask));
144 NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, 0x0);
145 NVWrite(pNv, NV50_DISPLAY_CTRL_STATE, NV50_DISPLAY_CTRL_STATE_DISABLE);
146 while ((NVRead(pNv, NV50_DISPLAY_UNK200_CTRL) & 0x1e0000) != 0);
147 while ((NVRead(pNv, NV50_SOR0_DPMS_STATE) & NV50_SOR_DPMS_STATE_WAIT));
148 while ((NVRead(pNv, NV50_SOR1_DPMS_STATE) & NV50_SOR_DPMS_STATE_WAIT));