summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/radeon_reg.h12
-rw-r--r--src/radeon_video.c1266
-rw-r--r--src/radeon_video.h5
-rw-r--r--src/theatre.c5
4 files changed, 1226 insertions, 62 deletions
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 6e2a4431..02c9b50e 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -845,6 +845,17 @@
#define RADEON_N_VIF_COUNT 0x0248
#define RADEON_OV0_AUTO_FLIP_CNTL 0x0470
+# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_NUM 0x00000007
+# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_REPEAT_FIELD 0x00000008
+# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 0x00000010
+# define RADEON_OV0_AUTO_FLIP_CNTL_IGNORE_REPEAT_FIELD 0x00000020
+# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE 0x00000040
+# define RADEON_OV0_AUTO_FLIP_CNTL_VID_PORT_SELECT 0x00000300
+# define RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 0x00010000
+# define RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN 0x00040000
+# define RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN 0x00080000
+# define RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE 0x00800000
+
#define RADEON_OV0_COLOUR_CNTL 0x04E0
#define RADEON_OV0_DEINTERLACE_PATTERN 0x0474
#define RADEON_OV0_EXCLUSIVE_HORZ 0x0408
@@ -861,6 +872,7 @@
#define RADEON_OV0_FOUR_TAP_COEF_2 0x04B8
#define RADEON_OV0_FOUR_TAP_COEF_3 0x04BC
#define RADEON_OV0_FOUR_TAP_COEF_4 0x04C0
+#define RADEON_OV0_FLAG_CNTL 0x04DC
#define RADEON_OV0_GAMMA_000_00F 0x0d40
#define RADEON_OV0_GAMMA_010_01F 0x0d44
#define RADEON_OV0_GAMMA_020_03F 0x0d48
diff --git a/src/radeon_video.c b/src/radeon_video.c
index e229a184..02a1c82f 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -15,6 +15,9 @@
#include "fourcc.h"
#include "theatre_reg.h"
+#include "fi1236.h"
+#include "msp3430.h"
+#include "tda9885.h"
#define OFF_DELAY 250 /* milliseconds */
#define FREE_DELAY 15000
@@ -25,6 +28,40 @@
#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+/* capture config constants */
+#define BUF_TYPE_FIELD 0
+#define BUF_TYPE_ALTERNATING 1
+#define BUF_TYPE_FRAME 2
+
+
+#define BUF_MODE_SINGLE 0
+#define BUF_MODE_DOUBLE 1
+#define BUF_MODE_TRIPLE 2
+/* CAP0_CONFIG values */
+
+#define FORMAT_BROOKTREE 0
+#define FORMAT_CCIR656 1
+#define FORMAT_ZV 2
+#define FORMAT_VIP16 3
+#define FORMAT_TRANSPORT 4
+
+#define ENABLE_RADEON_CAPTURE_WEAVE (RADEON_CAP0_CONFIG_CONTINUOS \
+ | (BUF_MODE_DOUBLE <<7) \
+ | (BUF_TYPE_FRAME << 4) \
+ | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
+ | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
+ | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
+ | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
+
+#define ENABLE_RADEON_CAPTURE_BOB (RADEON_CAP0_CONFIG_CONTINUOS \
+ | (BUF_MODE_SINGLE <<7) \
+ | (BUF_TYPE_ALTERNATING << 4) \
+ | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \
+ | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \
+ | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \
+ | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422)
+
+
static void RADEONInitOffscreenImages(ScreenPtr);
static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr);
@@ -40,8 +77,15 @@ static int RADEONQueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
unsigned short *, int *, int *);
static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now);
+static int RADEONPutVideo(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y,
+ short src_w, short src_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data);
+
static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv);
static void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv);
+static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv);
+static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv);
+static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv);
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
@@ -52,6 +96,14 @@ static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
static Atom xvGamma, xvColorspace;
static Atom xvSwitchCRT;
+static Atom xvEncoding, xvFrequency, xvVolume, xvMute,
+ xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
+ xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
+ xvLocationID, xvDeviceID, xvInstanceID, xvDumpStatus,
+ xvAdjustment;
+
+static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode;
+
#define GET_PORT_PRIVATE(pScrn) \
(RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
@@ -133,6 +185,7 @@ static XF86VideoFormatRec Formats[NUM_FORMATS] =
};
+#if 0
#define NUM_ATTRIBUTES 9+6
static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
@@ -154,6 +207,157 @@ static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
{XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
};
+#endif
+
+#define NUM_ATTRIBUTES 22
+#define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12)
+
+static XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] =
+{
+ { XvGettable, 0, ~0, "XV_DEVICE_ID"},
+ { XvGettable, 0, ~0, "XV_LOCATION_ID"},
+ { XvGettable, 0, ~0, "XV_INSTANCE_ID"},
+ {XvSettable , 0, 1, "XV_DUMP_STATUS"},
+ {XvSettable , 0, 1, "XV_SET_DEFAULTS"},
+ {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
+ {XvSettable | XvGettable, 0, ~0,"XV_COLORKEY"},
+ {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
+ {XvSettable | XvGettable, 0, 255, "XV_OVERLAY_ALPHA"},
+ {XvSettable | XvGettable, 0, 255, "XV_GRAPHICS_ALPHA"},
+ {XvSettable | XvGettable, 0, 1, "XV_ALPHA_MODE"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
+ {XvSettable | XvGettable, 0, 1, "XV_SWITCHCRT"},
+ {XvSettable | XvGettable, 100, 10000, "XV_GAMMA"},
+ {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
+
+ {XvSettable | XvGettable, -1000, 1000, "XV_DEC_BRIGHTNESS"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_DEC_CONTRAST"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_DEC_SATURATION"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_DEC_HUE"},
+ {XvSettable | XvGettable, 0, 2, "XV_OVERLAY_DEINTERLACING_METHOD"},
+ {XvSettable | XvGettable, 0, 12, "XV_ENCODING"},
+ {XvSettable | XvGettable, 0, -1, "XV_FREQ"},
+ { XvGettable, -1000, 1000, "XV_TUNER_STATUS"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_VOLUME"},
+ {XvSettable | XvGettable, 0, 1, "XV_MUTE"},
+ {XvSettable | XvGettable, 0, 1, "XV_SAP"},
+ {XvSettable | XvGettable, 0, 0x1F, "XV_DEBUG_ADJUSTMENT"},
+ { 0, 0, 0, NULL} /* just a place holder so I don't have to be fancy with commas */
+};
+
+
+#define INCLUDE_RGB_FORMATS 1
+
+#if INCLUDE_RGB_FORMATS
+
+#define NUM_IMAGES 8
+
+/* Note: GUIDs are bogus... - but nothing uses them anyway */
+
+#define FOURCC_RGBA32 0x41424752
+
+#define XVIMAGE_RGBA32(byte_order) \
+ { \
+ FOURCC_RGBA32, \
+ XvRGB, \
+ byte_order, \
+ { 'R', 'G', 'B', 'A', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 32, \
+ XvPacked, \
+ 1, \
+ 32, 0x00FF0000, 0x0000FF00, 0x000000FF, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ {'A', 'R', 'G', 'B', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_RGB24 0x00000000
+
+#define XVIMAGE_RGB24(byte_order) \
+ { \
+ FOURCC_RGB24, \
+ XvRGB, \
+ byte_order, \
+ { 'R', 'G', 'B', 0, \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 24, \
+ XvPacked, \
+ 1, \
+ 24, 0x00FF0000, 0x0000FF00, 0x000000FF, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ { 'R', 'G', 'B', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_RGBT16 0x54424752
+
+#define XVIMAGE_RGBT16(byte_order) \
+ { \
+ FOURCC_RGBT16, \
+ XvRGB, \
+ byte_order, \
+ { 'R', 'G', 'B', 'T', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 16, \
+ XvPacked, \
+ 1, \
+ 16, 0x00007C00, 0x000003E0, 0x0000001F, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ {'A', 'R', 'G', 'B', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define FOURCC_RGB16 0x32424752
+
+#define XVIMAGE_RGB16(byte_order) \
+ { \
+ FOURCC_RGB16, \
+ XvRGB, \
+ byte_order, \
+ { 'R', 'G', 'B', 0x00, \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 16, \
+ XvPacked, \
+ 1, \
+ 16, 0x0000F800, 0x000007E0, 0x0000001F, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ {'R', 'G', 'B', \
+ 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+static XF86ImageRec Images[NUM_IMAGES] =
+{
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ XVIMAGE_RGBA32(MSBFirst),
+ XVIMAGE_RGB24(MSBFirst),
+ XVIMAGE_RGBT16(MSBFirst),
+ XVIMAGE_RGB16(MSBFirst),
+#else
+ XVIMAGE_RGBA32(LSBFirst),
+ XVIMAGE_RGB24(LSBFirst),
+ XVIMAGE_RGBT16(LSBFirst),
+ XVIMAGE_RGB16(LSBFirst),
+#endif
+ XVIMAGE_YUY2,
+ XVIMAGE_UYVY,
+ XVIMAGE_YV12,
+ XVIMAGE_I420
+};
+
+#else
+
#define NUM_IMAGES 4
static XF86ImageRec Images[NUM_IMAGES] =
@@ -164,6 +368,8 @@ static XF86ImageRec Images[NUM_IMAGES] =
XVIMAGE_I420
};
+#endif
+
/* Reference color space transform data */
typedef struct tagREF_TRANSFORM
{
@@ -727,6 +933,58 @@ static void RADEONSetTransform (ScrnInfoPtr pScrn,
OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr);
}
+static void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (alpha_mode == 0) { /* key mode */
+ OUTREG(RADEON_OV0_KEY_CNTL,
+ RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */
+ RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */
+ RADEON_CMP_MIX_OR);
+ /* crtc 1 */
+ OUTREG(RADEON_DISP_MERGE_CNTL,
+ (RADEON_DISP_ALPHA_MODE_KEY &
+ RADEON_DISP_ALPHA_MODE_MASK) |
+ ((gr_alpha << 0x00000010) &
+ RADEON_DISP_GRPH_ALPHA_MASK) |
+ ((ov_alpha << 0x00000018) &
+ RADEON_DISP_OV0_ALPHA_MASK));
+ /* crtc 2 */
+ OUTREG(RADEON_DISP2_MERGE_CNTL,
+ (RADEON_DISP_ALPHA_MODE_KEY &
+ RADEON_DISP_ALPHA_MODE_MASK) |
+ ((gr_alpha << 0x00000010) &
+ RADEON_DISP_GRPH_ALPHA_MASK) |
+ ((ov_alpha << 0x00000018) &
+ RADEON_DISP_OV0_ALPHA_MASK));
+ } else { /* global mode */
+ OUTREG(RADEON_OV0_KEY_CNTL,
+ RADEON_GRAPHIC_KEY_FN_FALSE | /* what does this do? */
+ RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */
+ RADEON_CMP_MIX_AND);
+ /* crtc 2 */
+ OUTREG(RADEON_DISP2_MERGE_CNTL,
+ (RADEON_DISP_ALPHA_MODE_GLOBAL &
+ RADEON_DISP_ALPHA_MODE_MASK) |
+ ((gr_alpha << 0x00000010) &
+ RADEON_DISP_GRPH_ALPHA_MASK) |
+ ((ov_alpha << 0x00000018) &
+ RADEON_DISP_OV0_ALPHA_MASK));
+ /* crtc 1 */
+ OUTREG(RADEON_DISP_MERGE_CNTL,
+ (RADEON_DISP_ALPHA_MODE_GLOBAL &
+ RADEON_DISP_ALPHA_MODE_MASK) |
+ ((gr_alpha << 0x00000010) &
+ RADEON_DISP_GRPH_ALPHA_MASK) |
+ ((ov_alpha << 0x00000018) &
+ RADEON_DISP_OV0_ALPHA_MASK));
+ }
+ /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */
+ /* not yet supported */
+}
+
static void RADEONSetColorKey(ScrnInfoPtr pScrn, CARD32 colorKey)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -769,12 +1027,65 @@ RADEONResetVideo(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
+ char tmp[200];
/* this function is called from ScreenInit. pScreen is used
by XAA internally, but not valid until ScreenInit finishs.
*/
if (info->accelOn && pScrn->pScreen) info->accel->Sync(pScrn);
+ /* this is done here because each time the server is reset these
+ could change.. Otherwise they remain constant */
+ xvInstanceID = MAKE_ATOM("XV_INSTANCE_ID");
+ xvDeviceID = MAKE_ATOM("XV_DEVICE_ID");
+ xvLocationID = MAKE_ATOM("XV_LOCATION_ID");
+ xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS");
+
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvSaturation = MAKE_ATOM("XV_SATURATION");
+ xvColor = MAKE_ATOM("XV_COLOR");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
+ xvHue = MAKE_ATOM("XV_HUE");
+ xvRedIntensity = MAKE_ATOM("XV_RED_INTENSITY");
+ xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY");
+ xvBlueIntensity = MAKE_ATOM("XV_BLUE_INTENSITY");
+ xvGamma = MAKE_ATOM("XV_GAMMA");
+ xvColorspace = MAKE_ATOM("XV_COLORSPACE");
+
+ xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+ xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
+ xvSwitchCRT = MAKE_ATOM("XV_SWITCHCRT");
+
+ xvOvAlpha = MAKE_ATOM("XV_OVERLAY_ALPHA");
+ xvGrAlpha = MAKE_ATOM("XV_GRAPHICS_ALPHA");
+ xvAlphaMode = MAKE_ATOM("XV_ALPHA_MODE");
+
+ xvOverlayDeinterlacingMethod = MAKE_ATOM("XV_OVERLAY_DEINTERLACING_METHOD");
+
+ xvDecBrightness = MAKE_ATOM("XV_DEC_BRIGHTNESS");
+ xvDecSaturation = MAKE_ATOM("XV_DEC_SATURATION");
+ xvDecColor = MAKE_ATOM("XV_DEC_COLOR");
+ xvDecContrast = MAKE_ATOM("XV_DEC_CONTRAST");
+ xvDecHue = MAKE_ATOM("XV_DEC_HUE");
+
+ xvEncoding = MAKE_ATOM("XV_ENCODING");
+ xvFrequency = MAKE_ATOM("XV_FREQ");
+ xvTunerStatus = MAKE_ATOM("XV_TUNER_STATUS");
+ xvVolume = MAKE_ATOM("XV_VOLUME");
+ xvMute = MAKE_ATOM("XV_MUTE");
+ xvSAP = MAKE_ATOM("XV_SAP");
+
+ xvAdjustment = MAKE_ATOM("XV_DEBUG_ADJUSTMENT");
+
+ sprintf(tmp, "RXXX:%d.%d.%d", info->PciInfo->vendor, info->PciInfo->chipType, info->PciInfo->chipRev);
+ pPriv->device_id = MAKE_ATOM(tmp);
+ sprintf(tmp, "PCI:%02d:%02d.%d", info->PciInfo->bus, info->PciInfo->device, info->PciInfo->func);
+ pPriv->location_id = MAKE_ATOM(tmp);
+ sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex);
+ pPriv->instance_id = MAKE_ATOM(tmp);
+
OUTREG(RADEON_OV0_SCALE_CNTL, 0x80000000);
OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0); /* maybe */
OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0);
@@ -815,6 +1126,18 @@ RADEONResetVideo(ScrnInfoPtr pScrn)
RADEONSetOverlayGamma(pScrn, 0); /* gamma = 1.0 */
+ if(pPriv->VIP!=NULL){
+ RADEONVIP_reset(pScrn,pPriv);
+ }
+
+ if(pPriv->theatre != NULL) {
+ xf86_InitTheatre(pPriv->theatre);
+/* xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); */
+ }
+
+ if(pPriv->i2c != NULL){
+ RADEONResetI2C(pScrn, pPriv);
+ }
}
static void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
@@ -938,6 +1261,10 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
pPriv->crt2 = TRUE;
else
pPriv->crt2 = FALSE;
+
+ pPriv->ov_alpha = 255;
+ pPriv->gr_alpha = 255;
+ pPriv->alpha_mode = 0;
/* TV-in stuff */
pPriv->video_stream_active = FALSE;
@@ -1101,23 +1428,16 @@ RADEONSetupImageVideo(ScreenPtr pScreen)
pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr);
REGION_NULL(pScreen, &(pPriv->clip));
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvSaturation = MAKE_ATOM("XV_SATURATION");
- xvColor = MAKE_ATOM("XV_COLOR");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvColorKey = MAKE_ATOM("XV_COLORKEY");
- xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
- xvHue = MAKE_ATOM("XV_HUE");
- xvRedIntensity = MAKE_ATOM("XV_RED_INTENSITY");
- xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY");
- xvBlueIntensity = MAKE_ATOM("XV_BLUE_INTENSITY");
- xvGamma = MAKE_ATOM("XV_GAMMA");
- xvColorspace = MAKE_ATOM("XV_COLORSPACE");
+ if(pPriv->theatre != NULL)
+ {
+ /* video decoder is present, extend capabilities */
+ adapt->nEncodings = 13;
+ adapt->pEncodings = InputVideoEncodings;
+ adapt->type |= XvVideoMask;
+ adapt->nAttributes = NUM_DEC_ATTRIBUTES;
+ adapt->PutVideo = RADEONPutVideo;
+ }
- xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
- xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
- xvSwitchCRT = MAKE_ATOM("XV_SWITCHCRT");
-
RADEONResetVideo(pScrn);
return adapt;
@@ -1137,6 +1457,15 @@ RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
RADEONWaitForFifo(pScrn, 2);
OUTREG(RADEON_OV0_SCALE_CNTL, 0);
}
+ if(pPriv->video_stream_active){
+ RADEONWaitForFifo(pScrn, 2);
+ OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND);
+ OUTREG(RADEON_CAP0_TRIG_CNTL, 0);
+ RADEONResetVideo(pScrn);
+ pPriv->video_stream_active = FALSE;
+ if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
+ if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
+ }
if(info->videoLinear) {
xf86FreeOffscreenLinear(info->videoLinear);
info->videoLinear = NULL;
@@ -1159,6 +1488,8 @@ RADEONSetPortAttribute(ScrnInfoPtr pScrn,
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
Bool setTransform = FALSE;
+ Bool setAlpha = FALSE;
+ unsigned char *RADEONMMIO = info->MMIO;
info->accel->Sync(pScrn);
@@ -1185,7 +1516,23 @@ RADEONSetPortAttribute(ScrnInfoPtr pScrn,
pPriv->gamma = 1000;
pPriv->transform_index = 0;
pPriv->doubleBuffer = FALSE;
+ pPriv->ov_alpha = 255;
+ pPriv->gr_alpha = 255;
+ pPriv->alpha_mode = 0;
+
+ /* It is simpler to call itself */
+ RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data);
+ RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data);
+ RADEONSetPortAttribute(pScrn, xvDecContrast, 0, data);
+ RADEONSetPortAttribute(pScrn, xvDecHue, 0, data);
+
+ RADEONSetPortAttribute(pScrn, xvVolume, -1000, data);
+ RADEONSetPortAttribute(pScrn, xvMute, 1, data);
+ RADEONSetPortAttribute(pScrn, xvSAP, 0, data);
+ RADEONSetPortAttribute(pScrn, xvDoubleBuffer, 1, data);
+
setTransform = TRUE;
+ setAlpha = TRUE;
}
else if(attribute == xvBrightness)
{
@@ -1251,8 +1598,132 @@ RADEONSetPortAttribute(ScrnInfoPtr pScrn,
info->OverlayOnCRTC2 = TRUE;
else
info->OverlayOnCRTC2 = FALSE;
+ }
+ else if(attribute == xvOvAlpha)
+ {
+ pPriv->ov_alpha = ClipValue (value, 0, 255);
+ setAlpha = TRUE;
+ }
+ else if(attribute == xvGrAlpha)
+ {
+ pPriv->gr_alpha = ClipValue (value, 0, 255);
+ setAlpha = TRUE;
}
- else
+ else if(attribute == xvAlphaMode)
+ {
+ pPriv->alpha_mode = ClipValue (value, 0, 1);
+ setAlpha = TRUE;
+ }
+ else if(attribute == xvDecBrightness)
+ {
+ pPriv->dec_brightness = value;
+ if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness);
+ }
+ else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
+ {
+ if(value<-1000)value = -1000;
+ if(value>1000)value = 1000;
+ pPriv->dec_saturation = value;
+ if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value);
+ }
+ else if(attribute == xvDecContrast)
+ {
+ pPriv->dec_contrast = value;
+ if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value);
+ }
+ else if(attribute == xvDecHue)
+ {
+ pPriv->dec_hue = value;
+ if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value);
+ }
+ else if(attribute == xvEncoding)
+ {
+ pPriv->encoding = value;
+ if(pPriv->video_stream_active)
+ {
+ if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv);
+ if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
+ if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
+ if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
+ if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
+ /* put more here to actually change it */
+ }
+ }
+ else if(attribute == xvFrequency)
+ {
+ pPriv->frequency = value;
+ /* mute volume if it was not muted before */
+ if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
+ if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value);
+/* if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv); */
+ if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck))
+ xf86_InitMSP3430(pPriv->msp3430);
+ if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume));
+ }
+ else if(attribute == xvMute)
+ {
+ pPriv->mute = value;
+ if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
+ if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
+ }
+ else if(attribute == xvSAP)
+ {
+ pPriv->sap_channel = value;
+ if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3);
+ }
+ else if(attribute == xvVolume)
+ {
+ if(value<-1000)value = -1000;
+ if(value>1000)value = 1000;
+ pPriv->volume = value;
+ pPriv->mute = FALSE;
+ if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value));
+ if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv);
+ }
+ else if(attribute == xvOverlayDeinterlacingMethod)
+ {
+ if(value<0)value = 0;
+ if(value>2)value = 2;
+ pPriv->overlay_deinterlacing_method = value;
+ switch(pPriv->overlay_deinterlacing_method){
+ case METHOD_BOB:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
+ break;
+ case METHOD_SINGLE:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
+ break;
+ case METHOD_WEAVE:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0);
+ break;
+ default:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
+ }
+ }
+ else if(attribute == xvDumpStatus)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n",
+ pScrn->currentMode->Flags,
+ pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" ,
+ pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : ""
+ );
+ if(pPriv->tda9885 != NULL){
+ xf86_tda9885_getstatus(pPriv->tda9885);
+ xf86_tda9885_dumpstatus(pPriv->tda9885);
+ }
+ if(pPriv->fi1236!=NULL){
+ fi1236_dump_status(pPriv->fi1236);
+ }
+ }
+ else if(attribute == xvAdjustment)
+ {
+ pPriv->adjustment=value;
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %d\n", pPriv->adjustment);
+ if(pPriv->tda9885!=0){
+ pPriv->tda9885->top_adjustment=value;
+ RADEON_TDA9885_SetEncoding(pPriv);
+ }
+ }
+ else
return BadMatch;
if (setTransform)
@@ -1269,6 +1740,11 @@ RADEONSetPortAttribute(ScrnInfoPtr pScrn,
pPriv->gamma);
}
+ if (setAlpha)
+ {
+ RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode);
+ }
+
return Success;
}
@@ -1309,7 +1785,50 @@ RADEONGetPortAttribute(ScrnInfoPtr pScrn,
*value = pPriv->colorKey;
else if(attribute == xvSwitchCRT)
*value = pPriv->crt2 ? 1 : 0;
+ else if(attribute == xvOvAlpha)
+ *value = pPriv->ov_alpha;
+ else if(attribute == xvGrAlpha)
+ *value = pPriv->gr_alpha;
+ else if(attribute == xvAlphaMode)
+ *value = pPriv->alpha_mode;
+ else if(attribute == xvDecBrightness)
+ *value = pPriv->dec_brightness;
+ else if((attribute == xvDecSaturation) || (attribute == xvDecColor))
+ *value = pPriv->dec_saturation;
+ else if(attribute == xvDecContrast)
+ *value = pPriv->dec_contrast;
+ else if(attribute == xvDecHue)
+ *value = pPriv->dec_hue;
+ else if(attribute == xvEncoding)
+ *value = pPriv->encoding;
+ else if(attribute == xvFrequency)
+ *value = pPriv->frequency;
else
+ if(attribute == xvTunerStatus) {
+ if(pPriv->fi1236==NULL){
+ *value=TUNER_OFF;
+ } else
+ {
+ *value = xf86_TUNER_get_afc_hint(pPriv->fi1236);
+ }
+ }
+ else if(attribute == xvMute)
+ *value = pPriv->mute;
+ else if(attribute == xvSAP)
+ *value = pPriv->sap_channel;
+ else if(attribute == xvVolume)
+ *value = pPriv->volume;
+ else if(attribute == xvOverlayDeinterlacingMethod)
+ *value = pPriv->overlay_deinterlacing_method;
+ else if(attribute == xvDeviceID)
+ *value = pPriv->device_id;
+ else if(attribute == xvLocationID)
+ *value = pPriv->location_id;
+ else if(attribute == xvInstanceID)
+ *value = pPriv->instance_id;
+ else if(attribute == xvAdjustment)
+ *value = pPriv->adjustment;
+ else
return BadMatch;
return Success;
@@ -1333,6 +1852,89 @@ RADEONQueryBestSize(
*p_h = drw_h;
}
+static struct {
+ double range;
+ signed char coeff[5][4];
+ } TapCoeffs[]=
+ {
+ {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }},
+ {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }},
+ {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
+ {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
+ {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }},
+ {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }},
+ {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }},
+ {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
+ {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
+ {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }},
+ {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
+ {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
+ {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
+ {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }},
+ {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
+ {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
+ {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
+ {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
+ {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }},
+ {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
+ {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }},
+ {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
+ {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
+ {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }},
+ {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }},
+ {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
+ {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
+ {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
+ {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }},
+ {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }},
+ {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}
+ };
+
static void
RADEONCopyData(
unsigned char *src,
@@ -1351,6 +1953,32 @@ RADEONCopyData(
}
static void
+RADEONCopyRGB24Data(
+ unsigned char *src,
+ unsigned char *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+){
+ CARD32 *dptr;
+ CARD8 *sptr;
+ int i,j;
+
+
+ for(j=0;j<h;j++){
+ dptr=(CARD32 *)(dst+j*dstPitch);
+ sptr=src+j*srcPitch;
+
+ for(i=w;i>0;i--){
+ dptr[0]=((sptr[0])<<24)|((sptr[1])<<16)|(sptr[2]);
+ dptr++;
+ sptr+=3;
+ }
+ }
+}
+
+static void
RADEONCopyMungedData(
unsigned char *src1,
unsigned char *src2,
@@ -1440,18 +2068,22 @@ RADEONAllocateMemory(
static void
RADEONDisplayVideo(
ScrnInfoPtr pScrn,
+ RADEONPortPrivPtr pPriv,
int id,
int offset1, int offset2,
+ int offset3, int offset4,
short width, short height,
int pitch,
int left, int right, int top,
BoxPtr dstBox,
short src_w, short src_h,
- short drw_w, short drw_h
+ short drw_w, short drw_h,
+ int deinterlacing_method
){
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- int v_inc, h_inc, step_by, tmp;
+ int v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp;
+ double h_inc_d;
int p1_h_accum_init, p23_h_accum_init;
int p1_v_accum_init;
int ecp_div;
@@ -1462,6 +2094,22 @@ RADEONDisplayVideo(
CARD32 scaler_src;
CARD32 dot_clock;
DisplayModePtr overlay_mode;
+ int is_rgb;
+ int i;
+ CARD32 scale_cntl;
+ double dsr;
+ int tap_set;
+
+ is_rgb=0;
+ switch(id){
+ case FOURCC_RGBA32:
+ case FOURCC_RGB24:
+ case FOURCC_RGBT16:
+ case FOURCC_RGB16:
+ is_rgb=1;
+ break;
+ default:
+ }
/* Unlike older Mach64 chips, RADEON has only two ECP settings: 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
for higher clocks, sure makes life nicer
@@ -1517,34 +2165,76 @@ RADEONDisplayVideo(
v_inc = (src_h << v_inc_shift) / drw_h;
}
}
- h_inc = ((src_w << (12 + ecp_div)) / drw_w);
- step_by = 1;
- while(h_inc >= (2 << 12)) {
- step_by++;
- h_inc >>= 1;
- }
+ h_inc = (1 << (12 + ecp_div));
+
+ step_by_y = 1;
+ step_by_uv = step_by_y;
+
+ /* if the source width was larger than what would fit in overlay scaler increase step_by values */
+ i=src_w;
+ while(i>pPriv->overlay_scaler_buffer_width){
+ step_by_y++;
+ step_by_uv++;
+ h_inc >>=1;
+ i=i/2;
+ }
+
+
+ h_inc_d = src_w;
+ h_inc_d = h_inc_d/drw_w;
+ /* we could do a tad better - but why
+ bother when this concerns downscaling and the code is so much more
+ hairy */
+ while(h_inc*h_inc_d >= (2 << 12)) {
+ if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){
+ step_by_uv = step_by_y+1;
+ break;
+ }
+ step_by_y++;
+ step_by_uv = step_by_y;
+ h_inc >>= 1;
+ }
+ h_inc_uv = h_inc>>(step_by_uv-step_by_y);
+ h_inc = h_inc * h_inc_d;
+ h_inc_uv = h_inc_uv * h_inc_d;
+ /* pPriv->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit
+ in the buffer for 2 tap filtering */
+ /* the only place it is documented in is in ATI source code */
+ /* we need twice as much space for 4 tap filtering.. */
+ /* under special circumstances turn on 4 tap filtering */
+ if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12)) && (deinterlacing_method!=METHOD_WEAVE)
+ && (drw_w*2 <= pPriv->overlay_scaler_buffer_width)){
+ step_by_y=0;
+ step_by_uv=1;
+ h_inc_uv = h_inc;
+ }
/* keep everything in 16.16 */
offset1 += ((left >> 16) & ~7) << 1;
offset2 += ((left >> 16) & ~7) << 1;
+ offset3 += ((left >> 16) & ~7) << 1;
+ offset4 += ((left >> 16) & ~7) << 1;
if (info->IsSecondary) {
offset1 += info->FbMapSize;
offset2 += info->FbMapSize;
+ offset3 += info->FbMapSize;
+ offset4 += info->FbMapSize;
}
tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
p1_h_accum_init = ((tmp << 4) & 0x000f8000) |
((tmp << 12) & 0xf0000000);
- tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2);
+ tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2);
p23_h_accum_init = ((tmp << 4) & 0x000f8000) |
((tmp << 12) & 0x70000000);
tmp = (top & 0x0000ffff) + 0x00018000;
- p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001;
+ p1_v_accum_init = ((tmp << 4) & 0x03ff8000) |
+ (((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01);
left = (left >> 16) & 7;
@@ -1553,9 +2243,20 @@ RADEONDisplayVideo(
if (info->accelOn) info->accel->Sync(pScrn);
while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & (1 << 3)));
+ dsr=(double)(1<<0xC)/h_inc;
+ if(dsr<0.25)dsr=0.25;
+ if(dsr>1.0)dsr=1.0;
+ tap_set=(int)((dsr-0.25)*100);
+ for(i=0;i<5;i++){
+ OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) |
+ ((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) |
+ ((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) |
+ ((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24));
+ }
+
RADEONWaitForFifo(pScrn, 14);
- OUTREG(RADEON_OV0_H_INC, h_inc | ((h_inc >> 1) << 16));
- OUTREG(RADEON_OV0_STEP_BY, step_by | (step_by << 8));
+ OUTREG(RADEON_OV0_H_INC, h_inc | ((h_inc_uv >> 1) << 16));
+ OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8));
x_off = 8;
y_off = 0;
@@ -1601,6 +2302,19 @@ RADEONDisplayVideo(
scaler_src = 0;
}
+
+ dsr=(double)(1<<0xC)/h_inc;
+ if(dsr<0.25)dsr=0.25;
+ if(dsr>1.0)dsr=1.0;
+ tap_set=(int)((dsr-0.25)*100);
+ for(i=0;i<5;i++){
+ OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) |
+ ((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) |
+ ((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) |
+ ((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24));
+ }
+
+ RADEONWaitForFifo(pScrn, 10);
OUTREG(RADEON_OV0_V_INC, v_inc);
OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));
OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch);
@@ -1611,37 +2325,44 @@ RADEONDisplayVideo(
OUTREG(RADEON_OV0_P3_X_START_END, (src_w + left - 1) | (left << 16));
OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1 & 0xfffffff0);
OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2 & 0xfffffff0);
- OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset1 & 0xfffffff0);
+ OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3 & 0xfffffff0);
RADEONWaitForFifo(pScrn, 9);
- OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset2 & 0xfffffff0);
+ OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4 & 0xfffffff0);
OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset1 & 0xfffffff0);
OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset2 & 0xfffffff0);
OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
-#if 0
- if(id == FOURCC_UYVY)
- OUTREG(RADEON_OV0_SCALE_CNTL, 0x41008C03);
- else
- OUTREG(RADEON_OV0_SCALE_CNTL, 0x41008B03);
-#endif
-
- if (id == FOURCC_UYVY)
- OUTREG(RADEON_OV0_SCALE_CNTL, (RADEON_SCALER_SOURCE_YVYU422
- | RADEON_SCALER_ADAPTIVE_DEINT
- | RADEON_SCALER_SMART_SWITCH
- | RADEON_SCALER_DOUBLE_BUFFER
- | RADEON_SCALER_ENABLE
- | scaler_src));
- else
- OUTREG(RADEON_OV0_SCALE_CNTL, (RADEON_SCALER_SOURCE_VYUY422
- | RADEON_SCALER_ADAPTIVE_DEINT
- | RADEON_SCALER_SMART_SWITCH
- | RADEON_SCALER_DOUBLE_BUFFER
- | RADEON_SCALER_ENABLE
- | scaler_src));
+ scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER
+ | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16);
+ switch(id){
+ case FOURCC_UYVY:
+ OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOURCE_YVYU422 | scale_cntl);
+ break;
+ case FOURCC_RGB24:
+ case FOURCC_RGBA32:
+ OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOURCE_32BPP | scale_cntl | 0x10000000);
+ break;
+ case FOURCC_RGBT16:
+ OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOURCE_16BPP
+ | 0x10000000
+ | scale_cntl);
+ break;
+ case FOURCC_RGB16:
+ OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOURCE_16BPP
+ | 0x10000000
+ | scale_cntl);
+ break;
+ case FOURCC_YUY2:
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ default:
+ OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOURCE_VYUY422
+ | ((info->ChipFamily>=CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT :0)
+ | scale_cntl);
+ }
OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
}
@@ -1724,6 +2445,26 @@ RADEONPutImage(
bpp = pScrn->bitsPerPixel >> 3;
switch(id) {
+ case FOURCC_RGB24:
+ dstPitch=(width*4+0x0f)&(~0x0f);
+ srcPitch=width*3;
+ new_size=(dstPitch*height+bpp-1)/bpp;
+ break;
+ case FOURCC_RGBA32:
+ dstPitch=(width*4+0x0f)&(~0x0f);
+ srcPitch=width*4;
+ new_size=(dstPitch*height+bpp-1)/bpp;
+ break;
+ case FOURCC_RGBT16:
+ dstPitch=(width*2+0x0f)&(~0x0f);
+ srcPitch=(width*2+3)&(~0x03);
+ new_size=(dstPitch*height+bpp-1)/bpp;
+ break;
+ case FOURCC_RGB16:
+ dstPitch=(width*2+0x0f)&(~0x0f);
+ srcPitch=(width*2+3)&(~0x03);
+ new_size=(dstPitch*height+bpp-1)/bpp;
+ break;
case FOURCC_YV12:
case FOURCC_I420:
dstPitch = ((width << 1) + 15) & ~15;
@@ -1784,6 +2525,8 @@ RADEONPutImage(
buf + s3offset, dst_start, srcPitch, srcPitch2,
dstPitch, nlines, npixels);
break;
+ case FOURCC_RGBT16:
+ case FOURCC_RGB16:
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
@@ -1798,6 +2541,18 @@ RADEONPutImage(
#endif
RADEONCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
break;
+ case FOURCC_RGBA32:
+ buf += (top * srcPitch) + left*4;
+ nlines = ((yb + 0xffff) >> 16) - top;
+ dst_start += left*4;
+ RADEONCopyData(buf, dst_start, srcPitch, dstPitch, nlines, 2*npixels);
+ break;
+ case FOURCC_RGB24:
+ buf += (top * srcPitch) + left*3;
+ nlines = ((yb + 0xffff) >> 16) - top;
+ dst_start += left*4;
+ RADEONCopyRGB24Data(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ break;
}
#if X_BYTE_ORDER == X_BIG_ENDIAN
@@ -1814,8 +2569,8 @@ RADEONPutImage(
xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
}
- RADEONDisplayVideo(pScrn, id, offset, offset, width, height, dstPitch,
- xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h);
+ RADEONDisplayVideo(pScrn, pPriv, id, offset, offset, offset, offset, width, height, dstPitch,
+ xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
pPriv->videoStatus = CLIENT_VIDEO_ON;
@@ -2063,10 +2818,11 @@ RADEONDisplaySurface(
/* this isn't needed */
RADEONResetVideo(pScrn);
#endif
- RADEONDisplayVideo(pScrn, surface->id,
+ RADEONDisplayVideo(pScrn, portPriv, surface->id,
+ surface->offsets[0], surface->offsets[0],
surface->offsets[0], surface->offsets[0],
surface->width, surface->height, surface->pitches[0],
- xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h);
+ xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
if (portPriv->autopaint_colorkey)
xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
@@ -2113,7 +2869,271 @@ RADEONInitOffscreenImages(ScreenPtr pScreen)
xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
}
- /* miscellaneous helper functions */
+ /* TV-in functions */
+
+static int
+RADEONPutVideo(
+ ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data
+){
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
+ unsigned char *RADEONMMIO = info->MMIO;
+ INT32 xa, xb, ya, yb, top;
+ unsigned int pitch, new_size, offset1, offset2, offset3, offset4, s2offset, s3offset, vbi_offset0, vbi_offset1;
+ int srcPitch, srcPitch2, dstPitch;
+ int bpp;
+ BoxRec dstBox;
+ CARD32 id, display_base;
+ int width, height;
+ int mult;
+ int vbi_line_width;
+
+ info->accel->Sync(pScrn);
+ /*
+ * s2offset, s3offset - byte offsets into U and V plane of the
+ * source where copying starts. Y plane is
+ * done by editing "buf".
+ *
+ * offset - byte offset to the first line of the destination.
+ *
+ * dst_start - byte address to the first displayed pel.
+ *
+ */
+
+ /* make the compiler happy */
+ s2offset = s3offset = srcPitch2 = 0;
+
+ if(src_w > (drw_w << 4))
+ drw_w = src_w >> 4;
+ if(src_h > (drw_h << 4))
+ drw_h = src_h >> 4;
+
+ /* Clip */
+ xa = src_x;
+ xb = src_x + src_w;
+ ya = src_y;
+ yb = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ width = InputVideoEncodings[pPriv->encoding].width;
+ height = InputVideoEncodings[pPriv->encoding].height;
+
+ vbi_line_width = 798*2;
+ if(width<=640)
+ vbi_line_width = 0x640; /* 1600 actually */
+ else
+ vbi_line_width = 2000; /* might need adjustment */
+
+ if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
+ return Success;
+
+ dstBox.x1 -= pScrn->frameX0;
+ dstBox.x2 -= pScrn->frameX0;
+ dstBox.y1 -= pScrn->frameY0;
+ dstBox.y2 -= pScrn->frameY0;
+
+ bpp = pScrn->bitsPerPixel >> 3;
+ pitch = bpp * pScrn->displayWidth;
+
+ switch(pPriv->overlay_deinterlacing_method){
+ case METHOD_BOB:
+ case METHOD_SINGLE:
+ mult=2;
+ break;
+ case METHOD_WEAVE:
+ case METHOD_ADAPTIVE:
+ mult=4;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n");
+ mult=4;
+ }
+
+ id = FOURCC_YUY2;
+
+ top = ya>>16;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ top &= ~1;
+ dstPitch = ((width << 1) + 15) & ~15;
+ new_size = ((dstPitch * height) + bpp - 1) / bpp;
+ srcPitch = (width + 3) & ~3;
+ s2offset = srcPitch * height;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ s3offset = (srcPitch2 * (height >> 1)) + s2offset;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ dstPitch = ((width<<1) + 15) & ~15;
+ new_size = ((dstPitch * height) + bpp - 1) / bpp;
+ srcPitch = (width<<1);
+ break;
+ }
+
+ new_size = new_size + 0x1f; /* for aligning */
+ if(!(info->videoLinear = RADEONAllocateMemory(pScrn, info->videoLinear, new_size*mult+(pPriv->capture_vbi_data?2*2*vbi_line_width*21:0))))
+ {
+ return BadAlloc;
+ }
+
+/* I have suspicion that capture engine must be active _before_ Rage Theatre
+ is being manipulated with.. */
+
+ RADEONWaitForIdleMMIO(pScrn);
+ display_base=INREG(RADEON_DISPLAY_BASE_ADDR);
+
+/* RADEONWaitForFifo(pScrn, 15); */
+
+ switch(pPriv->overlay_deinterlacing_method){
+ case METHOD_BOB:
+ case METHOD_SINGLE:
+ offset1 = (info->videoLinear->offset*bpp+0xf) & (~0xf);
+ offset2 = ((info->videoLinear->offset+new_size)*bpp + 0xf) & (~0xf);
+ offset3 = offset1;
+ offset4 = offset2;
+ break;
+ case METHOD_WEAVE:
+ offset1 = (info->videoLinear->offset*bpp+0xf) & (~0xf);
+ offset2 = offset1+dstPitch;
+ offset3 = ((info->videoLinear->offset+2*new_size)*bpp + 0xf) & (~0xf);
+ offset4 = offset3+dstPitch;
+ break;
+ default:
+ offset1 = (info->videoLinear->offset*bpp+0xf) & (~0xf);
+ offset2 = ((info->videoLinear->offset+new_size)*bpp + 0xf) & (~0xf);
+ offset3 = offset1;
+ offset4 = offset2;
+ }
+
+ OUTREG(RADEON_CAP0_BUF0_OFFSET, offset1+display_base);
+ OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET, offset2+display_base);
+ OUTREG(RADEON_CAP0_BUF1_OFFSET, offset3+display_base);
+ OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET, offset4+display_base);
+
+ OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base);
+
+ if(pPriv->capture_vbi_data){
+ vbi_offset0 = ((info->videoLinear->offset+mult*new_size)*bpp+0xf) & (~0xf);
+ vbi_offset1 = vbi_offset0 + dstPitch*20;
+ OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base);
+ OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base);
+ OUTREG(RADEON_CAP0_VBI2_OFFSET, 0);
+ OUTREG(RADEON_CAP0_VBI3_OFFSET, 0);
+ OUTREG(RADEON_CAP0_VBI_V_WINDOW, 8 | ((pPriv->v-1)<<16));
+ OUTREG(RADEON_CAP0_VBI_V_WINDOW, 8 | ((20)<<16));
+ OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16);
+ }
+
+ OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2);
+ OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16);
+ OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1));
+ if(mult==2){
+ OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB);
+ } else {
+ OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE);
+ }
+ OUTREG(RADEON_CAP0_DEBUG, 0);
+
+ OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01);
+ OUTREG(RADEON_TEST_DEBUG_CNTL, 0);
+
+ if(! pPriv->video_stream_active)
+ {
+
+ RADEONWaitForIdleMMIO(pScrn);
+ OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 );
+ OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0);
+ OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK);
+ OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11);
+ if(pPriv->theatre != NULL)
+ {
+ RADEON_RT_SetEncoding(pScrn, pPriv);
+ }
+ if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv);
+ if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv);
+ if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv);
+ if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv);
+ }
+
+
+ /* update cliplist */
+ if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
+ REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ /* draw these */
+ if(pPriv->autopaint_colorkey)
+ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+ }
+
+ RADEONDisplayVideo(pScrn, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch, offset3+top*srcPitch, offset4+top*srcPitch, width, height, dstPitch*mult/2,
+ xa, xb, ya, &dstBox, src_w, src_h*mult/2, drw_w, drw_h, pPriv->overlay_deinterlacing_method);
+
+ RADEONWaitForFifo(pScrn, 1);
+ OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK);
+ RADEONWaitForIdleMMIO(pScrn);
+ while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
+
+
+ switch(pPriv->overlay_deinterlacing_method){
+ case METHOD_BOB:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
+ OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/
+ |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
+ break;
+ case METHOD_SINGLE:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28));
+ OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
+ |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
+ break;
+ case METHOD_WEAVE:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28));
+ OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0 |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
+ | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN
+ /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */
+ /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */
+ |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE);
+ break;
+ default:
+ OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA);
+ OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD
+ |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN);
+ }
+
+
+ RADEONWaitForIdleMMIO(pScrn);
+ OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
+ OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE ));
+
+ OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
+
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL));
+/* OUTREG(RADEON_OV0_FLAG_CNTL, 8); */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS));
+
+/* OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */
+#endif
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+ pPriv->video_stream_active = TRUE;
+
+ info->VideoTimerCallback = RADEONVideoTimerCallback;
+
+ return Success;
+}
+ /* miscellaneous TV-in helper functions */
static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv)
{
@@ -2217,3 +3237,135 @@ width = InputVideoEncodings[pPriv->encoding].width;
height = InputVideoEncodings[pPriv->encoding].height;
xf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data);
}
+
+static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv)
+{
+xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE);
+switch(pPriv->encoding){
+ case 1:
+ pPriv->msp3430->standard = MSP3430_PAL;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
+ break;
+ case 2:
+ pPriv->msp3430->standard = MSP3430_PAL;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
+ break;
+ case 3:
+ pPriv->msp3430->standard = MSP3430_PAL;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
+ break;
+ case 4:
+ pPriv->msp3430->standard = MSP3430_NTSC;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
+ break;
+ case 5:
+ pPriv->msp3430->standard = MSP3430_NTSC;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
+ break;
+ case 6:
+ pPriv->msp3430->standard = MSP3430_NTSC;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
+ break;
+ case 7:
+ pPriv->msp3430->standard = MSP3430_SECAM;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
+ break;
+ case 8:
+ pPriv->msp3430->standard = MSP3430_SECAM;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
+ break;
+ case 9:
+ pPriv->msp3430->standard = MSP3430_SECAM;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
+ break;
+ case 10:
+ pPriv->msp3430->standard = MSP3430_SECAM;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_3;
+ break;
+ case 11:
+ pPriv->msp3430->standard = MSP3430_SECAM;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_1;
+ break;
+ case 12:
+ pPriv->msp3430->standard = MSP3430_SECAM;
+ pPriv->msp3430->connector = MSP3430_CONNECTOR_2;
+ break;
+ default:
+ return;
+ }
+xf86_InitMSP3430(pPriv->msp3430);
+xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume));
+}
+
+static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv)
+{
+TDA9885Ptr t=pPriv->tda9885;
+
+switch(pPriv->encoding){
+ /* PAL */
+ case 1:
+ case 2:
+ case 3:
+ t->standard_video_if=2;
+ t->standard_sound_carrier=3;
+ t->modulation=0; /* positive AM */
+ break;
+ /* NTSC */
+ case 4:
+ case 5:
+ case 6:
+ t->standard_video_if=1;
+ t->standard_sound_carrier=0;
+ t->modulation=2; /* negative FM */
+ break;
+ /* SECAM */
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ t->standard_video_if=0;
+ t->standard_sound_carrier=3;
+ t->modulation=0; /* positive AM */
+ break;
+ default:
+ return;
+ }
+xf86_tda9885_setparameters(pPriv->tda9885);
+xf86_tda9885_getstatus(pPriv->tda9885);
+xf86_tda9885_dumpstatus(pPriv->tda9885);
+}
+
+static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv)
+{
+/* at the moment this only affect MT2032 */
+switch(pPriv->encoding){
+ /* PAL */
+ case 1:
+ case 2:
+ case 3:
+ pPriv->fi1236->video_if=38.900;
+ break;
+ /* NTSC */
+ case 4:
+ case 5:
+ case 6:
+ pPriv->fi1236->video_if=45.7812;
+ pPriv->fi1236->video_if=45.750;
+ pPriv->fi1236->video_if=45.125;
+ break;
+ /* SECAM */
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ pPriv->fi1236->video_if=58.7812;
+ break;
+ default:
+ return;
+ }
+}
+
diff --git a/src/radeon_video.h b/src/radeon_video.h
index 75673d3f..41c08b89 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -23,6 +23,11 @@ typedef struct {
int blue_intensity;
int ecp_div;
+ /* overlay composition mode */
+ int alpha_mode; /* 0 = key mode, 1 = global mode */
+ int ov_alpha;
+ int gr_alpha;
+
/* i2c bus and devices */
I2CBusPtr i2c;
CARD32 radeon_i2c_timing;
diff --git a/src/theatre.c b/src/theatre.c
index 0a3f5cdb..3ff0cb0a 100644
--- a/src/theatre.c
+++ b/src/theatre.c
@@ -1780,7 +1780,6 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
t->wConnector = wConnector;
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre Checkpoint 1\n");
/* Get the contrast value - make sure we are viewing a visible line*/
counter=0;
#if 0
@@ -1790,7 +1789,6 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
counter++;
}
dwTempContrast = ReadRT_fld (fld_LP_CONTRAST);
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre Checkpoint 2, counter=%ld (%d)\n", counter, ReadRT_fld(fld_VS_LINE_COUNT));
if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre: timeout waiting for line count (%d)\n", ReadRT_fld (fld_VS_LINE_COUNT));
@@ -1835,20 +1833,17 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
*/
i = 100000;
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre Checkpoint 3\n");
while ((i>=0) && (! ReadRT_fld (fld_HS_GENLOCKED)))
{
i--;
}
if(i<0) xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre: waiting for fld_HS_GENLOCKED failed\n");
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre Checkpoint 4 i=%d\n",i);
/* now we are waiting for a non-visible line.. and there is absolutely no point to wait too long */
counter = 0;
while (!((ReadRT_fld (fld_VS_LINE_COUNT)> 1) && (ReadRT_fld (fld_VS_LINE_COUNT)<20)) && (counter < 10000)){
counter++;
}
WriteRT_fld (fld_LP_CONTRAST, dwTempContrast);
- xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre Checkpoint 5 counter=%d (%d)\n", counter, ReadRT_fld (fld_VS_LINE_COUNT));
if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre: timeout waiting for line count (%d)\n", ReadRT_fld (fld_VS_LINE_COUNT));