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.
24 #include "nv_include.h"
26 void NV50DisplayWrite(ScrnInfoPtr pScrn, CARD32 addr, CARD32 value)
28 NVPtr pNv = NVPTR(pScrn);
29 pNv->NV50_PCRTC[addr/4] = value;
32 CARD32 NV50DisplayRead(ScrnInfoPtr pScrn, CARD32 addr)
34 NVPtr pNv = NVPTR(pScrn);
35 return pNv->NV50_PCRTC[addr/4];
38 /* Things related to crtc's seem to come with offsets of 0x800 */
39 void NV50CrtcWrite(xf86CrtcPtr crtc, CARD32 addr, CARD32 value)
41 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
42 ScrnInfoPtr pScrn = crtc->scrn;
43 NV50DisplayWrite(pScrn, addr + nv_crtc->head * 0x800, value);
46 CARD32 NV50CrtcRead(xf86CrtcPtr crtc, CARD32 addr)
48 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
49 ScrnInfoPtr pScrn = crtc->scrn;
50 return NV50DisplayRead(pScrn, addr + nv_crtc->head * 0x800);
53 /* Don't call the directly, only load state should do this on the long run*/
54 void NV50CheckWriteVClk(ScrnInfoPtr pScrn)
56 while (NV50DisplayRead(pScrn, 0x300) & 0x80000000) {
57 /* What does is the meaning of this? */
58 const int super = ffs((NV50DisplayRead(pScrn, 0x24) >> 4) & 0x7);
62 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
63 const CARD32 clockvar = NV50DisplayRead(pScrn, 0x30);
66 for(i = 0; i < xf86_config->num_crtc; i++) {
67 xf86CrtcPtr crtc = xf86_config->crtc[i];
68 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
70 if (clockvar & (1 << (9 + nv_crtc->head))) {
71 NV50CrtcSetPClk(crtc);
76 NV50DisplayWrite(pScrn, 0x24, 1 << (3 + super));
77 NV50DisplayWrite(pScrn, 0x30, 0x80000000);
82 void NV50DisplayCommand(ScrnInfoPtr pScrn, CARD32 addr, CARD32 value)
84 NV50DisplayWrite(pScrn, 0x304, value);
85 NV50DisplayWrite(pScrn, 0x300, addr | 0x80010001);
86 NV50CheckWriteVClk(pScrn);
89 void NV50CrtcCommand(xf86CrtcPtr crtc, CARD32 addr, CARD32 value)
91 ScrnInfoPtr pScrn = crtc->scrn;
92 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
94 /* This head dependent offset may not be true everywere */
95 NV50DisplayCommand(pScrn, addr + 0x400 * nv_crtc->head, value);
98 void nv50_crtc_dpms_set(xf86CrtcPtr crtc, int mode)
102 static Bool nv50_crtc_lock(xf86CrtcPtr crtc)
107 void nv50_crtc_load_state(xf86CrtcPtr crtc, NV50_HW_STATE *state)
109 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
112 regp = &state->crtc_reg[nv_crtc->head];
115 void nv50_crtc_save_state(xf86CrtcPtr crtc, NV50_HW_STATE *state)
117 NV50CrtcPrivPtr nv_crtc = crtc->driver_private;
120 regp = &state->crtc_reg[nv_crtc->head];
123 void nv50_crtc_restore(xf86CrtcPtr crtc)
125 ScrnInfoPtr pScrn = crtc->scrn;
126 NVPtr pNv = NVPTR(pScrn);
128 nv50_crtc_load_state(crtc, &(pNv->NV50ModeReg));
131 void nv50_crtc_save(xf86CrtcPtr crtc)
133 ScrnInfoPtr pScrn = crtc->scrn;
134 NVPtr pNv = NVPTR(pScrn);
136 nv50_crtc_save_state(crtc, &(pNv->NV50SavedReg));
139 static const xf86CrtcFuncsRec nv50_crtc_funcs = {
140 .dpms = nv50_crtc_dpms_set,
141 .save = nv50_crtc_save,
142 .restore = nv50_crtc_restore,
143 .lock = nv50_crtc_lock,
145 .mode_fixup = NV50CrtcModeFixup,
146 .prepare = NV50CrtcPrepare,
147 .mode_set = NV50CrtcModeSet,
148 // .gamma_set = NV50DispGammaSet,
149 .commit = NV50CrtcCommit,
150 .shadow_create = NULL,
151 .shadow_destroy = NULL,
152 .set_cursor_position = NV50SetCursorPosition,
153 .show_cursor = NV50CrtcShowCursor,
154 .hide_cursor = NV50CrtcHideCursor,
155 .load_cursor_argb = NV50LoadCursorARGB,
159 void NV50DispCreateCrtcs(ScrnInfoPtr pScrn)
161 NVPtr pNv = NVPTR(pScrn);
164 NV50CrtcPrivPtr nv50_crtc;
166 /* Create a "crtc" object for each head */
167 for(head = HEAD0; head <= HEAD1; head++) {
168 crtc = xf86CrtcCreate(pScrn, &nv50_crtc_funcs);
171 nv50_crtc = xnfcalloc(sizeof(*nv50_crtc), 1);
172 nv50_crtc->head = head;
173 nv50_crtc->dither = pNv->FPDither;
174 crtc->driver_private = nv50_crtc;