2 * Copyright (c) 2007 NVIDIA, Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include "nv_include.h"
33 void NV50CrtcWrite(ScrnInfoPtr pScrn, CARD32 addr, CARD32 value)
35 NVPtr pNv = NVPTR(pScrn);
36 pNv->NV50_PCRTC[addr/4] = value;
39 CARD32 NV50CrtcRead(ScrnInfoPtr pScrn, CARD32 addr)
41 NVPtr pNv = NVPTR(pScrn);
42 return pNv->NV50_PCRTC[addr/4];
45 /* Don't call the directly, only load state should do this on the long run*/
46 void NV50CheckWriteVClk(ScrnInfoPtr pScrn)
48 NVPtr pNv = NVPTR(pScrn);
49 while (NV50CrtcRead(pScrn, 0x300) & 0x80000000) {
50 /* What does is the meaning of this? */
51 const int super = ffs((NV50CrtcRead(pScrn, 0x24) >> 4) & 0x7);
55 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
56 const CARD32 clockvar = NV50CrtcRead(pScrn, 0x30);
59 for(i = 0; i < xf86_config->num_crtc; i++) {
60 xf86CrtcPtr crtc = xf86_config->crtc[i];
61 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
63 if (clockvar & (1 << (9 + nv_crtc->head))) {
64 NV50CrtcSetPClk(crtc);
69 NV50CrtcWrite(pScrn, 0x24, 1 << (3 + super));
70 NV50CrtcWrite(pScrn, 0x30, 0x80000000);
75 void NV50DisplayCommand(ScrnInfoPtr pScrn, CARD32 addr, CARD32 value)
77 NV50CrtcWrite(pScrn, 0x304, value);
78 NV50CrtcWrite(pScrn, 0x300, addr | 0x80010001);
79 NV50CheckWriteVClk(pScrn);
82 void NV50CrtcCommand(xf86CrtcPtr crtc, CARD32 addr, CARD32 value)
84 ScrnInfoPtr pScrn = crtc->scrn;
85 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
86 NVPtr pNv = NVPTR(pScrn);
88 /* This head dependent offset may not be true everywere */
89 NV50DisplayCommand(pScrn, addr + 0x400 * nv_crtc->head, value);
92 void nv50_crtc_dpms_set(xf86CrtcPtr crtc, int mode)
96 static Bool nv50_crtc_lock(xf86CrtcPtr crtc)
101 void nv50_crtc_load_state(xf86CrtcPtr crtc, NV50_HW_STATE *state)
103 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
106 regp = &state->crtc_reg[nv_crtc->head];
109 void nv50_crtc_save_state(xf86CrtcPtr crtc, NV50_HW_STATE *state)
111 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
114 regp = &state->crtc_reg[nv_crtc->head];
117 void nv50_crtc_restore(xf86CrtcPtr crtc)
119 ScrnInfoPtr pScrn = crtc->scrn;
120 NVPtr pNv = NVPTR(pScrn);
122 nv50_crtc_load_state(crtc, &(pNv->NV50ModeReg));
125 void nv50_crtc_save(xf86CrtcPtr crtc)
127 ScrnInfoPtr pScrn = crtc->scrn;
128 NVPtr pNv = NVPTR(pScrn);
130 nv50_crtc_save_state(crtc, &(pNv->NV50SavedReg));
133 static const xf86CrtcFuncsRec nv50_crtc_funcs = {
134 .dpms = nv50_crtc_dpms_set,
135 .save = nv50_crtc_save,
136 .restore = nv50_crtc_restore,
137 .lock = nv50_crtc_lock,
139 .mode_fixup = NV50CrtcModeFixup,
140 .prepare = NV50CrtcPrepare,
141 .mode_set = NV50CrtcModeSet,
142 // .gamma_set = NV50DispGammaSet,
143 .commit = NV50CrtcCommit,
144 .shadow_create = NULL,
145 .shadow_destroy = NULL,
146 .set_cursor_position = NV50SetCursorPosition,
147 .show_cursor = NV50CrtcShowCursor,
148 .hide_cursor = NV50CrtcHideCursor,
149 .load_cursor_argb = NV50LoadCursorARGB,
153 void NV50DispCreateCrtcs(ScrnInfoPtr pScrn)
155 NVPtr pNv = NVPTR(pScrn);
158 NV50CrtcPrivPtr nv50_crtc;
160 /* Create a "crtc" object for each head */
161 for(head = HEAD0; head <= HEAD1; head++) {
162 crtc = xf86CrtcCreate(pScrn, &nv50_crtc_funcs);
165 nv50_crtc = xnfcalloc(sizeof(*nv50_crtc), 1);
166 nv50_crtc->head = head;
167 nv50_crtc->dither = pNv->FPDither;
168 crtc->driver_private = nv50_crtc;
172 #endif /* ENABLE_RANDR12 */