diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
25 files changed, 558 insertions, 281 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 388140a7e651..e3b44562d265 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
| @@ -246,6 +246,9 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
| 246 | case ATOM_WS_ATTRIBUTES: | 246 | case ATOM_WS_ATTRIBUTES: |
| 247 | val = gctx->io_attr; | 247 | val = gctx->io_attr; |
| 248 | break; | 248 | break; |
| 249 | case ATOM_WS_REGPTR: | ||
| 250 | val = gctx->reg_block; | ||
| 251 | break; | ||
| 249 | default: | 252 | default: |
| 250 | val = ctx->ws[idx]; | 253 | val = ctx->ws[idx]; |
| 251 | } | 254 | } |
| @@ -385,6 +388,32 @@ static uint32_t atom_get_src(atom_exec_context *ctx, uint8_t attr, int *ptr) | |||
| 385 | return atom_get_src_int(ctx, attr, ptr, NULL, 1); | 388 | return atom_get_src_int(ctx, attr, ptr, NULL, 1); |
| 386 | } | 389 | } |
| 387 | 390 | ||
| 391 | static uint32_t atom_get_src_direct(atom_exec_context *ctx, uint8_t align, int *ptr) | ||
| 392 | { | ||
| 393 | uint32_t val = 0xCDCDCDCD; | ||
| 394 | |||
| 395 | switch (align) { | ||
| 396 | case ATOM_SRC_DWORD: | ||
| 397 | val = U32(*ptr); | ||
| 398 | (*ptr) += 4; | ||
| 399 | break; | ||
| 400 | case ATOM_SRC_WORD0: | ||
| 401 | case ATOM_SRC_WORD8: | ||
| 402 | case ATOM_SRC_WORD16: | ||
| 403 | val = U16(*ptr); | ||
| 404 | (*ptr) += 2; | ||
| 405 | break; | ||
| 406 | case ATOM_SRC_BYTE0: | ||
| 407 | case ATOM_SRC_BYTE8: | ||
| 408 | case ATOM_SRC_BYTE16: | ||
| 409 | case ATOM_SRC_BYTE24: | ||
| 410 | val = U8(*ptr); | ||
| 411 | (*ptr)++; | ||
| 412 | break; | ||
| 413 | } | ||
| 414 | return val; | ||
| 415 | } | ||
| 416 | |||
| 388 | static uint32_t atom_get_dst(atom_exec_context *ctx, int arg, uint8_t attr, | 417 | static uint32_t atom_get_dst(atom_exec_context *ctx, int arg, uint8_t attr, |
| 389 | int *ptr, uint32_t *saved, int print) | 418 | int *ptr, uint32_t *saved, int print) |
| 390 | { | 419 | { |
| @@ -482,6 +511,9 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, | |||
| 482 | case ATOM_WS_ATTRIBUTES: | 511 | case ATOM_WS_ATTRIBUTES: |
| 483 | gctx->io_attr = val; | 512 | gctx->io_attr = val; |
| 484 | break; | 513 | break; |
| 514 | case ATOM_WS_REGPTR: | ||
| 515 | gctx->reg_block = val; | ||
| 516 | break; | ||
| 485 | default: | 517 | default: |
| 486 | ctx->ws[idx] = val; | 518 | ctx->ws[idx] = val; |
| 487 | } | 519 | } |
| @@ -677,7 +709,7 @@ static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) | |||
| 677 | SDEBUG(" dst: "); | 709 | SDEBUG(" dst: "); |
| 678 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 710 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
| 679 | SDEBUG(" src1: "); | 711 | SDEBUG(" src1: "); |
| 680 | src1 = atom_get_src(ctx, attr, ptr); | 712 | src1 = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); |
| 681 | SDEBUG(" src2: "); | 713 | SDEBUG(" src2: "); |
| 682 | src2 = atom_get_src(ctx, attr, ptr); | 714 | src2 = atom_get_src(ctx, attr, ptr); |
| 683 | dst &= src1; | 715 | dst &= src1; |
| @@ -809,6 +841,38 @@ static void atom_op_setregblock(atom_exec_context *ctx, int *ptr, int arg) | |||
| 809 | SDEBUG(" base: 0x%04X\n", ctx->ctx->reg_block); | 841 | SDEBUG(" base: 0x%04X\n", ctx->ctx->reg_block); |
| 810 | } | 842 | } |
| 811 | 843 | ||
| 844 | static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg) | ||
| 845 | { | ||
| 846 | uint8_t attr = U8((*ptr)++), shift; | ||
| 847 | uint32_t saved, dst; | ||
| 848 | int dptr = *ptr; | ||
| 849 | attr &= 0x38; | ||
| 850 | attr |= atom_def_dst[attr >> 3] << 6; | ||
| 851 | SDEBUG(" dst: "); | ||
| 852 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | ||
| 853 | shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr); | ||
| 854 | SDEBUG(" shift: %d\n", shift); | ||
| 855 | dst <<= shift; | ||
| 856 | SDEBUG(" dst: "); | ||
| 857 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); | ||
| 858 | } | ||
| 859 | |||
| 860 | static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg) | ||
| 861 | { | ||
| 862 | uint8_t attr = U8((*ptr)++), shift; | ||
| 863 | uint32_t saved, dst; | ||
| 864 | int dptr = *ptr; | ||
| 865 | attr &= 0x38; | ||
| 866 | attr |= atom_def_dst[attr >> 3] << 6; | ||
| 867 | SDEBUG(" dst: "); | ||
| 868 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | ||
| 869 | shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr); | ||
| 870 | SDEBUG(" shift: %d\n", shift); | ||
| 871 | dst >>= shift; | ||
| 872 | SDEBUG(" dst: "); | ||
| 873 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); | ||
| 874 | } | ||
| 875 | |||
| 812 | static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) | 876 | static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) |
| 813 | { | 877 | { |
| 814 | uint8_t attr = U8((*ptr)++), shift; | 878 | uint8_t attr = U8((*ptr)++), shift; |
| @@ -818,7 +882,7 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) | |||
| 818 | attr |= atom_def_dst[attr >> 3] << 6; | 882 | attr |= atom_def_dst[attr >> 3] << 6; |
| 819 | SDEBUG(" dst: "); | 883 | SDEBUG(" dst: "); |
| 820 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 884 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
| 821 | shift = U8((*ptr)++); | 885 | shift = atom_get_src(ctx, attr, ptr); |
| 822 | SDEBUG(" shift: %d\n", shift); | 886 | SDEBUG(" shift: %d\n", shift); |
| 823 | dst <<= shift; | 887 | dst <<= shift; |
| 824 | SDEBUG(" dst: "); | 888 | SDEBUG(" dst: "); |
| @@ -834,7 +898,7 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) | |||
| 834 | attr |= atom_def_dst[attr >> 3] << 6; | 898 | attr |= atom_def_dst[attr >> 3] << 6; |
| 835 | SDEBUG(" dst: "); | 899 | SDEBUG(" dst: "); |
| 836 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 900 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
| 837 | shift = U8((*ptr)++); | 901 | shift = atom_get_src(ctx, attr, ptr); |
| 838 | SDEBUG(" shift: %d\n", shift); | 902 | SDEBUG(" shift: %d\n", shift); |
| 839 | dst >>= shift; | 903 | dst >>= shift; |
| 840 | SDEBUG(" dst: "); | 904 | SDEBUG(" dst: "); |
| @@ -937,18 +1001,18 @@ static struct { | |||
| 937 | atom_op_or, ATOM_ARG_FB}, { | 1001 | atom_op_or, ATOM_ARG_FB}, { |
| 938 | atom_op_or, ATOM_ARG_PLL}, { | 1002 | atom_op_or, ATOM_ARG_PLL}, { |
| 939 | atom_op_or, ATOM_ARG_MC}, { | 1003 | atom_op_or, ATOM_ARG_MC}, { |
| 940 | atom_op_shl, ATOM_ARG_REG}, { | 1004 | atom_op_shift_left, ATOM_ARG_REG}, { |
| 941 | atom_op_shl, ATOM_ARG_PS}, { | 1005 | atom_op_shift_left, ATOM_ARG_PS}, { |
| 942 | atom_op_shl, ATOM_ARG_WS}, { | 1006 | atom_op_shift_left, ATOM_ARG_WS}, { |
| 943 | atom_op_shl, ATOM_ARG_FB}, { | 1007 | atom_op_shift_left, ATOM_ARG_FB}, { |
| 944 | atom_op_shl, ATOM_ARG_PLL}, { | 1008 | atom_op_shift_left, ATOM_ARG_PLL}, { |
| 945 | atom_op_shl, ATOM_ARG_MC}, { | 1009 | atom_op_shift_left, ATOM_ARG_MC}, { |
| 946 | atom_op_shr, ATOM_ARG_REG}, { | 1010 | atom_op_shift_right, ATOM_ARG_REG}, { |
| 947 | atom_op_shr, ATOM_ARG_PS}, { | 1011 | atom_op_shift_right, ATOM_ARG_PS}, { |
| 948 | atom_op_shr, ATOM_ARG_WS}, { | 1012 | atom_op_shift_right, ATOM_ARG_WS}, { |
| 949 | atom_op_shr, ATOM_ARG_FB}, { | 1013 | atom_op_shift_right, ATOM_ARG_FB}, { |
| 950 | atom_op_shr, ATOM_ARG_PLL}, { | 1014 | atom_op_shift_right, ATOM_ARG_PLL}, { |
| 951 | atom_op_shr, ATOM_ARG_MC}, { | 1015 | atom_op_shift_right, ATOM_ARG_MC}, { |
| 952 | atom_op_mul, ATOM_ARG_REG}, { | 1016 | atom_op_mul, ATOM_ARG_REG}, { |
| 953 | atom_op_mul, ATOM_ARG_PS}, { | 1017 | atom_op_mul, ATOM_ARG_PS}, { |
| 954 | atom_op_mul, ATOM_ARG_WS}, { | 1018 | atom_op_mul, ATOM_ARG_WS}, { |
| @@ -1058,8 +1122,6 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 | |||
| 1058 | 1122 | ||
| 1059 | SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps); | 1123 | SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps); |
| 1060 | 1124 | ||
| 1061 | /* reset reg block */ | ||
| 1062 | ctx->reg_block = 0; | ||
| 1063 | ectx.ctx = ctx; | 1125 | ectx.ctx = ctx; |
| 1064 | ectx.ps_shift = ps / 4; | 1126 | ectx.ps_shift = ps / 4; |
| 1065 | ectx.start = base; | 1127 | ectx.start = base; |
| @@ -1096,6 +1158,12 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 | |||
| 1096 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | 1158 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) |
| 1097 | { | 1159 | { |
| 1098 | mutex_lock(&ctx->mutex); | 1160 | mutex_lock(&ctx->mutex); |
| 1161 | /* reset reg block */ | ||
| 1162 | ctx->reg_block = 0; | ||
| 1163 | /* reset fb window */ | ||
| 1164 | ctx->fb_base = 0; | ||
| 1165 | /* reset io mode */ | ||
| 1166 | ctx->io_mode = ATOM_IO_MM; | ||
| 1099 | atom_execute_table_locked(ctx, index, params); | 1167 | atom_execute_table_locked(ctx, index, params); |
| 1100 | mutex_unlock(&ctx->mutex); | 1168 | mutex_unlock(&ctx->mutex); |
| 1101 | } | 1169 | } |
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index 47fd943f6d14..bc73781423a1 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
| @@ -91,6 +91,7 @@ | |||
| 91 | #define ATOM_WS_AND_MASK 0x45 | 91 | #define ATOM_WS_AND_MASK 0x45 |
| 92 | #define ATOM_WS_FB_WINDOW 0x46 | 92 | #define ATOM_WS_FB_WINDOW 0x46 |
| 93 | #define ATOM_WS_ATTRIBUTES 0x47 | 93 | #define ATOM_WS_ATTRIBUTES 0x47 |
| 94 | #define ATOM_WS_REGPTR 0x48 | ||
| 94 | 95 | ||
| 95 | #define ATOM_IIO_NOP 0 | 96 | #define ATOM_IIO_NOP 0 |
| 96 | #define ATOM_IIO_START 1 | 97 | #define ATOM_IIO_START 1 |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 260fcf59f00c..af464e351fbd 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -307,7 +307,6 @@ atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, | |||
| 307 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | 307 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); |
| 308 | args.ucCRTC = radeon_crtc->crtc_id; | 308 | args.ucCRTC = radeon_crtc->crtc_id; |
| 309 | 309 | ||
| 310 | printk("executing set crtc dtd timing\n"); | ||
| 311 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 310 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 312 | } | 311 | } |
| 313 | 312 | ||
| @@ -347,7 +346,6 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, | |||
| 347 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | 346 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); |
| 348 | args.ucCRTC = radeon_crtc->crtc_id; | 347 | args.ucCRTC = radeon_crtc->crtc_id; |
| 349 | 348 | ||
| 350 | printk("executing set crtc timing\n"); | ||
| 351 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 349 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 352 | } | 350 | } |
| 353 | 351 | ||
| @@ -409,59 +407,57 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) | |||
| 409 | } | 407 | } |
| 410 | } | 408 | } |
| 411 | 409 | ||
| 412 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 410 | union adjust_pixel_clock { |
| 411 | ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; | ||
| 412 | }; | ||
| 413 | |||
| 414 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, | ||
| 415 | struct drm_display_mode *mode, | ||
| 416 | struct radeon_pll *pll) | ||
| 413 | { | 417 | { |
| 414 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 415 | struct drm_device *dev = crtc->dev; | 418 | struct drm_device *dev = crtc->dev; |
| 416 | struct radeon_device *rdev = dev->dev_private; | 419 | struct radeon_device *rdev = dev->dev_private; |
| 417 | struct drm_encoder *encoder = NULL; | 420 | struct drm_encoder *encoder = NULL; |
| 418 | struct radeon_encoder *radeon_encoder = NULL; | 421 | struct radeon_encoder *radeon_encoder = NULL; |
| 419 | uint8_t frev, crev; | 422 | u32 adjusted_clock = mode->clock; |
| 420 | int index; | ||
| 421 | SET_PIXEL_CLOCK_PS_ALLOCATION args; | ||
| 422 | PIXEL_CLOCK_PARAMETERS *spc1_ptr; | ||
| 423 | PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; | ||
| 424 | PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; | ||
| 425 | uint32_t pll_clock = mode->clock; | ||
| 426 | uint32_t adjusted_clock; | ||
| 427 | uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
| 428 | struct radeon_pll *pll; | ||
| 429 | int pll_flags = 0; | ||
| 430 | 423 | ||
| 431 | memset(&args, 0, sizeof(args)); | 424 | /* reset the pll flags */ |
| 425 | pll->flags = 0; | ||
| 432 | 426 | ||
| 433 | if (ASIC_IS_AVIVO(rdev)) { | 427 | if (ASIC_IS_AVIVO(rdev)) { |
| 434 | if ((rdev->family == CHIP_RS600) || | 428 | if ((rdev->family == CHIP_RS600) || |
| 435 | (rdev->family == CHIP_RS690) || | 429 | (rdev->family == CHIP_RS690) || |
| 436 | (rdev->family == CHIP_RS740)) | 430 | (rdev->family == CHIP_RS740)) |
| 437 | pll_flags |= (RADEON_PLL_USE_FRAC_FB_DIV | | 431 | pll->flags |= (RADEON_PLL_USE_FRAC_FB_DIV | |
| 438 | RADEON_PLL_PREFER_CLOSEST_LOWER); | 432 | RADEON_PLL_PREFER_CLOSEST_LOWER); |
| 439 | 433 | ||
| 440 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ | 434 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ |
| 441 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 435 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
| 442 | else | 436 | else |
| 443 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 437 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
| 444 | } else { | 438 | } else { |
| 445 | pll_flags |= RADEON_PLL_LEGACY; | 439 | pll->flags |= RADEON_PLL_LEGACY; |
| 446 | 440 | ||
| 447 | if (mode->clock > 200000) /* range limits??? */ | 441 | if (mode->clock > 200000) /* range limits??? */ |
| 448 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 442 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
| 449 | else | 443 | else |
| 450 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 444 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
| 451 | 445 | ||
| 452 | } | 446 | } |
| 453 | 447 | ||
| 454 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 448 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 455 | if (encoder->crtc == crtc) { | 449 | if (encoder->crtc == crtc) { |
| 456 | if (!ASIC_IS_AVIVO(rdev)) { | ||
| 457 | if (encoder->encoder_type != | ||
| 458 | DRM_MODE_ENCODER_DAC) | ||
| 459 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; | ||
| 460 | if (encoder->encoder_type == | ||
| 461 | DRM_MODE_ENCODER_LVDS) | ||
| 462 | pll_flags |= RADEON_PLL_USE_REF_DIV; | ||
| 463 | } | ||
| 464 | radeon_encoder = to_radeon_encoder(encoder); | 450 | radeon_encoder = to_radeon_encoder(encoder); |
| 451 | if (ASIC_IS_AVIVO(rdev)) { | ||
| 452 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | ||
| 453 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | ||
| 454 | adjusted_clock = mode->clock * 2; | ||
| 455 | } else { | ||
| 456 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | ||
| 457 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | ||
| 458 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) | ||
| 459 | pll->flags |= RADEON_PLL_USE_REF_DIV; | ||
| 460 | } | ||
| 465 | break; | 461 | break; |
| 466 | } | 462 | } |
| 467 | } | 463 | } |
| @@ -471,46 +467,101 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 471 | * special hw requirements. | 467 | * special hw requirements. |
| 472 | */ | 468 | */ |
| 473 | if (ASIC_IS_DCE3(rdev)) { | 469 | if (ASIC_IS_DCE3(rdev)) { |
| 474 | ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args; | 470 | union adjust_pixel_clock args; |
| 471 | struct radeon_encoder_atom_dig *dig; | ||
| 472 | u8 frev, crev; | ||
| 473 | int index; | ||
| 475 | 474 | ||
| 476 | if (!encoder) | 475 | if (!radeon_encoder->enc_priv) |
| 477 | return; | 476 | return adjusted_clock; |
| 478 | 477 | dig = radeon_encoder->enc_priv; | |
| 479 | memset(&adjust_pll_args, 0, sizeof(adjust_pll_args)); | ||
| 480 | adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10); | ||
| 481 | adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id; | ||
| 482 | adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
| 483 | 478 | ||
| 484 | index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); | 479 | index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); |
| 485 | atom_execute_table(rdev->mode_info.atom_context, | 480 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
| 486 | index, (uint32_t *)&adjust_pll_args); | 481 | &crev); |
| 487 | adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10; | 482 | |
| 488 | } else { | 483 | memset(&args, 0, sizeof(args)); |
| 489 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 484 | |
| 490 | if (ASIC_IS_AVIVO(rdev) && | 485 | switch (frev) { |
| 491 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)) | 486 | case 1: |
| 492 | adjusted_clock = mode->clock * 2; | 487 | switch (crev) { |
| 493 | else | 488 | case 1: |
| 494 | adjusted_clock = mode->clock; | 489 | case 2: |
| 490 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | ||
| 491 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | ||
| 492 | args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
| 493 | |||
| 494 | atom_execute_table(rdev->mode_info.atom_context, | ||
| 495 | index, (uint32_t *)&args); | ||
| 496 | adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; | ||
| 497 | break; | ||
| 498 | default: | ||
| 499 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | ||
| 500 | return adjusted_clock; | ||
| 501 | } | ||
| 502 | break; | ||
| 503 | default: | ||
| 504 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | ||
| 505 | return adjusted_clock; | ||
| 506 | } | ||
| 495 | } | 507 | } |
| 508 | return adjusted_clock; | ||
| 509 | } | ||
| 510 | |||
| 511 | union set_pixel_clock { | ||
| 512 | SET_PIXEL_CLOCK_PS_ALLOCATION base; | ||
| 513 | PIXEL_CLOCK_PARAMETERS v1; | ||
| 514 | PIXEL_CLOCK_PARAMETERS_V2 v2; | ||
| 515 | PIXEL_CLOCK_PARAMETERS_V3 v3; | ||
| 516 | }; | ||
| 517 | |||
| 518 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | ||
| 519 | { | ||
| 520 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 521 | struct drm_device *dev = crtc->dev; | ||
| 522 | struct radeon_device *rdev = dev->dev_private; | ||
| 523 | struct drm_encoder *encoder = NULL; | ||
| 524 | struct radeon_encoder *radeon_encoder = NULL; | ||
| 525 | u8 frev, crev; | ||
| 526 | int index; | ||
| 527 | union set_pixel_clock args; | ||
| 528 | u32 pll_clock = mode->clock; | ||
| 529 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
| 530 | struct radeon_pll *pll; | ||
| 531 | u32 adjusted_clock; | ||
| 532 | |||
| 533 | memset(&args, 0, sizeof(args)); | ||
| 534 | |||
| 535 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 536 | if (encoder->crtc == crtc) { | ||
| 537 | radeon_encoder = to_radeon_encoder(encoder); | ||
| 538 | break; | ||
| 539 | } | ||
| 540 | } | ||
| 541 | |||
| 542 | if (!radeon_encoder) | ||
| 543 | return; | ||
| 496 | 544 | ||
| 497 | if (radeon_crtc->crtc_id == 0) | 545 | if (radeon_crtc->crtc_id == 0) |
| 498 | pll = &rdev->clock.p1pll; | 546 | pll = &rdev->clock.p1pll; |
| 499 | else | 547 | else |
| 500 | pll = &rdev->clock.p2pll; | 548 | pll = &rdev->clock.p2pll; |
| 501 | 549 | ||
| 550 | /* adjust pixel clock as needed */ | ||
| 551 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll); | ||
| 552 | |||
| 502 | if (ASIC_IS_AVIVO(rdev)) { | 553 | if (ASIC_IS_AVIVO(rdev)) { |
| 503 | if (radeon_new_pll) | 554 | if (radeon_new_pll) |
| 504 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, | 555 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, |
| 505 | &fb_div, &frac_fb_div, | 556 | &fb_div, &frac_fb_div, |
| 506 | &ref_div, &post_div, pll_flags); | 557 | &ref_div, &post_div); |
| 507 | else | 558 | else |
| 508 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, | 559 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, |
| 509 | &fb_div, &frac_fb_div, | 560 | &fb_div, &frac_fb_div, |
| 510 | &ref_div, &post_div, pll_flags); | 561 | &ref_div, &post_div); |
| 511 | } else | 562 | } else |
| 512 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 563 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
| 513 | &ref_div, &post_div, pll_flags); | 564 | &ref_div, &post_div); |
| 514 | 565 | ||
| 515 | index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | 566 | index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); |
| 516 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, | 567 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
| @@ -520,45 +571,38 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 520 | case 1: | 571 | case 1: |
| 521 | switch (crev) { | 572 | switch (crev) { |
| 522 | case 1: | 573 | case 1: |
| 523 | spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; | 574 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
| 524 | spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); | 575 | args.v1.usRefDiv = cpu_to_le16(ref_div); |
| 525 | spc1_ptr->usRefDiv = cpu_to_le16(ref_div); | 576 | args.v1.usFbDiv = cpu_to_le16(fb_div); |
| 526 | spc1_ptr->usFbDiv = cpu_to_le16(fb_div); | 577 | args.v1.ucFracFbDiv = frac_fb_div; |
| 527 | spc1_ptr->ucFracFbDiv = frac_fb_div; | 578 | args.v1.ucPostDiv = post_div; |
| 528 | spc1_ptr->ucPostDiv = post_div; | 579 | args.v1.ucPpll = |
| 529 | spc1_ptr->ucPpll = | ||
| 530 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | 580 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
| 531 | spc1_ptr->ucCRTC = radeon_crtc->crtc_id; | 581 | args.v1.ucCRTC = radeon_crtc->crtc_id; |
| 532 | spc1_ptr->ucRefDivSrc = 1; | 582 | args.v1.ucRefDivSrc = 1; |
| 533 | break; | 583 | break; |
| 534 | case 2: | 584 | case 2: |
| 535 | spc2_ptr = | 585 | args.v2.usPixelClock = cpu_to_le16(mode->clock / 10); |
| 536 | (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; | 586 | args.v2.usRefDiv = cpu_to_le16(ref_div); |
| 537 | spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); | 587 | args.v2.usFbDiv = cpu_to_le16(fb_div); |
| 538 | spc2_ptr->usRefDiv = cpu_to_le16(ref_div); | 588 | args.v2.ucFracFbDiv = frac_fb_div; |
| 539 | spc2_ptr->usFbDiv = cpu_to_le16(fb_div); | 589 | args.v2.ucPostDiv = post_div; |
| 540 | spc2_ptr->ucFracFbDiv = frac_fb_div; | 590 | args.v2.ucPpll = |
| 541 | spc2_ptr->ucPostDiv = post_div; | ||
| 542 | spc2_ptr->ucPpll = | ||
| 543 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | 591 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
| 544 | spc2_ptr->ucCRTC = radeon_crtc->crtc_id; | 592 | args.v2.ucCRTC = radeon_crtc->crtc_id; |
| 545 | spc2_ptr->ucRefDivSrc = 1; | 593 | args.v2.ucRefDivSrc = 1; |
| 546 | break; | 594 | break; |
| 547 | case 3: | 595 | case 3: |
| 548 | if (!encoder) | 596 | args.v3.usPixelClock = cpu_to_le16(mode->clock / 10); |
| 549 | return; | 597 | args.v3.usRefDiv = cpu_to_le16(ref_div); |
| 550 | spc3_ptr = | 598 | args.v3.usFbDiv = cpu_to_le16(fb_div); |
| 551 | (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; | 599 | args.v3.ucFracFbDiv = frac_fb_div; |
| 552 | spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); | 600 | args.v3.ucPostDiv = post_div; |
| 553 | spc3_ptr->usRefDiv = cpu_to_le16(ref_div); | 601 | args.v3.ucPpll = |
| 554 | spc3_ptr->usFbDiv = cpu_to_le16(fb_div); | ||
| 555 | spc3_ptr->ucFracFbDiv = frac_fb_div; | ||
| 556 | spc3_ptr->ucPostDiv = post_div; | ||
| 557 | spc3_ptr->ucPpll = | ||
| 558 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | 602 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
| 559 | spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2); | 603 | args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2); |
| 560 | spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id; | 604 | args.v3.ucTransmitterId = radeon_encoder->encoder_id; |
| 561 | spc3_ptr->ucEncoderMode = | 605 | args.v3.ucEncoderMode = |
| 562 | atombios_get_encoder_mode(encoder); | 606 | atombios_get_encoder_mode(encoder); |
| 563 | break; | 607 | break; |
| 564 | default: | 608 | default: |
| @@ -571,12 +615,11 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 571 | return; | 615 | return; |
| 572 | } | 616 | } |
| 573 | 617 | ||
| 574 | printk("executing set pll\n"); | ||
| 575 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 618 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 576 | } | 619 | } |
| 577 | 620 | ||
| 578 | int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 621 | static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
| 579 | struct drm_framebuffer *old_fb) | 622 | struct drm_framebuffer *old_fb) |
| 580 | { | 623 | { |
| 581 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 624 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 582 | struct drm_device *dev = crtc->dev; | 625 | struct drm_device *dev = crtc->dev; |
| @@ -706,6 +749,42 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 706 | return 0; | 749 | return 0; |
| 707 | } | 750 | } |
| 708 | 751 | ||
| 752 | int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | ||
| 753 | struct drm_framebuffer *old_fb) | ||
| 754 | { | ||
| 755 | struct drm_device *dev = crtc->dev; | ||
| 756 | struct radeon_device *rdev = dev->dev_private; | ||
| 757 | |||
| 758 | if (ASIC_IS_AVIVO(rdev)) | ||
| 759 | return avivo_crtc_set_base(crtc, x, y, old_fb); | ||
| 760 | else | ||
| 761 | return radeon_crtc_set_base(crtc, x, y, old_fb); | ||
| 762 | } | ||
| 763 | |||
| 764 | /* properly set additional regs when using atombios */ | ||
| 765 | static void radeon_legacy_atom_fixup(struct drm_crtc *crtc) | ||
| 766 | { | ||
| 767 | struct drm_device *dev = crtc->dev; | ||
| 768 | struct radeon_device *rdev = dev->dev_private; | ||
| 769 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 770 | u32 disp_merge_cntl; | ||
| 771 | |||
| 772 | switch (radeon_crtc->crtc_id) { | ||
| 773 | case 0: | ||
| 774 | disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL); | ||
| 775 | disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; | ||
| 776 | WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl); | ||
| 777 | break; | ||
| 778 | case 1: | ||
| 779 | disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL); | ||
| 780 | disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; | ||
| 781 | WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl); | ||
| 782 | WREG32(RADEON_FP_H2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_H_SYNC_STRT_WID)); | ||
| 783 | WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID)); | ||
| 784 | break; | ||
| 785 | } | ||
| 786 | } | ||
| 787 | |||
| 709 | int atombios_crtc_mode_set(struct drm_crtc *crtc, | 788 | int atombios_crtc_mode_set(struct drm_crtc *crtc, |
| 710 | struct drm_display_mode *mode, | 789 | struct drm_display_mode *mode, |
| 711 | struct drm_display_mode *adjusted_mode, | 790 | struct drm_display_mode *adjusted_mode, |
| @@ -727,8 +806,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
| 727 | else { | 806 | else { |
| 728 | if (radeon_crtc->crtc_id == 0) | 807 | if (radeon_crtc->crtc_id == 0) |
| 729 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 808 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
| 730 | radeon_crtc_set_base(crtc, x, y, old_fb); | 809 | atombios_crtc_set_base(crtc, x, y, old_fb); |
| 731 | radeon_legacy_atom_set_surface(crtc); | 810 | radeon_legacy_atom_fixup(crtc); |
| 732 | } | 811 | } |
| 733 | atombios_overscan_setup(crtc, mode, adjusted_mode); | 812 | atombios_overscan_setup(crtc, mode, adjusted_mode); |
| 734 | atombios_scaler_setup(crtc); | 813 | atombios_scaler_setup(crtc); |
| @@ -746,8 +825,8 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
| 746 | 825 | ||
| 747 | static void atombios_crtc_prepare(struct drm_crtc *crtc) | 826 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
| 748 | { | 827 | { |
| 749 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | ||
| 750 | atombios_lock_crtc(crtc, 1); | 828 | atombios_lock_crtc(crtc, 1); |
| 829 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | ||
| 751 | } | 830 | } |
| 752 | 831 | ||
| 753 | static void atombios_crtc_commit(struct drm_crtc *crtc) | 832 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8760d66e058a..11c9a3fe6810 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -1504,6 +1504,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
| 1504 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); | 1504 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
| 1505 | return -EINVAL; | 1505 | return -EINVAL; |
| 1506 | } | 1506 | } |
| 1507 | track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 0)); | ||
| 1507 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); | 1508 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
| 1508 | track->immd_dwords = pkt->count - 1; | 1509 | track->immd_dwords = pkt->count - 1; |
| 1509 | r = r100_cs_track_check(p->rdev, track); | 1510 | r = r100_cs_track_check(p->rdev, track); |
| @@ -3399,9 +3400,7 @@ int r100_mc_init(struct radeon_device *rdev) | |||
| 3399 | if (rdev->flags & RADEON_IS_AGP) { | 3400 | if (rdev->flags & RADEON_IS_AGP) { |
| 3400 | r = radeon_agp_init(rdev); | 3401 | r = radeon_agp_init(rdev); |
| 3401 | if (r) { | 3402 | if (r) { |
| 3402 | printk(KERN_WARNING "[drm] Disabling AGP\n"); | 3403 | radeon_agp_disable(rdev); |
| 3403 | rdev->flags &= ~RADEON_IS_AGP; | ||
| 3404 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
| 3405 | } else { | 3404 | } else { |
| 3406 | rdev->mc.gtt_location = rdev->mc.agp_base; | 3405 | rdev->mc.gtt_location = rdev->mc.agp_base; |
| 3407 | } | 3406 | } |
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 20942127c46b..ff1e0cd608bf 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
| @@ -371,13 +371,16 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 371 | case 5: | 371 | case 5: |
| 372 | case 6: | 372 | case 6: |
| 373 | case 7: | 373 | case 7: |
| 374 | /* 1D/2D */ | ||
| 374 | track->textures[i].tex_coord_type = 0; | 375 | track->textures[i].tex_coord_type = 0; |
| 375 | break; | 376 | break; |
| 376 | case 1: | 377 | case 1: |
| 377 | track->textures[i].tex_coord_type = 1; | 378 | /* CUBE */ |
| 379 | track->textures[i].tex_coord_type = 2; | ||
| 378 | break; | 380 | break; |
| 379 | case 2: | 381 | case 2: |
| 380 | track->textures[i].tex_coord_type = 2; | 382 | /* 3D */ |
| 383 | track->textures[i].tex_coord_type = 1; | ||
| 381 | break; | 384 | break; |
| 382 | } | 385 | } |
| 383 | break; | 386 | break; |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 053404e71a9d..4526faaacca8 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
| @@ -50,9 +50,7 @@ int r420_mc_init(struct radeon_device *rdev) | |||
| 50 | if (rdev->flags & RADEON_IS_AGP) { | 50 | if (rdev->flags & RADEON_IS_AGP) { |
| 51 | r = radeon_agp_init(rdev); | 51 | r = radeon_agp_init(rdev); |
| 52 | if (r) { | 52 | if (r) { |
| 53 | printk(KERN_WARNING "[drm] Disabling AGP\n"); | 53 | radeon_agp_disable(rdev); |
| 54 | rdev->flags &= ~RADEON_IS_AGP; | ||
| 55 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
| 56 | } else { | 54 | } else { |
| 57 | rdev->mc.gtt_location = rdev->mc.agp_base; | 55 | rdev->mc.gtt_location = rdev->mc.agp_base; |
| 58 | } | 56 | } |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c0651991c3e4..da9aa3c31bcf 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -624,7 +624,6 @@ int r600_mc_init(struct radeon_device *rdev) | |||
| 624 | fixed20_12 a; | 624 | fixed20_12 a; |
| 625 | u32 tmp; | 625 | u32 tmp; |
| 626 | int chansize, numchan; | 626 | int chansize, numchan; |
| 627 | int r; | ||
| 628 | 627 | ||
| 629 | /* Get VRAM informations */ | 628 | /* Get VRAM informations */ |
| 630 | rdev->mc.vram_is_ddr = true; | 629 | rdev->mc.vram_is_ddr = true; |
| @@ -667,9 +666,6 @@ int r600_mc_init(struct radeon_device *rdev) | |||
| 667 | rdev->mc.real_vram_size = rdev->mc.aper_size; | 666 | rdev->mc.real_vram_size = rdev->mc.aper_size; |
| 668 | 667 | ||
| 669 | if (rdev->flags & RADEON_IS_AGP) { | 668 | if (rdev->flags & RADEON_IS_AGP) { |
| 670 | r = radeon_agp_init(rdev); | ||
| 671 | if (r) | ||
| 672 | return r; | ||
| 673 | /* gtt_size is setup by radeon_agp_init */ | 669 | /* gtt_size is setup by radeon_agp_init */ |
| 674 | rdev->mc.gtt_location = rdev->mc.agp_base; | 670 | rdev->mc.gtt_location = rdev->mc.agp_base; |
| 675 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; | 671 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; |
| @@ -1958,14 +1954,17 @@ int r600_suspend(struct radeon_device *rdev) | |||
| 1958 | /* FIXME: we should wait for ring to be empty */ | 1954 | /* FIXME: we should wait for ring to be empty */ |
| 1959 | r600_cp_stop(rdev); | 1955 | r600_cp_stop(rdev); |
| 1960 | rdev->cp.ready = false; | 1956 | rdev->cp.ready = false; |
| 1957 | r600_irq_suspend(rdev); | ||
| 1961 | r600_wb_disable(rdev); | 1958 | r600_wb_disable(rdev); |
| 1962 | r600_pcie_gart_disable(rdev); | 1959 | r600_pcie_gart_disable(rdev); |
| 1963 | /* unpin shaders bo */ | 1960 | /* unpin shaders bo */ |
| 1964 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 1961 | if (rdev->r600_blit.shader_obj) { |
| 1965 | if (unlikely(r != 0)) | 1962 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
| 1966 | return r; | 1963 | if (!r) { |
| 1967 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | 1964 | radeon_bo_unpin(rdev->r600_blit.shader_obj); |
| 1968 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 1965 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
| 1966 | } | ||
| 1967 | } | ||
| 1969 | return 0; | 1968 | return 0; |
| 1970 | } | 1969 | } |
| 1971 | 1970 | ||
| @@ -2026,6 +2025,11 @@ int r600_init(struct radeon_device *rdev) | |||
| 2026 | r = radeon_fence_driver_init(rdev); | 2025 | r = radeon_fence_driver_init(rdev); |
| 2027 | if (r) | 2026 | if (r) |
| 2028 | return r; | 2027 | return r; |
| 2028 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 2029 | r = radeon_agp_init(rdev); | ||
| 2030 | if (r) | ||
| 2031 | radeon_agp_disable(rdev); | ||
| 2032 | } | ||
| 2029 | r = r600_mc_init(rdev); | 2033 | r = r600_mc_init(rdev); |
| 2030 | if (r) | 2034 | if (r) |
| 2031 | return r; | 2035 | return r; |
| @@ -2060,13 +2064,14 @@ int r600_init(struct radeon_device *rdev) | |||
| 2060 | if (rdev->accel_working) { | 2064 | if (rdev->accel_working) { |
| 2061 | r = radeon_ib_pool_init(rdev); | 2065 | r = radeon_ib_pool_init(rdev); |
| 2062 | if (r) { | 2066 | if (r) { |
| 2063 | DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); | 2067 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
| 2064 | rdev->accel_working = false; | ||
| 2065 | } | ||
| 2066 | r = r600_ib_test(rdev); | ||
| 2067 | if (r) { | ||
| 2068 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | ||
| 2069 | rdev->accel_working = false; | 2068 | rdev->accel_working = false; |
| 2069 | } else { | ||
| 2070 | r = r600_ib_test(rdev); | ||
| 2071 | if (r) { | ||
| 2072 | dev_err(rdev->dev, "IB test failed (%d).\n", r); | ||
| 2073 | rdev->accel_working = false; | ||
| 2074 | } | ||
| 2070 | } | 2075 | } |
| 2071 | } | 2076 | } |
| 2072 | 2077 | ||
| @@ -2197,14 +2202,14 @@ void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) | |||
| 2197 | rb_bufsz = drm_order(ring_size / 4); | 2202 | rb_bufsz = drm_order(ring_size / 4); |
| 2198 | ring_size = (1 << rb_bufsz) * 4; | 2203 | ring_size = (1 << rb_bufsz) * 4; |
| 2199 | rdev->ih.ring_size = ring_size; | 2204 | rdev->ih.ring_size = ring_size; |
| 2200 | rdev->ih.align_mask = 4 - 1; | 2205 | rdev->ih.ptr_mask = rdev->ih.ring_size - 1; |
| 2206 | rdev->ih.rptr = 0; | ||
| 2201 | } | 2207 | } |
| 2202 | 2208 | ||
| 2203 | static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size) | 2209 | static int r600_ih_ring_alloc(struct radeon_device *rdev) |
| 2204 | { | 2210 | { |
| 2205 | int r; | 2211 | int r; |
| 2206 | 2212 | ||
| 2207 | rdev->ih.ring_size = ring_size; | ||
| 2208 | /* Allocate ring buffer */ | 2213 | /* Allocate ring buffer */ |
| 2209 | if (rdev->ih.ring_obj == NULL) { | 2214 | if (rdev->ih.ring_obj == NULL) { |
| 2210 | r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, | 2215 | r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, |
| @@ -2234,9 +2239,6 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size) | |||
| 2234 | return r; | 2239 | return r; |
| 2235 | } | 2240 | } |
| 2236 | } | 2241 | } |
| 2237 | rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1; | ||
| 2238 | rdev->ih.rptr = 0; | ||
| 2239 | |||
| 2240 | return 0; | 2242 | return 0; |
| 2241 | } | 2243 | } |
| 2242 | 2244 | ||
| @@ -2386,7 +2388,7 @@ int r600_irq_init(struct radeon_device *rdev) | |||
| 2386 | u32 interrupt_cntl, ih_cntl, ih_rb_cntl; | 2388 | u32 interrupt_cntl, ih_cntl, ih_rb_cntl; |
| 2387 | 2389 | ||
| 2388 | /* allocate ring */ | 2390 | /* allocate ring */ |
| 2389 | ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size); | 2391 | ret = r600_ih_ring_alloc(rdev); |
| 2390 | if (ret) | 2392 | if (ret) |
| 2391 | return ret; | 2393 | return ret; |
| 2392 | 2394 | ||
| @@ -2449,10 +2451,15 @@ int r600_irq_init(struct radeon_device *rdev) | |||
| 2449 | return ret; | 2451 | return ret; |
| 2450 | } | 2452 | } |
| 2451 | 2453 | ||
| 2452 | void r600_irq_fini(struct radeon_device *rdev) | 2454 | void r600_irq_suspend(struct radeon_device *rdev) |
| 2453 | { | 2455 | { |
| 2454 | r600_disable_interrupts(rdev); | 2456 | r600_disable_interrupts(rdev); |
| 2455 | r600_rlc_stop(rdev); | 2457 | r600_rlc_stop(rdev); |
| 2458 | } | ||
| 2459 | |||
| 2460 | void r600_irq_fini(struct radeon_device *rdev) | ||
| 2461 | { | ||
| 2462 | r600_irq_suspend(rdev); | ||
| 2456 | r600_ih_ring_fini(rdev); | 2463 | r600_ih_ring_fini(rdev); |
| 2457 | } | 2464 | } |
| 2458 | 2465 | ||
| @@ -2467,8 +2474,12 @@ int r600_irq_set(struct radeon_device *rdev) | |||
| 2467 | return -EINVAL; | 2474 | return -EINVAL; |
| 2468 | } | 2475 | } |
| 2469 | /* don't enable anything if the ih is disabled */ | 2476 | /* don't enable anything if the ih is disabled */ |
| 2470 | if (!rdev->ih.enabled) | 2477 | if (!rdev->ih.enabled) { |
| 2478 | r600_disable_interrupts(rdev); | ||
| 2479 | /* force the active interrupt state to all disabled */ | ||
| 2480 | r600_disable_interrupt_state(rdev); | ||
| 2471 | return 0; | 2481 | return 0; |
| 2482 | } | ||
| 2472 | 2483 | ||
| 2473 | if (ASIC_IS_DCE3(rdev)) { | 2484 | if (ASIC_IS_DCE3(rdev)) { |
| 2474 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | 2485 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; |
| @@ -2638,16 +2649,18 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
| 2638 | wptr = RREG32(IH_RB_WPTR); | 2649 | wptr = RREG32(IH_RB_WPTR); |
| 2639 | 2650 | ||
| 2640 | if (wptr & RB_OVERFLOW) { | 2651 | if (wptr & RB_OVERFLOW) { |
| 2641 | WARN_ON(1); | 2652 | /* When a ring buffer overflow happen start parsing interrupt |
| 2642 | /* XXX deal with overflow */ | 2653 | * from the last not overwritten vector (wptr + 16). Hopefully |
| 2643 | DRM_ERROR("IH RB overflow\n"); | 2654 | * this should allow us to catchup. |
| 2655 | */ | ||
| 2656 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | ||
| 2657 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | ||
| 2658 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | ||
| 2644 | tmp = RREG32(IH_RB_CNTL); | 2659 | tmp = RREG32(IH_RB_CNTL); |
| 2645 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 2660 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
| 2646 | WREG32(IH_RB_CNTL, tmp); | 2661 | WREG32(IH_RB_CNTL, tmp); |
| 2647 | } | 2662 | } |
| 2648 | wptr = wptr & WPTR_OFFSET_MASK; | 2663 | return (wptr & rdev->ih.ptr_mask); |
| 2649 | |||
| 2650 | return wptr; | ||
| 2651 | } | 2664 | } |
| 2652 | 2665 | ||
| 2653 | /* r600 IV Ring | 2666 | /* r600 IV Ring |
| @@ -2683,12 +2696,13 @@ int r600_irq_process(struct radeon_device *rdev) | |||
| 2683 | u32 wptr = r600_get_ih_wptr(rdev); | 2696 | u32 wptr = r600_get_ih_wptr(rdev); |
| 2684 | u32 rptr = rdev->ih.rptr; | 2697 | u32 rptr = rdev->ih.rptr; |
| 2685 | u32 src_id, src_data; | 2698 | u32 src_id, src_data; |
| 2686 | u32 last_entry = rdev->ih.ring_size - 16; | ||
| 2687 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; | 2699 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; |
| 2688 | unsigned long flags; | 2700 | unsigned long flags; |
| 2689 | bool queue_hotplug = false; | 2701 | bool queue_hotplug = false; |
| 2690 | 2702 | ||
| 2691 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 2703 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); |
| 2704 | if (!rdev->ih.enabled) | ||
| 2705 | return IRQ_NONE; | ||
| 2692 | 2706 | ||
| 2693 | spin_lock_irqsave(&rdev->ih.lock, flags); | 2707 | spin_lock_irqsave(&rdev->ih.lock, flags); |
| 2694 | 2708 | ||
| @@ -2729,7 +2743,7 @@ restart_ih: | |||
| 2729 | } | 2743 | } |
| 2730 | break; | 2744 | break; |
| 2731 | default: | 2745 | default: |
| 2732 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2746 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
| 2733 | break; | 2747 | break; |
| 2734 | } | 2748 | } |
| 2735 | break; | 2749 | break; |
| @@ -2749,7 +2763,7 @@ restart_ih: | |||
| 2749 | } | 2763 | } |
| 2750 | break; | 2764 | break; |
| 2751 | default: | 2765 | default: |
| 2752 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2766 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
| 2753 | break; | 2767 | break; |
| 2754 | } | 2768 | } |
| 2755 | break; | 2769 | break; |
| @@ -2798,7 +2812,7 @@ restart_ih: | |||
| 2798 | } | 2812 | } |
| 2799 | break; | 2813 | break; |
| 2800 | default: | 2814 | default: |
| 2801 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2815 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
| 2802 | break; | 2816 | break; |
| 2803 | } | 2817 | } |
| 2804 | break; | 2818 | break; |
| @@ -2812,15 +2826,13 @@ restart_ih: | |||
| 2812 | DRM_DEBUG("IH: CP EOP\n"); | 2826 | DRM_DEBUG("IH: CP EOP\n"); |
| 2813 | break; | 2827 | break; |
| 2814 | default: | 2828 | default: |
| 2815 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | 2829 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
| 2816 | break; | 2830 | break; |
| 2817 | } | 2831 | } |
| 2818 | 2832 | ||
| 2819 | /* wptr/rptr are in bytes! */ | 2833 | /* wptr/rptr are in bytes! */ |
| 2820 | if (rptr == last_entry) | 2834 | rptr += 16; |
| 2821 | rptr = 0; | 2835 | rptr &= rdev->ih.ptr_mask; |
| 2822 | else | ||
| 2823 | rptr += 16; | ||
| 2824 | } | 2836 | } |
| 2825 | /* make sure wptr hasn't changed while processing */ | 2837 | /* make sure wptr hasn't changed while processing */ |
| 2826 | wptr = r600_get_ih_wptr(rdev); | 2838 | wptr = r600_get_ih_wptr(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 8787ea89dc6e..2bedce477a97 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
| @@ -512,14 +512,16 @@ void r600_blit_fini(struct radeon_device *rdev) | |||
| 512 | { | 512 | { |
| 513 | int r; | 513 | int r; |
| 514 | 514 | ||
| 515 | if (rdev->r600_blit.shader_obj == NULL) | ||
| 516 | return; | ||
| 517 | /* If we can't reserve the bo, unref should be enough to destroy | ||
| 518 | * it when it becomes idle. | ||
| 519 | */ | ||
| 515 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 520 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
| 516 | if (unlikely(r != 0)) { | 521 | if (!r) { |
| 517 | dev_err(rdev->dev, "(%d) can't finish r600 blit\n", r); | 522 | radeon_bo_unpin(rdev->r600_blit.shader_obj); |
| 518 | goto out_unref; | 523 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
| 519 | } | 524 | } |
| 520 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | ||
| 521 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
| 522 | out_unref: | ||
| 523 | radeon_bo_unref(&rdev->r600_blit.shader_obj); | 525 | radeon_bo_unref(&rdev->r600_blit.shader_obj); |
| 524 | } | 526 | } |
| 525 | 527 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 44060b92d9e6..e4c45ec16507 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -36,6 +36,10 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | |||
| 36 | typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); | 36 | typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); |
| 37 | static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; | 37 | static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; |
| 38 | 38 | ||
| 39 | struct r600_cs_track { | ||
| 40 | u32 cb_color0_base_last; | ||
| 41 | }; | ||
| 42 | |||
| 39 | /** | 43 | /** |
| 40 | * r600_cs_packet_parse() - parse cp packet and point ib index to next packet | 44 | * r600_cs_packet_parse() - parse cp packet and point ib index to next packet |
| 41 | * @parser: parser structure holding parsing context. | 45 | * @parser: parser structure holding parsing context. |
| @@ -177,6 +181,28 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | |||
| 177 | } | 181 | } |
| 178 | 182 | ||
| 179 | /** | 183 | /** |
| 184 | * r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc | ||
| 185 | * @parser: parser structure holding parsing context. | ||
| 186 | * | ||
| 187 | * Check next packet is relocation packet3, do bo validation and compute | ||
| 188 | * GPU offset using the provided start. | ||
| 189 | **/ | ||
| 190 | static inline int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) | ||
| 191 | { | ||
| 192 | struct radeon_cs_packet p3reloc; | ||
| 193 | int r; | ||
| 194 | |||
| 195 | r = r600_cs_packet_parse(p, &p3reloc, p->idx); | ||
| 196 | if (r) { | ||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | return 1; | ||
| 203 | } | ||
| 204 | |||
| 205 | /** | ||
| 180 | * r600_cs_packet_next_vline() - parse userspace VLINE packet | 206 | * r600_cs_packet_next_vline() - parse userspace VLINE packet |
| 181 | * @parser: parser structure holding parsing context. | 207 | * @parser: parser structure holding parsing context. |
| 182 | * | 208 | * |
| @@ -337,6 +363,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 337 | struct radeon_cs_packet *pkt) | 363 | struct radeon_cs_packet *pkt) |
| 338 | { | 364 | { |
| 339 | struct radeon_cs_reloc *reloc; | 365 | struct radeon_cs_reloc *reloc; |
| 366 | struct r600_cs_track *track; | ||
| 340 | volatile u32 *ib; | 367 | volatile u32 *ib; |
| 341 | unsigned idx; | 368 | unsigned idx; |
| 342 | unsigned i; | 369 | unsigned i; |
| @@ -344,6 +371,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 344 | int r; | 371 | int r; |
| 345 | u32 idx_value; | 372 | u32 idx_value; |
| 346 | 373 | ||
| 374 | track = (struct r600_cs_track *)p->track; | ||
| 347 | ib = p->ib->ptr; | 375 | ib = p->ib->ptr; |
| 348 | idx = pkt->idx + 1; | 376 | idx = pkt->idx + 1; |
| 349 | idx_value = radeon_get_ib_value(p, idx); | 377 | idx_value = radeon_get_ib_value(p, idx); |
| @@ -503,9 +531,60 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 503 | for (i = 0; i < pkt->count; i++) { | 531 | for (i = 0; i < pkt->count; i++) { |
| 504 | reg = start_reg + (4 * i); | 532 | reg = start_reg + (4 * i); |
| 505 | switch (reg) { | 533 | switch (reg) { |
| 534 | /* This register were added late, there is userspace | ||
| 535 | * which does provide relocation for those but set | ||
| 536 | * 0 offset. In order to avoid breaking old userspace | ||
| 537 | * we detect this and set address to point to last | ||
| 538 | * CB_COLOR0_BASE, note that if userspace doesn't set | ||
| 539 | * CB_COLOR0_BASE before this register we will report | ||
| 540 | * error. Old userspace always set CB_COLOR0_BASE | ||
| 541 | * before any of this. | ||
| 542 | */ | ||
| 543 | case R_0280E0_CB_COLOR0_FRAG: | ||
| 544 | case R_0280E4_CB_COLOR1_FRAG: | ||
| 545 | case R_0280E8_CB_COLOR2_FRAG: | ||
| 546 | case R_0280EC_CB_COLOR3_FRAG: | ||
| 547 | case R_0280F0_CB_COLOR4_FRAG: | ||
| 548 | case R_0280F4_CB_COLOR5_FRAG: | ||
| 549 | case R_0280F8_CB_COLOR6_FRAG: | ||
| 550 | case R_0280FC_CB_COLOR7_FRAG: | ||
| 551 | case R_0280C0_CB_COLOR0_TILE: | ||
| 552 | case R_0280C4_CB_COLOR1_TILE: | ||
| 553 | case R_0280C8_CB_COLOR2_TILE: | ||
| 554 | case R_0280CC_CB_COLOR3_TILE: | ||
| 555 | case R_0280D0_CB_COLOR4_TILE: | ||
| 556 | case R_0280D4_CB_COLOR5_TILE: | ||
| 557 | case R_0280D8_CB_COLOR6_TILE: | ||
| 558 | case R_0280DC_CB_COLOR7_TILE: | ||
| 559 | if (!r600_cs_packet_next_is_pkt3_nop(p)) { | ||
| 560 | if (!track->cb_color0_base_last) { | ||
| 561 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); | ||
| 562 | return -EINVAL; | ||
| 563 | } | ||
| 564 | ib[idx+1+i] = track->cb_color0_base_last; | ||
| 565 | printk_once(KERN_WARNING "radeon: You have old & broken userspace " | ||
| 566 | "please consider updating mesa & xf86-video-ati\n"); | ||
| 567 | } else { | ||
| 568 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
| 569 | if (r) { | ||
| 570 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | ||
| 571 | return -EINVAL; | ||
| 572 | } | ||
| 573 | ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
| 574 | } | ||
| 575 | break; | ||
| 506 | case DB_DEPTH_BASE: | 576 | case DB_DEPTH_BASE: |
| 507 | case DB_HTILE_DATA_BASE: | 577 | case DB_HTILE_DATA_BASE: |
| 508 | case CB_COLOR0_BASE: | 578 | case CB_COLOR0_BASE: |
| 579 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
| 580 | if (r) { | ||
| 581 | DRM_ERROR("bad SET_CONTEXT_REG " | ||
| 582 | "0x%04X\n", reg); | ||
| 583 | return -EINVAL; | ||
| 584 | } | ||
| 585 | ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
| 586 | track->cb_color0_base_last = ib[idx+1+i]; | ||
| 587 | break; | ||
| 509 | case CB_COLOR1_BASE: | 588 | case CB_COLOR1_BASE: |
| 510 | case CB_COLOR2_BASE: | 589 | case CB_COLOR2_BASE: |
| 511 | case CB_COLOR3_BASE: | 590 | case CB_COLOR3_BASE: |
| @@ -678,8 +757,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 678 | int r600_cs_parse(struct radeon_cs_parser *p) | 757 | int r600_cs_parse(struct radeon_cs_parser *p) |
| 679 | { | 758 | { |
| 680 | struct radeon_cs_packet pkt; | 759 | struct radeon_cs_packet pkt; |
| 760 | struct r600_cs_track *track; | ||
| 681 | int r; | 761 | int r; |
| 682 | 762 | ||
| 763 | track = kzalloc(sizeof(*track), GFP_KERNEL); | ||
| 764 | p->track = track; | ||
| 683 | do { | 765 | do { |
| 684 | r = r600_cs_packet_parse(p, &pkt, p->idx); | 766 | r = r600_cs_packet_parse(p, &pkt, p->idx); |
| 685 | if (r) { | 767 | if (r) { |
| @@ -757,6 +839,7 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, | |||
| 757 | /* initialize parser */ | 839 | /* initialize parser */ |
| 758 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); | 840 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); |
| 759 | parser.filp = filp; | 841 | parser.filp = filp; |
| 842 | parser.dev = &dev->pdev->dev; | ||
| 760 | parser.rdev = NULL; | 843 | parser.rdev = NULL; |
| 761 | parser.family = family; | 844 | parser.family = family; |
| 762 | parser.ib = &fake_ib; | 845 | parser.ib = &fake_ib; |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 05894edadab4..30480881aed1 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -882,4 +882,29 @@ | |||
| 882 | #define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) | 882 | #define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) |
| 883 | 883 | ||
| 884 | #define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 | 884 | #define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 |
| 885 | |||
| 886 | #define R_0280E0_CB_COLOR0_FRAG 0x0280E0 | ||
| 887 | #define S_0280E0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 888 | #define G_0280E0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 889 | #define C_0280E0_BASE_256B 0x00000000 | ||
| 890 | #define R_0280E4_CB_COLOR1_FRAG 0x0280E4 | ||
| 891 | #define R_0280E8_CB_COLOR2_FRAG 0x0280E8 | ||
| 892 | #define R_0280EC_CB_COLOR3_FRAG 0x0280EC | ||
| 893 | #define R_0280F0_CB_COLOR4_FRAG 0x0280F0 | ||
| 894 | #define R_0280F4_CB_COLOR5_FRAG 0x0280F4 | ||
| 895 | #define R_0280F8_CB_COLOR6_FRAG 0x0280F8 | ||
| 896 | #define R_0280FC_CB_COLOR7_FRAG 0x0280FC | ||
| 897 | #define R_0280C0_CB_COLOR0_TILE 0x0280C0 | ||
| 898 | #define S_0280C0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 899 | #define G_0280C0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 900 | #define C_0280C0_BASE_256B 0x00000000 | ||
| 901 | #define R_0280C4_CB_COLOR1_TILE 0x0280C4 | ||
| 902 | #define R_0280C8_CB_COLOR2_TILE 0x0280C8 | ||
| 903 | #define R_0280CC_CB_COLOR3_TILE 0x0280CC | ||
| 904 | #define R_0280D0_CB_COLOR4_TILE 0x0280D0 | ||
| 905 | #define R_0280D4_CB_COLOR5_TILE 0x0280D4 | ||
| 906 | #define R_0280D8_CB_COLOR6_TILE 0x0280D8 | ||
| 907 | #define R_0280DC_CB_COLOR7_TILE 0x0280DC | ||
| 908 | |||
| 909 | |||
| 885 | #endif | 910 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index eb5f99b9469d..f7df1a7e4413 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -410,7 +410,6 @@ struct r600_ih { | |||
| 410 | unsigned wptr_old; | 410 | unsigned wptr_old; |
| 411 | unsigned ring_size; | 411 | unsigned ring_size; |
| 412 | uint64_t gpu_addr; | 412 | uint64_t gpu_addr; |
| 413 | uint32_t align_mask; | ||
| 414 | uint32_t ptr_mask; | 413 | uint32_t ptr_mask; |
| 415 | spinlock_t lock; | 414 | spinlock_t lock; |
| 416 | bool enabled; | 415 | bool enabled; |
| @@ -465,6 +464,7 @@ struct radeon_cs_chunk { | |||
| 465 | }; | 464 | }; |
| 466 | 465 | ||
| 467 | struct radeon_cs_parser { | 466 | struct radeon_cs_parser { |
| 467 | struct device *dev; | ||
| 468 | struct radeon_device *rdev; | 468 | struct radeon_device *rdev; |
| 469 | struct drm_file *filp; | 469 | struct drm_file *filp; |
| 470 | /* chunks */ | 470 | /* chunks */ |
| @@ -847,7 +847,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
| 847 | 847 | ||
| 848 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | 848 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) |
| 849 | { | 849 | { |
| 850 | if (reg < 0x10000) | 850 | if (reg < rdev->rmmio_size) |
| 851 | return readl(((void __iomem *)rdev->rmmio) + reg); | 851 | return readl(((void __iomem *)rdev->rmmio) + reg); |
| 852 | else { | 852 | else { |
| 853 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | 853 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); |
| @@ -857,7 +857,7 @@ static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | |||
| 857 | 857 | ||
| 858 | static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | 858 | static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
| 859 | { | 859 | { |
| 860 | if (reg < 0x10000) | 860 | if (reg < rdev->rmmio_size) |
| 861 | writel(v, ((void __iomem *)rdev->rmmio) + reg); | 861 | writel(v, ((void __iomem *)rdev->rmmio) + reg); |
| 862 | else { | 862 | else { |
| 863 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | 863 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); |
| @@ -1017,6 +1017,8 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
| 1017 | #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) | 1017 | #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) |
| 1018 | 1018 | ||
| 1019 | /* Common functions */ | 1019 | /* Common functions */ |
| 1020 | /* AGP */ | ||
| 1021 | extern void radeon_agp_disable(struct radeon_device *rdev); | ||
| 1020 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); | 1022 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); |
| 1021 | extern int radeon_modeset_init(struct radeon_device *rdev); | 1023 | extern int radeon_modeset_init(struct radeon_device *rdev); |
| 1022 | extern void radeon_modeset_fini(struct radeon_device *rdev); | 1024 | extern void radeon_modeset_fini(struct radeon_device *rdev); |
| @@ -1160,7 +1162,8 @@ extern int r600_irq_init(struct radeon_device *rdev); | |||
| 1160 | extern void r600_irq_fini(struct radeon_device *rdev); | 1162 | extern void r600_irq_fini(struct radeon_device *rdev); |
| 1161 | extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); | 1163 | extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); |
| 1162 | extern int r600_irq_set(struct radeon_device *rdev); | 1164 | extern int r600_irq_set(struct radeon_device *rdev); |
| 1163 | 1165 | extern void r600_irq_suspend(struct radeon_device *rdev); | |
| 1166 | /* r600 audio */ | ||
| 1164 | extern int r600_audio_init(struct radeon_device *rdev); | 1167 | extern int r600_audio_init(struct radeon_device *rdev); |
| 1165 | extern int r600_audio_tmds_index(struct drm_encoder *encoder); | 1168 | extern int r600_audio_tmds_index(struct drm_encoder *encoder); |
| 1166 | extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); | 1169 | extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 220f454ea9fa..c9ad7f5cc1ac 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
| @@ -133,6 +133,13 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
| 133 | bool is_v3; | 133 | bool is_v3; |
| 134 | int ret; | 134 | int ret; |
| 135 | 135 | ||
| 136 | if (rdev->ddev->agp->agp_info.aper_size < 32) { | ||
| 137 | dev_warn(rdev->dev, "AGP aperture to small (%dM) " | ||
| 138 | "need at least 32M, disabling AGP\n", | ||
| 139 | rdev->ddev->agp->agp_info.aper_size); | ||
| 140 | return -EINVAL; | ||
| 141 | } | ||
| 142 | |||
| 136 | /* Acquire AGP. */ | 143 | /* Acquire AGP. */ |
| 137 | if (!rdev->ddev->agp->acquired) { | 144 | if (!rdev->ddev->agp->acquired) { |
| 138 | ret = drm_agp_acquire(rdev->ddev); | 145 | ret = drm_agp_acquire(rdev->ddev); |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 812f24dbc2a8..73c4405bf42f 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
| @@ -56,7 +56,7 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) | |||
| 56 | else if (post_div == 3) | 56 | else if (post_div == 3) |
| 57 | sclk >>= 2; | 57 | sclk >>= 2; |
| 58 | else if (post_div == 4) | 58 | else if (post_div == 4) |
| 59 | sclk >>= 4; | 59 | sclk >>= 3; |
| 60 | 60 | ||
| 61 | return sclk; | 61 | return sclk; |
| 62 | } | 62 | } |
| @@ -86,7 +86,7 @@ uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) | |||
| 86 | else if (post_div == 3) | 86 | else if (post_div == 3) |
| 87 | mclk >>= 2; | 87 | mclk >>= 2; |
| 88 | else if (post_div == 4) | 88 | else if (post_div == 4) |
| 89 | mclk >>= 4; | 89 | mclk >>= 3; |
| 90 | 90 | ||
| 91 | return mclk; | 91 | return mclk; |
| 92 | } | 92 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 7914455c96ca..579c8920e081 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -687,6 +687,9 @@ radeon_combios_get_tv_info(struct radeon_device *rdev) | |||
| 687 | uint16_t tv_info; | 687 | uint16_t tv_info; |
| 688 | enum radeon_tv_std tv_std = TV_STD_NTSC; | 688 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
| 689 | 689 | ||
| 690 | if (rdev->bios == NULL) | ||
| 691 | return tv_std; | ||
| 692 | |||
| 690 | tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); | 693 | tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); |
| 691 | if (tv_info) { | 694 | if (tv_info) { |
| 692 | if (RBIOS8(tv_info + 6) == 'T') { | 695 | if (RBIOS8(tv_info + 6) == 'T') { |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 9da10dd5df80..55266416fa47 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -900,10 +900,18 @@ static void radeon_dvi_force(struct drm_connector *connector) | |||
| 900 | static int radeon_dvi_mode_valid(struct drm_connector *connector, | 900 | static int radeon_dvi_mode_valid(struct drm_connector *connector, |
| 901 | struct drm_display_mode *mode) | 901 | struct drm_display_mode *mode) |
| 902 | { | 902 | { |
| 903 | struct drm_device *dev = connector->dev; | ||
| 904 | struct radeon_device *rdev = dev->dev_private; | ||
| 903 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 905 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 904 | 906 | ||
| 905 | /* XXX check mode bandwidth */ | 907 | /* XXX check mode bandwidth */ |
| 906 | 908 | ||
| 909 | /* clocks over 135 MHz have heat issues with DVI on RV100 */ | ||
| 910 | if (radeon_connector->use_digital && | ||
| 911 | (rdev->family == CHIP_RV100) && | ||
| 912 | (mode->clock > 135000)) | ||
| 913 | return MODE_CLOCK_HIGH; | ||
| 914 | |||
| 907 | if (radeon_connector->use_digital && (mode->clock > 165000)) { | 915 | if (radeon_connector->use_digital && (mode->clock > 165000)) { |
| 908 | if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || | 916 | if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || |
| 909 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || | 917 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 65590a0f1d93..1496cb8658ef 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -231,6 +231,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 231 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); | 231 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); |
| 232 | parser.filp = filp; | 232 | parser.filp = filp; |
| 233 | parser.rdev = rdev; | 233 | parser.rdev = rdev; |
| 234 | parser.dev = rdev->dev; | ||
| 234 | r = radeon_cs_parser_init(&parser, data); | 235 | r = radeon_cs_parser_init(&parser, data); |
| 235 | if (r) { | 236 | if (r) { |
| 236 | DRM_ERROR("Failed to initialize parser !\n"); | 237 | DRM_ERROR("Failed to initialize parser !\n"); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0c51f8e46613..768b1509fa03 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -544,6 +544,7 @@ void radeon_agp_disable(struct radeon_device *rdev) | |||
| 544 | rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; | 544 | rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; |
| 545 | rdev->asic->gart_set_page = &r100_pci_gart_set_page; | 545 | rdev->asic->gart_set_page = &r100_pci_gart_set_page; |
| 546 | } | 546 | } |
| 547 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
| 547 | } | 548 | } |
| 548 | 549 | ||
| 549 | void radeon_check_arguments(struct radeon_device *rdev) | 550 | void radeon_check_arguments(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0ec491ead2ff..6a92f994cc26 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -357,7 +357,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
| 357 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || | 357 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || |
| 358 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { | 358 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { |
| 359 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | 359 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
| 360 | if (dig->dp_i2c_bus) | 360 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || |
| 361 | dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus) | ||
| 361 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); | 362 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); |
| 362 | } | 363 | } |
| 363 | if (!radeon_connector->ddc_bus) | 364 | if (!radeon_connector->ddc_bus) |
| @@ -410,11 +411,12 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 410 | uint32_t *fb_div_p, | 411 | uint32_t *fb_div_p, |
| 411 | uint32_t *frac_fb_div_p, | 412 | uint32_t *frac_fb_div_p, |
| 412 | uint32_t *ref_div_p, | 413 | uint32_t *ref_div_p, |
| 413 | uint32_t *post_div_p, | 414 | uint32_t *post_div_p) |
| 414 | int flags) | ||
| 415 | { | 415 | { |
| 416 | uint32_t min_ref_div = pll->min_ref_div; | 416 | uint32_t min_ref_div = pll->min_ref_div; |
| 417 | uint32_t max_ref_div = pll->max_ref_div; | 417 | uint32_t max_ref_div = pll->max_ref_div; |
| 418 | uint32_t min_post_div = pll->min_post_div; | ||
| 419 | uint32_t max_post_div = pll->max_post_div; | ||
| 418 | uint32_t min_fractional_feed_div = 0; | 420 | uint32_t min_fractional_feed_div = 0; |
| 419 | uint32_t max_fractional_feed_div = 0; | 421 | uint32_t max_fractional_feed_div = 0; |
| 420 | uint32_t best_vco = pll->best_vco; | 422 | uint32_t best_vco = pll->best_vco; |
| @@ -430,7 +432,7 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 430 | DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); | 432 | DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); |
| 431 | freq = freq * 1000; | 433 | freq = freq * 1000; |
| 432 | 434 | ||
| 433 | if (flags & RADEON_PLL_USE_REF_DIV) | 435 | if (pll->flags & RADEON_PLL_USE_REF_DIV) |
| 434 | min_ref_div = max_ref_div = pll->reference_div; | 436 | min_ref_div = max_ref_div = pll->reference_div; |
| 435 | else { | 437 | else { |
| 436 | while (min_ref_div < max_ref_div-1) { | 438 | while (min_ref_div < max_ref_div-1) { |
| @@ -445,19 +447,22 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 445 | } | 447 | } |
| 446 | } | 448 | } |
| 447 | 449 | ||
| 448 | if (flags & RADEON_PLL_USE_FRAC_FB_DIV) { | 450 | if (pll->flags & RADEON_PLL_USE_POST_DIV) |
| 451 | min_post_div = max_post_div = pll->post_div; | ||
| 452 | |||
| 453 | if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { | ||
| 449 | min_fractional_feed_div = pll->min_frac_feedback_div; | 454 | min_fractional_feed_div = pll->min_frac_feedback_div; |
| 450 | max_fractional_feed_div = pll->max_frac_feedback_div; | 455 | max_fractional_feed_div = pll->max_frac_feedback_div; |
| 451 | } | 456 | } |
| 452 | 457 | ||
| 453 | for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) { | 458 | for (post_div = min_post_div; post_div <= max_post_div; ++post_div) { |
| 454 | uint32_t ref_div; | 459 | uint32_t ref_div; |
| 455 | 460 | ||
| 456 | if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) | 461 | if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) |
| 457 | continue; | 462 | continue; |
| 458 | 463 | ||
| 459 | /* legacy radeons only have a few post_divs */ | 464 | /* legacy radeons only have a few post_divs */ |
| 460 | if (flags & RADEON_PLL_LEGACY) { | 465 | if (pll->flags & RADEON_PLL_LEGACY) { |
| 461 | if ((post_div == 5) || | 466 | if ((post_div == 5) || |
| 462 | (post_div == 7) || | 467 | (post_div == 7) || |
| 463 | (post_div == 9) || | 468 | (post_div == 9) || |
| @@ -504,7 +509,7 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 504 | tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div; | 509 | tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div; |
| 505 | current_freq = radeon_div(tmp, ref_div * post_div); | 510 | current_freq = radeon_div(tmp, ref_div * post_div); |
| 506 | 511 | ||
| 507 | if (flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { | 512 | if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { |
| 508 | error = freq - current_freq; | 513 | error = freq - current_freq; |
| 509 | error = error < 0 ? 0xffffffff : error; | 514 | error = error < 0 ? 0xffffffff : error; |
| 510 | } else | 515 | } else |
| @@ -531,12 +536,12 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
| 531 | best_freq = current_freq; | 536 | best_freq = current_freq; |
| 532 | best_error = error; | 537 | best_error = error; |
| 533 | best_vco_diff = vco_diff; | 538 | best_vco_diff = vco_diff; |
| 534 | } else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) || | 539 | } else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) || |
| 535 | ((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) || | 540 | ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) || |
| 536 | ((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) || | 541 | ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) || |
| 537 | ((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) || | 542 | ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) || |
| 538 | ((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) || | 543 | ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) || |
| 539 | ((flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) { | 544 | ((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) { |
| 540 | best_post_div = post_div; | 545 | best_post_div = post_div; |
| 541 | best_ref_div = ref_div; | 546 | best_ref_div = ref_div; |
| 542 | best_feedback_div = feedback_div; | 547 | best_feedback_div = feedback_div; |
| @@ -572,8 +577,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, | |||
| 572 | uint32_t *fb_div_p, | 577 | uint32_t *fb_div_p, |
| 573 | uint32_t *frac_fb_div_p, | 578 | uint32_t *frac_fb_div_p, |
| 574 | uint32_t *ref_div_p, | 579 | uint32_t *ref_div_p, |
| 575 | uint32_t *post_div_p, | 580 | uint32_t *post_div_p) |
| 576 | int flags) | ||
| 577 | { | 581 | { |
| 578 | fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq; | 582 | fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq; |
| 579 | fixed20_12 pll_out_max, pll_out_min; | 583 | fixed20_12 pll_out_max, pll_out_min; |
| @@ -667,7 +671,6 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
| 667 | radeonfb_remove(dev, fb); | 671 | radeonfb_remove(dev, fb); |
| 668 | 672 | ||
| 669 | if (radeon_fb->obj) { | 673 | if (radeon_fb->obj) { |
| 670 | radeon_gem_object_unpin(radeon_fb->obj); | ||
| 671 | mutex_lock(&dev->struct_mutex); | 674 | mutex_lock(&dev->struct_mutex); |
| 672 | drm_gem_object_unreference(radeon_fb->obj); | 675 | drm_gem_object_unreference(radeon_fb->obj); |
| 673 | mutex_unlock(&dev->struct_mutex); | 676 | mutex_unlock(&dev->struct_mutex); |
| @@ -715,7 +718,11 @@ radeon_user_framebuffer_create(struct drm_device *dev, | |||
| 715 | struct drm_gem_object *obj; | 718 | struct drm_gem_object *obj; |
| 716 | 719 | ||
| 717 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); | 720 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); |
| 718 | 721 | if (obj == NULL) { | |
| 722 | dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " | ||
| 723 | "can't create framebuffer\n", mode_cmd->handle); | ||
| 724 | return NULL; | ||
| 725 | } | ||
| 719 | return radeon_framebuffer_create(dev, mode_cmd, obj); | 726 | return radeon_framebuffer_create(dev, mode_cmd, obj); |
| 720 | } | 727 | } |
| 721 | 728 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index cc27485a07ad..b6d8081e1246 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -339,69 +339,6 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 339 | } | 339 | } |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | /* properly set crtc bpp when using atombios */ | ||
| 343 | void radeon_legacy_atom_set_surface(struct drm_crtc *crtc) | ||
| 344 | { | ||
| 345 | struct drm_device *dev = crtc->dev; | ||
| 346 | struct radeon_device *rdev = dev->dev_private; | ||
| 347 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 348 | int format; | ||
| 349 | uint32_t crtc_gen_cntl; | ||
| 350 | uint32_t disp_merge_cntl; | ||
| 351 | uint32_t crtc_pitch; | ||
| 352 | |||
| 353 | switch (crtc->fb->bits_per_pixel) { | ||
| 354 | case 8: | ||
| 355 | format = 2; | ||
| 356 | break; | ||
| 357 | case 15: /* 555 */ | ||
| 358 | format = 3; | ||
| 359 | break; | ||
| 360 | case 16: /* 565 */ | ||
| 361 | format = 4; | ||
| 362 | break; | ||
| 363 | case 24: /* RGB */ | ||
| 364 | format = 5; | ||
| 365 | break; | ||
| 366 | case 32: /* xRGB */ | ||
| 367 | format = 6; | ||
| 368 | break; | ||
| 369 | default: | ||
| 370 | return; | ||
| 371 | } | ||
| 372 | |||
| 373 | crtc_pitch = ((((crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8)) * crtc->fb->bits_per_pixel) + | ||
| 374 | ((crtc->fb->bits_per_pixel * 8) - 1)) / | ||
| 375 | (crtc->fb->bits_per_pixel * 8)); | ||
| 376 | crtc_pitch |= crtc_pitch << 16; | ||
| 377 | |||
| 378 | WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); | ||
| 379 | |||
| 380 | switch (radeon_crtc->crtc_id) { | ||
| 381 | case 0: | ||
| 382 | disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL); | ||
| 383 | disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; | ||
| 384 | WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl); | ||
| 385 | |||
| 386 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0xfffff0ff; | ||
| 387 | crtc_gen_cntl |= (format << 8); | ||
| 388 | crtc_gen_cntl |= RADEON_CRTC_EXT_DISP_EN; | ||
| 389 | WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); | ||
| 390 | break; | ||
| 391 | case 1: | ||
| 392 | disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL); | ||
| 393 | disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; | ||
| 394 | WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl); | ||
| 395 | |||
| 396 | crtc_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0xfffff0ff; | ||
| 397 | crtc_gen_cntl |= (format << 8); | ||
| 398 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc_gen_cntl); | ||
| 399 | WREG32(RADEON_FP_H2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_H_SYNC_STRT_WID)); | ||
| 400 | WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID)); | ||
| 401 | break; | ||
| 402 | } | ||
| 403 | } | ||
| 404 | |||
| 405 | int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 342 | int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
| 406 | struct drm_framebuffer *old_fb) | 343 | struct drm_framebuffer *old_fb) |
| 407 | { | 344 | { |
| @@ -755,7 +692,6 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 755 | uint32_t post_divider = 0; | 692 | uint32_t post_divider = 0; |
| 756 | uint32_t freq = 0; | 693 | uint32_t freq = 0; |
| 757 | uint8_t pll_gain; | 694 | uint8_t pll_gain; |
| 758 | int pll_flags = RADEON_PLL_LEGACY; | ||
| 759 | bool use_bios_divs = false; | 695 | bool use_bios_divs = false; |
| 760 | /* PLL registers */ | 696 | /* PLL registers */ |
| 761 | uint32_t pll_ref_div = 0; | 697 | uint32_t pll_ref_div = 0; |
| @@ -789,10 +725,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 789 | else | 725 | else |
| 790 | pll = &rdev->clock.p1pll; | 726 | pll = &rdev->clock.p1pll; |
| 791 | 727 | ||
| 728 | pll->flags = RADEON_PLL_LEGACY; | ||
| 729 | |||
| 792 | if (mode->clock > 200000) /* range limits??? */ | 730 | if (mode->clock > 200000) /* range limits??? */ |
| 793 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 731 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
| 794 | else | 732 | else |
| 795 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 733 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
| 796 | 734 | ||
| 797 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 735 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 798 | if (encoder->crtc == crtc) { | 736 | if (encoder->crtc == crtc) { |
| @@ -804,7 +742,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 804 | } | 742 | } |
| 805 | 743 | ||
| 806 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 744 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
| 807 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; | 745 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
| 808 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { | 746 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { |
| 809 | if (!rdev->is_atom_bios) { | 747 | if (!rdev->is_atom_bios) { |
| 810 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 748 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| @@ -819,7 +757,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 819 | } | 757 | } |
| 820 | } | 758 | } |
| 821 | } | 759 | } |
| 822 | pll_flags |= RADEON_PLL_USE_REF_DIV; | 760 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
| 823 | } | 761 | } |
| 824 | } | 762 | } |
| 825 | } | 763 | } |
| @@ -829,8 +767,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
| 829 | if (!use_bios_divs) { | 767 | if (!use_bios_divs) { |
| 830 | radeon_compute_pll(pll, mode->clock, | 768 | radeon_compute_pll(pll, mode->clock, |
| 831 | &freq, &feedback_div, &frac_fb_div, | 769 | &freq, &feedback_div, &frac_fb_div, |
| 832 | &reference_div, &post_divider, | 770 | &reference_div, &post_divider); |
| 833 | pll_flags); | ||
| 834 | 771 | ||
| 835 | for (post_div = &post_divs[0]; post_div->divider; ++post_div) { | 772 | for (post_div = &post_divs[0]; post_div->divider; ++post_div) { |
| 836 | if (post_div->divider == post_divider) | 773 | if (post_div->divider == post_divider) |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 981508ff7037..38e45e231ef5 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
| @@ -46,6 +46,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 46 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 46 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 47 | uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; | 47 | uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; |
| 48 | int panel_pwr_delay = 2000; | 48 | int panel_pwr_delay = 2000; |
| 49 | bool is_mac = false; | ||
| 49 | DRM_DEBUG("\n"); | 50 | DRM_DEBUG("\n"); |
| 50 | 51 | ||
| 51 | if (radeon_encoder->enc_priv) { | 52 | if (radeon_encoder->enc_priv) { |
| @@ -58,6 +59,15 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 58 | } | 59 | } |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 62 | /* macs (and possibly some x86 oem systems?) wire up LVDS strangely | ||
| 63 | * Taken from radeonfb. | ||
| 64 | */ | ||
| 65 | if ((rdev->mode_info.connector_table == CT_IBOOK) || | ||
| 66 | (rdev->mode_info.connector_table == CT_POWERBOOK_EXTERNAL) || | ||
| 67 | (rdev->mode_info.connector_table == CT_POWERBOOK_INTERNAL) || | ||
| 68 | (rdev->mode_info.connector_table == CT_POWERBOOK_VGA)) | ||
| 69 | is_mac = true; | ||
| 70 | |||
| 61 | switch (mode) { | 71 | switch (mode) { |
| 62 | case DRM_MODE_DPMS_ON: | 72 | case DRM_MODE_DPMS_ON: |
| 63 | disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); | 73 | disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); |
| @@ -74,6 +84,8 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 74 | 84 | ||
| 75 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | 85 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); |
| 76 | lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON); | 86 | lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON); |
| 87 | if (is_mac) | ||
| 88 | lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; | ||
| 77 | lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); | 89 | lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS); |
| 78 | udelay(panel_pwr_delay * 1000); | 90 | udelay(panel_pwr_delay * 1000); |
| 79 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 91 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
| @@ -85,7 +97,14 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 85 | WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); | 97 | WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); |
| 86 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | 98 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); |
| 87 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; | 99 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; |
| 88 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); | 100 | if (is_mac) { |
| 101 | lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN; | ||
| 102 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | ||
| 103 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_EN); | ||
| 104 | } else { | ||
| 105 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | ||
| 106 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); | ||
| 107 | } | ||
| 89 | udelay(panel_pwr_delay * 1000); | 108 | udelay(panel_pwr_delay * 1000); |
| 90 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 109 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
| 91 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 110 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 91cb041cb40d..96b851f92f4c 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -125,16 +125,24 @@ struct radeon_tmds_pll { | |||
| 125 | #define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) | 125 | #define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) |
| 126 | #define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) | 126 | #define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) |
| 127 | #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) | 127 | #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) |
| 128 | #define RADEON_PLL_USE_POST_DIV (1 << 12) | ||
| 128 | 129 | ||
| 129 | struct radeon_pll { | 130 | struct radeon_pll { |
| 130 | uint16_t reference_freq; | 131 | /* reference frequency */ |
| 131 | uint16_t reference_div; | 132 | uint32_t reference_freq; |
| 133 | |||
| 134 | /* fixed dividers */ | ||
| 135 | uint32_t reference_div; | ||
| 136 | uint32_t post_div; | ||
| 137 | |||
| 138 | /* pll in/out limits */ | ||
| 132 | uint32_t pll_in_min; | 139 | uint32_t pll_in_min; |
| 133 | uint32_t pll_in_max; | 140 | uint32_t pll_in_max; |
| 134 | uint32_t pll_out_min; | 141 | uint32_t pll_out_min; |
| 135 | uint32_t pll_out_max; | 142 | uint32_t pll_out_max; |
| 136 | uint16_t xclk; | 143 | uint32_t best_vco; |
| 137 | 144 | ||
| 145 | /* divider limits */ | ||
| 138 | uint32_t min_ref_div; | 146 | uint32_t min_ref_div; |
| 139 | uint32_t max_ref_div; | 147 | uint32_t max_ref_div; |
| 140 | uint32_t min_post_div; | 148 | uint32_t min_post_div; |
| @@ -143,7 +151,12 @@ struct radeon_pll { | |||
| 143 | uint32_t max_feedback_div; | 151 | uint32_t max_feedback_div; |
| 144 | uint32_t min_frac_feedback_div; | 152 | uint32_t min_frac_feedback_div; |
| 145 | uint32_t max_frac_feedback_div; | 153 | uint32_t max_frac_feedback_div; |
| 146 | uint32_t best_vco; | 154 | |
| 155 | /* flags for the current clock */ | ||
| 156 | uint32_t flags; | ||
| 157 | |||
| 158 | /* pll id */ | ||
| 159 | uint32_t id; | ||
| 147 | }; | 160 | }; |
| 148 | 161 | ||
| 149 | struct radeon_i2c_chan { | 162 | struct radeon_i2c_chan { |
| @@ -417,8 +430,7 @@ extern void radeon_compute_pll(struct radeon_pll *pll, | |||
| 417 | uint32_t *fb_div_p, | 430 | uint32_t *fb_div_p, |
| 418 | uint32_t *frac_fb_div_p, | 431 | uint32_t *frac_fb_div_p, |
| 419 | uint32_t *ref_div_p, | 432 | uint32_t *ref_div_p, |
| 420 | uint32_t *post_div_p, | 433 | uint32_t *post_div_p); |
| 421 | int flags); | ||
| 422 | 434 | ||
| 423 | extern void radeon_compute_pll_avivo(struct radeon_pll *pll, | 435 | extern void radeon_compute_pll_avivo(struct radeon_pll *pll, |
| 424 | uint64_t freq, | 436 | uint64_t freq, |
| @@ -426,8 +438,7 @@ extern void radeon_compute_pll_avivo(struct radeon_pll *pll, | |||
| 426 | uint32_t *fb_div_p, | 438 | uint32_t *fb_div_p, |
| 427 | uint32_t *frac_fb_div_p, | 439 | uint32_t *frac_fb_div_p, |
| 428 | uint32_t *ref_div_p, | 440 | uint32_t *ref_div_p, |
| 429 | uint32_t *post_div_p, | 441 | uint32_t *post_div_p); |
| 430 | int flags); | ||
| 431 | 442 | ||
| 432 | extern void radeon_setup_encoder_clones(struct drm_device *dev); | 443 | extern void radeon_setup_encoder_clones(struct drm_device *dev); |
| 433 | 444 | ||
| @@ -453,7 +464,6 @@ extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode); | |||
| 453 | 464 | ||
| 454 | extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 465 | extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
| 455 | struct drm_framebuffer *old_fb); | 466 | struct drm_framebuffer *old_fb); |
| 456 | extern void radeon_legacy_atom_set_surface(struct drm_crtc *crtc); | ||
| 457 | 467 | ||
| 458 | extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, | 468 | extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, |
| 459 | struct drm_file *file_priv, | 469 | struct drm_file *file_priv, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 4e636de877b2..d72a71bff218 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -220,7 +220,8 @@ int radeon_bo_unpin(struct radeon_bo *bo) | |||
| 220 | 220 | ||
| 221 | int radeon_bo_evict_vram(struct radeon_device *rdev) | 221 | int radeon_bo_evict_vram(struct radeon_device *rdev) |
| 222 | { | 222 | { |
| 223 | if (rdev->flags & RADEON_IS_IGP) { | 223 | /* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */ |
| 224 | if (0 && (rdev->flags & RADEON_IS_IGP)) { | ||
| 224 | if (rdev->mc.igp_sideport_enabled == false) | 225 | if (rdev->mc.igp_sideport_enabled == false) |
| 225 | /* Useless to evict on IGP chips */ | 226 | /* Useless to evict on IGP chips */ |
| 226 | return 0; | 227 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 3b0c07b444a2..58b5adf974ca 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
| @@ -215,7 +215,10 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, | |||
| 215 | rbo = container_of(bo, struct radeon_bo, tbo); | 215 | rbo = container_of(bo, struct radeon_bo, tbo); |
| 216 | switch (bo->mem.mem_type) { | 216 | switch (bo->mem.mem_type) { |
| 217 | case TTM_PL_VRAM: | 217 | case TTM_PL_VRAM: |
| 218 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); | 218 | if (rbo->rdev->cp.ready == false) |
| 219 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); | ||
| 220 | else | ||
| 221 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); | ||
| 219 | break; | 222 | break; |
| 220 | case TTM_PL_TT: | 223 | case TTM_PL_TT: |
| 221 | default: | 224 | default: |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r200 b/drivers/gpu/drm/radeon/reg_srcs/r200 index 6021c8849a16..c29ac434ac9c 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r200 +++ b/drivers/gpu/drm/radeon/reg_srcs/r200 | |||
| @@ -91,6 +91,8 @@ r200 0x3294 | |||
| 91 | 0x22b8 SE_TCL_TEX_CYL_WRAP_CTL | 91 | 0x22b8 SE_TCL_TEX_CYL_WRAP_CTL |
| 92 | 0x22c0 SE_TCL_UCP_VERT_BLEND_CNTL | 92 | 0x22c0 SE_TCL_UCP_VERT_BLEND_CNTL |
| 93 | 0x22c4 SE_TCL_POINT_SPRITE_CNTL | 93 | 0x22c4 SE_TCL_POINT_SPRITE_CNTL |
| 94 | 0x22d0 SE_PVS_CNTL | ||
| 95 | 0x22d4 SE_PVS_CONST_CNTL | ||
| 94 | 0x2648 RE_POINTSIZE | 96 | 0x2648 RE_POINTSIZE |
| 95 | 0x26c0 RE_TOP_LEFT | 97 | 0x26c0 RE_TOP_LEFT |
| 96 | 0x26c4 RE_MISC | 98 | 0x26c4 RE_MISC |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 59c71245fb91..55f6ffc4e58b 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -779,7 +779,6 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
| 779 | fixed20_12 a; | 779 | fixed20_12 a; |
| 780 | u32 tmp; | 780 | u32 tmp; |
| 781 | int chansize, numchan; | 781 | int chansize, numchan; |
| 782 | int r; | ||
| 783 | 782 | ||
| 784 | /* Get VRAM informations */ | 783 | /* Get VRAM informations */ |
| 785 | rdev->mc.vram_is_ddr = true; | 784 | rdev->mc.vram_is_ddr = true; |
| @@ -822,9 +821,6 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
| 822 | rdev->mc.real_vram_size = rdev->mc.aper_size; | 821 | rdev->mc.real_vram_size = rdev->mc.aper_size; |
| 823 | 822 | ||
| 824 | if (rdev->flags & RADEON_IS_AGP) { | 823 | if (rdev->flags & RADEON_IS_AGP) { |
| 825 | r = radeon_agp_init(rdev); | ||
| 826 | if (r) | ||
| 827 | return r; | ||
| 828 | /* gtt_size is setup by radeon_agp_init */ | 824 | /* gtt_size is setup by radeon_agp_init */ |
| 829 | rdev->mc.gtt_location = rdev->mc.agp_base; | 825 | rdev->mc.gtt_location = rdev->mc.agp_base; |
| 830 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; | 826 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; |
| @@ -972,13 +968,16 @@ int rv770_suspend(struct radeon_device *rdev) | |||
| 972 | /* FIXME: we should wait for ring to be empty */ | 968 | /* FIXME: we should wait for ring to be empty */ |
| 973 | r700_cp_stop(rdev); | 969 | r700_cp_stop(rdev); |
| 974 | rdev->cp.ready = false; | 970 | rdev->cp.ready = false; |
| 971 | r600_irq_suspend(rdev); | ||
| 975 | r600_wb_disable(rdev); | 972 | r600_wb_disable(rdev); |
| 976 | rv770_pcie_gart_disable(rdev); | 973 | rv770_pcie_gart_disable(rdev); |
| 977 | /* unpin shaders bo */ | 974 | /* unpin shaders bo */ |
| 978 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 975 | if (rdev->r600_blit.shader_obj) { |
| 979 | if (likely(r == 0)) { | 976 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
| 980 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | 977 | if (likely(r == 0)) { |
| 981 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 978 | radeon_bo_unpin(rdev->r600_blit.shader_obj); |
| 979 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
| 980 | } | ||
| 982 | } | 981 | } |
| 983 | return 0; | 982 | return 0; |
| 984 | } | 983 | } |
| @@ -1037,6 +1036,11 @@ int rv770_init(struct radeon_device *rdev) | |||
| 1037 | r = radeon_fence_driver_init(rdev); | 1036 | r = radeon_fence_driver_init(rdev); |
| 1038 | if (r) | 1037 | if (r) |
| 1039 | return r; | 1038 | return r; |
| 1039 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 1040 | r = radeon_agp_init(rdev); | ||
| 1041 | if (r) | ||
| 1042 | radeon_agp_disable(rdev); | ||
| 1043 | } | ||
| 1040 | r = rv770_mc_init(rdev); | 1044 | r = rv770_mc_init(rdev); |
| 1041 | if (r) | 1045 | if (r) |
| 1042 | return r; | 1046 | return r; |
| @@ -1071,13 +1075,14 @@ int rv770_init(struct radeon_device *rdev) | |||
| 1071 | if (rdev->accel_working) { | 1075 | if (rdev->accel_working) { |
| 1072 | r = radeon_ib_pool_init(rdev); | 1076 | r = radeon_ib_pool_init(rdev); |
| 1073 | if (r) { | 1077 | if (r) { |
| 1074 | DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); | 1078 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
| 1075 | rdev->accel_working = false; | ||
| 1076 | } | ||
| 1077 | r = r600_ib_test(rdev); | ||
| 1078 | if (r) { | ||
| 1079 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | ||
| 1080 | rdev->accel_working = false; | 1079 | rdev->accel_working = false; |
| 1080 | } else { | ||
| 1081 | r = r600_ib_test(rdev); | ||
| 1082 | if (r) { | ||
| 1083 | dev_err(rdev->dev, "IB test failed (%d).\n", r); | ||
| 1084 | rdev->accel_working = false; | ||
| 1085 | } | ||
| 1081 | } | 1086 | } |
| 1082 | } | 1087 | } |
| 1083 | return 0; | 1088 | return 0; |
