2
* Copyright 2004-2005 The Unichrome Project [unichrome.sf.net]
3
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
4
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the "Software"),
8
* to deal in the Software without restriction, including without limitation
9
* the rights to use, copy, modify, merge, publish, distribute, sub license,
10
* and/or sell copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice (including the
14
* next paragraph) shall be included in all copies or substantial portions
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
* DEALINGS IN THE SOFTWARE.
31
#include "xf86_OSproc.h"
35
#include "via_drmclient.h"
38
#include "via_driver.h"
44
* Warning: this file contains revision checks which are CLE266-specific.
45
* There seems to be no checking present for KM400 or more recent devices.
48
* - pVia->Chipset checking, of course
49
* - move content of pVia->HWDiff into pVia->swov
50
* - merge with CLEXF40040
54
* Old via_regrec code.
56
#define VIDREG_BUFFER_SIZE 100 /* Number of entries in the VidRegBuffer. */
57
#define IN_VIDEO_DISPLAY (*((unsigned long volatile *)(pVia->MapBase + V_FLAGS)) & VBI_STATUS)
58
#define VIA_FIRETIMEOUT 40000
67
/* register offsets for VT3553/VX800 */
68
static const unsigned hqv_cme_regs[] = {
69
[HQV_SDO_CTRL1] = HQV_SRC_DATA_OFFSET_CONTROL1,
70
[HQV_SDO_CTRL2] = HQV_SRC_DATA_OFFSET_CONTROL2,
71
[HQV_SDO_CTRL3] = HQV_SRC_DATA_OFFSET_CONTROL3,
72
[HQV_SDO_CTRL4] = HQV_SRC_DATA_OFFSET_CONTROL4
75
/* register hqv offsets for new VT3409/VX855 */
76
static const unsigned hqv_cme_regs_409[] = {
77
[HQV_SDO_CTRL1] = HQV_SRC_DATA_OFFSET_CTRL1_409,
78
[HQV_SDO_CTRL2] = HQV_SRC_DATA_OFFSET_CTRL2_409,
79
[HQV_SDO_CTRL3] = HQV_SRC_DATA_OFFSET_CTRL3_409,
80
[HQV_SDO_CTRL4] = HQV_SRC_DATA_OFFSET_CTRL4_409
83
#define HQV_CME_REG(HWDiff, name) (HWDiff)->HQVCmeRegs[name]
86
viaWaitVideoCommandFire(VIAPtr pVia)
89
* Uncached PCI reading throughput is about 9 MB/s; so 8 bytes/loop means about
90
* 1M loops/second. We want to time out after 50 ms, which means 50000 loops.
92
unsigned count = 50000;
93
CARD32 volatile *pdwState =
94
(CARD32 volatile *)(pVia->MapBase + V_COMPOSE_MODE);
96
while (--count && ((*pdwState & V1_COMMAND_FIRE)
97
|| (*pdwState & V3_COMMAND_FIRE))) ;
99
ErrorF("viaWaitVideoCommandFire: Timeout.\n");
104
viaWaitHQVFlip(VIAPtr pVia)
106
unsigned long proReg = 0;
107
CARD32 volatile *pdwState;
108
unsigned count = 50000;
110
if (pVia->ChipId == PCI_CHIP_VT3259
111
&& !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
112
proReg = PRO_HQV1_OFFSET;
114
pdwState = (CARD32 volatile *)(pVia->MapBase + (HQV_CONTROL + proReg));
116
if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
117
while (--count && (*pdwState & HQV_SUBPIC_FLIP));
119
while (--count && !(*pdwState & HQV_FLIP_STATUS)) ;
124
viaWaitHQVFlipClear(VIAPtr pVia, unsigned long dwData)
126
CARD32 volatile *pdwState =
127
(CARD32 volatile *)(pVia->MapBase + HQV_CONTROL);
129
unsigned count = 50000;
131
while (--count && (*pdwState & HQV_FLIP_STATUS)) {
132
VIASETREG(HQV_CONTROL, *pdwState | HQV_FLIP_STATUS);
137
viaWaitVBI(VIAPtr pVia)
139
while (IN_VIDEO_DISPLAY) ;
143
viaWaitHQVDone(VIAPtr pVia)
145
CARD32 volatile *pdwState;
146
unsigned long proReg = 0;
147
unsigned count = 50000;
149
if (pVia->ChipId == PCI_CHIP_VT3259
150
&& !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
151
proReg = PRO_HQV1_OFFSET;
153
pdwState = (CARD32 volatile *)(pVia->MapBase + (HQV_CONTROL + proReg));
154
if (pVia->swov.MPEG_ON) {
155
while (--count && (*pdwState & HQV_SW_FLIP)) ;
160
* Send all data in VidRegBuffer to the hardware.
163
FlushVidRegBuffer(VIAPtr pVia)
167
viaWaitVideoCommandFire(pVia);
169
for (i = 0; i < pVia->VidRegCursor; i += 2) {
170
VIASETREG(pVia->VidRegBuffer[i], pVia->VidRegBuffer[i + 1]);
171
DBG_DD(ErrorF("FlushVideoRegs: [%i] %08lx %08lx\n",
172
i >> 1, pVia->VidRegBuffer[i] + 0x200,
173
pVia->VidRegBuffer[i + 1]));
176
/* BUG: (?) VIA never resets the cursor.
177
* My fix is commented out for now, in case they had a reason for that. /A
179
/* pVia->VidRegCursor = 0; */
183
* Initialize and clear VidRegBuffer.
186
ResetVidRegBuffer(VIAPtr pVia)
188
/* BUG: (Memory leak) This allocation may need have a corresponding free somewhere... /A */
189
if (!pVia->VidRegBuffer)
191
xnfcalloc(VIDREG_BUFFER_SIZE, sizeof(CARD32) * 2);
192
pVia->VidRegCursor = 0;
196
* Save a video register and data in VidRegBuffer.
199
SaveVideoRegister(VIAPtr pVia, CARD32 index, CARD32 data)
201
if (pVia->VidRegCursor >= VIDREG_BUFFER_SIZE) {
202
DBG_DD(ErrorF("SaveVideoRegister: Out of video register space flushing"));
203
FlushVidRegBuffer(pVia);
204
ResetVidRegBuffer(pVia);
207
pVia->VidRegBuffer[pVia->VidRegCursor++] = index;
208
pVia->VidRegBuffer[pVia->VidRegCursor++] = data;
212
* HW Difference Flag (moved here from via_hwdiff.c)
214
* These are the entries of HWDiff used in our code (currently):
215
* CLE266Ax CLE266Cx KM400 K8M800 PM800
216
* ThreeHQVBuffer FALSE TRUE TRUE TRUE TRUE
217
* HQVFetchByteUnit FALSE TRUE TRUE TRUE TRUE
218
* SupportTwoColorKey FALSE TRUE FALSE FALSE TRUE
219
* HQVInitPatch TRUE FALSE FALSE FALSE FALSE
220
* HQVDisablePatch FALSE TRUE TRUE TRUE FALSE
222
* This is now up to date with CLEXF40040. All unused entries were removed.
223
* The functions depending on this struct are untouched.
226
VIAVidHWDiffInit(ScrnInfoPtr pScrn)
228
VIAPtr pVia = VIAPTR(pScrn);
229
VIAHWDiff *HWDiff = &pVia->HWDiff;
231
switch (pVia->Chipset) {
233
if (CLE266_REV_IS_AX(pVia->ChipRev)) {
234
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_FALSE;
235
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_FALSE;
236
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE;
237
HWDiff->dwHQVInitPatch = VID_HWDIFF_TRUE;
238
HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
239
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
241
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
242
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
243
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE;
244
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
245
HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
246
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
248
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
251
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
252
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
253
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE;
254
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
255
HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
256
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
257
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
260
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
261
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
262
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE;
263
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
264
HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
265
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
266
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
269
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
270
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
271
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE;
272
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
273
HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
274
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
275
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
276
HWDiff->HQVCmeRegs = hqv_cme_regs;
280
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
281
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
282
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE;
283
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
284
HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
285
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
286
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
287
HWDiff->HQVCmeRegs = hqv_cme_regs;
290
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
291
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
292
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE;
293
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
294
HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
295
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_TRUE;
296
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
297
HWDiff->HQVCmeRegs = hqv_cme_regs;
300
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
301
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
302
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_FALSE;
303
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
304
HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
305
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
306
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
307
HWDiff->HQVCmeRegs = hqv_cme_regs;
310
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
311
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
312
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE;
313
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
314
HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
315
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
316
HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
317
HWDiff->HQVCmeRegs = hqv_cme_regs;
320
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
321
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
322
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE;
323
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
324
HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
325
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
326
HWDiff->dwNewScaleCtl = VID_HWDIFF_TRUE;
327
HWDiff->HQVCmeRegs = hqv_cme_regs;
331
HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
332
HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
333
HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE;
334
HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
335
HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
336
HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
337
HWDiff->dwNewScaleCtl = VID_HWDIFF_TRUE;
338
HWDiff->HQVCmeRegs = hqv_cme_regs_409;
341
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
342
"VIAVidHWDiffInit: Unhandled ChipSet.\n");
347
* Old via_overlay code.
349
typedef struct _YCBCRREC
357
* Verify that using V1 bit definitions on V3
358
* is not broken in OverlayGetV1V3Format().
361
#if V1_COLORSPACE_SIGN != V3_COLORSPACE_SIGN
362
#error "V1_COLORSPACE_SIGN != V3_COLORSPACE_SIGN"
364
#if V1_YUV422 != V3_YUV422
365
#error "V1_YUV422 != V3_YUV422"
367
#if V1_SWAP_HW_HQV != V3_SWAP_HW_HQV
368
#error "V1_SWAP_HW_HQV != V3_SWAP_HW_HQV"
370
#if V1_RGB15 != V3_RGB15
371
#error "V1_RGB15 != V3_RGB15"
373
#if V1_RGB16 != V3_RGB16
374
#error "V1_RGB16 != V3_RGB16"
376
#if V1_RGB32 != V3_RGB32
377
#error "V1_RGB32 != V3_RGB32"
381
viaOverlayGetV1V3Format(VIAPtr pVia, int vport, /* 1 or 3, as in V1 or V3 */
382
unsigned long videoFlag, unsigned long *pVidCtl,
383
unsigned long *pHQVCtl)
385
if (videoFlag & VIDEO_HQV_INUSE) {
386
switch (pVia->swov.SrcFourCC) {
390
*pHQVCtl |= HQV_YUV420;
393
*pHQVCtl |= HQV_YUV422;
396
*pVidCtl |= V1_RGB32;
397
*pHQVCtl |= HQV_RGB32;
400
*pVidCtl |= V1_RGB15;
401
*pHQVCtl |= HQV_RGB15;
404
*pVidCtl |= V1_RGB16;
405
*pHQVCtl |= HQV_RGB16;
408
DBG_DD(ErrorF("viaOverlayGetV1V3Format: "
409
"Invalid FOURCC format (0x%lx).\n",
410
pVia->swov.SrcFourCC));
413
*pVidCtl |= V1_SWAP_HW_HQV;
414
*pHQVCtl |= HQV_SRC_SW | HQV_ENABLE | HQV_SW_FLIP;
416
switch (pVia->swov.SrcFourCC) {
421
*pVidCtl |= V1_YCbCr420;
423
DBG_DD(ErrorF("viaOverlayGetV1V3Format: "
424
"V3 does not support planar YUV.\n"));
429
*pVidCtl |= V1_YUV422;
434
ErrorF("viaOverlayGetV1V3Format: "
435
"Can't display RGB video in this configuration.\n");
438
DBG_DD(ErrorF("viaOverlayGetV1V3Format: "
439
"Invalid FOURCC format (0x%lx).\n",
440
pVia->swov.SrcFourCC));
444
*pVidCtl |= V1_COLORSPACE_SIGN;
449
viaOverlayGetSrcStartAddress(VIAPtr pVia,
450
unsigned long videoFlag,
451
LPDDUPDATEOVERLAY pUpdate,
452
unsigned long srcPitch,
453
unsigned long *pHQVoffset)
455
unsigned long srcWidth =
456
(unsigned long)(pUpdate->SrcRight - pUpdate->SrcLeft);
457
unsigned long dstWidth =
458
(unsigned long)(pUpdate->DstRight - pUpdate->DstLeft);
459
unsigned long srcHeight =
460
(unsigned long)(pUpdate->SrcBottom - pUpdate->SrcTop);
461
unsigned long dstHeight =
462
(unsigned long)(pUpdate->DstBottom - pUpdate->DstTop);
464
unsigned long offset = 0;
465
unsigned long srcTopOffset = 0;
466
unsigned long srcLeftOffset = 0;
470
if ((pUpdate->SrcLeft != 0) || (pUpdate->SrcTop != 0)) {
471
switch (pVia->swov.SrcFourCC) {
479
if (videoFlag & VIDEO_HQV_INUSE) {
480
offset = (((pUpdate->SrcTop & ~3) * srcPitch)
481
+ ((pUpdate->SrcLeft << n) & ~31));
483
if (srcHeight > dstHeight)
484
srcTopOffset = ((pUpdate->SrcTop & ~3)
485
* dstHeight / srcHeight) * srcPitch;
487
srcTopOffset = (pUpdate->SrcTop & ~3) * srcPitch;
489
if (srcWidth > dstWidth)
490
srcLeftOffset = (((pUpdate->SrcLeft << n) & ~31)
491
* dstWidth / srcWidth);
493
srcLeftOffset = (pUpdate->SrcLeft << n) & ~31;
494
*pHQVoffset = srcTopOffset + srcLeftOffset;
496
offset = ((pUpdate->SrcTop * srcPitch)
497
+ ((pUpdate->SrcLeft << n) & ~15));
504
if (videoFlag & VIDEO_HQV_INUSE)
505
offset = (((pUpdate->SrcTop & ~3) * (srcPitch << 1))
506
+ ((pUpdate->SrcLeft << 1) & ~31));
508
offset = ((((pUpdate->SrcTop & ~3) * srcPitch)
509
+ pUpdate->SrcLeft) & ~31);
510
if (pUpdate->SrcTop > 0)
511
pVia->swov.overlayRecordV1.dwUVoffset
512
= (((((pUpdate->SrcTop & ~3) >> 1) * srcPitch)
513
+ pUpdate->SrcLeft) & ~31) >> 1;
515
pVia->swov.overlayRecordV1.dwUVoffset = offset >> 1;
520
DBG_DD(ErrorF("viaGetSrcStartAddress: "
521
"Invalid FOURCC format (0x%lx).\n",
522
pVia->swov.SrcFourCC));
526
pVia->swov.overlayRecordV1.dwUVoffset = offset = 0;
533
viaOverlayGetYCbCrStartAddress(unsigned long videoFlag,
534
unsigned long startAddr, unsigned long offset,
535
unsigned long UVoffset, unsigned long srcPitch,
536
unsigned long srcHeight)
540
if (videoFlag & VIDEO_HQV_INUSE) {
541
YCbCr.dwY = startAddr;
542
YCbCr.dwCB = startAddr + srcPitch * srcHeight;
543
YCbCr.dwCR = (startAddr + srcPitch * srcHeight
544
+ srcPitch * (srcHeight >> 2));
546
YCbCr.dwY = startAddr + offset;
547
YCbCr.dwCB = startAddr + srcPitch * srcHeight + UVoffset;
548
YCbCr.dwCR = (startAddr + srcPitch * srcHeight + UVoffset
549
+ srcPitch * (srcHeight >> 2));
555
viaOverlayHQVCalcZoomWidth(VIAPtr pVia,
556
unsigned long videoFlag, unsigned long srcWidth,
557
unsigned long dstWidth, unsigned long *pZoomCtl,
558
unsigned long *pMiniCtl,
559
unsigned long *pHQVfilterCtl,
560
unsigned long *pHQVminiCtl,
561
unsigned long *pHQVscaleCtlH,
562
unsigned long *pHQVzoomflag)
564
unsigned long tmp, sw1, d, falign, mdiv;
566
VIAHWDiff *hwDiff = &pVia->HWDiff;
568
CARD32 HQVfilter[5] = { HQV_H_FILTER_DEFAULT, HQV_H_TAP4_121,
569
HQV_H_TAP4_121, HQV_H_TAP8_12221, HQV_H_TAP8_12221
571
/* CARD HQVmini[5] = { 0, 0xc00, 0xa00, 0x900, 0x8800 }; */
576
if (srcWidth == dstWidth) { /* No zoom */
577
*pHQVfilterCtl |= HQV_H_FILTER_DEFAULT;
578
} else if (srcWidth < dstWidth) { /* Zoom in */
579
*pZoomCtl &= 0x0000FFFF;
580
tmp = srcWidth * 0x800 / dstWidth;
581
*pZoomCtl |= ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;
582
*pMiniCtl |= V1_X_INTERPOLY;
583
zoom_ok = !(tmp > 0x7ff);
586
*pHQVfilterCtl |= HQV_H_FILTER_DEFAULT;
587
} else { /* srcWidth > dstWidth - Zoom out */
588
if (hwDiff->dwNewScaleCtl) {
589
if (srcWidth > (dstWidth << 3)) {
592
if (dstWidth <= 32) {
595
if (srcWidth > (dstWidth << 5)) {
596
tmp = 1 * 0x1000 / 31;
598
tmp = (dstWidth * 0x1000) / srcWidth;
601
*pHQVscaleCtlH = HQV_H_SCALE_DOWN_UNDER_EIGHTH;
602
} else if (srcWidth == (dstWidth << 3)) {
604
tmp = ((dstWidth - 1) * 0x1000) / srcWidth;
605
*pHQVscaleCtlH = HQV_H_SCALE_DOWN_UNDER_EIGHTH;
606
} else if (srcWidth > (dstWidth << 2)) {
607
/*1/4 -1/8 zoom-out*/
608
tmp = (srcWidth * 0x1000) / dstWidth;
609
*pHQVscaleCtlH = HQV_H_SCALE_DOWN_FOURTH_TO_EIGHTH;
612
/*setting :src/(destination+0.5)*/
613
tmp = (srcWidth * 0x2000) / ((dstWidth << 1) + 1);
614
*pHQVscaleCtlH = HQV_H_SCALE_DOWN_FOURTH_TO_1;
617
/*rounding to nearest interger*/
618
tmp += (((tmp * 0x1000) & 0xfff) > 1) ? 1 : 0;
619
*pHQVscaleCtlH |= (tmp & 0x7fff) | HQV_H_SCALE_ENABLE;
621
/* HQV rounding patch, instead of:
622
* //tmp = dstWidth*0x0800 / srcWidth; */
623
tmp = dstWidth * 0x800 * 0x400 / srcWidth;
624
tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
626
*pHQVminiCtl = (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE | HQV_H_MINIFY_DOWN;
628
*pHQVminiCtl |= HQV_HDEBLOCK_FILTER;
630
/* Scale down the picture by a factor mdiv = (1 << d) = {2, 4, 8 or 16} */
633
for (d = 1; d < 5; d++) {
638
if (d == 5) { /* Too small. */
642
mdiv = 1 << d; /* <= {2,4,8,16} */
643
falign = ((mdiv << 1) - 1) & 0xf; /* <= {3,7,15,15} */
644
*pMiniCtl |= V1_X_INTERPOLY;
645
*pMiniCtl |= ((d << 1) - 1) << 24; /* <= {1,3,5,7} << 24 */
647
*pHQVfilterCtl |= HQVfilter[d];
649
/* Scale to arbitrary size, on top of previous scaling by (1 << d). */
651
if (sw1 < dstWidth) {
653
*pZoomCtl = sw1 * 0x0800 / dstWidth;*/
654
*pZoomCtl = (sw1 - 2) * 0x0800 / dstWidth;
655
*pZoomCtl = ((*pZoomCtl & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;
658
if (videoFlag & VIDEO_1_INUSE) {
659
pVia->swov.overlayRecordV1.dwFetchAlignment = falign;
660
pVia->swov.overlayRecordV1.dwminifyH = mdiv;
662
pVia->swov.overlayRecordV3.dwFetchAlignment = falign;
663
pVia->swov.overlayRecordV3.dwminifyH = mdiv;
670
viaOverlayHQVCalcZoomHeight(VIAPtr pVia,
671
unsigned long srcHeight, unsigned long dstHeight,
672
unsigned long *pZoomCtl, unsigned long *pMiniCtl,
673
unsigned long *pHQVfilterCtl,
674
unsigned long *pHQVminiCtl,
675
unsigned long *pHQVscaleCtlV,
676
unsigned long *pHQVzoomflag)
678
unsigned long tmp, sh1, d;
680
VIAHWDiff *hwDiff = &pVia->HWDiff;
682
CARD32 HQVfilter[5] = { HQV_V_TAP4_121, HQV_V_TAP4_121, HQV_V_TAP4_121,
683
HQV_V_TAP8_12221, HQV_V_TAP8_12221 };
684
/* CARD32 HQVmini[5] = { 0, 0x0c000000, 0x0a000000, 0x09000000, 0x08800000 }; */
686
/*if (pVia->pBIOSInfo->scaleY)
688
* dstHeight = dstHeight + 1;
691
if (srcHeight == dstHeight) { /* No zoom */
692
*pHQVfilterCtl |= HQV_V_TAP4_121;
693
} else if (srcHeight < dstHeight) { /* Zoom in */
694
*pZoomCtl &= 0xFFFF0000;
695
tmp = srcHeight * 0x400 / dstHeight - 1;
696
*pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE);
697
*pMiniCtl |= (V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY);
700
*pHQVfilterCtl |= HQV_V_TAP4_121;
701
} else { /* srcHeight > dstHeight - Zoom out */
702
if (hwDiff->dwNewScaleCtl) {
703
/*setting :src/(destination+0.5)*/
704
tmp = srcHeight * 0x2000 / ((dstHeight << 1) + 1);
705
tmp += (((tmp * 0x1000) & 0xfff) > 1) ? 1 : 0;
706
if ((tmp & 0x1ffff) == 0) {
710
*pHQVscaleCtlV = (tmp & 0x1ffff) | HQV_V_SCALE_ENABLE| HQV_V_SCALE_DOWN;
712
/* HQV rounding patch, instead of:
713
* //tmp = dstHeight*0x0800 / srcHeight; */
714
tmp = dstHeight * 0x0800 * 0x400 / srcHeight;
715
tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
716
*pHQVminiCtl |= (((tmp & 0x7ff) << 16) | HQV_V_MINIFY_ENABLE
717
| HQV_V_MINIFY_DOWN);
719
/* Scale down the picture by a factor (1 << d) = {2, 4, 8 or 16} */
721
for (d = 1; d < 5; d++) {
723
if (sh1 <= dstHeight)
726
if (d == 5) { /* Too small. */
731
*pMiniCtl |= ((d << 1) - 1) << 16; /* <= {1,3,5,7} << 16 */
733
*pHQVfilterCtl |= HQVfilter[d];
734
/* *pHQVminiCtl |= HQVmini[d]; */
735
*pHQVminiCtl |= HQV_VDEBLOCK_FILTER;
737
/* Scale to arbitrary size, on top of previous scaling by (1 << d). */
739
if (sh1 < dstHeight) {
740
tmp = sh1 * 0x0400 / dstHeight;
741
*pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE);
742
*pMiniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY;
750
viaOverlayGetFetch(VIAPtr pVia, unsigned long videoFlag,
751
unsigned long srcWidth, unsigned long dstWidth,
752
unsigned long oriSrcWidth, unsigned long *pHQVsrcFetch)
754
unsigned long fetch = 0;
755
int n = 2; /* 2^n bytes per pixel. */
757
switch (pVia->swov.SrcFourCC) {
761
n = 0; /* 2^n = 1 byte per pixel (Y channel in planar YUV) */
767
n = 1; /* 2^n = 2 bytes per pixel (packed YUV) */
773
DBG_DD(ErrorF("viaOverlayGetFetch: "
774
"Invalid FOURCC format (0x%lx).\n",
775
pVia->swov.SrcFourCC));
779
if (videoFlag & VIDEO_HQV_INUSE) {
780
*pHQVsrcFetch = oriSrcWidth << n;
782
/* Assume n == 0 <=> Planar YUV.
783
* The V1/V3 pixelformat is always packed YUV when we use HQV,
784
* so we switch from 8-bit to 16-bit pixels here.
788
if (dstWidth >= srcWidth)
789
fetch = (ALIGN_TO(srcWidth << n, 16) >> 4) + 1;
791
fetch = (ALIGN_TO(dstWidth << n, 16) >> 4) + 1;
794
fetch = (ALIGN_TO(srcWidth, 32) >> 4);
796
fetch = (ALIGN_TO(srcWidth << n, 16) >> 4) + 1;
799
/* Fix planar mode problem. */
807
* This function uses quadratic mapping to adjust the midpoint of the scaling.
810
rangeEqualize(float inLow, float inHigh, float outLow, float outHigh,
811
float outMid, float inValue)
813
float inRange = inHigh - inLow,
814
outRange = outHigh - outLow,
815
normIn = ((inValue - inLow) / inRange) * 2. - 1.,
816
delta = outMid - outRange * 0.5 - outLow;
817
return ((inValue - inLow) * outRange / inRange + outLow
818
+ (1. - normIn * normIn) * delta);
822
vPackFloat(float val, float hiLimit, float loLimit, float mult, int shift,
825
unsigned packed, mask, sign;
827
val = (val > hiLimit) ? hiLimit : val;
828
val = (val < loLimit) ? loLimit : val;
829
sign = (val < 0) ? 1 : 0;
830
val = (sign) ? -val : val;
831
packed = ((unsigned)(val * mult + 1.)) >> 1;
832
mask = (1 << shift) - 1;
833
return (((packed >= mask) ? mask : packed)
834
| ((doSign) ? (sign << shift) : 0));
838
typedef float colorCoeff[5];
839
static colorCoeff colorCTable[] = {
840
{1.1875, 1.625, 0.875, 0.375, 2.0},
841
{1.164, 1.596, 0.54, 0.45, 2.2}
845
* This function is a partial rewrite of the overlay.c file of the original VIA
846
* drivers, which was extremely nasty and difficult to follow. Coefficients for
847
* new chipset models should be added in the table above and, if needed,
848
* implemented in the model switch below.
851
viaCalculateVideoColor(VIAPtr pVia, int hue, int saturation,
852
int brightness, int contrast, Bool reset,
853
CARD32 * col1, CARD32 * col2)
855
float fA, fB1, fC1, fD, fB2, fC2, fB3, fC3;
856
float fPI, fContrast, fSaturation, fHue, fBrightness;
858
unsigned long dwA, dwB1, dwC1, dwD, dwB2, dwC2, dwB3, dwC3, dwS;
859
unsigned long dwD_Int, dwD_Dec;
863
fPI = (float)(M_PI / 180.);
871
switch (pVia->ChipId) {
872
case PCI_CHIP_VT3205:
873
case PCI_CHIP_VT3204:
874
case PCI_CHIP_VT3259:
875
case PCI_CHIP_VT3314:
876
case PCI_CHIP_VT3336:
877
case PCI_CHIP_VT3364:
878
case PCI_CHIP_VT3324:
879
case PCI_CHIP_VT3327:
880
case PCI_CHIP_VT3353:
881
case PCI_CHIP_VT3409:
882
case PCI_CHIP_VT3410:
885
case PCI_CHIP_CLE3122:
886
model = (CLE266_REV_IS_CX(pVia->ChipRev) ? 0 : 1);
889
ErrorF("Unknown Chip ID\n");
895
fBrightness = rangeEqualize(0., 10000., -128., 128., -16.,
897
fContrast = rangeEqualize(0., 20000., 0., 1.6645, 1.0,
899
fSaturation = rangeEqualize(0., 20000, 0., 2., 1.,
903
fBrightness = rangeEqualize(0., 10000., -128., 128., -12.,
905
fContrast = rangeEqualize(0., 20000., 0., 1.6645, 1.1,
907
fSaturation = rangeEqualize(0., 20000, 0., 2., 1.15,
913
mCoeff = colorCTable[model];
915
fA = (float)(mCoeff[0] * fContrast);
916
fB1 = (float)(-mCoeff[1] * fContrast * fSaturation * sin(fHue * fPI));
917
fC1 = (float)(mCoeff[1] * fContrast * fSaturation * cos(fHue * fPI));
918
fD = (float)(mCoeff[0] * (fBrightness));
919
fB2 = (float)((mCoeff[2] * sin(fHue * fPI) - mCoeff[3] * cos(fHue * fPI))
920
* fContrast * fSaturation);
921
fC2 = (float)(-(mCoeff[2] * cos(fHue * fPI) + mCoeff[3] * sin(fHue * fPI))
922
* fContrast * fSaturation);
923
fB3 = (float)(mCoeff[4] * fContrast * fSaturation * cos(fHue * fPI));
924
fC3 = (float)(mCoeff[4] * fContrast * fSaturation * sin(fHue * fPI));
928
dwA = vPackFloat(fA, 1.9375, 0., 32., 5, 0);
929
dwB1 = vPackFloat(fB1, 2.125, -2.125, 16., 5, 1);
930
dwC1 = vPackFloat(fC1, 2.125, -2.125, 16., 5, 1);
936
dwD_Int = ((unsigned long)intD) & 0xff;
937
dwD = ((unsigned long)(fD * 16 + 1)) >> 1;
944
dwD_Int = ((unsigned long)intD) & 0xff;
946
dwD = ((unsigned long)(fD * 16 + 1)) >> 1;
950
dwB2 = vPackFloat(fB2, 1.875, -1.875, 16, 4, 1);
951
dwC2 = vPackFloat(fC2, 1.875, -1.875, 16, 4, 1);
952
dwB3 = vPackFloat(fB3, 3.875, -3.875, 16, 5, 1);
953
dwC3 = vPackFloat(fC3, 3.875, -3.875, 16, 5, 1);
954
*col1 = (dwA << 24) | (dwB1 << 16) | (dwC1 << 8) | dwD_Int;
955
*col2 = (dwD_Dec << 29 | dwB2 << 24) | (dwC2 << 16) | (dwB3 << 8)
960
dwA = vPackFloat(fA, 1.9375, -0., 32, 5, 0);
961
dwB1 = vPackFloat(fB1, 0.75, -0.75, 8., 2, 1);
962
dwC1 = vPackFloat(fC1, 2.875, 1., 16., 5, 0);
977
dwD = ((unsigned long)(fD * 2 + 1)) >> 1;
979
dwD = 0x7f | (dwS << 7);
981
dwD = (dwD & 0x7f) | (dwS << 7);
984
dwB2 = vPackFloat(fB2, 0., -0.875, 16., 3, 0);
985
dwC2 = vPackFloat(fC2, 0., -1.875, 16., 4, 0);
986
dwB3 = vPackFloat(fB3, 3.75, 0., 8., 4, 0);
987
dwC3 = vPackFloat(fC3, 1.25, -1.25, 8., 3, 1);
988
*col1 = (dwA << 24) | (dwB1 << 18) | (dwC1 << 9) | dwD;
989
*col2 = (dwB2 << 25) | (dwC2 << 17) | (dwB3 << 10) | (dwC3 << 2);
999
viaSetColorSpace(VIAPtr pVia, int hue, int saturation, int brightness,
1000
int contrast, Bool reset)
1004
viaCalculateVideoColor(pVia, hue, saturation, brightness, contrast, reset,
1006
switch (pVia->ChipId) {
1007
case PCI_CHIP_VT3205:
1008
case PCI_CHIP_VT3204:
1009
case PCI_CHIP_VT3314:
1010
VIASETREG(V3_ColorSpaceReg_1, col1);
1011
VIASETREG(V3_ColorSpaceReg_2, col2);
1012
DBG_DD(ErrorF("000002C4 %08lx\n", col1));
1013
DBG_DD(ErrorF("000002C8 %08lx\n", col2));
1014
case PCI_CHIP_VT3259:
1015
case PCI_CHIP_VT3327:
1016
case PCI_CHIP_VT3336:
1017
case PCI_CHIP_VT3324:
1018
case PCI_CHIP_VT3364:
1019
case PCI_CHIP_VT3353:
1020
case PCI_CHIP_VT3409:
1021
case PCI_CHIP_VT3410:
1022
case PCI_CHIP_CLE3122:
1023
VIASETREG(V1_ColorSpaceReg_1, col1);
1024
VIASETREG(V1_ColorSpaceReg_2, col2);
1025
DBG_DD(ErrorF("00000288 %08lx\n", col2));
1026
DBG_DD(ErrorF("00000284 %08lx\n", col1));
1029
DBG_DD(ErrorF("Unknown DeviceID\n"));
1034
static unsigned long
1035
ViaInitVideoStatusFlag(VIAPtr pVia)
1037
switch (pVia->ChipId) {
1038
case PCI_CHIP_VT3205:
1039
case PCI_CHIP_VT3204:
1040
case PCI_CHIP_VT3314:
1041
return VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_3_INUSE;
1042
case PCI_CHIP_VT3259:
1043
case PCI_CHIP_VT3327:
1044
case PCI_CHIP_VT3336:
1045
case PCI_CHIP_VT3324:
1046
case PCI_CHIP_VT3364:
1047
case PCI_CHIP_VT3353:
1048
case PCI_CHIP_VT3409:
1049
case PCI_CHIP_VT3410:
1050
return (VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_1_INUSE
1051
| VIDEO_ACTIVE | VIDEO_SHOW);
1052
case PCI_CHIP_CLE3122:
1053
return VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_1_INUSE;
1055
DBG_DD(ErrorF("Unknown DeviceID\n"));
1061
static unsigned long
1062
ViaSetVidCtl(VIAPtr pVia, unsigned int videoFlag)
1064
if (videoFlag & VIDEO_1_INUSE) {
1065
/*=* Modify for C1 FIFO *=*/
1066
/* WARNING: not checking Chipset! */
1067
if (CLE266_REV_IS_CX(pVia->ChipRev))
1068
return V1_ENABLE | V1_EXPIRE_NUM_F;
1070
/* Overlay source format for V1 */
1071
if (pVia->swov.gdwUseExtendedFIFO)
1072
return V1_ENABLE | V1_EXPIRE_NUM_A | V1_FIFO_EXTENDED;
1074
return V1_ENABLE | V1_EXPIRE_NUM;
1077
switch (pVia->ChipId) {
1078
case PCI_CHIP_VT3205:
1079
case PCI_CHIP_VT3204:
1080
case PCI_CHIP_VT3259:
1081
case PCI_CHIP_VT3314:
1082
return V3_ENABLE | V3_EXPIRE_NUM_3205;
1083
case PCI_CHIP_VT3327:
1084
case PCI_CHIP_VT3336:
1085
case PCI_CHIP_VT3324:
1086
case PCI_CHIP_VT3364:
1087
case PCI_CHIP_VT3353:
1088
return V3_ENABLE | VIDEO_EXPIRE_NUM_VT3336;
1089
case PCI_CHIP_VT3409:
1090
case PCI_CHIP_VT3410:
1091
return V3_ENABLE | VIDEO_EXPIRE_NUM_VT3409;
1092
case PCI_CHIP_CLE3122:
1093
if (CLE266_REV_IS_CX(pVia->ChipRev))
1094
return V3_ENABLE | V3_EXPIRE_NUM_F;
1096
return V3_ENABLE | V3_EXPIRE_NUM;
1098
DBG_DD(ErrorF("Unknown DeviceID\n"));
1106
* Fill the buffer with 0x8000 (YUV2 black).
1109
ViaYUVFillBlack(VIAPtr pVia, void *buf, int num)
1111
CARD16 *ptr = (CARD16 *) buf;
1114
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
1122
* Add an HQV surface to an existing FOURCC surface.
1123
* numbuf: number of buffers, 1, 2 or 3
1124
* fourcc: FOURCC code of the current (already existing) surface
1127
AddHQVSurface(ScrnInfoPtr pScrn, unsigned int numbuf, CARD32 fourcc)
1129
unsigned int i, width, height, pitch, fbsize, addr;
1133
VIAPtr pVia = VIAPTR(pScrn);
1134
CARD32 AddrReg[3] = { HQV_DST_STARTADDR0, HQV_DST_STARTADDR1,
1135
HQV_DST_STARTADDR2 };
1136
unsigned long proReg = 0;
1138
if (pVia->ChipId == PCI_CHIP_VT3259 &&
1139
!(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
1140
proReg = PRO_HQV1_OFFSET;
1142
isplanar = ((fourcc == FOURCC_YV12) || (fourcc == FOURCC_I420) ||
1143
(fourcc == FOURCC_XVMC));
1145
width = pVia->swov.SWDevice.gdwSWSrcWidth;
1146
height = pVia->swov.SWDevice.gdwSWSrcHeight;
1147
pitch = pVia->swov.SWDevice.dwPitch;
1148
fbsize = pitch * height * (isplanar ? 2 : 1);
1150
pVia->swov.HQVMem = drm_bo_alloc(pScrn, fbsize * numbuf, 1, TTM_PL_FLAG_VRAM);
1151
if (!pVia->swov.HQVMem)
1153
addr = pVia->swov.HQVMem->offset;
1154
buf = drm_bo_map(pScrn, pVia->swov.HQVMem);
1156
ViaYUVFillBlack(pVia, buf, fbsize);
1158
for (i = 0; i < numbuf; i++) {
1159
pVia->swov.overlayRecordV1.dwHQVAddr[i] = addr;
1160
VIASETREG(AddrReg[i] + proReg, addr);
1163
drm_bo_unmap(pScrn, pVia->swov.HQVMem);
1168
* Create a FOURCC surface.
1169
* doalloc: set true to actually allocate memory for the framebuffers
1172
CreateSurface(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width,
1173
CARD16 Height, BOOL doalloc)
1175
VIAPtr pVia = VIAPTR(pScrn);
1176
unsigned long pitch, fbsize, addr;
1180
pVia->swov.SrcFourCC = FourCC;
1181
pVia->swov.gdwVideoFlagSW = ViaInitVideoStatusFlag(pVia);
1189
pitch = ALIGN_TO(Width, 32);
1190
fbsize = pitch * Height * 1.5;
1193
pitch = ALIGN_TO(Width << 2, 32);
1194
fbsize = pitch * Height;
1197
pitch = ALIGN_TO(Width << 1, 32);
1198
fbsize = pitch * Height;
1203
pVia->swov.SWfbMem = drm_bo_alloc(pScrn, fbsize * 2, 1, TTM_PL_FLAG_VRAM);
1204
if (!pVia->swov.SWfbMem)
1206
addr = pVia->swov.SWfbMem->offset;
1207
buf = drm_bo_map(pScrn, pVia->swov.SWfbMem);
1209
ViaYUVFillBlack(pVia, buf, fbsize);
1211
pVia->swov.SWDevice.dwSWPhysicalAddr[0] = addr;
1212
pVia->swov.SWDevice.dwSWPhysicalAddr[1] = addr + fbsize;
1213
pVia->swov.SWDevice.lpSWOverlaySurface[0] = buf;
1214
pVia->swov.SWDevice.lpSWOverlaySurface[1] = buf + fbsize;
1217
pVia->swov.SWDevice.dwSWCrPhysicalAddr[0] =
1218
pVia->swov.SWDevice.dwSWPhysicalAddr[0] +
1220
pVia->swov.SWDevice.dwSWCrPhysicalAddr[1] =
1221
pVia->swov.SWDevice.dwSWPhysicalAddr[1] +
1223
pVia->swov.SWDevice.dwSWCbPhysicalAddr[0] =
1224
pVia->swov.SWDevice.dwSWCrPhysicalAddr[0] +
1225
((pitch >> 1) * (Height >> 1));
1226
pVia->swov.SWDevice.dwSWCbPhysicalAddr[1] =
1227
pVia->swov.SWDevice.dwSWCrPhysicalAddr[1] +
1228
((pitch >> 1) * (Height >> 1));
1232
pVia->swov.SWDevice.gdwSWSrcWidth = Width;
1233
pVia->swov.SWDevice.gdwSWSrcHeight = Height;
1234
pVia->swov.SWDevice.dwPitch = pitch;
1236
pVia->swov.overlayRecordV1.dwV1OriWidth = Width;
1237
pVia->swov.overlayRecordV1.dwV1OriHeight = Height;
1238
pVia->swov.overlayRecordV1.dwV1OriPitch = pitch;
1247
ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv,
1248
CARD32 FourCC, CARD16 Width, CARD16 Height)
1250
VIAPtr pVia = VIAPTR(pScrn);
1251
unsigned long retCode = Success;
1252
int numbuf = pVia->HWDiff.dwThreeHQVBuffer ? 3 : 2;
1254
DBG_DD(ErrorF("ViaSwovSurfaceCreate: FourCC =0x%08lx\n", FourCC));
1256
if ((pVia->VideoStatus & VIDEO_SWOV_SURFACE_CREATED)
1257
&& (FourCC == pPriv->FourCC))
1260
pPriv->FourCC = FourCC;
1266
retCode = CreateSurface(pScrn, FourCC, Width, Height, TRUE);
1267
if (retCode != Success)
1269
if ((pVia->swov.gdwVideoFlagSW & SW_USE_HQV))
1270
retCode = AddHQVSurface(pScrn, numbuf, FourCC);
1274
retCode = AddHQVSurface(pScrn, numbuf, FOURCC_YUY2);
1279
retCode = CreateSurface(pScrn, FourCC, Width, Height, TRUE);
1280
if (retCode == Success)
1281
retCode = AddHQVSurface(pScrn, numbuf, FourCC);
1285
retCode = CreateSurface(pScrn, FourCC, Width, Height, FALSE);
1286
if (retCode == Success)
1287
retCode = AddHQVSurface(pScrn, numbuf, FOURCC_XVMC);
1294
if (retCode == Success) {
1295
DBG_DD(ErrorF(" lpSWOverlaySurface[0]: %p\n",
1296
pVia->swov.SWDevice.lpSWOverlaySurface[0]));
1297
DBG_DD(ErrorF(" lpSWOverlaySurface[1]: %p\n",
1298
pVia->swov.SWDevice.lpSWOverlaySurface[1]));
1300
pVia->VideoStatus |= VIDEO_SWOV_SURFACE_CREATED | VIDEO_SWOV_ON;
1309
ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv)
1311
VIAPtr pVia = VIAPTR(pScrn);
1313
DBG_DD(ErrorF("ViaSwovSurfaceDestroy: FourCC =0x%08lx\n", pPriv->FourCC));
1315
if (pVia->VideoStatus & VIDEO_SWOV_SURFACE_CREATED) {
1316
DBG_DD(ErrorF("ViaSwovSurfaceDestroy: VideoStatus =0x%08lx\n",
1317
pVia->VideoStatus));
1319
switch (pPriv->FourCC) {
1324
pVia->swov.SrcFourCC = 0;
1326
drm_bo_unmap(pScrn, pVia->swov.SWfbMem);
1327
drm_bo_free(pScrn, pVia->swov.SWfbMem);
1328
if ((pVia->swov.gdwVideoFlagSW & SW_USE_HQV)) {
1329
drm_bo_unmap(pScrn, pVia->swov.HQVMem);
1330
drm_bo_free(pScrn, pVia->swov.HQVMem);
1332
pVia->swov.gdwVideoFlagSW = 0;
1336
drm_bo_free(pScrn, pVia->swov.HQVMem);
1337
pVia->swov.gdwVideoFlagSW = 0;
1342
drm_bo_unmap(pScrn, pVia->swov.SWfbMem);
1343
drm_bo_free(pScrn, pVia->swov.SWfbMem);
1345
pVia->swov.SrcFourCC = 0;
1347
drm_bo_free(pScrn, pVia->swov.HQVMem);
1348
pVia->swov.gdwVideoFlagSW = 0;
1353
pVia->VideoStatus &= ~VIDEO_SWOV_SURFACE_CREATED;
1356
DBG_DD(ErrorF("ViaSwovSurfaceDestroy: No SW Surface Destroyed, "
1357
"VideoStatus =0x%08lx\n", pVia->VideoStatus));
1361
SetFIFO_V1(VIAPtr pVia, CARD8 depth, CARD8 prethreshold, CARD8 threshold)
1363
SaveVideoRegister(pVia, V_FIFO_CONTROL,
1364
((depth - 1) & 0x7f) |
1365
((prethreshold & 0x7f) << 24) |
1366
((threshold & 0x7f) << 8));
1370
SetFIFO_V3(VIAPtr pVia, CARD8 depth, CARD8 prethreshold, CARD8 threshold)
1372
switch (pVia->ChipId) {
1373
case PCI_CHIP_VT3314:
1374
case PCI_CHIP_VT3324:
1375
case PCI_CHIP_VT3327:
1376
case PCI_CHIP_VT3353:
1377
case PCI_CHIP_VT3409:
1378
case PCI_CHIP_VT3410:
1379
SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL,
1380
(VIAGETREG(ALPHA_V3_FIFO_CONTROL) & ALPHA_FIFO_MASK)
1381
| ((depth - 1) & 0xff) | ((threshold & 0xff) << 8));
1382
SaveVideoRegister(pVia, ALPHA_V3_PREFIFO_CONTROL,
1383
(VIAGETREG(ALPHA_V3_PREFIFO_CONTROL)
1384
& ~V3_FIFO_MASK_3314) | (prethreshold & 0xff));
1387
SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL,
1388
(VIAGETREG(ALPHA_V3_FIFO_CONTROL) & ALPHA_FIFO_MASK)
1389
| ((depth - 1) & 0xff) | ((threshold & 0xff) << 8));
1390
SaveVideoRegister(pVia, ALPHA_V3_PREFIFO_CONTROL,
1391
(VIAGETREG(ALPHA_V3_PREFIFO_CONTROL) & ~V3_FIFO_MASK)
1392
| (prethreshold & 0x7f));
1398
SetFIFO_64or32(VIAPtr pVia)
1400
/*=* Modify for C1 FIFO *=*/
1401
/* WARNING: not checking Chipset! */
1402
if (CLE266_REV_IS_CX(pVia->ChipRev))
1403
SetFIFO_V1(pVia, 64, 56, 56);
1405
SetFIFO_V1(pVia, 32, 29, 16);
1409
SetFIFO_64or16(VIAPtr pVia)
1411
/*=* Modify for C1 FIFO *=*/
1412
/* WARNING: not checking Chipset! */
1413
if (CLE266_REV_IS_CX(pVia->ChipRev))
1414
SetFIFO_V1(pVia, 64, 56, 56);
1416
SetFIFO_V1(pVia, 16, 12, 8);
1420
SetFIFO_64or48or32(VIAPtr pVia)
1422
/*=* Modify for C1 FIFO *=*/
1423
/* WARNING: not checking Chipset! */
1424
if (CLE266_REV_IS_CX(pVia->ChipRev))
1425
SetFIFO_V1(pVia, 64, 56, 56);
1427
if (pVia->swov.gdwUseExtendedFIFO)
1428
SetFIFO_V1(pVia, 48, 40, 40);
1430
SetFIFO_V1(pVia, 32, 29, 16);
1435
SetFIFO_V3_64or32or32(VIAPtr pVia)
1437
switch (pVia->ChipId) {
1438
case PCI_CHIP_VT3327:
1439
case PCI_CHIP_VT3336:
1440
case PCI_CHIP_VT3324:
1441
case PCI_CHIP_VT3364:
1442
case PCI_CHIP_VT3353:
1443
case PCI_CHIP_VT3409:
1444
case PCI_CHIP_VT3410:
1445
SetFIFO_V3(pVia, 225, 200, 250);
1447
case PCI_CHIP_VT3204:
1448
SetFIFO_V3(pVia, 100, 89, 89);
1450
case PCI_CHIP_VT3314:
1451
SetFIFO_V3(pVia, 64, 61, 61);
1453
case PCI_CHIP_VT3205:
1454
case PCI_CHIP_VT3259:
1455
SetFIFO_V3(pVia, 32, 29, 29);
1457
case PCI_CHIP_CLE3122:
1458
if (CLE266_REV_IS_CX(pVia->ChipRev))
1459
SetFIFO_V3(pVia, 64, 56, 56);
1461
SetFIFO_V3(pVia, 32, 16, 16);
1469
SetFIFO_V3_64or32or16(VIAPtr pVia)
1471
switch (pVia->ChipId) {
1472
case PCI_CHIP_VT3327:
1473
case PCI_CHIP_VT3336:
1474
case PCI_CHIP_VT3324:
1475
case PCI_CHIP_VT3364:
1476
case PCI_CHIP_VT3353:
1477
case PCI_CHIP_VT3409:
1478
case PCI_CHIP_VT3410:
1479
SetFIFO_V3(pVia, 225, 200, 250);
1481
case PCI_CHIP_VT3204:
1482
SetFIFO_V3(pVia, 100, 89, 89);
1484
case PCI_CHIP_VT3314:
1485
SetFIFO_V3(pVia, 64, 61, 61);
1487
case PCI_CHIP_VT3205:
1488
case PCI_CHIP_VT3259:
1489
SetFIFO_V3(pVia, 32, 29, 29);
1492
case PCI_CHIP_CLE3122:
1493
if (CLE266_REV_IS_CX(pVia->ChipRev))
1494
SetFIFO_V3(pVia, 64, 56, 56);
1496
SetFIFO_V3(pVia, 16, 16, 8);
1505
SetupFIFOs(VIAPtr pVia, unsigned long videoFlag,
1506
unsigned long miniCtl, unsigned long srcWidth)
1508
if (miniCtl & V1_Y_INTERPOLY) {
1509
if (pVia->swov.SrcFourCC == FOURCC_YV12
1510
|| pVia->swov.SrcFourCC == FOURCC_I420
1511
|| pVia->swov.SrcFourCC == FOURCC_XVMC) {
1512
if (videoFlag & VIDEO_HQV_INUSE) {
1513
if (videoFlag & VIDEO_1_INUSE)
1514
SetFIFO_64or32(pVia);
1516
SetFIFO_V3_64or32or16(pVia);
1518
/* Minified video will be skewed without this workaround. */
1519
if (srcWidth <= 80) { /* Fetch count <= 5 */
1520
if (videoFlag & VIDEO_1_INUSE)
1521
SetFIFO_V1(pVia, 16, 0, 0);
1523
SetFIFO_V3(pVia, 16, 16, 0);
1525
if (videoFlag & VIDEO_1_INUSE)
1526
SetFIFO_64or16(pVia);
1528
SetFIFO_V3_64or32or16(pVia);
1532
if (videoFlag & VIDEO_1_INUSE)
1533
SetFIFO_64or48or32(pVia);
1537
SetFIFO_V3(pVia, 1, 0, 0);
1539
SetFIFO_V3_64or32or32(pVia);
1543
if (pVia->swov.SrcFourCC == FOURCC_YV12
1544
|| pVia->swov.SrcFourCC == FOURCC_I420
1545
|| pVia->swov.SrcFourCC == FOURCC_XVMC) {
1546
if (videoFlag & VIDEO_HQV_INUSE) {
1547
if (videoFlag & VIDEO_1_INUSE)
1548
SetFIFO_64or32(pVia);
1550
SetFIFO_V3_64or32or16(pVia);
1552
/* Minified video will be skewed without this workaround. */
1553
if (srcWidth <= 80) { /* Fetch count <= 5 */
1554
if (videoFlag & VIDEO_1_INUSE)
1555
SetFIFO_V1(pVia, 16, 0, 0);
1557
SetFIFO_V3(pVia, 16, 16, 0);
1559
if (videoFlag & VIDEO_1_INUSE)
1560
SetFIFO_64or16(pVia);
1562
SetFIFO_V3_64or32or16(pVia);
1566
if (videoFlag & VIDEO_1_INUSE)
1567
SetFIFO_64or48or32(pVia);
1571
SetFIFO_V3(pVia, 1, 0, 0);
1573
SetFIFO_V3_64or32or32(pVia);
1580
SetColorKey(VIAPtr pVia, unsigned long videoFlag,
1581
CARD32 keyLow, CARD32 keyHigh, CARD32 compose)
1583
keyLow &= 0x00FFFFFF;
1584
if (pVia->VideoEngine == VIDEO_ENGINE_CME)
1585
keyLow |= 0x40000000;
1587
if (videoFlag & VIDEO_1_INUSE) {
1588
SaveVideoRegister(pVia, V_COLOR_KEY, keyLow);
1589
SaveVideoRegister(pVia, SND_COLOR_KEY, keyLow);
1591
if (pVia->HWDiff.dwSupportTwoColorKey) /*CLE_C0 */
1592
SaveVideoRegister(pVia, V3_COLOR_KEY, keyLow);
1596
compose = ((compose & ~0x0f) | SELECT_VIDEO_IF_COLOR_KEY |
1597
SELECT_VIDEO3_IF_COLOR_KEY);
1603
SetChromaKey(VIAPtr pVia, unsigned long videoFlag,
1604
CARD32 chromaLow, CARD32 chromaHigh,
1605
CARD32 miniCtl, CARD32 compose)
1607
chromaLow &= CHROMA_KEY_LOW;
1608
chromaHigh &= CHROMA_KEY_HIGH;
1610
chromaLow |= (VIAGETREG(V_CHROMAKEY_LOW) & ~CHROMA_KEY_LOW);
1611
chromaHigh |= (VIAGETREG(V_CHROMAKEY_HIGH) & ~CHROMA_KEY_HIGH);
1613
if (pVia->VideoEngine == VIDEO_ENGINE_CME)
1614
chromaLow |= 0x40000000;
1616
SaveVideoRegister(pVia, V_CHROMAKEY_HIGH, chromaHigh);
1617
if (videoFlag & VIDEO_1_INUSE) {
1618
SaveVideoRegister(pVia, V_CHROMAKEY_LOW, chromaLow & ~V_CHROMAKEY_V3);
1619
/* Temporarily solve the HW interpolation error when using Chroma key */
1620
SaveVideoRegister(pVia, V1_MINI_CONTROL, miniCtl & 0xFFFFFFF8);
1622
SaveVideoRegister(pVia, V_CHROMAKEY_LOW, chromaLow | V_CHROMAKEY_V3);
1623
SaveVideoRegister(pVia, V3_MINI_CONTROL, miniCtl & 0xFFFFFFF8);
1626
/* Modified by Scottie[2001.12.5] for select video if (Color key & Chroma key) */
1627
if (compose == SELECT_VIDEO_IF_COLOR_KEY)
1628
compose = SELECT_VIDEO_IF_COLOR_KEY | SELECT_VIDEO_IF_CHROMA_KEY;
1630
compose = (compose & ~0x0f) | SELECT_VIDEO_IF_CHROMA_KEY;
1636
SetVideoStart(VIAPtr pVia, unsigned long videoFlag,
1637
unsigned int numbufs, CARD32 a1, CARD32 a2, CARD32 a3)
1639
CARD32 V1Addr[3] = { V1_STARTADDR_0, V1_STARTADDR_1, V1_STARTADDR_2 };
1640
CARD32 V3Addr[3] = { V3_STARTADDR_0, V3_STARTADDR_1, V3_STARTADDR_2 };
1641
CARD32 *VideoAddr = (videoFlag & VIDEO_1_INUSE) ? V1Addr : V3Addr;
1643
SaveVideoRegister(pVia, VideoAddr[0], a1);
1645
SaveVideoRegister(pVia, VideoAddr[1], a2);
1647
SaveVideoRegister(pVia, VideoAddr[2], a3);
1651
SetHQVFetch(VIAPtr pVia, CARD32 srcFetch, unsigned long srcHeight)
1653
unsigned long proReg = 0;
1655
if (pVia->ChipId == PCI_CHIP_VT3259
1656
&& !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
1657
proReg = PRO_HQV1_OFFSET;
1659
if (!pVia->HWDiff.dwHQVFetchByteUnit) { /* CLE_C0 */
1660
srcFetch >>= 3; /* fetch unit is 8 bytes */
1663
if ((pVia->ChipId != PCI_CHIP_VT3409) && (pVia->ChipId != PCI_CHIP_VT3410))
1664
SaveVideoRegister(pVia, HQV_SRC_FETCH_LINE + proReg,
1665
((srcFetch - 1) << 16) | (srcHeight - 1));
1669
SetFetch(VIAPtr pVia, unsigned long videoFlag, CARD32 fetch)
1672
if (videoFlag & VIDEO_1_INUSE) {
1673
SaveVideoRegister(pVia, V12_QWORD_PER_LINE, fetch);
1675
fetch |= VIAGETREG(V3_ALPHA_QWORD_PER_LINE) & ~V3_FETCH_COUNT;
1676
SaveVideoRegister(pVia, V3_ALPHA_QWORD_PER_LINE, fetch);
1681
SetDisplayCount(VIAPtr pVia, unsigned long videoFlag,
1682
unsigned long srcWidth, unsigned long srcHeight)
1684
unsigned long DisplayCount;
1686
/* Removed VIA's large pixelformat switch/case.
1687
* All formats (YV12, UYVY, YUY2, VIA, RGB16 and RGB32)
1688
* seem to use the same count. /A
1691
if (videoFlag & VIDEO_HQV_INUSE)
1692
DisplayCount = srcWidth - 1;
1694
DisplayCount = srcWidth - pVia->swov.overlayRecordV1.dwminifyH;
1696
if (videoFlag & VIDEO_1_INUSE)
1697
SaveVideoRegister(pVia, V1_SOURCE_HEIGHT,
1698
(srcHeight << 16) | DisplayCount);
1700
SaveVideoRegister(pVia, V3_SOURCE_WIDTH, DisplayCount);
1704
SetMiniAndZoom(VIAPtr pVia, unsigned long videoFlag,
1705
CARD32 miniCtl, CARD32 zoomCtl)
1707
if (videoFlag & VIDEO_1_INUSE) {
1708
SaveVideoRegister(pVia, V1_MINI_CONTROL, miniCtl);
1709
SaveVideoRegister(pVia, V1_ZOOM_CONTROL, zoomCtl);
1711
SaveVideoRegister(pVia, V3_MINI_CONTROL, miniCtl);
1712
SaveVideoRegister(pVia, V3_ZOOM_CONTROL, zoomCtl);
1717
SetVideoControl(VIAPtr pVia, unsigned long videoFlag, CARD32 vidCtl)
1719
if (videoFlag & VIDEO_1_INUSE)
1720
SaveVideoRegister(pVia, V1_CONTROL, vidCtl);
1722
SaveVideoRegister(pVia, V3_CONTROL, vidCtl);
1726
FireVideoCommand(VIAPtr pVia, unsigned long videoFlag, CARD32 compose)
1728
if (videoFlag & VIDEO_1_INUSE)
1729
SaveVideoRegister(pVia, V_COMPOSE_MODE, compose | V1_COMMAND_FIRE);
1731
SaveVideoRegister(pVia, V_COMPOSE_MODE, compose | V3_COMMAND_FIRE);
1735
SetVideoWindow(ScrnInfoPtr pScrn, unsigned long videoFlag,
1736
LPDDUPDATEOVERLAY pUpdate)
1738
VIAPtr pVia = VIAPTR(pScrn);
1739
CARD32 left = pUpdate->DstLeft;
1740
CARD32 top = pUpdate->DstTop;
1741
CARD32 right = pUpdate->DstRight - 1;
1742
CARD32 bottom = pUpdate->DstBottom - 1;
1744
DBG_DD(ErrorF("SetVideoWindow: X (%ld,%ld) Y (%ld,%ld)\n",
1745
left, right, top, bottom));
1747
/* Modify for HW DVI limitation.
1748
* When we enable both the CRT and DVI, then change resolution.
1749
* If the resolution is smaller than the panel's physical size,
1750
* the video display in Y direction will be cut.
1751
* So, we need to adjust the Y top and bottom position.
1753
if (videoFlag & VIDEO_1_INUSE) {
1754
if (pBIOSInfo->SetDVI && pBIOSInfo->scaleY) {
1755
top = (pUpdate->DstTop * pBIOSInfo->Panel->NativeMode->Height
1756
/ pScrn->currentMode->VDisplay);
1757
bottom = (pUpdate->DstBottom * pBIOSInfo->Panel->NativeMode->Height
1758
/ pScrn->currentMode->VDisplay);
1764
else if (top > 2047)
1769
else if (bottom > 2047)
1774
else if (left > 2047)
1779
else if (right > 2047)
1782
if (videoFlag & VIDEO_1_INUSE) {
1783
SaveVideoRegister(pVia, V1_WIN_END_Y, (right << 16) | bottom);
1784
SaveVideoRegister(pVia, V1_WIN_START_Y, (left << 16) | top);
1786
SaveVideoRegister(pVia, V3_WIN_END_Y, (right << 16) | bottom);
1787
SaveVideoRegister(pVia, V3_WIN_START_Y, (left << 16) | top);
1795
Upd_Video(xf86CrtcPtr crtc, unsigned long videoFlag,
1796
unsigned long startAddr, LPDDUPDATEOVERLAY pUpdate,
1797
unsigned long srcPitch,
1798
unsigned long oriSrcWidth, unsigned long oriSrcHeight,
1799
unsigned long deinterlaceMode,
1800
unsigned long haveColorKey, unsigned long haveChromaKey,
1801
unsigned long colorKeyLow, unsigned long colorKeyHigh,
1802
unsigned long chromaKeyLow, unsigned long chromaKeyHigh)
1804
drmmode_crtc_private_ptr iga = crtc->driver_private;
1805
ScrnInfoPtr pScrn = crtc->scrn;
1806
VIAPtr pVia = VIAPTR(pScrn);
1807
vgaHWPtr hwp = VGAHWPTR(pScrn);
1808
VIAHWDiff *hwDiff = &pVia->HWDiff;
1809
unsigned long vidCtl = 0, compose;
1810
unsigned long srcWidth, srcHeight, dstWidth, dstHeight;
1811
unsigned long zoomCtl = 0, miniCtl = 0;
1812
unsigned long hqvCtl = 0;
1813
unsigned long hqvFilterCtl = 0, hqvMiniCtl = 0;
1814
unsigned long hqvScaleCtlH = 0, hqvScaleCtlV = 0;
1815
unsigned long haveHQVzoomH = 0, haveHQVzoomV = 0;
1816
unsigned long hqvSrcWidth = 0, hqvDstWidth = 0;
1817
unsigned long hqvSrcFetch = 0, hqvOffset = 0;
1818
unsigned long dwOffset = 0, fetch = 0, tmp = 0;
1819
unsigned long proReg = 0;
1822
DBG_DD(ErrorF("videoflag=%ld\n", videoFlag));
1824
if (pVia->ChipId == PCI_CHIP_VT3259 && !(videoFlag & VIDEO_1_INUSE))
1825
proReg = PRO_HQV1_OFFSET;
1827
compose = ((VIAGETREG(V_COMPOSE_MODE)
1828
& ~(SELECT_VIDEO_IF_COLOR_KEY
1829
| V1_COMMAND_FIRE | V3_COMMAND_FIRE))
1830
| V_COMMAND_LOAD_VBI);
1832
DBG_DD(ErrorF("// Upd_Video:\n"));
1833
DBG_DD(ErrorF("Modified rSrc X (%ld,%ld) Y (%ld,%ld)\n",
1834
pUpdate->SrcLeft, pUpdate->SrcRight,
1835
pUpdate->SrcTop, pUpdate->SrcBottom));
1836
DBG_DD(ErrorF("Modified rDest X (%ld,%ld) Y (%ld,%ld)\n",
1837
pUpdate->DstLeft, pUpdate->DstRight,
1838
pUpdate->DstTop, pUpdate->DstBottom));
1840
dstWidth = pUpdate->DstRight - pUpdate->DstLeft;
1841
/*if (pBIOSInfo->lvds && pBIOSInfo->lvds->status == XF86OutputStatusConnected &&
1842
pBIOSInfo->Panel->Scale) {
1843
* FIXME: We need to determine if the panel is using V1 or V3 *
1844
float hfactor = (float)pBIOSInfo->Panel->NativeMode->Width
1845
/ pScrn->currentMode->HDisplay;
1846
dstWidth *= hfactor;
1849
pVia->swov.overlayRecordV1.dwWidth = dstWidth;
1850
pVia->swov.overlayRecordV1.dwHeight = dstHeight =
1851
pUpdate->DstBottom - pUpdate->DstTop;
1852
srcWidth = (unsigned long)pUpdate->SrcRight - pUpdate->SrcLeft;
1853
srcHeight = (unsigned long)pUpdate->SrcBottom - pUpdate->SrcTop;
1854
DBG_DD(ErrorF("===srcWidth= %ld \n", srcWidth));
1855
DBG_DD(ErrorF("===srcHeight= %ld \n", srcHeight));
1857
vidCtl = ViaSetVidCtl(pVia, videoFlag);
1859
if (hwDiff->dwNeedV1Prefetch) {
1860
DBG_DD(ErrorF("NEEDV1PREFETCH\n"));
1861
vidCtl |= V1_PREFETCH_ON_3336;
1865
* Enable video on secondary
1867
if ((pVia->VideoEngine == VIDEO_ENGINE_CME ||
1868
pVia->Chipset == VIA_VM800) && iga->index) {
1869
/* V1_ON_SND_DISPLAY */
1870
vidCtl |= V1_ON_SND_DISPLAY;
1871
/* SECOND_DISPLAY_COLOR_KEY_ENABLE */
1872
compose |= SECOND_DISPLAY_COLOR_KEY_ENABLE | 0x1;
1875
viaOverlayGetV1V3Format(pVia, (videoFlag & VIDEO_1_INUSE) ? 1 : 3,
1876
videoFlag, &vidCtl, &hqvCtl);
1878
if (hwDiff->dwThreeHQVBuffer) { /* CLE_C0: HQV supports triple-buffering */
1879
hqvCtl &= ~HQV_SW_FLIP;
1880
hqvCtl |= HQV_TRIPLE_BUFF | HQV_FLIP_STATUS;
1883
/* Starting address of source and Source offset */
1884
dwOffset = viaOverlayGetSrcStartAddress(pVia, videoFlag, pUpdate,
1885
srcPitch, &hqvOffset);
1886
DBG_DD(ErrorF("===dwOffset= 0x%lx \n", dwOffset));
1888
pVia->swov.overlayRecordV1.dwOffset = dwOffset;
1890
if (pVia->swov.SrcFourCC == FOURCC_YV12
1891
|| pVia->swov.SrcFourCC == FOURCC_I420
1892
|| pVia->swov.SrcFourCC == FOURCC_XVMC) {
1896
if (videoFlag & VIDEO_HQV_INUSE) {
1897
SetVideoStart(pVia, videoFlag, hwDiff->dwThreeHQVBuffer ? 3 : 2,
1898
pVia->swov.overlayRecordV1.dwHQVAddr[0] + dwOffset,
1899
pVia->swov.overlayRecordV1.dwHQVAddr[1] + dwOffset,
1900
pVia->swov.overlayRecordV1.dwHQVAddr[2] + dwOffset);
1902
if (pVia->swov.SrcFourCC != FOURCC_XVMC) {
1903
YCbCr = viaOverlayGetYCbCrStartAddress(videoFlag, startAddr,
1904
pVia->swov.overlayRecordV1.dwOffset,
1905
pVia->swov.overlayRecordV1.dwUVoffset,
1906
srcPitch, oriSrcHeight);
1907
if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
1908
SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg,
1910
SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U + proReg,
1913
SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y, YCbCr.dwY);
1914
SaveVideoRegister(pVia, HQV_SRC_STARTADDR_U, YCbCr.dwCR);
1915
SaveVideoRegister(pVia, HQV_SRC_STARTADDR_V, YCbCr.dwCB);
1919
YCbCr = viaOverlayGetYCbCrStartAddress(videoFlag, startAddr,
1920
pVia->swov.overlayRecordV1.dwOffset,
1921
pVia->swov.overlayRecordV1.dwUVoffset,
1922
srcPitch, oriSrcHeight);
1924
if (videoFlag & VIDEO_1_INUSE) {
1925
SaveVideoRegister(pVia, V1_STARTADDR_0, YCbCr.dwY);
1926
SaveVideoRegister(pVia, V1_STARTADDR_CB0, YCbCr.dwCR);
1927
SaveVideoRegister(pVia, V1_STARTADDR_CR0, YCbCr.dwCB);
1929
DBG_DD(ErrorF("Upd_Video(): "
1930
"We do not support YV12 with V3!\n"));
1933
if (videoFlag & VIDEO_HQV_INUSE) {
1934
hqvSrcWidth = (unsigned long)pUpdate->SrcRight - pUpdate->SrcLeft;
1935
hqvDstWidth = (unsigned long)pUpdate->DstRight - pUpdate->DstLeft;
1937
if (hqvSrcWidth > hqvDstWidth)
1938
dwOffset = dwOffset * hqvDstWidth / hqvSrcWidth;
1940
SetVideoStart(pVia, videoFlag, hwDiff->dwThreeHQVBuffer ? 3 : 2,
1941
pVia->swov.overlayRecordV1.dwHQVAddr[0] + hqvOffset,
1942
pVia->swov.overlayRecordV1.dwHQVAddr[1] + hqvOffset,
1943
pVia->swov.overlayRecordV1.dwHQVAddr[2] + hqvOffset);
1945
if (pVia->VideoEngine == VIDEO_ENGINE_CME)
1946
SaveVideoRegister(pVia, 0x1cc + proReg, dwOffset);
1948
SaveVideoRegister(pVia, HQV_SRC_STARTADDR_Y + proReg, startAddr);
1950
startAddr += dwOffset;
1951
SetVideoStart(pVia, videoFlag, 1, startAddr, 0, 0);
1955
fetch = viaOverlayGetFetch(pVia, videoFlag,
1956
srcWidth, dstWidth, oriSrcWidth, &hqvSrcFetch);
1957
DBG_DD(ErrorF("===fetch= 0x%lx\n", fetch));
1960
/* For DCT450 test-BOB INTERLEAVE */
1961
if ((deinterlaceMode & DDOVER_INTERLEAVED)
1962
&& (deinterlaceMode & DDOVER_BOB)) {
1963
if (videoFlag & VIDEO_HQV_INUSE)
1964
hqvCtl |= HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD | HQV_DEINTERLACE;
1966
vidCtl |= V1_BOB_ENABLE | V1_FRAME_BASE;
1967
} else if (deinterlaceMode & DDOVER_BOB) {
1968
if (videoFlag & VIDEO_HQV_INUSE)
1969
/* The HQV source data line count should be two times of the original line count */
1970
hqvCtl |= HQV_FIELD_2_FRAME | HQV_DEINTERLACE;
1972
vidCtl |= V1_BOB_ENABLE;
1976
if (videoFlag & VIDEO_HQV_INUSE) {
1977
if (!(deinterlaceMode & DDOVER_INTERLEAVED)
1978
&& (deinterlaceMode & DDOVER_BOB))
1979
SetHQVFetch(pVia, hqvSrcFetch, oriSrcHeight << 1);
1981
SetHQVFetch(pVia, hqvSrcFetch, oriSrcHeight);
1983
if (pVia->swov.SrcFourCC == FOURCC_YV12
1984
|| pVia->swov.SrcFourCC == FOURCC_I420
1985
|| pVia->swov.SrcFourCC == FOURCC_XVMC) {
1986
if (videoFlag & VIDEO_1_INUSE)
1987
SaveVideoRegister(pVia, V1_STRIDE, srcPitch << 1);
1989
SaveVideoRegister(pVia, V3_STRIDE, srcPitch << 1);
1991
if (pVia->HWDiff.dwHQVFetchByteUnit)
1992
SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg,
1993
((srcPitch >> 1) << 16) | srcPitch |
1996
SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg,
1997
((srcPitch >> 1) << 16) | srcPitch);
1999
SaveVideoRegister(pVia, HQV_DST_STRIDE + proReg, (srcPitch << 1));
2001
if (videoFlag & VIDEO_1_INUSE)
2002
SaveVideoRegister(pVia, V1_STRIDE, srcPitch);
2004
SaveVideoRegister(pVia, V3_STRIDE, srcPitch);
2006
SaveVideoRegister(pVia, HQV_SRC_STRIDE + proReg, srcPitch);
2007
SaveVideoRegister(pVia, HQV_DST_STRIDE + proReg, srcPitch);
2011
if (videoFlag & VIDEO_1_INUSE)
2012
SaveVideoRegister(pVia, V1_STRIDE, srcPitch | (srcPitch << 15));
2014
SaveVideoRegister(pVia, V3_STRIDE, srcPitch | (srcPitch << 15));
2017
/* Set destination window */
2018
SetVideoWindow(pScrn, videoFlag, pUpdate);
2020
compose |= ALWAYS_SELECT_VIDEO;
2022
/* Set up X zoom factor */
2024
pVia->swov.overlayRecordV1.dwFetchAlignment = 0;
2026
if (!viaOverlayHQVCalcZoomWidth(pVia, videoFlag, srcWidth, dstWidth,
2027
&zoomCtl, &miniCtl, &hqvFilterCtl,
2028
&hqvMiniCtl, &hqvScaleCtlH, &haveHQVzoomH)) {
2029
/* Need to scale (minify) too much - can't handle it. */
2030
SetFetch(pVia, videoFlag, fetch);
2031
FireVideoCommand(pVia, videoFlag, compose);
2032
FlushVidRegBuffer(pVia);
2036
SetFetch(pVia, videoFlag, fetch);
2038
/* Set up Y zoom factor */
2040
/* For DCT450 test-BOB INTERLEAVE */
2041
if ((deinterlaceMode & DDOVER_INTERLEAVED)
2042
&& (deinterlaceMode & DDOVER_BOB)) {
2043
if (!(videoFlag & VIDEO_HQV_INUSE)) {
2045
if (videoFlag & VIDEO_1_INUSE)
2046
vidCtl |= V1_BOB_ENABLE | V1_FRAME_BASE;
2048
vidCtl |= V3_BOB_ENABLE | V3_FRAME_BASE;
2050
hqvCtl |= HQV_FIELD_2_FRAME | HQV_FRAME_2_FIELD | HQV_DEINTERLACE;
2051
} else if (deinterlaceMode & DDOVER_BOB) {
2052
if (videoFlag & VIDEO_HQV_INUSE) {
2054
hqvCtl |= HQV_FIELD_2_FRAME | HQV_DEINTERLACE;
2056
if (videoFlag & VIDEO_1_INUSE)
2057
vidCtl |= V1_BOB_ENABLE;
2059
vidCtl |= V3_BOB_ENABLE;
2063
SetDisplayCount(pVia, videoFlag, srcWidth, srcHeight);
2065
if (!viaOverlayHQVCalcZoomHeight(pVia, srcHeight, dstHeight, &zoomCtl,
2066
&miniCtl, &hqvFilterCtl, &hqvMiniCtl,
2067
&hqvScaleCtlV, &haveHQVzoomV)) {
2068
/* Need to scale (minify) too much - can't handle it. */
2069
FireVideoCommand(pVia, videoFlag, compose);
2070
FlushVidRegBuffer(pVia);
2074
SetupFIFOs(pVia, videoFlag, miniCtl, srcWidth);
2076
if (videoFlag & VIDEO_HQV_INUSE) {
2079
if (haveHQVzoomH || haveHQVzoomV) {
2083
miniCtl = V1_X_INTERPOLY;
2084
/* Disable X interpolation if the height exceeds
2085
* the maximum supported by the hardware */
2086
if (srcHeight >= pVia->swov.maxHInterp)
2087
miniCtl &= ~V1_X_INTERPOLY;
2088
tmp = zoomCtl & 0xffff0000;
2092
miniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY;
2093
/* Disable Y interpolation if the width exceeds
2094
* the maximum supported by the hardware */
2095
if (srcWidth >= pVia->swov.maxWInterp)
2096
miniCtl &= ~V1_Y_INTERPOLY;
2097
tmp |= zoomCtl & 0x0000ffff;
2098
hqvFilterCtl &= 0xfffdffff;
2101
/* Temporary fix for 2D bandwidth problem. 2002/08/01 */
2102
if (pVia->swov.gdwUseExtendedFIFO)
2103
miniCtl &= ~V1_Y_INTERPOLY;
2105
SetMiniAndZoom(pVia, videoFlag, miniCtl, tmp);
2107
if (srcHeight == dstHeight)
2108
hqvFilterCtl &= 0xfffdffff;
2109
SetMiniAndZoom(pVia, videoFlag, 0, 0);
2111
if (hwDiff->dwNewScaleCtl) {
2112
SaveVideoRegister(pVia, HQV_H_SCALE_CONTROL + proReg, hqvScaleCtlH);
2113
SaveVideoRegister(pVia, HQV_V_SCALE_CONTROL + proReg, hqvScaleCtlV);
2115
SaveVideoRegister(pVia, HQV_MINIFY_CONTROL + proReg, hqvMiniCtl);
2117
SaveVideoRegister(pVia, HQV_FILTER_CONTROL + proReg, hqvFilterCtl);
2119
SetMiniAndZoom(pVia, videoFlag, miniCtl, zoomCtl);
2122
compose = SetColorKey(pVia, videoFlag, colorKeyLow, colorKeyHigh,
2126
compose = SetChromaKey(pVia, videoFlag, chromaKeyLow, chromaKeyHigh,
2129
if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
2130
SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL1),0);
2131
SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL3),((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
2132
if ((pVia->Chipset == VIA_VX800) ||
2133
(pVia->Chipset == VIA_VX855) ||
2134
(pVia->Chipset == VIA_VX900)) {
2135
SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL2),0);
2136
SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL4),((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
2137
if ((pVia->Chipset == VIA_VX855) ||
2138
(pVia->Chipset == VIA_VX900)) {
2139
SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL1,0);
2140
SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL3,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
2141
SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL2,0);
2142
SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL4,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
2143
SaveVideoRegister(pVia, HQV_BACKGROUND_DATA_OFFSET,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
2144
SaveVideoRegister(pVia, HQV_EXTENDED_CONTROL,0);
2146
SaveVideoRegister(pVia, HQV_SUBP_HSCALE_CTRL,0);
2148
SaveVideoRegister(pVia, HQV_SUBP_VSCALE_CTRL,0);
2151
if (pVia->Chipset == VIA_VX900) {
2153
SaveVideoRegister(pVia, HQV_SHARPNESS_DECODER_HANDSHAKE_CTRL_410, 0);
2156
// TODO Need to be tested on VX800
2158
SaveVideoRegister(pVia, HQV_DEFAULT_VIDEO_COLOR, HQV_FIX_COLOR);
2163
/* Set up video control */
2164
if (videoFlag & VIDEO_HQV_INUSE) {
2166
if (!pVia->swov.SWVideo_ON) {
2167
DBG_DD(ErrorF(" First HQV\n"));
2169
FlushVidRegBuffer(pVia);
2171
DBG_DD(ErrorF(" Wait flips"));
2173
if (hwDiff->dwHQVInitPatch) {
2174
DBG_DD(ErrorF(" Initializing HQV twice ..."));
2175
for (i = 0; i < 2; i++) {
2176
viaWaitHQVFlipClear(pVia,
2177
((hqvCtl & ~HQV_SW_FLIP) |
2178
HQV_FLIP_STATUS) & ~HQV_ENABLE);
2179
VIASETREG(HQV_CONTROL + proReg, hqvCtl);
2180
viaWaitHQVFlip(pVia);
2182
DBG_DD(ErrorF(" done.\n"));
2183
} else { /* CLE_C0 */
2184
CARD32 volatile *HQVCtrl =
2185
(CARD32 volatile *)(pVia->MapBase + HQV_CONTROL +
2188
/* Check that HQV is idle */
2189
DBG_DD(ErrorF("HQV control wf - %08lx\n", *HQVCtrl));
2190
while (!(*HQVCtrl & HQV_IDLE)) {
2191
DBG_DD(ErrorF("HQV control busy - %08lx\n", *HQVCtrl));
2195
VIASETREG(HQV_CONTROL + proReg, hqvCtl & ~HQV_SW_FLIP);
2196
VIASETREG(HQV_CONTROL + proReg, hqvCtl | HQV_SW_FLIP);
2198
DBG_DD(ErrorF("HQV control wf5 - %08lx\n", *HQVCtrl));
2199
DBG_DD(ErrorF(" Wait flips5"));
2201
if (pVia->VideoEngine != VIDEO_ENGINE_CME) {
2202
for (i = 0; (i < 50) && !(*HQVCtrl & HQV_FLIP_STATUS);
2204
DBG_DD(ErrorF(" HQV wait %d %08lx\n", i, *HQVCtrl));
2205
*HQVCtrl |= HQV_SW_FLIP | HQV_FLIP_STATUS;
2209
viaWaitHQVFlip(pVia);
2212
DBG_DD(ErrorF(" Wait flips6"));
2215
if (videoFlag & VIDEO_1_INUSE) {
2216
VIASETREG(V1_CONTROL, vidCtl);
2217
VIASETREG(V_COMPOSE_MODE, compose | V1_COMMAND_FIRE);
2218
if (pVia->swov.gdwUseExtendedFIFO) {
2219
/* Set Display FIFO */
2220
DBG_DD(ErrorF(" Wait flips7"));
2222
DBG_DD(ErrorF(" Wait flips 8"));
2223
hwp->writeSeq(hwp, 0x17, 0x2F);
2224
ViaSeqMask(hwp, 0x16, 0x14, 0x1F);
2225
hwp->writeSeq(hwp, 0x18, 0x56);
2226
DBG_DD(ErrorF(" Wait flips 9"));
2229
DBG_DD(ErrorF(" Wait flips 10"));
2230
VIASETREG(V3_CONTROL, vidCtl);
2231
VIASETREG(V_COMPOSE_MODE, compose | V3_COMMAND_FIRE);
2233
DBG_DD(ErrorF(" Done flips"));
2235
DBG_DD(ErrorF(" Normal called\n"));
2236
SaveVideoRegister(pVia, HQV_CONTROL + proReg,
2237
hqvCtl | HQV_FLIP_STATUS);
2238
SetVideoControl(pVia, videoFlag, vidCtl);
2239
FireVideoCommand(pVia, videoFlag, compose);
2240
viaWaitHQVDone(pVia);
2241
FlushVidRegBuffer(pVia);
2244
SetVideoControl(pVia, videoFlag, vidCtl);
2245
FireVideoCommand(pVia, videoFlag, compose);
2246
viaWaitHQVDone(pVia);
2247
FlushVidRegBuffer(pVia);
2249
pVia->swov.SWVideo_ON = TRUE;
2251
DBG_DD(ErrorF(" Done Upd_Video"));
2258
* VIAVidUpdateOverlay()
2259
* Parameters: src rectangle, dst rectangle, colorkey...
2260
* Return value: unsigned long of state
2261
* Note: updates the overlay image parameter.
2264
VIAVidUpdateOverlay(xf86CrtcPtr crtc, LPDDUPDATEOVERLAY pUpdate)
2266
ScrnInfoPtr pScrn = crtc->scrn;
2267
VIAPtr pVia = VIAPTR(pScrn);
2268
OVERLAYRECORD *ovlV1 = &pVia->swov.overlayRecordV1;
2270
unsigned long flags = pUpdate->dwFlags;
2271
unsigned long videoFlag = 0;
2272
unsigned long startAddr = 0;
2273
unsigned long deinterlaceMode = 0;
2275
unsigned long haveColorKey = 0, haveChromaKey = 0;
2276
unsigned long colorKeyLow = 0, colorKeyHigh = 0;
2277
unsigned long chromaKeyLow = 0, chromaKeyHigh = 0;
2279
unsigned long scrnWidth, scrnHeight;
2280
int dstTop, dstBottom, dstLeft, dstRight;
2281
int panDX, panDY; /* Panning delta */
2283
unsigned long proReg = 0;
2285
panDX = pVia->swov.panning_x;
2286
panDY = pVia->swov.panning_y;
2287
pVia->swov.oldPanningX = pVia->swov.panning_x;
2288
pVia->swov.oldPanningY = pVia->swov.panning_y;
2290
pUpdate->DstLeft -= panDX;
2291
pUpdate->DstTop -= panDY;
2292
pUpdate->DstRight -= panDX;
2293
pUpdate->DstBottom -= panDY;
2295
DBG_DD(ErrorF("Raw rSrc X (%ld,%ld) Y (%ld,%ld)\n",
2296
pUpdate->SrcLeft, pUpdate->SrcRight,
2297
pUpdate->SrcTop, pUpdate->SrcBottom));
2298
DBG_DD(ErrorF("Raw rDest X (%ld,%ld) Y (%ld,%ld)\n",
2299
pUpdate->DstLeft, pUpdate->DstRight,
2300
pUpdate->DstTop, pUpdate->DstBottom));
2302
if ((pVia->swov.SrcFourCC == FOURCC_YUY2) ||
2303
(pVia->swov.SrcFourCC == FOURCC_RV15) ||
2304
(pVia->swov.SrcFourCC == FOURCC_RV16) ||
2305
(pVia->swov.SrcFourCC == FOURCC_RV32) ||
2306
(pVia->swov.SrcFourCC == FOURCC_YV12) ||
2307
(pVia->swov.SrcFourCC == FOURCC_I420) ||
2308
(pVia->swov.SrcFourCC == FOURCC_XVMC)) {
2309
videoFlag = pVia->swov.gdwVideoFlagSW;
2312
if (pVia->ChipId == PCI_CHIP_VT3259 && !(videoFlag & VIDEO_1_INUSE))
2313
proReg = PRO_HQV1_OFFSET;
2315
flags |= DDOVER_INTERLEAVED;
2317
/* Disable destination color keying if the alpha window is in use. */
2318
if (pVia->swov.gdwAlphaEnabled)
2319
flags &= ~DDOVER_KEYDEST;
2321
ResetVidRegBuffer(pVia);
2323
/* For SW decode HW overlay use */
2324
startAddr = VIAGETREG(HQV_SRC_STARTADDR_Y + proReg);
2326
if (flags & DDOVER_KEYDEST) {
2328
colorKeyLow = pUpdate->dwColorSpaceLowValue;
2331
if (flags & DDOVER_INTERLEAVED)
2332
deinterlaceMode |= DDOVER_INTERLEAVED;
2334
if (flags & DDOVER_BOB)
2335
deinterlaceMode |= DDOVER_BOB;
2337
if ((pVia->ChipId == PCI_CHIP_CLE3122)
2338
&& (pScrn->currentMode->HDisplay > 1024)) {
2339
DBG_DD(ErrorF("UseExtendedFIFO\n"));
2340
pVia->swov.gdwUseExtendedFIFO = 1;
2342
pVia->swov.gdwUseExtendedFIFO = 0;
2344
/* Figure out actual rSrc rectangle */
2346
dstLeft = pUpdate->DstLeft;
2347
dstTop = pUpdate->DstTop;
2348
dstRight = pUpdate->DstRight;
2349
dstBottom = pUpdate->DstBottom;
2351
scrnWidth = pScrn->currentMode->HDisplay;
2352
scrnHeight = pScrn->currentMode->VDisplay;
2355
pUpdate->SrcLeft = ((((-dstLeft) * ovlV1->dwV1OriWidth) +
2356
((dstRight - dstLeft) >> 1))
2357
/ (dstRight - dstLeft));
2359
if (dstRight > scrnWidth) {
2360
pUpdate->SrcRight = ((((scrnWidth - dstLeft) * ovlV1->dwV1OriWidth) +
2361
((dstRight - dstLeft) >> 1))
2362
/ (dstRight - dstLeft));
2365
pUpdate->SrcTop = ((((-dstTop) * ovlV1->dwV1OriHeight) +
2366
((dstBottom - dstTop) >> 1))
2367
/ (dstBottom - dstTop));
2369
if (dstBottom > scrnHeight) {
2370
pUpdate->SrcBottom = ((((scrnHeight - dstTop) * ovlV1->dwV1OriHeight) +
2371
((dstBottom - dstTop) >> 1))
2372
/ (dstBottom - dstTop));
2375
/* Save modified src & original dest rectangle parameters */
2377
if ((pVia->swov.SrcFourCC == FOURCC_YUY2) ||
2378
(pVia->swov.SrcFourCC == FOURCC_RV15) ||
2379
(pVia->swov.SrcFourCC == FOURCC_RV16) ||
2380
(pVia->swov.SrcFourCC == FOURCC_RV32) ||
2381
(pVia->swov.SrcFourCC == FOURCC_YV12) ||
2382
(pVia->swov.SrcFourCC == FOURCC_I420) ||
2383
(pVia->swov.SrcFourCC == FOURCC_XVMC)) {
2384
pVia->swov.SWDevice.gdwSWDstLeft = pUpdate->DstLeft + panDX;
2385
pVia->swov.SWDevice.gdwSWDstTop = pUpdate->DstTop + panDY;
2386
pVia->swov.SWDevice.gdwSWDstWidth =
2387
pUpdate->DstRight - pUpdate->DstLeft;
2388
pVia->swov.SWDevice.gdwSWDstHeight =
2389
pUpdate->DstBottom - pUpdate->DstTop;
2391
pVia->swov.SWDevice.gdwSWSrcWidth = ovlV1->dwV1SrcWidth =
2392
pUpdate->SrcRight - pUpdate->SrcLeft;
2393
pVia->swov.SWDevice.gdwSWSrcHeight = ovlV1->dwV1SrcHeight =
2394
pUpdate->SrcBottom - pUpdate->SrcTop;
2397
ovlV1->dwV1SrcLeft = pUpdate->SrcLeft;
2398
ovlV1->dwV1SrcRight = pUpdate->SrcRight;
2399
ovlV1->dwV1SrcTop = pUpdate->SrcTop;
2400
ovlV1->dwV1SrcBot = pUpdate->SrcBottom;
2402
/* Figure out actual rDest rectangle */
2404
pUpdate->DstLeft = (dstLeft < 0) ? 0 : dstLeft;
2405
pUpdate->DstTop = (dstTop < 0) ? 0 : dstTop;
2406
if (pUpdate->DstTop >= scrnHeight)
2407
pUpdate->DstTop = scrnHeight - 1;
2408
pUpdate->DstRight = (dstRight > scrnWidth) ? scrnWidth : dstRight;
2409
pUpdate->DstBottom = (dstBottom > scrnHeight) ? scrnHeight : dstBottom;
2411
/* Update the overlay */
2413
if (!Upd_Video(crtc, videoFlag, startAddr, pUpdate,
2414
pVia->swov.SWDevice.dwPitch, ovlV1->dwV1OriWidth,
2415
ovlV1->dwV1OriHeight, deinterlaceMode, haveColorKey,
2416
haveChromaKey, colorKeyLow, colorKeyHigh, chromaKeyLow,
2420
pVia->swov.SWVideo_ON = FALSE;
2424
} /* VIAVidUpdateOverlay */
2430
ViaOverlayHide(ScrnInfoPtr pScrn)
2432
VIAPtr pVia = VIAPTR(pScrn);
2433
vgaHWPtr hwp = VGAHWPTR(pScrn);
2434
CARD32 videoFlag = 0;
2435
unsigned long proReg = 0;
2437
if ((pVia->swov.SrcFourCC == FOURCC_YUY2) ||
2438
(pVia->swov.SrcFourCC == FOURCC_RV15) ||
2439
(pVia->swov.SrcFourCC == FOURCC_RV16) ||
2440
(pVia->swov.SrcFourCC == FOURCC_RV32) ||
2441
(pVia->swov.SrcFourCC == FOURCC_YV12) ||
2442
(pVia->swov.SrcFourCC == FOURCC_I420) ||
2443
(pVia->swov.SrcFourCC == FOURCC_XVMC))
2444
videoFlag = pVia->swov.gdwVideoFlagSW;
2446
if (pVia->ChipId == PCI_CHIP_VT3259 && !(videoFlag & VIDEO_1_INUSE))
2447
proReg = PRO_HQV1_OFFSET;
2449
ResetVidRegBuffer(pVia);
2451
if (pVia->HWDiff.dwHQVDisablePatch)
2452
ViaSeqMask(hwp, 0x2E, 0x00, 0x10);
2454
SaveVideoRegister(pVia, V_FIFO_CONTROL, V1_FIFO_PRETHRESHOLD12 |
2455
V1_FIFO_THRESHOLD8 | V1_FIFO_DEPTH16);
2456
SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL,
2457
ALPHA_FIFO_THRESHOLD4 | ALPHA_FIFO_DEPTH8 |
2458
V3_FIFO_THRESHOLD24 | V3_FIFO_DEPTH32);
2460
if (videoFlag & VIDEO_HQV_INUSE)
2461
SaveVideoRegister(pVia, HQV_CONTROL + proReg,
2462
VIAGETREG(HQV_CONTROL + proReg) & ~HQV_ENABLE);
2464
if (videoFlag & VIDEO_1_INUSE)
2465
SaveVideoRegister(pVia, V1_CONTROL, VIAGETREG(V1_CONTROL) & ~V1_ENABLE);
2467
SaveVideoRegister(pVia, V3_CONTROL, VIAGETREG(V3_CONTROL) & ~V3_ENABLE);
2469
FireVideoCommand(pVia, videoFlag, VIAGETREG(V_COMPOSE_MODE));
2470
FlushVidRegBuffer(pVia);
2472
if (pVia->HWDiff.dwHQVDisablePatch)
2473
ViaSeqMask(hwp, 0x2E, 0x10, 0x10);
2475
pVia->swov.SWVideo_ON = FALSE;
2476
pVia->VideoStatus &= ~VIDEO_SWOV_ON;