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