radeon_video.c revision 209ff23f
1 2#ifdef HAVE_CONFIG_H 3#include "config.h" 4#endif 5 6#include <stdlib.h> 7#include <string.h> 8#include <stdio.h> 9#include <math.h> 10 11#include "radeon.h" 12#include "radeon_reg.h" 13#include "radeon_macros.h" 14#include "radeon_probe.h" 15#include "radeon_video.h" 16 17#include "xf86.h" 18#include "dixstruct.h" 19#include "atipciids.h" 20#include "xf86fbman.h" 21 22#include <X11/extensions/Xv.h> 23#include "fourcc.h" 24 25#include "theatre_detect.h" 26#include "theatre_reg.h" 27#include "fi1236.h" 28#include "msp3430.h" 29#include "tda9885.h" 30 31#define OFF_DELAY 250 /* milliseconds */ 32#define FREE_DELAY 15000 33 34#define OFF_TIMER 0x01 35#define FREE_TIMER 0x02 36#define CLIENT_VIDEO_ON 0x04 37 38#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 39 40/* capture config constants */ 41#define BUF_TYPE_FIELD 0 42#define BUF_TYPE_ALTERNATING 1 43#define BUF_TYPE_FRAME 2 44 45 46#define BUF_MODE_SINGLE 0 47#define BUF_MODE_DOUBLE 1 48#define BUF_MODE_TRIPLE 2 49/* CAP0_CONFIG values */ 50 51#define FORMAT_BROOKTREE 0 52#define FORMAT_CCIR656 1 53#define FORMAT_ZV 2 54#define FORMAT_VIP16 3 55#define FORMAT_TRANSPORT 4 56 57#define ENABLE_RADEON_CAPTURE_WEAVE (RADEON_CAP0_CONFIG_CONTINUOS \ 58 | (BUF_MODE_DOUBLE <<7) \ 59 | (BUF_TYPE_FRAME << 4) \ 60 | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \ 61 | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \ 62 | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \ 63 | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422) 64 65#define ENABLE_RADEON_CAPTURE_BOB (RADEON_CAP0_CONFIG_CONTINUOS \ 66 | (BUF_MODE_SINGLE <<7) \ 67 | (BUF_TYPE_ALTERNATING << 4) \ 68 | ( (pPriv->theatre !=NULL)?(FORMAT_CCIR656<<23):(FORMAT_BROOKTREE<<23)) \ 69 | RADEON_CAP0_CONFIG_HORZ_DECIMATOR \ 70 | (pPriv->capture_vbi_data ? RADEON_CAP0_CONFIG_VBI_EN : 0) \ 71 | RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422) 72 73 74static void RADEONInitOffscreenImages(ScreenPtr); 75 76static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr); 77static int RADEONPutImage(ScrnInfoPtr, short, short, short, short, short, 78 short, short, short, int, unsigned char*, short, 79 short, Bool, RegionPtr, pointer, 80 DrawablePtr); 81static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now); 82static int RADEONPutVideo(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y, 83 short src_w, short src_h, short drw_w, short drw_h, 84 RegionPtr clipBoxes, pointer data, DrawablePtr pDraw); 85 86static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv); 87static void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv); 88static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv); 89static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv); 90static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv); 91 92 93 94#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) 95 96static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer; 97static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity; 98static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults; 99static Atom xvGamma, xvColorspace; 100static Atom xvCRTC; 101static Atom xvEncoding, xvFrequency, xvVolume, xvMute, 102 xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation, 103 xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod, 104 xvLocationID, xvDeviceID, xvInstanceID, xvDumpStatus, 105 xvAdjustment; 106 107static Atom xvOvAlpha, xvGrAlpha, xvAlphaMode; 108 109 110#define GET_PORT_PRIVATE(pScrn) \ 111 (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 112 113#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER 114static void 115radeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) 116{ 117 dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1; 118 dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2; 119 dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1; 120 dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2; 121 122 if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2) 123 dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; 124} 125 126static void 127radeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) 128{ 129 if (crtc->enabled) { 130 crtc_box->x1 = crtc->x; 131 crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation); 132 crtc_box->y1 = crtc->y; 133 crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation); 134 } else 135 crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; 136} 137 138static int 139radeon_box_area(BoxPtr box) 140{ 141 return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1); 142} 143 144static xf86CrtcPtr 145radeon_covering_crtc(ScrnInfoPtr pScrn, 146 BoxPtr box, 147 xf86CrtcPtr desired, 148 BoxPtr crtc_box_ret) 149{ 150 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 151 xf86CrtcPtr crtc, best_crtc; 152 int coverage, best_coverage; 153 int c; 154 BoxRec crtc_box, cover_box; 155 156 best_crtc = NULL; 157 best_coverage = 0; 158 crtc_box_ret->x1 = 0; 159 crtc_box_ret->x2 = 0; 160 crtc_box_ret->y1 = 0; 161 crtc_box_ret->y2 = 0; 162 for (c = 0; c < xf86_config->num_crtc; c++) { 163 crtc = xf86_config->crtc[c]; 164 radeon_crtc_box(crtc, &crtc_box); 165 radeon_box_intersect(&cover_box, &crtc_box, box); 166 coverage = radeon_box_area(&cover_box); 167 if (coverage && crtc == desired) { 168 *crtc_box_ret = crtc_box; 169 return crtc; 170 } else if (coverage > best_coverage) { 171 *crtc_box_ret = crtc_box; 172 best_crtc = crtc; 173 best_coverage = coverage; 174 } 175 } 176 return best_crtc; 177} 178 179static Bool 180radeon_crtc_clip_video_helper(ScrnInfoPtr pScrn, 181 xf86CrtcPtr *crtc_ret, 182 xf86CrtcPtr desired_crtc, 183 BoxPtr dst, 184 INT32 *xa, 185 INT32 *xb, 186 INT32 *ya, 187 INT32 *yb, 188 RegionPtr reg, 189 INT32 width, 190 INT32 height) 191{ 192 Bool ret; 193 RegionRec crtc_region_local; 194 RegionPtr crtc_region = reg; 195 196 /* 197 * For overlay video, compute the relevant CRTC and 198 * clip video to that 199 */ 200 if (crtc_ret) { 201 BoxRec crtc_box; 202 xf86CrtcPtr crtc = radeon_covering_crtc(pScrn, dst, 203 desired_crtc, 204 &crtc_box); 205 206 if (crtc) { 207 REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1); 208 crtc_region = &crtc_region_local; 209 REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg); 210 } 211 *crtc_ret = crtc; 212 } 213 214 ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, 215 crtc_region, width, height); 216 217 if (crtc_region != reg) 218 REGION_UNINIT (pScreen, &crtc_region_local); 219 220 return ret; 221} 222#endif 223 224static Bool 225radeon_crtc_clip_video(ScrnInfoPtr pScrn, 226 xf86CrtcPtr *crtc_ret, 227 xf86CrtcPtr desired_crtc, 228 BoxPtr dst, 229 INT32 *xa, 230 INT32 *xb, 231 INT32 *ya, 232 INT32 *yb, 233 RegionPtr reg, 234 INT32 width, 235 INT32 height) 236{ 237#ifndef HAVE_XF86CRTCCLIPVIDEOHELPER 238 return radeon_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc, 239 dst, xa, xb, ya, yb, 240 reg, width, height); 241#else 242 return xf86_crtc_clip_video_helper(pScrn, crtc_ret, desired_crtc, 243 dst, xa, xb, ya, yb, 244 reg, width, height); 245#endif 246} 247 248#ifdef USE_EXA 249static void 250ATIVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) 251{ 252 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 253 RADEONInfoPtr info = RADEONPTR(pScrn); 254 RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; 255 256 if (pPriv->video_memory == area) 257 pPriv->video_memory = NULL; 258} 259#endif /* USE_EXA */ 260 261void RADEONInitVideo(ScreenPtr pScreen) 262{ 263 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 264 RADEONInfoPtr info = RADEONPTR(pScrn); 265 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 266 XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL; 267 int num_adaptors; 268 269 270 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 271 newAdaptors = xalloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *)); 272 if (newAdaptors == NULL) 273 return; 274 275 memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr)); 276 adaptors = newAdaptors; 277 278 if (!IS_AVIVO_VARIANT) { 279 overlayAdaptor = RADEONSetupImageVideo(pScreen); 280 if (overlayAdaptor != NULL) { 281 adaptors[num_adaptors++] = overlayAdaptor; 282 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n"); 283 } else 284 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up overlay video\n"); 285 RADEONInitOffscreenImages(pScreen); 286 } 287 288 if (info->ChipFamily != CHIP_FAMILY_RV250) { 289 if ((info->ChipFamily < CHIP_FAMILY_RS400) 290#ifdef XF86DRI 291 || (info->directRenderingEnabled) 292#endif 293 ) { 294 texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen); 295 if (texturedAdaptor != NULL) { 296 adaptors[num_adaptors++] = texturedAdaptor; 297 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n"); 298 } else 299 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up textured video\n"); 300 } else 301 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video requires CP on R5xx/IGP\n"); 302 } else 303 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video disabled on RV250 due to HW bug\n"); 304 305 if(num_adaptors) 306 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 307 308 if(newAdaptors) 309 xfree(newAdaptors); 310 311} 312 313/* client libraries expect an encoding */ 314static XF86VideoEncodingRec DummyEncoding = 315{ 316 0, 317 "XV_IMAGE", 318 2048, 2048, 319 {1, 1} 320}; 321 322 /* the picture is interlaced - hence the half-heights */ 323 324static XF86VideoEncodingRec 325InputVideoEncodings[] = 326{ 327 { 0, "XV_IMAGE", 2048,2048,{1,1}}, 328 { 1, "pal-composite", 720, 288, { 1, 50 }}, 329 { 2, "pal-tuner", 720, 288, { 1, 50 }}, 330 { 3, "pal-svideo", 720, 288, { 1, 50 }}, 331 { 4, "ntsc-composite", 640, 240, { 1001, 60000 }}, 332 { 5, "ntsc-tuner", 640, 240, { 1001, 60000 }}, 333 { 6, "ntsc-svideo", 640, 240, { 1001, 60000 }}, 334 { 7, "secam-composite", 720, 288, { 1, 50 }}, 335 { 8, "secam-tuner", 720, 288, { 1, 50 }}, 336 { 9, "secam-svideo", 720, 288, { 1, 50 }}, 337 { 10,"pal_60-composite", 768, 288, { 1, 50 }}, 338 { 11,"pal_60-tuner", 768, 288, { 1, 50 }}, 339 { 12,"pal_60-svideo", 768, 288, { 1, 50 }} 340}; 341 342 343#define NUM_FORMATS 12 344 345static XF86VideoFormatRec Formats[NUM_FORMATS] = 346{ 347 {8, TrueColor}, {8, DirectColor}, {8, PseudoColor}, 348 {8, GrayScale}, {8, StaticGray}, {8, StaticColor}, 349 {15, TrueColor}, {16, TrueColor}, {24, TrueColor}, 350 {15, DirectColor}, {16, DirectColor}, {24, DirectColor} 351}; 352 353 354#if 0 355#define NUM_ATTRIBUTES 9+6 356 357static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 358{ 359 {XvSettable , 0, 1, "XV_SET_DEFAULTS"}, 360 {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, 361 {XvSettable | XvGettable, 0, ~0, "XV_COLORKEY"}, 362 {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 363 {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, 364 {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, 365 {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, 366 {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"}, 367 {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}, 368 {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"}, 369 {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"}, 370 {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"}, 371 {XvSettable | XvGettable, -1, 1, "XV_CRTC"}, 372 {XvSettable | XvGettable, 100, 10000, "XV_GAMMA"}, 373 {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"}, 374}; 375 376#endif 377 378#define NUM_ATTRIBUTES 22 379#define NUM_DEC_ATTRIBUTES (NUM_ATTRIBUTES+12) 380 381static XF86AttributeRec Attributes[NUM_DEC_ATTRIBUTES+1] = 382{ 383 { XvGettable, 0, ~0, "XV_DEVICE_ID"}, 384 { XvGettable, 0, ~0, "XV_LOCATION_ID"}, 385 { XvGettable, 0, ~0, "XV_INSTANCE_ID"}, 386 {XvSettable , 0, 1, "XV_DUMP_STATUS"}, 387 {XvSettable , 0, 1, "XV_SET_DEFAULTS"}, 388 {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, 389 {XvSettable | XvGettable, 0, ~0,"XV_COLORKEY"}, 390 {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 391 {XvSettable | XvGettable, 0, 255, "XV_OVERLAY_ALPHA"}, 392 {XvSettable | XvGettable, 0, 255, "XV_GRAPHICS_ALPHA"}, 393 {XvSettable | XvGettable, 0, 1, "XV_ALPHA_MODE"}, 394 {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, 395 {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, 396 {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, 397 {XvSettable | XvGettable, -1000, 1000, "XV_COLOR"}, 398 {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}, 399 {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"}, 400 {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"}, 401 {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"}, 402 {XvSettable | XvGettable, -1, 1, "XV_CRTC"}, 403 {XvSettable | XvGettable, 100, 10000, "XV_GAMMA"}, 404 {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"}, 405 406 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_BRIGHTNESS"}, 407 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_CONTRAST"}, 408 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_SATURATION"}, 409 {XvSettable | XvGettable, -1000, 1000, "XV_DEC_HUE"}, 410 {XvSettable | XvGettable, 0, 2, "XV_OVERLAY_DEINTERLACING_METHOD"}, 411 {XvSettable | XvGettable, 0, 12, "XV_ENCODING"}, 412 {XvSettable | XvGettable, 0, -1, "XV_FREQ"}, 413 { XvGettable, -1000, 1000, "XV_TUNER_STATUS"}, 414 {XvSettable | XvGettable, -1000, 1000, "XV_VOLUME"}, 415 {XvSettable | XvGettable, 0, 1, "XV_MUTE"}, 416 {XvSettable | XvGettable, 0, 1, "XV_SAP"}, 417 {XvSettable | XvGettable, 0, 0x1F, "XV_DEBUG_ADJUSTMENT"}, 418 { 0, 0, 0, NULL} /* just a place holder so I don't have to be fancy with commas */ 419}; 420 421 422#define INCLUDE_RGB_FORMATS 1 423 424#if INCLUDE_RGB_FORMATS 425 426#define NUM_IMAGES 8 427 428/* Note: GUIDs are bogus... - but nothing uses them anyway */ 429 430#define FOURCC_RGBA32 0x41424752 431 432#define XVIMAGE_RGBA32(byte_order) \ 433 { \ 434 FOURCC_RGBA32, \ 435 XvRGB, \ 436 byte_order, \ 437 { 'R', 'G', 'B', 'A', \ 438 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 439 32, \ 440 XvPacked, \ 441 1, \ 442 32, 0x00FF0000, 0x0000FF00, 0x000000FF, \ 443 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 444 {'A', 'R', 'G', 'B', \ 445 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}, \ 446 XvTopToBottom \ 447 } 448 449#define FOURCC_RGB24 0x00000000 450 451#define XVIMAGE_RGB24 \ 452 { \ 453 FOURCC_RGB24, \ 454 XvRGB, \ 455 LSBFirst, \ 456 { 'R', 'G', 'B', 0, \ 457 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 458 24, \ 459 XvPacked, \ 460 1, \ 461 24, 0x00FF0000, 0x0000FF00, 0x000000FF, \ 462 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 463 { 'R', 'G', 'B', \ 464 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}, \ 465 XvTopToBottom \ 466 } 467 468#define FOURCC_RGBT16 0x54424752 469 470#define XVIMAGE_RGBT16(byte_order) \ 471 { \ 472 FOURCC_RGBT16, \ 473 XvRGB, \ 474 byte_order, \ 475 { 'R', 'G', 'B', 'T', \ 476 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 477 16, \ 478 XvPacked, \ 479 1, \ 480 16, 0x00007C00, 0x000003E0, 0x0000001F, \ 481 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 482 {'A', 'R', 'G', 'B', \ 483 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}, \ 484 XvTopToBottom \ 485 } 486 487#define FOURCC_RGB16 0x32424752 488 489#define XVIMAGE_RGB16(byte_order) \ 490 { \ 491 FOURCC_RGB16, \ 492 XvRGB, \ 493 byte_order, \ 494 { 'R', 'G', 'B', 0x00, \ 495 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 496 16, \ 497 XvPacked, \ 498 1, \ 499 16, 0x0000F800, 0x000007E0, 0x0000001F, \ 500 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 501 {'R', 'G', 'B', \ 502 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}, \ 503 XvTopToBottom \ 504 } 505 506static XF86ImageRec Images[NUM_IMAGES] = 507{ 508#if X_BYTE_ORDER == X_BIG_ENDIAN 509 XVIMAGE_RGBA32(MSBFirst), 510 XVIMAGE_RGBT16(MSBFirst), 511 XVIMAGE_RGB16(MSBFirst), 512#else 513 XVIMAGE_RGBA32(LSBFirst), 514 XVIMAGE_RGBT16(LSBFirst), 515 XVIMAGE_RGB16(LSBFirst), 516#endif 517 XVIMAGE_RGB24, 518 XVIMAGE_YUY2, 519 XVIMAGE_UYVY, 520 XVIMAGE_YV12, 521 XVIMAGE_I420 522}; 523 524#else 525 526#define NUM_IMAGES 4 527 528static XF86ImageRec Images[NUM_IMAGES] = 529{ 530 XVIMAGE_YUY2, 531 XVIMAGE_UYVY, 532 XVIMAGE_YV12, 533 XVIMAGE_I420 534}; 535 536#endif 537 538/* Reference color space transform data */ 539typedef struct tagREF_TRANSFORM 540{ 541 float RefLuma; 542 float RefRCb; 543 float RefRCr; 544 float RefGCb; 545 float RefGCr; 546 float RefBCb; 547 float RefBCr; 548} REF_TRANSFORM; 549 550/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */ 551static REF_TRANSFORM trans[2] = 552{ 553 {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */ 554 {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */ 555}; 556 557 558/* Gamma curve definition for preset gammas */ 559typedef struct tagGAMMA_CURVE_R100 560{ 561 uint32_t GAMMA_0_F_SLOPE; 562 uint32_t GAMMA_0_F_OFFSET; 563 uint32_t GAMMA_10_1F_SLOPE; 564 uint32_t GAMMA_10_1F_OFFSET; 565 uint32_t GAMMA_20_3F_SLOPE; 566 uint32_t GAMMA_20_3F_OFFSET; 567 uint32_t GAMMA_40_7F_SLOPE; 568 uint32_t GAMMA_40_7F_OFFSET; 569 uint32_t GAMMA_380_3BF_SLOPE; 570 uint32_t GAMMA_380_3BF_OFFSET; 571 uint32_t GAMMA_3C0_3FF_SLOPE; 572 uint32_t GAMMA_3C0_3FF_OFFSET; 573 float OvGammaCont; 574} GAMMA_CURVE_R100; 575 576typedef struct tagGAMMA_CURVE_R200 577{ 578 uint32_t GAMMA_0_F_SLOPE; 579 uint32_t GAMMA_0_F_OFFSET; 580 uint32_t GAMMA_10_1F_SLOPE; 581 uint32_t GAMMA_10_1F_OFFSET; 582 uint32_t GAMMA_20_3F_SLOPE; 583 uint32_t GAMMA_20_3F_OFFSET; 584 uint32_t GAMMA_40_7F_SLOPE; 585 uint32_t GAMMA_40_7F_OFFSET; 586 uint32_t GAMMA_80_BF_SLOPE; 587 uint32_t GAMMA_80_BF_OFFSET; 588 uint32_t GAMMA_C0_FF_SLOPE; 589 uint32_t GAMMA_C0_FF_OFFSET; 590 uint32_t GAMMA_100_13F_SLOPE; 591 uint32_t GAMMA_100_13F_OFFSET; 592 uint32_t GAMMA_140_17F_SLOPE; 593 uint32_t GAMMA_140_17F_OFFSET; 594 uint32_t GAMMA_180_1BF_SLOPE; 595 uint32_t GAMMA_180_1BF_OFFSET; 596 uint32_t GAMMA_1C0_1FF_SLOPE; 597 uint32_t GAMMA_1C0_1FF_OFFSET; 598 uint32_t GAMMA_200_23F_SLOPE; 599 uint32_t GAMMA_200_23F_OFFSET; 600 uint32_t GAMMA_240_27F_SLOPE; 601 uint32_t GAMMA_240_27F_OFFSET; 602 uint32_t GAMMA_280_2BF_SLOPE; 603 uint32_t GAMMA_280_2BF_OFFSET; 604 uint32_t GAMMA_2C0_2FF_SLOPE; 605 uint32_t GAMMA_2C0_2FF_OFFSET; 606 uint32_t GAMMA_300_33F_SLOPE; 607 uint32_t GAMMA_300_33F_OFFSET; 608 uint32_t GAMMA_340_37F_SLOPE; 609 uint32_t GAMMA_340_37F_OFFSET; 610 uint32_t GAMMA_380_3BF_SLOPE; 611 uint32_t GAMMA_380_3BF_OFFSET; 612 uint32_t GAMMA_3C0_3FF_SLOPE; 613 uint32_t GAMMA_3C0_3FF_OFFSET; 614 float OvGammaCont; 615} GAMMA_CURVE_R200; 616 617 618/* Preset gammas */ 619static GAMMA_CURVE_R100 gamma_curve_r100[8] = 620{ 621 /* Gamma 1.0 */ 622 {0x100, 0x0, 623 0x100, 0x20, 624 0x100, 0x40, 625 0x100, 0x80, 626 0x100, 0x100, 627 0x100, 0x100, 628 1.0}, 629 /* Gamma 0.85 */ 630 {0x75, 0x0, 631 0xA2, 0xF, 632 0xAC, 0x23, 633 0xC6, 0x4E, 634 0x129, 0xD6, 635 0x12B, 0xD5, 636 1.0}, 637 /* Gamma 1.1 */ 638 {0x180, 0x0, 639 0x13C, 0x30, 640 0x13C, 0x57, 641 0x123, 0xA5, 642 0xEA, 0x116, 643 0xEA, 0x116, 644 0.9913}, 645 /* Gamma 1.2 */ 646 {0x21B, 0x0, 647 0x16D, 0x43, 648 0x172, 0x71, 649 0x13D, 0xCD, 650 0xD9, 0x128, 651 0xD6, 0x12A, 652 0.9827}, 653 /* Gamma 1.45 */ 654 {0x404, 0x0, 655 0x1B9, 0x81, 656 0x1EE, 0xB8, 657 0x16A, 0x133, 658 0xB7, 0x14B, 659 0xB2, 0x14E, 660 0.9567}, 661 /* Gamma 1.7 */ 662 {0x658, 0x0, 663 0x1B5, 0xCB, 664 0x25F, 0x102, 665 0x181, 0x199, 666 0x9C, 0x165, 667 0x98, 0x167, 668 0.9394}, 669 /* Gamma 2.2 */ 670 {0x7FF, 0x0, 671 0x625, 0x100, 672 0x1E4, 0x1C4, 673 0x1BD, 0x23D, 674 0x79, 0x187, 675 0x76, 0x188, 676 0.9135}, 677 /* Gamma 2.5 */ 678 {0x7FF, 0x0, 679 0x7FF, 0x100, 680 0x2AD, 0x200, 681 0x1A2, 0x2AB, 682 0x6E, 0x194, 683 0x67, 0x197, 684 0.9135} 685}; 686 687static GAMMA_CURVE_R200 gamma_curve_r200[8] = 688 { 689 /* Gamma 1.0 */ 690 {0x00000100, 0x00000000, 691 0x00000100, 0x00000020, 692 0x00000100, 0x00000040, 693 0x00000100, 0x00000080, 694 0x00000100, 0x00000100, 695 0x00000100, 0x00000100, 696 0x00000100, 0x00000200, 697 0x00000100, 0x00000200, 698 0x00000100, 0x00000300, 699 0x00000100, 0x00000300, 700 0x00000100, 0x00000400, 701 0x00000100, 0x00000400, 702 0x00000100, 0x00000500, 703 0x00000100, 0x00000500, 704 0x00000100, 0x00000600, 705 0x00000100, 0x00000600, 706 0x00000100, 0x00000700, 707 0x00000100, 0x00000700, 708 1.0}, 709 /* Gamma 0.85 */ 710 {0x0000001D, 0x00000000, 711 0x00000028, 0x0000000F, 712 0x00000056, 0x00000023, 713 0x000000C5, 0x0000004E, 714 0x000000DA, 0x000000B0, 715 0x000000E6, 0x000000AA, 716 0x000000F1, 0x00000190, 717 0x000000F9, 0x0000018C, 718 0x00000101, 0x00000286, 719 0x00000108, 0x00000282, 720 0x0000010D, 0x0000038A, 721 0x00000113, 0x00000387, 722 0x00000118, 0x0000049A, 723 0x0000011C, 0x00000498, 724 0x00000120, 0x000005B4, 725 0x00000124, 0x000005B2, 726 0x00000128, 0x000006D6, 727 0x0000012C, 0x000006D5, 728 1.0}, 729 /* Gamma 1.1 */ 730 {0x00000060, 0x00000000, 731 0x0000004F, 0x00000030, 732 0x0000009C, 0x00000057, 733 0x00000121, 0x000000A5, 734 0x00000113, 0x00000136, 735 0x0000010B, 0x0000013A, 736 0x00000105, 0x00000245, 737 0x00000100, 0x00000247, 738 0x000000FD, 0x00000348, 739 0x000000F9, 0x00000349, 740 0x000000F6, 0x00000443, 741 0x000000F4, 0x00000444, 742 0x000000F2, 0x00000538, 743 0x000000F0, 0x00000539, 744 0x000000EE, 0x00000629, 745 0x000000EC, 0x00000629, 746 0x000000EB, 0x00000716, 747 0x000000E9, 0x00000717, 748 0.9913}, 749 /* Gamma 1.2 */ 750 {0x00000087, 0x00000000, 751 0x0000005B, 0x00000043, 752 0x000000B7, 0x00000071, 753 0x0000013D, 0x000000CD, 754 0x00000121, 0x0000016B, 755 0x00000113, 0x00000172, 756 0x00000107, 0x00000286, 757 0x000000FF, 0x0000028A, 758 0x000000F8, 0x00000389, 759 0x000000F2, 0x0000038B, 760 0x000000ED, 0x0000047D, 761 0x000000E9, 0x00000480, 762 0x000000E5, 0x00000568, 763 0x000000E1, 0x0000056A, 764 0x000000DE, 0x0000064B, 765 0x000000DB, 0x0000064D, 766 0x000000D9, 0x00000728, 767 0x000000D6, 0x00000729, 768 0.9827}, 769 /* Gamma 1.45 */ 770 {0x00000101, 0x00000000, 771 0x0000006E, 0x00000081, 772 0x000000F7, 0x000000B8, 773 0x0000016E, 0x00000133, 774 0x00000139, 0x000001EA, 775 0x0000011B, 0x000001F9, 776 0x00000105, 0x00000314, 777 0x000000F6, 0x0000031C, 778 0x000000E9, 0x00000411, 779 0x000000DF, 0x00000417, 780 0x000000D7, 0x000004F6, 781 0x000000CF, 0x000004F9, 782 0x000000C9, 0x000005C9, 783 0x000000C4, 0x000005CC, 784 0x000000BF, 0x0000068F, 785 0x000000BA, 0x00000691, 786 0x000000B6, 0x0000074B, 787 0x000000B2, 0x0000074D, 788 0.9567}, 789 /* Gamma 1.7 */ 790 {0x00000196, 0x00000000, 791 0x0000006D, 0x000000CB, 792 0x0000012F, 0x00000102, 793 0x00000187, 0x00000199, 794 0x00000144, 0x0000025b, 795 0x00000118, 0x00000273, 796 0x000000FE, 0x0000038B, 797 0x000000E9, 0x00000395, 798 0x000000DA, 0x0000047E, 799 0x000000CE, 0x00000485, 800 0x000000C3, 0x00000552, 801 0x000000BB, 0x00000556, 802 0x000000B3, 0x00000611, 803 0x000000AC, 0x00000614, 804 0x000000A7, 0x000006C1, 805 0x000000A1, 0x000006C3, 806 0x0000009D, 0x00000765, 807 0x00000098, 0x00000767, 808 0.9394}, 809 /* Gamma 2.2 */ 810 {0x000001FF, 0x00000000, 811 0x0000018A, 0x00000100, 812 0x000000F1, 0x000001C5, 813 0x000001D6, 0x0000023D, 814 0x00000124, 0x00000328, 815 0x00000116, 0x0000032F, 816 0x000000E2, 0x00000446, 817 0x000000D3, 0x0000044D, 818 0x000000BC, 0x00000520, 819 0x000000B0, 0x00000526, 820 0x000000A4, 0x000005D6, 821 0x0000009B, 0x000005DB, 822 0x00000092, 0x00000676, 823 0x0000008B, 0x00000679, 824 0x00000085, 0x00000704, 825 0x00000080, 0x00000707, 826 0x0000007B, 0x00000787, 827 0x00000076, 0x00000789, 828 0.9135}, 829 /* Gamma 2.5 */ 830 {0x000001FF, 0x00000000, 831 0x000001FF, 0x00000100, 832 0x00000159, 0x000001FF, 833 0x000001AC, 0x000002AB, 834 0x0000012F, 0x00000381, 835 0x00000101, 0x00000399, 836 0x000000D9, 0x0000049A, 837 0x000000C3, 0x000004A5, 838 0x000000AF, 0x00000567, 839 0x000000A1, 0x0000056E, 840 0x00000095, 0x00000610, 841 0x0000008C, 0x00000614, 842 0x00000084, 0x000006A0, 843 0x0000007D, 0x000006A4, 844 0x00000077, 0x00000721, 845 0x00000071, 0x00000723, 846 0x0000006D, 0x00000795, 847 0x00000068, 0x00000797, 848 0.9135} 849}; 850 851static void 852RADEONSetOverlayGamma(ScrnInfoPtr pScrn, uint32_t gamma) 853{ 854 RADEONInfoPtr info = RADEONPTR(pScrn); 855 unsigned char *RADEONMMIO = info->MMIO; 856 857 /* Set gamma */ 858 RADEONWaitForIdleMMIO(pScrn); 859 860 if (info->ChipFamily < CHIP_FAMILY_R200) { 861 uint32_t ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL) & ~RADEON_SCALER_GAMMA_SEL_MASK; 862 OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 5)); 863 } 864 865 /* Load gamma curve adjustments */ 866 if (info->ChipFamily >= CHIP_FAMILY_R200) { 867 OUTREG(RADEON_OV0_GAMMA_000_00F, 868 (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) | 869 (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010)); 870 OUTREG(RADEON_OV0_GAMMA_010_01F, 871 (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) | 872 (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010)); 873 OUTREG(RADEON_OV0_GAMMA_020_03F, 874 (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) | 875 (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010)); 876 OUTREG(RADEON_OV0_GAMMA_040_07F, 877 (gamma_curve_r200[gamma].GAMMA_40_7F_OFFSET << 0x00000000) | 878 (gamma_curve_r200[gamma].GAMMA_40_7F_SLOPE << 0x00000010)); 879 OUTREG(RADEON_OV0_GAMMA_080_0BF, 880 (gamma_curve_r200[gamma].GAMMA_80_BF_OFFSET << 0x00000000) | 881 (gamma_curve_r200[gamma].GAMMA_80_BF_SLOPE << 0x00000010)); 882 OUTREG(RADEON_OV0_GAMMA_0C0_0FF, 883 (gamma_curve_r200[gamma].GAMMA_C0_FF_OFFSET << 0x00000000) | 884 (gamma_curve_r200[gamma].GAMMA_C0_FF_SLOPE << 0x00000010)); 885 OUTREG(RADEON_OV0_GAMMA_100_13F, 886 (gamma_curve_r200[gamma].GAMMA_100_13F_OFFSET << 0x00000000) | 887 (gamma_curve_r200[gamma].GAMMA_100_13F_SLOPE << 0x00000010)); 888 OUTREG(RADEON_OV0_GAMMA_140_17F, 889 (gamma_curve_r200[gamma].GAMMA_140_17F_OFFSET << 0x00000000) | 890 (gamma_curve_r200[gamma].GAMMA_140_17F_SLOPE << 0x00000010)); 891 OUTREG(RADEON_OV0_GAMMA_180_1BF, 892 (gamma_curve_r200[gamma].GAMMA_180_1BF_OFFSET << 0x00000000) | 893 (gamma_curve_r200[gamma].GAMMA_180_1BF_SLOPE << 0x00000010)); 894 OUTREG(RADEON_OV0_GAMMA_1C0_1FF, 895 (gamma_curve_r200[gamma].GAMMA_1C0_1FF_OFFSET << 0x00000000) | 896 (gamma_curve_r200[gamma].GAMMA_1C0_1FF_SLOPE << 0x00000010)); 897 OUTREG(RADEON_OV0_GAMMA_200_23F, 898 (gamma_curve_r200[gamma].GAMMA_200_23F_OFFSET << 0x00000000) | 899 (gamma_curve_r200[gamma].GAMMA_200_23F_SLOPE << 0x00000010)); 900 OUTREG(RADEON_OV0_GAMMA_240_27F, 901 (gamma_curve_r200[gamma].GAMMA_240_27F_OFFSET << 0x00000000) | 902 (gamma_curve_r200[gamma].GAMMA_240_27F_SLOPE << 0x00000010)); 903 OUTREG(RADEON_OV0_GAMMA_280_2BF, 904 (gamma_curve_r200[gamma].GAMMA_280_2BF_OFFSET << 0x00000000) | 905 (gamma_curve_r200[gamma].GAMMA_280_2BF_SLOPE << 0x00000010)); 906 OUTREG(RADEON_OV0_GAMMA_2C0_2FF, 907 (gamma_curve_r200[gamma].GAMMA_2C0_2FF_OFFSET << 0x00000000) | 908 (gamma_curve_r200[gamma].GAMMA_2C0_2FF_SLOPE << 0x00000010)); 909 OUTREG(RADEON_OV0_GAMMA_300_33F, 910 (gamma_curve_r200[gamma].GAMMA_300_33F_OFFSET << 0x00000000) | 911 (gamma_curve_r200[gamma].GAMMA_300_33F_SLOPE << 0x00000010)); 912 OUTREG(RADEON_OV0_GAMMA_340_37F, 913 (gamma_curve_r200[gamma].GAMMA_340_37F_OFFSET << 0x00000000) | 914 (gamma_curve_r200[gamma].GAMMA_340_37F_SLOPE << 0x00000010)); 915 OUTREG(RADEON_OV0_GAMMA_380_3BF, 916 (gamma_curve_r200[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) | 917 (gamma_curve_r200[gamma].GAMMA_380_3BF_SLOPE << 0x00000010)); 918 OUTREG(RADEON_OV0_GAMMA_3C0_3FF, 919 (gamma_curve_r200[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) | 920 (gamma_curve_r200[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010)); 921 } else { 922 OUTREG(RADEON_OV0_GAMMA_000_00F, 923 (gamma_curve_r100[gamma].GAMMA_0_F_OFFSET << 0x00000000) | 924 (gamma_curve_r100[gamma].GAMMA_0_F_SLOPE << 0x00000010)); 925 OUTREG(RADEON_OV0_GAMMA_010_01F, 926 (gamma_curve_r100[gamma].GAMMA_10_1F_OFFSET << 0x00000000) | 927 (gamma_curve_r100[gamma].GAMMA_10_1F_SLOPE << 0x00000010)); 928 OUTREG(RADEON_OV0_GAMMA_020_03F, 929 (gamma_curve_r100[gamma].GAMMA_20_3F_OFFSET << 0x00000000) | 930 (gamma_curve_r100[gamma].GAMMA_20_3F_SLOPE << 0x00000010)); 931 OUTREG(RADEON_OV0_GAMMA_040_07F, 932 (gamma_curve_r100[gamma].GAMMA_40_7F_OFFSET << 0x00000000) | 933 (gamma_curve_r100[gamma].GAMMA_40_7F_SLOPE << 0x00000010)); 934 OUTREG(RADEON_OV0_GAMMA_380_3BF, 935 (gamma_curve_r100[gamma].GAMMA_380_3BF_OFFSET << 0x00000000) | 936 (gamma_curve_r100[gamma].GAMMA_380_3BF_SLOPE << 0x00000010)); 937 OUTREG(RADEON_OV0_GAMMA_3C0_3FF, 938 (gamma_curve_r100[gamma].GAMMA_3C0_3FF_OFFSET << 0x00000000) | 939 (gamma_curve_r100[gamma].GAMMA_3C0_3FF_SLOPE << 0x00000010)); 940 } 941 942} 943 944static uint32_t 945RADEONTranslateUserGamma(uint32_t user_gamma) 946{ 947 /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */ 948 if (user_gamma <= 925) /* 0.85 */ 949 return 1; 950 else if (user_gamma <= 1050) /* 1.0 */ 951 return 0; 952 else if (user_gamma <= 1150) /* 1.1 */ 953 return 2; 954 else if (user_gamma <= 1325) /* 1.2 */ 955 return 3; 956 else if (user_gamma <= 1575) /* 1.45 */ 957 return 4; 958 else if (user_gamma <= 1950) /* 1.7 */ 959 return 5; 960 else if (user_gamma <= 2350) /* 2.2 */ 961 return 6; 962 else if (user_gamma > 2350) /* 2.5 */ 963 return 7; 964 else 965 return 0; 966} 967 968 969/**************************************************************************** 970 * SetTransform * 971 * Function: Calculates and sets color space transform from supplied * 972 * reference transform, gamma, brightness, contrast, hue and * 973 * saturation. * 974 * Inputs: bright - brightness * 975 * cont - contrast * 976 * sat - saturation * 977 * hue - hue * 978 * red_intensity - intensity of red component * 979 * green_intensity - intensity of green component * 980 * blue_intensity - intensity of blue component * 981 * ref - index to the table of refernce transforms * 982 * user_gamma - gamma value x 1000 (e.g., 1200 = gamma of 1.2) * 983 * Outputs: NONE * 984 ****************************************************************************/ 985 986static void RADEONSetTransform (ScrnInfoPtr pScrn, 987 float bright, 988 float cont, 989 float sat, 990 float hue, 991 float red_intensity, 992 float green_intensity, 993 float blue_intensity, 994 uint32_t ref, 995 uint32_t user_gamma) 996{ 997 RADEONInfoPtr info = RADEONPTR(pScrn); 998 unsigned char *RADEONMMIO = info->MMIO; 999 float OvHueSin, OvHueCos; 1000 float CAdjLuma, CAdjOff; 1001 float CAdjRCb, CAdjRCr; 1002 float CAdjGCb, CAdjGCr; 1003 float CAdjBCb, CAdjBCr; 1004 float RedAdj,GreenAdj,BlueAdj; 1005 float OvLuma, OvROff, OvGOff, OvBOff; 1006 float OvRCb, OvRCr; 1007 float OvGCb, OvGCr; 1008 float OvBCb, OvBCr; 1009 float Loff = 64.0; 1010 float Coff = 512.0f; 1011 1012 uint32_t dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff; 1013 uint32_t dwOvRCb, dwOvRCr; 1014 uint32_t dwOvGCb, dwOvGCr; 1015 uint32_t dwOvBCb, dwOvBCr; 1016 uint32_t gamma = 0; 1017 1018 if (ref >= 2) 1019 return; 1020 1021 /* translate from user_gamma (gamma x 1000) to radeon gamma table index value */ 1022 gamma = RADEONTranslateUserGamma(user_gamma); 1023 1024 if (gamma >= 8) 1025 return; 1026 1027 OvHueSin = sin(hue); 1028 OvHueCos = cos(hue); 1029 1030 CAdjLuma = cont * trans[ref].RefLuma; 1031 CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0; 1032 RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0; 1033 GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0; 1034 BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0; 1035 1036 CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr; 1037 CAdjRCr = sat * OvHueCos * trans[ref].RefRCr; 1038 CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr); 1039 CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr); 1040 CAdjBCb = sat * OvHueCos * trans[ref].RefBCb; 1041 CAdjBCr = sat * OvHueSin * trans[ref].RefBCb; 1042 1043#if 0 /* default constants */ 1044 CAdjLuma = 1.16455078125; 1045 1046 CAdjRCb = 0.0; 1047 CAdjRCr = 1.59619140625; 1048 CAdjGCb = -0.39111328125; 1049 CAdjGCr = -0.8125; 1050 CAdjBCb = 2.01708984375; 1051 CAdjBCr = 0; 1052#endif 1053 1054 OvLuma = CAdjLuma * gamma_curve_r100[gamma].OvGammaCont; 1055 OvRCb = CAdjRCb * gamma_curve_r100[gamma].OvGammaCont; 1056 OvRCr = CAdjRCr * gamma_curve_r100[gamma].OvGammaCont; 1057 OvGCb = CAdjGCb * gamma_curve_r100[gamma].OvGammaCont; 1058 OvGCr = CAdjGCr * gamma_curve_r100[gamma].OvGammaCont; 1059 OvBCb = CAdjBCb * gamma_curve_r100[gamma].OvGammaCont; 1060 OvBCr = CAdjBCr * gamma_curve_r100[gamma].OvGammaCont; 1061 OvROff = CAdjOff * gamma_curve_r100[gamma].OvGammaCont - 1062 OvLuma * Loff - (OvRCb + OvRCr) * Coff; 1063 OvGOff = CAdjOff * gamma_curve_r100[gamma].OvGammaCont - 1064 OvLuma * Loff - (OvGCb + OvGCr) * Coff; 1065 OvBOff = CAdjOff * gamma_curve_r100[gamma].OvGammaCont - 1066 OvLuma * Loff - (OvBCb + OvBCr) * Coff; 1067#if 0 /* default constants */ 1068 OvROff = -888.5; 1069 OvGOff = 545; 1070 OvBOff = -1104; 1071#endif 1072 1073 OvROff = ClipValue(OvROff, -2048.0, 2047.5); 1074 OvGOff = ClipValue(OvGOff, -2048.0, 2047.5); 1075 OvBOff = ClipValue(OvBOff, -2048.0, 2047.5); 1076 dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff; 1077 dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff; 1078 dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff; 1079 1080 if(info->ChipFamily == CHIP_FAMILY_RADEON) 1081 { 1082 dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17; 1083 dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1; 1084 dwOvRCr = (((INT32)(OvRCr * 2048.0))&0x7fff)<<17; 1085 dwOvGCb = (((INT32)(OvGCb * 2048.0))&0x7fff)<<1; 1086 dwOvGCr = (((INT32)(OvGCr * 2048.0))&0x7fff)<<17; 1087 dwOvBCb = (((INT32)(OvBCb * 2048.0))&0x7fff)<<1; 1088 dwOvBCr = (((INT32)(OvBCr * 2048.0))&0x7fff)<<17; 1089 } 1090 else 1091 { 1092 dwOvLuma = (((INT32)(OvLuma * 256.0))&0xfff)<<20; 1093 dwOvRCb = (((INT32)(OvRCb * 256.0))&0xfff)<<4; 1094 dwOvRCr = (((INT32)(OvRCr * 256.0))&0xfff)<<20; 1095 dwOvGCb = (((INT32)(OvGCb * 256.0))&0xfff)<<4; 1096 dwOvGCr = (((INT32)(OvGCr * 256.0))&0xfff)<<20; 1097 dwOvBCb = (((INT32)(OvBCb * 256.0))&0xfff)<<4; 1098 dwOvBCr = (((INT32)(OvBCr * 256.0))&0xfff)<<20; 1099 } 1100 1101 /* set gamma */ 1102 RADEONSetOverlayGamma(pScrn, gamma); 1103 1104 /* color transforms */ 1105 OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma); 1106 OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr); 1107 OUTREG(RADEON_OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma); 1108 OUTREG(RADEON_OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr); 1109 OUTREG(RADEON_OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma); 1110 OUTREG(RADEON_OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr); 1111} 1112 1113static void RADEONSetOverlayAlpha(ScrnInfoPtr pScrn, int ov_alpha, int gr_alpha, int alpha_mode) 1114{ 1115 RADEONInfoPtr info = RADEONPTR(pScrn); 1116 unsigned char *RADEONMMIO = info->MMIO; 1117 1118 if (alpha_mode == 0) { /* key mode */ 1119 OUTREG(RADEON_OV0_KEY_CNTL, 1120 RADEON_GRAPHIC_KEY_FN_EQ | /* what does this do? */ 1121 RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */ 1122 RADEON_CMP_MIX_OR); 1123 /* crtc 1 */ 1124 OUTREG(RADEON_DISP_MERGE_CNTL, 1125 (RADEON_DISP_ALPHA_MODE_KEY & 1126 RADEON_DISP_ALPHA_MODE_MASK) | 1127 ((gr_alpha << 0x00000010) & 1128 RADEON_DISP_GRPH_ALPHA_MASK) | 1129 ((ov_alpha << 0x00000018) & 1130 RADEON_DISP_OV0_ALPHA_MASK)); 1131 /* crtc 2 */ 1132 OUTREG(RADEON_DISP2_MERGE_CNTL, 1133 (RADEON_DISP_ALPHA_MODE_KEY & 1134 RADEON_DISP_ALPHA_MODE_MASK) | 1135 ((gr_alpha << 0x00000010) & 1136 RADEON_DISP_GRPH_ALPHA_MASK) | 1137 ((ov_alpha << 0x00000018) & 1138 RADEON_DISP_OV0_ALPHA_MASK)); 1139 } else { /* global mode */ 1140 OUTREG(RADEON_OV0_KEY_CNTL, 1141 RADEON_GRAPHIC_KEY_FN_FALSE | /* what does this do? */ 1142 RADEON_VIDEO_KEY_FN_FALSE | /* what does this do? */ 1143 RADEON_CMP_MIX_AND); 1144 /* crtc 2 */ 1145 OUTREG(RADEON_DISP2_MERGE_CNTL, 1146 (RADEON_DISP_ALPHA_MODE_GLOBAL & 1147 RADEON_DISP_ALPHA_MODE_MASK) | 1148 ((gr_alpha << 0x00000010) & 1149 RADEON_DISP_GRPH_ALPHA_MASK) | 1150 ((ov_alpha << 0x00000018) & 1151 RADEON_DISP_OV0_ALPHA_MASK)); 1152 /* crtc 1 */ 1153 OUTREG(RADEON_DISP_MERGE_CNTL, 1154 (RADEON_DISP_ALPHA_MODE_GLOBAL & 1155 RADEON_DISP_ALPHA_MODE_MASK) | 1156 ((gr_alpha << 0x00000010) & 1157 RADEON_DISP_GRPH_ALPHA_MASK) | 1158 ((ov_alpha << 0x00000018) & 1159 RADEON_DISP_OV0_ALPHA_MASK)); 1160 } 1161 /* per-pixel mode - RADEON_DISP_ALPHA_MODE_PER_PIXEL */ 1162 /* not yet supported */ 1163} 1164 1165static void RADEONSetColorKey(ScrnInfoPtr pScrn, uint32_t colorKey) 1166{ 1167 RADEONInfoPtr info = RADEONPTR(pScrn); 1168 unsigned char *RADEONMMIO = info->MMIO; 1169 uint32_t min, max; 1170 uint8_t r, g, b; 1171 1172 if (info->CurrentLayout.depth > 8) 1173 { 1174 uint32_t rbits, gbits, bbits; 1175 1176 rbits = (colorKey & pScrn->mask.red) >> pScrn->offset.red; 1177 gbits = (colorKey & pScrn->mask.green) >> pScrn->offset.green; 1178 bbits = (colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 1179 1180 r = rbits << (8 - pScrn->weight.red); 1181 g = gbits << (8 - pScrn->weight.green); 1182 b = bbits << (8 - pScrn->weight.blue); 1183 } 1184 else 1185 { 1186 uint32_t bits; 1187 1188 bits = colorKey & ((1 << info->CurrentLayout.depth) - 1); 1189 r = bits; 1190 g = bits; 1191 b = bits; 1192 } 1193 min = (r << 16) | (g << 8) | (b); 1194 max = (0xff << 24) | (r << 16) | (g << 8) | (b); 1195 1196 RADEONWaitForFifo(pScrn, 2); 1197 OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_HIGH, max); 1198 OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR_LOW, min); 1199} 1200 1201void 1202RADEONResetVideo(ScrnInfoPtr pScrn) 1203{ 1204 RADEONInfoPtr info = RADEONPTR(pScrn); 1205 unsigned char *RADEONMMIO = info->MMIO; 1206 RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; 1207 char tmp[200]; 1208 1209 /* this function is called from ScreenInit. pScreen is used 1210 by XAA internally, but not valid until ScreenInit finishs. 1211 */ 1212 if (info->accelOn && pScrn->pScreen) 1213 RADEON_SYNC(info, pScrn); 1214 1215 /* this is done here because each time the server is reset these 1216 could change.. Otherwise they remain constant */ 1217 xvInstanceID = MAKE_ATOM("XV_INSTANCE_ID"); 1218 xvDeviceID = MAKE_ATOM("XV_DEVICE_ID"); 1219 xvLocationID = MAKE_ATOM("XV_LOCATION_ID"); 1220 xvDumpStatus = MAKE_ATOM("XV_DUMP_STATUS"); 1221 1222 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 1223 xvSaturation = MAKE_ATOM("XV_SATURATION"); 1224 xvColor = MAKE_ATOM("XV_COLOR"); 1225 xvContrast = MAKE_ATOM("XV_CONTRAST"); 1226 xvColorKey = MAKE_ATOM("XV_COLORKEY"); 1227 xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 1228 xvHue = MAKE_ATOM("XV_HUE"); 1229 xvRedIntensity = MAKE_ATOM("XV_RED_INTENSITY"); 1230 xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY"); 1231 xvBlueIntensity = MAKE_ATOM("XV_BLUE_INTENSITY"); 1232 xvGamma = MAKE_ATOM("XV_GAMMA"); 1233 xvColorspace = MAKE_ATOM("XV_COLORSPACE"); 1234 1235 xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); 1236 xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); 1237 xvCRTC = MAKE_ATOM("XV_CRTC"); 1238 1239 xvOvAlpha = MAKE_ATOM("XV_OVERLAY_ALPHA"); 1240 xvGrAlpha = MAKE_ATOM("XV_GRAPHICS_ALPHA"); 1241 xvAlphaMode = MAKE_ATOM("XV_ALPHA_MODE"); 1242 1243 xvOverlayDeinterlacingMethod = MAKE_ATOM("XV_OVERLAY_DEINTERLACING_METHOD"); 1244 1245 xvDecBrightness = MAKE_ATOM("XV_DEC_BRIGHTNESS"); 1246 xvDecSaturation = MAKE_ATOM("XV_DEC_SATURATION"); 1247 xvDecColor = MAKE_ATOM("XV_DEC_COLOR"); 1248 xvDecContrast = MAKE_ATOM("XV_DEC_CONTRAST"); 1249 xvDecHue = MAKE_ATOM("XV_DEC_HUE"); 1250 1251 xvEncoding = MAKE_ATOM("XV_ENCODING"); 1252 xvFrequency = MAKE_ATOM("XV_FREQ"); 1253 xvTunerStatus = MAKE_ATOM("XV_TUNER_STATUS"); 1254 xvVolume = MAKE_ATOM("XV_VOLUME"); 1255 xvMute = MAKE_ATOM("XV_MUTE"); 1256 xvSAP = MAKE_ATOM("XV_SAP"); 1257 1258 xvAdjustment = MAKE_ATOM("XV_DEBUG_ADJUSTMENT"); 1259 1260 sprintf(tmp, "RXXX:%d.%d.%d", PCI_DEV_VENDOR_ID(info->PciInfo), 1261 PCI_DEV_DEVICE_ID(info->PciInfo), PCI_DEV_REVISION(info->PciInfo)); 1262 pPriv->device_id = MAKE_ATOM(tmp); 1263 sprintf(tmp, "PCI:%02d:%02d.%d", PCI_DEV_BUS(info->PciInfo), 1264 PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo)); 1265 pPriv->location_id = MAKE_ATOM(tmp); 1266 sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex); 1267 pPriv->instance_id = MAKE_ATOM(tmp); 1268 1269 OUTREG(RADEON_OV0_SCALE_CNTL, RADEON_SCALER_SOFT_RESET); 1270 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0); /* maybe */ 1271 OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0); 1272 OUTREG(RADEON_OV0_FILTER_CNTL, RADEON_FILTER_PROGRAMMABLE_COEF); 1273 OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_EQ | 1274 RADEON_VIDEO_KEY_FN_FALSE | 1275 RADEON_CMP_MIX_OR); 1276 OUTREG(RADEON_OV0_TEST, 0); 1277 OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); 1278 OUTREG(RADEON_CAP0_TRIG_CNTL, 0); 1279 RADEONSetColorKey(pScrn, pPriv->colorKey); 1280 1281 if (info->ChipFamily == CHIP_FAMILY_RADEON) { 1282 1283 OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a00000); 1284 OUTREG(RADEON_OV0_LIN_TRANS_B, 0x1990190e); 1285 OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a0f9c0); 1286 OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf3000442); 1287 OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a02040); 1288 OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f); 1289 1290 } else { 1291 1292 OUTREG(RADEON_OV0_LIN_TRANS_A, 0x12a20000); 1293 OUTREG(RADEON_OV0_LIN_TRANS_B, 0x198a190e); 1294 OUTREG(RADEON_OV0_LIN_TRANS_C, 0x12a2f9da); 1295 OUTREG(RADEON_OV0_LIN_TRANS_D, 0xf2fe0442); 1296 OUTREG(RADEON_OV0_LIN_TRANS_E, 0x12a22046); 1297 OUTREG(RADEON_OV0_LIN_TRANS_F, 0x175f); 1298 } 1299 /* 1300 * Set default Gamma ramp: 1301 * 1302 * Of 18 segments for gamma curve, all segments in R200 (and 1303 * newer) are programmable, while only lower 4 and upper 2 1304 * segments are programmable in the older Radeons. 1305 */ 1306 1307 RADEONSetOverlayGamma(pScrn, 0); /* gamma = 1.0 */ 1308 1309 if(pPriv->VIP!=NULL){ 1310 RADEONVIP_reset(pScrn,pPriv); 1311 } 1312 1313 if(pPriv->theatre != NULL) { 1314 xf86_InitTheatre(pPriv->theatre); 1315/* xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); */ 1316 } 1317 1318 if(pPriv->i2c != NULL){ 1319 RADEONResetI2C(pScrn, pPriv); 1320 } 1321} 1322 1323static void RADEONSetupTheatre(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 1324{ 1325 RADEONInfoPtr info = RADEONPTR(pScrn); 1326 RADEONPLLPtr pll = &(info->pll); 1327 TheatrePtr t; 1328 1329 uint8_t a; 1330 int i; 1331 1332 pPriv->theatre = NULL; 1333 1334 if(!info->MM_TABLE_valid && 1335 !((info->RageTheatreCrystal>=0) && 1336 (info->RageTheatreTunerPort>=0) && (info->RageTheatreCompositePort>=0) && 1337 (info->RageTheatreSVideoPort>=0))) 1338 { 1339 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no multimedia table present, disabling Rage Theatre.\n"); 1340 return; 1341 } 1342 1343 /* Go and find Rage Theatre, if it exists */ 1344 1345 if (info->IsMobility) 1346 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n"); 1347 else 1348 pPriv->theatre=xf86_DetectTheatre(pPriv->VIP); 1349 1350 if(pPriv->theatre==NULL)return; 1351 1352 /* just a matter of convenience */ 1353 t=pPriv->theatre; 1354 1355 t->video_decoder_type=info->video_decoder_type; 1356 1357 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type is 0x%04x (BIOS value) versus 0x%04x (current PLL setting)\n", 1358 t->video_decoder_type, pll->xclk); 1359 1360 if(info->MM_TABLE_valid){ 1361 for(i=0;i<5;i++){ 1362 a=info->MM_TABLE.input[i]; 1363 1364 switch(a & 0x3){ 1365 case 1: 1366 t->wTunerConnector=i; 1367 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tuner is on port %d\n",i); 1368 break; 1369 case 2: if(a & 0x4){ 1370 t->wComp0Connector=RT_COMP2; 1371 } else { 1372 t->wComp0Connector=RT_COMP1; 1373 } 1374 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector); 1375 break; 1376 case 3: if(a & 0x4){ 1377 t->wSVideo0Connector=RT_YCR_COMP4; 1378 } else { 1379 t->wSVideo0Connector=RT_YCF_COMP4; 1380 } 1381 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector); 1382 break; 1383 default: 1384 break; 1385 } 1386 } 1387 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n", 1388 (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector); 1389 1390 } 1391 1392 if(info->RageTheatreTunerPort>=0)t->wTunerConnector=info->RageTheatreTunerPort; 1393 if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort; 1394 if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort; 1395 1396 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n", 1397 (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector); 1398 1399 switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){ 1400 case 2700: 1401 t->video_decoder_type=RT_FREF_2700; 1402 break; 1403 case 2950: 1404 t->video_decoder_type=RT_FREF_2950; 1405 break; 1406 default: 1407 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1408 "Unsupported reference clock frequency, Rage Theatre disabled\n"); 1409 t->theatre_num=-1; 1410 xfree(pPriv->theatre); 1411 pPriv->theatre = NULL; 1412 return; 1413 } 1414 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type used: 0x%04x\n", t->video_decoder_type); 1415} 1416 1417static XF86VideoAdaptorPtr 1418RADEONAllocAdaptor(ScrnInfoPtr pScrn) 1419{ 1420 XF86VideoAdaptorPtr adapt; 1421 RADEONInfoPtr info = RADEONPTR(pScrn); 1422 RADEONPortPrivPtr pPriv; 1423 uint32_t dot_clock; 1424 int ecp; 1425 1426 if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn))) 1427 return NULL; 1428 1429 if(!(pPriv = xcalloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion)))) 1430 { 1431 xfree(adapt); 1432 return NULL; 1433 } 1434 1435 adapt->pPortPrivates = (DevUnion*)(&pPriv[1]); 1436 adapt->pPortPrivates[0].ptr = (pointer)pPriv; 1437 1438 pPriv->colorKey = info->videoKey; 1439 pPriv->doubleBuffer = TRUE; 1440 pPriv->videoStatus = 0; 1441 pPriv->brightness = 0; 1442 pPriv->transform_index = 0; 1443 pPriv->saturation = 0; 1444 pPriv->contrast = 0; 1445 pPriv->red_intensity = 0; 1446 pPriv->green_intensity = 0; 1447 pPriv->blue_intensity = 0; 1448 pPriv->hue = 0; 1449 pPriv->currentBuffer = 0; 1450 pPriv->autopaint_colorkey = TRUE; 1451 pPriv->gamma = 1000; 1452 pPriv->desired_crtc = NULL; 1453 1454 pPriv->ov_alpha = 255; 1455 pPriv->gr_alpha = 255; 1456 pPriv->alpha_mode = 0; 1457 1458 /* TV-in stuff */ 1459 pPriv->video_stream_active = FALSE; 1460 pPriv->encoding = 4; 1461 pPriv->frequency = 1000; 1462 pPriv->volume = -1000; 1463 pPriv->mute = TRUE; 1464 pPriv->v = 0; 1465 pPriv->overlay_deinterlacing_method = METHOD_BOB; 1466 pPriv->capture_vbi_data = 0; 1467 pPriv->dec_brightness = 0; 1468 pPriv->dec_saturation = 0; 1469 pPriv->dec_contrast = 0; 1470 pPriv->dec_hue = 0; 1471 1472 1473 /* 1474 * Unlike older Mach64 chips, RADEON has only two ECP settings: 1475 * 0 for PIXCLK < 175Mhz, and 1 (divide by 2) 1476 * for higher clocks, sure makes life nicer 1477 */ 1478 dot_clock = info->ModeReg->dot_clock_freq; 1479 1480 if (dot_clock < 17500) 1481 info->ecp_div = 0; 1482 else 1483 info->ecp_div = 1; 1484 ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8); 1485 1486 if (info->IsIGP) { 1487 /* Force the overlay clock on for integrated chips 1488 */ 1489 ecp |= (1<<18); 1490 } 1491 1492 OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp); 1493 1494 1495 /* Decide on tuner type */ 1496 if((info->tunerType<0) && (info->MM_TABLE_valid)) { 1497 pPriv->tuner_type = info->MM_TABLE.tuner_type; 1498 } else 1499 pPriv->tuner_type = info->tunerType; 1500 1501 /* Initialize I2C bus */ 1502 RADEONInitI2C(pScrn, pPriv); 1503 if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv); 1504 1505 1506 #if 0 /* this is just here for easy debugging - normally off */ 1507 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n"); 1508 for(i=0;i<255;i+=2) 1509 if(RADEONProbeAddress(pPriv->i2c, i)) 1510 xf86DrvMsg(pScrn->scrnIndex, X_INFO, " found device at address 0x%02x\n", i); 1511 #endif 1512 1513 /* resetting the VIP bus causes problems with some mobility chips. 1514 * we don't support video in on any mobility chips at the moment anyway 1515 */ 1516 /* Initialize VIP bus */ 1517 if (!info->IsMobility) 1518 RADEONVIP_init(pScrn, pPriv); 1519 1520 info->adaptor = adapt; 1521 1522 if(!xf86LoadSubModule(pScrn,"theatre_detect")) 1523 { 1524 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n"); 1525 goto skip_theatre; 1526 } 1527 RADEONSetupTheatre(pScrn, pPriv); 1528 1529 /* 1530 * Now load the correspondind theatre chip based on what has been detected. 1531 */ 1532 if (pPriv->theatre) 1533 { 1534 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Going to load the corresponding theatre module\n"); 1535 switch (pPriv->theatre->theatre_id) 1536 { 1537 case RT100_ATI_ID: 1538 { 1539 if(!xf86LoadSubModule(pScrn,"theatre")) 1540 { 1541 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n"); 1542 xfree(pPriv->theatre); 1543 goto skip_theatre; 1544 } 1545 break; 1546 } 1547 case RT200_ATI_ID: 1548 { 1549 if(!xf86LoadSubModule(pScrn,"theatre200")) 1550 { 1551 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n"); 1552 xfree(pPriv->theatre); 1553 goto skip_theatre; 1554 } 1555 pPriv->theatre->microc_path = info->RageTheatreMicrocPath; 1556 pPriv->theatre->microc_type = info->RageTheatreMicrocType; 1557 break; 1558 } 1559 default: 1560 { 1561 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unknown Theatre chip\n"); 1562 xfree(pPriv->theatre); 1563 goto skip_theatre; 1564 } 1565 } 1566 } 1567 1568 if(pPriv->theatre!=NULL) 1569 { 1570 xf86_InitTheatre(pPriv->theatre); 1571 if(pPriv->theatre->mode == MODE_UNINITIALIZED) 1572 { 1573 Xfree(pPriv->theatre); 1574 pPriv->theatre = NULL; 1575 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Rage Theatre disabled\n"); 1576 /* Here the modules must be unloaded */ 1577 goto skip_theatre; 1578 } 1579 } 1580 1581 if(pPriv->theatre!=NULL){ 1582 xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); 1583 xf86_RT_SetTint(pPriv->theatre, pPriv->dec_hue); 1584 xf86_RT_SetSaturation(pPriv->theatre, pPriv->dec_saturation); 1585 xf86_RT_SetSharpness(pPriv->theatre, RT_NORM_SHARPNESS); 1586 xf86_RT_SetContrast(pPriv->theatre, pPriv->dec_contrast); 1587 xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness); 1588 1589 RADEON_RT_SetEncoding(pScrn, pPriv); 1590 } 1591 1592skip_theatre: 1593 1594 return adapt; 1595} 1596 1597static XF86VideoAdaptorPtr 1598RADEONSetupImageVideo(ScreenPtr pScreen) 1599{ 1600 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1601 RADEONPortPrivPtr pPriv; 1602 XF86VideoAdaptorPtr adapt; 1603 1604 if(!(adapt = RADEONAllocAdaptor(pScrn))) 1605 return NULL; 1606 1607 adapt->type = XvWindowMask | XvInputMask | XvImageMask; 1608 adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/; 1609 adapt->name = "ATI Radeon Video Overlay"; 1610 adapt->nEncodings = 1; 1611 adapt->pEncodings = &DummyEncoding; 1612 adapt->nFormats = NUM_FORMATS; 1613 adapt->pFormats = Formats; 1614 adapt->nPorts = 1; 1615 adapt->nAttributes = NUM_ATTRIBUTES; 1616 adapt->pAttributes = Attributes; 1617 adapt->nImages = NUM_IMAGES; 1618 adapt->pImages = Images; 1619 adapt->PutVideo = NULL; 1620 adapt->PutStill = NULL; 1621 adapt->GetVideo = NULL; 1622 adapt->GetStill = NULL; 1623 adapt->StopVideo = RADEONStopVideo; 1624 adapt->SetPortAttribute = RADEONSetPortAttribute; 1625 adapt->GetPortAttribute = RADEONGetPortAttribute; 1626 adapt->QueryBestSize = RADEONQueryBestSize; 1627 adapt->PutImage = RADEONPutImage; 1628 adapt->QueryImageAttributes = RADEONQueryImageAttributes; 1629 1630 pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr); 1631 REGION_NULL(pScreen, &(pPriv->clip)); 1632 1633 pPriv->textured = FALSE; 1634 1635 if(pPriv->theatre != NULL) 1636 { 1637 /* video decoder is present, extend capabilities */ 1638 adapt->nEncodings = 13; 1639 adapt->pEncodings = InputVideoEncodings; 1640 adapt->type |= XvVideoMask; 1641 adapt->nAttributes = NUM_DEC_ATTRIBUTES; 1642 adapt->PutVideo = RADEONPutVideo; 1643 } 1644 1645 RADEONResetVideo(pScrn); 1646 1647 return adapt; 1648} 1649 1650void 1651RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup) 1652{ 1653 RADEONInfoPtr info = RADEONPTR(pScrn); 1654 unsigned char *RADEONMMIO = info->MMIO; 1655 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1656 1657 if (pPriv->textured) 1658 return; 1659 1660 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1661 1662 if(cleanup) { 1663 if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1664 RADEONWaitForFifo(pScrn, 2); 1665 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 1666 } 1667 if(pPriv->video_stream_active){ 1668 RADEONWaitForFifo(pScrn, 2); 1669 OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); 1670 OUTREG(RADEON_CAP0_TRIG_CNTL, 0); 1671 RADEONResetVideo(pScrn); 1672 pPriv->video_stream_active = FALSE; 1673 if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 1674 if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE); 1675 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1676 } 1677 if (pPriv->video_memory != NULL) { 1678 RADEONFreeMemory(pScrn, pPriv->video_memory); 1679 pPriv->video_memory = NULL; 1680 } 1681 pPriv->videoStatus = 0; 1682 } else { 1683 if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1684 pPriv->videoStatus |= OFF_TIMER; 1685 pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 1686 } 1687 } 1688} 1689 1690int 1691RADEONSetPortAttribute(ScrnInfoPtr pScrn, 1692 Atom attribute, 1693 INT32 value, 1694 pointer data) 1695{ 1696 RADEONInfoPtr info = RADEONPTR(pScrn); 1697 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1698 Bool setTransform = FALSE; 1699 Bool setAlpha = FALSE; 1700 unsigned char *RADEONMMIO = info->MMIO; 1701 1702 if (pPriv->textured) 1703 return BadMatch; 1704 1705 RADEON_SYNC(info, pScrn); 1706 1707#define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0) 1708#define RTFBrightness(a) (((a)*1.0)/2000.0) 1709#define RTFIntensity(a) (((a)*1.0)/2000.0) 1710#define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) 1711#define RTFHue(a) (((a)*3.1416)/1000.0) 1712 1713 if(attribute == xvAutopaintColorkey) 1714 { 1715 pPriv->autopaint_colorkey = ClipValue (value, 0, 1); 1716 } 1717 else if(attribute == xvSetDefaults) 1718 { 1719 pPriv->autopaint_colorkey = TRUE; 1720 pPriv->brightness = 0; 1721 pPriv->saturation = 0; 1722 pPriv->contrast = 0; 1723 pPriv->hue = 0; 1724 pPriv->red_intensity = 0; 1725 pPriv->green_intensity = 0; 1726 pPriv->blue_intensity = 0; 1727 pPriv->gamma = 1000; 1728 pPriv->transform_index = 0; 1729 pPriv->doubleBuffer = FALSE; 1730 pPriv->ov_alpha = 255; 1731 pPriv->gr_alpha = 255; 1732 pPriv->alpha_mode = 0; 1733 1734 /* It is simpler to call itself */ 1735 RADEONSetPortAttribute(pScrn, xvDecBrightness, 0, data); 1736 RADEONSetPortAttribute(pScrn, xvDecSaturation, 0, data); 1737 RADEONSetPortAttribute(pScrn, xvDecContrast, 0, data); 1738 RADEONSetPortAttribute(pScrn, xvDecHue, 0, data); 1739 1740 RADEONSetPortAttribute(pScrn, xvVolume, -1000, data); 1741 RADEONSetPortAttribute(pScrn, xvMute, 1, data); 1742 RADEONSetPortAttribute(pScrn, xvSAP, 0, data); 1743 RADEONSetPortAttribute(pScrn, xvDoubleBuffer, 1, data); 1744 1745 setTransform = TRUE; 1746 setAlpha = TRUE; 1747 } 1748 else if(attribute == xvBrightness) 1749 { 1750 pPriv->brightness = ClipValue (value, -1000, 1000); 1751 setTransform = TRUE; 1752 } 1753 else if((attribute == xvSaturation) || (attribute == xvColor)) 1754 { 1755 pPriv->saturation = ClipValue (value, -1000, 1000); 1756 setTransform = TRUE; 1757 } 1758 else if(attribute == xvContrast) 1759 { 1760 pPriv->contrast = ClipValue (value, -1000, 1000); 1761 setTransform = TRUE; 1762 } 1763 else if(attribute == xvHue) 1764 { 1765 pPriv->hue = ClipValue (value, -1000, 1000); 1766 setTransform = TRUE; 1767 } 1768 else if(attribute == xvRedIntensity) 1769 { 1770 pPriv->red_intensity = ClipValue (value, -1000, 1000); 1771 setTransform = TRUE; 1772 } 1773 else if(attribute == xvGreenIntensity) 1774 { 1775 pPriv->green_intensity = ClipValue (value, -1000, 1000); 1776 setTransform = TRUE; 1777 } 1778 else if(attribute == xvBlueIntensity) 1779 { 1780 pPriv->blue_intensity = ClipValue (value, -1000, 1000); 1781 setTransform = TRUE; 1782 } 1783 else if(attribute == xvGamma) 1784 { 1785 pPriv->gamma = ClipValue (value, 100, 10000); 1786 setTransform = TRUE; 1787 } 1788 else if(attribute == xvColorspace) 1789 { 1790 pPriv->transform_index = ClipValue (value, 0, 1); 1791 setTransform = TRUE; 1792 } 1793 else if(attribute == xvDoubleBuffer) 1794 { 1795 pPriv->doubleBuffer = ClipValue (value, 0, 1); 1796 } 1797 else if(attribute == xvColorKey) 1798 { 1799 pPriv->colorKey = value; 1800 RADEONSetColorKey (pScrn, pPriv->colorKey); 1801 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1802 } 1803 else if(attribute == xvCRTC) 1804 { 1805 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1806 if ((value < -1) || (value > xf86_config->num_crtc)) 1807 return BadValue; 1808 if (value < 0) 1809 pPriv->desired_crtc = NULL; 1810 else 1811 pPriv->desired_crtc = xf86_config->crtc[value]; 1812 } 1813 else if(attribute == xvOvAlpha) 1814 { 1815 pPriv->ov_alpha = ClipValue (value, 0, 255); 1816 setAlpha = TRUE; 1817 } 1818 else if(attribute == xvGrAlpha) 1819 { 1820 pPriv->gr_alpha = ClipValue (value, 0, 255); 1821 setAlpha = TRUE; 1822 } 1823 else if(attribute == xvAlphaMode) 1824 { 1825 pPriv->alpha_mode = ClipValue (value, 0, 1); 1826 setAlpha = TRUE; 1827 } 1828 else if(attribute == xvDecBrightness) 1829 { 1830 pPriv->dec_brightness = value; 1831 if(pPriv->theatre!=NULL) xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness); 1832 } 1833 else if((attribute == xvDecSaturation) || (attribute == xvDecColor)) 1834 { 1835 if(value<-1000)value = -1000; 1836 if(value>1000)value = 1000; 1837 pPriv->dec_saturation = value; 1838 if(pPriv->theatre != NULL)xf86_RT_SetSaturation(pPriv->theatre, value); 1839 } 1840 else if(attribute == xvDecContrast) 1841 { 1842 pPriv->dec_contrast = value; 1843 if(pPriv->theatre != NULL)xf86_RT_SetContrast(pPriv->theatre, value); 1844 } 1845 else if(attribute == xvDecHue) 1846 { 1847 pPriv->dec_hue = value; 1848 if(pPriv->theatre != NULL)xf86_RT_SetTint(pPriv->theatre, value); 1849 } 1850 else if(attribute == xvEncoding) 1851 { 1852 pPriv->encoding = value; 1853 if(pPriv->video_stream_active) 1854 { 1855 if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv); 1856 if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv); 1857 if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv); 1858 if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv); 1859 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1860 /* put more here to actually change it */ 1861 } 1862 } 1863 else if(attribute == xvFrequency) 1864 { 1865 pPriv->frequency = value; 1866 /* mute volume if it was not muted before */ 1867 if((pPriv->msp3430!=NULL)&& !pPriv->mute)xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 1868 if((pPriv->uda1380!=NULL)&& !pPriv->mute)xf86_uda1380_mute(pPriv->uda1380, TRUE); 1869 if(pPriv->fi1236 != NULL) xf86_TUNER_set_frequency(pPriv->fi1236, value); 1870/* if(pPriv->theatre != NULL) RADEON_RT_SetEncoding(pScrn, pPriv); */ 1871 if((pPriv->msp3430 != NULL) && (pPriv->msp3430->recheck)) 1872 xf86_InitMSP3430(pPriv->msp3430); 1873 if((pPriv->msp3430 != NULL)&& !pPriv->mute) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(pPriv->volume)); 1874 if((pPriv->uda1380 != NULL)&& !pPriv->mute) xf86_uda1380_setvolume(pPriv->uda1380, pPriv->volume); 1875 } 1876 else if(attribute == xvMute) 1877 { 1878 pPriv->mute = value; 1879 if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume)); 1880 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1881 if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, pPriv->mute); 1882 } 1883 else if(attribute == xvSAP) 1884 { 1885 pPriv->sap_channel = value; 1886 if(pPriv->msp3430 != NULL) xf86_MSP3430SetSAP(pPriv->msp3430, pPriv->sap_channel?4:3); 1887 } 1888 else if(attribute == xvVolume) 1889 { 1890 if(value<-1000)value = -1000; 1891 if(value>1000)value = 1000; 1892 pPriv->volume = value; 1893 pPriv->mute = FALSE; 1894 if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_VOLUME(value)); 1895 if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); 1896 if(pPriv->uda1380 != NULL) xf86_uda1380_setvolume(pPriv->uda1380, value); 1897 } 1898 else if(attribute == xvOverlayDeinterlacingMethod) 1899 { 1900 if(value<0)value = 0; 1901 if(value>2)value = 2; 1902 pPriv->overlay_deinterlacing_method = value; 1903 switch(pPriv->overlay_deinterlacing_method){ 1904 case METHOD_BOB: 1905 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 1906 break; 1907 case METHOD_SINGLE: 1908 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28)); 1909 break; 1910 case METHOD_WEAVE: 1911 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x0); 1912 break; 1913 default: 1914 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 1915 } 1916 } 1917 else if(attribute == xvDumpStatus) 1918 { 1919 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode flags 0x%08x: %s%s\n", 1920 pScrn->currentMode->Flags, 1921 pScrn->currentMode->Flags & V_INTERLACE ? " interlaced" : "" , 1922 pScrn->currentMode->Flags & V_DBLSCAN ? " doublescan" : "" 1923 ); 1924 if(pPriv->tda9885 != NULL){ 1925 xf86_tda9885_getstatus(pPriv->tda9885); 1926 xf86_tda9885_dumpstatus(pPriv->tda9885); 1927 } 1928 if(pPriv->fi1236!=NULL){ 1929 xf86_fi1236_dump_status(pPriv->fi1236); 1930 } 1931 } 1932 else if(attribute == xvAdjustment) 1933 { 1934 pPriv->adjustment=value; 1935 xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n", 1936 (unsigned)pPriv->adjustment); 1937 if(pPriv->tda9885!=0){ 1938 pPriv->tda9885->top_adjustment=value; 1939 RADEON_TDA9885_SetEncoding(pPriv); 1940 } 1941 } 1942 else 1943 return BadMatch; 1944 1945 if (setTransform) 1946 { 1947 RADEONSetTransform(pScrn, 1948 RTFBrightness(pPriv->brightness), 1949 RTFContrast(pPriv->contrast), 1950 RTFSaturation(pPriv->saturation), 1951 RTFHue(pPriv->hue), 1952 RTFIntensity(pPriv->red_intensity), 1953 RTFIntensity(pPriv->green_intensity), 1954 RTFIntensity(pPriv->blue_intensity), 1955 pPriv->transform_index, 1956 pPriv->gamma); 1957 } 1958 1959 if (setAlpha) 1960 { 1961 RADEONSetOverlayAlpha(pScrn, pPriv->ov_alpha, pPriv->gr_alpha, pPriv->alpha_mode); 1962 } 1963 1964 return Success; 1965} 1966 1967int 1968RADEONGetPortAttribute(ScrnInfoPtr pScrn, 1969 Atom attribute, 1970 INT32 *value, 1971 pointer data) 1972{ 1973 RADEONInfoPtr info = RADEONPTR(pScrn); 1974 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 1975 1976 if (pPriv->textured) 1977 return BadMatch; 1978 1979 if (info->accelOn) RADEON_SYNC(info, pScrn); 1980 1981 if(attribute == xvAutopaintColorkey) 1982 *value = pPriv->autopaint_colorkey; 1983 else if(attribute == xvBrightness) 1984 *value = pPriv->brightness; 1985 else if((attribute == xvSaturation) || (attribute == xvColor)) 1986 *value = pPriv->saturation; 1987 else if(attribute == xvContrast) 1988 *value = pPriv->contrast; 1989 else if(attribute == xvHue) 1990 *value = pPriv->hue; 1991 else if(attribute == xvRedIntensity) 1992 *value = pPriv->red_intensity; 1993 else if(attribute == xvGreenIntensity) 1994 *value = pPriv->green_intensity; 1995 else if(attribute == xvBlueIntensity) 1996 *value = pPriv->blue_intensity; 1997 else if(attribute == xvGamma) 1998 *value = pPriv->gamma; 1999 else if(attribute == xvColorspace) 2000 *value = pPriv->transform_index; 2001 else if(attribute == xvDoubleBuffer) 2002 *value = pPriv->doubleBuffer ? 1 : 0; 2003 else if(attribute == xvColorKey) 2004 *value = pPriv->colorKey; 2005 else if(attribute == xvCRTC) { 2006 int c; 2007 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2008 for (c = 0; c < xf86_config->num_crtc; c++) 2009 if (xf86_config->crtc[c] == pPriv->desired_crtc) 2010 break; 2011 if (c == xf86_config->num_crtc) 2012 c = -1; 2013 *value = c; 2014 } 2015 else if(attribute == xvOvAlpha) 2016 *value = pPriv->ov_alpha; 2017 else if(attribute == xvGrAlpha) 2018 *value = pPriv->gr_alpha; 2019 else if(attribute == xvAlphaMode) 2020 *value = pPriv->alpha_mode; 2021 else if(attribute == xvDecBrightness) 2022 *value = pPriv->dec_brightness; 2023 else if((attribute == xvDecSaturation) || (attribute == xvDecColor)) 2024 *value = pPriv->dec_saturation; 2025 else if(attribute == xvDecContrast) 2026 *value = pPriv->dec_contrast; 2027 else if(attribute == xvDecHue) 2028 *value = pPriv->dec_hue; 2029 else if(attribute == xvEncoding) 2030 *value = pPriv->encoding; 2031 else if(attribute == xvFrequency) 2032 *value = pPriv->frequency; 2033 else 2034 if(attribute == xvTunerStatus) { 2035 if(pPriv->fi1236==NULL){ 2036 *value=TUNER_OFF; 2037 } else 2038 { 2039 *value = xf86_TUNER_get_afc_hint(pPriv->fi1236); 2040 } 2041 } 2042 else if(attribute == xvMute) 2043 *value = pPriv->mute; 2044 else if(attribute == xvSAP) 2045 *value = pPriv->sap_channel; 2046 else if(attribute == xvVolume) 2047 *value = pPriv->volume; 2048 else if(attribute == xvOverlayDeinterlacingMethod) 2049 *value = pPriv->overlay_deinterlacing_method; 2050 else if(attribute == xvDeviceID) 2051 *value = pPriv->device_id; 2052 else if(attribute == xvLocationID) 2053 *value = pPriv->location_id; 2054 else if(attribute == xvInstanceID) 2055 *value = pPriv->instance_id; 2056 else if(attribute == xvAdjustment) 2057 *value = pPriv->adjustment; 2058 else 2059 return BadMatch; 2060 2061 return Success; 2062} 2063 2064void 2065RADEONQueryBestSize( 2066 ScrnInfoPtr pScrn, 2067 Bool motion, 2068 short vid_w, short vid_h, 2069 short drw_w, short drw_h, 2070 unsigned int *p_w, unsigned int *p_h, 2071 pointer data 2072){ 2073 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 2074 2075 if (!pPriv->textured) { 2076 if (vid_w > (drw_w << 4)) 2077 drw_w = vid_w >> 4; 2078 if (vid_h > (drw_h << 4)) 2079 drw_h = vid_h >> 4; 2080 } 2081 2082 *p_w = drw_w; 2083 *p_h = drw_h; 2084} 2085 2086static struct { 2087 double range; 2088 signed char coeff[5][4]; 2089 } TapCoeffs[]= 2090 { 2091 {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2092 {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2093 {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2094 {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2095 {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2096 {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2097 {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2098 {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2099 {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2100 {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2101 {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2102 {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2103 {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2104 {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2105 {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2106 {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2107 {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2108 {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2109 {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2110 {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2111 {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2112 {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2113 {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2114 {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2115 {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2116 {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, 2117 {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }}, 2118 {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2119 {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2120 {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, 2121 {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }}, 2122 {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2123 {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2124 {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2125 {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2126 {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2127 {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2128 {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2129 {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2130 {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, 2131 {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2132 {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2133 {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, 2134 {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2135 {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2136 {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2137 {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, 2138 {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2139 {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2140 {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2141 {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2142 {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, 2143 {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, 2144 {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, 2145 {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2146 {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2147 {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, 2148 {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }}, 2149 {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2150 {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2151 {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2152 {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2153 {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, 2154 {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2155 {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2156 {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2157 {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2158 {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2159 {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2160 {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, 2161 {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2162 {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2163 {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2164 {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, 2165 {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}, 2166 {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }} 2167 }; 2168 2169void 2170RADEONCopyData( 2171 ScrnInfoPtr pScrn, 2172 unsigned char *src, 2173 unsigned char *dst, 2174 unsigned int srcPitch, 2175 unsigned int dstPitch, 2176 unsigned int h, 2177 unsigned int w, 2178 unsigned int bpp 2179){ 2180 RADEONInfoPtr info = RADEONPTR(pScrn); 2181 2182 /* Get the byte-swapping right for big endian systems */ 2183 if ( bpp == 2 ) { 2184 w *= 2; 2185 bpp = 1; 2186 } 2187 2188#ifdef XF86DRI 2189 2190 if ( info->directRenderingEnabled && info->DMAForXv ) 2191 { 2192 uint8_t *buf; 2193 uint32_t bufPitch, dstPitchOff; 2194 int x, y; 2195 unsigned int hpass; 2196 2197 RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y ); 2198 2199 while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch, 2200 x, &y, &h, &hpass )) ) 2201 { 2202 RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch, 2203 srcPitch ); 2204 src += hpass * srcPitch; 2205 } 2206 2207 FLUSH_RING(); 2208 2209 return; 2210 } 2211 else 2212#endif /* XF86DRI */ 2213 { 2214#if X_BYTE_ORDER == X_BIG_ENDIAN 2215 unsigned char *RADEONMMIO = info->MMIO; 2216 unsigned int swapper = info->ModeReg->surface_cntl & 2217 ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP | 2218 RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP); 2219 2220 switch(bpp) { 2221 case 2: 2222 swapper |= RADEON_NONSURF_AP0_SWP_16BPP 2223 | RADEON_NONSURF_AP1_SWP_16BPP; 2224 break; 2225 case 4: 2226 swapper |= RADEON_NONSURF_AP0_SWP_32BPP 2227 | RADEON_NONSURF_AP1_SWP_32BPP; 2228 break; 2229 } 2230 OUTREG(RADEON_SURFACE_CNTL, swapper); 2231#endif 2232 w *= bpp; 2233 2234 while (h--) { 2235 memcpy(dst, src, w); 2236 src += srcPitch; 2237 dst += dstPitch; 2238 } 2239 2240#if X_BYTE_ORDER == X_BIG_ENDIAN 2241 /* restore byte swapping */ 2242 OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl); 2243#endif 2244 } 2245} 2246 2247static void 2248RADEONCopyRGB24Data( 2249 ScrnInfoPtr pScrn, 2250 unsigned char *src, 2251 unsigned char *dst, 2252 unsigned int srcPitch, 2253 unsigned int dstPitch, 2254 unsigned int h, 2255 unsigned int w 2256){ 2257 uint32_t *dptr; 2258 uint8_t *sptr; 2259 int i,j; 2260 RADEONInfoPtr info = RADEONPTR(pScrn); 2261#ifdef XF86DRI 2262 2263 if ( info->directRenderingEnabled && info->DMAForXv ) 2264 { 2265 uint32_t bufPitch, dstPitchOff; 2266 int x, y; 2267 unsigned int hpass; 2268 2269 RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y ); 2270 2271 while ( (dptr = ( uint32_t* )RADEONHostDataBlit( pScrn, 4, w, dstPitchOff, 2272 &bufPitch, x, &y, &h, 2273 &hpass )) ) 2274 { 2275 for( j = 0; j < hpass; j++ ) 2276 { 2277 sptr = src; 2278 2279 for ( i = 0 ; i < w; i++, sptr += 3 ) 2280 { 2281 dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0]; 2282 } 2283 2284 src += srcPitch; 2285 dptr += bufPitch / 4; 2286 } 2287 } 2288 2289 FLUSH_RING(); 2290 2291 return; 2292 } 2293 else 2294#endif /* XF86DRI */ 2295 { 2296#if X_BYTE_ORDER == X_BIG_ENDIAN 2297 unsigned char *RADEONMMIO = info->MMIO; 2298 OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg->surface_cntl 2299 | RADEON_NONSURF_AP0_SWP_32BPP) 2300 & ~RADEON_NONSURF_AP0_SWP_16BPP); 2301#endif 2302 2303 for (j = 0; j < h; j++) { 2304 dptr = (uint32_t *)(dst + j * dstPitch); 2305 sptr = src + j * srcPitch; 2306 2307 for (i = 0; i < w; i++, sptr += 3) { 2308 dptr[i] = (sptr[2] << 16) | (sptr[1] << 8) | sptr[0]; 2309 } 2310 } 2311 2312#if X_BYTE_ORDER == X_BIG_ENDIAN 2313 /* restore byte swapping */ 2314 OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl); 2315#endif 2316 } 2317} 2318 2319 2320#ifdef XF86DRI 2321static void RADEON_420_422( 2322 unsigned int *d, 2323 unsigned char *s1, 2324 unsigned char *s2, 2325 unsigned char *s3, 2326 unsigned int n 2327) 2328{ 2329 while ( n ) { 2330 *(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); 2331 s1+=2; s2++; s3++; 2332 n--; 2333 } 2334} 2335#endif 2336 2337void 2338RADEONCopyMungedData( 2339 ScrnInfoPtr pScrn, 2340 unsigned char *src1, 2341 unsigned char *src2, 2342 unsigned char *src3, 2343 unsigned char *dst1, 2344 unsigned int srcPitch, 2345 unsigned int srcPitch2, 2346 unsigned int dstPitch, 2347 unsigned int h, 2348 unsigned int w 2349){ 2350 RADEONInfoPtr info = RADEONPTR(pScrn); 2351#ifdef XF86DRI 2352 2353 if ( info->directRenderingEnabled && info->DMAForXv ) 2354 { 2355 uint8_t *buf; 2356 uint32_t y = 0, bufPitch, dstPitchOff; 2357 int blitX, blitY; 2358 unsigned int hpass; 2359 2360 /* XXX Fix endian flip on R300 */ 2361 2362 RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY ); 2363 2364 while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch, 2365 blitX, &blitY, &h, &hpass )) ) 2366 { 2367 while ( hpass-- ) 2368 { 2369 RADEON_420_422( (unsigned int *) buf, src1, src2, src3, 2370 bufPitch / 4 ); 2371 src1 += srcPitch; 2372 if ( y & 1 ) 2373 { 2374 src2 += srcPitch2; 2375 src3 += srcPitch2; 2376 } 2377 buf += bufPitch; 2378 y++; 2379 } 2380 } 2381 2382 FLUSH_RING(); 2383 } 2384 else 2385#endif /* XF86DRI */ 2386 { 2387 uint32_t *dst; 2388 uint8_t *s1, *s2, *s3; 2389 int i, j; 2390 2391#if X_BYTE_ORDER == X_BIG_ENDIAN 2392 unsigned char *RADEONMMIO = info->MMIO; 2393 OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg->surface_cntl 2394 | RADEON_NONSURF_AP0_SWP_32BPP) 2395 & ~RADEON_NONSURF_AP0_SWP_16BPP); 2396#endif 2397 2398 w /= 2; 2399 2400 for( j = 0; j < h; j++ ) 2401 { 2402 dst = (pointer)dst1; 2403 s1 = src1; s2 = src2; s3 = src3; 2404 i = w; 2405 while( i > 4 ) 2406 { 2407 dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); 2408 dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24); 2409 dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24); 2410 dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24); 2411 dst += 4; s2 += 4; s3 += 4; s1 += 8; 2412 i -= 4; 2413 } 2414 while( i-- ) 2415 { 2416 dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); 2417 dst++; s2++; s3++; 2418 s1 += 2; 2419 } 2420 2421 dst1 += dstPitch; 2422 src1 += srcPitch; 2423 if( j & 1 ) 2424 { 2425 src2 += srcPitch2; 2426 src3 += srcPitch2; 2427 } 2428 } 2429#if X_BYTE_ORDER == X_BIG_ENDIAN 2430 /* restore byte swapping */ 2431 OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl); 2432#endif 2433 } 2434} 2435 2436 2437/* Allocates memory, either by resizing the allocation pointed to by mem_struct, 2438 * or by freeing mem_struct (if non-NULL) and allocating a new space. The size 2439 * is measured in bytes, and the offset from the beginning of card space is 2440 * returned. 2441 */ 2442uint32_t 2443RADEONAllocateMemory( 2444 ScrnInfoPtr pScrn, 2445 void **mem_struct, 2446 int size 2447){ 2448 ScreenPtr pScreen; 2449 RADEONInfoPtr info = RADEONPTR(pScrn); 2450 int offset = 0; 2451 2452 pScreen = screenInfo.screens[pScrn->scrnIndex]; 2453#ifdef USE_EXA 2454 if (info->useEXA) { 2455 ExaOffscreenArea *area = *mem_struct; 2456 2457 if (area != NULL) { 2458 if (area->size >= size) 2459 return area->offset; 2460 2461 exaOffscreenFree(pScrn->pScreen, area); 2462 } 2463 2464 area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, ATIVideoSave, 2465 NULL); 2466 *mem_struct = area; 2467 if (area == NULL) 2468 return 0; 2469 offset = area->offset; 2470 } 2471#endif /* USE_EXA */ 2472#ifdef USE_XAA 2473 if (!info->useEXA) { 2474 FBLinearPtr linear = *mem_struct; 2475 int cpp = info->CurrentLayout.bitsPerPixel / 8; 2476 2477 /* XAA allocates in units of pixels at the screen bpp, so adjust size 2478 * appropriately. 2479 */ 2480 size = (size + cpp - 1) / cpp; 2481 2482 if (linear) { 2483 if(linear->size >= size) 2484 return linear->offset * cpp; 2485 2486 if(xf86ResizeOffscreenLinear(linear, size)) 2487 return linear->offset * cpp; 2488 2489 xf86FreeOffscreenLinear(linear); 2490 } 2491 2492 linear = xf86AllocateOffscreenLinear(pScreen, size, 16, 2493 NULL, NULL, NULL); 2494 *mem_struct = linear; 2495 2496 if (!linear) { 2497 int max_size; 2498 2499 xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, 2500 PRIORITY_EXTREME); 2501 2502 if(max_size < size) 2503 return 0; 2504 2505 xf86PurgeUnlockedOffscreenAreas(pScreen); 2506 linear = xf86AllocateOffscreenLinear(pScreen, size, 16, 2507 NULL, NULL, NULL); 2508 *mem_struct = linear; 2509 if (!linear) 2510 return 0; 2511 } 2512 offset = linear->offset * cpp; 2513 } 2514#endif /* USE_XAA */ 2515 2516 return offset; 2517} 2518 2519void 2520RADEONFreeMemory( 2521 ScrnInfoPtr pScrn, 2522 void *mem_struct 2523){ 2524 RADEONInfoPtr info = RADEONPTR(pScrn); 2525 2526#ifdef USE_EXA 2527 if (info->useEXA) { 2528 ExaOffscreenArea *area = mem_struct; 2529 2530 if (area != NULL) 2531 exaOffscreenFree(pScrn->pScreen, area); 2532 } 2533#endif /* USE_EXA */ 2534#ifdef USE_XAA 2535 if (!info->useEXA) { 2536 FBLinearPtr linear = mem_struct; 2537 2538 if (linear != NULL) 2539 xf86FreeOffscreenLinear(linear); 2540 } 2541#endif /* USE_XAA */ 2542} 2543 2544static void 2545RADEONDisplayVideo( 2546 ScrnInfoPtr pScrn, 2547 xf86CrtcPtr crtc, 2548 RADEONPortPrivPtr pPriv, 2549 int id, 2550 int offset1, int offset2, 2551 int offset3, int offset4, 2552 int offset5, int offset6, 2553 short width, short height, 2554 int pitch, 2555 int left, int right, int top, 2556 BoxPtr dstBox, 2557 short src_w, short src_h, 2558 short drw_w, short drw_h, 2559 int deinterlacing_method 2560){ 2561 RADEONInfoPtr info = RADEONPTR(pScrn); 2562 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2563 unsigned char *RADEONMMIO = info->MMIO; 2564 uint32_t v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp; 2565 double h_inc_d; 2566 int p1_h_accum_init, p23_h_accum_init; 2567 int p1_v_accum_init, p23_v_accum_init; 2568 int p23_blank_lines; 2569 int ecp_div; 2570 int v_inc_shift; 2571 int y_mult; 2572 int x_off; 2573 int y_off; 2574 uint32_t scaler_src; 2575 uint32_t dot_clock; 2576 int is_rgb; 2577 int is_planar; 2578 int i; 2579 uint32_t scale_cntl; 2580 double dsr; 2581 int tap_set; 2582 int predownscale=0; 2583 int src_w_d; 2584 int leftuv = 0; 2585 DisplayModePtr mode; 2586 RADEONOutputPrivatePtr radeon_output; 2587 xf86OutputPtr output; 2588 RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; 2589 2590 is_rgb=0; is_planar=0; 2591 switch(id){ 2592 case FOURCC_I420: 2593 case FOURCC_YV12: 2594 is_planar=1; 2595 break; 2596 case FOURCC_RGBA32: 2597 case FOURCC_RGB24: 2598 case FOURCC_RGBT16: 2599 case FOURCC_RGB16: 2600 is_rgb=1; 2601 break; 2602 default: 2603 break; 2604 } 2605 2606 /* Here we need to find ecp_div again, as the user may have switched resolutions 2607 but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to 2608 workarounds for chip erratas */ 2609 2610 /* Figure out which head we are on for dot clock */ 2611 if (radeon_crtc->crtc_id == 1) 2612 dot_clock = info->ModeReg->dot_clock_freq_2; 2613 else 2614 dot_clock = info->ModeReg->dot_clock_freq; 2615 2616 if (dot_clock < 17500) 2617 ecp_div = 0; 2618 else 2619 ecp_div = 1; 2620 2621 if (ecp_div != info->ecp_div) { 2622 info->ecp_div = ecp_div; 2623 OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, 2624 (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8)); 2625 } 2626 2627 /* I suspect we may need a usleep after writing to the PLL. if you play a video too soon 2628 after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey 2629 on the right edge video output. 2630 Is this still the case? Might have been chips which need the errata, 2631 there is now plenty of usleep after INPLL/OUTPLL for those...*/ 2632 2633 v_inc_shift = 20; 2634 y_mult = 1; 2635 2636 mode = &crtc->mode; 2637 2638 if (mode->Flags & V_INTERLACE) 2639 v_inc_shift++; 2640 if (mode->Flags & V_DBLSCAN) { 2641 v_inc_shift--; 2642 y_mult = 2; 2643 } 2644 2645 v_inc = (src_h << v_inc_shift) / drw_h; 2646 2647 for (i = 0; i < xf86_config->num_output; i++) { 2648 output = xf86_config->output[i]; 2649 if (output->crtc == crtc) { 2650 radeon_output = output->driver_private; 2651 if (radeon_output->Flags & RADEON_USE_RMX) 2652 v_inc = ((src_h * mode->CrtcVDisplay / 2653 radeon_output->PanelYRes) << v_inc_shift) / drw_h; 2654 break; 2655 } 2656 } 2657 2658 h_inc = (1 << (12 + ecp_div)); 2659 2660 step_by_y = 1; 2661 step_by_uv = step_by_y; 2662 2663 src_w_d = src_w; 2664#if 0 2665 /* XXX this does not appear to work */ 2666 /* if the source width was larger than what would fit in overlay scaler increase step_by values */ 2667 i=src_w; 2668 while(i>info->overlay_scaler_buffer_width){ 2669 step_by_y++; 2670 step_by_uv++; 2671 h_inc >>=1; 2672 i=i/2; 2673 } 2674#else 2675 /* predownscale instead (yes this hurts quality) - will only work for widths up 2676 to 2 times the overlay_scaler_buffer_width, should be enough */ 2677 if (src_w_d > info->overlay_scaler_buffer_width) { 2678 src_w_d /= 2; /* odd widths? */ 2679 predownscale = 1; 2680 } 2681#endif 2682 2683 h_inc_d = src_w_d; 2684 h_inc_d = h_inc_d/drw_w; 2685 /* we could do a tad better - but why 2686 bother when this concerns downscaling and the code is so much more 2687 hairy */ 2688 while(h_inc*h_inc_d >= (2 << 12)) { 2689 if(!is_rgb && (((h_inc+h_inc/2)*h_inc_d)<(2<<12))){ 2690 step_by_uv = step_by_y+1; 2691 break; 2692 } 2693 step_by_y++; 2694 step_by_uv = step_by_y; 2695 h_inc >>= 1; 2696 } 2697 2698 h_inc_uv = h_inc>>(step_by_uv-step_by_y); 2699 h_inc = h_inc * h_inc_d; 2700 h_inc_uv = h_inc_uv * h_inc_d; 2701 /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit 2702 in the buffer for 2 tap filtering */ 2703 /* the only place it is documented in is in ATI source code */ 2704 /* we need twice as much space for 4 tap filtering.. */ 2705 /* under special circumstances turn on 4 tap filtering */ 2706 /* disable this code for now as it has a DISASTROUS effect on image quality when upscaling 2707 at least on rv250 (only as long as the drw_w*2 <=... requirement is still met of course) */ 2708#if 0 2709 if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12)) 2710 && (deinterlacing_method!=METHOD_WEAVE) 2711 && (drw_w*2 <= info->overlay_scaler_buffer_width)){ 2712 step_by_y=0; 2713 step_by_uv=1; 2714 h_inc_uv = h_inc; 2715 } 2716#endif 2717 2718 /* keep everything in 16.16 */ 2719 2720 if (is_planar) { 2721 offset1 += ((left >> 16) & ~15); 2722 offset2 += ((left >> 16) & ~31) >> 1; 2723 offset3 += ((left >> 16) & ~31) >> 1; 2724 offset4 += ((left >> 16) & ~15); 2725 offset5 += ((left >> 16) & ~31) >> 1; 2726 offset6 += ((left >> 16) & ~31) >> 1; 2727 offset2 |= RADEON_VIF_BUF0_PITCH_SEL; 2728 offset3 |= RADEON_VIF_BUF0_PITCH_SEL; 2729 offset5 |= RADEON_VIF_BUF0_PITCH_SEL; 2730 offset6 |= RADEON_VIF_BUF0_PITCH_SEL; 2731 } 2732 else { 2733 /* is this really correct for non-2-byte formats? */ 2734 offset1 += ((left >> 16) & ~7) << 1; 2735 offset2 += ((left >> 16) & ~7) << 1; 2736 offset3 += ((left >> 16) & ~7) << 1; 2737 offset4 += ((left >> 16) & ~7) << 1; 2738 offset5 += ((left >> 16) & ~7) << 1; 2739 offset6 += ((left >> 16) & ~7) << 1; 2740 } 2741 2742 tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); 2743 p1_h_accum_init = ((tmp << 4) & 0x000f8000) | 2744 ((tmp << 12) & 0xf0000000); 2745 2746 tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc_uv << 2); 2747 p23_h_accum_init = ((tmp << 4) & 0x000f8000) | 2748 ((tmp << 12) & 0x70000000); 2749 2750 tmp = (top & 0x0000ffff) + 0x00018000; 2751 p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 2752 (((deinterlacing_method!=METHOD_WEAVE)&&!is_rgb)?0x03:0x01); 2753 2754 if (is_planar) { 2755 p23_v_accum_init = ((tmp << 4) & 0x03ff8000) | 2756 ((deinterlacing_method != METHOD_WEAVE) ? 0x03 : 0x01); 2757 p23_blank_lines = (((src_h >> 1) - 1) << 16); 2758 } 2759 else { 2760 p23_v_accum_init = 0; 2761 p23_blank_lines = 0; 2762 } 2763 2764 if (is_planar) { 2765 leftuv = ((left >> 16) >> 1) & 15; 2766 left = (left >> 16) & 15; 2767 } 2768 else { 2769 left = (left >> 16) & 7; 2770 if (!is_rgb) 2771 leftuv = left >> 1; 2772 } 2773 2774 RADEONWaitForFifo(pScrn, 2); 2775 OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK); 2776 if (info->accelOn) RADEON_SYNC(info, pScrn); 2777 while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK)); 2778 2779 RADEONWaitForFifo(pScrn, 10); 2780 OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16)); 2781 OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) | 2782 predownscale << 4 | predownscale << 12); 2783 2784 x_off = 8; 2785 y_off = 0; 2786 2787 if (IS_R300_VARIANT || 2788 (info->ChipFamily == CHIP_FAMILY_R200)) 2789 x_off = 0; 2790 2791 /* needed to make the overlay work on crtc1 in leftof and above modes */ 2792 /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */ 2793 /* 2794 if (srel == radeonLeftOf) { 2795 x_off -= mode->CrtcHDisplay; 2796 } 2797 if (srel == radeonAbove) { 2798 y_off -= mode->CrtcVDisplay; 2799 } 2800 */ 2801 2802 /* Put the hardware overlay on CRTC2: 2803 * 2804 * Since one hardware overlay can not be displayed on two heads 2805 * at the same time, we might need to consider using software 2806 * rendering for the second head. 2807 */ 2808 2809 if (radeon_crtc->crtc_id == 1) { 2810 x_off = 0; 2811 OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) | 2812 ((dstBox->y1*y_mult) << 16))); 2813 OUTREG(RADEON_OV1_Y_X_END, ((dstBox->x2 + x_off) | 2814 ((dstBox->y2*y_mult) << 16))); 2815 scaler_src = RADEON_SCALER_CRTC_SEL; 2816 } else { 2817 OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) | 2818 (((dstBox->y1*y_mult) + y_off) << 16))); 2819 OUTREG(RADEON_OV0_Y_X_END, ((dstBox->x2 + x_off) | 2820 (((dstBox->y2*y_mult) + y_off) << 16))); 2821 scaler_src = 0; 2822 } 2823 2824 /* program the tap coefficients for better downscaling quality. 2825 Could do slightly better by using hardcoded coefficients for one axis 2826 in case only the other axis is downscaled (see RADEON_OV0_FILTER_CNTL) */ 2827 dsr=(double)(1<<0xC)/h_inc; 2828 if(dsr<0.25)dsr=0.25; 2829 if(dsr>1.0)dsr=1.0; 2830 tap_set=(int)((dsr-0.25)*100); 2831 for(i=0;i<5;i++){ 2832 OUTREG(RADEON_OV0_FOUR_TAP_COEF_0+i*4, (TapCoeffs[tap_set].coeff[i][0] &0xf) | 2833 ((TapCoeffs[tap_set].coeff[i][1] &0x7f)<<8) | 2834 ((TapCoeffs[tap_set].coeff[i][2] &0x7f)<<16) | 2835 ((TapCoeffs[tap_set].coeff[i][3] &0xf)<<24)); 2836 } 2837 2838 RADEONWaitForFifo(pScrn, 11); 2839 OUTREG(RADEON_OV0_V_INC, v_inc); 2840 OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16)); 2841 OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | p23_blank_lines); 2842 OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch); 2843 OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch); 2844 OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16)); 2845 if (!is_rgb) 2846 src_w >>= 1; 2847 OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16)); 2848 OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16)); 2849 OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1); 2850 OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2); 2851 OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3); 2852 2853 RADEONWaitForFifo(pScrn, 9); 2854 OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS, offset4); 2855 OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS, offset5); 2856 OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS, offset6); 2857 OUTREG(RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init); 2858 OUTREG(RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init); 2859 OUTREG(RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init); 2860 OUTREG(RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init); 2861 2862 scale_cntl = RADEON_SCALER_ADAPTIVE_DEINT | RADEON_SCALER_DOUBLE_BUFFER 2863 | RADEON_SCALER_ENABLE | RADEON_SCALER_SMART_SWITCH | (0x7f<<16) | scaler_src; 2864 switch(id){ 2865 case FOURCC_UYVY: 2866 scale_cntl |= RADEON_SCALER_SOURCE_YVYU422; 2867 break; 2868 case FOURCC_RGB24: 2869 case FOURCC_RGBA32: 2870 scale_cntl |= RADEON_SCALER_SOURCE_32BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2871 break; 2872 case FOURCC_RGB16: 2873 scale_cntl |= RADEON_SCALER_SOURCE_16BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2874 break; 2875 case FOURCC_RGBT16: 2876 scale_cntl |= RADEON_SCALER_SOURCE_15BPP | RADEON_SCALER_LIN_TRANS_BYPASS; 2877 break; 2878 case FOURCC_YV12: 2879 case FOURCC_I420: 2880 scale_cntl |= RADEON_SCALER_SOURCE_YUV12; 2881 break; 2882 case FOURCC_YUY2: 2883 default: 2884 scale_cntl |= RADEON_SCALER_SOURCE_VYUY422 2885 | ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0); 2886 break; 2887 } 2888 2889 if (info->ChipFamily < CHIP_FAMILY_R200) { 2890 scale_cntl &= ~RADEON_SCALER_GAMMA_SEL_MASK; 2891 scale_cntl |= ((RADEONTranslateUserGamma(pPriv->gamma)) << 5); 2892 } 2893 2894 OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl); 2895 OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0); 2896} 2897 2898 2899static void 2900RADEONFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes) 2901{ 2902#if HAVE_XV_DRAWABLE_HELPER 2903 xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes); 2904#else 2905 xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes); 2906#endif 2907} 2908 2909 2910static int 2911RADEONPutImage( 2912 ScrnInfoPtr pScrn, 2913 short src_x, short src_y, 2914 short drw_x, short drw_y, 2915 short src_w, short src_h, 2916 short drw_w, short drw_h, 2917 int id, unsigned char* buf, 2918 short width, short height, 2919 Bool Sync, 2920 RegionPtr clipBoxes, pointer data, 2921 DrawablePtr pDraw 2922){ 2923 RADEONInfoPtr info = RADEONPTR(pScrn); 2924 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 2925 INT32 xa, xb, ya, yb; 2926 unsigned char *dst_start; 2927 int new_size, offset, s2offset, s3offset; 2928 int srcPitch, srcPitch2, dstPitch; 2929 int d2line, d3line; 2930 int top, left, npixels, nlines, bpp; 2931 int idconv = id; 2932 BoxRec dstBox; 2933 uint32_t tmp; 2934 xf86CrtcPtr crtc; 2935 2936 /* 2937 * s2offset, s3offset - byte offsets into U and V plane of the 2938 * source where copying starts. Y plane is 2939 * done by editing "buf". 2940 * 2941 * offset - byte offset to the first line of the destination. 2942 * 2943 * dst_start - byte address to the first displayed pel. 2944 * 2945 */ 2946 2947 /* make the compiler happy */ 2948 s2offset = s3offset = srcPitch2 = 0; 2949 d2line = d3line = 0; 2950 2951 if(src_w > (drw_w << 4)) 2952 drw_w = src_w >> 4; 2953 if(src_h > (drw_h << 4)) 2954 drw_h = src_h >> 4; 2955 2956 /* Clip */ 2957 xa = src_x; 2958 xb = src_x + src_w; 2959 ya = src_y; 2960 yb = src_y + src_h; 2961 2962 dstBox.x1 = drw_x; 2963 dstBox.x2 = drw_x + drw_w; 2964 dstBox.y1 = drw_y; 2965 dstBox.y2 = drw_y + drw_h; 2966 2967 if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc, 2968 &dstBox, &xa, &xb, &ya, &yb, 2969 clipBoxes, width, height)) 2970 return Success; 2971 2972 if (!crtc) { 2973 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 2974 unsigned char *RADEONMMIO = info->MMIO; 2975 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 2976 pPriv->videoStatus &= ~CLIENT_VIDEO_ON; 2977 } 2978 return Success; 2979 } 2980 2981 dstBox.x1 -= crtc->x; 2982 dstBox.x2 -= crtc->x; 2983 dstBox.y1 -= crtc->y; 2984 dstBox.y2 -= crtc->y; 2985 2986 bpp = pScrn->bitsPerPixel >> 3; 2987 2988 switch(id) { 2989 case FOURCC_RGB24: 2990 dstPitch = width * 4; 2991 srcPitch = width * 3; 2992 break; 2993 case FOURCC_RGBA32: 2994 dstPitch = width * 4; 2995 srcPitch = width * 4; 2996 break; 2997 case FOURCC_RGB16: 2998 case FOURCC_RGBT16: 2999 dstPitch = width * 2; 3000 srcPitch = (width * 2 + 3) & ~3; 3001 break; 3002 case FOURCC_YV12: 3003 case FOURCC_I420: 3004 /* it seems rs4xx chips (all of them???) either can't handle planar 3005 yuv at all or would need some unknown different setup. */ 3006 if ((info->ChipFamily != CHIP_FAMILY_RS400) && 3007 (info->ChipFamily != CHIP_FAMILY_RS480)) { 3008 /* need 16bytes alignment for u,v plane, so 2 times that for width 3009 but blitter needs 64bytes alignment. 128byte is a waste but dstpitch 3010 for uv planes needs to be dstpitch yplane >> 1 for now. */ 3011 dstPitch = ((width + 127) & ~127); 3012 srcPitch = (width + 3) & ~3; 3013 } 3014 else { 3015 dstPitch = width * 2; 3016 srcPitch = (width + 3) & ~3; 3017 idconv = FOURCC_YUY2; 3018 } 3019 break; 3020 case FOURCC_UYVY: 3021 case FOURCC_YUY2: 3022 default: 3023 dstPitch = width * 2; 3024 srcPitch = width * 2; 3025 break; 3026 } 3027 3028#ifdef XF86DRI 3029 if (info->directRenderingEnabled && info->DMAForXv) { 3030 /* The upload blit only supports multiples of 64 bytes */ 3031 dstPitch = (dstPitch + 63) & ~63; 3032 } else 3033#endif 3034 /* The overlay only supports multiples of 16 bytes */ 3035 dstPitch = (dstPitch + 15) & ~15; 3036 3037 new_size = dstPitch * height; 3038 if (idconv == FOURCC_YV12 || id == FOURCC_I420) { 3039 new_size += (dstPitch >> 1) * ((height + 1) & ~1); 3040 } 3041 pPriv->video_offset = RADEONAllocateMemory(pScrn, &pPriv->video_memory, 3042 (pPriv->doubleBuffer ? 3043 (new_size * 2) : new_size)); 3044 if (pPriv->video_offset == 0) 3045 return BadAlloc; 3046 3047 pPriv->currentBuffer ^= 1; 3048 3049 /* copy data */ 3050 top = ya >> 16; 3051 left = (xa >> 16) & ~1; 3052 npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left; 3053 3054 offset = (pPriv->video_offset) + (top * dstPitch); 3055 3056 if(pPriv->doubleBuffer) { 3057 unsigned char *RADEONMMIO = info->MMIO; 3058 3059 /* Wait for last flip to take effect */ 3060 while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK)); 3061 3062 offset += pPriv->currentBuffer * new_size; 3063 } 3064 3065 dst_start = info->FB + offset; 3066 3067 switch(id) { 3068 case FOURCC_YV12: 3069 case FOURCC_I420: 3070 if (id == idconv) { 3071 /* meh. Such a mess just for someone who wants to watch half the video clipped */ 3072 top &= ~1; 3073 /* odd number of pixels? That may not work correctly */ 3074 srcPitch2 = ((width >> 1) + 3) & ~3; 3075 /* odd number of lines? Maybe... */ 3076 s2offset = srcPitch * ((height + 1) & ~1); 3077 s3offset = s2offset + srcPitch2 * ((height + 1) >> 1); 3078 s2offset += (top >> 1) * srcPitch2 + (left >> 1); 3079 s3offset += (top >> 1) * srcPitch2 + (left >> 1); 3080 d2line = (height * dstPitch); 3081 d3line = d2line + ((height + 1) >> 1) * (dstPitch >> 1); 3082 nlines = ((yb + 0xffff) >> 16) - top; 3083 d2line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch); 3084 d3line += (top >> 1) * (dstPitch >> 1) - (top * dstPitch); 3085 if(id == FOURCC_YV12) { 3086 tmp = s2offset; 3087 s2offset = s3offset; 3088 s3offset = tmp; 3089 } 3090 RADEONCopyData(pScrn, buf + (top * srcPitch) + left, dst_start + left, 3091 srcPitch, dstPitch, nlines, npixels, 1); 3092 RADEONCopyData(pScrn, buf + s2offset, dst_start + d2line + (left >> 1), 3093 srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1); 3094 RADEONCopyData(pScrn, buf + s3offset, dst_start + d3line + (left >> 1), 3095 srcPitch2, dstPitch >> 1, (nlines + 1) >> 1, npixels >> 1, 1); 3096 } 3097 else { 3098 s2offset = srcPitch * height; 3099 srcPitch2 = ((width >> 1) + 3) & ~3; 3100 s3offset = (srcPitch2 * (height >> 1)) + s2offset; 3101 top &= ~1; 3102 dst_start += left << 1; 3103 tmp = ((top >> 1) * srcPitch2) + (left >> 1); 3104 s2offset += tmp; 3105 s3offset += tmp; 3106 if(id == FOURCC_I420) { 3107 tmp = s2offset; 3108 s2offset = s3offset; 3109 s3offset = tmp; 3110 } 3111 nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top; 3112 RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left, 3113 buf + s2offset, buf + s3offset, dst_start, 3114 srcPitch, srcPitch2, dstPitch, nlines, npixels); 3115 } 3116 break; 3117 case FOURCC_RGBT16: 3118 case FOURCC_RGB16: 3119 case FOURCC_UYVY: 3120 case FOURCC_YUY2: 3121 default: 3122 left <<= 1; 3123 buf += (top * srcPitch) + left; 3124 nlines = ((yb + 0xffff) >> 16) - top; 3125 dst_start += left; 3126 RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2); 3127 break; 3128 case FOURCC_RGBA32: 3129 buf += (top * srcPitch) + left*4; 3130 nlines = ((yb + 0xffff) >> 16) - top; 3131 dst_start += left*4; 3132 RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4); 3133 break; 3134 case FOURCC_RGB24: 3135 buf += (top * srcPitch) + left*3; 3136 nlines = ((yb + 0xffff) >> 16) - top; 3137 dst_start += left*4; 3138 RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels); 3139 break; 3140 } 3141 3142 /* update cliplist */ 3143 if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) 3144 { 3145 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 3146 /* draw these */ 3147 if(pPriv->autopaint_colorkey) 3148 RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 3149 } 3150 3151 /* FIXME: someone should look at these offsets, I don't think it makes sense how 3152 they are handled throughout the source. */ 3153 RADEONDisplayVideo(pScrn, crtc, pPriv, idconv, offset, offset + d2line, offset + d3line, 3154 offset, offset + d2line, offset + d3line, width, height, dstPitch, 3155 xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB); 3156 3157 pPriv->videoStatus = CLIENT_VIDEO_ON; 3158 3159 info->VideoTimerCallback = RADEONVideoTimerCallback; 3160 3161 return Success; 3162} 3163 3164 3165int 3166RADEONQueryImageAttributes( 3167 ScrnInfoPtr pScrn, 3168 int id, 3169 unsigned short *w, unsigned short *h, 3170 int *pitches, int *offsets 3171){ 3172 int size, tmp; 3173 3174 if(*w > 2048) *w = 2048; 3175 if(*h > 2048) *h = 2048; 3176 3177 *w = (*w + 1) & ~1; 3178 if(offsets) offsets[0] = 0; 3179 3180 switch(id) { 3181 case FOURCC_YV12: 3182 case FOURCC_I420: 3183 *h = (*h + 1) & ~1; 3184 size = (*w + 3) & ~3; 3185 if(pitches) pitches[0] = size; 3186 size *= *h; 3187 if(offsets) offsets[1] = size; 3188 tmp = ((*w >> 1) + 3) & ~3; 3189 if(pitches) pitches[1] = pitches[2] = tmp; 3190 tmp *= (*h >> 1); 3191 size += tmp; 3192 if(offsets) offsets[2] = size; 3193 size += tmp; 3194 break; 3195 case FOURCC_RGBA32: 3196 size = *w << 2; 3197 if(pitches) pitches[0] = size; 3198 size *= *h; 3199 break; 3200 case FOURCC_RGB24: 3201 size = *w * 3; 3202 if(pitches) pitches[0] = size; 3203 size *= *h; 3204 break; 3205 case FOURCC_RGBT16: 3206 case FOURCC_RGB16: 3207 case FOURCC_UYVY: 3208 case FOURCC_YUY2: 3209 default: 3210 size = *w << 1; 3211 if(pitches) pitches[0] = size; 3212 size *= *h; 3213 break; 3214 } 3215 3216 return size; 3217} 3218 3219static void 3220RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now) 3221{ 3222 RADEONInfoPtr info = RADEONPTR(pScrn); 3223 RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; 3224 3225 if(pPriv->videoStatus & TIMER_MASK) { 3226 if(pPriv->videoStatus & OFF_TIMER) { 3227 if(pPriv->offTime < now) { 3228 unsigned char *RADEONMMIO = info->MMIO; 3229 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3230 pPriv->videoStatus = FREE_TIMER; 3231 pPriv->freeTime = now + FREE_DELAY; 3232 } 3233 } else { /* FREE_TIMER */ 3234 if(pPriv->freeTime < now) { 3235 if (pPriv->video_memory != NULL) { 3236 RADEONFreeMemory(pScrn, pPriv->video_memory); 3237 pPriv->video_memory = NULL; 3238 } 3239 pPriv->videoStatus = 0; 3240 info->VideoTimerCallback = NULL; 3241 } 3242 } 3243 } else /* shouldn't get here */ 3244 info->VideoTimerCallback = NULL; 3245} 3246 3247/****************** Offscreen stuff ***************/ 3248typedef struct { 3249 void *surface_memory; 3250 Bool isOn; 3251} OffscreenPrivRec, * OffscreenPrivPtr; 3252 3253static int 3254RADEONAllocateSurface( 3255 ScrnInfoPtr pScrn, 3256 int id, 3257 unsigned short w, 3258 unsigned short h, 3259 XF86SurfacePtr surface 3260){ 3261 int offset, pitch, size; 3262 OffscreenPrivPtr pPriv; 3263 void *surface_memory = NULL; 3264 if((w > 1024) || (h > 1024)) 3265 return BadAlloc; 3266 3267 w = (w + 1) & ~1; 3268 pitch = ((w << 1) + 15) & ~15; 3269 size = pitch * h; 3270 3271 offset = RADEONAllocateMemory(pScrn, &surface_memory, size); 3272 if (offset == 0) 3273 return BadAlloc; 3274 3275 surface->width = w; 3276 surface->height = h; 3277 3278 if(!(surface->pitches = xalloc(sizeof(int)))) { 3279 RADEONFreeMemory(pScrn, surface_memory); 3280 return BadAlloc; 3281 } 3282 if(!(surface->offsets = xalloc(sizeof(int)))) { 3283 xfree(surface->pitches); 3284 RADEONFreeMemory(pScrn, surface_memory); 3285 return BadAlloc; 3286 } 3287 if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { 3288 xfree(surface->pitches); 3289 xfree(surface->offsets); 3290 RADEONFreeMemory(pScrn, surface_memory); 3291 return BadAlloc; 3292 } 3293 3294 pPriv->surface_memory = surface_memory; 3295 pPriv->isOn = FALSE; 3296 3297 surface->pScrn = pScrn; 3298 surface->id = id; 3299 surface->pitches[0] = pitch; 3300 surface->offsets[0] = offset; 3301 surface->devPrivate.ptr = (pointer)pPriv; 3302 3303 return Success; 3304} 3305 3306static int 3307RADEONStopSurface( 3308 XF86SurfacePtr surface 3309){ 3310 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3311 RADEONInfoPtr info = RADEONPTR(surface->pScrn); 3312 unsigned char *RADEONMMIO = info->MMIO; 3313 3314 if(pPriv->isOn) { 3315 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3316 pPriv->isOn = FALSE; 3317 } 3318 return Success; 3319} 3320 3321 3322static int 3323RADEONFreeSurface( 3324 XF86SurfacePtr surface 3325){ 3326 ScrnInfoPtr pScrn = surface->pScrn; 3327 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3328 3329 if(pPriv->isOn) 3330 RADEONStopSurface(surface); 3331 RADEONFreeMemory(pScrn, pPriv->surface_memory); 3332 xfree(surface->pitches); 3333 xfree(surface->offsets); 3334 xfree(surface->devPrivate.ptr); 3335 3336 return Success; 3337} 3338 3339static int 3340RADEONGetSurfaceAttribute( 3341 ScrnInfoPtr pScrn, 3342 Atom attribute, 3343 INT32 *value 3344){ 3345 return RADEONGetPortAttribute(pScrn, attribute, value, 3346 (pointer)(GET_PORT_PRIVATE(pScrn))); 3347} 3348 3349static int 3350RADEONSetSurfaceAttribute( 3351 ScrnInfoPtr pScrn, 3352 Atom attribute, 3353 INT32 value 3354){ 3355 return RADEONSetPortAttribute(pScrn, attribute, value, 3356 (pointer)(GET_PORT_PRIVATE(pScrn))); 3357} 3358 3359 3360static int 3361RADEONDisplaySurface( 3362 XF86SurfacePtr surface, 3363 short src_x, short src_y, 3364 short drw_x, short drw_y, 3365 short src_w, short src_h, 3366 short drw_w, short drw_h, 3367 RegionPtr clipBoxes 3368){ 3369 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 3370 ScrnInfoPtr pScrn = surface->pScrn; 3371 RADEONInfoPtr info = RADEONPTR(pScrn); 3372 RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr; 3373 3374 INT32 xa, ya, xb, yb; 3375 BoxRec dstBox; 3376 xf86CrtcPtr crtc; 3377 3378 if (src_w > (drw_w << 4)) 3379 drw_w = src_w >> 4; 3380 if (src_h > (drw_h << 4)) 3381 drw_h = src_h >> 4; 3382 3383 xa = src_x; 3384 xb = src_x + src_w; 3385 ya = src_y; 3386 yb = src_y + src_h; 3387 3388 dstBox.x1 = drw_x; 3389 dstBox.x2 = drw_x + drw_w; 3390 dstBox.y1 = drw_y; 3391 dstBox.y2 = drw_y + drw_h; 3392 3393 if (!radeon_crtc_clip_video(pScrn, &crtc, portPriv->desired_crtc, 3394 &dstBox, &xa, &xb, &ya, &yb, clipBoxes, 3395 surface->width, surface->height)) 3396 return Success; 3397 3398 if (!crtc) { 3399 if (pPriv->isOn) { 3400 unsigned char *RADEONMMIO = info->MMIO; 3401 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3402 pPriv->isOn = FALSE; 3403 } 3404 return Success; 3405 } 3406 3407 dstBox.x1 -= crtc->x; 3408 dstBox.x2 -= crtc->x; 3409 dstBox.y1 -= crtc->y; 3410 dstBox.y2 -= crtc->y; 3411 3412#if 0 3413 /* this isn't needed */ 3414 RADEONResetVideo(pScrn); 3415#endif 3416 RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id, 3417 surface->offsets[0], surface->offsets[0], 3418 surface->offsets[0], surface->offsets[0], 3419 surface->offsets[0], surface->offsets[0], 3420 surface->width, surface->height, surface->pitches[0], 3421 xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB); 3422 3423 if (portPriv->autopaint_colorkey) 3424 xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 3425 3426 pPriv->isOn = TRUE; 3427 /* we've prempted the XvImage stream so set its free timer */ 3428 if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 3429 REGION_EMPTY(pScrn->pScreen, &portPriv->clip); 3430 UpdateCurrentTime(); 3431 portPriv->videoStatus = FREE_TIMER; 3432 portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 3433 info->VideoTimerCallback = RADEONVideoTimerCallback; 3434 } 3435 3436 return Success; 3437} 3438 3439 3440static void 3441RADEONInitOffscreenImages(ScreenPtr pScreen) 3442{ 3443/* ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 3444 RADEONInfoPtr info = RADEONPTR(pScrn); */ 3445 XF86OffscreenImagePtr offscreenImages; 3446 /* need to free this someplace */ 3447 3448 if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) 3449 return; 3450 3451 offscreenImages[0].image = &Images[0]; 3452 offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*| 3453 VIDEO_CLIP_TO_VIEWPORT*/; 3454 offscreenImages[0].alloc_surface = RADEONAllocateSurface; 3455 offscreenImages[0].free_surface = RADEONFreeSurface; 3456 offscreenImages[0].display = RADEONDisplaySurface; 3457 offscreenImages[0].stop = RADEONStopSurface; 3458 offscreenImages[0].setAttribute = RADEONSetSurfaceAttribute; 3459 offscreenImages[0].getAttribute = RADEONGetSurfaceAttribute; 3460 offscreenImages[0].max_width = 2048; 3461 offscreenImages[0].max_height = 2048; 3462 offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 3463 offscreenImages[0].attributes = Attributes; 3464 3465 xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 3466} 3467 3468 /* TV-in functions */ 3469 3470static int 3471RADEONPutVideo( 3472 ScrnInfoPtr pScrn, 3473 short src_x, short src_y, 3474 short drw_x, short drw_y, 3475 short src_w, short src_h, 3476 short drw_w, short drw_h, 3477 RegionPtr clipBoxes, pointer data, 3478 DrawablePtr pDraw 3479){ 3480 RADEONInfoPtr info = RADEONPTR(pScrn); 3481 RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; 3482 unsigned char *RADEONMMIO = info->MMIO; 3483 INT32 xa, xb, ya, yb, top; 3484 unsigned int pitch, new_size, alloc_size; 3485 unsigned int offset1, offset2, offset3, offset4, s2offset, s3offset; 3486 unsigned int vbi_offset0, vbi_offset1; 3487 int srcPitch, srcPitch2, dstPitch; 3488 int bpp; 3489 BoxRec dstBox; 3490 uint32_t id, display_base; 3491 int width, height; 3492 int mult; 3493 int vbi_line_width, vbi_start, vbi_end; 3494 xf86CrtcPtr crtc; 3495 3496 RADEON_SYNC(info, pScrn); 3497 /* 3498 * s2offset, s3offset - byte offsets into U and V plane of the 3499 * source where copying starts. Y plane is 3500 * done by editing "buf". 3501 * 3502 * offset - byte offset to the first line of the destination. 3503 * 3504 * dst_start - byte address to the first displayed pel. 3505 * 3506 */ 3507 3508 /* make the compiler happy */ 3509 s2offset = s3offset = srcPitch2 = 0; 3510 3511 if(src_w > (drw_w << 4)) 3512 drw_w = src_w >> 4; 3513 if(src_h > (drw_h << 4)) 3514 drw_h = src_h >> 4; 3515 3516 /* Clip */ 3517 xa = src_x; 3518 xb = src_x + src_w; 3519 ya = src_y; 3520 yb = src_y + src_h; 3521 3522 dstBox.x1 = drw_x; 3523 dstBox.x2 = drw_x + drw_w; 3524 dstBox.y1 = drw_y; 3525 dstBox.y2 = drw_y + drw_h; 3526 3527 width = InputVideoEncodings[pPriv->encoding].width; 3528 height = InputVideoEncodings[pPriv->encoding].height; 3529 3530 vbi_line_width = 798*2; 3531 if(width<=640) 3532 vbi_line_width = 0x640; /* 1600 actually */ 3533 else 3534 vbi_line_width = 2000; /* might need adjustment */ 3535 3536 if (!radeon_crtc_clip_video(pScrn, &crtc, pPriv->desired_crtc, 3537 &dstBox, &xa, &xb, &ya, &yb, 3538 clipBoxes, width, height)) 3539 return Success; 3540 3541 if (!crtc) { 3542 if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 3543 unsigned char *RADEONMMIO = info->MMIO; 3544 OUTREG(RADEON_OV0_SCALE_CNTL, 0); 3545 pPriv->videoStatus &= ~CLIENT_VIDEO_ON; 3546 } 3547 return Success; 3548 } 3549 3550 dstBox.x1 -= crtc->x; 3551 dstBox.x2 -= crtc->x; 3552 dstBox.y1 -= crtc->y; 3553 dstBox.y2 -= crtc->y; 3554 3555 bpp = pScrn->bitsPerPixel >> 3; 3556 pitch = bpp * pScrn->displayWidth; 3557 3558 switch(pPriv->overlay_deinterlacing_method){ 3559 case METHOD_BOB: 3560 case METHOD_SINGLE: 3561 mult=2; 3562 break; 3563 case METHOD_WEAVE: 3564 case METHOD_ADAPTIVE: 3565 mult=4; 3566 break; 3567 default: 3568 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Internal error: PutVideo\n"); 3569 mult=4; 3570 } 3571 3572 id = FOURCC_YUY2; 3573 3574 top = ya>>16; 3575#if 0 3576 /* setting the ID above makes this useful - needs revisiting */ 3577 switch(id) { 3578 case FOURCC_YV12: 3579 case FOURCC_I420: 3580 top &= ~1; 3581 dstPitch = ((width << 1) + 15) & ~15; 3582 srcPitch = (width + 3) & ~3; 3583 s2offset = srcPitch * height; 3584 srcPitch2 = ((width >> 1) + 3) & ~3; 3585 s3offset = (srcPitch2 * (height >> 1)) + s2offset; 3586 break; 3587 case FOURCC_UYVY: 3588 case FOURCC_YUY2: 3589 default: 3590 dstPitch = ((width<<1) + 15) & ~15; 3591 srcPitch = (width<<1); 3592 break; 3593 } 3594#else 3595 dstPitch = ((width<<1) + 15) & ~15; 3596 srcPitch = (width<<1); 3597#endif 3598 3599 new_size = dstPitch * height; 3600 new_size = new_size + 0x1f; /* for aligning */ 3601 alloc_size = new_size * mult; 3602 if (pPriv->capture_vbi_data) 3603 alloc_size += 2 * 2 * vbi_line_width * 21; 3604 3605 pPriv->video_offset = RADEONAllocateMemory(pScrn, &pPriv->video_memory, 3606 (pPriv->doubleBuffer ? 3607 (new_size * 2) : new_size)); 3608 if (pPriv->video_offset == 0) 3609 return BadAlloc; 3610 3611/* I have suspicion that capture engine must be active _before_ Rage Theatre 3612 is being manipulated with.. */ 3613 3614 RADEONWaitForIdleMMIO(pScrn); 3615 display_base=INREG(RADEON_DISPLAY_BASE_ADDR); 3616 3617/* RADEONWaitForFifo(pScrn, 15); */ 3618 3619 switch(pPriv->overlay_deinterlacing_method){ 3620 case METHOD_BOB: 3621 case METHOD_SINGLE: 3622 offset1 = (pPriv->video_offset + 0xf) & (~0xf); 3623 offset2 = (pPriv->video_offset + new_size + 0xf) & (~0xf); 3624 offset3 = offset1; 3625 offset4 = offset2; 3626 break; 3627 case METHOD_WEAVE: 3628 offset1 = (pPriv->video_offset + 0xf) & (~0xf); 3629 offset2 = offset1+dstPitch; 3630 offset3 = (pPriv->video_offset + 2 * new_size + 0xf) & (~0xf); 3631 offset4 = offset3+dstPitch; 3632 break; 3633 default: 3634 offset1 = (pPriv->video_offset + 0xf) & (~0xf); 3635 offset2 = (pPriv->video_offset + new_size + 0xf) & (~0xf); 3636 offset3 = offset1; 3637 offset4 = offset2; 3638 } 3639 3640 OUTREG(RADEON_CAP0_BUF0_OFFSET, offset1+display_base); 3641 OUTREG(RADEON_CAP0_BUF0_EVEN_OFFSET, offset2+display_base); 3642 OUTREG(RADEON_CAP0_BUF1_OFFSET, offset3+display_base); 3643 OUTREG(RADEON_CAP0_BUF1_EVEN_OFFSET, offset4+display_base); 3644 3645 OUTREG(RADEON_CAP0_ONESHOT_BUF_OFFSET, offset1+display_base); 3646 3647 if(pPriv->capture_vbi_data){ 3648 if ((pPriv->encoding==2)||(pPriv->encoding==8)) { 3649 /* PAL, SECAM */ 3650 vbi_start = 5; 3651 vbi_end = 21; 3652 } else { 3653 /* NTSC */ 3654 vbi_start = 8; 3655 vbi_end = 20; 3656 } 3657 3658 vbi_offset0 = (pPriv->video_offset + mult * new_size * bpp + 0xf) & (~0xf); 3659 vbi_offset1 = vbi_offset0 + dstPitch*20; 3660 OUTREG(RADEON_CAP0_VBI0_OFFSET, vbi_offset0+display_base); 3661 OUTREG(RADEON_CAP0_VBI1_OFFSET, vbi_offset1+display_base); 3662 OUTREG(RADEON_CAP0_VBI2_OFFSET, 0); 3663 OUTREG(RADEON_CAP0_VBI3_OFFSET, 0); 3664 OUTREG(RADEON_CAP0_VBI_V_WINDOW, vbi_start | (vbi_end<<16)); 3665 OUTREG(RADEON_CAP0_VBI_H_WINDOW, 0 | (vbi_line_width)<<16); 3666 } 3667 3668 OUTREG(RADEON_CAP0_BUF_PITCH, dstPitch*mult/2); 3669 OUTREG(RADEON_CAP0_H_WINDOW, (2*width)<<16); 3670 OUTREG(RADEON_CAP0_V_WINDOW, (((height)+pPriv->v-1)<<16)|(pPriv->v-1)); 3671 if(mult==2){ 3672 OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_BOB); 3673 } else { 3674 OUTREG(RADEON_CAP0_CONFIG, ENABLE_RADEON_CAPTURE_WEAVE); 3675 } 3676 OUTREG(RADEON_CAP0_DEBUG, 0); 3677 3678 OUTREG(RADEON_VID_BUFFER_CONTROL, (1<<16) | 0x01); 3679 OUTREG(RADEON_TEST_DEBUG_CNTL, 0); 3680 3681 if(! pPriv->video_stream_active) 3682 { 3683 3684 RADEONWaitForIdleMMIO(pScrn); 3685 OUTREG(RADEON_VIDEOMUX_CNTL, INREG(RADEON_VIDEOMUX_CNTL)|1 ); 3686 OUTREG(RADEON_CAP0_PORT_MODE_CNTL, (pPriv->theatre!=NULL)? 1: 0); 3687 OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_PCLK); 3688 OUTREG(RADEON_CAP0_TRIG_CNTL, 0x11); 3689 if(pPriv->theatre != NULL) 3690 { 3691 RADEON_RT_SetEncoding(pScrn, pPriv); 3692 } 3693 if(pPriv->msp3430 != NULL) RADEON_MSP_SetEncoding(pPriv); 3694 if(pPriv->tda9885 != NULL) RADEON_TDA9885_SetEncoding(pPriv); 3695 if(pPriv->fi1236 != NULL) RADEON_FI1236_SetEncoding(pPriv); 3696 if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv); 3697 } 3698 3699 3700 /* update cliplist */ 3701 if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 3702 REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 3703 /* draw these */ 3704 if(pPriv->autopaint_colorkey) 3705 RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 3706 } 3707 3708 RADEONDisplayVideo(pScrn, crtc, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch, 3709 offset3+top*srcPitch, offset4+top*srcPitch, offset1+top*srcPitch, 3710 offset2+top*srcPitch, width, height, dstPitch*mult/2, 3711 xa, xb, ya, &dstBox, src_w, src_h*mult/2, drw_w, drw_h, pPriv->overlay_deinterlacing_method); 3712 3713 RADEONWaitForFifo(pScrn, 1); 3714 OUTREG(RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK); 3715 RADEONWaitForIdleMMIO(pScrn); 3716 while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK)); 3717 3718 3719 switch(pPriv->overlay_deinterlacing_method){ 3720 case METHOD_BOB: 3721 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 3722 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,0 /*| RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD*/ 3723 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3724 break; 3725 case METHOD_SINGLE: 3726 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xEEEEE | (9<<28)); 3727 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3728 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3729 break; 3730 case METHOD_WEAVE: 3731 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0x11111 | (9<<28)); 3732 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0 |RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3733 | RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 3734 /* |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN */ 3735 /*|RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN */ 3736 |RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE); 3737 break; 3738 default: 3739 OUTREG(RADEON_OV0_DEINTERLACE_PATTERN, 0xAAAAA); 3740 OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 3741 |RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN); 3742 } 3743 3744 3745 RADEONWaitForIdleMMIO(pScrn); 3746 OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE )); 3747 OUTREG (RADEON_OV0_AUTO_FLIP_CNTL, (INREG (RADEON_OV0_AUTO_FLIP_CNTL) ^ RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE )); 3748 3749 OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0); 3750 3751#if 0 3752 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_FLAG_CNTL=0x%08x\n", INREG(RADEON_OV0_FLAG_CNTL)); 3753/* OUTREG(RADEON_OV0_FLAG_CNTL, 8); */ 3754 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OV0_VID_BUFFER_CNTL=0x%08x\n", INREG(RADEON_VID_BUFFER_CONTROL)); 3755 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CAP0_BUF_STATUS=0x%08x\n", INREG(RADEON_CAP0_BUF_STATUS)); 3756 3757/* OUTREG(RADEON_OV0_SCALE_CNTL, 0x417f1B00); */ 3758#endif 3759 3760 pPriv->videoStatus = CLIENT_VIDEO_ON; 3761 pPriv->video_stream_active = TRUE; 3762 3763 info->VideoTimerCallback = RADEONVideoTimerCallback; 3764 3765 return Success; 3766} 3767 /* miscellaneous TV-in helper functions */ 3768 3769static void RADEON_board_setmisc(RADEONPortPrivPtr pPriv) 3770{ 3771 /* Adjust PAL/SECAM constants for FI1216MF tuner */ 3772 if((((pPriv->tuner_type & 0xf)==5) || 3773 ((pPriv->tuner_type & 0xf)==11)|| 3774 ((pPriv->tuner_type & 0xf)==14)) 3775 && (pPriv->fi1236!=NULL)) 3776 { 3777 if((pPriv->encoding>=1)&&(pPriv->encoding<=3)) /*PAL*/ 3778 { 3779 pPriv->fi1236->parm.band_low = 0xA1; 3780 pPriv->fi1236->parm.band_mid = 0x91; 3781 pPriv->fi1236->parm.band_high = 0x31; 3782 } 3783 if((pPriv->encoding>=7)&&(pPriv->encoding<=9)) /*SECAM*/ 3784 { 3785 pPriv->fi1236->parm.band_low = 0xA3; 3786 pPriv->fi1236->parm.band_mid = 0x93; 3787 pPriv->fi1236->parm.band_high = 0x33; 3788 } 3789 } 3790 3791} 3792 3793static void RADEON_RT_SetEncoding(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 3794{ 3795int width, height; 3796RADEONWaitForIdleMMIO(pScrn); 3797 3798/* Disable VBI capture for anything but TV tuner */ 3799switch(pPriv->encoding){ 3800 case 2: 3801 case 5: 3802 case 8: 3803 pPriv->capture_vbi_data=1; 3804 break; 3805 default: 3806 pPriv->capture_vbi_data=0; 3807 } 3808 3809switch(pPriv->encoding){ 3810 case 1: 3811 xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0); 3812 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3813 pPriv->v=25; 3814 break; 3815 case 2: 3816 xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0); 3817 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3818 pPriv->v=25; 3819 break; 3820 case 3: 3821 xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0); 3822 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL); 3823 pPriv->v=25; 3824 break; 3825 case 4: 3826 xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE,0); 3827 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3828 pPriv->v=23; 3829 break; 3830 case 5: 3831 xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0); 3832 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3833 pPriv->v=23; 3834 break; 3835 case 6: 3836 xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0); 3837 xf86_RT_SetStandard(pPriv->theatre,DEC_NTSC | extNONE); 3838 pPriv->v=23; 3839 break; 3840 case 7: 3841 xf86_RT_SetConnector(pPriv->theatre, DEC_COMPOSITE, 0); 3842 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3843 pPriv->v=25; 3844 break; 3845 case 8: 3846 xf86_RT_SetConnector(pPriv->theatre, DEC_TUNER, 0); 3847 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3848 pPriv->v=25; 3849 break; 3850 case 9: 3851 xf86_RT_SetConnector(pPriv->theatre, DEC_SVIDEO, 0); 3852 xf86_RT_SetStandard(pPriv->theatre,DEC_SECAM | extNONE); 3853 pPriv->v=25; 3854 break; 3855 case 10: 3856 xf86_RT_SetConnector(pPriv->theatre,DEC_COMPOSITE, 0); 3857 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3858 pPriv->v=25; 3859 break; 3860 case 11: 3861 xf86_RT_SetConnector(pPriv->theatre,DEC_TUNER,0); 3862 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3863 pPriv->v=25; 3864 break; 3865 case 12: 3866 xf86_RT_SetConnector(pPriv->theatre,DEC_SVIDEO,0); 3867 xf86_RT_SetStandard(pPriv->theatre,DEC_PAL | extPAL_60); 3868 pPriv->v=25; 3869 break; 3870 default: 3871 pPriv->v=0; 3872 return; 3873 } 3874xf86_RT_SetInterlace(pPriv->theatre, 1); 3875width = InputVideoEncodings[pPriv->encoding].width; 3876height = InputVideoEncodings[pPriv->encoding].height; 3877xf86_RT_SetOutputVideoSize(pPriv->theatre, width, height*2, 0, pPriv->capture_vbi_data); 3878} 3879 3880static void RADEON_MSP_SetEncoding(RADEONPortPrivPtr pPriv) 3881{ 3882xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); 3883switch(pPriv->encoding){ 3884 case 1: 3885 pPriv->msp3430->standard = MSP3430_PAL; 3886 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3887 break; 3888 case 2: 3889 pPriv->msp3430->standard = MSP3430_PAL; 3890 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3891 break; 3892 case 3: 3893 pPriv->msp3430->standard = MSP3430_PAL; 3894 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3895 break; 3896 case 4: 3897 pPriv->msp3430->standard = MSP3430_NTSC; 3898 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3899 break; 3900 case 5: 3901 pPriv->msp3430->standard = MSP3430_NTSC; 3902 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3903 break; 3904 case 6: 3905 pPriv->msp3430->standard = MSP3430_NTSC; 3906 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3907 break; 3908 case 7: 3909 pPriv->msp3430->standard = MSP3430_SECAM; 3910 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3911 break; 3912 case 8: 3913 pPriv->msp3430->standard = MSP3430_SECAM; 3914 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3915 break; 3916 case 9: 3917 pPriv->msp3430->standard = MSP3430_SECAM; 3918 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3919 break; 3920 case 10: 3921 pPriv->msp3430->standard = MSP3430_SECAM; 3922 pPriv->msp3430->connector = MSP3430_CONNECTOR_3; 3923 break; 3924 case 11: 3925 pPriv->msp3430->standard = MSP3430_SECAM; 3926 pPriv->msp3430->connector = MSP3430_CONNECTOR_1; 3927 break; 3928 case 12: 3929 pPriv->msp3430->standard = MSP3430_SECAM; 3930 pPriv->msp3430->connector = MSP3430_CONNECTOR_2; 3931 break; 3932 default: 3933 return; 3934 } 3935xf86_InitMSP3430(pPriv->msp3430); 3936xf86_MSP3430SetVolume(pPriv->msp3430, pPriv->mute ? MSP3430_FAST_MUTE : MSP3430_VOLUME(pPriv->volume)); 3937} 3938 3939static void RADEON_TDA9885_SetEncoding(RADEONPortPrivPtr pPriv) 3940{ 3941TDA9885Ptr t=pPriv->tda9885; 3942 3943switch(pPriv->encoding){ 3944 /* PAL */ 3945 case 1: 3946 case 2: 3947 case 3: 3948 t->standard_video_if=2; 3949 t->standard_sound_carrier=1; 3950 t->modulation=2; /* negative FM */ 3951 break; 3952 /* NTSC */ 3953 case 4: 3954 case 5: 3955 case 6: 3956 t->standard_video_if=1; 3957 t->standard_sound_carrier=0; 3958 t->modulation=2; /* negative FM */ 3959 break; 3960 /* SECAM */ 3961 case 7: 3962 case 8: 3963 case 9: 3964 case 10: 3965 case 11: 3966 case 12: 3967 t->standard_video_if=0; 3968 t->standard_sound_carrier=3; 3969 t->modulation=0; /* positive AM */ 3970 break; 3971 default: 3972 return; 3973 } 3974xf86_tda9885_setparameters(pPriv->tda9885); 3975xf86_tda9885_getstatus(pPriv->tda9885); 3976xf86_tda9885_dumpstatus(pPriv->tda9885); 3977} 3978 3979static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv) 3980{ 3981/* at the moment this only affect MT2032 */ 3982switch(pPriv->encoding){ 3983 /* PAL */ 3984 case 1: 3985 case 2: 3986 case 3: 3987 pPriv->fi1236->video_if=38.900; 3988 break; 3989 /* NTSC */ 3990 case 4: 3991 case 5: 3992 case 6: 3993 pPriv->fi1236->video_if=45.7812; 3994 pPriv->fi1236->video_if=45.750; 3995 pPriv->fi1236->video_if=45.125; 3996 break; 3997 /* SECAM */ 3998 case 7: 3999 case 8: 4000 case 9: 4001 case 10: 4002 case 11: 4003 case 12: 4004 pPriv->fi1236->video_if=58.7812; 4005 break; 4006 default: 4007 return; 4008 } 4009} 4010 4011