1 /***************************************************************************\
3 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
5 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6 |* international laws. Users and possessors of this source code are *|
7 |* hereby granted a nonexclusive, royalty-free copyright license to *|
8 |* use this code in individual and commercial software. *|
10 |* Any use of this source code must include, in the user documenta- *|
11 |* tion and internal comments to the code, notices to the end user *|
14 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
16 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
28 |* U.S. Government End Users. This source code is a "commercial *|
29 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30 |* consisting of "commercial computer software" and "commercial *|
31 |* computer software documentation," as such terms are used in *|
32 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35 |* all U.S. Government End Users acquire the source code with only *|
36 |* those rights set forth herein. *|
38 \***************************************************************************/
41 * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/
42 * XFree86 'nv' driver, this source code is provided under MIT-style licensing
43 * where the source code is provided "as is" without warranty of any kind.
44 * The only usage restriction is for the copyright notices to be retained
45 * whenever code is used.
47 * Antonino Daplas <adaplas@pol.net> 2005-03-11
56 /* There is a HW race condition with videoram command buffers.
57 You can't jump to the location of your put offset. We write put
58 at the jump offset + SKIPS dwords with noop padding in between
59 to solve this problem */
62 static const int NVCopyROP
[16] = {
67 static const int NVCopyROP_PM
[16] = {
72 static inline void nvidiafb_safe_mode(struct fb_info
*info
)
74 struct nvidia_par
*par
= info
->par
;
76 touch_softlockup_watchdog();
77 info
->pixmap
.scan_align
= 1;
81 static inline void NVFlush(struct fb_info
*info
)
83 struct nvidia_par
*par
= info
->par
;
84 int count
= 1000000000;
86 while (--count
&& READ_GET(par
) != par
->dmaPut
) ;
89 printk("nvidiafb: DMA Flush lockup\n");
90 nvidiafb_safe_mode(info
);
94 static inline void NVSync(struct fb_info
*info
)
96 struct nvidia_par
*par
= info
->par
;
97 int count
= 1000000000;
99 while (--count
&& NV_RD32(par
->PGRAPH
, 0x0700)) ;
102 printk("nvidiafb: DMA Sync lockup\n");
103 nvidiafb_safe_mode(info
);
107 static void NVDmaKickoff(struct nvidia_par
*par
)
109 if (par
->dmaCurrent
!= par
->dmaPut
) {
110 par
->dmaPut
= par
->dmaCurrent
;
111 WRITE_PUT(par
, par
->dmaPut
);
115 static void NVDmaWait(struct fb_info
*info
, int size
)
117 struct nvidia_par
*par
= info
->par
;
119 int count
= 1000000000, cnt
;
122 while (par
->dmaFree
< size
&& --count
&& !par
->lockup
) {
123 dmaGet
= READ_GET(par
);
125 if (par
->dmaPut
>= dmaGet
) {
126 par
->dmaFree
= par
->dmaMax
- par
->dmaCurrent
;
127 if (par
->dmaFree
< size
) {
128 NVDmaNext(par
, 0x20000000);
129 if (dmaGet
<= SKIPS
) {
130 if (par
->dmaPut
<= SKIPS
)
131 WRITE_PUT(par
, SKIPS
+ 1);
134 dmaGet
= READ_GET(par
);
135 } while (--cnt
&& dmaGet
<= SKIPS
);
137 printk("DMA Get lockup\n");
141 WRITE_PUT(par
, SKIPS
);
142 par
->dmaCurrent
= par
->dmaPut
= SKIPS
;
143 par
->dmaFree
= dmaGet
- (SKIPS
+ 1);
146 par
->dmaFree
= dmaGet
- par
->dmaCurrent
- 1;
150 printk("nvidiafb: DMA Wait Lockup\n");
151 nvidiafb_safe_mode(info
);
155 static void NVSetPattern(struct fb_info
*info
, u32 clr0
, u32 clr1
,
158 struct nvidia_par
*par
= info
->par
;
160 NVDmaStart(info
, par
, PATTERN_COLOR_0
, 4);
161 NVDmaNext(par
, clr0
);
162 NVDmaNext(par
, clr1
);
163 NVDmaNext(par
, pat0
);
164 NVDmaNext(par
, pat1
);
167 static void NVSetRopSolid(struct fb_info
*info
, u32 rop
, u32 planemask
)
169 struct nvidia_par
*par
= info
->par
;
171 if (planemask
!= ~0) {
172 NVSetPattern(info
, 0, planemask
, ~0, ~0);
173 if (par
->currentRop
!= (rop
+ 32)) {
174 NVDmaStart(info
, par
, ROP_SET
, 1);
175 NVDmaNext(par
, NVCopyROP_PM
[rop
]);
176 par
->currentRop
= rop
+ 32;
178 } else if (par
->currentRop
!= rop
) {
179 if (par
->currentRop
>= 16)
180 NVSetPattern(info
, ~0, ~0, ~0, ~0);
181 NVDmaStart(info
, par
, ROP_SET
, 1);
182 NVDmaNext(par
, NVCopyROP
[rop
]);
183 par
->currentRop
= rop
;
187 static void NVSetClippingRectangle(struct fb_info
*info
, int x1
, int y1
,
190 struct nvidia_par
*par
= info
->par
;
194 NVDmaStart(info
, par
, CLIP_POINT
, 2);
195 NVDmaNext(par
, (y1
<< 16) | x1
);
196 NVDmaNext(par
, (h
<< 16) | w
);
199 void NVResetGraphics(struct fb_info
*info
)
201 struct nvidia_par
*par
= info
->par
;
202 u32 surfaceFormat
, patternFormat
, rectFormat
, lineFormat
;
205 pitch
= info
->fix
.line_length
;
207 par
->dmaBase
= (u32 __iomem
*) (&par
->FbStart
[par
->FbUsableSize
]);
209 for (i
= 0; i
< SKIPS
; i
++)
210 NV_WR32(&par
->dmaBase
[i
], 0, 0x00000000);
212 NV_WR32(&par
->dmaBase
[0x0 + SKIPS
], 0, 0x00040000);
213 NV_WR32(&par
->dmaBase
[0x1 + SKIPS
], 0, 0x80000010);
214 NV_WR32(&par
->dmaBase
[0x2 + SKIPS
], 0, 0x00042000);
215 NV_WR32(&par
->dmaBase
[0x3 + SKIPS
], 0, 0x80000011);
216 NV_WR32(&par
->dmaBase
[0x4 + SKIPS
], 0, 0x00044000);
217 NV_WR32(&par
->dmaBase
[0x5 + SKIPS
], 0, 0x80000012);
218 NV_WR32(&par
->dmaBase
[0x6 + SKIPS
], 0, 0x00046000);
219 NV_WR32(&par
->dmaBase
[0x7 + SKIPS
], 0, 0x80000013);
220 NV_WR32(&par
->dmaBase
[0x8 + SKIPS
], 0, 0x00048000);
221 NV_WR32(&par
->dmaBase
[0x9 + SKIPS
], 0, 0x80000014);
222 NV_WR32(&par
->dmaBase
[0xA + SKIPS
], 0, 0x0004A000);
223 NV_WR32(&par
->dmaBase
[0xB + SKIPS
], 0, 0x80000015);
224 NV_WR32(&par
->dmaBase
[0xC + SKIPS
], 0, 0x0004C000);
225 NV_WR32(&par
->dmaBase
[0xD + SKIPS
], 0, 0x80000016);
226 NV_WR32(&par
->dmaBase
[0xE + SKIPS
], 0, 0x0004E000);
227 NV_WR32(&par
->dmaBase
[0xF + SKIPS
], 0, 0x80000017);
230 par
->dmaCurrent
= 16 + SKIPS
;
232 par
->dmaFree
= par
->dmaMax
- par
->dmaCurrent
;
234 switch (info
->var
.bits_per_pixel
) {
237 surfaceFormat
= SURFACE_FORMAT_DEPTH24
;
238 patternFormat
= PATTERN_FORMAT_DEPTH24
;
239 rectFormat
= RECT_FORMAT_DEPTH24
;
240 lineFormat
= LINE_FORMAT_DEPTH24
;
243 surfaceFormat
= SURFACE_FORMAT_DEPTH16
;
244 patternFormat
= PATTERN_FORMAT_DEPTH16
;
245 rectFormat
= RECT_FORMAT_DEPTH16
;
246 lineFormat
= LINE_FORMAT_DEPTH16
;
249 surfaceFormat
= SURFACE_FORMAT_DEPTH8
;
250 patternFormat
= PATTERN_FORMAT_DEPTH8
;
251 rectFormat
= RECT_FORMAT_DEPTH8
;
252 lineFormat
= LINE_FORMAT_DEPTH8
;
256 NVDmaStart(info
, par
, SURFACE_FORMAT
, 4);
257 NVDmaNext(par
, surfaceFormat
);
258 NVDmaNext(par
, pitch
| (pitch
<< 16));
262 NVDmaStart(info
, par
, PATTERN_FORMAT
, 1);
263 NVDmaNext(par
, patternFormat
);
265 NVDmaStart(info
, par
, RECT_FORMAT
, 1);
266 NVDmaNext(par
, rectFormat
);
268 NVDmaStart(info
, par
, LINE_FORMAT
, 1);
269 NVDmaNext(par
, lineFormat
);
271 par
->currentRop
= ~0; /* set to something invalid */
272 NVSetRopSolid(info
, ROP_COPY
, ~0);
274 NVSetClippingRectangle(info
, 0, 0, info
->var
.xres_virtual
,
275 info
->var
.yres_virtual
);
280 int nvidiafb_sync(struct fb_info
*info
)
282 struct nvidia_par
*par
= info
->par
;
284 if (info
->state
!= FBINFO_STATE_RUNNING
)
296 void nvidiafb_copyarea(struct fb_info
*info
, const struct fb_copyarea
*region
)
298 struct nvidia_par
*par
= info
->par
;
300 if (info
->state
!= FBINFO_STATE_RUNNING
)
304 return cfb_copyarea(info
, region
);
306 NVDmaStart(info
, par
, BLIT_POINT_SRC
, 3);
307 NVDmaNext(par
, (region
->sy
<< 16) | region
->sx
);
308 NVDmaNext(par
, (region
->dy
<< 16) | region
->dx
);
309 NVDmaNext(par
, (region
->height
<< 16) | region
->width
);
314 void nvidiafb_fillrect(struct fb_info
*info
, const struct fb_fillrect
*rect
)
316 struct nvidia_par
*par
= info
->par
;
319 if (info
->state
!= FBINFO_STATE_RUNNING
)
323 return cfb_fillrect(info
, rect
);
325 if (info
->var
.bits_per_pixel
== 8)
328 color
= ((u32
*) info
->pseudo_palette
)[rect
->color
];
330 if (rect
->rop
!= ROP_COPY
)
331 NVSetRopSolid(info
, rect
->rop
, ~0);
333 NVDmaStart(info
, par
, RECT_SOLID_COLOR
, 1);
334 NVDmaNext(par
, color
);
336 NVDmaStart(info
, par
, RECT_SOLID_RECTS(0), 2);
337 NVDmaNext(par
, (rect
->dx
<< 16) | rect
->dy
);
338 NVDmaNext(par
, (rect
->width
<< 16) | rect
->height
);
342 if (rect
->rop
!= ROP_COPY
)
343 NVSetRopSolid(info
, ROP_COPY
, ~0);
346 static void nvidiafb_mono_color_expand(struct fb_info
*info
,
347 const struct fb_image
*image
)
349 struct nvidia_par
*par
= info
->par
;
350 u32 fg
, bg
, mask
= ~(~0 >> (32 - info
->var
.bits_per_pixel
));
351 u32 dsize
, width
, *data
= (u32
*) image
->data
, tmp
;
354 width
= (image
->width
+ 31) & ~31;
355 dsize
= (width
* image
->height
) >> 5;
357 if (info
->var
.bits_per_pixel
== 8) {
358 fg
= image
->fg_color
| mask
;
359 bg
= image
->bg_color
| mask
;
361 fg
= ((u32
*) info
->pseudo_palette
)[image
->fg_color
] | mask
;
362 bg
= ((u32
*) info
->pseudo_palette
)[image
->bg_color
] | mask
;
365 NVDmaStart(info
, par
, RECT_EXPAND_TWO_COLOR_CLIP
, 7);
366 NVDmaNext(par
, (image
->dy
<< 16) | (image
->dx
& 0xffff));
367 NVDmaNext(par
, ((image
->dy
+ image
->height
) << 16) |
368 ((image
->dx
+ image
->width
) & 0xffff));
371 NVDmaNext(par
, (image
->height
<< 16) | width
);
372 NVDmaNext(par
, (image
->height
<< 16) | width
);
373 NVDmaNext(par
, (image
->dy
<< 16) | (image
->dx
& 0xffff));
375 while (dsize
>= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS
) {
376 NVDmaStart(info
, par
, RECT_EXPAND_TWO_COLOR_DATA(0),
377 RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS
);
379 for (j
= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS
; j
--;) {
385 dsize
-= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS
;
389 NVDmaStart(info
, par
, RECT_EXPAND_TWO_COLOR_DATA(0), dsize
);
391 for (j
= dsize
; j
--;) {
401 void nvidiafb_imageblit(struct fb_info
*info
, const struct fb_image
*image
)
403 struct nvidia_par
*par
= info
->par
;
405 if (info
->state
!= FBINFO_STATE_RUNNING
)
408 if (image
->depth
== 1 && !par
->lockup
)
409 nvidiafb_mono_color_expand(info
, image
);
411 cfb_imageblit(info
, image
);