diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
47 files changed, 4963 insertions, 1173 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 6cae4f2028d2..e47eecfc2df4 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
| @@ -65,10 +65,13 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
| 65 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ | 65 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
| 66 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ | 66 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
| 67 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ | 67 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ |
| 68 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o | 68 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ |
| 69 | radeon_trace_points.o ni.o | ||
| 69 | 70 | ||
| 70 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 71 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
| 71 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o | 72 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
| 72 | radeon-$(CONFIG_ACPI) += radeon_acpi.o | 73 | radeon-$(CONFIG_ACPI) += radeon_acpi.o |
| 73 | 74 | ||
| 74 | obj-$(CONFIG_DRM_RADEON)+= radeon.o | 75 | obj-$(CONFIG_DRM_RADEON)+= radeon.o |
| 76 | |||
| 77 | CFLAGS_radeon_trace_points.o := -I$(src) \ No newline at end of file | ||
diff --git a/drivers/gpu/drm/radeon/ObjectID.h b/drivers/gpu/drm/radeon/ObjectID.h index c714179d1bfa..c61c3fe9fb98 100644 --- a/drivers/gpu/drm/radeon/ObjectID.h +++ b/drivers/gpu/drm/radeon/ObjectID.h | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | #define GRAPH_OBJECT_TYPE_CONNECTOR 0x3 | 37 | #define GRAPH_OBJECT_TYPE_CONNECTOR 0x3 |
| 38 | #define GRAPH_OBJECT_TYPE_ROUTER 0x4 | 38 | #define GRAPH_OBJECT_TYPE_ROUTER 0x4 |
| 39 | /* deleted */ | 39 | /* deleted */ |
| 40 | #define GRAPH_OBJECT_TYPE_DISPLAY_PATH 0x6 | ||
| 41 | #define GRAPH_OBJECT_TYPE_GENERIC 0x7 | ||
| 40 | 42 | ||
| 41 | /****************************************************/ | 43 | /****************************************************/ |
| 42 | /* Encoder Object ID Definition */ | 44 | /* Encoder Object ID Definition */ |
| @@ -64,6 +66,9 @@ | |||
| 64 | #define ENCODER_OBJECT_ID_VT1623 0x10 | 66 | #define ENCODER_OBJECT_ID_VT1623 0x10 |
| 65 | #define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 | 67 | #define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 |
| 66 | #define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 | 68 | #define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 |
| 69 | #define ENCODER_OBJECT_ID_ALMOND 0x22 | ||
| 70 | #define ENCODER_OBJECT_ID_TRAVIS 0x23 | ||
| 71 | #define ENCODER_OBJECT_ID_NUTMEG 0x22 | ||
| 67 | /* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */ | 72 | /* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */ |
| 68 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 | 73 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 |
| 69 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 | 74 | #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 |
| @@ -108,6 +113,7 @@ | |||
| 108 | #define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 | 113 | #define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 |
| 109 | #define CONNECTOR_OBJECT_ID_eDP 0x14 | 114 | #define CONNECTOR_OBJECT_ID_eDP 0x14 |
| 110 | #define CONNECTOR_OBJECT_ID_MXM 0x15 | 115 | #define CONNECTOR_OBJECT_ID_MXM 0x15 |
| 116 | #define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16 | ||
| 111 | 117 | ||
| 112 | /* deleted */ | 118 | /* deleted */ |
| 113 | 119 | ||
| @@ -124,6 +130,7 @@ | |||
| 124 | #define GENERIC_OBJECT_ID_GLSYNC 0x01 | 130 | #define GENERIC_OBJECT_ID_GLSYNC 0x01 |
| 125 | #define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02 | 131 | #define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02 |
| 126 | #define GENERIC_OBJECT_ID_MXM_OPM 0x03 | 132 | #define GENERIC_OBJECT_ID_MXM_OPM 0x03 |
| 133 | #define GENERIC_OBJECT_ID_STEREO_PIN 0x04 //This object could show up from Misc Object table, it follows ATOM_OBJECT format, and contains one ATOM_OBJECT_GPIO_CNTL_RECORD for the stereo pin | ||
| 127 | 134 | ||
| 128 | /****************************************************/ | 135 | /****************************************************/ |
| 129 | /* Graphics Object ENUM ID Definition */ | 136 | /* Graphics Object ENUM ID Definition */ |
| @@ -360,6 +367,26 @@ | |||
| 360 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 367 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
| 361 | ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) | 368 | ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) |
| 362 | 369 | ||
| 370 | #define ENCODER_ALMOND_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
| 371 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
| 372 | ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT) | ||
| 373 | |||
| 374 | #define ENCODER_ALMOND_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
| 375 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
| 376 | ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT) | ||
| 377 | |||
| 378 | #define ENCODER_TRAVIS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
| 379 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
| 380 | ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT) | ||
| 381 | |||
| 382 | #define ENCODER_TRAVIS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
| 383 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
| 384 | ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT) | ||
| 385 | |||
| 386 | #define ENCODER_NUTMEG_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ | ||
| 387 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
| 388 | ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT) | ||
| 389 | |||
| 363 | /****************************************************/ | 390 | /****************************************************/ |
| 364 | /* Connector Object ID definition - Shared with BIOS */ | 391 | /* Connector Object ID definition - Shared with BIOS */ |
| 365 | /****************************************************/ | 392 | /****************************************************/ |
| @@ -421,6 +448,14 @@ | |||
| 421 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 448 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
| 422 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) | 449 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) |
| 423 | 450 | ||
| 451 | #define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
| 452 | GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ | ||
| 453 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) | ||
| 454 | |||
| 455 | #define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
| 456 | GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ | ||
| 457 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) | ||
| 458 | |||
| 424 | #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 459 | #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
| 425 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 460 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
| 426 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) | 461 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) |
| @@ -512,6 +547,7 @@ | |||
| 512 | #define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 547 | #define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
| 513 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 548 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
| 514 | CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) | 549 | CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) |
| 550 | |||
| 515 | #define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | 551 | #define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ |
| 516 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | 552 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ |
| 517 | CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) | 553 | CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) |
| @@ -593,6 +629,14 @@ | |||
| 593 | GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\ | 629 | GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\ |
| 594 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC | 630 | CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC |
| 595 | 631 | ||
| 632 | #define CONNECTOR_LVDS_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
| 633 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
| 634 | CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT) | ||
| 635 | |||
| 636 | #define CONNECTOR_LVDS_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ | ||
| 637 | GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ | ||
| 638 | CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT) | ||
| 639 | |||
| 596 | /****************************************************/ | 640 | /****************************************************/ |
| 597 | /* Router Object ID definition - Shared with BIOS */ | 641 | /* Router Object ID definition - Shared with BIOS */ |
| 598 | /****************************************************/ | 642 | /****************************************************/ |
| @@ -621,6 +665,10 @@ | |||
| 621 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | 665 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ |
| 622 | GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT) | 666 | GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT) |
| 623 | 667 | ||
| 668 | #define GENERICOBJECT_STEREO_PIN_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ | ||
| 669 | GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ | ||
| 670 | GENERIC_OBJECT_ID_STEREO_PIN << OBJECT_ID_SHIFT) | ||
| 671 | |||
| 624 | /****************************************************/ | 672 | /****************************************************/ |
| 625 | /* Object Cap definition - Shared with BIOS */ | 673 | /* Object Cap definition - Shared with BIOS */ |
| 626 | /****************************************************/ | 674 | /****************************************************/ |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 05efb5b9f13e..258fa5e7a2d9 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
| @@ -734,16 +734,16 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) | |||
| 734 | static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) | 734 | static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) |
| 735 | { | 735 | { |
| 736 | uint8_t attr = U8((*ptr)++); | 736 | uint8_t attr = U8((*ptr)++); |
| 737 | uint32_t dst, src1, src2, saved; | 737 | uint32_t dst, mask, src, saved; |
| 738 | int dptr = *ptr; | 738 | int dptr = *ptr; |
| 739 | SDEBUG(" dst: "); | 739 | SDEBUG(" dst: "); |
| 740 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 740 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
| 741 | SDEBUG(" src1: "); | 741 | mask = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); |
| 742 | src1 = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); | 742 | SDEBUG(" mask: 0x%08x", mask); |
| 743 | SDEBUG(" src2: "); | 743 | SDEBUG(" src: "); |
| 744 | src2 = atom_get_src(ctx, attr, ptr); | 744 | src = atom_get_src(ctx, attr, ptr); |
| 745 | dst &= src1; | 745 | dst &= mask; |
| 746 | dst |= src2; | 746 | dst |= src; |
| 747 | SDEBUG(" dst: "); | 747 | SDEBUG(" dst: "); |
| 748 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); | 748 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); |
| 749 | } | 749 | } |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index fe359a239df3..58a0cd02c0a2 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
| @@ -73,8 +73,18 @@ | |||
| 73 | #define ATOM_PPLL1 0 | 73 | #define ATOM_PPLL1 0 |
| 74 | #define ATOM_PPLL2 1 | 74 | #define ATOM_PPLL2 1 |
| 75 | #define ATOM_DCPLL 2 | 75 | #define ATOM_DCPLL 2 |
| 76 | #define ATOM_PPLL0 2 | ||
| 77 | #define ATOM_EXT_PLL1 8 | ||
| 78 | #define ATOM_EXT_PLL2 9 | ||
| 79 | #define ATOM_EXT_CLOCK 10 | ||
| 76 | #define ATOM_PPLL_INVALID 0xFF | 80 | #define ATOM_PPLL_INVALID 0xFF |
| 77 | 81 | ||
| 82 | #define ENCODER_REFCLK_SRC_P1PLL 0 | ||
| 83 | #define ENCODER_REFCLK_SRC_P2PLL 1 | ||
| 84 | #define ENCODER_REFCLK_SRC_DCPLL 2 | ||
| 85 | #define ENCODER_REFCLK_SRC_EXTCLK 3 | ||
| 86 | #define ENCODER_REFCLK_SRC_INVALID 0xFF | ||
| 87 | |||
| 78 | #define ATOM_SCALER1 0 | 88 | #define ATOM_SCALER1 0 |
| 79 | #define ATOM_SCALER2 1 | 89 | #define ATOM_SCALER2 1 |
| 80 | 90 | ||
| @@ -192,6 +202,9 @@ typedef struct _ATOM_COMMON_TABLE_HEADER | |||
| 192 | /*Image can't be updated, while Driver needs to carry the new table! */ | 202 | /*Image can't be updated, while Driver needs to carry the new table! */ |
| 193 | }ATOM_COMMON_TABLE_HEADER; | 203 | }ATOM_COMMON_TABLE_HEADER; |
| 194 | 204 | ||
| 205 | /****************************************************************************/ | ||
| 206 | // Structure stores the ROM header. | ||
| 207 | /****************************************************************************/ | ||
| 195 | typedef struct _ATOM_ROM_HEADER | 208 | typedef struct _ATOM_ROM_HEADER |
| 196 | { | 209 | { |
| 197 | ATOM_COMMON_TABLE_HEADER sHeader; | 210 | ATOM_COMMON_TABLE_HEADER sHeader; |
| @@ -221,6 +234,9 @@ typedef struct _ATOM_ROM_HEADER | |||
| 221 | #define USHORT void* | 234 | #define USHORT void* |
| 222 | #endif | 235 | #endif |
| 223 | 236 | ||
| 237 | /****************************************************************************/ | ||
| 238 | // Structures used in Command.mtb | ||
| 239 | /****************************************************************************/ | ||
| 224 | typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ | 240 | typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ |
| 225 | USHORT ASIC_Init; //Function Table, used by various SW components,latest version 1.1 | 241 | USHORT ASIC_Init; //Function Table, used by various SW components,latest version 1.1 |
| 226 | USHORT GetDisplaySurfaceSize; //Atomic Table, Used by Bios when enabling HW ICON | 242 | USHORT GetDisplaySurfaceSize; //Atomic Table, Used by Bios when enabling HW ICON |
| @@ -312,6 +328,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ | |||
| 312 | #define SetUniphyInstance ASIC_StaticPwrMgtStatusChange | 328 | #define SetUniphyInstance ASIC_StaticPwrMgtStatusChange |
| 313 | #define HPDInterruptService ReadHWAssistedI2CStatus | 329 | #define HPDInterruptService ReadHWAssistedI2CStatus |
| 314 | #define EnableVGA_Access GetSCLKOverMCLKRatio | 330 | #define EnableVGA_Access GetSCLKOverMCLKRatio |
| 331 | #define GetDispObjectInfo EnableYUV | ||
| 315 | 332 | ||
| 316 | typedef struct _ATOM_MASTER_COMMAND_TABLE | 333 | typedef struct _ATOM_MASTER_COMMAND_TABLE |
| 317 | { | 334 | { |
| @@ -357,6 +374,24 @@ typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER | |||
| 357 | /****************************************************************************/ | 374 | /****************************************************************************/ |
| 358 | #define COMPUTE_MEMORY_PLL_PARAM 1 | 375 | #define COMPUTE_MEMORY_PLL_PARAM 1 |
| 359 | #define COMPUTE_ENGINE_PLL_PARAM 2 | 376 | #define COMPUTE_ENGINE_PLL_PARAM 2 |
| 377 | #define ADJUST_MC_SETTING_PARAM 3 | ||
| 378 | |||
| 379 | /****************************************************************************/ | ||
| 380 | // Structures used by AdjustMemoryControllerTable | ||
| 381 | /****************************************************************************/ | ||
| 382 | typedef struct _ATOM_ADJUST_MEMORY_CLOCK_FREQ | ||
| 383 | { | ||
| 384 | #if ATOM_BIG_ENDIAN | ||
| 385 | ULONG ulPointerReturnFlag:1; // BYTE_3[7]=1 - Return the pointer to the right Data Block; BYTE_3[7]=0 - Program the right Data Block | ||
| 386 | ULONG ulMemoryModuleNumber:7; // BYTE_3[6:0] | ||
| 387 | ULONG ulClockFreq:24; | ||
| 388 | #else | ||
| 389 | ULONG ulClockFreq:24; | ||
| 390 | ULONG ulMemoryModuleNumber:7; // BYTE_3[6:0] | ||
| 391 | ULONG ulPointerReturnFlag:1; // BYTE_3[7]=1 - Return the pointer to the right Data Block; BYTE_3[7]=0 - Program the right Data Block | ||
| 392 | #endif | ||
| 393 | }ATOM_ADJUST_MEMORY_CLOCK_FREQ; | ||
| 394 | #define POINTER_RETURN_FLAG 0x80 | ||
| 360 | 395 | ||
| 361 | typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS | 396 | typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS |
| 362 | { | 397 | { |
| @@ -440,6 +475,26 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 | |||
| 440 | #endif | 475 | #endif |
| 441 | }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4; | 476 | }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4; |
| 442 | 477 | ||
| 478 | typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 | ||
| 479 | { | ||
| 480 | union | ||
| 481 | { | ||
| 482 | ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter | ||
| 483 | ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter | ||
| 484 | }; | ||
| 485 | UCHAR ucRefDiv; //Output Parameter | ||
| 486 | UCHAR ucPostDiv; //Output Parameter | ||
| 487 | union | ||
| 488 | { | ||
| 489 | UCHAR ucCntlFlag; //Output Flags | ||
| 490 | UCHAR ucInputFlag; //Input Flags. ucInputFlag[0] - Strobe(1)/Performance(0) mode | ||
| 491 | }; | ||
| 492 | UCHAR ucReserved; | ||
| 493 | }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5; | ||
| 494 | |||
| 495 | // ucInputFlag | ||
| 496 | #define ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN 1 // 1-StrobeMode, 0-PerformanceMode | ||
| 497 | |||
| 443 | typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER | 498 | typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER |
| 444 | { | 499 | { |
| 445 | ATOM_COMPUTE_CLOCK_FREQ ulClock; | 500 | ATOM_COMPUTE_CLOCK_FREQ ulClock; |
| @@ -583,6 +638,7 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS | |||
| 583 | #define ATOM_ENCODER_CONFIG_DPLINKRATE_MASK 0x01 | 638 | #define ATOM_ENCODER_CONFIG_DPLINKRATE_MASK 0x01 |
| 584 | #define ATOM_ENCODER_CONFIG_DPLINKRATE_1_62GHZ 0x00 | 639 | #define ATOM_ENCODER_CONFIG_DPLINKRATE_1_62GHZ 0x00 |
| 585 | #define ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ 0x01 | 640 | #define ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ 0x01 |
| 641 | #define ATOM_ENCODER_CONFIG_DPLINKRATE_5_40GHZ 0x02 | ||
| 586 | #define ATOM_ENCODER_CONFIG_LINK_SEL_MASK 0x04 | 642 | #define ATOM_ENCODER_CONFIG_LINK_SEL_MASK 0x04 |
| 587 | #define ATOM_ENCODER_CONFIG_LINKA 0x00 | 643 | #define ATOM_ENCODER_CONFIG_LINKA 0x00 |
| 588 | #define ATOM_ENCODER_CONFIG_LINKB 0x04 | 644 | #define ATOM_ENCODER_CONFIG_LINKB 0x04 |
| @@ -608,6 +664,9 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS | |||
| 608 | #define ATOM_ENCODER_MODE_TV 13 | 664 | #define ATOM_ENCODER_MODE_TV 13 |
| 609 | #define ATOM_ENCODER_MODE_CV 14 | 665 | #define ATOM_ENCODER_MODE_CV 14 |
| 610 | #define ATOM_ENCODER_MODE_CRT 15 | 666 | #define ATOM_ENCODER_MODE_CRT 15 |
| 667 | #define ATOM_ENCODER_MODE_DVO 16 | ||
| 668 | #define ATOM_ENCODER_MODE_DP_SST ATOM_ENCODER_MODE_DP // For DP1.2 | ||
| 669 | #define ATOM_ENCODER_MODE_DP_MST 5 // For DP1.2 | ||
| 611 | 670 | ||
| 612 | typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 | 671 | typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 |
| 613 | { | 672 | { |
| @@ -661,6 +720,7 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 | |||
| 661 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_START 0x08 | 720 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_START 0x08 |
| 662 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1 0x09 | 721 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1 0x09 |
| 663 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2 0x0a | 722 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2 0x0a |
| 723 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3 0x13 | ||
| 664 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE 0x0b | 724 | #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE 0x0b |
| 665 | #define ATOM_ENCODER_CMD_DP_VIDEO_OFF 0x0c | 725 | #define ATOM_ENCODER_CMD_DP_VIDEO_OFF 0x0c |
| 666 | #define ATOM_ENCODER_CMD_DP_VIDEO_ON 0x0d | 726 | #define ATOM_ENCODER_CMD_DP_VIDEO_ON 0x0d |
| @@ -671,24 +731,34 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 | |||
| 671 | #define ATOM_ENCODER_STATUS_LINK_TRAINING_COMPLETE 0x10 | 731 | #define ATOM_ENCODER_STATUS_LINK_TRAINING_COMPLETE 0x10 |
| 672 | #define ATOM_ENCODER_STATUS_LINK_TRAINING_INCOMPLETE 0x00 | 732 | #define ATOM_ENCODER_STATUS_LINK_TRAINING_INCOMPLETE 0x00 |
| 673 | 733 | ||
| 734 | //ucTableFormatRevision=1 | ||
| 735 | //ucTableContentRevision=3 | ||
| 674 | // Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver | 736 | // Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver |
| 675 | typedef struct _ATOM_DIG_ENCODER_CONFIG_V3 | 737 | typedef struct _ATOM_DIG_ENCODER_CONFIG_V3 |
| 676 | { | 738 | { |
| 677 | #if ATOM_BIG_ENDIAN | 739 | #if ATOM_BIG_ENDIAN |
| 678 | UCHAR ucReserved1:1; | 740 | UCHAR ucReserved1:1; |
| 679 | UCHAR ucDigSel:3; // =0: DIGA/B/C/D/E/F | 741 | UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) |
| 680 | UCHAR ucReserved:3; | 742 | UCHAR ucReserved:3; |
| 681 | UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz | 743 | UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz |
| 682 | #else | 744 | #else |
| 683 | UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz | 745 | UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz |
| 684 | UCHAR ucReserved:3; | 746 | UCHAR ucReserved:3; |
| 685 | UCHAR ucDigSel:3; // =0: DIGA/B/C/D/E/F | 747 | UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) |
| 686 | UCHAR ucReserved1:1; | 748 | UCHAR ucReserved1:1; |
| 687 | #endif | 749 | #endif |
| 688 | }ATOM_DIG_ENCODER_CONFIG_V3; | 750 | }ATOM_DIG_ENCODER_CONFIG_V3; |
| 689 | 751 | ||
| 752 | #define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03 | ||
| 753 | #define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ 0x00 | ||
| 754 | #define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ 0x01 | ||
| 690 | #define ATOM_ENCODER_CONFIG_V3_ENCODER_SEL 0x70 | 755 | #define ATOM_ENCODER_CONFIG_V3_ENCODER_SEL 0x70 |
| 691 | 756 | #define ATOM_ENCODER_CONFIG_V3_DIG0_ENCODER 0x00 | |
| 757 | #define ATOM_ENCODER_CONFIG_V3_DIG1_ENCODER 0x10 | ||
| 758 | #define ATOM_ENCODER_CONFIG_V3_DIG2_ENCODER 0x20 | ||
| 759 | #define ATOM_ENCODER_CONFIG_V3_DIG3_ENCODER 0x30 | ||
| 760 | #define ATOM_ENCODER_CONFIG_V3_DIG4_ENCODER 0x40 | ||
| 761 | #define ATOM_ENCODER_CONFIG_V3_DIG5_ENCODER 0x50 | ||
| 692 | 762 | ||
| 693 | typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3 | 763 | typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3 |
| 694 | { | 764 | { |
| @@ -707,6 +777,56 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3 | |||
| 707 | UCHAR ucReserved; | 777 | UCHAR ucReserved; |
| 708 | }DIG_ENCODER_CONTROL_PARAMETERS_V3; | 778 | }DIG_ENCODER_CONTROL_PARAMETERS_V3; |
| 709 | 779 | ||
| 780 | //ucTableFormatRevision=1 | ||
| 781 | //ucTableContentRevision=4 | ||
| 782 | // start from NI | ||
| 783 | // Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver | ||
| 784 | typedef struct _ATOM_DIG_ENCODER_CONFIG_V4 | ||
| 785 | { | ||
| 786 | #if ATOM_BIG_ENDIAN | ||
| 787 | UCHAR ucReserved1:1; | ||
| 788 | UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) | ||
| 789 | UCHAR ucReserved:2; | ||
| 790 | UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version | ||
| 791 | #else | ||
| 792 | UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version | ||
| 793 | UCHAR ucReserved:2; | ||
| 794 | UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) | ||
| 795 | UCHAR ucReserved1:1; | ||
| 796 | #endif | ||
| 797 | }ATOM_DIG_ENCODER_CONFIG_V4; | ||
| 798 | |||
| 799 | #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_MASK 0x03 | ||
| 800 | #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ 0x00 | ||
| 801 | #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ 0x01 | ||
| 802 | #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ 0x02 | ||
| 803 | #define ATOM_ENCODER_CONFIG_V4_ENCODER_SEL 0x70 | ||
| 804 | #define ATOM_ENCODER_CONFIG_V4_DIG0_ENCODER 0x00 | ||
| 805 | #define ATOM_ENCODER_CONFIG_V4_DIG1_ENCODER 0x10 | ||
| 806 | #define ATOM_ENCODER_CONFIG_V4_DIG2_ENCODER 0x20 | ||
| 807 | #define ATOM_ENCODER_CONFIG_V4_DIG3_ENCODER 0x30 | ||
| 808 | #define ATOM_ENCODER_CONFIG_V4_DIG4_ENCODER 0x40 | ||
| 809 | #define ATOM_ENCODER_CONFIG_V4_DIG5_ENCODER 0x50 | ||
| 810 | |||
| 811 | typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V4 | ||
| 812 | { | ||
| 813 | USHORT usPixelClock; // in 10KHz; for bios convenient | ||
| 814 | union{ | ||
| 815 | ATOM_DIG_ENCODER_CONFIG_V4 acConfig; | ||
| 816 | UCHAR ucConfig; | ||
| 817 | }; | ||
| 818 | UCHAR ucAction; | ||
| 819 | UCHAR ucEncoderMode; | ||
| 820 | // =0: DP encoder | ||
| 821 | // =1: LVDS encoder | ||
| 822 | // =2: DVI encoder | ||
| 823 | // =3: HDMI encoder | ||
| 824 | // =4: SDVO encoder | ||
| 825 | // =5: DP audio | ||
| 826 | UCHAR ucLaneNum; // how many lanes to enable | ||
| 827 | UCHAR ucBitPerColor; // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP | ||
| 828 | UCHAR ucHPD_ID; // HPD ID (1-6). =0 means to skip HDP programming. New comparing to previous version | ||
| 829 | }DIG_ENCODER_CONTROL_PARAMETERS_V4; | ||
| 710 | 830 | ||
| 711 | // define ucBitPerColor: | 831 | // define ucBitPerColor: |
| 712 | #define PANEL_BPC_UNDEFINE 0x00 | 832 | #define PANEL_BPC_UNDEFINE 0x00 |
| @@ -893,6 +1013,7 @@ typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V3 | |||
| 893 | #endif | 1013 | #endif |
| 894 | }ATOM_DIG_TRANSMITTER_CONFIG_V3; | 1014 | }ATOM_DIG_TRANSMITTER_CONFIG_V3; |
| 895 | 1015 | ||
| 1016 | |||
| 896 | typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 | 1017 | typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 |
| 897 | { | 1018 | { |
| 898 | union | 1019 | union |
| @@ -936,6 +1057,149 @@ typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 | |||
| 936 | #define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER2 0x40 //CD | 1057 | #define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER2 0x40 //CD |
| 937 | #define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER3 0x80 //EF | 1058 | #define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER3 0x80 //EF |
| 938 | 1059 | ||
| 1060 | |||
| 1061 | /****************************************************************************/ | ||
| 1062 | // Structures used by UNIPHYTransmitterControlTable V1.4 | ||
| 1063 | // ASIC Families: NI | ||
| 1064 | // ucTableFormatRevision=1 | ||
| 1065 | // ucTableContentRevision=4 | ||
| 1066 | /****************************************************************************/ | ||
| 1067 | typedef struct _ATOM_DP_VS_MODE_V4 | ||
| 1068 | { | ||
| 1069 | UCHAR ucLaneSel; | ||
| 1070 | union | ||
| 1071 | { | ||
| 1072 | UCHAR ucLaneSet; | ||
| 1073 | struct { | ||
| 1074 | #if ATOM_BIG_ENDIAN | ||
| 1075 | UCHAR ucPOST_CURSOR2:2; //Bit[7:6] Post Cursor2 Level <= New in V4 | ||
| 1076 | UCHAR ucPRE_EMPHASIS:3; //Bit[5:3] Pre-emphasis Level | ||
| 1077 | UCHAR ucVOLTAGE_SWING:3; //Bit[2:0] Voltage Swing Level | ||
| 1078 | #else | ||
| 1079 | UCHAR ucVOLTAGE_SWING:3; //Bit[2:0] Voltage Swing Level | ||
| 1080 | UCHAR ucPRE_EMPHASIS:3; //Bit[5:3] Pre-emphasis Level | ||
| 1081 | UCHAR ucPOST_CURSOR2:2; //Bit[7:6] Post Cursor2 Level <= New in V4 | ||
| 1082 | #endif | ||
| 1083 | }; | ||
| 1084 | }; | ||
| 1085 | }ATOM_DP_VS_MODE_V4; | ||
| 1086 | |||
| 1087 | typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V4 | ||
| 1088 | { | ||
| 1089 | #if ATOM_BIG_ENDIAN | ||
| 1090 | UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) | ||
| 1091 | // =1 Dig Transmitter 2 ( Uniphy CD ) | ||
| 1092 | // =2 Dig Transmitter 3 ( Uniphy EF ) | ||
| 1093 | UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, DCPLL=2, EXT_CLK=3 <= New | ||
| 1094 | UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F | ||
| 1095 | UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E | ||
| 1096 | // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F | ||
| 1097 | UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) | ||
| 1098 | UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector | ||
| 1099 | #else | ||
| 1100 | UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector | ||
| 1101 | UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) | ||
| 1102 | UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E | ||
| 1103 | // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F | ||
| 1104 | UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F | ||
| 1105 | UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, DCPLL=2, EXT_CLK=3 <= New | ||
| 1106 | UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) | ||
| 1107 | // =1 Dig Transmitter 2 ( Uniphy CD ) | ||
| 1108 | // =2 Dig Transmitter 3 ( Uniphy EF ) | ||
| 1109 | #endif | ||
| 1110 | }ATOM_DIG_TRANSMITTER_CONFIG_V4; | ||
| 1111 | |||
| 1112 | typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 | ||
| 1113 | { | ||
| 1114 | union | ||
| 1115 | { | ||
| 1116 | USHORT usPixelClock; // in 10KHz; for bios convenient | ||
| 1117 | USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h | ||
| 1118 | ATOM_DP_VS_MODE_V4 asMode; // DP Voltage swing mode Redefined comparing to previous version | ||
| 1119 | }; | ||
| 1120 | union | ||
| 1121 | { | ||
| 1122 | ATOM_DIG_TRANSMITTER_CONFIG_V4 acConfig; | ||
| 1123 | UCHAR ucConfig; | ||
| 1124 | }; | ||
| 1125 | UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX | ||
| 1126 | UCHAR ucLaneNum; | ||
| 1127 | UCHAR ucReserved[3]; | ||
| 1128 | }DIG_TRANSMITTER_CONTROL_PARAMETERS_V4; | ||
| 1129 | |||
| 1130 | //ucConfig | ||
| 1131 | //Bit0 | ||
| 1132 | #define ATOM_TRANSMITTER_CONFIG_V4_DUAL_LINK_CONNECTOR 0x01 | ||
| 1133 | //Bit1 | ||
| 1134 | #define ATOM_TRANSMITTER_CONFIG_V4_COHERENT 0x02 | ||
| 1135 | //Bit2 | ||
| 1136 | #define ATOM_TRANSMITTER_CONFIG_V4_LINK_SEL_MASK 0x04 | ||
| 1137 | #define ATOM_TRANSMITTER_CONFIG_V4_LINKA 0x00 | ||
| 1138 | #define ATOM_TRANSMITTER_CONFIG_V4_LINKB 0x04 | ||
| 1139 | // Bit3 | ||
| 1140 | #define ATOM_TRANSMITTER_CONFIG_V4_ENCODER_SEL_MASK 0x08 | ||
| 1141 | #define ATOM_TRANSMITTER_CONFIG_V4_DIG1_ENCODER 0x00 | ||
| 1142 | #define ATOM_TRANSMITTER_CONFIG_V4_DIG2_ENCODER 0x08 | ||
| 1143 | // Bit5:4 | ||
| 1144 | #define ATOM_TRANSMITTER_CONFIG_V4_REFCLK_SEL_MASK 0x30 | ||
| 1145 | #define ATOM_TRANSMITTER_CONFIG_V4_P1PLL 0x00 | ||
| 1146 | #define ATOM_TRANSMITTER_CONFIG_V4_P2PLL 0x10 | ||
| 1147 | #define ATOM_TRANSMITTER_CONFIG_V4_DCPLL 0x20 // New in _V4 | ||
| 1148 | #define ATOM_TRANSMITTER_CONFIG_V4_REFCLK_SRC_EXT 0x30 // Changed comparing to V3 | ||
| 1149 | // Bit7:6 | ||
| 1150 | #define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER_SEL_MASK 0xC0 | ||
| 1151 | #define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER1 0x00 //AB | ||
| 1152 | #define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER2 0x40 //CD | ||
| 1153 | #define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER3 0x80 //EF | ||
| 1154 | |||
| 1155 | |||
| 1156 | /****************************************************************************/ | ||
| 1157 | // Structures used by ExternalEncoderControlTable V1.3 | ||
| 1158 | // ASIC Families: Evergreen, Llano, NI | ||
| 1159 | // ucTableFormatRevision=1 | ||
| 1160 | // ucTableContentRevision=3 | ||
| 1161 | /****************************************************************************/ | ||
| 1162 | |||
| 1163 | typedef struct _EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 | ||
| 1164 | { | ||
| 1165 | union{ | ||
| 1166 | USHORT usPixelClock; // pixel clock in 10Khz, valid when ucAction=SETUP/ENABLE_OUTPUT | ||
| 1167 | USHORT usConnectorId; // connector id, valid when ucAction = INIT | ||
| 1168 | }; | ||
| 1169 | UCHAR ucConfig; // indicate which encoder, and DP link rate when ucAction = SETUP/ENABLE_OUTPUT | ||
| 1170 | UCHAR ucAction; // | ||
| 1171 | UCHAR ucEncoderMode; // encoder mode, only used when ucAction = SETUP/ENABLE_OUTPUT | ||
| 1172 | UCHAR ucLaneNum; // lane number, only used when ucAction = SETUP/ENABLE_OUTPUT | ||
| 1173 | UCHAR ucBitPerColor; // output bit per color, only valid when ucAction = SETUP/ENABLE_OUTPUT and ucEncodeMode= DP | ||
| 1174 | UCHAR ucReserved; | ||
| 1175 | }EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3; | ||
| 1176 | |||
| 1177 | // ucAction | ||
| 1178 | #define EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT 0x00 | ||
| 1179 | #define EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT 0x01 | ||
| 1180 | #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT 0x07 | ||
| 1181 | #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP 0x0f | ||
| 1182 | #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF 0x10 | ||
| 1183 | #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING 0x11 | ||
| 1184 | #define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION 0x12 | ||
| 1185 | |||
| 1186 | // ucConfig | ||
| 1187 | #define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03 | ||
| 1188 | #define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ 0x00 | ||
| 1189 | #define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ 0x01 | ||
| 1190 | #define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ 0x02 | ||
| 1191 | #define EXTERNAL_ENCODER_CONFIG_V3_ENCODER_SEL_MASK 0x70 | ||
| 1192 | #define EXTERNAL_ENCODER_CONFIG_V3_ENCODER1 0x00 | ||
| 1193 | #define EXTERNAL_ENCODER_CONFIG_V3_ENCODER2 0x10 | ||
| 1194 | #define EXTERNAL_ENCODER_CONFIG_V3_ENCODER3 0x20 | ||
| 1195 | |||
| 1196 | typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 | ||
| 1197 | { | ||
| 1198 | EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 sExtEncoder; | ||
| 1199 | ULONG ulReserved[2]; | ||
| 1200 | }EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3; | ||
| 1201 | |||
| 1202 | |||
| 939 | /****************************************************************************/ | 1203 | /****************************************************************************/ |
| 940 | // Structures used by DAC1OuputControlTable | 1204 | // Structures used by DAC1OuputControlTable |
| 941 | // DAC2OuputControlTable | 1205 | // DAC2OuputControlTable |
| @@ -1142,6 +1406,7 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V2 | |||
| 1142 | #define PIXEL_CLOCK_V4_MISC_SS_ENABLE 0x10 | 1406 | #define PIXEL_CLOCK_V4_MISC_SS_ENABLE 0x10 |
| 1143 | #define PIXEL_CLOCK_V4_MISC_COHERENT_MODE 0x20 | 1407 | #define PIXEL_CLOCK_V4_MISC_COHERENT_MODE 0x20 |
| 1144 | 1408 | ||
| 1409 | |||
| 1145 | typedef struct _PIXEL_CLOCK_PARAMETERS_V3 | 1410 | typedef struct _PIXEL_CLOCK_PARAMETERS_V3 |
| 1146 | { | 1411 | { |
| 1147 | USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) | 1412 | USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) |
| @@ -1202,6 +1467,55 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V5 | |||
| 1202 | #define PIXEL_CLOCK_V5_MISC_HDMI_32BPP 0x08 | 1467 | #define PIXEL_CLOCK_V5_MISC_HDMI_32BPP 0x08 |
| 1203 | #define PIXEL_CLOCK_V5_MISC_REF_DIV_SRC 0x10 | 1468 | #define PIXEL_CLOCK_V5_MISC_REF_DIV_SRC 0x10 |
| 1204 | 1469 | ||
| 1470 | typedef struct _CRTC_PIXEL_CLOCK_FREQ | ||
| 1471 | { | ||
| 1472 | #if ATOM_BIG_ENDIAN | ||
| 1473 | ULONG ucCRTC:8; // ATOM_CRTC1~6, indicate the CRTC controller to | ||
| 1474 | // drive the pixel clock. not used for DCPLL case. | ||
| 1475 | ULONG ulPixelClock:24; // target the pixel clock to drive the CRTC timing. | ||
| 1476 | // 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to previous version. | ||
| 1477 | #else | ||
| 1478 | ULONG ulPixelClock:24; // target the pixel clock to drive the CRTC timing. | ||
| 1479 | // 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to previous version. | ||
| 1480 | ULONG ucCRTC:8; // ATOM_CRTC1~6, indicate the CRTC controller to | ||
| 1481 | // drive the pixel clock. not used for DCPLL case. | ||
| 1482 | #endif | ||
| 1483 | }CRTC_PIXEL_CLOCK_FREQ; | ||
| 1484 | |||
| 1485 | typedef struct _PIXEL_CLOCK_PARAMETERS_V6 | ||
| 1486 | { | ||
| 1487 | union{ | ||
| 1488 | CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; // pixel clock and CRTC id frequency | ||
| 1489 | ULONG ulDispEngClkFreq; // dispclk frequency | ||
| 1490 | }; | ||
| 1491 | USHORT usFbDiv; // feedback divider integer part. | ||
| 1492 | UCHAR ucPostDiv; // post divider. | ||
| 1493 | UCHAR ucRefDiv; // Reference divider | ||
| 1494 | UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2/ATOM_DCPLL | ||
| 1495 | UCHAR ucTransmitterID; // ASIC encoder id defined in objectId.h, | ||
| 1496 | // indicate which graphic encoder will be used. | ||
| 1497 | UCHAR ucEncoderMode; // Encoder mode: | ||
| 1498 | UCHAR ucMiscInfo; // bit[0]= Force program PPLL | ||
| 1499 | // bit[1]= when VGA timing is used. | ||
| 1500 | // bit[3:2]= HDMI panel bit depth: =0: 24bpp =1:30bpp, =2:32bpp | ||
| 1501 | // bit[4]= RefClock source for PPLL. | ||
| 1502 | // =0: XTLAIN( default mode ) | ||
| 1503 | // =1: other external clock source, which is pre-defined | ||
| 1504 | // by VBIOS depend on the feature required. | ||
| 1505 | // bit[7:5]: reserved. | ||
| 1506 | ULONG ulFbDivDecFrac; // 20 bit feedback divider decimal fraction part, range from 1~999999 ( 0.000001 to 0.999999 ) | ||
| 1507 | |||
| 1508 | }PIXEL_CLOCK_PARAMETERS_V6; | ||
| 1509 | |||
| 1510 | #define PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL 0x01 | ||
| 1511 | #define PIXEL_CLOCK_V6_MISC_VGA_MODE 0x02 | ||
| 1512 | #define PIXEL_CLOCK_V6_MISC_HDMI_BPP_MASK 0x0c | ||
| 1513 | #define PIXEL_CLOCK_V6_MISC_HDMI_24BPP 0x00 | ||
| 1514 | #define PIXEL_CLOCK_V6_MISC_HDMI_36BPP 0x04 | ||
| 1515 | #define PIXEL_CLOCK_V6_MISC_HDMI_30BPP 0x08 | ||
| 1516 | #define PIXEL_CLOCK_V6_MISC_HDMI_48BPP 0x0c | ||
| 1517 | #define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC 0x10 | ||
| 1518 | |||
| 1205 | typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2 | 1519 | typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2 |
| 1206 | { | 1520 | { |
| 1207 | PIXEL_CLOCK_PARAMETERS_V3 sDispClkInput; | 1521 | PIXEL_CLOCK_PARAMETERS_V3 sDispClkInput; |
| @@ -1241,10 +1555,11 @@ typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS | |||
| 1241 | typedef struct _ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3 | 1555 | typedef struct _ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3 |
| 1242 | { | 1556 | { |
| 1243 | USHORT usPixelClock; // target pixel clock | 1557 | USHORT usPixelClock; // target pixel clock |
| 1244 | UCHAR ucTransmitterID; // transmitter id defined in objectid.h | 1558 | UCHAR ucTransmitterID; // GPU transmitter id defined in objectid.h |
| 1245 | UCHAR ucEncodeMode; // encoder mode: CRT, LVDS, DP, TMDS or HDMI | 1559 | UCHAR ucEncodeMode; // encoder mode: CRT, LVDS, DP, TMDS or HDMI |
| 1246 | UCHAR ucDispPllConfig; // display pll configure parameter defined as following DISPPLL_CONFIG_XXXX | 1560 | UCHAR ucDispPllConfig; // display pll configure parameter defined as following DISPPLL_CONFIG_XXXX |
| 1247 | UCHAR ucReserved[3]; | 1561 | UCHAR ucExtTransmitterID; // external encoder id. |
| 1562 | UCHAR ucReserved[2]; | ||
| 1248 | }ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3; | 1563 | }ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3; |
| 1249 | 1564 | ||
| 1250 | // usDispPllConfig v1.2 for RoadRunner | 1565 | // usDispPllConfig v1.2 for RoadRunner |
| @@ -1358,6 +1673,7 @@ typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS | |||
| 1358 | /**************************************************************************/ | 1673 | /**************************************************************************/ |
| 1359 | #define SPEED_FAN_CONTROL_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS | 1674 | #define SPEED_FAN_CONTROL_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS |
| 1360 | 1675 | ||
| 1676 | |||
| 1361 | /****************************************************************************/ | 1677 | /****************************************************************************/ |
| 1362 | // Structures used by PowerConnectorDetectionTable | 1678 | // Structures used by PowerConnectorDetectionTable |
| 1363 | /****************************************************************************/ | 1679 | /****************************************************************************/ |
| @@ -1438,6 +1754,31 @@ typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 | |||
| 1438 | #define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK 0x0F00 | 1754 | #define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK 0x0F00 |
| 1439 | #define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT 8 | 1755 | #define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT 8 |
| 1440 | 1756 | ||
| 1757 | // Used by DCE5.0 | ||
| 1758 | typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 | ||
| 1759 | { | ||
| 1760 | USHORT usSpreadSpectrumAmountFrac; // SS_AMOUNT_DSFRAC New in DCE5.0 | ||
| 1761 | UCHAR ucSpreadSpectrumType; // Bit[0]: 0-Down Spread,1-Center Spread. | ||
| 1762 | // Bit[1]: 1-Ext. 0-Int. | ||
| 1763 | // Bit[3:2]: =0 P1PLL =1 P2PLL =2 DCPLL | ||
| 1764 | // Bits[7:4] reserved | ||
| 1765 | UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE | ||
| 1766 | USHORT usSpreadSpectrumAmount; // Includes SS_AMOUNT_FBDIV[7:0] and SS_AMOUNT_NFRAC_SLIP[11:8] | ||
| 1767 | USHORT usSpreadSpectrumStep; // SS_STEP_SIZE_DSFRAC | ||
| 1768 | }ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3; | ||
| 1769 | |||
| 1770 | #define ATOM_PPLL_SS_TYPE_V3_DOWN_SPREAD 0x00 | ||
| 1771 | #define ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD 0x01 | ||
| 1772 | #define ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD 0x02 | ||
| 1773 | #define ATOM_PPLL_SS_TYPE_V3_PPLL_SEL_MASK 0x0c | ||
| 1774 | #define ATOM_PPLL_SS_TYPE_V3_P1PLL 0x00 | ||
| 1775 | #define ATOM_PPLL_SS_TYPE_V3_P2PLL 0x04 | ||
| 1776 | #define ATOM_PPLL_SS_TYPE_V3_DCPLL 0x08 | ||
| 1777 | #define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK 0x00FF | ||
| 1778 | #define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT 0 | ||
| 1779 | #define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK 0x0F00 | ||
| 1780 | #define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT 8 | ||
| 1781 | |||
| 1441 | #define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION ENABLE_SPREAD_SPECTRUM_ON_PPLL | 1782 | #define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION ENABLE_SPREAD_SPECTRUM_ON_PPLL |
| 1442 | 1783 | ||
| 1443 | /**************************************************************************/ | 1784 | /**************************************************************************/ |
| @@ -1706,7 +2047,7 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES | |||
| 1706 | USHORT StandardVESA_Timing; // Only used by Bios | 2047 | USHORT StandardVESA_Timing; // Only used by Bios |
| 1707 | USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 | 2048 | USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 |
| 1708 | USHORT DAC_Info; // Will be obsolete from R600 | 2049 | USHORT DAC_Info; // Will be obsolete from R600 |
| 1709 | USHORT LVDS_Info; // Shared by various SW components,latest version 1.1 | 2050 | USHORT LCD_Info; // Shared by various SW components,latest version 1.3, was called LVDS_Info |
| 1710 | USHORT TMDS_Info; // Will be obsolete from R600 | 2051 | USHORT TMDS_Info; // Will be obsolete from R600 |
| 1711 | USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 | 2052 | USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 |
| 1712 | USHORT SupportedDevicesInfo; // Will be obsolete from R600 | 2053 | USHORT SupportedDevicesInfo; // Will be obsolete from R600 |
| @@ -1736,12 +2077,16 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES | |||
| 1736 | USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 | 2077 | USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 |
| 1737 | }ATOM_MASTER_LIST_OF_DATA_TABLES; | 2078 | }ATOM_MASTER_LIST_OF_DATA_TABLES; |
| 1738 | 2079 | ||
| 2080 | // For backward compatible | ||
| 2081 | #define LVDS_Info LCD_Info | ||
| 2082 | |||
| 1739 | typedef struct _ATOM_MASTER_DATA_TABLE | 2083 | typedef struct _ATOM_MASTER_DATA_TABLE |
| 1740 | { | 2084 | { |
| 1741 | ATOM_COMMON_TABLE_HEADER sHeader; | 2085 | ATOM_COMMON_TABLE_HEADER sHeader; |
| 1742 | ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; | 2086 | ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; |
| 1743 | }ATOM_MASTER_DATA_TABLE; | 2087 | }ATOM_MASTER_DATA_TABLE; |
| 1744 | 2088 | ||
| 2089 | |||
| 1745 | /****************************************************************************/ | 2090 | /****************************************************************************/ |
| 1746 | // Structure used in MultimediaCapabilityInfoTable | 2091 | // Structure used in MultimediaCapabilityInfoTable |
| 1747 | /****************************************************************************/ | 2092 | /****************************************************************************/ |
| @@ -1776,6 +2121,7 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO | |||
| 1776 | UCHAR ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) | 2121 | UCHAR ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) |
| 1777 | }ATOM_MULTIMEDIA_CONFIG_INFO; | 2122 | }ATOM_MULTIMEDIA_CONFIG_INFO; |
| 1778 | 2123 | ||
| 2124 | |||
| 1779 | /****************************************************************************/ | 2125 | /****************************************************************************/ |
| 1780 | // Structures used in FirmwareInfoTable | 2126 | // Structures used in FirmwareInfoTable |
| 1781 | /****************************************************************************/ | 2127 | /****************************************************************************/ |
| @@ -2031,8 +2377,47 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_1 | |||
| 2031 | UCHAR ucReserved4[3]; | 2377 | UCHAR ucReserved4[3]; |
| 2032 | }ATOM_FIRMWARE_INFO_V2_1; | 2378 | }ATOM_FIRMWARE_INFO_V2_1; |
| 2033 | 2379 | ||
| 2380 | //the structure below to be used from NI | ||
| 2381 | //ucTableFormatRevision=2 | ||
| 2382 | //ucTableContentRevision=2 | ||
| 2383 | typedef struct _ATOM_FIRMWARE_INFO_V2_2 | ||
| 2384 | { | ||
| 2385 | ATOM_COMMON_TABLE_HEADER sHeader; | ||
| 2386 | ULONG ulFirmwareRevision; | ||
| 2387 | ULONG ulDefaultEngineClock; //In 10Khz unit | ||
| 2388 | ULONG ulDefaultMemoryClock; //In 10Khz unit | ||
| 2389 | ULONG ulReserved[2]; | ||
| 2390 | ULONG ulReserved1; //Was ulMaxEngineClockPLL_Output; //In 10Khz unit* | ||
| 2391 | ULONG ulReserved2; //Was ulMaxMemoryClockPLL_Output; //In 10Khz unit* | ||
| 2392 | ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit | ||
| 2393 | ULONG ulBinaryAlteredInfo; //Was ulASICMaxEngineClock ? | ||
| 2394 | ULONG ulDefaultDispEngineClkFreq; //In 10Khz unit. This is the frequency before DCDTO, corresponding to usBootUpVDDCVoltage. | ||
| 2395 | UCHAR ucReserved3; //Was ucASICMaxTemperature; | ||
| 2396 | UCHAR ucMinAllowedBL_Level; | ||
| 2397 | USHORT usBootUpVDDCVoltage; //In MV unit | ||
| 2398 | USHORT usLcdMinPixelClockPLL_Output; // In MHz unit | ||
| 2399 | USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit | ||
| 2400 | ULONG ulReserved4; //Was ulAsicMaximumVoltage | ||
| 2401 | ULONG ulMinPixelClockPLL_Output; //In 10Khz unit | ||
| 2402 | ULONG ulReserved5; //Was usMinEngineClockPLL_Input and usMaxEngineClockPLL_Input | ||
| 2403 | ULONG ulReserved6; //Was usMinEngineClockPLL_Output and usMinMemoryClockPLL_Input | ||
| 2404 | ULONG ulReserved7; //Was usMaxMemoryClockPLL_Input and usMinMemoryClockPLL_Output | ||
| 2405 | USHORT usReserved11; //Was usMaxPixelClock; //In 10Khz unit, Max. Pclk used only for DAC | ||
| 2406 | USHORT usMinPixelClockPLL_Input; //In 10Khz unit | ||
| 2407 | USHORT usMaxPixelClockPLL_Input; //In 10Khz unit | ||
| 2408 | USHORT usBootUpVDDCIVoltage; //In unit of mv; Was usMinPixelClockPLL_Output; | ||
| 2409 | ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; | ||
| 2410 | USHORT usCoreReferenceClock; //In 10Khz unit | ||
| 2411 | USHORT usMemoryReferenceClock; //In 10Khz unit | ||
| 2412 | USHORT usUniphyDPModeExtClkFreq; //In 10Khz unit, if it is 0, In DP Mode Uniphy Input clock from internal PPLL, otherwise Input clock from external Spread clock | ||
| 2413 | UCHAR ucMemoryModule_ID; //Indicate what is the board design | ||
| 2414 | UCHAR ucReserved9[3]; | ||
| 2415 | USHORT usBootUpMVDDCVoltage; //In unit of mv; Was usMinPixelClockPLL_Output; | ||
| 2416 | USHORT usReserved12; | ||
| 2417 | ULONG ulReserved10[3]; // New added comparing to previous version | ||
| 2418 | }ATOM_FIRMWARE_INFO_V2_2; | ||
| 2034 | 2419 | ||
| 2035 | #define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_1 | 2420 | #define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_2 |
| 2036 | 2421 | ||
| 2037 | /****************************************************************************/ | 2422 | /****************************************************************************/ |
| 2038 | // Structures used in IntegratedSystemInfoTable | 2423 | // Structures used in IntegratedSystemInfoTable |
| @@ -2212,7 +2597,7 @@ ulDockingPinCFGInfo: [15:0]-Bus/Device/Function # to CFG to read this Docking Pi | |||
| 2212 | ucDockingPinBit: which bit in this register to read the pin status; | 2597 | ucDockingPinBit: which bit in this register to read the pin status; |
| 2213 | ucDockingPinPolarity:Polarity of the pin when docked; | 2598 | ucDockingPinPolarity:Polarity of the pin when docked; |
| 2214 | 2599 | ||
| 2215 | ulCPUCapInfo: [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, other bits reserved for now and must be 0x0 | 2600 | ulCPUCapInfo: [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, [7:0]=4:Pharaoh, other bits reserved for now and must be 0x0 |
| 2216 | 2601 | ||
| 2217 | usNumberOfCyclesInPeriod:Indicate how many cycles when PWM duty is 100%. | 2602 | usNumberOfCyclesInPeriod:Indicate how many cycles when PWM duty is 100%. |
| 2218 | 2603 | ||
| @@ -2250,6 +2635,14 @@ usMinUpStreamHTLinkWidth: Asymmetric link width support in the future, to rep | |||
| 2250 | usMinDownStreamHTLinkWidth: same as above. | 2635 | usMinDownStreamHTLinkWidth: same as above. |
| 2251 | */ | 2636 | */ |
| 2252 | 2637 | ||
| 2638 | // ATOM_INTEGRATED_SYSTEM_INFO::ulCPUCapInfo - CPU type definition | ||
| 2639 | #define INTEGRATED_SYSTEM_INFO__UNKNOWN_CPU 0 | ||
| 2640 | #define INTEGRATED_SYSTEM_INFO__AMD_CPU__GRIFFIN 1 | ||
| 2641 | #define INTEGRATED_SYSTEM_INFO__AMD_CPU__GREYHOUND 2 | ||
| 2642 | #define INTEGRATED_SYSTEM_INFO__AMD_CPU__K8 3 | ||
| 2643 | #define INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH 4 | ||
| 2644 | |||
| 2645 | #define INTEGRATED_SYSTEM_INFO__AMD_CPU__MAX_CODE INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH // this deff reflects max defined CPU code | ||
| 2253 | 2646 | ||
| 2254 | #define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001 | 2647 | #define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001 |
| 2255 | #define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002 | 2648 | #define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002 |
| @@ -2778,8 +3171,88 @@ typedef struct _ATOM_LVDS_INFO_V12 | |||
| 2778 | #define PANEL_RANDOM_DITHER 0x80 | 3171 | #define PANEL_RANDOM_DITHER 0x80 |
| 2779 | #define PANEL_RANDOM_DITHER_MASK 0x80 | 3172 | #define PANEL_RANDOM_DITHER_MASK 0x80 |
| 2780 | 3173 | ||
| 3174 | #define ATOM_LVDS_INFO_LAST ATOM_LVDS_INFO_V12 // no need to change this | ||
| 3175 | |||
| 3176 | /****************************************************************************/ | ||
| 3177 | // Structures used by LCD_InfoTable V1.3 Note: previous version was called ATOM_LVDS_INFO_V12 | ||
| 3178 | // ASIC Families: NI | ||
| 3179 | // ucTableFormatRevision=1 | ||
| 3180 | // ucTableContentRevision=3 | ||
| 3181 | /****************************************************************************/ | ||
| 3182 | typedef struct _ATOM_LCD_INFO_V13 | ||
| 3183 | { | ||
| 3184 | ATOM_COMMON_TABLE_HEADER sHeader; | ||
| 3185 | ATOM_DTD_FORMAT sLCDTiming; | ||
| 3186 | USHORT usExtInfoTableOffset; | ||
| 3187 | USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. | ||
| 3188 | ULONG ulReserved0; | ||
| 3189 | UCHAR ucLCD_Misc; // Reorganized in V13 | ||
| 3190 | // Bit0: {=0:single, =1:dual}, | ||
| 3191 | // Bit1: {=0:LDI format for RGB888, =1 FPDI format for RGB888} // was {=0:666RGB, =1:888RGB}, | ||
| 3192 | // Bit3:2: {Grey level} | ||
| 3193 | // Bit6:4 Color Bit Depth definition (see below definition in EDID V1.4 @BYTE 14h) | ||
| 3194 | // Bit7 Reserved. was for ATOM_PANEL_MISC_API_ENABLED, still need it? | ||
| 3195 | UCHAR ucPanelDefaultRefreshRate; | ||
| 3196 | UCHAR ucPanelIdentification; | ||
| 3197 | UCHAR ucSS_Id; | ||
| 3198 | USHORT usLCDVenderID; | ||
| 3199 | USHORT usLCDProductID; | ||
| 3200 | UCHAR ucLCDPanel_SpecialHandlingCap; // Reorganized in V13 | ||
| 3201 | // Bit0: Once DAL sees this CAP is set, it will read EDID from LCD on its own | ||
| 3202 | // Bit1: See LCDPANEL_CAP_DRR_SUPPORTED | ||
| 3203 | // Bit2: a quick reference whether an embadded panel (LCD1 ) is LVDS (0) or eDP (1) | ||
| 3204 | // Bit7-3: Reserved | ||
| 3205 | UCHAR ucPanelInfoSize; // start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable | ||
| 3206 | USHORT usBacklightPWM; // Backlight PWM in Hz. New in _V13 | ||
| 3207 | |||
| 3208 | UCHAR ucPowerSequenceDIGONtoDE_in4Ms; | ||
| 3209 | UCHAR ucPowerSequenceDEtoVARY_BL_in4Ms; | ||
| 3210 | UCHAR ucPowerSequenceDEtoDIGON_in4Ms; | ||
| 3211 | UCHAR ucPowerSequenceVARY_BLtoDE_in4Ms; | ||
| 3212 | |||
| 3213 | UCHAR ucOffDelay_in4Ms; | ||
| 3214 | UCHAR ucPowerSequenceVARY_BLtoBLON_in4Ms; | ||
| 3215 | UCHAR ucPowerSequenceBLONtoVARY_BL_in4Ms; | ||
| 3216 | UCHAR ucReserved1; | ||
| 3217 | |||
| 3218 | ULONG ulReserved[4]; | ||
| 3219 | }ATOM_LCD_INFO_V13; | ||
| 3220 | |||
| 3221 | #define ATOM_LCD_INFO_LAST ATOM_LCD_INFO_V13 | ||
| 3222 | |||
| 3223 | //Definitions for ucLCD_Misc | ||
| 3224 | #define ATOM_PANEL_MISC_V13_DUAL 0x00000001 | ||
| 3225 | #define ATOM_PANEL_MISC_V13_FPDI 0x00000002 | ||
| 3226 | #define ATOM_PANEL_MISC_V13_GREY_LEVEL 0x0000000C | ||
| 3227 | #define ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT 2 | ||
| 3228 | #define ATOM_PANEL_MISC_V13_COLOR_BIT_DEPTH_MASK 0x70 | ||
| 3229 | #define ATOM_PANEL_MISC_V13_6BIT_PER_COLOR 0x10 | ||
| 3230 | #define ATOM_PANEL_MISC_V13_8BIT_PER_COLOR 0x20 | ||
| 3231 | |||
| 3232 | //Color Bit Depth definition in EDID V1.4 @BYTE 14h | ||
| 3233 | //Bit 6 5 4 | ||
| 3234 | // 0 0 0 - Color bit depth is undefined | ||
| 3235 | // 0 0 1 - 6 Bits per Primary Color | ||
| 3236 | // 0 1 0 - 8 Bits per Primary Color | ||
| 3237 | // 0 1 1 - 10 Bits per Primary Color | ||
| 3238 | // 1 0 0 - 12 Bits per Primary Color | ||
| 3239 | // 1 0 1 - 14 Bits per Primary Color | ||
| 3240 | // 1 1 0 - 16 Bits per Primary Color | ||
| 3241 | // 1 1 1 - Reserved | ||
| 3242 | |||
| 3243 | //Definitions for ucLCDPanel_SpecialHandlingCap: | ||
| 3244 | |||
| 3245 | //Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. | ||
| 3246 | //Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL | ||
| 3247 | #define LCDPANEL_CAP_V13_READ_EDID 0x1 // = LCDPANEL_CAP_READ_EDID no change comparing to previous version | ||
| 3248 | |||
| 3249 | //If a design supports DRR (dynamic refresh rate) on internal panels (LVDS or EDP), this cap is set in ucLCDPanel_SpecialHandlingCap together | ||
| 3250 | //with multiple supported refresh rates@usSupportedRefreshRate. This cap should not be set when only slow refresh rate is supported (static | ||
| 3251 | //refresh rate switch by SW. This is only valid from ATOM_LVDS_INFO_V12 | ||
| 3252 | #define LCDPANEL_CAP_V13_DRR_SUPPORTED 0x2 // = LCDPANEL_CAP_DRR_SUPPORTED no change comparing to previous version | ||
| 2781 | 3253 | ||
| 2782 | #define ATOM_LVDS_INFO_LAST ATOM_LVDS_INFO_V12 | 3254 | //Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP. |
| 3255 | #define LCDPANEL_CAP_V13_eDP 0x4 // = LCDPANEL_CAP_eDP no change comparing to previous version | ||
| 2783 | 3256 | ||
| 2784 | typedef struct _ATOM_PATCH_RECORD_MODE | 3257 | typedef struct _ATOM_PATCH_RECORD_MODE |
| 2785 | { | 3258 | { |
| @@ -2944,9 +3417,9 @@ typedef struct _ATOM_DPCD_INFO | |||
| 2944 | #define MAX_DTD_MODE_IN_VRAM 6 | 3417 | #define MAX_DTD_MODE_IN_VRAM 6 |
| 2945 | #define ATOM_DTD_MODE_SUPPORT_TBL_SIZE (MAX_DTD_MODE_IN_VRAM*28) //28= (SIZEOF ATOM_DTD_FORMAT) | 3418 | #define ATOM_DTD_MODE_SUPPORT_TBL_SIZE (MAX_DTD_MODE_IN_VRAM*28) //28= (SIZEOF ATOM_DTD_FORMAT) |
| 2946 | #define ATOM_STD_MODE_SUPPORT_TBL_SIZE 32*8 //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) | 3419 | #define ATOM_STD_MODE_SUPPORT_TBL_SIZE 32*8 //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) |
| 2947 | #define DFP_ENCODER_TYPE_OFFSET 0x80 | 3420 | //20 bytes for Encoder Type and DPCD in STD EDID area |
| 2948 | #define DP_ENCODER_LANE_NUM_OFFSET 0x84 | 3421 | #define DFP_ENCODER_TYPE_OFFSET (ATOM_EDID_RAW_DATASIZE + ATOM_DTD_MODE_SUPPORT_TBL_SIZE + ATOM_STD_MODE_SUPPORT_TBL_SIZE - 20) |
| 2949 | #define DP_ENCODER_LINK_RATE_OFFSET 0x88 | 3422 | #define ATOM_DP_DPCD_OFFSET (DFP_ENCODER_TYPE_OFFSET + 4 ) |
| 2950 | 3423 | ||
| 2951 | #define ATOM_HWICON1_SURFACE_ADDR 0 | 3424 | #define ATOM_HWICON1_SURFACE_ADDR 0 |
| 2952 | #define ATOM_HWICON2_SURFACE_ADDR (ATOM_HWICON1_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE) | 3425 | #define ATOM_HWICON2_SURFACE_ADDR (ATOM_HWICON1_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE) |
| @@ -2997,14 +3470,16 @@ typedef struct _ATOM_DPCD_INFO | |||
| 2997 | #define ATOM_DFP5_DTD_MODE_TBL_ADDR (ATOM_DFP5_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) | 3470 | #define ATOM_DFP5_DTD_MODE_TBL_ADDR (ATOM_DFP5_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) |
| 2998 | #define ATOM_DFP5_STD_MODE_TBL_ADDR (ATOM_DFP5_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) | 3471 | #define ATOM_DFP5_STD_MODE_TBL_ADDR (ATOM_DFP5_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) |
| 2999 | 3472 | ||
| 3000 | #define ATOM_DP_TRAINING_TBL_ADDR (ATOM_DFP5_STD_MODE_TBL_ADDR+ATOM_STD_MODE_SUPPORT_TBL_SIZE) | 3473 | #define ATOM_DP_TRAINING_TBL_ADDR (ATOM_DFP5_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) |
| 3001 | 3474 | ||
| 3002 | #define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR+256) | 3475 | #define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR + 1024) |
| 3003 | #define ATOM_STACK_STORAGE_END ATOM_STACK_STORAGE_START+512 | 3476 | #define ATOM_STACK_STORAGE_END ATOM_STACK_STORAGE_START + 512 |
| 3004 | 3477 | ||
| 3005 | //The size below is in Kb! | 3478 | //The size below is in Kb! |
| 3006 | #define ATOM_VRAM_RESERVE_SIZE ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC) | 3479 | #define ATOM_VRAM_RESERVE_SIZE ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC) |
| 3007 | 3480 | ||
| 3481 | #define ATOM_VRAM_RESERVE_V2_SIZE 32 | ||
| 3482 | |||
| 3008 | #define ATOM_VRAM_OPERATION_FLAGS_MASK 0xC0000000L | 3483 | #define ATOM_VRAM_OPERATION_FLAGS_MASK 0xC0000000L |
| 3009 | #define ATOM_VRAM_OPERATION_FLAGS_SHIFT 30 | 3484 | #define ATOM_VRAM_OPERATION_FLAGS_SHIFT 30 |
| 3010 | #define ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION 0x1 | 3485 | #define ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION 0x1 |
| @@ -3206,6 +3681,15 @@ typedef struct _ATOM_DISPLAY_OBJECT_PATH | |||
| 3206 | USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. | 3681 | USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. |
| 3207 | }ATOM_DISPLAY_OBJECT_PATH; | 3682 | }ATOM_DISPLAY_OBJECT_PATH; |
| 3208 | 3683 | ||
| 3684 | typedef struct _ATOM_DISPLAY_EXTERNAL_OBJECT_PATH | ||
| 3685 | { | ||
| 3686 | USHORT usDeviceTag; //supported device | ||
| 3687 | USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH | ||
| 3688 | USHORT usConnObjectId; //Connector Object ID | ||
| 3689 | USHORT usGPUObjectId; //GPU ID | ||
| 3690 | USHORT usGraphicObjIds[2]; //usGraphicObjIds[0]= GPU internal encoder, usGraphicObjIds[1]= external encoder | ||
| 3691 | }ATOM_DISPLAY_EXTERNAL_OBJECT_PATH; | ||
| 3692 | |||
| 3209 | typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE | 3693 | typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE |
| 3210 | { | 3694 | { |
| 3211 | UCHAR ucNumOfDispPath; | 3695 | UCHAR ucNumOfDispPath; |
| @@ -3261,6 +3745,47 @@ typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset | |||
| 3261 | #define EXT_AUXDDC_LUTINDEX_7 7 | 3745 | #define EXT_AUXDDC_LUTINDEX_7 7 |
| 3262 | #define MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES (EXT_AUXDDC_LUTINDEX_7+1) | 3746 | #define MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES (EXT_AUXDDC_LUTINDEX_7+1) |
| 3263 | 3747 | ||
| 3748 | //ucChannelMapping are defined as following | ||
| 3749 | //for DP connector, eDP, DP to VGA/LVDS | ||
| 3750 | //Bit[1:0]: Define which pin connect to DP connector DP_Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3751 | //Bit[3:2]: Define which pin connect to DP connector DP_Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3752 | //Bit[5:4]: Define which pin connect to DP connector DP_Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3753 | //Bit[7:6]: Define which pin connect to DP connector DP_Lane3, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3754 | typedef struct _ATOM_DP_CONN_CHANNEL_MAPPING | ||
| 3755 | { | ||
| 3756 | #if ATOM_BIG_ENDIAN | ||
| 3757 | UCHAR ucDP_Lane3_Source:2; | ||
| 3758 | UCHAR ucDP_Lane2_Source:2; | ||
| 3759 | UCHAR ucDP_Lane1_Source:2; | ||
| 3760 | UCHAR ucDP_Lane0_Source:2; | ||
| 3761 | #else | ||
| 3762 | UCHAR ucDP_Lane0_Source:2; | ||
| 3763 | UCHAR ucDP_Lane1_Source:2; | ||
| 3764 | UCHAR ucDP_Lane2_Source:2; | ||
| 3765 | UCHAR ucDP_Lane3_Source:2; | ||
| 3766 | #endif | ||
| 3767 | }ATOM_DP_CONN_CHANNEL_MAPPING; | ||
| 3768 | |||
| 3769 | //for DVI/HDMI, in dual link case, both links have to have same mapping. | ||
| 3770 | //Bit[1:0]: Define which pin connect to DVI connector data Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3771 | //Bit[3:2]: Define which pin connect to DVI connector data Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3772 | //Bit[5:4]: Define which pin connect to DVI connector data Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3773 | //Bit[7:6]: Define which pin connect to DVI connector clock lane, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 | ||
| 3774 | typedef struct _ATOM_DVI_CONN_CHANNEL_MAPPING | ||
| 3775 | { | ||
| 3776 | #if ATOM_BIG_ENDIAN | ||
| 3777 | UCHAR ucDVI_CLK_Source:2; | ||
| 3778 | UCHAR ucDVI_DATA0_Source:2; | ||
| 3779 | UCHAR ucDVI_DATA1_Source:2; | ||
| 3780 | UCHAR ucDVI_DATA2_Source:2; | ||
| 3781 | #else | ||
| 3782 | UCHAR ucDVI_DATA2_Source:2; | ||
| 3783 | UCHAR ucDVI_DATA1_Source:2; | ||
| 3784 | UCHAR ucDVI_DATA0_Source:2; | ||
| 3785 | UCHAR ucDVI_CLK_Source:2; | ||
| 3786 | #endif | ||
| 3787 | }ATOM_DVI_CONN_CHANNEL_MAPPING; | ||
| 3788 | |||
| 3264 | typedef struct _EXT_DISPLAY_PATH | 3789 | typedef struct _EXT_DISPLAY_PATH |
| 3265 | { | 3790 | { |
| 3266 | USHORT usDeviceTag; //A bit vector to show what devices are supported | 3791 | USHORT usDeviceTag; //A bit vector to show what devices are supported |
| @@ -3269,7 +3794,13 @@ typedef struct _EXT_DISPLAY_PATH | |||
| 3269 | UCHAR ucExtAUXDDCLutIndex; //An index into external AUX/DDC channel LUT | 3794 | UCHAR ucExtAUXDDCLutIndex; //An index into external AUX/DDC channel LUT |
| 3270 | UCHAR ucExtHPDPINLutIndex; //An index into external HPD pin LUT | 3795 | UCHAR ucExtHPDPINLutIndex; //An index into external HPD pin LUT |
| 3271 | USHORT usExtEncoderObjId; //external encoder object id | 3796 | USHORT usExtEncoderObjId; //external encoder object id |
| 3272 | USHORT usReserved[3]; | 3797 | union{ |
| 3798 | UCHAR ucChannelMapping; // if ucChannelMapping=0, using default one to one mapping | ||
| 3799 | ATOM_DP_CONN_CHANNEL_MAPPING asDPMapping; | ||
| 3800 | ATOM_DVI_CONN_CHANNEL_MAPPING asDVIMapping; | ||
| 3801 | }; | ||
| 3802 | UCHAR ucReserved; | ||
| 3803 | USHORT usReserved[2]; | ||
| 3273 | }EXT_DISPLAY_PATH; | 3804 | }EXT_DISPLAY_PATH; |
| 3274 | 3805 | ||
| 3275 | #define NUMBER_OF_UCHAR_FOR_GUID 16 | 3806 | #define NUMBER_OF_UCHAR_FOR_GUID 16 |
| @@ -3281,7 +3812,8 @@ typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO | |||
| 3281 | UCHAR ucGuid [NUMBER_OF_UCHAR_FOR_GUID]; // a GUID is a 16 byte long string | 3812 | UCHAR ucGuid [NUMBER_OF_UCHAR_FOR_GUID]; // a GUID is a 16 byte long string |
| 3282 | EXT_DISPLAY_PATH sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries. | 3813 | EXT_DISPLAY_PATH sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries. |
| 3283 | UCHAR ucChecksum; // a simple Checksum of the sum of whole structure equal to 0x0. | 3814 | UCHAR ucChecksum; // a simple Checksum of the sum of whole structure equal to 0x0. |
| 3284 | UCHAR Reserved [7]; // for potential expansion | 3815 | UCHAR uc3DStereoPinId; // use for eDP panel |
| 3816 | UCHAR Reserved [6]; // for potential expansion | ||
| 3285 | }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; | 3817 | }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; |
| 3286 | 3818 | ||
| 3287 | //Related definitions, all records are differnt but they have a commond header | 3819 | //Related definitions, all records are differnt but they have a commond header |
| @@ -3311,10 +3843,11 @@ typedef struct _ATOM_COMMON_RECORD_HEADER | |||
| 3311 | #define ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE 17 //This is for the case when connectors are not known to object table | 3843 | #define ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE 17 //This is for the case when connectors are not known to object table |
| 3312 | #define ATOM_OBJECT_LINK_RECORD_TYPE 18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record | 3844 | #define ATOM_OBJECT_LINK_RECORD_TYPE 18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record |
| 3313 | #define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19 | 3845 | #define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19 |
| 3846 | #define ATOM_ENCODER_CAP_RECORD_TYPE 20 | ||
| 3314 | 3847 | ||
| 3315 | 3848 | ||
| 3316 | //Must be updated when new record type is added,equal to that record definition! | 3849 | //Must be updated when new record type is added,equal to that record definition! |
| 3317 | #define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE | 3850 | #define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_ENCODER_CAP_RECORD_TYPE |
| 3318 | 3851 | ||
| 3319 | typedef struct _ATOM_I2C_RECORD | 3852 | typedef struct _ATOM_I2C_RECORD |
| 3320 | { | 3853 | { |
| @@ -3441,6 +3974,26 @@ typedef struct _ATOM_ENCODER_DVO_CF_RECORD | |||
| 3441 | UCHAR ucPadding[2]; | 3974 | UCHAR ucPadding[2]; |
| 3442 | }ATOM_ENCODER_DVO_CF_RECORD; | 3975 | }ATOM_ENCODER_DVO_CF_RECORD; |
| 3443 | 3976 | ||
| 3977 | // Bit maps for ATOM_ENCODER_CAP_RECORD.ucEncoderCap | ||
| 3978 | #define ATOM_ENCODER_CAP_RECORD_HBR2 0x01 // DP1.2 HBR2 is supported by this path | ||
| 3979 | |||
| 3980 | typedef struct _ATOM_ENCODER_CAP_RECORD | ||
| 3981 | { | ||
| 3982 | ATOM_COMMON_RECORD_HEADER sheader; | ||
| 3983 | union { | ||
| 3984 | USHORT usEncoderCap; | ||
| 3985 | struct { | ||
| 3986 | #if ATOM_BIG_ENDIAN | ||
| 3987 | USHORT usReserved:15; // Bit1-15 may be defined for other capability in future | ||
| 3988 | USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. | ||
| 3989 | #else | ||
| 3990 | USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. | ||
| 3991 | USHORT usReserved:15; // Bit1-15 may be defined for other capability in future | ||
| 3992 | #endif | ||
| 3993 | }; | ||
| 3994 | }; | ||
| 3995 | }ATOM_ENCODER_CAP_RECORD; | ||
| 3996 | |||
| 3444 | // value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle | 3997 | // value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle |
| 3445 | #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA 1 | 3998 | #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA 1 |
| 3446 | #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB 2 | 3999 | #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB 2 |
| @@ -3580,6 +4133,11 @@ typedef struct _ATOM_VOLTAGE_CONTROL | |||
| 3580 | #define VOLTAGE_CONTROL_ID_DAC 0x02 //I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI | 4133 | #define VOLTAGE_CONTROL_ID_DAC 0x02 //I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI |
| 3581 | #define VOLTAGE_CONTROL_ID_VT116xM 0x03 //I2C control, used for R6xx Core Voltage | 4134 | #define VOLTAGE_CONTROL_ID_VT116xM 0x03 //I2C control, used for R6xx Core Voltage |
| 3582 | #define VOLTAGE_CONTROL_ID_DS4402 0x04 | 4135 | #define VOLTAGE_CONTROL_ID_DS4402 0x04 |
| 4136 | #define VOLTAGE_CONTROL_ID_UP6266 0x05 | ||
| 4137 | #define VOLTAGE_CONTROL_ID_SCORPIO 0x06 | ||
| 4138 | #define VOLTAGE_CONTROL_ID_VT1556M 0x07 | ||
| 4139 | #define VOLTAGE_CONTROL_ID_CHL822x 0x08 | ||
| 4140 | #define VOLTAGE_CONTROL_ID_VT1586M 0x09 | ||
| 3583 | 4141 | ||
| 3584 | typedef struct _ATOM_VOLTAGE_OBJECT | 4142 | typedef struct _ATOM_VOLTAGE_OBJECT |
| 3585 | { | 4143 | { |
| @@ -3670,66 +4228,157 @@ typedef struct _ATOM_POWER_SOURCE_INFO | |||
| 3670 | #define POWER_SENSOR_GPIO 0x01 | 4228 | #define POWER_SENSOR_GPIO 0x01 |
| 3671 | #define POWER_SENSOR_I2C 0x02 | 4229 | #define POWER_SENSOR_I2C 0x02 |
| 3672 | 4230 | ||
| 4231 | typedef struct _ATOM_CLK_VOLT_CAPABILITY | ||
| 4232 | { | ||
| 4233 | ULONG ulVoltageIndex; // The Voltage Index indicated by FUSE, same voltage index shared with SCLK DPM fuse table | ||
| 4234 | ULONG ulMaximumSupportedCLK; // Maximum clock supported with specified voltage index, unit in 10kHz | ||
| 4235 | }ATOM_CLK_VOLT_CAPABILITY; | ||
| 4236 | |||
| 4237 | typedef struct _ATOM_AVAILABLE_SCLK_LIST | ||
| 4238 | { | ||
| 4239 | ULONG ulSupportedSCLK; // Maximum clock supported with specified voltage index, unit in 10kHz | ||
| 4240 | USHORT usVoltageIndex; // The Voltage Index indicated by FUSE for specified SCLK | ||
| 4241 | USHORT usVoltageID; // The Voltage ID indicated by FUSE for specified SCLK | ||
| 4242 | }ATOM_AVAILABLE_SCLK_LIST; | ||
| 4243 | |||
| 4244 | // ATOM_INTEGRATED_SYSTEM_INFO_V6 ulSystemConfig cap definition | ||
| 4245 | #define ATOM_IGP_INFO_V6_SYSTEM_CONFIG__PCIE_POWER_GATING_ENABLE 1 // refer to ulSystemConfig bit[0] | ||
| 4246 | |||
| 4247 | // this IntegrateSystemInfoTable is used for Liano/Ontario APU | ||
| 3673 | typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 | 4248 | typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 |
| 3674 | { | 4249 | { |
| 3675 | ATOM_COMMON_TABLE_HEADER sHeader; | 4250 | ATOM_COMMON_TABLE_HEADER sHeader; |
| 3676 | ULONG ulBootUpEngineClock; | 4251 | ULONG ulBootUpEngineClock; |
| 3677 | ULONG ulDentistVCOFreq; | 4252 | ULONG ulDentistVCOFreq; |
| 3678 | ULONG ulBootUpUMAClock; | 4253 | ULONG ulBootUpUMAClock; |
| 3679 | ULONG ulReserved1[8]; | 4254 | ATOM_CLK_VOLT_CAPABILITY sDISPCLK_Voltage[4]; |
| 3680 | ULONG ulBootUpReqDisplayVector; | 4255 | ULONG ulBootUpReqDisplayVector; |
| 3681 | ULONG ulOtherDisplayMisc; | 4256 | ULONG ulOtherDisplayMisc; |
| 3682 | ULONG ulGPUCapInfo; | 4257 | ULONG ulGPUCapInfo; |
| 3683 | ULONG ulReserved2[3]; | 4258 | ULONG ulSB_MMIO_Base_Addr; |
| 4259 | USHORT usRequestedPWMFreqInHz; | ||
| 4260 | UCHAR ucHtcTmpLmt; | ||
| 4261 | UCHAR ucHtcHystLmt; | ||
| 4262 | ULONG ulMinEngineClock; | ||
| 3684 | ULONG ulSystemConfig; | 4263 | ULONG ulSystemConfig; |
| 3685 | ULONG ulCPUCapInfo; | 4264 | ULONG ulCPUCapInfo; |
| 3686 | USHORT usMaxNBVoltage; | 4265 | USHORT usNBP0Voltage; |
| 3687 | USHORT usMinNBVoltage; | 4266 | USHORT usNBP1Voltage; |
| 3688 | USHORT usBootUpNBVoltage; | 4267 | USHORT usBootUpNBVoltage; |
| 3689 | USHORT usExtDispConnInfoOffset; | 4268 | USHORT usExtDispConnInfoOffset; |
| 3690 | UCHAR ucHtcTmpLmt; | 4269 | USHORT usPanelRefreshRateRange; |
| 3691 | UCHAR ucTjOffset; | ||
| 3692 | UCHAR ucMemoryType; | 4270 | UCHAR ucMemoryType; |
| 3693 | UCHAR ucUMAChannelNumber; | 4271 | UCHAR ucUMAChannelNumber; |
| 3694 | ULONG ulCSR_M3_ARB_CNTL_DEFAULT[10]; | 4272 | ULONG ulCSR_M3_ARB_CNTL_DEFAULT[10]; |
| 3695 | ULONG ulCSR_M3_ARB_CNTL_UVD[10]; | 4273 | ULONG ulCSR_M3_ARB_CNTL_UVD[10]; |
| 3696 | ULONG ulCSR_M3_ARB_CNTL_FS3D[10]; | 4274 | ULONG ulCSR_M3_ARB_CNTL_FS3D[10]; |
| 3697 | ULONG ulReserved3[42]; | 4275 | ATOM_AVAILABLE_SCLK_LIST sAvail_SCLK[5]; |
| 4276 | ULONG ulGMCRestoreResetTime; | ||
| 4277 | ULONG ulMinimumNClk; | ||
| 4278 | ULONG ulIdleNClk; | ||
| 4279 | ULONG ulDDR_DLL_PowerUpTime; | ||
| 4280 | ULONG ulDDR_PLL_PowerUpTime; | ||
| 4281 | USHORT usPCIEClkSSPercentage; | ||
| 4282 | USHORT usPCIEClkSSType; | ||
| 4283 | USHORT usLvdsSSPercentage; | ||
| 4284 | USHORT usLvdsSSpreadRateIn10Hz; | ||
| 4285 | USHORT usHDMISSPercentage; | ||
| 4286 | USHORT usHDMISSpreadRateIn10Hz; | ||
| 4287 | USHORT usDVISSPercentage; | ||
| 4288 | USHORT usDVISSpreadRateIn10Hz; | ||
| 4289 | ULONG ulReserved3[21]; | ||
| 3698 | ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; | 4290 | ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; |
| 3699 | }ATOM_INTEGRATED_SYSTEM_INFO_V6; | 4291 | }ATOM_INTEGRATED_SYSTEM_INFO_V6; |
| 3700 | 4292 | ||
| 4293 | // ulGPUCapInfo | ||
| 4294 | #define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01 | ||
| 4295 | #define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__DISABLE_AUX_HW_MODE_DETECTION 0x08 | ||
| 4296 | |||
| 4297 | // ulOtherDisplayMisc | ||
| 4298 | #define INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT 0x01 | ||
| 4299 | |||
| 4300 | |||
| 3701 | /********************************************************************************************************************** | 4301 | /********************************************************************************************************************** |
| 3702 | // ATOM_INTEGRATED_SYSTEM_INFO_V6 Description | 4302 | ATOM_INTEGRATED_SYSTEM_INFO_V6 Description |
| 3703 | //ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. | 4303 | ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock |
| 3704 | //ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. | 4304 | ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. |
| 3705 | //ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. | 4305 | ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. |
| 3706 | //ulReserved1[8] Reserved by now, must be 0x0. | 4306 | sDISPCLK_Voltage: Report Display clock voltage requirement. |
| 3707 | //ulBootUpReqDisplayVector VBIOS boot up display IDs | 4307 | |
| 3708 | // ATOM_DEVICE_CRT1_SUPPORT 0x0001 | 4308 | ulBootUpReqDisplayVector: VBIOS boot up display IDs, following are supported devices in Liano/Ontaio projects: |
| 3709 | // ATOM_DEVICE_CRT2_SUPPORT 0x0010 | 4309 | ATOM_DEVICE_CRT1_SUPPORT 0x0001 |
| 3710 | // ATOM_DEVICE_DFP1_SUPPORT 0x0008 | 4310 | ATOM_DEVICE_CRT2_SUPPORT 0x0010 |
| 3711 | // ATOM_DEVICE_DFP6_SUPPORT 0x0040 | 4311 | ATOM_DEVICE_DFP1_SUPPORT 0x0008 |
| 3712 | // ATOM_DEVICE_DFP2_SUPPORT 0x0080 | 4312 | ATOM_DEVICE_DFP6_SUPPORT 0x0040 |
| 3713 | // ATOM_DEVICE_DFP3_SUPPORT 0x0200 | 4313 | ATOM_DEVICE_DFP2_SUPPORT 0x0080 |
| 3714 | // ATOM_DEVICE_DFP4_SUPPORT 0x0400 | 4314 | ATOM_DEVICE_DFP3_SUPPORT 0x0200 |
| 3715 | // ATOM_DEVICE_DFP5_SUPPORT 0x0800 | 4315 | ATOM_DEVICE_DFP4_SUPPORT 0x0400 |
| 3716 | // ATOM_DEVICE_LCD1_SUPPORT 0x0002 | 4316 | ATOM_DEVICE_DFP5_SUPPORT 0x0800 |
| 3717 | //ulOtherDisplayMisc Other display related flags, not defined yet. | 4317 | ATOM_DEVICE_LCD1_SUPPORT 0x0002 |
| 3718 | //ulGPUCapInfo TBD | 4318 | ulOtherDisplayMisc: Other display related flags, not defined yet. |
| 3719 | //ulReserved2[3] must be 0x0 for the reserved. | 4319 | ulGPUCapInfo: bit[0]=0: TMDS/HDMI Coherent Mode use cascade PLL mode. |
| 3720 | //ulSystemConfig TBD | 4320 | =1: TMDS/HDMI Coherent Mode use signel PLL mode. |
| 3721 | //ulCPUCapInfo TBD | 4321 | bit[3]=0: Enable HW AUX mode detection logic |
| 3722 | //usMaxNBVoltage High NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse. | 4322 | =1: Disable HW AUX mode dettion logic |
| 3723 | //usMinNBVoltage Low NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse. | 4323 | ulSB_MMIO_Base_Addr: Physical Base address to SB MMIO space. Driver needs to initialize it for SMU usage. |
| 3724 | //usBootUpNBVoltage Boot up NB voltage in unit of mv. | 4324 | |
| 3725 | //ucHtcTmpLmt Bit [22:16] of D24F3x64 Thermal Control (HTC) Register. | 4325 | usRequestedPWMFreqInHz: When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW). |
| 3726 | //ucTjOffset Bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed. | 4326 | Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0; |
| 3727 | //ucMemoryType [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. | 4327 | |
| 3728 | //ucUMAChannelNumber System memory channel numbers. | 4328 | When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below: |
| 3729 | //usExtDispConnectionInfoOffset ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO offset relative to beginning of this table. | 4329 | 1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use; |
| 3730 | //ulCSR_M3_ARB_CNTL_DEFAULT[10] Arrays with values for CSR M3 arbiter for default | 4330 | VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result, |
| 3731 | //ulCSR_M3_ARB_CNTL_UVD[10] Arrays with values for CSR M3 arbiter for UVD playback. | 4331 | Changing BL using VBIOS function is functional in both driver and non-driver present environment; |
| 3732 | //ulCSR_M3_ARB_CNTL_FS3D[10] Arrays with values for CSR M3 arbiter for Full Screen 3D applications. | 4332 | and enabling VariBri under the driver environment from PP table is optional. |
| 4333 | |||
| 4334 | 2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating | ||
| 4335 | that BL control from GPU is expected. | ||
| 4336 | VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1 | ||
| 4337 | Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but | ||
| 4338 | it's per platform | ||
| 4339 | and enabling VariBri under the driver environment from PP table is optional. | ||
| 4340 | |||
| 4341 | ucHtcTmpLmt: Refer to D18F3x64 bit[22:16], HtcTmpLmt. | ||
| 4342 | Threshold on value to enter HTC_active state. | ||
| 4343 | ucHtcHystLmt: Refer to D18F3x64 bit[27:24], HtcHystLmt. | ||
| 4344 | To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt. | ||
| 4345 | ulMinEngineClock: Minimum SCLK allowed in 10kHz unit. This is calculated based on WRCK Fuse settings. | ||
| 4346 | ulSystemConfig: Bit[0]=0: PCIE Power Gating Disabled | ||
| 4347 | =1: PCIE Power Gating Enabled | ||
| 4348 | Bit[1]=0: DDR-DLL shut-down feature disabled. | ||
| 4349 | 1: DDR-DLL shut-down feature enabled. | ||
| 4350 | Bit[2]=0: DDR-PLL Power down feature disabled. | ||
| 4351 | 1: DDR-PLL Power down feature enabled. | ||
| 4352 | ulCPUCapInfo: TBD | ||
| 4353 | usNBP0Voltage: VID for voltage on NB P0 State | ||
| 4354 | usNBP1Voltage: VID for voltage on NB P1 State | ||
| 4355 | usBootUpNBVoltage: Voltage Index of GNB voltage configured by SBIOS, which is suffcient to support VBIOS DISPCLK requirement. | ||
| 4356 | usExtDispConnInfoOffset: Offset to sExtDispConnInfo inside the structure | ||
| 4357 | usPanelRefreshRateRange: Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set | ||
| 4358 | to indicate a range. | ||
| 4359 | SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 | ||
| 4360 | SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 | ||
| 4361 | SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 | ||
| 4362 | SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 | ||
| 4363 | ucMemoryType: [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. | ||
| 4364 | ucUMAChannelNumber: System memory channel numbers. | ||
| 4365 | ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default | ||
| 4366 | ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback. | ||
| 4367 | ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications. | ||
| 4368 | sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high | ||
| 4369 | ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. | ||
| 4370 | ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz. | ||
| 4371 | ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz. | ||
| 4372 | ulDDR_DLL_PowerUpTime: DDR PHY DLL power up time. Unit in ns. | ||
| 4373 | ulDDR_PLL_PowerUpTime: DDR PHY PLL power up time. Unit in ns. | ||
| 4374 | usPCIEClkSSPercentage: PCIE Clock Spred Spectrum Percentage in unit 0.01%; 100 mean 1%. | ||
| 4375 | usPCIEClkSSType: PCIE Clock Spred Spectrum Type. 0 for Down spread(default); 1 for Center spread. | ||
| 4376 | usLvdsSSPercentage: LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting. | ||
| 4377 | usLvdsSSpreadRateIn10Hz: LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. | ||
| 4378 | usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. | ||
| 4379 | usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. | ||
| 4380 | usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. | ||
| 4381 | usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. | ||
| 3733 | **********************************************************************************************************************/ | 4382 | **********************************************************************************************************************/ |
| 3734 | 4383 | ||
| 3735 | /**************************************************************************/ | 4384 | /**************************************************************************/ |
| @@ -3790,6 +4439,7 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT | |||
| 3790 | #define ASIC_INTERNAL_SS_ON_LVDS 6 | 4439 | #define ASIC_INTERNAL_SS_ON_LVDS 6 |
| 3791 | #define ASIC_INTERNAL_SS_ON_DP 7 | 4440 | #define ASIC_INTERNAL_SS_ON_DP 7 |
| 3792 | #define ASIC_INTERNAL_SS_ON_DCPLL 8 | 4441 | #define ASIC_INTERNAL_SS_ON_DCPLL 8 |
| 4442 | #define ASIC_EXTERNAL_SS_ON_DP_CLOCK 9 | ||
| 3793 | 4443 | ||
| 3794 | typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2 | 4444 | typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2 |
| 3795 | { | 4445 | { |
| @@ -3903,6 +4553,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 | |||
| 3903 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_AC 1 | 4553 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_AC 1 |
| 3904 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 | 4554 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 |
| 3905 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 | 4555 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 |
| 4556 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LIT2AC 4 | ||
| 3906 | 4557 | ||
| 3907 | //Byte aligned defintion for BIOS usage | 4558 | //Byte aligned defintion for BIOS usage |
| 3908 | #define ATOM_S0_CRT1_MONOb0 0x01 | 4559 | #define ATOM_S0_CRT1_MONOb0 0x01 |
| @@ -4529,7 +5180,8 @@ typedef struct _ATOM_INIT_REG_BLOCK{ | |||
| 4529 | #define INDEX_ACCESS_RANGE_BEGIN (VALUE_DWORD + 1) | 5180 | #define INDEX_ACCESS_RANGE_BEGIN (VALUE_DWORD + 1) |
| 4530 | #define INDEX_ACCESS_RANGE_END (INDEX_ACCESS_RANGE_BEGIN + 1) | 5181 | #define INDEX_ACCESS_RANGE_END (INDEX_ACCESS_RANGE_BEGIN + 1) |
| 4531 | #define VALUE_INDEX_ACCESS_SINGLE (INDEX_ACCESS_RANGE_END + 1) | 5182 | #define VALUE_INDEX_ACCESS_SINGLE (INDEX_ACCESS_RANGE_END + 1) |
| 4532 | 5183 | //#define ACCESS_MCIODEBUGIND 0x40 //defined in BIOS code | |
| 5184 | #define ACCESS_PLACEHOLDER 0x80 | ||
| 4533 | 5185 | ||
| 4534 | typedef struct _ATOM_MC_INIT_PARAM_TABLE | 5186 | typedef struct _ATOM_MC_INIT_PARAM_TABLE |
| 4535 | { | 5187 | { |
| @@ -4554,6 +5206,10 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE | |||
| 4554 | #define _32Mx32 0x33 | 5206 | #define _32Mx32 0x33 |
| 4555 | #define _64Mx8 0x41 | 5207 | #define _64Mx8 0x41 |
| 4556 | #define _64Mx16 0x42 | 5208 | #define _64Mx16 0x42 |
| 5209 | #define _64Mx32 0x43 | ||
| 5210 | #define _128Mx8 0x51 | ||
| 5211 | #define _128Mx16 0x52 | ||
| 5212 | #define _256Mx8 0x61 | ||
| 4557 | 5213 | ||
| 4558 | #define SAMSUNG 0x1 | 5214 | #define SAMSUNG 0x1 |
| 4559 | #define INFINEON 0x2 | 5215 | #define INFINEON 0x2 |
| @@ -4569,10 +5225,11 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE | |||
| 4569 | #define QIMONDA INFINEON | 5225 | #define QIMONDA INFINEON |
| 4570 | #define PROMOS MOSEL | 5226 | #define PROMOS MOSEL |
| 4571 | #define KRETON INFINEON | 5227 | #define KRETON INFINEON |
| 5228 | #define ELIXIR NANYA | ||
| 4572 | 5229 | ||
| 4573 | /////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// | 5230 | /////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// |
| 4574 | 5231 | ||
| 4575 | #define UCODE_ROM_START_ADDRESS 0x1c000 | 5232 | #define UCODE_ROM_START_ADDRESS 0x1b800 |
| 4576 | #define UCODE_SIGNATURE 0x4375434d // 'MCuC' - MC uCode | 5233 | #define UCODE_SIGNATURE 0x4375434d // 'MCuC' - MC uCode |
| 4577 | 5234 | ||
| 4578 | //uCode block header for reference | 5235 | //uCode block header for reference |
| @@ -4903,7 +5560,34 @@ typedef struct _ATOM_VRAM_MODULE_V6 | |||
| 4903 | ATOM_MEMORY_TIMING_FORMAT_V2 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock | 5560 | ATOM_MEMORY_TIMING_FORMAT_V2 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock |
| 4904 | }ATOM_VRAM_MODULE_V6; | 5561 | }ATOM_VRAM_MODULE_V6; |
| 4905 | 5562 | ||
| 4906 | 5563 | typedef struct _ATOM_VRAM_MODULE_V7 | |
| 5564 | { | ||
| 5565 | // Design Specific Values | ||
| 5566 | ULONG ulChannelMapCfg; // mmMC_SHARED_CHREMAP | ||
| 5567 | USHORT usModuleSize; // Size of ATOM_VRAM_MODULE_V7 | ||
| 5568 | USHORT usPrivateReserved; // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) | ||
| 5569 | USHORT usReserved; | ||
| 5570 | UCHAR ucExtMemoryID; // Current memory module ID | ||
| 5571 | UCHAR ucMemoryType; // MEM_TYPE_DDR2/DDR3/GDDR3/GDDR5 | ||
| 5572 | UCHAR ucChannelNum; // Number of mem. channels supported in this module | ||
| 5573 | UCHAR ucChannelWidth; // CHANNEL_16BIT/CHANNEL_32BIT/CHANNEL_64BIT | ||
| 5574 | UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 | ||
| 5575 | UCHAR ucReserve; // Former container for Mx_FLAGS like DBI_AC_MODE_ENABLE_ASIC for GDDR4. Not used now. | ||
| 5576 | UCHAR ucMisc; // RANK_OF_THISMEMORY etc. | ||
| 5577 | UCHAR ucVREFI; // Not used. | ||
| 5578 | UCHAR ucNPL_RT; // Round trip delay (MC_SEQ_CAS_TIMING [28:24]:TCL=CL+NPL_RT-2). Always 2. | ||
| 5579 | UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble | ||
| 5580 | UCHAR ucMemorySize; // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros | ||
| 5581 | UCHAR ucReserved[3]; | ||
| 5582 | // Memory Module specific values | ||
| 5583 | USHORT usEMRS2Value; // EMRS2/MR2 Value. | ||
| 5584 | USHORT usEMRS3Value; // EMRS3/MR3 Value. | ||
| 5585 | UCHAR ucMemoryVenderID; // [7:4] Revision, [3:0] Vendor code | ||
| 5586 | UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) | ||
| 5587 | UCHAR ucFIFODepth; // FIFO depth can be detected during vendor detection, here is hardcoded per memory | ||
| 5588 | UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth | ||
| 5589 | char strMemPNString[20]; // part number end with '0'. | ||
| 5590 | }ATOM_VRAM_MODULE_V7; | ||
| 4907 | 5591 | ||
| 4908 | typedef struct _ATOM_VRAM_INFO_V2 | 5592 | typedef struct _ATOM_VRAM_INFO_V2 |
| 4909 | { | 5593 | { |
| @@ -4942,6 +5626,20 @@ typedef struct _ATOM_VRAM_INFO_V4 | |||
| 4942 | // ATOM_INIT_REG_BLOCK aMemAdjust; | 5626 | // ATOM_INIT_REG_BLOCK aMemAdjust; |
| 4943 | }ATOM_VRAM_INFO_V4; | 5627 | }ATOM_VRAM_INFO_V4; |
| 4944 | 5628 | ||
| 5629 | typedef struct _ATOM_VRAM_INFO_HEADER_V2_1 | ||
| 5630 | { | ||
| 5631 | ATOM_COMMON_TABLE_HEADER sHeader; | ||
| 5632 | USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting | ||
| 5633 | USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting | ||
| 5634 | USHORT usReserved[4]; | ||
| 5635 | UCHAR ucNumOfVRAMModule; // indicate number of VRAM module | ||
| 5636 | UCHAR ucMemoryClkPatchTblVer; // version of memory AC timing register list | ||
| 5637 | UCHAR ucVramModuleVer; // indicate ATOM_VRAM_MODUE version | ||
| 5638 | UCHAR ucReserved; | ||
| 5639 | ATOM_VRAM_MODULE_V7 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; | ||
| 5640 | }ATOM_VRAM_INFO_HEADER_V2_1; | ||
| 5641 | |||
| 5642 | |||
| 4945 | typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO | 5643 | typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO |
| 4946 | { | 5644 | { |
| 4947 | ATOM_COMMON_TABLE_HEADER sHeader; | 5645 | ATOM_COMMON_TABLE_HEADER sHeader; |
| @@ -5182,6 +5880,16 @@ typedef struct _ASIC_TRANSMITTER_INFO | |||
| 5182 | UCHAR ucReserved; | 5880 | UCHAR ucReserved; |
| 5183 | }ASIC_TRANSMITTER_INFO; | 5881 | }ASIC_TRANSMITTER_INFO; |
| 5184 | 5882 | ||
| 5883 | #define ASIC_TRANSMITTER_INFO_CONFIG__DVO_SDR_MODE 0x01 | ||
| 5884 | #define ASIC_TRANSMITTER_INFO_CONFIG__COHERENT_MODE 0x02 | ||
| 5885 | #define ASIC_TRANSMITTER_INFO_CONFIG__ENCODEROBJ_ID_MASK 0xc4 | ||
| 5886 | #define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_A 0x00 | ||
| 5887 | #define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_B 0x04 | ||
| 5888 | #define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_C 0x40 | ||
| 5889 | #define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_D 0x44 | ||
| 5890 | #define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_E 0x80 | ||
| 5891 | #define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_F 0x84 | ||
| 5892 | |||
| 5185 | typedef struct _ASIC_ENCODER_INFO | 5893 | typedef struct _ASIC_ENCODER_INFO |
| 5186 | { | 5894 | { |
| 5187 | UCHAR ucEncoderID; | 5895 | UCHAR ucEncoderID; |
| @@ -5284,6 +5992,28 @@ typedef struct _DP_ENCODER_SERVICE_PARAMETERS | |||
| 5284 | /* /obselete */ | 5992 | /* /obselete */ |
| 5285 | #define DP_ENCODER_SERVICE_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS | 5993 | #define DP_ENCODER_SERVICE_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS |
| 5286 | 5994 | ||
| 5995 | |||
| 5996 | typedef struct _DP_ENCODER_SERVICE_PARAMETERS_V2 | ||
| 5997 | { | ||
| 5998 | USHORT usExtEncoderObjId; // External Encoder Object Id, output parameter only, use when ucAction = DP_SERVICE_V2_ACTION_DET_EXT_CONNECTION | ||
| 5999 | UCHAR ucAuxId; | ||
| 6000 | UCHAR ucAction; | ||
| 6001 | UCHAR ucSinkType; // Iput and Output parameters. | ||
| 6002 | UCHAR ucHPDId; // Input parameter, used when ucAction = DP_SERVICE_V2_ACTION_DET_EXT_CONNECTION | ||
| 6003 | UCHAR ucReserved[2]; | ||
| 6004 | }DP_ENCODER_SERVICE_PARAMETERS_V2; | ||
| 6005 | |||
| 6006 | typedef struct _DP_ENCODER_SERVICE_PS_ALLOCATION_V2 | ||
| 6007 | { | ||
| 6008 | DP_ENCODER_SERVICE_PARAMETERS_V2 asDPServiceParam; | ||
| 6009 | PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 asAuxParam; | ||
| 6010 | }DP_ENCODER_SERVICE_PS_ALLOCATION_V2; | ||
| 6011 | |||
| 6012 | // ucAction | ||
| 6013 | #define DP_SERVICE_V2_ACTION_GET_SINK_TYPE 0x01 | ||
| 6014 | #define DP_SERVICE_V2_ACTION_DET_LCD_CONNECTION 0x02 | ||
| 6015 | |||
| 6016 | |||
| 5287 | // DP_TRAINING_TABLE | 6017 | // DP_TRAINING_TABLE |
| 5288 | #define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR ATOM_DP_TRAINING_TBL_ADDR | 6018 | #define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR ATOM_DP_TRAINING_TBL_ADDR |
| 5289 | #define DPCD_SET_SS_CNTL_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 8 ) | 6019 | #define DPCD_SET_SS_CNTL_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 8 ) |
| @@ -5339,6 +6069,7 @@ typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2 | |||
| 5339 | #define SELECT_DCIO_IMPCAL 4 | 6069 | #define SELECT_DCIO_IMPCAL 4 |
| 5340 | #define SELECT_DCIO_DIG 6 | 6070 | #define SELECT_DCIO_DIG 6 |
| 5341 | #define SELECT_CRTC_PIXEL_RATE 7 | 6071 | #define SELECT_CRTC_PIXEL_RATE 7 |
| 6072 | #define SELECT_VGA_BLK 8 | ||
| 5342 | 6073 | ||
| 5343 | /****************************************************************************/ | 6074 | /****************************************************************************/ |
| 5344 | //Portion VI: Definitinos for vbios MC scratch registers that driver used | 6075 | //Portion VI: Definitinos for vbios MC scratch registers that driver used |
| @@ -5744,7 +6475,17 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER | |||
| 5744 | #define ATOM_PP_THERMALCONTROLLER_ADT7473 9 | 6475 | #define ATOM_PP_THERMALCONTROLLER_ADT7473 9 |
| 5745 | #define ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO 11 | 6476 | #define ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO 11 |
| 5746 | #define ATOM_PP_THERMALCONTROLLER_EVERGREEN 12 | 6477 | #define ATOM_PP_THERMALCONTROLLER_EVERGREEN 12 |
| 6478 | #define ATOM_PP_THERMALCONTROLLER_EMC2103 13 /* 0x0D */ // Only fan control will be implemented, do NOT show this in PPGen. | ||
| 6479 | #define ATOM_PP_THERMALCONTROLLER_SUMO 14 /* 0x0E */ // Sumo type, used internally | ||
| 6480 | #define ATOM_PP_THERMALCONTROLLER_NISLANDS 15 | ||
| 6481 | |||
| 6482 | // Thermal controller 'combo type' to use an external controller for Fan control and an internal controller for thermal. | ||
| 6483 | // We probably should reserve the bit 0x80 for this use. | ||
| 6484 | // To keep the number of these types low we should also use the same code for all ASICs (i.e. do not distinguish RV6xx and RV7xx Internal here). | ||
| 6485 | // The driver can pick the correct internal controller based on the ASIC. | ||
| 6486 | |||
| 5747 | #define ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL 0x89 // ADT7473 Fan Control + Internal Thermal Controller | 6487 | #define ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL 0x89 // ADT7473 Fan Control + Internal Thermal Controller |
| 6488 | #define ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL 0x8D // EMC2103 Fan Control + Internal Thermal Controller | ||
| 5748 | 6489 | ||
| 5749 | typedef struct _ATOM_PPLIB_STATE | 6490 | typedef struct _ATOM_PPLIB_STATE |
| 5750 | { | 6491 | { |
| @@ -5841,6 +6582,29 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 | |||
| 5841 | USHORT usExtendendedHeaderOffset; | 6582 | USHORT usExtendendedHeaderOffset; |
| 5842 | } ATOM_PPLIB_POWERPLAYTABLE3, *LPATOM_PPLIB_POWERPLAYTABLE3; | 6583 | } ATOM_PPLIB_POWERPLAYTABLE3, *LPATOM_PPLIB_POWERPLAYTABLE3; |
| 5843 | 6584 | ||
| 6585 | typedef struct _ATOM_PPLIB_POWERPLAYTABLE4 | ||
| 6586 | { | ||
| 6587 | ATOM_PPLIB_POWERPLAYTABLE3 basicTable3; | ||
| 6588 | ULONG ulGoldenPPID; // PPGen use only | ||
| 6589 | ULONG ulGoldenRevision; // PPGen use only | ||
| 6590 | USHORT usVddcDependencyOnSCLKOffset; | ||
| 6591 | USHORT usVddciDependencyOnMCLKOffset; | ||
| 6592 | USHORT usVddcDependencyOnMCLKOffset; | ||
| 6593 | USHORT usMaxClockVoltageOnDCOffset; | ||
| 6594 | USHORT usReserved[2]; | ||
| 6595 | } ATOM_PPLIB_POWERPLAYTABLE4, *LPATOM_PPLIB_POWERPLAYTABLE4; | ||
| 6596 | |||
| 6597 | typedef struct _ATOM_PPLIB_POWERPLAYTABLE5 | ||
| 6598 | { | ||
| 6599 | ATOM_PPLIB_POWERPLAYTABLE4 basicTable4; | ||
| 6600 | ULONG ulTDPLimit; | ||
| 6601 | ULONG ulNearTDPLimit; | ||
| 6602 | ULONG ulSQRampingThreshold; | ||
| 6603 | USHORT usCACLeakageTableOffset; // Points to ATOM_PPLIB_CAC_Leakage_Table | ||
| 6604 | ULONG ulCACLeakage; // TBD, this parameter is still under discussion. Change to ulReserved if not needed. | ||
| 6605 | ULONG ulReserved; | ||
| 6606 | } ATOM_PPLIB_POWERPLAYTABLE5, *LPATOM_PPLIB_POWERPLAYTABLE5; | ||
| 6607 | |||
| 5844 | //// ATOM_PPLIB_NONCLOCK_INFO::usClassification | 6608 | //// ATOM_PPLIB_NONCLOCK_INFO::usClassification |
| 5845 | #define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007 | 6609 | #define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007 |
| 5846 | #define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0 | 6610 | #define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0 |
| @@ -5864,6 +6628,10 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 | |||
| 5864 | #define ATOM_PPLIB_CLASSIFICATION_HDSTATE 0x4000 | 6628 | #define ATOM_PPLIB_CLASSIFICATION_HDSTATE 0x4000 |
| 5865 | #define ATOM_PPLIB_CLASSIFICATION_SDSTATE 0x8000 | 6629 | #define ATOM_PPLIB_CLASSIFICATION_SDSTATE 0x8000 |
| 5866 | 6630 | ||
| 6631 | //// ATOM_PPLIB_NONCLOCK_INFO::usClassification2 | ||
| 6632 | #define ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2 0x0001 | ||
| 6633 | #define ATOM_PPLIB_CLASSIFICATION2_ULV 0x0002 | ||
| 6634 | |||
| 5867 | //// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings | 6635 | //// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings |
| 5868 | #define ATOM_PPLIB_SINGLE_DISPLAY_ONLY 0x00000001 | 6636 | #define ATOM_PPLIB_SINGLE_DISPLAY_ONLY 0x00000001 |
| 5869 | #define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK 0x00000002 | 6637 | #define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK 0x00000002 |
| @@ -5896,9 +6664,21 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 | |||
| 5896 | #define ATOM_PPLIB_M3ARB_MASK 0x00060000 | 6664 | #define ATOM_PPLIB_M3ARB_MASK 0x00060000 |
| 5897 | #define ATOM_PPLIB_M3ARB_SHIFT 17 | 6665 | #define ATOM_PPLIB_M3ARB_SHIFT 17 |
| 5898 | 6666 | ||
| 6667 | #define ATOM_PPLIB_ENABLE_DRR 0x00080000 | ||
| 6668 | |||
| 6669 | // remaining 16 bits are reserved | ||
| 6670 | typedef struct _ATOM_PPLIB_THERMAL_STATE | ||
| 6671 | { | ||
| 6672 | UCHAR ucMinTemperature; | ||
| 6673 | UCHAR ucMaxTemperature; | ||
| 6674 | UCHAR ucThermalAction; | ||
| 6675 | }ATOM_PPLIB_THERMAL_STATE, *LPATOM_PPLIB_THERMAL_STATE; | ||
| 6676 | |||
| 5899 | // Contained in an array starting at the offset | 6677 | // Contained in an array starting at the offset |
| 5900 | // in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset. | 6678 | // in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset. |
| 5901 | // referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex | 6679 | // referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex |
| 6680 | #define ATOM_PPLIB_NONCLOCKINFO_VER1 12 | ||
| 6681 | #define ATOM_PPLIB_NONCLOCKINFO_VER2 24 | ||
| 5902 | typedef struct _ATOM_PPLIB_NONCLOCK_INFO | 6682 | typedef struct _ATOM_PPLIB_NONCLOCK_INFO |
| 5903 | { | 6683 | { |
| 5904 | USHORT usClassification; | 6684 | USHORT usClassification; |
| @@ -5906,15 +6686,15 @@ typedef struct _ATOM_PPLIB_NONCLOCK_INFO | |||
| 5906 | UCHAR ucMaxTemperature; | 6686 | UCHAR ucMaxTemperature; |
| 5907 | ULONG ulCapsAndSettings; | 6687 | ULONG ulCapsAndSettings; |
| 5908 | UCHAR ucRequiredPower; | 6688 | UCHAR ucRequiredPower; |
| 5909 | UCHAR ucUnused1[3]; | 6689 | USHORT usClassification2; |
| 6690 | ULONG ulVCLK; | ||
| 6691 | ULONG ulDCLK; | ||
| 6692 | UCHAR ucUnused[5]; | ||
| 5910 | } ATOM_PPLIB_NONCLOCK_INFO; | 6693 | } ATOM_PPLIB_NONCLOCK_INFO; |
| 5911 | 6694 | ||
| 5912 | // Contained in an array starting at the offset | 6695 | // Contained in an array starting at the offset |
| 5913 | // in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset. | 6696 | // in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset. |
| 5914 | // referenced from ATOM_PPLIB_STATE::ucClockStateIndices | 6697 | // referenced from ATOM_PPLIB_STATE::ucClockStateIndices |
| 5915 | #define ATOM_PPLIB_NONCLOCKINFO_VER1 12 | ||
| 5916 | #define ATOM_PPLIB_NONCLOCKINFO_VER2 24 | ||
| 5917 | |||
| 5918 | typedef struct _ATOM_PPLIB_R600_CLOCK_INFO | 6698 | typedef struct _ATOM_PPLIB_R600_CLOCK_INFO |
| 5919 | { | 6699 | { |
| 5920 | USHORT usEngineClockLow; | 6700 | USHORT usEngineClockLow; |
| @@ -5985,6 +6765,93 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO | |||
| 5985 | #define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 | 6765 | #define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 |
| 5986 | #define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 | 6766 | #define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 |
| 5987 | 6767 | ||
| 6768 | typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO{ | ||
| 6769 | USHORT usEngineClockLow; //clockfrequency & 0xFFFF. The unit is in 10khz | ||
| 6770 | UCHAR ucEngineClockHigh; //clockfrequency >> 16. | ||
| 6771 | UCHAR vddcIndex; //2-bit vddc index; | ||
| 6772 | UCHAR leakage; //please use 8-bit absolute value, not the 6-bit % value | ||
| 6773 | //please initalize to 0 | ||
| 6774 | UCHAR rsv; | ||
| 6775 | //please initalize to 0 | ||
| 6776 | USHORT rsv1; | ||
| 6777 | //please initialize to 0s | ||
| 6778 | ULONG rsv2[2]; | ||
| 6779 | }ATOM_PPLIB_SUMO_CLOCK_INFO; | ||
| 6780 | |||
| 6781 | |||
| 6782 | |||
| 6783 | typedef struct _ATOM_PPLIB_STATE_V2 | ||
| 6784 | { | ||
| 6785 | //number of valid dpm levels in this state; Driver uses it to calculate the whole | ||
| 6786 | //size of the state: sizeof(ATOM_PPLIB_STATE_V2) + (ucNumDPMLevels - 1) * sizeof(UCHAR) | ||
| 6787 | UCHAR ucNumDPMLevels; | ||
| 6788 | |||
| 6789 | //a index to the array of nonClockInfos | ||
| 6790 | UCHAR nonClockInfoIndex; | ||
| 6791 | /** | ||
| 6792 | * Driver will read the first ucNumDPMLevels in this array | ||
| 6793 | */ | ||
| 6794 | UCHAR clockInfoIndex[1]; | ||
| 6795 | } ATOM_PPLIB_STATE_V2; | ||
| 6796 | |||
| 6797 | typedef struct StateArray{ | ||
| 6798 | //how many states we have | ||
| 6799 | UCHAR ucNumEntries; | ||
| 6800 | |||
| 6801 | ATOM_PPLIB_STATE_V2 states[1]; | ||
| 6802 | }StateArray; | ||
| 6803 | |||
| 6804 | |||
| 6805 | typedef struct ClockInfoArray{ | ||
| 6806 | //how many clock levels we have | ||
| 6807 | UCHAR ucNumEntries; | ||
| 6808 | |||
| 6809 | //sizeof(ATOM_PPLIB_SUMO_CLOCK_INFO) | ||
| 6810 | UCHAR ucEntrySize; | ||
| 6811 | |||
| 6812 | //this is for Sumo | ||
| 6813 | ATOM_PPLIB_SUMO_CLOCK_INFO clockInfo[1]; | ||
| 6814 | }ClockInfoArray; | ||
| 6815 | |||
| 6816 | typedef struct NonClockInfoArray{ | ||
| 6817 | |||
| 6818 | //how many non-clock levels we have. normally should be same as number of states | ||
| 6819 | UCHAR ucNumEntries; | ||
| 6820 | //sizeof(ATOM_PPLIB_NONCLOCK_INFO) | ||
| 6821 | UCHAR ucEntrySize; | ||
| 6822 | |||
| 6823 | ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1]; | ||
| 6824 | }NonClockInfoArray; | ||
| 6825 | |||
| 6826 | typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record | ||
| 6827 | { | ||
| 6828 | USHORT usClockLow; | ||
| 6829 | UCHAR ucClockHigh; | ||
| 6830 | USHORT usVoltage; | ||
| 6831 | }ATOM_PPLIB_Clock_Voltage_Dependency_Record; | ||
| 6832 | |||
| 6833 | typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table | ||
| 6834 | { | ||
| 6835 | UCHAR ucNumEntries; // Number of entries. | ||
| 6836 | ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries. | ||
| 6837 | }ATOM_PPLIB_Clock_Voltage_Dependency_Table; | ||
| 6838 | |||
| 6839 | typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record | ||
| 6840 | { | ||
| 6841 | USHORT usSclkLow; | ||
| 6842 | UCHAR ucSclkHigh; | ||
| 6843 | USHORT usMclkLow; | ||
| 6844 | UCHAR ucMclkHigh; | ||
| 6845 | USHORT usVddc; | ||
| 6846 | USHORT usVddci; | ||
| 6847 | }ATOM_PPLIB_Clock_Voltage_Limit_Record; | ||
| 6848 | |||
| 6849 | typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table | ||
| 6850 | { | ||
| 6851 | UCHAR ucNumEntries; // Number of entries. | ||
| 6852 | ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries. | ||
| 6853 | }ATOM_PPLIB_Clock_Voltage_Limit_Table; | ||
| 6854 | |||
| 5988 | /**************************************************************************/ | 6855 | /**************************************************************************/ |
| 5989 | 6856 | ||
| 5990 | 6857 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9fbabaa6ee44..b0ab185b86f6 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -403,6 +403,7 @@ union atom_enable_ss { | |||
| 403 | ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2; | 403 | ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2; |
| 404 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; | 404 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; |
| 405 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2; | 405 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2; |
| 406 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; | ||
| 406 | }; | 407 | }; |
| 407 | 408 | ||
| 408 | static void atombios_crtc_program_ss(struct drm_crtc *crtc, | 409 | static void atombios_crtc_program_ss(struct drm_crtc *crtc, |
| @@ -417,7 +418,30 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, | |||
| 417 | 418 | ||
| 418 | memset(&args, 0, sizeof(args)); | 419 | memset(&args, 0, sizeof(args)); |
| 419 | 420 | ||
| 420 | if (ASIC_IS_DCE4(rdev)) { | 421 | if (ASIC_IS_DCE5(rdev)) { |
| 422 | args.v3.usSpreadSpectrumAmountFrac = 0; | ||
| 423 | args.v3.ucSpreadSpectrumType = ss->type; | ||
| 424 | switch (pll_id) { | ||
| 425 | case ATOM_PPLL1: | ||
| 426 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; | ||
| 427 | args.v3.usSpreadSpectrumAmount = ss->amount; | ||
| 428 | args.v3.usSpreadSpectrumStep = ss->step; | ||
| 429 | break; | ||
| 430 | case ATOM_PPLL2: | ||
| 431 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; | ||
| 432 | args.v3.usSpreadSpectrumAmount = ss->amount; | ||
| 433 | args.v3.usSpreadSpectrumStep = ss->step; | ||
| 434 | break; | ||
| 435 | case ATOM_DCPLL: | ||
| 436 | args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; | ||
| 437 | args.v3.usSpreadSpectrumAmount = 0; | ||
| 438 | args.v3.usSpreadSpectrumStep = 0; | ||
| 439 | break; | ||
| 440 | case ATOM_PPLL_INVALID: | ||
| 441 | return; | ||
| 442 | } | ||
| 443 | args.v2.ucEnable = enable; | ||
| 444 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 421 | args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); | 445 | args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
| 422 | args.v2.ucSpreadSpectrumType = ss->type; | 446 | args.v2.ucSpreadSpectrumType = ss->type; |
| 423 | switch (pll_id) { | 447 | switch (pll_id) { |
| @@ -673,9 +697,14 @@ union set_pixel_clock { | |||
| 673 | PIXEL_CLOCK_PARAMETERS_V2 v2; | 697 | PIXEL_CLOCK_PARAMETERS_V2 v2; |
| 674 | PIXEL_CLOCK_PARAMETERS_V3 v3; | 698 | PIXEL_CLOCK_PARAMETERS_V3 v3; |
| 675 | PIXEL_CLOCK_PARAMETERS_V5 v5; | 699 | PIXEL_CLOCK_PARAMETERS_V5 v5; |
| 700 | PIXEL_CLOCK_PARAMETERS_V6 v6; | ||
| 676 | }; | 701 | }; |
| 677 | 702 | ||
| 678 | static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) | 703 | /* on DCE5, make sure the voltage is high enough to support the |
| 704 | * required disp clk. | ||
| 705 | */ | ||
| 706 | static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, | ||
| 707 | u32 dispclk) | ||
| 679 | { | 708 | { |
| 680 | struct drm_device *dev = crtc->dev; | 709 | struct drm_device *dev = crtc->dev; |
| 681 | struct radeon_device *rdev = dev->dev_private; | 710 | struct radeon_device *rdev = dev->dev_private; |
| @@ -698,9 +727,16 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) | |||
| 698 | * SetPixelClock provides the dividers | 727 | * SetPixelClock provides the dividers |
| 699 | */ | 728 | */ |
| 700 | args.v5.ucCRTC = ATOM_CRTC_INVALID; | 729 | args.v5.ucCRTC = ATOM_CRTC_INVALID; |
| 701 | args.v5.usPixelClock = rdev->clock.default_dispclk; | 730 | args.v5.usPixelClock = dispclk; |
| 702 | args.v5.ucPpll = ATOM_DCPLL; | 731 | args.v5.ucPpll = ATOM_DCPLL; |
| 703 | break; | 732 | break; |
| 733 | case 6: | ||
| 734 | /* if the default dcpll clock is specified, | ||
| 735 | * SetPixelClock provides the dividers | ||
| 736 | */ | ||
| 737 | args.v6.ulDispEngClkFreq = dispclk; | ||
| 738 | args.v6.ucPpll = ATOM_DCPLL; | ||
| 739 | break; | ||
| 704 | default: | 740 | default: |
| 705 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | 741 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
| 706 | return; | 742 | return; |
| @@ -784,6 +820,18 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
| 784 | args.v5.ucEncoderMode = encoder_mode; | 820 | args.v5.ucEncoderMode = encoder_mode; |
| 785 | args.v5.ucPpll = pll_id; | 821 | args.v5.ucPpll = pll_id; |
| 786 | break; | 822 | break; |
| 823 | case 6: | ||
| 824 | args.v6.ulCrtcPclkFreq.ucCRTC = crtc_id; | ||
| 825 | args.v6.ulCrtcPclkFreq.ulPixelClock = cpu_to_le32(clock / 10); | ||
| 826 | args.v6.ucRefDiv = ref_div; | ||
| 827 | args.v6.usFbDiv = cpu_to_le16(fb_div); | ||
| 828 | args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); | ||
| 829 | args.v6.ucPostDiv = post_div; | ||
| 830 | args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */ | ||
| 831 | args.v6.ucTransmitterID = encoder_id; | ||
| 832 | args.v6.ucEncoderMode = encoder_mode; | ||
| 833 | args.v6.ucPpll = pll_id; | ||
| 834 | break; | ||
| 787 | default: | 835 | default: |
| 788 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | 836 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
| 789 | return; | 837 | return; |
| @@ -1377,7 +1425,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
| 1377 | rdev->clock.default_dispclk); | 1425 | rdev->clock.default_dispclk); |
| 1378 | if (ss_enabled) | 1426 | if (ss_enabled) |
| 1379 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss); | 1427 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss); |
| 1380 | atombios_crtc_set_dcpll(crtc); | 1428 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ |
| 1429 | atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk); | ||
| 1381 | if (ss_enabled) | 1430 | if (ss_enabled) |
| 1382 | atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss); | 1431 | atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss); |
| 1383 | } | 1432 | } |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 7b337c361a12..7fe8ebdcdc0e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -39,6 +39,62 @@ | |||
| 39 | 39 | ||
| 40 | static void evergreen_gpu_init(struct radeon_device *rdev); | 40 | static void evergreen_gpu_init(struct radeon_device *rdev); |
| 41 | void evergreen_fini(struct radeon_device *rdev); | 41 | void evergreen_fini(struct radeon_device *rdev); |
| 42 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | ||
| 43 | |||
| 44 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) | ||
| 45 | { | ||
| 46 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | ||
| 47 | u32 tmp; | ||
| 48 | |||
| 49 | /* make sure flip is at vb rather than hb */ | ||
| 50 | tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); | ||
| 51 | tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; | ||
| 52 | WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); | ||
| 53 | |||
| 54 | /* set pageflip to happen anywhere in vblank interval */ | ||
| 55 | WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); | ||
| 56 | |||
| 57 | /* enable the pflip int */ | ||
| 58 | radeon_irq_kms_pflip_irq_get(rdev, crtc); | ||
| 59 | } | ||
| 60 | |||
| 61 | void evergreen_post_page_flip(struct radeon_device *rdev, int crtc) | ||
| 62 | { | ||
| 63 | /* disable the pflip int */ | ||
| 64 | radeon_irq_kms_pflip_irq_put(rdev, crtc); | ||
| 65 | } | ||
| 66 | |||
| 67 | u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | ||
| 68 | { | ||
| 69 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
| 70 | u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); | ||
| 71 | |||
| 72 | /* Lock the graphics update lock */ | ||
| 73 | tmp |= EVERGREEN_GRPH_UPDATE_LOCK; | ||
| 74 | WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
| 75 | |||
| 76 | /* update the scanout addresses */ | ||
| 77 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
| 78 | upper_32_bits(crtc_base)); | ||
| 79 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
| 80 | (u32)crtc_base); | ||
| 81 | |||
| 82 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
| 83 | upper_32_bits(crtc_base)); | ||
| 84 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
| 85 | (u32)crtc_base); | ||
| 86 | |||
| 87 | /* Wait for update_pending to go high. */ | ||
| 88 | while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)); | ||
| 89 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | ||
| 90 | |||
| 91 | /* Unlock the lock, so double-buffering can take place inside vblank */ | ||
| 92 | tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK; | ||
| 93 | WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
| 94 | |||
| 95 | /* Return current update_pending status: */ | ||
| 96 | return RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING; | ||
| 97 | } | ||
| 42 | 98 | ||
| 43 | /* get temperature in millidegrees */ | 99 | /* get temperature in millidegrees */ |
| 44 | u32 evergreen_get_temp(struct radeon_device *rdev) | 100 | u32 evergreen_get_temp(struct radeon_device *rdev) |
| @@ -57,6 +113,14 @@ u32 evergreen_get_temp(struct radeon_device *rdev) | |||
| 57 | return actual_temp * 1000; | 113 | return actual_temp * 1000; |
| 58 | } | 114 | } |
| 59 | 115 | ||
| 116 | u32 sumo_get_temp(struct radeon_device *rdev) | ||
| 117 | { | ||
| 118 | u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff; | ||
| 119 | u32 actual_temp = (temp >> 1) & 0xff; | ||
| 120 | |||
| 121 | return actual_temp * 1000; | ||
| 122 | } | ||
| 123 | |||
| 60 | void evergreen_pm_misc(struct radeon_device *rdev) | 124 | void evergreen_pm_misc(struct radeon_device *rdev) |
| 61 | { | 125 | { |
| 62 | int req_ps_idx = rdev->pm.requested_power_state_index; | 126 | int req_ps_idx = rdev->pm.requested_power_state_index; |
| @@ -337,16 +401,28 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, | |||
| 337 | case 0: | 401 | case 0: |
| 338 | case 4: | 402 | case 4: |
| 339 | default: | 403 | default: |
| 340 | return 3840 * 2; | 404 | if (ASIC_IS_DCE5(rdev)) |
| 405 | return 4096 * 2; | ||
| 406 | else | ||
| 407 | return 3840 * 2; | ||
| 341 | case 1: | 408 | case 1: |
| 342 | case 5: | 409 | case 5: |
| 343 | return 5760 * 2; | 410 | if (ASIC_IS_DCE5(rdev)) |
| 411 | return 6144 * 2; | ||
| 412 | else | ||
| 413 | return 5760 * 2; | ||
| 344 | case 2: | 414 | case 2: |
| 345 | case 6: | 415 | case 6: |
| 346 | return 7680 * 2; | 416 | if (ASIC_IS_DCE5(rdev)) |
| 417 | return 8192 * 2; | ||
| 418 | else | ||
| 419 | return 7680 * 2; | ||
| 347 | case 3: | 420 | case 3: |
| 348 | case 7: | 421 | case 7: |
| 349 | return 1920 * 2; | 422 | if (ASIC_IS_DCE5(rdev)) |
| 423 | return 2048 * 2; | ||
| 424 | else | ||
| 425 | return 1920 * 2; | ||
| 350 | } | 426 | } |
| 351 | } | 427 | } |
| 352 | 428 | ||
| @@ -890,31 +966,39 @@ static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa | |||
| 890 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 966 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
| 891 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | 967 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); |
| 892 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | 968 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); |
| 893 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | 969 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 894 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | 970 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); |
| 895 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | 971 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); |
| 896 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | 972 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); |
| 973 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
| 974 | } | ||
| 897 | 975 | ||
| 898 | /* Stop all video */ | 976 | /* Stop all video */ |
| 899 | WREG32(VGA_RENDER_CONTROL, 0); | 977 | WREG32(VGA_RENDER_CONTROL, 0); |
| 900 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | 978 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); |
| 901 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | 979 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); |
| 902 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | 980 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 903 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | 981 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); |
| 904 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | 982 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); |
| 905 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | 983 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); |
| 984 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
| 985 | } | ||
| 906 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 986 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
| 907 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 987 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
| 908 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 988 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 909 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 989 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
| 910 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 990 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
| 911 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 991 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
| 992 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 993 | } | ||
| 912 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 994 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
| 913 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 995 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
| 914 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 996 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 915 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 997 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
| 916 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 998 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
| 917 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 999 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
| 1000 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 1001 | } | ||
| 918 | 1002 | ||
| 919 | WREG32(D1VGA_CONTROL, 0); | 1003 | WREG32(D1VGA_CONTROL, 0); |
| 920 | WREG32(D2VGA_CONTROL, 0); | 1004 | WREG32(D2VGA_CONTROL, 0); |
| @@ -944,41 +1028,43 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ | |||
| 944 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, | 1028 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, |
| 945 | (u32)rdev->mc.vram_start); | 1029 | (u32)rdev->mc.vram_start); |
| 946 | 1030 | ||
| 947 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1031 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 948 | upper_32_bits(rdev->mc.vram_start)); | 1032 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, |
| 949 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1033 | upper_32_bits(rdev->mc.vram_start)); |
| 950 | upper_32_bits(rdev->mc.vram_start)); | 1034 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, |
| 951 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1035 | upper_32_bits(rdev->mc.vram_start)); |
| 952 | (u32)rdev->mc.vram_start); | 1036 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, |
| 953 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1037 | (u32)rdev->mc.vram_start); |
| 954 | (u32)rdev->mc.vram_start); | 1038 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, |
| 955 | 1039 | (u32)rdev->mc.vram_start); | |
| 956 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1040 | |
| 957 | upper_32_bits(rdev->mc.vram_start)); | 1041 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, |
| 958 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1042 | upper_32_bits(rdev->mc.vram_start)); |
| 959 | upper_32_bits(rdev->mc.vram_start)); | 1043 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, |
| 960 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1044 | upper_32_bits(rdev->mc.vram_start)); |
| 961 | (u32)rdev->mc.vram_start); | 1045 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, |
| 962 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1046 | (u32)rdev->mc.vram_start); |
| 963 | (u32)rdev->mc.vram_start); | 1047 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, |
| 964 | 1048 | (u32)rdev->mc.vram_start); | |
| 965 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1049 | |
| 966 | upper_32_bits(rdev->mc.vram_start)); | 1050 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, |
| 967 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1051 | upper_32_bits(rdev->mc.vram_start)); |
| 968 | upper_32_bits(rdev->mc.vram_start)); | 1052 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, |
| 969 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1053 | upper_32_bits(rdev->mc.vram_start)); |
| 970 | (u32)rdev->mc.vram_start); | 1054 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, |
| 971 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1055 | (u32)rdev->mc.vram_start); |
| 972 | (u32)rdev->mc.vram_start); | 1056 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, |
| 973 | 1057 | (u32)rdev->mc.vram_start); | |
| 974 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1058 | |
| 975 | upper_32_bits(rdev->mc.vram_start)); | 1059 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, |
| 976 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1060 | upper_32_bits(rdev->mc.vram_start)); |
| 977 | upper_32_bits(rdev->mc.vram_start)); | 1061 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, |
| 978 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1062 | upper_32_bits(rdev->mc.vram_start)); |
| 979 | (u32)rdev->mc.vram_start); | 1063 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, |
| 980 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1064 | (u32)rdev->mc.vram_start); |
| 981 | (u32)rdev->mc.vram_start); | 1065 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, |
| 1066 | (u32)rdev->mc.vram_start); | ||
| 1067 | } | ||
| 982 | 1068 | ||
| 983 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); | 1069 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); |
| 984 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); | 1070 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); |
| @@ -994,22 +1080,28 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ | |||
| 994 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | 1080 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); |
| 995 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | 1081 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); |
| 996 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | 1082 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); |
| 997 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | 1083 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 998 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | 1084 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); |
| 999 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | 1085 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); |
| 1000 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | 1086 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); |
| 1087 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
| 1088 | } | ||
| 1001 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | 1089 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); |
| 1002 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | 1090 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); |
| 1003 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | 1091 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 1004 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | 1092 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); |
| 1005 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | 1093 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); |
| 1006 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | 1094 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); |
| 1095 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
| 1096 | } | ||
| 1007 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1097 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
| 1008 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1098 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
| 1009 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1099 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 1010 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1100 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
| 1011 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1101 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
| 1012 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1102 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
| 1103 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 1104 | } | ||
| 1013 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1105 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
| 1014 | } | 1106 | } |
| 1015 | 1107 | ||
| @@ -1057,11 +1149,17 @@ static void evergreen_mc_program(struct radeon_device *rdev) | |||
| 1057 | rdev->mc.vram_end >> 12); | 1149 | rdev->mc.vram_end >> 12); |
| 1058 | } | 1150 | } |
| 1059 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 1151 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); |
| 1152 | if (rdev->flags & RADEON_IS_IGP) { | ||
| 1153 | tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; | ||
| 1154 | tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; | ||
| 1155 | tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20; | ||
| 1156 | WREG32(MC_FUS_VM_FB_OFFSET, tmp); | ||
| 1157 | } | ||
| 1060 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 1158 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
| 1061 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 1159 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
| 1062 | WREG32(MC_VM_FB_LOCATION, tmp); | 1160 | WREG32(MC_VM_FB_LOCATION, tmp); |
| 1063 | WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); | 1161 | WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); |
| 1064 | WREG32(HDP_NONSURFACE_INFO, (2 << 7)); | 1162 | WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); |
| 1065 | WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); | 1163 | WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); |
| 1066 | if (rdev->flags & RADEON_IS_AGP) { | 1164 | if (rdev->flags & RADEON_IS_AGP) { |
| 1067 | WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); | 1165 | WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); |
| @@ -1285,11 +1383,15 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
| 1285 | switch (rdev->family) { | 1383 | switch (rdev->family) { |
| 1286 | case CHIP_CEDAR: | 1384 | case CHIP_CEDAR: |
| 1287 | case CHIP_REDWOOD: | 1385 | case CHIP_REDWOOD: |
| 1386 | case CHIP_PALM: | ||
| 1387 | case CHIP_TURKS: | ||
| 1388 | case CHIP_CAICOS: | ||
| 1288 | force_no_swizzle = false; | 1389 | force_no_swizzle = false; |
| 1289 | break; | 1390 | break; |
| 1290 | case CHIP_CYPRESS: | 1391 | case CHIP_CYPRESS: |
| 1291 | case CHIP_HEMLOCK: | 1392 | case CHIP_HEMLOCK: |
| 1292 | case CHIP_JUNIPER: | 1393 | case CHIP_JUNIPER: |
| 1394 | case CHIP_BARTS: | ||
| 1293 | default: | 1395 | default: |
| 1294 | force_no_swizzle = true; | 1396 | force_no_swizzle = true; |
| 1295 | break; | 1397 | break; |
| @@ -1384,6 +1486,46 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
| 1384 | return backend_map; | 1486 | return backend_map; |
| 1385 | } | 1487 | } |
| 1386 | 1488 | ||
| 1489 | static void evergreen_program_channel_remap(struct radeon_device *rdev) | ||
| 1490 | { | ||
| 1491 | u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; | ||
| 1492 | |||
| 1493 | tmp = RREG32(MC_SHARED_CHMAP); | ||
| 1494 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
| 1495 | case 0: | ||
| 1496 | case 1: | ||
| 1497 | case 2: | ||
| 1498 | case 3: | ||
| 1499 | default: | ||
| 1500 | /* default mapping */ | ||
| 1501 | mc_shared_chremap = 0x00fac688; | ||
| 1502 | break; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | switch (rdev->family) { | ||
| 1506 | case CHIP_HEMLOCK: | ||
| 1507 | case CHIP_CYPRESS: | ||
| 1508 | case CHIP_BARTS: | ||
| 1509 | tcp_chan_steer_lo = 0x54763210; | ||
| 1510 | tcp_chan_steer_hi = 0x0000ba98; | ||
| 1511 | break; | ||
| 1512 | case CHIP_JUNIPER: | ||
| 1513 | case CHIP_REDWOOD: | ||
| 1514 | case CHIP_CEDAR: | ||
| 1515 | case CHIP_PALM: | ||
| 1516 | case CHIP_TURKS: | ||
| 1517 | case CHIP_CAICOS: | ||
| 1518 | default: | ||
| 1519 | tcp_chan_steer_lo = 0x76543210; | ||
| 1520 | tcp_chan_steer_hi = 0x0000ba98; | ||
| 1521 | break; | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); | ||
| 1525 | WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); | ||
| 1526 | WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); | ||
| 1527 | } | ||
| 1528 | |||
| 1387 | static void evergreen_gpu_init(struct radeon_device *rdev) | 1529 | static void evergreen_gpu_init(struct radeon_device *rdev) |
| 1388 | { | 1530 | { |
| 1389 | u32 cc_rb_backend_disable = 0; | 1531 | u32 cc_rb_backend_disable = 0; |
| @@ -1495,6 +1637,90 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1495 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | 1637 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; |
| 1496 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | 1638 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; |
| 1497 | break; | 1639 | break; |
| 1640 | case CHIP_PALM: | ||
| 1641 | rdev->config.evergreen.num_ses = 1; | ||
| 1642 | rdev->config.evergreen.max_pipes = 2; | ||
| 1643 | rdev->config.evergreen.max_tile_pipes = 2; | ||
| 1644 | rdev->config.evergreen.max_simds = 2; | ||
| 1645 | rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; | ||
| 1646 | rdev->config.evergreen.max_gprs = 256; | ||
| 1647 | rdev->config.evergreen.max_threads = 192; | ||
| 1648 | rdev->config.evergreen.max_gs_threads = 16; | ||
| 1649 | rdev->config.evergreen.max_stack_entries = 256; | ||
| 1650 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
| 1651 | rdev->config.evergreen.sx_max_export_size = 128; | ||
| 1652 | rdev->config.evergreen.sx_max_export_pos_size = 32; | ||
| 1653 | rdev->config.evergreen.sx_max_export_smx_size = 96; | ||
| 1654 | rdev->config.evergreen.max_hw_contexts = 4; | ||
| 1655 | rdev->config.evergreen.sq_num_cf_insts = 1; | ||
| 1656 | |||
| 1657 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | ||
| 1658 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
| 1659 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
| 1660 | break; | ||
| 1661 | case CHIP_BARTS: | ||
| 1662 | rdev->config.evergreen.num_ses = 2; | ||
| 1663 | rdev->config.evergreen.max_pipes = 4; | ||
| 1664 | rdev->config.evergreen.max_tile_pipes = 8; | ||
| 1665 | rdev->config.evergreen.max_simds = 7; | ||
| 1666 | rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; | ||
| 1667 | rdev->config.evergreen.max_gprs = 256; | ||
| 1668 | rdev->config.evergreen.max_threads = 248; | ||
| 1669 | rdev->config.evergreen.max_gs_threads = 32; | ||
| 1670 | rdev->config.evergreen.max_stack_entries = 512; | ||
| 1671 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
| 1672 | rdev->config.evergreen.sx_max_export_size = 256; | ||
| 1673 | rdev->config.evergreen.sx_max_export_pos_size = 64; | ||
| 1674 | rdev->config.evergreen.sx_max_export_smx_size = 192; | ||
| 1675 | rdev->config.evergreen.max_hw_contexts = 8; | ||
| 1676 | rdev->config.evergreen.sq_num_cf_insts = 2; | ||
| 1677 | |||
| 1678 | rdev->config.evergreen.sc_prim_fifo_size = 0x100; | ||
| 1679 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
| 1680 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
| 1681 | break; | ||
| 1682 | case CHIP_TURKS: | ||
| 1683 | rdev->config.evergreen.num_ses = 1; | ||
| 1684 | rdev->config.evergreen.max_pipes = 4; | ||
| 1685 | rdev->config.evergreen.max_tile_pipes = 4; | ||
| 1686 | rdev->config.evergreen.max_simds = 6; | ||
| 1687 | rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; | ||
| 1688 | rdev->config.evergreen.max_gprs = 256; | ||
| 1689 | rdev->config.evergreen.max_threads = 248; | ||
| 1690 | rdev->config.evergreen.max_gs_threads = 32; | ||
| 1691 | rdev->config.evergreen.max_stack_entries = 256; | ||
| 1692 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
| 1693 | rdev->config.evergreen.sx_max_export_size = 256; | ||
| 1694 | rdev->config.evergreen.sx_max_export_pos_size = 64; | ||
| 1695 | rdev->config.evergreen.sx_max_export_smx_size = 192; | ||
| 1696 | rdev->config.evergreen.max_hw_contexts = 8; | ||
| 1697 | rdev->config.evergreen.sq_num_cf_insts = 2; | ||
| 1698 | |||
| 1699 | rdev->config.evergreen.sc_prim_fifo_size = 0x100; | ||
| 1700 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
| 1701 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
| 1702 | break; | ||
| 1703 | case CHIP_CAICOS: | ||
| 1704 | rdev->config.evergreen.num_ses = 1; | ||
| 1705 | rdev->config.evergreen.max_pipes = 4; | ||
| 1706 | rdev->config.evergreen.max_tile_pipes = 2; | ||
| 1707 | rdev->config.evergreen.max_simds = 2; | ||
| 1708 | rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; | ||
| 1709 | rdev->config.evergreen.max_gprs = 256; | ||
| 1710 | rdev->config.evergreen.max_threads = 192; | ||
| 1711 | rdev->config.evergreen.max_gs_threads = 16; | ||
| 1712 | rdev->config.evergreen.max_stack_entries = 256; | ||
| 1713 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
| 1714 | rdev->config.evergreen.sx_max_export_size = 128; | ||
| 1715 | rdev->config.evergreen.sx_max_export_pos_size = 32; | ||
| 1716 | rdev->config.evergreen.sx_max_export_smx_size = 96; | ||
| 1717 | rdev->config.evergreen.max_hw_contexts = 4; | ||
| 1718 | rdev->config.evergreen.sq_num_cf_insts = 1; | ||
| 1719 | |||
| 1720 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | ||
| 1721 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
| 1722 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
| 1723 | break; | ||
| 1498 | } | 1724 | } |
| 1499 | 1725 | ||
| 1500 | /* Initialize HDP */ | 1726 | /* Initialize HDP */ |
| @@ -1636,6 +1862,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1636 | switch (rdev->family) { | 1862 | switch (rdev->family) { |
| 1637 | case CHIP_CYPRESS: | 1863 | case CHIP_CYPRESS: |
| 1638 | case CHIP_HEMLOCK: | 1864 | case CHIP_HEMLOCK: |
| 1865 | case CHIP_BARTS: | ||
| 1639 | gb_backend_map = 0x66442200; | 1866 | gb_backend_map = 0x66442200; |
| 1640 | break; | 1867 | break; |
| 1641 | case CHIP_JUNIPER: | 1868 | case CHIP_JUNIPER: |
| @@ -1687,6 +1914,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1687 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); | 1914 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); |
| 1688 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); | 1915 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); |
| 1689 | 1916 | ||
| 1917 | evergreen_program_channel_remap(rdev); | ||
| 1918 | |||
| 1690 | num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; | 1919 | num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; |
| 1691 | grbm_gfx_index = INSTANCE_BROADCAST_WRITES; | 1920 | grbm_gfx_index = INSTANCE_BROADCAST_WRITES; |
| 1692 | 1921 | ||
| @@ -1769,9 +1998,16 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1769 | GS_PRIO(2) | | 1998 | GS_PRIO(2) | |
| 1770 | ES_PRIO(3)); | 1999 | ES_PRIO(3)); |
| 1771 | 2000 | ||
| 1772 | if (rdev->family == CHIP_CEDAR) | 2001 | switch (rdev->family) { |
| 2002 | case CHIP_CEDAR: | ||
| 2003 | case CHIP_PALM: | ||
| 2004 | case CHIP_CAICOS: | ||
| 1773 | /* no vertex cache */ | 2005 | /* no vertex cache */ |
| 1774 | sq_config &= ~VC_ENABLE; | 2006 | sq_config &= ~VC_ENABLE; |
| 2007 | break; | ||
| 2008 | default: | ||
| 2009 | break; | ||
| 2010 | } | ||
| 1775 | 2011 | ||
| 1776 | sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT); | 2012 | sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT); |
| 1777 | 2013 | ||
| @@ -1783,10 +2019,15 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1783 | sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); | 2019 | sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); |
| 1784 | sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); | 2020 | sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); |
| 1785 | 2021 | ||
| 1786 | if (rdev->family == CHIP_CEDAR) | 2022 | switch (rdev->family) { |
| 2023 | case CHIP_CEDAR: | ||
| 2024 | case CHIP_PALM: | ||
| 1787 | ps_thread_count = 96; | 2025 | ps_thread_count = 96; |
| 1788 | else | 2026 | break; |
| 2027 | default: | ||
| 1789 | ps_thread_count = 128; | 2028 | ps_thread_count = 128; |
| 2029 | break; | ||
| 2030 | } | ||
| 1790 | 2031 | ||
| 1791 | sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); | 2032 | sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); |
| 1792 | sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); | 2033 | sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); |
| @@ -1817,10 +2058,16 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1817 | WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | | 2058 | WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | |
| 1818 | FORCE_EOV_MAX_REZ_CNT(255))); | 2059 | FORCE_EOV_MAX_REZ_CNT(255))); |
| 1819 | 2060 | ||
| 1820 | if (rdev->family == CHIP_CEDAR) | 2061 | switch (rdev->family) { |
| 2062 | case CHIP_CEDAR: | ||
| 2063 | case CHIP_PALM: | ||
| 2064 | case CHIP_CAICOS: | ||
| 1821 | vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY); | 2065 | vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY); |
| 1822 | else | 2066 | break; |
| 2067 | default: | ||
| 1823 | vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC); | 2068 | vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC); |
| 2069 | break; | ||
| 2070 | } | ||
| 1824 | vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO); | 2071 | vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO); |
| 1825 | WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); | 2072 | WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); |
| 1826 | 2073 | ||
| @@ -1904,12 +2151,18 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
| 1904 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); | 2151 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
| 1905 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); | 2152 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
| 1906 | /* Setup GPU memory space */ | 2153 | /* Setup GPU memory space */ |
| 1907 | /* size in MB on evergreen */ | 2154 | if (rdev->flags & RADEON_IS_IGP) { |
| 1908 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 2155 | /* size in bytes on fusion */ |
| 1909 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 2156 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
| 2157 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | ||
| 2158 | } else { | ||
| 2159 | /* size in MB on evergreen */ | ||
| 2160 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | ||
| 2161 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | ||
| 2162 | } | ||
| 1910 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 2163 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 1911 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 2164 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; |
| 1912 | r600_vram_gtt_location(rdev, &rdev->mc); | 2165 | r700_vram_gtt_location(rdev, &rdev->mc); |
| 1913 | radeon_update_bandwidth_info(rdev); | 2166 | radeon_update_bandwidth_info(rdev); |
| 1914 | 2167 | ||
| 1915 | return 0; | 2168 | return 0; |
| @@ -1917,8 +2170,30 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
| 1917 | 2170 | ||
| 1918 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev) | 2171 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev) |
| 1919 | { | 2172 | { |
| 1920 | /* FIXME: implement for evergreen */ | 2173 | u32 srbm_status; |
| 1921 | return false; | 2174 | u32 grbm_status; |
| 2175 | u32 grbm_status_se0, grbm_status_se1; | ||
| 2176 | struct r100_gpu_lockup *lockup = &rdev->config.evergreen.lockup; | ||
| 2177 | int r; | ||
| 2178 | |||
| 2179 | srbm_status = RREG32(SRBM_STATUS); | ||
| 2180 | grbm_status = RREG32(GRBM_STATUS); | ||
| 2181 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); | ||
| 2182 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); | ||
| 2183 | if (!(grbm_status & GUI_ACTIVE)) { | ||
| 2184 | r100_gpu_lockup_update(lockup, &rdev->cp); | ||
| 2185 | return false; | ||
| 2186 | } | ||
| 2187 | /* force CP activities */ | ||
| 2188 | r = radeon_ring_lock(rdev, 2); | ||
| 2189 | if (!r) { | ||
| 2190 | /* PACKET2 NOP */ | ||
| 2191 | radeon_ring_write(rdev, 0x80000000); | ||
| 2192 | radeon_ring_write(rdev, 0x80000000); | ||
| 2193 | radeon_ring_unlock_commit(rdev); | ||
| 2194 | } | ||
| 2195 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | ||
| 2196 | return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); | ||
| 1922 | } | 2197 | } |
| 1923 | 2198 | ||
| 1924 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | 2199 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) |
| @@ -2011,17 +2286,21 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
| 2011 | WREG32(GRBM_INT_CNTL, 0); | 2286 | WREG32(GRBM_INT_CNTL, 0); |
| 2012 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2287 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
| 2013 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2288 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
| 2014 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 2289 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 2015 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 2290 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
| 2016 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 2291 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
| 2017 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 2292 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
| 2293 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 2294 | } | ||
| 2018 | 2295 | ||
| 2019 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2296 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
| 2020 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2297 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
| 2021 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 2298 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 2022 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 2299 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
| 2023 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 2300 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
| 2024 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 2301 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
| 2302 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 2303 | } | ||
| 2025 | 2304 | ||
| 2026 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | 2305 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); |
| 2027 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); | 2306 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); |
| @@ -2047,6 +2326,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
| 2047 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; | 2326 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; |
| 2048 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 2327 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; |
| 2049 | u32 grbm_int_cntl = 0; | 2328 | u32 grbm_int_cntl = 0; |
| 2329 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | ||
| 2050 | 2330 | ||
| 2051 | if (!rdev->irq.installed) { | 2331 | if (!rdev->irq.installed) { |
| 2052 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 2332 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
| @@ -2072,27 +2352,33 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
| 2072 | cp_int_cntl |= RB_INT_ENABLE; | 2352 | cp_int_cntl |= RB_INT_ENABLE; |
| 2073 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 2353 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
| 2074 | } | 2354 | } |
| 2075 | if (rdev->irq.crtc_vblank_int[0]) { | 2355 | if (rdev->irq.crtc_vblank_int[0] || |
| 2356 | rdev->irq.pflip[0]) { | ||
| 2076 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); | 2357 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); |
| 2077 | crtc1 |= VBLANK_INT_MASK; | 2358 | crtc1 |= VBLANK_INT_MASK; |
| 2078 | } | 2359 | } |
| 2079 | if (rdev->irq.crtc_vblank_int[1]) { | 2360 | if (rdev->irq.crtc_vblank_int[1] || |
| 2361 | rdev->irq.pflip[1]) { | ||
| 2080 | DRM_DEBUG("evergreen_irq_set: vblank 1\n"); | 2362 | DRM_DEBUG("evergreen_irq_set: vblank 1\n"); |
| 2081 | crtc2 |= VBLANK_INT_MASK; | 2363 | crtc2 |= VBLANK_INT_MASK; |
| 2082 | } | 2364 | } |
| 2083 | if (rdev->irq.crtc_vblank_int[2]) { | 2365 | if (rdev->irq.crtc_vblank_int[2] || |
| 2366 | rdev->irq.pflip[2]) { | ||
| 2084 | DRM_DEBUG("evergreen_irq_set: vblank 2\n"); | 2367 | DRM_DEBUG("evergreen_irq_set: vblank 2\n"); |
| 2085 | crtc3 |= VBLANK_INT_MASK; | 2368 | crtc3 |= VBLANK_INT_MASK; |
| 2086 | } | 2369 | } |
| 2087 | if (rdev->irq.crtc_vblank_int[3]) { | 2370 | if (rdev->irq.crtc_vblank_int[3] || |
| 2371 | rdev->irq.pflip[3]) { | ||
| 2088 | DRM_DEBUG("evergreen_irq_set: vblank 3\n"); | 2372 | DRM_DEBUG("evergreen_irq_set: vblank 3\n"); |
| 2089 | crtc4 |= VBLANK_INT_MASK; | 2373 | crtc4 |= VBLANK_INT_MASK; |
| 2090 | } | 2374 | } |
| 2091 | if (rdev->irq.crtc_vblank_int[4]) { | 2375 | if (rdev->irq.crtc_vblank_int[4] || |
| 2376 | rdev->irq.pflip[4]) { | ||
| 2092 | DRM_DEBUG("evergreen_irq_set: vblank 4\n"); | 2377 | DRM_DEBUG("evergreen_irq_set: vblank 4\n"); |
| 2093 | crtc5 |= VBLANK_INT_MASK; | 2378 | crtc5 |= VBLANK_INT_MASK; |
| 2094 | } | 2379 | } |
| 2095 | if (rdev->irq.crtc_vblank_int[5]) { | 2380 | if (rdev->irq.crtc_vblank_int[5] || |
| 2381 | rdev->irq.pflip[5]) { | ||
| 2096 | DRM_DEBUG("evergreen_irq_set: vblank 5\n"); | 2382 | DRM_DEBUG("evergreen_irq_set: vblank 5\n"); |
| 2097 | crtc6 |= VBLANK_INT_MASK; | 2383 | crtc6 |= VBLANK_INT_MASK; |
| 2098 | } | 2384 | } |
| @@ -2130,10 +2416,19 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
| 2130 | 2416 | ||
| 2131 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 2417 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
| 2132 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); | 2418 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); |
| 2133 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); | 2419 | if (!(rdev->flags & RADEON_IS_IGP)) { |
| 2134 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); | 2420 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); |
| 2135 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); | 2421 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); |
| 2136 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | 2422 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); |
| 2423 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | ||
| 2424 | } | ||
| 2425 | |||
| 2426 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); | ||
| 2427 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); | ||
| 2428 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); | ||
| 2429 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); | ||
| 2430 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); | ||
| 2431 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); | ||
| 2137 | 2432 | ||
| 2138 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 2433 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
| 2139 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | 2434 | WREG32(DC_HPD2_INT_CONTROL, hpd2); |
| @@ -2145,79 +2440,92 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
| 2145 | return 0; | 2440 | return 0; |
| 2146 | } | 2441 | } |
| 2147 | 2442 | ||
| 2148 | static inline void evergreen_irq_ack(struct radeon_device *rdev, | 2443 | static inline void evergreen_irq_ack(struct radeon_device *rdev) |
| 2149 | u32 *disp_int, | ||
| 2150 | u32 *disp_int_cont, | ||
| 2151 | u32 *disp_int_cont2, | ||
| 2152 | u32 *disp_int_cont3, | ||
| 2153 | u32 *disp_int_cont4, | ||
| 2154 | u32 *disp_int_cont5) | ||
| 2155 | { | 2444 | { |
| 2156 | u32 tmp; | 2445 | u32 tmp; |
| 2157 | 2446 | ||
| 2158 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | 2447 | rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
| 2159 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | 2448 | rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
| 2160 | *disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); | 2449 | rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); |
| 2161 | *disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); | 2450 | rdev->irq.stat_regs.evergreen.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); |
| 2162 | *disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); | 2451 | rdev->irq.stat_regs.evergreen.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); |
| 2163 | *disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); | 2452 | rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); |
| 2164 | 2453 | rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); | |
| 2165 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) | 2454 | rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); |
| 2455 | rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
| 2456 | rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
| 2457 | rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
| 2458 | rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
| 2459 | |||
| 2460 | if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
| 2461 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
| 2462 | if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
| 2463 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
| 2464 | if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
| 2465 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
| 2466 | if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
| 2467 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
| 2468 | if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
| 2469 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
| 2470 | if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
| 2471 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
| 2472 | |||
| 2473 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) | ||
| 2166 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); | 2474 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); |
| 2167 | if (*disp_int & LB_D1_VLINE_INTERRUPT) | 2475 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) |
| 2168 | WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); | 2476 | WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); |
| 2169 | 2477 | ||
| 2170 | if (*disp_int_cont & LB_D2_VBLANK_INTERRUPT) | 2478 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) |
| 2171 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); | 2479 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); |
| 2172 | if (*disp_int_cont & LB_D2_VLINE_INTERRUPT) | 2480 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) |
| 2173 | WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); | 2481 | WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); |
| 2174 | 2482 | ||
| 2175 | if (*disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) | 2483 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) |
| 2176 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); | 2484 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); |
| 2177 | if (*disp_int_cont2 & LB_D3_VLINE_INTERRUPT) | 2485 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) |
| 2178 | WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); | 2486 | WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); |
| 2179 | 2487 | ||
| 2180 | if (*disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) | 2488 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) |
| 2181 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); | 2489 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); |
| 2182 | if (*disp_int_cont3 & LB_D4_VLINE_INTERRUPT) | 2490 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) |
| 2183 | WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); | 2491 | WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); |
| 2184 | 2492 | ||
| 2185 | if (*disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) | 2493 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) |
| 2186 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); | 2494 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); |
| 2187 | if (*disp_int_cont4 & LB_D5_VLINE_INTERRUPT) | 2495 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) |
| 2188 | WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); | 2496 | WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); |
| 2189 | 2497 | ||
| 2190 | if (*disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) | 2498 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) |
| 2191 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); | 2499 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); |
| 2192 | if (*disp_int_cont5 & LB_D6_VLINE_INTERRUPT) | 2500 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) |
| 2193 | WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); | 2501 | WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); |
| 2194 | 2502 | ||
| 2195 | if (*disp_int & DC_HPD1_INTERRUPT) { | 2503 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { |
| 2196 | tmp = RREG32(DC_HPD1_INT_CONTROL); | 2504 | tmp = RREG32(DC_HPD1_INT_CONTROL); |
| 2197 | tmp |= DC_HPDx_INT_ACK; | 2505 | tmp |= DC_HPDx_INT_ACK; |
| 2198 | WREG32(DC_HPD1_INT_CONTROL, tmp); | 2506 | WREG32(DC_HPD1_INT_CONTROL, tmp); |
| 2199 | } | 2507 | } |
| 2200 | if (*disp_int_cont & DC_HPD2_INTERRUPT) { | 2508 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { |
| 2201 | tmp = RREG32(DC_HPD2_INT_CONTROL); | 2509 | tmp = RREG32(DC_HPD2_INT_CONTROL); |
| 2202 | tmp |= DC_HPDx_INT_ACK; | 2510 | tmp |= DC_HPDx_INT_ACK; |
| 2203 | WREG32(DC_HPD2_INT_CONTROL, tmp); | 2511 | WREG32(DC_HPD2_INT_CONTROL, tmp); |
| 2204 | } | 2512 | } |
| 2205 | if (*disp_int_cont2 & DC_HPD3_INTERRUPT) { | 2513 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { |
| 2206 | tmp = RREG32(DC_HPD3_INT_CONTROL); | 2514 | tmp = RREG32(DC_HPD3_INT_CONTROL); |
| 2207 | tmp |= DC_HPDx_INT_ACK; | 2515 | tmp |= DC_HPDx_INT_ACK; |
| 2208 | WREG32(DC_HPD3_INT_CONTROL, tmp); | 2516 | WREG32(DC_HPD3_INT_CONTROL, tmp); |
| 2209 | } | 2517 | } |
| 2210 | if (*disp_int_cont3 & DC_HPD4_INTERRUPT) { | 2518 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { |
| 2211 | tmp = RREG32(DC_HPD4_INT_CONTROL); | 2519 | tmp = RREG32(DC_HPD4_INT_CONTROL); |
| 2212 | tmp |= DC_HPDx_INT_ACK; | 2520 | tmp |= DC_HPDx_INT_ACK; |
| 2213 | WREG32(DC_HPD4_INT_CONTROL, tmp); | 2521 | WREG32(DC_HPD4_INT_CONTROL, tmp); |
| 2214 | } | 2522 | } |
| 2215 | if (*disp_int_cont4 & DC_HPD5_INTERRUPT) { | 2523 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { |
| 2216 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 2524 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
| 2217 | tmp |= DC_HPDx_INT_ACK; | 2525 | tmp |= DC_HPDx_INT_ACK; |
| 2218 | WREG32(DC_HPD5_INT_CONTROL, tmp); | 2526 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
| 2219 | } | 2527 | } |
| 2220 | if (*disp_int_cont5 & DC_HPD6_INTERRUPT) { | 2528 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { |
| 2221 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 2529 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
| 2222 | tmp |= DC_HPDx_INT_ACK; | 2530 | tmp |= DC_HPDx_INT_ACK; |
| 2223 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 2531 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
| @@ -2226,14 +2534,10 @@ static inline void evergreen_irq_ack(struct radeon_device *rdev, | |||
| 2226 | 2534 | ||
| 2227 | void evergreen_irq_disable(struct radeon_device *rdev) | 2535 | void evergreen_irq_disable(struct radeon_device *rdev) |
| 2228 | { | 2536 | { |
| 2229 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
| 2230 | u32 disp_int_cont3, disp_int_cont4, disp_int_cont5; | ||
| 2231 | |||
| 2232 | r600_disable_interrupts(rdev); | 2537 | r600_disable_interrupts(rdev); |
| 2233 | /* Wait and acknowledge irq */ | 2538 | /* Wait and acknowledge irq */ |
| 2234 | mdelay(1); | 2539 | mdelay(1); |
| 2235 | evergreen_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2, | 2540 | evergreen_irq_ack(rdev); |
| 2236 | &disp_int_cont3, &disp_int_cont4, &disp_int_cont5); | ||
| 2237 | evergreen_disable_interrupt_state(rdev); | 2541 | evergreen_disable_interrupt_state(rdev); |
| 2238 | } | 2542 | } |
| 2239 | 2543 | ||
| @@ -2273,8 +2577,6 @@ int evergreen_irq_process(struct radeon_device *rdev) | |||
| 2273 | u32 rptr = rdev->ih.rptr; | 2577 | u32 rptr = rdev->ih.rptr; |
| 2274 | u32 src_id, src_data; | 2578 | u32 src_id, src_data; |
| 2275 | u32 ring_index; | 2579 | u32 ring_index; |
| 2276 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
| 2277 | u32 disp_int_cont3, disp_int_cont4, disp_int_cont5; | ||
| 2278 | unsigned long flags; | 2580 | unsigned long flags; |
| 2279 | bool queue_hotplug = false; | 2581 | bool queue_hotplug = false; |
| 2280 | 2582 | ||
| @@ -2295,8 +2597,7 @@ int evergreen_irq_process(struct radeon_device *rdev) | |||
| 2295 | 2597 | ||
| 2296 | restart_ih: | 2598 | restart_ih: |
| 2297 | /* display interrupts */ | 2599 | /* display interrupts */ |
| 2298 | evergreen_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2, | 2600 | evergreen_irq_ack(rdev); |
| 2299 | &disp_int_cont3, &disp_int_cont4, &disp_int_cont5); | ||
| 2300 | 2601 | ||
| 2301 | rdev->ih.wptr = wptr; | 2602 | rdev->ih.wptr = wptr; |
| 2302 | while (rptr != wptr) { | 2603 | while (rptr != wptr) { |
| @@ -2309,17 +2610,21 @@ restart_ih: | |||
| 2309 | case 1: /* D1 vblank/vline */ | 2610 | case 1: /* D1 vblank/vline */ |
| 2310 | switch (src_data) { | 2611 | switch (src_data) { |
| 2311 | case 0: /* D1 vblank */ | 2612 | case 0: /* D1 vblank */ |
| 2312 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | 2613 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { |
| 2313 | drm_handle_vblank(rdev->ddev, 0); | 2614 | if (rdev->irq.crtc_vblank_int[0]) { |
| 2314 | rdev->pm.vblank_sync = true; | 2615 | drm_handle_vblank(rdev->ddev, 0); |
| 2315 | wake_up(&rdev->irq.vblank_queue); | 2616 | rdev->pm.vblank_sync = true; |
| 2316 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 2617 | wake_up(&rdev->irq.vblank_queue); |
| 2618 | } | ||
| 2619 | if (rdev->irq.pflip[0]) | ||
| 2620 | radeon_crtc_handle_flip(rdev, 0); | ||
| 2621 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | ||
| 2317 | DRM_DEBUG("IH: D1 vblank\n"); | 2622 | DRM_DEBUG("IH: D1 vblank\n"); |
| 2318 | } | 2623 | } |
| 2319 | break; | 2624 | break; |
| 2320 | case 1: /* D1 vline */ | 2625 | case 1: /* D1 vline */ |
| 2321 | if (disp_int & LB_D1_VLINE_INTERRUPT) { | 2626 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { |
| 2322 | disp_int &= ~LB_D1_VLINE_INTERRUPT; | 2627 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; |
| 2323 | DRM_DEBUG("IH: D1 vline\n"); | 2628 | DRM_DEBUG("IH: D1 vline\n"); |
| 2324 | } | 2629 | } |
| 2325 | break; | 2630 | break; |
| @@ -2331,17 +2636,21 @@ restart_ih: | |||
| 2331 | case 2: /* D2 vblank/vline */ | 2636 | case 2: /* D2 vblank/vline */ |
| 2332 | switch (src_data) { | 2637 | switch (src_data) { |
| 2333 | case 0: /* D2 vblank */ | 2638 | case 0: /* D2 vblank */ |
| 2334 | if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) { | 2639 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { |
| 2335 | drm_handle_vblank(rdev->ddev, 1); | 2640 | if (rdev->irq.crtc_vblank_int[1]) { |
| 2336 | rdev->pm.vblank_sync = true; | 2641 | drm_handle_vblank(rdev->ddev, 1); |
| 2337 | wake_up(&rdev->irq.vblank_queue); | 2642 | rdev->pm.vblank_sync = true; |
| 2338 | disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; | 2643 | wake_up(&rdev->irq.vblank_queue); |
| 2644 | } | ||
| 2645 | if (rdev->irq.pflip[1]) | ||
| 2646 | radeon_crtc_handle_flip(rdev, 1); | ||
| 2647 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; | ||
| 2339 | DRM_DEBUG("IH: D2 vblank\n"); | 2648 | DRM_DEBUG("IH: D2 vblank\n"); |
| 2340 | } | 2649 | } |
| 2341 | break; | 2650 | break; |
| 2342 | case 1: /* D2 vline */ | 2651 | case 1: /* D2 vline */ |
| 2343 | if (disp_int_cont & LB_D2_VLINE_INTERRUPT) { | 2652 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { |
| 2344 | disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; | 2653 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; |
| 2345 | DRM_DEBUG("IH: D2 vline\n"); | 2654 | DRM_DEBUG("IH: D2 vline\n"); |
| 2346 | } | 2655 | } |
| 2347 | break; | 2656 | break; |
| @@ -2353,17 +2662,21 @@ restart_ih: | |||
| 2353 | case 3: /* D3 vblank/vline */ | 2662 | case 3: /* D3 vblank/vline */ |
| 2354 | switch (src_data) { | 2663 | switch (src_data) { |
| 2355 | case 0: /* D3 vblank */ | 2664 | case 0: /* D3 vblank */ |
| 2356 | if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { | 2665 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { |
| 2357 | drm_handle_vblank(rdev->ddev, 2); | 2666 | if (rdev->irq.crtc_vblank_int[2]) { |
| 2358 | rdev->pm.vblank_sync = true; | 2667 | drm_handle_vblank(rdev->ddev, 2); |
| 2359 | wake_up(&rdev->irq.vblank_queue); | 2668 | rdev->pm.vblank_sync = true; |
| 2360 | disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; | 2669 | wake_up(&rdev->irq.vblank_queue); |
| 2670 | } | ||
| 2671 | if (rdev->irq.pflip[2]) | ||
| 2672 | radeon_crtc_handle_flip(rdev, 2); | ||
| 2673 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; | ||
| 2361 | DRM_DEBUG("IH: D3 vblank\n"); | 2674 | DRM_DEBUG("IH: D3 vblank\n"); |
| 2362 | } | 2675 | } |
| 2363 | break; | 2676 | break; |
| 2364 | case 1: /* D3 vline */ | 2677 | case 1: /* D3 vline */ |
| 2365 | if (disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { | 2678 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { |
| 2366 | disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; | 2679 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; |
| 2367 | DRM_DEBUG("IH: D3 vline\n"); | 2680 | DRM_DEBUG("IH: D3 vline\n"); |
| 2368 | } | 2681 | } |
| 2369 | break; | 2682 | break; |
| @@ -2375,17 +2688,21 @@ restart_ih: | |||
| 2375 | case 4: /* D4 vblank/vline */ | 2688 | case 4: /* D4 vblank/vline */ |
| 2376 | switch (src_data) { | 2689 | switch (src_data) { |
| 2377 | case 0: /* D4 vblank */ | 2690 | case 0: /* D4 vblank */ |
| 2378 | if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { | 2691 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { |
| 2379 | drm_handle_vblank(rdev->ddev, 3); | 2692 | if (rdev->irq.crtc_vblank_int[3]) { |
| 2380 | rdev->pm.vblank_sync = true; | 2693 | drm_handle_vblank(rdev->ddev, 3); |
| 2381 | wake_up(&rdev->irq.vblank_queue); | 2694 | rdev->pm.vblank_sync = true; |
| 2382 | disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; | 2695 | wake_up(&rdev->irq.vblank_queue); |
| 2696 | } | ||
| 2697 | if (rdev->irq.pflip[3]) | ||
| 2698 | radeon_crtc_handle_flip(rdev, 3); | ||
| 2699 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; | ||
| 2383 | DRM_DEBUG("IH: D4 vblank\n"); | 2700 | DRM_DEBUG("IH: D4 vblank\n"); |
| 2384 | } | 2701 | } |
| 2385 | break; | 2702 | break; |
| 2386 | case 1: /* D4 vline */ | 2703 | case 1: /* D4 vline */ |
| 2387 | if (disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { | 2704 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { |
| 2388 | disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; | 2705 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; |
| 2389 | DRM_DEBUG("IH: D4 vline\n"); | 2706 | DRM_DEBUG("IH: D4 vline\n"); |
| 2390 | } | 2707 | } |
| 2391 | break; | 2708 | break; |
| @@ -2397,17 +2714,21 @@ restart_ih: | |||
| 2397 | case 5: /* D5 vblank/vline */ | 2714 | case 5: /* D5 vblank/vline */ |
| 2398 | switch (src_data) { | 2715 | switch (src_data) { |
| 2399 | case 0: /* D5 vblank */ | 2716 | case 0: /* D5 vblank */ |
| 2400 | if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { | 2717 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { |
| 2401 | drm_handle_vblank(rdev->ddev, 4); | 2718 | if (rdev->irq.crtc_vblank_int[4]) { |
| 2402 | rdev->pm.vblank_sync = true; | 2719 | drm_handle_vblank(rdev->ddev, 4); |
| 2403 | wake_up(&rdev->irq.vblank_queue); | 2720 | rdev->pm.vblank_sync = true; |
| 2404 | disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; | 2721 | wake_up(&rdev->irq.vblank_queue); |
| 2722 | } | ||
| 2723 | if (rdev->irq.pflip[4]) | ||
| 2724 | radeon_crtc_handle_flip(rdev, 4); | ||
| 2725 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; | ||
| 2405 | DRM_DEBUG("IH: D5 vblank\n"); | 2726 | DRM_DEBUG("IH: D5 vblank\n"); |
| 2406 | } | 2727 | } |
| 2407 | break; | 2728 | break; |
| 2408 | case 1: /* D5 vline */ | 2729 | case 1: /* D5 vline */ |
| 2409 | if (disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { | 2730 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { |
| 2410 | disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; | 2731 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; |
| 2411 | DRM_DEBUG("IH: D5 vline\n"); | 2732 | DRM_DEBUG("IH: D5 vline\n"); |
| 2412 | } | 2733 | } |
| 2413 | break; | 2734 | break; |
| @@ -2419,17 +2740,21 @@ restart_ih: | |||
| 2419 | case 6: /* D6 vblank/vline */ | 2740 | case 6: /* D6 vblank/vline */ |
| 2420 | switch (src_data) { | 2741 | switch (src_data) { |
| 2421 | case 0: /* D6 vblank */ | 2742 | case 0: /* D6 vblank */ |
| 2422 | if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { | 2743 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { |
| 2423 | drm_handle_vblank(rdev->ddev, 5); | 2744 | if (rdev->irq.crtc_vblank_int[5]) { |
| 2424 | rdev->pm.vblank_sync = true; | 2745 | drm_handle_vblank(rdev->ddev, 5); |
| 2425 | wake_up(&rdev->irq.vblank_queue); | 2746 | rdev->pm.vblank_sync = true; |
| 2426 | disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; | 2747 | wake_up(&rdev->irq.vblank_queue); |
| 2748 | } | ||
| 2749 | if (rdev->irq.pflip[5]) | ||
| 2750 | radeon_crtc_handle_flip(rdev, 5); | ||
| 2751 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; | ||
| 2427 | DRM_DEBUG("IH: D6 vblank\n"); | 2752 | DRM_DEBUG("IH: D6 vblank\n"); |
| 2428 | } | 2753 | } |
| 2429 | break; | 2754 | break; |
| 2430 | case 1: /* D6 vline */ | 2755 | case 1: /* D6 vline */ |
| 2431 | if (disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { | 2756 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { |
| 2432 | disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; | 2757 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; |
| 2433 | DRM_DEBUG("IH: D6 vline\n"); | 2758 | DRM_DEBUG("IH: D6 vline\n"); |
| 2434 | } | 2759 | } |
| 2435 | break; | 2760 | break; |
| @@ -2441,43 +2766,43 @@ restart_ih: | |||
| 2441 | case 42: /* HPD hotplug */ | 2766 | case 42: /* HPD hotplug */ |
| 2442 | switch (src_data) { | 2767 | switch (src_data) { |
| 2443 | case 0: | 2768 | case 0: |
| 2444 | if (disp_int & DC_HPD1_INTERRUPT) { | 2769 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { |
| 2445 | disp_int &= ~DC_HPD1_INTERRUPT; | 2770 | rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; |
| 2446 | queue_hotplug = true; | 2771 | queue_hotplug = true; |
| 2447 | DRM_DEBUG("IH: HPD1\n"); | 2772 | DRM_DEBUG("IH: HPD1\n"); |
| 2448 | } | 2773 | } |
| 2449 | break; | 2774 | break; |
| 2450 | case 1: | 2775 | case 1: |
| 2451 | if (disp_int_cont & DC_HPD2_INTERRUPT) { | 2776 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { |
| 2452 | disp_int_cont &= ~DC_HPD2_INTERRUPT; | 2777 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; |
| 2453 | queue_hotplug = true; | 2778 | queue_hotplug = true; |
| 2454 | DRM_DEBUG("IH: HPD2\n"); | 2779 | DRM_DEBUG("IH: HPD2\n"); |
| 2455 | } | 2780 | } |
| 2456 | break; | 2781 | break; |
| 2457 | case 2: | 2782 | case 2: |
| 2458 | if (disp_int_cont2 & DC_HPD3_INTERRUPT) { | 2783 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { |
| 2459 | disp_int_cont2 &= ~DC_HPD3_INTERRUPT; | 2784 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; |
| 2460 | queue_hotplug = true; | 2785 | queue_hotplug = true; |
| 2461 | DRM_DEBUG("IH: HPD3\n"); | 2786 | DRM_DEBUG("IH: HPD3\n"); |
| 2462 | } | 2787 | } |
| 2463 | break; | 2788 | break; |
| 2464 | case 3: | 2789 | case 3: |
| 2465 | if (disp_int_cont3 & DC_HPD4_INTERRUPT) { | 2790 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { |
| 2466 | disp_int_cont3 &= ~DC_HPD4_INTERRUPT; | 2791 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; |
| 2467 | queue_hotplug = true; | 2792 | queue_hotplug = true; |
| 2468 | DRM_DEBUG("IH: HPD4\n"); | 2793 | DRM_DEBUG("IH: HPD4\n"); |
| 2469 | } | 2794 | } |
| 2470 | break; | 2795 | break; |
| 2471 | case 4: | 2796 | case 4: |
| 2472 | if (disp_int_cont4 & DC_HPD5_INTERRUPT) { | 2797 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { |
| 2473 | disp_int_cont4 &= ~DC_HPD5_INTERRUPT; | 2798 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; |
| 2474 | queue_hotplug = true; | 2799 | queue_hotplug = true; |
| 2475 | DRM_DEBUG("IH: HPD5\n"); | 2800 | DRM_DEBUG("IH: HPD5\n"); |
| 2476 | } | 2801 | } |
| 2477 | break; | 2802 | break; |
| 2478 | case 5: | 2803 | case 5: |
| 2479 | if (disp_int_cont5 & DC_HPD6_INTERRUPT) { | 2804 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { |
| 2480 | disp_int_cont5 &= ~DC_HPD6_INTERRUPT; | 2805 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; |
| 2481 | queue_hotplug = true; | 2806 | queue_hotplug = true; |
| 2482 | DRM_DEBUG("IH: HPD6\n"); | 2807 | DRM_DEBUG("IH: HPD6\n"); |
| 2483 | } | 2808 | } |
| @@ -2516,7 +2841,7 @@ restart_ih: | |||
| 2516 | if (wptr != rdev->ih.wptr) | 2841 | if (wptr != rdev->ih.wptr) |
| 2517 | goto restart_ih; | 2842 | goto restart_ih; |
| 2518 | if (queue_hotplug) | 2843 | if (queue_hotplug) |
| 2519 | queue_work(rdev->wq, &rdev->hotplug_work); | 2844 | schedule_work(&rdev->hotplug_work); |
| 2520 | rdev->ih.rptr = rptr; | 2845 | rdev->ih.rptr = rptr; |
| 2521 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 2846 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
| 2522 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 2847 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
| @@ -2527,12 +2852,31 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 2527 | { | 2852 | { |
| 2528 | int r; | 2853 | int r; |
| 2529 | 2854 | ||
| 2530 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2855 | /* enable pcie gen2 link */ |
| 2531 | r = r600_init_microcode(rdev); | 2856 | if (!ASIC_IS_DCE5(rdev)) |
| 2857 | evergreen_pcie_gen2_enable(rdev); | ||
| 2858 | |||
| 2859 | if (ASIC_IS_DCE5(rdev)) { | ||
| 2860 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | ||
| 2861 | r = ni_init_microcode(rdev); | ||
| 2862 | if (r) { | ||
| 2863 | DRM_ERROR("Failed to load firmware!\n"); | ||
| 2864 | return r; | ||
| 2865 | } | ||
| 2866 | } | ||
| 2867 | r = btc_mc_load_microcode(rdev); | ||
| 2532 | if (r) { | 2868 | if (r) { |
| 2533 | DRM_ERROR("Failed to load firmware!\n"); | 2869 | DRM_ERROR("Failed to load MC firmware!\n"); |
| 2534 | return r; | 2870 | return r; |
| 2535 | } | 2871 | } |
| 2872 | } else { | ||
| 2873 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
| 2874 | r = r600_init_microcode(rdev); | ||
| 2875 | if (r) { | ||
| 2876 | DRM_ERROR("Failed to load firmware!\n"); | ||
| 2877 | return r; | ||
| 2878 | } | ||
| 2879 | } | ||
| 2536 | } | 2880 | } |
| 2537 | 2881 | ||
| 2538 | evergreen_mc_program(rdev); | 2882 | evergreen_mc_program(rdev); |
| @@ -2551,6 +2895,11 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 2551 | rdev->asic->copy = NULL; | 2895 | rdev->asic->copy = NULL; |
| 2552 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | 2896 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
| 2553 | } | 2897 | } |
| 2898 | /* XXX: ontario has problems blitting to gart at the moment */ | ||
| 2899 | if (rdev->family == CHIP_PALM) { | ||
| 2900 | rdev->asic->copy = NULL; | ||
| 2901 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
| 2902 | } | ||
| 2554 | 2903 | ||
| 2555 | /* allocate wb buffer */ | 2904 | /* allocate wb buffer */ |
| 2556 | r = radeon_wb_init(rdev); | 2905 | r = radeon_wb_init(rdev); |
| @@ -2658,12 +3007,16 @@ static bool evergreen_card_posted(struct radeon_device *rdev) | |||
| 2658 | u32 reg; | 3007 | u32 reg; |
| 2659 | 3008 | ||
| 2660 | /* first check CRTCs */ | 3009 | /* first check CRTCs */ |
| 2661 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | | 3010 | if (rdev->flags & RADEON_IS_IGP) |
| 2662 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | | 3011 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | |
| 2663 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | | 3012 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); |
| 2664 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | | 3013 | else |
| 2665 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | | 3014 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | |
| 2666 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | 3015 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | |
| 3016 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | | ||
| 3017 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | | ||
| 3018 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | | ||
| 3019 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
| 2667 | if (reg & EVERGREEN_CRTC_MASTER_EN) | 3020 | if (reg & EVERGREEN_CRTC_MASTER_EN) |
| 2668 | return true; | 3021 | return true; |
| 2669 | 3022 | ||
| @@ -2800,3 +3153,52 @@ void evergreen_fini(struct radeon_device *rdev) | |||
| 2800 | rdev->bios = NULL; | 3153 | rdev->bios = NULL; |
| 2801 | radeon_dummy_page_fini(rdev); | 3154 | radeon_dummy_page_fini(rdev); |
| 2802 | } | 3155 | } |
| 3156 | |||
| 3157 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | ||
| 3158 | { | ||
| 3159 | u32 link_width_cntl, speed_cntl; | ||
| 3160 | |||
| 3161 | if (rdev->flags & RADEON_IS_IGP) | ||
| 3162 | return; | ||
| 3163 | |||
| 3164 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
| 3165 | return; | ||
| 3166 | |||
| 3167 | /* x2 cards have a special sequence */ | ||
| 3168 | if (ASIC_IS_X2(rdev)) | ||
| 3169 | return; | ||
| 3170 | |||
| 3171 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3172 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || | ||
| 3173 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
| 3174 | |||
| 3175 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 3176 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
| 3177 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 3178 | |||
| 3179 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3180 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
| 3181 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 3182 | |||
| 3183 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3184 | speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
| 3185 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 3186 | |||
| 3187 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3188 | speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
| 3189 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 3190 | |||
| 3191 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3192 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
| 3193 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 3194 | |||
| 3195 | } else { | ||
| 3196 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 3197 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
| 3198 | if (1) | ||
| 3199 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
| 3200 | else | ||
| 3201 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
| 3202 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 3203 | } | ||
| 3204 | } | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index e0e590110dd4..b758dc7f2f2c 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
| @@ -147,7 +147,9 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | |||
| 147 | radeon_ring_write(rdev, 0); | 147 | radeon_ring_write(rdev, 0); |
| 148 | radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30); | 148 | radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30); |
| 149 | 149 | ||
| 150 | if (rdev->family == CHIP_CEDAR) | 150 | if ((rdev->family == CHIP_CEDAR) || |
| 151 | (rdev->family == CHIP_PALM) || | ||
| 152 | (rdev->family == CHIP_CAICOS)) | ||
| 151 | cp_set_surface_sync(rdev, | 153 | cp_set_surface_sync(rdev, |
| 152 | PACKET3_TC_ACTION_ENA, 48, gpu_addr); | 154 | PACKET3_TC_ACTION_ENA, 48, gpu_addr); |
| 153 | else | 155 | else |
| @@ -331,9 +333,95 @@ set_default_state(struct radeon_device *rdev) | |||
| 331 | num_hs_stack_entries = 85; | 333 | num_hs_stack_entries = 85; |
| 332 | num_ls_stack_entries = 85; | 334 | num_ls_stack_entries = 85; |
| 333 | break; | 335 | break; |
| 336 | case CHIP_PALM: | ||
| 337 | num_ps_gprs = 93; | ||
| 338 | num_vs_gprs = 46; | ||
| 339 | num_temp_gprs = 4; | ||
| 340 | num_gs_gprs = 31; | ||
| 341 | num_es_gprs = 31; | ||
| 342 | num_hs_gprs = 23; | ||
| 343 | num_ls_gprs = 23; | ||
| 344 | num_ps_threads = 96; | ||
| 345 | num_vs_threads = 16; | ||
| 346 | num_gs_threads = 16; | ||
| 347 | num_es_threads = 16; | ||
| 348 | num_hs_threads = 16; | ||
| 349 | num_ls_threads = 16; | ||
| 350 | num_ps_stack_entries = 42; | ||
| 351 | num_vs_stack_entries = 42; | ||
| 352 | num_gs_stack_entries = 42; | ||
| 353 | num_es_stack_entries = 42; | ||
| 354 | num_hs_stack_entries = 42; | ||
| 355 | num_ls_stack_entries = 42; | ||
| 356 | break; | ||
| 357 | case CHIP_BARTS: | ||
| 358 | num_ps_gprs = 93; | ||
| 359 | num_vs_gprs = 46; | ||
| 360 | num_temp_gprs = 4; | ||
| 361 | num_gs_gprs = 31; | ||
| 362 | num_es_gprs = 31; | ||
| 363 | num_hs_gprs = 23; | ||
| 364 | num_ls_gprs = 23; | ||
| 365 | num_ps_threads = 128; | ||
| 366 | num_vs_threads = 20; | ||
| 367 | num_gs_threads = 20; | ||
| 368 | num_es_threads = 20; | ||
| 369 | num_hs_threads = 20; | ||
| 370 | num_ls_threads = 20; | ||
| 371 | num_ps_stack_entries = 85; | ||
| 372 | num_vs_stack_entries = 85; | ||
| 373 | num_gs_stack_entries = 85; | ||
| 374 | num_es_stack_entries = 85; | ||
| 375 | num_hs_stack_entries = 85; | ||
| 376 | num_ls_stack_entries = 85; | ||
| 377 | break; | ||
| 378 | case CHIP_TURKS: | ||
| 379 | num_ps_gprs = 93; | ||
| 380 | num_vs_gprs = 46; | ||
| 381 | num_temp_gprs = 4; | ||
| 382 | num_gs_gprs = 31; | ||
| 383 | num_es_gprs = 31; | ||
| 384 | num_hs_gprs = 23; | ||
| 385 | num_ls_gprs = 23; | ||
| 386 | num_ps_threads = 128; | ||
| 387 | num_vs_threads = 20; | ||
| 388 | num_gs_threads = 20; | ||
| 389 | num_es_threads = 20; | ||
| 390 | num_hs_threads = 20; | ||
| 391 | num_ls_threads = 20; | ||
| 392 | num_ps_stack_entries = 42; | ||
| 393 | num_vs_stack_entries = 42; | ||
| 394 | num_gs_stack_entries = 42; | ||
| 395 | num_es_stack_entries = 42; | ||
| 396 | num_hs_stack_entries = 42; | ||
| 397 | num_ls_stack_entries = 42; | ||
| 398 | break; | ||
| 399 | case CHIP_CAICOS: | ||
| 400 | num_ps_gprs = 93; | ||
| 401 | num_vs_gprs = 46; | ||
| 402 | num_temp_gprs = 4; | ||
| 403 | num_gs_gprs = 31; | ||
| 404 | num_es_gprs = 31; | ||
| 405 | num_hs_gprs = 23; | ||
| 406 | num_ls_gprs = 23; | ||
| 407 | num_ps_threads = 128; | ||
| 408 | num_vs_threads = 10; | ||
| 409 | num_gs_threads = 10; | ||
| 410 | num_es_threads = 10; | ||
| 411 | num_hs_threads = 10; | ||
| 412 | num_ls_threads = 10; | ||
| 413 | num_ps_stack_entries = 42; | ||
| 414 | num_vs_stack_entries = 42; | ||
| 415 | num_gs_stack_entries = 42; | ||
| 416 | num_es_stack_entries = 42; | ||
| 417 | num_hs_stack_entries = 42; | ||
| 418 | num_ls_stack_entries = 42; | ||
| 419 | break; | ||
| 334 | } | 420 | } |
| 335 | 421 | ||
| 336 | if (rdev->family == CHIP_CEDAR) | 422 | if ((rdev->family == CHIP_CEDAR) || |
| 423 | (rdev->family == CHIP_PALM) || | ||
| 424 | (rdev->family == CHIP_CAICOS)) | ||
| 337 | sq_config = 0; | 425 | sq_config = 0; |
| 338 | else | 426 | else |
| 339 | sq_config = VC_ENABLE; | 427 | sq_config = VC_ENABLE; |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 2330f3a36fd5..c781c92c3451 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
| @@ -105,6 +105,11 @@ | |||
| 105 | #define EVERGREEN_GRPH_Y_START 0x6830 | 105 | #define EVERGREEN_GRPH_Y_START 0x6830 |
| 106 | #define EVERGREEN_GRPH_X_END 0x6834 | 106 | #define EVERGREEN_GRPH_X_END 0x6834 |
| 107 | #define EVERGREEN_GRPH_Y_END 0x6838 | 107 | #define EVERGREEN_GRPH_Y_END 0x6838 |
| 108 | #define EVERGREEN_GRPH_UPDATE 0x6844 | ||
| 109 | # define EVERGREEN_GRPH_SURFACE_UPDATE_PENDING (1 << 2) | ||
| 110 | # define EVERGREEN_GRPH_UPDATE_LOCK (1 << 16) | ||
| 111 | #define EVERGREEN_GRPH_FLIP_CONTROL 0x6848 | ||
| 112 | # define EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN (1 << 0) | ||
| 108 | 113 | ||
| 109 | /* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */ | 114 | /* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */ |
| 110 | #define EVERGREEN_CUR_CONTROL 0x6998 | 115 | #define EVERGREEN_CUR_CONTROL 0x6998 |
| @@ -178,6 +183,7 @@ | |||
| 178 | # define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) | 183 | # define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) |
| 179 | #define EVERGREEN_CRTC_STATUS 0x6e8c | 184 | #define EVERGREEN_CRTC_STATUS 0x6e8c |
| 180 | #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 | 185 | #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 |
| 186 | #define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8 | ||
| 181 | #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 | 187 | #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 |
| 182 | 188 | ||
| 183 | #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 | 189 | #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index a73b53c44359..36d32d83d866 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -164,11 +164,13 @@ | |||
| 164 | #define SE_SC_BUSY (1 << 29) | 164 | #define SE_SC_BUSY (1 << 29) |
| 165 | #define SE_DB_BUSY (1 << 30) | 165 | #define SE_DB_BUSY (1 << 30) |
| 166 | #define SE_CB_BUSY (1 << 31) | 166 | #define SE_CB_BUSY (1 << 31) |
| 167 | 167 | /* evergreen */ | |
| 168 | #define CG_MULT_THERMAL_STATUS 0x740 | 168 | #define CG_MULT_THERMAL_STATUS 0x740 |
| 169 | #define ASIC_T(x) ((x) << 16) | 169 | #define ASIC_T(x) ((x) << 16) |
| 170 | #define ASIC_T_MASK 0x7FF0000 | 170 | #define ASIC_T_MASK 0x7FF0000 |
| 171 | #define ASIC_T_SHIFT 16 | 171 | #define ASIC_T_SHIFT 16 |
| 172 | /* APU */ | ||
| 173 | #define CG_THERMAL_STATUS 0x678 | ||
| 172 | 174 | ||
| 173 | #define HDP_HOST_PATH_CNTL 0x2C00 | 175 | #define HDP_HOST_PATH_CNTL 0x2C00 |
| 174 | #define HDP_NONSURFACE_BASE 0x2C04 | 176 | #define HDP_NONSURFACE_BASE 0x2C04 |
| @@ -181,6 +183,7 @@ | |||
| 181 | #define MC_SHARED_CHMAP 0x2004 | 183 | #define MC_SHARED_CHMAP 0x2004 |
| 182 | #define NOOFCHAN_SHIFT 12 | 184 | #define NOOFCHAN_SHIFT 12 |
| 183 | #define NOOFCHAN_MASK 0x00003000 | 185 | #define NOOFCHAN_MASK 0x00003000 |
| 186 | #define MC_SHARED_CHREMAP 0x2008 | ||
| 184 | 187 | ||
| 185 | #define MC_ARB_RAMCFG 0x2760 | 188 | #define MC_ARB_RAMCFG 0x2760 |
| 186 | #define NOOFBANK_SHIFT 0 | 189 | #define NOOFBANK_SHIFT 0 |
| @@ -200,6 +203,7 @@ | |||
| 200 | #define MC_VM_AGP_BOT 0x202C | 203 | #define MC_VM_AGP_BOT 0x202C |
| 201 | #define MC_VM_AGP_BASE 0x2030 | 204 | #define MC_VM_AGP_BASE 0x2030 |
| 202 | #define MC_VM_FB_LOCATION 0x2024 | 205 | #define MC_VM_FB_LOCATION 0x2024 |
| 206 | #define MC_FUS_VM_FB_OFFSET 0x2898 | ||
| 203 | #define MC_VM_MB_L1_TLB0_CNTL 0x2234 | 207 | #define MC_VM_MB_L1_TLB0_CNTL 0x2234 |
| 204 | #define MC_VM_MB_L1_TLB1_CNTL 0x2238 | 208 | #define MC_VM_MB_L1_TLB1_CNTL 0x2238 |
| 205 | #define MC_VM_MB_L1_TLB2_CNTL 0x223C | 209 | #define MC_VM_MB_L1_TLB2_CNTL 0x223C |
| @@ -349,6 +353,9 @@ | |||
| 349 | #define SYNC_WALKER (1 << 25) | 353 | #define SYNC_WALKER (1 << 25) |
| 350 | #define SYNC_ALIGNER (1 << 26) | 354 | #define SYNC_ALIGNER (1 << 26) |
| 351 | 355 | ||
| 356 | #define TCP_CHAN_STEER_LO 0x960c | ||
| 357 | #define TCP_CHAN_STEER_HI 0x9610 | ||
| 358 | |||
| 352 | #define VGT_CACHE_INVALIDATION 0x88C4 | 359 | #define VGT_CACHE_INVALIDATION 0x88C4 |
| 353 | #define CACHE_INVALIDATION(x) ((x) << 0) | 360 | #define CACHE_INVALIDATION(x) ((x) << 0) |
| 354 | #define VC_ONLY 0 | 361 | #define VC_ONLY 0 |
| @@ -574,6 +581,44 @@ | |||
| 574 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) | 581 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) |
| 575 | # define DC_HPDx_EN (1 << 28) | 582 | # define DC_HPDx_EN (1 << 28) |
| 576 | 583 | ||
| 584 | /* PCIE link stuff */ | ||
| 585 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ | ||
| 586 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ | ||
| 587 | # define LC_LINK_WIDTH_SHIFT 0 | ||
| 588 | # define LC_LINK_WIDTH_MASK 0x7 | ||
| 589 | # define LC_LINK_WIDTH_X0 0 | ||
| 590 | # define LC_LINK_WIDTH_X1 1 | ||
| 591 | # define LC_LINK_WIDTH_X2 2 | ||
| 592 | # define LC_LINK_WIDTH_X4 3 | ||
| 593 | # define LC_LINK_WIDTH_X8 4 | ||
| 594 | # define LC_LINK_WIDTH_X16 6 | ||
| 595 | # define LC_LINK_WIDTH_RD_SHIFT 4 | ||
| 596 | # define LC_LINK_WIDTH_RD_MASK 0x70 | ||
| 597 | # define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
| 598 | # define LC_RECONFIG_NOW (1 << 8) | ||
| 599 | # define LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
| 600 | # define LC_RENEGOTIATE_EN (1 << 10) | ||
| 601 | # define LC_SHORT_RECONFIG_EN (1 << 11) | ||
| 602 | # define LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
| 603 | # define LC_UPCONFIGURE_DIS (1 << 13) | ||
| 604 | #define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ | ||
| 605 | # define LC_GEN2_EN_STRAP (1 << 0) | ||
| 606 | # define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) | ||
| 607 | # define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) | ||
| 608 | # define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) | ||
| 609 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) | ||
| 610 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 | ||
| 611 | # define LC_CURRENT_DATA_RATE (1 << 11) | ||
| 612 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) | ||
| 613 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) | ||
| 614 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) | ||
| 615 | # define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) | ||
| 616 | #define MM_CFGREGS_CNTL 0x544c | ||
| 617 | # define MM_WR_TO_CFG_EN (1 << 3) | ||
| 618 | #define LINK_CNTL2 0x88 /* F0 */ | ||
| 619 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | ||
| 620 | # define SELECTABLE_DEEMPHASIS (1 << 6) | ||
| 621 | |||
| 577 | /* | 622 | /* |
| 578 | * PM4 | 623 | * PM4 |
| 579 | */ | 624 | */ |
| @@ -603,7 +648,7 @@ | |||
| 603 | #define PACKET3_NOP 0x10 | 648 | #define PACKET3_NOP 0x10 |
| 604 | #define PACKET3_SET_BASE 0x11 | 649 | #define PACKET3_SET_BASE 0x11 |
| 605 | #define PACKET3_CLEAR_STATE 0x12 | 650 | #define PACKET3_CLEAR_STATE 0x12 |
| 606 | #define PACKET3_INDIRECT_BUFFER_SIZE 0x13 | 651 | #define PACKET3_INDEX_BUFFER_SIZE 0x13 |
| 607 | #define PACKET3_DISPATCH_DIRECT 0x15 | 652 | #define PACKET3_DISPATCH_DIRECT 0x15 |
| 608 | #define PACKET3_DISPATCH_INDIRECT 0x16 | 653 | #define PACKET3_DISPATCH_INDIRECT 0x16 |
| 609 | #define PACKET3_INDIRECT_BUFFER_END 0x17 | 654 | #define PACKET3_INDIRECT_BUFFER_END 0x17 |
| @@ -644,14 +689,14 @@ | |||
| 644 | # define PACKET3_CB8_DEST_BASE_ENA (1 << 15) | 689 | # define PACKET3_CB8_DEST_BASE_ENA (1 << 15) |
| 645 | # define PACKET3_CB9_DEST_BASE_ENA (1 << 16) | 690 | # define PACKET3_CB9_DEST_BASE_ENA (1 << 16) |
| 646 | # define PACKET3_CB10_DEST_BASE_ENA (1 << 17) | 691 | # define PACKET3_CB10_DEST_BASE_ENA (1 << 17) |
| 647 | # define PACKET3_CB11_DEST_BASE_ENA (1 << 17) | 692 | # define PACKET3_CB11_DEST_BASE_ENA (1 << 18) |
| 648 | # define PACKET3_FULL_CACHE_ENA (1 << 20) | 693 | # define PACKET3_FULL_CACHE_ENA (1 << 20) |
| 649 | # define PACKET3_TC_ACTION_ENA (1 << 23) | 694 | # define PACKET3_TC_ACTION_ENA (1 << 23) |
| 650 | # define PACKET3_VC_ACTION_ENA (1 << 24) | 695 | # define PACKET3_VC_ACTION_ENA (1 << 24) |
| 651 | # define PACKET3_CB_ACTION_ENA (1 << 25) | 696 | # define PACKET3_CB_ACTION_ENA (1 << 25) |
| 652 | # define PACKET3_DB_ACTION_ENA (1 << 26) | 697 | # define PACKET3_DB_ACTION_ENA (1 << 26) |
| 653 | # define PACKET3_SH_ACTION_ENA (1 << 27) | 698 | # define PACKET3_SH_ACTION_ENA (1 << 27) |
| 654 | # define PACKET3_SMX_ACTION_ENA (1 << 28) | 699 | # define PACKET3_SX_ACTION_ENA (1 << 28) |
| 655 | #define PACKET3_ME_INITIALIZE 0x44 | 700 | #define PACKET3_ME_INITIALIZE 0x44 |
| 656 | #define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) | 701 | #define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) |
| 657 | #define PACKET3_COND_WRITE 0x45 | 702 | #define PACKET3_COND_WRITE 0x45 |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c new file mode 100644 index 000000000000..5e0bef80ad7f --- /dev/null +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2010 Advanced Micro Devices, Inc. | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * | ||
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 21 | * | ||
| 22 | * Authors: Alex Deucher | ||
| 23 | */ | ||
| 24 | #include <linux/firmware.h> | ||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/slab.h> | ||
| 27 | #include "drmP.h" | ||
| 28 | #include "radeon.h" | ||
| 29 | #include "radeon_asic.h" | ||
| 30 | #include "radeon_drm.h" | ||
| 31 | #include "nid.h" | ||
| 32 | #include "atom.h" | ||
| 33 | #include "ni_reg.h" | ||
| 34 | |||
| 35 | #define EVERGREEN_PFP_UCODE_SIZE 1120 | ||
| 36 | #define EVERGREEN_PM4_UCODE_SIZE 1376 | ||
| 37 | #define EVERGREEN_RLC_UCODE_SIZE 768 | ||
| 38 | #define BTC_MC_UCODE_SIZE 6024 | ||
| 39 | |||
| 40 | /* Firmware Names */ | ||
| 41 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); | ||
| 42 | MODULE_FIRMWARE("radeon/BARTS_me.bin"); | ||
| 43 | MODULE_FIRMWARE("radeon/BARTS_mc.bin"); | ||
| 44 | MODULE_FIRMWARE("radeon/BTC_rlc.bin"); | ||
| 45 | MODULE_FIRMWARE("radeon/TURKS_pfp.bin"); | ||
| 46 | MODULE_FIRMWARE("radeon/TURKS_me.bin"); | ||
| 47 | MODULE_FIRMWARE("radeon/TURKS_mc.bin"); | ||
| 48 | MODULE_FIRMWARE("radeon/CAICOS_pfp.bin"); | ||
| 49 | MODULE_FIRMWARE("radeon/CAICOS_me.bin"); | ||
| 50 | MODULE_FIRMWARE("radeon/CAICOS_mc.bin"); | ||
| 51 | |||
| 52 | #define BTC_IO_MC_REGS_SIZE 29 | ||
| 53 | |||
| 54 | static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { | ||
| 55 | {0x00000077, 0xff010100}, | ||
| 56 | {0x00000078, 0x00000000}, | ||
| 57 | {0x00000079, 0x00001434}, | ||
| 58 | {0x0000007a, 0xcc08ec08}, | ||
| 59 | {0x0000007b, 0x00040000}, | ||
| 60 | {0x0000007c, 0x000080c0}, | ||
| 61 | {0x0000007d, 0x09000000}, | ||
| 62 | {0x0000007e, 0x00210404}, | ||
| 63 | {0x00000081, 0x08a8e800}, | ||
| 64 | {0x00000082, 0x00030444}, | ||
| 65 | {0x00000083, 0x00000000}, | ||
| 66 | {0x00000085, 0x00000001}, | ||
| 67 | {0x00000086, 0x00000002}, | ||
| 68 | {0x00000087, 0x48490000}, | ||
| 69 | {0x00000088, 0x20244647}, | ||
| 70 | {0x00000089, 0x00000005}, | ||
| 71 | {0x0000008b, 0x66030000}, | ||
| 72 | {0x0000008c, 0x00006603}, | ||
| 73 | {0x0000008d, 0x00000100}, | ||
| 74 | {0x0000008f, 0x00001c0a}, | ||
| 75 | {0x00000090, 0xff000001}, | ||
| 76 | {0x00000094, 0x00101101}, | ||
| 77 | {0x00000095, 0x00000fff}, | ||
| 78 | {0x00000096, 0x00116fff}, | ||
| 79 | {0x00000097, 0x60010000}, | ||
| 80 | {0x00000098, 0x10010000}, | ||
| 81 | {0x00000099, 0x00006000}, | ||
| 82 | {0x0000009a, 0x00001000}, | ||
| 83 | {0x0000009f, 0x00946a00} | ||
| 84 | }; | ||
| 85 | |||
| 86 | static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { | ||
| 87 | {0x00000077, 0xff010100}, | ||
| 88 | {0x00000078, 0x00000000}, | ||
| 89 | {0x00000079, 0x00001434}, | ||
| 90 | {0x0000007a, 0xcc08ec08}, | ||
| 91 | {0x0000007b, 0x00040000}, | ||
| 92 | {0x0000007c, 0x000080c0}, | ||
| 93 | {0x0000007d, 0x09000000}, | ||
| 94 | {0x0000007e, 0x00210404}, | ||
| 95 | {0x00000081, 0x08a8e800}, | ||
| 96 | {0x00000082, 0x00030444}, | ||
| 97 | {0x00000083, 0x00000000}, | ||
| 98 | {0x00000085, 0x00000001}, | ||
| 99 | {0x00000086, 0x00000002}, | ||
| 100 | {0x00000087, 0x48490000}, | ||
| 101 | {0x00000088, 0x20244647}, | ||
| 102 | {0x00000089, 0x00000005}, | ||
| 103 | {0x0000008b, 0x66030000}, | ||
| 104 | {0x0000008c, 0x00006603}, | ||
| 105 | {0x0000008d, 0x00000100}, | ||
| 106 | {0x0000008f, 0x00001c0a}, | ||
| 107 | {0x00000090, 0xff000001}, | ||
| 108 | {0x00000094, 0x00101101}, | ||
| 109 | {0x00000095, 0x00000fff}, | ||
| 110 | {0x00000096, 0x00116fff}, | ||
| 111 | {0x00000097, 0x60010000}, | ||
| 112 | {0x00000098, 0x10010000}, | ||
| 113 | {0x00000099, 0x00006000}, | ||
| 114 | {0x0000009a, 0x00001000}, | ||
| 115 | {0x0000009f, 0x00936a00} | ||
| 116 | }; | ||
| 117 | |||
| 118 | static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { | ||
| 119 | {0x00000077, 0xff010100}, | ||
| 120 | {0x00000078, 0x00000000}, | ||
| 121 | {0x00000079, 0x00001434}, | ||
| 122 | {0x0000007a, 0xcc08ec08}, | ||
| 123 | {0x0000007b, 0x00040000}, | ||
| 124 | {0x0000007c, 0x000080c0}, | ||
| 125 | {0x0000007d, 0x09000000}, | ||
| 126 | {0x0000007e, 0x00210404}, | ||
| 127 | {0x00000081, 0x08a8e800}, | ||
| 128 | {0x00000082, 0x00030444}, | ||
| 129 | {0x00000083, 0x00000000}, | ||
| 130 | {0x00000085, 0x00000001}, | ||
| 131 | {0x00000086, 0x00000002}, | ||
| 132 | {0x00000087, 0x48490000}, | ||
| 133 | {0x00000088, 0x20244647}, | ||
| 134 | {0x00000089, 0x00000005}, | ||
| 135 | {0x0000008b, 0x66030000}, | ||
| 136 | {0x0000008c, 0x00006603}, | ||
| 137 | {0x0000008d, 0x00000100}, | ||
| 138 | {0x0000008f, 0x00001c0a}, | ||
| 139 | {0x00000090, 0xff000001}, | ||
| 140 | {0x00000094, 0x00101101}, | ||
| 141 | {0x00000095, 0x00000fff}, | ||
| 142 | {0x00000096, 0x00116fff}, | ||
| 143 | {0x00000097, 0x60010000}, | ||
| 144 | {0x00000098, 0x10010000}, | ||
| 145 | {0x00000099, 0x00006000}, | ||
| 146 | {0x0000009a, 0x00001000}, | ||
| 147 | {0x0000009f, 0x00916a00} | ||
| 148 | }; | ||
| 149 | |||
| 150 | int btc_mc_load_microcode(struct radeon_device *rdev) | ||
| 151 | { | ||
| 152 | const __be32 *fw_data; | ||
| 153 | u32 mem_type, running, blackout = 0; | ||
| 154 | u32 *io_mc_regs; | ||
| 155 | int i; | ||
| 156 | |||
| 157 | if (!rdev->mc_fw) | ||
| 158 | return -EINVAL; | ||
| 159 | |||
| 160 | switch (rdev->family) { | ||
| 161 | case CHIP_BARTS: | ||
| 162 | io_mc_regs = (u32 *)&barts_io_mc_regs; | ||
| 163 | break; | ||
| 164 | case CHIP_TURKS: | ||
| 165 | io_mc_regs = (u32 *)&turks_io_mc_regs; | ||
| 166 | break; | ||
| 167 | case CHIP_CAICOS: | ||
| 168 | default: | ||
| 169 | io_mc_regs = (u32 *)&caicos_io_mc_regs; | ||
| 170 | break; | ||
| 171 | } | ||
| 172 | |||
| 173 | mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT; | ||
| 174 | running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; | ||
| 175 | |||
| 176 | if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) { | ||
| 177 | if (running) { | ||
| 178 | blackout = RREG32(MC_SHARED_BLACKOUT_CNTL); | ||
| 179 | WREG32(MC_SHARED_BLACKOUT_CNTL, 1); | ||
| 180 | } | ||
| 181 | |||
| 182 | /* reset the engine and set to writable */ | ||
| 183 | WREG32(MC_SEQ_SUP_CNTL, 0x00000008); | ||
| 184 | WREG32(MC_SEQ_SUP_CNTL, 0x00000010); | ||
| 185 | |||
| 186 | /* load mc io regs */ | ||
| 187 | for (i = 0; i < BTC_IO_MC_REGS_SIZE; i++) { | ||
| 188 | WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); | ||
| 189 | WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); | ||
| 190 | } | ||
| 191 | /* load the MC ucode */ | ||
| 192 | fw_data = (const __be32 *)rdev->mc_fw->data; | ||
| 193 | for (i = 0; i < BTC_MC_UCODE_SIZE; i++) | ||
| 194 | WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); | ||
| 195 | |||
| 196 | /* put the engine back into the active state */ | ||
| 197 | WREG32(MC_SEQ_SUP_CNTL, 0x00000008); | ||
| 198 | WREG32(MC_SEQ_SUP_CNTL, 0x00000004); | ||
| 199 | WREG32(MC_SEQ_SUP_CNTL, 0x00000001); | ||
| 200 | |||
| 201 | /* wait for training to complete */ | ||
| 202 | while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)) | ||
| 203 | udelay(10); | ||
| 204 | |||
| 205 | if (running) | ||
| 206 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); | ||
| 207 | } | ||
| 208 | |||
| 209 | return 0; | ||
| 210 | } | ||
| 211 | |||
| 212 | int ni_init_microcode(struct radeon_device *rdev) | ||
| 213 | { | ||
| 214 | struct platform_device *pdev; | ||
| 215 | const char *chip_name; | ||
| 216 | const char *rlc_chip_name; | ||
| 217 | size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size; | ||
| 218 | char fw_name[30]; | ||
| 219 | int err; | ||
| 220 | |||
| 221 | DRM_DEBUG("\n"); | ||
| 222 | |||
| 223 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); | ||
| 224 | err = IS_ERR(pdev); | ||
| 225 | if (err) { | ||
| 226 | printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); | ||
| 227 | return -EINVAL; | ||
| 228 | } | ||
| 229 | |||
| 230 | switch (rdev->family) { | ||
| 231 | case CHIP_BARTS: | ||
| 232 | chip_name = "BARTS"; | ||
| 233 | rlc_chip_name = "BTC"; | ||
| 234 | break; | ||
| 235 | case CHIP_TURKS: | ||
| 236 | chip_name = "TURKS"; | ||
| 237 | rlc_chip_name = "BTC"; | ||
| 238 | break; | ||
| 239 | case CHIP_CAICOS: | ||
| 240 | chip_name = "CAICOS"; | ||
| 241 | rlc_chip_name = "BTC"; | ||
| 242 | break; | ||
| 243 | default: BUG(); | ||
| 244 | } | ||
| 245 | |||
| 246 | pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; | ||
| 247 | me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; | ||
| 248 | rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; | ||
| 249 | mc_req_size = BTC_MC_UCODE_SIZE * 4; | ||
| 250 | |||
| 251 | DRM_INFO("Loading %s Microcode\n", chip_name); | ||
| 252 | |||
| 253 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); | ||
| 254 | err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); | ||
| 255 | if (err) | ||
| 256 | goto out; | ||
| 257 | if (rdev->pfp_fw->size != pfp_req_size) { | ||
| 258 | printk(KERN_ERR | ||
| 259 | "ni_cp: Bogus length %zu in firmware \"%s\"\n", | ||
| 260 | rdev->pfp_fw->size, fw_name); | ||
| 261 | err = -EINVAL; | ||
| 262 | goto out; | ||
| 263 | } | ||
| 264 | |||
| 265 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); | ||
| 266 | err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); | ||
| 267 | if (err) | ||
| 268 | goto out; | ||
| 269 | if (rdev->me_fw->size != me_req_size) { | ||
| 270 | printk(KERN_ERR | ||
| 271 | "ni_cp: Bogus length %zu in firmware \"%s\"\n", | ||
| 272 | rdev->me_fw->size, fw_name); | ||
| 273 | err = -EINVAL; | ||
| 274 | } | ||
| 275 | |||
| 276 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); | ||
| 277 | err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); | ||
| 278 | if (err) | ||
| 279 | goto out; | ||
| 280 | if (rdev->rlc_fw->size != rlc_req_size) { | ||
| 281 | printk(KERN_ERR | ||
| 282 | "ni_rlc: Bogus length %zu in firmware \"%s\"\n", | ||
| 283 | rdev->rlc_fw->size, fw_name); | ||
| 284 | err = -EINVAL; | ||
| 285 | } | ||
| 286 | |||
| 287 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); | ||
| 288 | err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); | ||
| 289 | if (err) | ||
| 290 | goto out; | ||
| 291 | if (rdev->mc_fw->size != mc_req_size) { | ||
| 292 | printk(KERN_ERR | ||
| 293 | "ni_mc: Bogus length %zu in firmware \"%s\"\n", | ||
| 294 | rdev->mc_fw->size, fw_name); | ||
| 295 | err = -EINVAL; | ||
| 296 | } | ||
| 297 | out: | ||
| 298 | platform_device_unregister(pdev); | ||
| 299 | |||
| 300 | if (err) { | ||
| 301 | if (err != -EINVAL) | ||
| 302 | printk(KERN_ERR | ||
| 303 | "ni_cp: Failed to load firmware \"%s\"\n", | ||
| 304 | fw_name); | ||
| 305 | release_firmware(rdev->pfp_fw); | ||
| 306 | rdev->pfp_fw = NULL; | ||
| 307 | release_firmware(rdev->me_fw); | ||
| 308 | rdev->me_fw = NULL; | ||
| 309 | release_firmware(rdev->rlc_fw); | ||
| 310 | rdev->rlc_fw = NULL; | ||
| 311 | release_firmware(rdev->mc_fw); | ||
| 312 | rdev->mc_fw = NULL; | ||
| 313 | } | ||
| 314 | return err; | ||
| 315 | } | ||
| 316 | |||
diff --git a/drivers/gpu/drm/radeon/ni_reg.h b/drivers/gpu/drm/radeon/ni_reg.h new file mode 100644 index 000000000000..5db7b7d6feb0 --- /dev/null +++ b/drivers/gpu/drm/radeon/ni_reg.h | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2010 Advanced Micro Devices, Inc. | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * | ||
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 21 | * | ||
| 22 | * Authors: Alex Deucher | ||
| 23 | */ | ||
| 24 | #ifndef __NI_REG_H__ | ||
| 25 | #define __NI_REG_H__ | ||
| 26 | |||
| 27 | /* northern islands - DCE5 */ | ||
| 28 | |||
| 29 | #define NI_INPUT_GAMMA_CONTROL 0x6840 | ||
| 30 | # define NI_GRPH_INPUT_GAMMA_MODE(x) (((x) & 0x3) << 0) | ||
| 31 | # define NI_INPUT_GAMMA_USE_LUT 0 | ||
| 32 | # define NI_INPUT_GAMMA_BYPASS 1 | ||
| 33 | # define NI_INPUT_GAMMA_SRGB_24 2 | ||
| 34 | # define NI_INPUT_GAMMA_XVYCC_222 3 | ||
| 35 | # define NI_OVL_INPUT_GAMMA_MODE(x) (((x) & 0x3) << 4) | ||
| 36 | |||
| 37 | #define NI_PRESCALE_GRPH_CONTROL 0x68b4 | ||
| 38 | # define NI_GRPH_PRESCALE_BYPASS (1 << 4) | ||
| 39 | |||
| 40 | #define NI_PRESCALE_OVL_CONTROL 0x68c4 | ||
| 41 | # define NI_OVL_PRESCALE_BYPASS (1 << 4) | ||
| 42 | |||
| 43 | #define NI_INPUT_CSC_CONTROL 0x68d4 | ||
| 44 | # define NI_INPUT_CSC_GRPH_MODE(x) (((x) & 0x3) << 0) | ||
| 45 | # define NI_INPUT_CSC_BYPASS 0 | ||
| 46 | # define NI_INPUT_CSC_PROG_COEFF 1 | ||
| 47 | # define NI_INPUT_CSC_PROG_SHARED_MATRIXA 2 | ||
| 48 | # define NI_INPUT_CSC_OVL_MODE(x) (((x) & 0x3) << 4) | ||
| 49 | |||
| 50 | #define NI_OUTPUT_CSC_CONTROL 0x68f0 | ||
| 51 | # define NI_OUTPUT_CSC_GRPH_MODE(x) (((x) & 0x7) << 0) | ||
| 52 | # define NI_OUTPUT_CSC_BYPASS 0 | ||
| 53 | # define NI_OUTPUT_CSC_TV_RGB 1 | ||
| 54 | # define NI_OUTPUT_CSC_YCBCR_601 2 | ||
| 55 | # define NI_OUTPUT_CSC_YCBCR_709 3 | ||
| 56 | # define NI_OUTPUT_CSC_PROG_COEFF 4 | ||
| 57 | # define NI_OUTPUT_CSC_PROG_SHARED_MATRIXB 5 | ||
| 58 | # define NI_OUTPUT_CSC_OVL_MODE(x) (((x) & 0x7) << 4) | ||
| 59 | |||
| 60 | #define NI_DEGAMMA_CONTROL 0x6960 | ||
| 61 | # define NI_GRPH_DEGAMMA_MODE(x) (((x) & 0x3) << 0) | ||
| 62 | # define NI_DEGAMMA_BYPASS 0 | ||
| 63 | # define NI_DEGAMMA_SRGB_24 1 | ||
| 64 | # define NI_DEGAMMA_XVYCC_222 2 | ||
| 65 | # define NI_OVL_DEGAMMA_MODE(x) (((x) & 0x3) << 4) | ||
| 66 | # define NI_ICON_DEGAMMA_MODE(x) (((x) & 0x3) << 8) | ||
| 67 | # define NI_CURSOR_DEGAMMA_MODE(x) (((x) & 0x3) << 12) | ||
| 68 | |||
| 69 | #define NI_GAMUT_REMAP_CONTROL 0x6964 | ||
| 70 | # define NI_GRPH_GAMUT_REMAP_MODE(x) (((x) & 0x3) << 0) | ||
| 71 | # define NI_GAMUT_REMAP_BYPASS 0 | ||
| 72 | # define NI_GAMUT_REMAP_PROG_COEFF 1 | ||
| 73 | # define NI_GAMUT_REMAP_PROG_SHARED_MATRIXA 2 | ||
| 74 | # define NI_GAMUT_REMAP_PROG_SHARED_MATRIXB 3 | ||
| 75 | # define NI_OVL_GAMUT_REMAP_MODE(x) (((x) & 0x3) << 4) | ||
| 76 | |||
| 77 | #define NI_REGAMMA_CONTROL 0x6a80 | ||
| 78 | # define NI_GRPH_REGAMMA_MODE(x) (((x) & 0x7) << 0) | ||
| 79 | # define NI_REGAMMA_BYPASS 0 | ||
| 80 | # define NI_REGAMMA_SRGB_24 1 | ||
| 81 | # define NI_REGAMMA_XVYCC_222 2 | ||
| 82 | # define NI_REGAMMA_PROG_A 3 | ||
| 83 | # define NI_REGAMMA_PROG_B 4 | ||
| 84 | # define NI_OVL_REGAMMA_MODE(x) (((x) & 0x7) << 4) | ||
| 85 | |||
| 86 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h new file mode 100644 index 000000000000..f7b445390e02 --- /dev/null +++ b/drivers/gpu/drm/radeon/nid.h | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2010 Advanced Micro Devices, Inc. | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * | ||
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 21 | * | ||
| 22 | * Authors: Alex Deucher | ||
| 23 | */ | ||
| 24 | #ifndef NI_H | ||
| 25 | #define NI_H | ||
| 26 | |||
| 27 | #define MC_SHARED_BLACKOUT_CNTL 0x20ac | ||
| 28 | #define MC_SEQ_SUP_CNTL 0x28c8 | ||
| 29 | #define RUN_MASK (1 << 0) | ||
| 30 | #define MC_SEQ_SUP_PGM 0x28cc | ||
| 31 | #define MC_IO_PAD_CNTL_D0 0x29d0 | ||
| 32 | #define MEM_FALL_OUT_CMD (1 << 8) | ||
| 33 | #define MC_SEQ_MISC0 0x2a00 | ||
| 34 | #define MC_SEQ_MISC0_GDDR5_SHIFT 28 | ||
| 35 | #define MC_SEQ_MISC0_GDDR5_MASK 0xf0000000 | ||
| 36 | #define MC_SEQ_MISC0_GDDR5_VALUE 5 | ||
| 37 | #define MC_SEQ_IO_DEBUG_INDEX 0x2a44 | ||
| 38 | #define MC_SEQ_IO_DEBUG_DATA 0x2a48 | ||
| 39 | |||
| 40 | #endif | ||
| 41 | |||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8e10aa9f74b0..f637595b14e1 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -68,6 +68,56 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
| 68 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 68 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
| 69 | */ | 69 | */ |
| 70 | 70 | ||
| 71 | void r100_pre_page_flip(struct radeon_device *rdev, int crtc) | ||
| 72 | { | ||
| 73 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | ||
| 74 | u32 tmp; | ||
| 75 | |||
| 76 | /* make sure flip is at vb rather than hb */ | ||
| 77 | tmp = RREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset); | ||
| 78 | tmp &= ~RADEON_CRTC_OFFSET_FLIP_CNTL; | ||
| 79 | /* make sure pending bit is asserted */ | ||
| 80 | tmp |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN; | ||
| 81 | WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, tmp); | ||
| 82 | |||
| 83 | /* set pageflip to happen as late as possible in the vblank interval. | ||
| 84 | * same field for crtc1/2 | ||
| 85 | */ | ||
| 86 | tmp = RREG32(RADEON_CRTC_GEN_CNTL); | ||
| 87 | tmp &= ~RADEON_CRTC_VSTAT_MODE_MASK; | ||
| 88 | WREG32(RADEON_CRTC_GEN_CNTL, tmp); | ||
| 89 | |||
| 90 | /* enable the pflip int */ | ||
| 91 | radeon_irq_kms_pflip_irq_get(rdev, crtc); | ||
| 92 | } | ||
| 93 | |||
| 94 | void r100_post_page_flip(struct radeon_device *rdev, int crtc) | ||
| 95 | { | ||
| 96 | /* disable the pflip int */ | ||
| 97 | radeon_irq_kms_pflip_irq_put(rdev, crtc); | ||
| 98 | } | ||
| 99 | |||
| 100 | u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | ||
| 101 | { | ||
| 102 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
| 103 | u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; | ||
| 104 | |||
| 105 | /* Lock the graphics update lock */ | ||
| 106 | /* update the scanout addresses */ | ||
| 107 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); | ||
| 108 | |||
| 109 | /* Wait for update_pending to go high. */ | ||
| 110 | while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)); | ||
| 111 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | ||
| 112 | |||
| 113 | /* Unlock the lock, so double-buffering can take place inside vblank */ | ||
| 114 | tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK; | ||
| 115 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); | ||
| 116 | |||
| 117 | /* Return current update_pending status: */ | ||
| 118 | return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET; | ||
| 119 | } | ||
| 120 | |||
| 71 | void r100_pm_get_dynpm_state(struct radeon_device *rdev) | 121 | void r100_pm_get_dynpm_state(struct radeon_device *rdev) |
| 72 | { | 122 | { |
| 73 | int i; | 123 | int i; |
| @@ -526,10 +576,12 @@ int r100_irq_set(struct radeon_device *rdev) | |||
| 526 | if (rdev->irq.gui_idle) { | 576 | if (rdev->irq.gui_idle) { |
| 527 | tmp |= RADEON_GUI_IDLE_MASK; | 577 | tmp |= RADEON_GUI_IDLE_MASK; |
| 528 | } | 578 | } |
| 529 | if (rdev->irq.crtc_vblank_int[0]) { | 579 | if (rdev->irq.crtc_vblank_int[0] || |
| 580 | rdev->irq.pflip[0]) { | ||
| 530 | tmp |= RADEON_CRTC_VBLANK_MASK; | 581 | tmp |= RADEON_CRTC_VBLANK_MASK; |
| 531 | } | 582 | } |
| 532 | if (rdev->irq.crtc_vblank_int[1]) { | 583 | if (rdev->irq.crtc_vblank_int[1] || |
| 584 | rdev->irq.pflip[1]) { | ||
| 533 | tmp |= RADEON_CRTC2_VBLANK_MASK; | 585 | tmp |= RADEON_CRTC2_VBLANK_MASK; |
| 534 | } | 586 | } |
| 535 | if (rdev->irq.hpd[0]) { | 587 | if (rdev->irq.hpd[0]) { |
| @@ -600,14 +652,22 @@ int r100_irq_process(struct radeon_device *rdev) | |||
| 600 | } | 652 | } |
| 601 | /* Vertical blank interrupts */ | 653 | /* Vertical blank interrupts */ |
| 602 | if (status & RADEON_CRTC_VBLANK_STAT) { | 654 | if (status & RADEON_CRTC_VBLANK_STAT) { |
| 603 | drm_handle_vblank(rdev->ddev, 0); | 655 | if (rdev->irq.crtc_vblank_int[0]) { |
| 604 | rdev->pm.vblank_sync = true; | 656 | drm_handle_vblank(rdev->ddev, 0); |
| 605 | wake_up(&rdev->irq.vblank_queue); | 657 | rdev->pm.vblank_sync = true; |
| 658 | wake_up(&rdev->irq.vblank_queue); | ||
| 659 | } | ||
| 660 | if (rdev->irq.pflip[0]) | ||
| 661 | radeon_crtc_handle_flip(rdev, 0); | ||
| 606 | } | 662 | } |
| 607 | if (status & RADEON_CRTC2_VBLANK_STAT) { | 663 | if (status & RADEON_CRTC2_VBLANK_STAT) { |
| 608 | drm_handle_vblank(rdev->ddev, 1); | 664 | if (rdev->irq.crtc_vblank_int[1]) { |
| 609 | rdev->pm.vblank_sync = true; | 665 | drm_handle_vblank(rdev->ddev, 1); |
| 610 | wake_up(&rdev->irq.vblank_queue); | 666 | rdev->pm.vblank_sync = true; |
| 667 | wake_up(&rdev->irq.vblank_queue); | ||
| 668 | } | ||
| 669 | if (rdev->irq.pflip[1]) | ||
| 670 | radeon_crtc_handle_flip(rdev, 1); | ||
| 611 | } | 671 | } |
| 612 | if (status & RADEON_FP_DETECT_STAT) { | 672 | if (status & RADEON_FP_DETECT_STAT) { |
| 613 | queue_hotplug = true; | 673 | queue_hotplug = true; |
| @@ -622,7 +682,7 @@ int r100_irq_process(struct radeon_device *rdev) | |||
| 622 | /* reset gui idle ack. the status bit is broken */ | 682 | /* reset gui idle ack. the status bit is broken */ |
| 623 | rdev->irq.gui_idle_acked = false; | 683 | rdev->irq.gui_idle_acked = false; |
| 624 | if (queue_hotplug) | 684 | if (queue_hotplug) |
| 625 | queue_work(rdev->wq, &rdev->hotplug_work); | 685 | schedule_work(&rdev->hotplug_work); |
| 626 | if (rdev->msi_enabled) { | 686 | if (rdev->msi_enabled) { |
| 627 | switch (rdev->family) { | 687 | switch (rdev->family) { |
| 628 | case CHIP_RS400: | 688 | case CHIP_RS400: |
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h index b121b6c678d4..eab91760fae0 100644 --- a/drivers/gpu/drm/radeon/r100d.h +++ b/drivers/gpu/drm/radeon/r100d.h | |||
| @@ -551,7 +551,7 @@ | |||
| 551 | #define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31) | 551 | #define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31) |
| 552 | #define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1) | 552 | #define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1) |
| 553 | #define C_000360_CUR2_LOCK 0x7FFFFFFF | 553 | #define C_000360_CUR2_LOCK 0x7FFFFFFF |
| 554 | #define R_0003C2_GENMO_WT 0x0003C0 | 554 | #define R_0003C2_GENMO_WT 0x0003C2 |
| 555 | #define S_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0) | 555 | #define S_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0) |
| 556 | #define G_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1) | 556 | #define G_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1) |
| 557 | #define C_0003C2_GENMO_MONO_ADDRESS_B 0xFE | 557 | #define C_0003C2_GENMO_MONO_ADDRESS_B 0xFE |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index cde1d3480d93..fae5e709f270 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
| @@ -558,10 +558,7 @@ int rv370_get_pcie_lanes(struct radeon_device *rdev) | |||
| 558 | 558 | ||
| 559 | /* FIXME wait for idle */ | 559 | /* FIXME wait for idle */ |
| 560 | 560 | ||
| 561 | if (rdev->family < CHIP_R600) | 561 | link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); |
| 562 | link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
| 563 | else | ||
| 564 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
| 565 | 562 | ||
| 566 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { | 563 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { |
| 567 | case RADEON_PCIE_LC_LINK_WIDTH_X0: | 564 | case RADEON_PCIE_LC_LINK_WIDTH_X0: |
| @@ -745,6 +742,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 745 | break; | 742 | break; |
| 746 | case 0x4E00: | 743 | case 0x4E00: |
| 747 | /* RB3D_CCTL */ | 744 | /* RB3D_CCTL */ |
| 745 | if ((idx_value & (1 << 10)) && /* CMASK_ENABLE */ | ||
| 746 | p->rdev->cmask_filp != p->filp) { | ||
| 747 | DRM_ERROR("Invalid RB3D_CCTL: Cannot enable CMASK.\n"); | ||
| 748 | return -EINVAL; | ||
| 749 | } | ||
| 748 | track->num_cb = ((idx_value >> 5) & 0x3) + 1; | 750 | track->num_cb = ((idx_value >> 5) & 0x3) + 1; |
| 749 | break; | 751 | break; |
| 750 | case 0x4E38: | 752 | case 0x4E38: |
| @@ -787,6 +789,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 787 | case 15: | 789 | case 15: |
| 788 | track->cb[i].cpp = 2; | 790 | track->cb[i].cpp = 2; |
| 789 | break; | 791 | break; |
| 792 | case 5: | ||
| 793 | if (p->rdev->family < CHIP_RV515) { | ||
| 794 | DRM_ERROR("Invalid color buffer format (%d)!\n", | ||
| 795 | ((idx_value >> 21) & 0xF)); | ||
| 796 | return -EINVAL; | ||
| 797 | } | ||
| 798 | /* Pass through. */ | ||
| 790 | case 6: | 799 | case 6: |
| 791 | track->cb[i].cpp = 4; | 800 | track->cb[i].cpp = 4; |
| 792 | break; | 801 | break; |
| @@ -1199,6 +1208,10 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1199 | if (p->rdev->hyperz_filp != p->filp) | 1208 | if (p->rdev->hyperz_filp != p->filp) |
| 1200 | return -EINVAL; | 1209 | return -EINVAL; |
| 1201 | break; | 1210 | break; |
| 1211 | case PACKET3_3D_CLEAR_CMASK: | ||
| 1212 | if (p->rdev->cmask_filp != p->filp) | ||
| 1213 | return -EINVAL; | ||
| 1214 | break; | ||
| 1202 | case PACKET3_NOP: | 1215 | case PACKET3_NOP: |
| 1203 | break; | 1216 | break; |
| 1204 | default: | 1217 | default: |
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h index 0c036c60d9df..1f519a5ffb8c 100644 --- a/drivers/gpu/drm/radeon/r300d.h +++ b/drivers/gpu/drm/radeon/r300d.h | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #define PACKET3_3D_DRAW_IMMD_2 0x35 | 54 | #define PACKET3_3D_DRAW_IMMD_2 0x35 |
| 55 | #define PACKET3_3D_DRAW_INDX_2 0x36 | 55 | #define PACKET3_3D_DRAW_INDX_2 0x36 |
| 56 | #define PACKET3_3D_CLEAR_HIZ 0x37 | 56 | #define PACKET3_3D_CLEAR_HIZ 0x37 |
| 57 | #define PACKET3_3D_CLEAR_CMASK 0x38 | ||
| 57 | #define PACKET3_BITBLT_MULTI 0x9B | 58 | #define PACKET3_BITBLT_MULTI 0x9B |
| 58 | 59 | ||
| 59 | #define PACKET0(reg, n) (CP_PACKET0 | \ | 60 | #define PACKET0(reg, n) (CP_PACKET0 | \ |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 6ac1f604e29b..fc437059918f 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
| @@ -355,6 +355,8 @@ | |||
| 355 | #define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 | 355 | #define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 |
| 356 | #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 | 356 | #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 |
| 357 | 357 | ||
| 358 | #define AVIVO_D1MODE_MASTER_UPDATE_MODE 0x60e4 | ||
| 359 | |||
| 358 | /* master controls */ | 360 | /* master controls */ |
| 359 | #define AVIVO_DC_CRTC_MASTER_EN 0x60f8 | 361 | #define AVIVO_DC_CRTC_MASTER_EN 0x60f8 |
| 360 | #define AVIVO_DC_CRTC_TV_CONTROL 0x60fc | 362 | #define AVIVO_DC_CRTC_TV_CONTROL 0x60fc |
| @@ -409,8 +411,10 @@ | |||
| 409 | #define AVIVO_D1GRPH_X_END 0x6134 | 411 | #define AVIVO_D1GRPH_X_END 0x6134 |
| 410 | #define AVIVO_D1GRPH_Y_END 0x6138 | 412 | #define AVIVO_D1GRPH_Y_END 0x6138 |
| 411 | #define AVIVO_D1GRPH_UPDATE 0x6144 | 413 | #define AVIVO_D1GRPH_UPDATE 0x6144 |
| 414 | # define AVIVO_D1GRPH_SURFACE_UPDATE_PENDING (1 << 2) | ||
| 412 | # define AVIVO_D1GRPH_UPDATE_LOCK (1 << 16) | 415 | # define AVIVO_D1GRPH_UPDATE_LOCK (1 << 16) |
| 413 | #define AVIVO_D1GRPH_FLIP_CONTROL 0x6148 | 416 | #define AVIVO_D1GRPH_FLIP_CONTROL 0x6148 |
| 417 | # define AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN (1 << 0) | ||
| 414 | 418 | ||
| 415 | #define AVIVO_D1CUR_CONTROL 0x6400 | 419 | #define AVIVO_D1CUR_CONTROL 0x6400 |
| 416 | # define AVIVO_D1CURSOR_EN (1 << 0) | 420 | # define AVIVO_D1CURSOR_EN (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 9c92db7c896b..6b50716267c0 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -83,6 +83,9 @@ MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); | |||
| 83 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); | 83 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); |
| 84 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); | 84 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); |
| 85 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); | 85 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); |
| 86 | MODULE_FIRMWARE("radeon/PALM_pfp.bin"); | ||
| 87 | MODULE_FIRMWARE("radeon/PALM_me.bin"); | ||
| 88 | MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); | ||
| 86 | 89 | ||
| 87 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); | 90 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); |
| 88 | 91 | ||
| @@ -91,6 +94,7 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
| 91 | void r600_gpu_init(struct radeon_device *rdev); | 94 | void r600_gpu_init(struct radeon_device *rdev); |
| 92 | void r600_fini(struct radeon_device *rdev); | 95 | void r600_fini(struct radeon_device *rdev); |
| 93 | void r600_irq_disable(struct radeon_device *rdev); | 96 | void r600_irq_disable(struct radeon_device *rdev); |
| 97 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); | ||
| 94 | 98 | ||
| 95 | /* get temperature in millidegrees */ | 99 | /* get temperature in millidegrees */ |
| 96 | u32 rv6xx_get_temp(struct radeon_device *rdev) | 100 | u32 rv6xx_get_temp(struct radeon_device *rdev) |
| @@ -1164,7 +1168,7 @@ static void r600_mc_program(struct radeon_device *rdev) | |||
| 1164 | * Note: GTT start, end, size should be initialized before calling this | 1168 | * Note: GTT start, end, size should be initialized before calling this |
| 1165 | * function on AGP platform. | 1169 | * function on AGP platform. |
| 1166 | */ | 1170 | */ |
| 1167 | void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | 1171 | static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) |
| 1168 | { | 1172 | { |
| 1169 | u64 size_bf, size_af; | 1173 | u64 size_bf, size_af; |
| 1170 | 1174 | ||
| @@ -2009,6 +2013,10 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
| 2009 | chip_name = "CYPRESS"; | 2013 | chip_name = "CYPRESS"; |
| 2010 | rlc_chip_name = "CYPRESS"; | 2014 | rlc_chip_name = "CYPRESS"; |
| 2011 | break; | 2015 | break; |
| 2016 | case CHIP_PALM: | ||
| 2017 | chip_name = "PALM"; | ||
| 2018 | rlc_chip_name = "SUMO"; | ||
| 2019 | break; | ||
| 2012 | default: BUG(); | 2020 | default: BUG(); |
| 2013 | } | 2021 | } |
| 2014 | 2022 | ||
| @@ -2372,6 +2380,9 @@ int r600_startup(struct radeon_device *rdev) | |||
| 2372 | { | 2380 | { |
| 2373 | int r; | 2381 | int r; |
| 2374 | 2382 | ||
| 2383 | /* enable pcie gen2 link */ | ||
| 2384 | r600_pcie_gen2_enable(rdev); | ||
| 2385 | |||
| 2375 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2386 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
| 2376 | r = r600_init_microcode(rdev); | 2387 | r = r600_init_microcode(rdev); |
| 2377 | if (r) { | 2388 | if (r) { |
| @@ -2874,6 +2885,8 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) | |||
| 2874 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 2885 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
| 2875 | WREG32(GRBM_INT_CNTL, 0); | 2886 | WREG32(GRBM_INT_CNTL, 0); |
| 2876 | WREG32(DxMODE_INT_MASK, 0); | 2887 | WREG32(DxMODE_INT_MASK, 0); |
| 2888 | WREG32(D1GRPH_INTERRUPT_CONTROL, 0); | ||
| 2889 | WREG32(D2GRPH_INTERRUPT_CONTROL, 0); | ||
| 2877 | if (ASIC_IS_DCE3(rdev)) { | 2890 | if (ASIC_IS_DCE3(rdev)) { |
| 2878 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); | 2891 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); |
| 2879 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); | 2892 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); |
| @@ -2998,6 +3011,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
| 2998 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 3011 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
| 2999 | u32 grbm_int_cntl = 0; | 3012 | u32 grbm_int_cntl = 0; |
| 3000 | u32 hdmi1, hdmi2; | 3013 | u32 hdmi1, hdmi2; |
| 3014 | u32 d1grph = 0, d2grph = 0; | ||
| 3001 | 3015 | ||
| 3002 | if (!rdev->irq.installed) { | 3016 | if (!rdev->irq.installed) { |
| 3003 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 3017 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
| @@ -3034,11 +3048,13 @@ int r600_irq_set(struct radeon_device *rdev) | |||
| 3034 | cp_int_cntl |= RB_INT_ENABLE; | 3048 | cp_int_cntl |= RB_INT_ENABLE; |
| 3035 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 3049 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
| 3036 | } | 3050 | } |
| 3037 | if (rdev->irq.crtc_vblank_int[0]) { | 3051 | if (rdev->irq.crtc_vblank_int[0] || |
| 3052 | rdev->irq.pflip[0]) { | ||
| 3038 | DRM_DEBUG("r600_irq_set: vblank 0\n"); | 3053 | DRM_DEBUG("r600_irq_set: vblank 0\n"); |
| 3039 | mode_int |= D1MODE_VBLANK_INT_MASK; | 3054 | mode_int |= D1MODE_VBLANK_INT_MASK; |
| 3040 | } | 3055 | } |
| 3041 | if (rdev->irq.crtc_vblank_int[1]) { | 3056 | if (rdev->irq.crtc_vblank_int[1] || |
| 3057 | rdev->irq.pflip[1]) { | ||
| 3042 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | 3058 | DRM_DEBUG("r600_irq_set: vblank 1\n"); |
| 3043 | mode_int |= D2MODE_VBLANK_INT_MASK; | 3059 | mode_int |= D2MODE_VBLANK_INT_MASK; |
| 3044 | } | 3060 | } |
| @@ -3081,6 +3097,8 @@ int r600_irq_set(struct radeon_device *rdev) | |||
| 3081 | 3097 | ||
| 3082 | WREG32(CP_INT_CNTL, cp_int_cntl); | 3098 | WREG32(CP_INT_CNTL, cp_int_cntl); |
| 3083 | WREG32(DxMODE_INT_MASK, mode_int); | 3099 | WREG32(DxMODE_INT_MASK, mode_int); |
| 3100 | WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); | ||
| 3101 | WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); | ||
| 3084 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 3102 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
| 3085 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); | 3103 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); |
| 3086 | if (ASIC_IS_DCE3(rdev)) { | 3104 | if (ASIC_IS_DCE3(rdev)) { |
| @@ -3103,32 +3121,35 @@ int r600_irq_set(struct radeon_device *rdev) | |||
| 3103 | return 0; | 3121 | return 0; |
| 3104 | } | 3122 | } |
| 3105 | 3123 | ||
| 3106 | static inline void r600_irq_ack(struct radeon_device *rdev, | 3124 | static inline void r600_irq_ack(struct radeon_device *rdev) |
| 3107 | u32 *disp_int, | ||
| 3108 | u32 *disp_int_cont, | ||
| 3109 | u32 *disp_int_cont2) | ||
| 3110 | { | 3125 | { |
| 3111 | u32 tmp; | 3126 | u32 tmp; |
| 3112 | 3127 | ||
| 3113 | if (ASIC_IS_DCE3(rdev)) { | 3128 | if (ASIC_IS_DCE3(rdev)) { |
| 3114 | *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | 3129 | rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); |
| 3115 | *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | 3130 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); |
| 3116 | *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | 3131 | rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); |
| 3117 | } else { | 3132 | } else { |
| 3118 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | 3133 | rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
| 3119 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | 3134 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
| 3120 | *disp_int_cont2 = 0; | 3135 | rdev->irq.stat_regs.r600.disp_int_cont2 = 0; |
| 3121 | } | 3136 | } |
| 3122 | 3137 | rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); | |
| 3123 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) | 3138 | rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); |
| 3139 | |||
| 3140 | if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED) | ||
| 3141 | WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); | ||
| 3142 | if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED) | ||
| 3143 | WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); | ||
| 3144 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) | ||
| 3124 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 3145 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
| 3125 | if (*disp_int & LB_D1_VLINE_INTERRUPT) | 3146 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) |
| 3126 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 3147 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
| 3127 | if (*disp_int & LB_D2_VBLANK_INTERRUPT) | 3148 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) |
| 3128 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 3149 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
| 3129 | if (*disp_int & LB_D2_VLINE_INTERRUPT) | 3150 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) |
| 3130 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 3151 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
| 3131 | if (*disp_int & DC_HPD1_INTERRUPT) { | 3152 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
| 3132 | if (ASIC_IS_DCE3(rdev)) { | 3153 | if (ASIC_IS_DCE3(rdev)) { |
| 3133 | tmp = RREG32(DC_HPD1_INT_CONTROL); | 3154 | tmp = RREG32(DC_HPD1_INT_CONTROL); |
| 3134 | tmp |= DC_HPDx_INT_ACK; | 3155 | tmp |= DC_HPDx_INT_ACK; |
| @@ -3139,7 +3160,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
| 3139 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | 3160 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); |
| 3140 | } | 3161 | } |
| 3141 | } | 3162 | } |
| 3142 | if (*disp_int & DC_HPD2_INTERRUPT) { | 3163 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
| 3143 | if (ASIC_IS_DCE3(rdev)) { | 3164 | if (ASIC_IS_DCE3(rdev)) { |
| 3144 | tmp = RREG32(DC_HPD2_INT_CONTROL); | 3165 | tmp = RREG32(DC_HPD2_INT_CONTROL); |
| 3145 | tmp |= DC_HPDx_INT_ACK; | 3166 | tmp |= DC_HPDx_INT_ACK; |
| @@ -3150,7 +3171,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
| 3150 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | 3171 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); |
| 3151 | } | 3172 | } |
| 3152 | } | 3173 | } |
| 3153 | if (*disp_int_cont & DC_HPD3_INTERRUPT) { | 3174 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
| 3154 | if (ASIC_IS_DCE3(rdev)) { | 3175 | if (ASIC_IS_DCE3(rdev)) { |
| 3155 | tmp = RREG32(DC_HPD3_INT_CONTROL); | 3176 | tmp = RREG32(DC_HPD3_INT_CONTROL); |
| 3156 | tmp |= DC_HPDx_INT_ACK; | 3177 | tmp |= DC_HPDx_INT_ACK; |
| @@ -3161,18 +3182,18 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
| 3161 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | 3182 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); |
| 3162 | } | 3183 | } |
| 3163 | } | 3184 | } |
| 3164 | if (*disp_int_cont & DC_HPD4_INTERRUPT) { | 3185 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
| 3165 | tmp = RREG32(DC_HPD4_INT_CONTROL); | 3186 | tmp = RREG32(DC_HPD4_INT_CONTROL); |
| 3166 | tmp |= DC_HPDx_INT_ACK; | 3187 | tmp |= DC_HPDx_INT_ACK; |
| 3167 | WREG32(DC_HPD4_INT_CONTROL, tmp); | 3188 | WREG32(DC_HPD4_INT_CONTROL, tmp); |
| 3168 | } | 3189 | } |
| 3169 | if (ASIC_IS_DCE32(rdev)) { | 3190 | if (ASIC_IS_DCE32(rdev)) { |
| 3170 | if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { | 3191 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
| 3171 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 3192 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
| 3172 | tmp |= DC_HPDx_INT_ACK; | 3193 | tmp |= DC_HPDx_INT_ACK; |
| 3173 | WREG32(DC_HPD5_INT_CONTROL, tmp); | 3194 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
| 3174 | } | 3195 | } |
| 3175 | if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { | 3196 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
| 3176 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 3197 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
| 3177 | tmp |= DC_HPDx_INT_ACK; | 3198 | tmp |= DC_HPDx_INT_ACK; |
| 3178 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 3199 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
| @@ -3194,12 +3215,10 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
| 3194 | 3215 | ||
| 3195 | void r600_irq_disable(struct radeon_device *rdev) | 3216 | void r600_irq_disable(struct radeon_device *rdev) |
| 3196 | { | 3217 | { |
| 3197 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
| 3198 | |||
| 3199 | r600_disable_interrupts(rdev); | 3218 | r600_disable_interrupts(rdev); |
| 3200 | /* Wait and acknowledge irq */ | 3219 | /* Wait and acknowledge irq */ |
| 3201 | mdelay(1); | 3220 | mdelay(1); |
| 3202 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | 3221 | r600_irq_ack(rdev); |
| 3203 | r600_disable_interrupt_state(rdev); | 3222 | r600_disable_interrupt_state(rdev); |
| 3204 | } | 3223 | } |
| 3205 | 3224 | ||
| @@ -3262,7 +3281,7 @@ int r600_irq_process(struct radeon_device *rdev) | |||
| 3262 | u32 wptr = r600_get_ih_wptr(rdev); | 3281 | u32 wptr = r600_get_ih_wptr(rdev); |
| 3263 | u32 rptr = rdev->ih.rptr; | 3282 | u32 rptr = rdev->ih.rptr; |
| 3264 | u32 src_id, src_data; | 3283 | u32 src_id, src_data; |
| 3265 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; | 3284 | u32 ring_index; |
| 3266 | unsigned long flags; | 3285 | unsigned long flags; |
| 3267 | bool queue_hotplug = false; | 3286 | bool queue_hotplug = false; |
| 3268 | 3287 | ||
| @@ -3283,7 +3302,7 @@ int r600_irq_process(struct radeon_device *rdev) | |||
| 3283 | 3302 | ||
| 3284 | restart_ih: | 3303 | restart_ih: |
| 3285 | /* display interrupts */ | 3304 | /* display interrupts */ |
| 3286 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | 3305 | r600_irq_ack(rdev); |
| 3287 | 3306 | ||
| 3288 | rdev->ih.wptr = wptr; | 3307 | rdev->ih.wptr = wptr; |
| 3289 | while (rptr != wptr) { | 3308 | while (rptr != wptr) { |
| @@ -3296,17 +3315,21 @@ restart_ih: | |||
| 3296 | case 1: /* D1 vblank/vline */ | 3315 | case 1: /* D1 vblank/vline */ |
| 3297 | switch (src_data) { | 3316 | switch (src_data) { |
| 3298 | case 0: /* D1 vblank */ | 3317 | case 0: /* D1 vblank */ |
| 3299 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | 3318 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { |
| 3300 | drm_handle_vblank(rdev->ddev, 0); | 3319 | if (rdev->irq.crtc_vblank_int[0]) { |
| 3301 | rdev->pm.vblank_sync = true; | 3320 | drm_handle_vblank(rdev->ddev, 0); |
| 3302 | wake_up(&rdev->irq.vblank_queue); | 3321 | rdev->pm.vblank_sync = true; |
| 3303 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 3322 | wake_up(&rdev->irq.vblank_queue); |
| 3323 | } | ||
| 3324 | if (rdev->irq.pflip[0]) | ||
| 3325 | radeon_crtc_handle_flip(rdev, 0); | ||
| 3326 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | ||
| 3304 | DRM_DEBUG("IH: D1 vblank\n"); | 3327 | DRM_DEBUG("IH: D1 vblank\n"); |
| 3305 | } | 3328 | } |
| 3306 | break; | 3329 | break; |
| 3307 | case 1: /* D1 vline */ | 3330 | case 1: /* D1 vline */ |
| 3308 | if (disp_int & LB_D1_VLINE_INTERRUPT) { | 3331 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { |
| 3309 | disp_int &= ~LB_D1_VLINE_INTERRUPT; | 3332 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; |
| 3310 | DRM_DEBUG("IH: D1 vline\n"); | 3333 | DRM_DEBUG("IH: D1 vline\n"); |
| 3311 | } | 3334 | } |
| 3312 | break; | 3335 | break; |
| @@ -3318,17 +3341,21 @@ restart_ih: | |||
| 3318 | case 5: /* D2 vblank/vline */ | 3341 | case 5: /* D2 vblank/vline */ |
| 3319 | switch (src_data) { | 3342 | switch (src_data) { |
| 3320 | case 0: /* D2 vblank */ | 3343 | case 0: /* D2 vblank */ |
| 3321 | if (disp_int & LB_D2_VBLANK_INTERRUPT) { | 3344 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { |
| 3322 | drm_handle_vblank(rdev->ddev, 1); | 3345 | if (rdev->irq.crtc_vblank_int[1]) { |
| 3323 | rdev->pm.vblank_sync = true; | 3346 | drm_handle_vblank(rdev->ddev, 1); |
| 3324 | wake_up(&rdev->irq.vblank_queue); | 3347 | rdev->pm.vblank_sync = true; |
| 3325 | disp_int &= ~LB_D2_VBLANK_INTERRUPT; | 3348 | wake_up(&rdev->irq.vblank_queue); |
| 3349 | } | ||
| 3350 | if (rdev->irq.pflip[1]) | ||
| 3351 | radeon_crtc_handle_flip(rdev, 1); | ||
| 3352 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; | ||
| 3326 | DRM_DEBUG("IH: D2 vblank\n"); | 3353 | DRM_DEBUG("IH: D2 vblank\n"); |
| 3327 | } | 3354 | } |
| 3328 | break; | 3355 | break; |
| 3329 | case 1: /* D1 vline */ | 3356 | case 1: /* D1 vline */ |
| 3330 | if (disp_int & LB_D2_VLINE_INTERRUPT) { | 3357 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { |
| 3331 | disp_int &= ~LB_D2_VLINE_INTERRUPT; | 3358 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; |
| 3332 | DRM_DEBUG("IH: D2 vline\n"); | 3359 | DRM_DEBUG("IH: D2 vline\n"); |
| 3333 | } | 3360 | } |
| 3334 | break; | 3361 | break; |
| @@ -3340,43 +3367,43 @@ restart_ih: | |||
| 3340 | case 19: /* HPD/DAC hotplug */ | 3367 | case 19: /* HPD/DAC hotplug */ |
| 3341 | switch (src_data) { | 3368 | switch (src_data) { |
| 3342 | case 0: | 3369 | case 0: |
| 3343 | if (disp_int & DC_HPD1_INTERRUPT) { | 3370 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
| 3344 | disp_int &= ~DC_HPD1_INTERRUPT; | 3371 | rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; |
| 3345 | queue_hotplug = true; | 3372 | queue_hotplug = true; |
| 3346 | DRM_DEBUG("IH: HPD1\n"); | 3373 | DRM_DEBUG("IH: HPD1\n"); |
| 3347 | } | 3374 | } |
| 3348 | break; | 3375 | break; |
| 3349 | case 1: | 3376 | case 1: |
| 3350 | if (disp_int & DC_HPD2_INTERRUPT) { | 3377 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
| 3351 | disp_int &= ~DC_HPD2_INTERRUPT; | 3378 | rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; |
| 3352 | queue_hotplug = true; | 3379 | queue_hotplug = true; |
| 3353 | DRM_DEBUG("IH: HPD2\n"); | 3380 | DRM_DEBUG("IH: HPD2\n"); |
| 3354 | } | 3381 | } |
| 3355 | break; | 3382 | break; |
| 3356 | case 4: | 3383 | case 4: |
| 3357 | if (disp_int_cont & DC_HPD3_INTERRUPT) { | 3384 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
| 3358 | disp_int_cont &= ~DC_HPD3_INTERRUPT; | 3385 | rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; |
| 3359 | queue_hotplug = true; | 3386 | queue_hotplug = true; |
| 3360 | DRM_DEBUG("IH: HPD3\n"); | 3387 | DRM_DEBUG("IH: HPD3\n"); |
| 3361 | } | 3388 | } |
| 3362 | break; | 3389 | break; |
| 3363 | case 5: | 3390 | case 5: |
| 3364 | if (disp_int_cont & DC_HPD4_INTERRUPT) { | 3391 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
| 3365 | disp_int_cont &= ~DC_HPD4_INTERRUPT; | 3392 | rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; |
| 3366 | queue_hotplug = true; | 3393 | queue_hotplug = true; |
| 3367 | DRM_DEBUG("IH: HPD4\n"); | 3394 | DRM_DEBUG("IH: HPD4\n"); |
| 3368 | } | 3395 | } |
| 3369 | break; | 3396 | break; |
| 3370 | case 10: | 3397 | case 10: |
| 3371 | if (disp_int_cont2 & DC_HPD5_INTERRUPT) { | 3398 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
| 3372 | disp_int_cont2 &= ~DC_HPD5_INTERRUPT; | 3399 | rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; |
| 3373 | queue_hotplug = true; | 3400 | queue_hotplug = true; |
| 3374 | DRM_DEBUG("IH: HPD5\n"); | 3401 | DRM_DEBUG("IH: HPD5\n"); |
| 3375 | } | 3402 | } |
| 3376 | break; | 3403 | break; |
| 3377 | case 12: | 3404 | case 12: |
| 3378 | if (disp_int_cont2 & DC_HPD6_INTERRUPT) { | 3405 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
| 3379 | disp_int_cont2 &= ~DC_HPD6_INTERRUPT; | 3406 | rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; |
| 3380 | queue_hotplug = true; | 3407 | queue_hotplug = true; |
| 3381 | DRM_DEBUG("IH: HPD6\n"); | 3408 | DRM_DEBUG("IH: HPD6\n"); |
| 3382 | } | 3409 | } |
| @@ -3419,7 +3446,7 @@ restart_ih: | |||
| 3419 | if (wptr != rdev->ih.wptr) | 3446 | if (wptr != rdev->ih.wptr) |
| 3420 | goto restart_ih; | 3447 | goto restart_ih; |
| 3421 | if (queue_hotplug) | 3448 | if (queue_hotplug) |
| 3422 | queue_work(rdev->wq, &rdev->hotplug_work); | 3449 | schedule_work(&rdev->hotplug_work); |
| 3423 | rdev->ih.rptr = rptr; | 3450 | rdev->ih.rptr = rptr; |
| 3424 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3451 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
| 3425 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3452 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
| @@ -3508,3 +3535,219 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
| 3508 | } else | 3535 | } else |
| 3509 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 3536 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); |
| 3510 | } | 3537 | } |
| 3538 | |||
| 3539 | void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes) | ||
| 3540 | { | ||
| 3541 | u32 link_width_cntl, mask, target_reg; | ||
| 3542 | |||
| 3543 | if (rdev->flags & RADEON_IS_IGP) | ||
| 3544 | return; | ||
| 3545 | |||
| 3546 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
| 3547 | return; | ||
| 3548 | |||
| 3549 | /* x2 cards have a special sequence */ | ||
| 3550 | if (ASIC_IS_X2(rdev)) | ||
| 3551 | return; | ||
| 3552 | |||
| 3553 | /* FIXME wait for idle */ | ||
| 3554 | |||
| 3555 | switch (lanes) { | ||
| 3556 | case 0: | ||
| 3557 | mask = RADEON_PCIE_LC_LINK_WIDTH_X0; | ||
| 3558 | break; | ||
| 3559 | case 1: | ||
| 3560 | mask = RADEON_PCIE_LC_LINK_WIDTH_X1; | ||
| 3561 | break; | ||
| 3562 | case 2: | ||
| 3563 | mask = RADEON_PCIE_LC_LINK_WIDTH_X2; | ||
| 3564 | break; | ||
| 3565 | case 4: | ||
| 3566 | mask = RADEON_PCIE_LC_LINK_WIDTH_X4; | ||
| 3567 | break; | ||
| 3568 | case 8: | ||
| 3569 | mask = RADEON_PCIE_LC_LINK_WIDTH_X8; | ||
| 3570 | break; | ||
| 3571 | case 12: | ||
| 3572 | mask = RADEON_PCIE_LC_LINK_WIDTH_X12; | ||
| 3573 | break; | ||
| 3574 | case 16: | ||
| 3575 | default: | ||
| 3576 | mask = RADEON_PCIE_LC_LINK_WIDTH_X16; | ||
| 3577 | break; | ||
| 3578 | } | ||
| 3579 | |||
| 3580 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
| 3581 | |||
| 3582 | if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == | ||
| 3583 | (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) | ||
| 3584 | return; | ||
| 3585 | |||
| 3586 | if (link_width_cntl & R600_PCIE_LC_UPCONFIGURE_DIS) | ||
| 3587 | return; | ||
| 3588 | |||
| 3589 | link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | | ||
| 3590 | RADEON_PCIE_LC_RECONFIG_NOW | | ||
| 3591 | R600_PCIE_LC_RENEGOTIATE_EN | | ||
| 3592 | R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
| 3593 | link_width_cntl |= mask; | ||
| 3594 | |||
| 3595 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 3596 | |||
| 3597 | /* some northbridges can renegotiate the link rather than requiring | ||
| 3598 | * a complete re-config. | ||
| 3599 | * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, etc.) | ||
| 3600 | */ | ||
| 3601 | if (link_width_cntl & R600_PCIE_LC_RENEGOTIATION_SUPPORT) | ||
| 3602 | link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN | R600_PCIE_LC_UPCONFIGURE_SUPPORT; | ||
| 3603 | else | ||
| 3604 | link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE; | ||
| 3605 | |||
| 3606 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl | | ||
| 3607 | RADEON_PCIE_LC_RECONFIG_NOW)); | ||
| 3608 | |||
| 3609 | if (rdev->family >= CHIP_RV770) | ||
| 3610 | target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
| 3611 | else | ||
| 3612 | target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
| 3613 | |||
| 3614 | /* wait for lane set to complete */ | ||
| 3615 | link_width_cntl = RREG32(target_reg); | ||
| 3616 | while (link_width_cntl == 0xffffffff) | ||
| 3617 | link_width_cntl = RREG32(target_reg); | ||
| 3618 | |||
| 3619 | } | ||
| 3620 | |||
| 3621 | int r600_get_pcie_lanes(struct radeon_device *rdev) | ||
| 3622 | { | ||
| 3623 | u32 link_width_cntl; | ||
| 3624 | |||
| 3625 | if (rdev->flags & RADEON_IS_IGP) | ||
| 3626 | return 0; | ||
| 3627 | |||
| 3628 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
| 3629 | return 0; | ||
| 3630 | |||
| 3631 | /* x2 cards have a special sequence */ | ||
| 3632 | if (ASIC_IS_X2(rdev)) | ||
| 3633 | return 0; | ||
| 3634 | |||
| 3635 | /* FIXME wait for idle */ | ||
| 3636 | |||
| 3637 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
| 3638 | |||
| 3639 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { | ||
| 3640 | case RADEON_PCIE_LC_LINK_WIDTH_X0: | ||
| 3641 | return 0; | ||
| 3642 | case RADEON_PCIE_LC_LINK_WIDTH_X1: | ||
| 3643 | return 1; | ||
| 3644 | case RADEON_PCIE_LC_LINK_WIDTH_X2: | ||
| 3645 | return 2; | ||
| 3646 | case RADEON_PCIE_LC_LINK_WIDTH_X4: | ||
| 3647 | return 4; | ||
| 3648 | case RADEON_PCIE_LC_LINK_WIDTH_X8: | ||
| 3649 | return 8; | ||
| 3650 | case RADEON_PCIE_LC_LINK_WIDTH_X16: | ||
| 3651 | default: | ||
| 3652 | return 16; | ||
| 3653 | } | ||
| 3654 | } | ||
| 3655 | |||
| 3656 | static void r600_pcie_gen2_enable(struct radeon_device *rdev) | ||
| 3657 | { | ||
| 3658 | u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; | ||
| 3659 | u16 link_cntl2; | ||
| 3660 | |||
| 3661 | if (rdev->flags & RADEON_IS_IGP) | ||
| 3662 | return; | ||
| 3663 | |||
| 3664 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
| 3665 | return; | ||
| 3666 | |||
| 3667 | /* x2 cards have a special sequence */ | ||
| 3668 | if (ASIC_IS_X2(rdev)) | ||
| 3669 | return; | ||
| 3670 | |||
| 3671 | /* only RV6xx+ chips are supported */ | ||
| 3672 | if (rdev->family <= CHIP_R600) | ||
| 3673 | return; | ||
| 3674 | |||
| 3675 | /* 55 nm r6xx asics */ | ||
| 3676 | if ((rdev->family == CHIP_RV670) || | ||
| 3677 | (rdev->family == CHIP_RV620) || | ||
| 3678 | (rdev->family == CHIP_RV635)) { | ||
| 3679 | /* advertise upconfig capability */ | ||
| 3680 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 3681 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
| 3682 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 3683 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 3684 | if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { | ||
| 3685 | lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; | ||
| 3686 | link_width_cntl &= ~(LC_LINK_WIDTH_MASK | | ||
| 3687 | LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
| 3688 | link_width_cntl |= lanes | LC_RECONFIG_NOW | LC_RENEGOTIATE_EN; | ||
| 3689 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 3690 | } else { | ||
| 3691 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
| 3692 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 3693 | } | ||
| 3694 | } | ||
| 3695 | |||
| 3696 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3697 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
| 3698 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
| 3699 | |||
| 3700 | /* 55 nm r6xx asics */ | ||
| 3701 | if ((rdev->family == CHIP_RV670) || | ||
| 3702 | (rdev->family == CHIP_RV620) || | ||
| 3703 | (rdev->family == CHIP_RV635)) { | ||
| 3704 | WREG32(MM_CFGREGS_CNTL, 0x8); | ||
| 3705 | link_cntl2 = RREG32(0x4088); | ||
| 3706 | WREG32(MM_CFGREGS_CNTL, 0); | ||
| 3707 | /* not supported yet */ | ||
| 3708 | if (link_cntl2 & SELECTABLE_DEEMPHASIS) | ||
| 3709 | return; | ||
| 3710 | } | ||
| 3711 | |||
| 3712 | speed_cntl &= ~LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK; | ||
| 3713 | speed_cntl |= (0x3 << LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT); | ||
| 3714 | speed_cntl &= ~LC_VOLTAGE_TIMER_SEL_MASK; | ||
| 3715 | speed_cntl &= ~LC_FORCE_DIS_HW_SPEED_CHANGE; | ||
| 3716 | speed_cntl |= LC_FORCE_EN_HW_SPEED_CHANGE; | ||
| 3717 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 3718 | |||
| 3719 | tmp = RREG32(0x541c); | ||
| 3720 | WREG32(0x541c, tmp | 0x8); | ||
| 3721 | WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); | ||
| 3722 | link_cntl2 = RREG16(0x4088); | ||
| 3723 | link_cntl2 &= ~TARGET_LINK_SPEED_MASK; | ||
| 3724 | link_cntl2 |= 0x2; | ||
| 3725 | WREG16(0x4088, link_cntl2); | ||
| 3726 | WREG32(MM_CFGREGS_CNTL, 0); | ||
| 3727 | |||
| 3728 | if ((rdev->family == CHIP_RV670) || | ||
| 3729 | (rdev->family == CHIP_RV620) || | ||
| 3730 | (rdev->family == CHIP_RV635)) { | ||
| 3731 | training_cntl = RREG32_PCIE_P(PCIE_LC_TRAINING_CNTL); | ||
| 3732 | training_cntl &= ~LC_POINT_7_PLUS_EN; | ||
| 3733 | WREG32_PCIE_P(PCIE_LC_TRAINING_CNTL, training_cntl); | ||
| 3734 | } else { | ||
| 3735 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3736 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
| 3737 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 3738 | } | ||
| 3739 | |||
| 3740 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 3741 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
| 3742 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 3743 | |||
| 3744 | } else { | ||
| 3745 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 3746 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
| 3747 | if (1) | ||
| 3748 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
| 3749 | else | ||
| 3750 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
| 3751 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 3752 | } | ||
| 3753 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index bff4dc4f410f..a5d898b4bad2 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -728,6 +728,54 @@ | |||
| 728 | /* DCE 3.2 */ | 728 | /* DCE 3.2 */ |
| 729 | # define DC_HPDx_EN (1 << 28) | 729 | # define DC_HPDx_EN (1 << 28) |
| 730 | 730 | ||
| 731 | #define D1GRPH_INTERRUPT_STATUS 0x6158 | ||
| 732 | #define D2GRPH_INTERRUPT_STATUS 0x6958 | ||
| 733 | # define DxGRPH_PFLIP_INT_OCCURRED (1 << 0) | ||
| 734 | # define DxGRPH_PFLIP_INT_CLEAR (1 << 8) | ||
| 735 | #define D1GRPH_INTERRUPT_CONTROL 0x615c | ||
| 736 | #define D2GRPH_INTERRUPT_CONTROL 0x695c | ||
| 737 | # define DxGRPH_PFLIP_INT_MASK (1 << 0) | ||
| 738 | # define DxGRPH_PFLIP_INT_TYPE (1 << 8) | ||
| 739 | |||
| 740 | /* PCIE link stuff */ | ||
| 741 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ | ||
| 742 | # define LC_POINT_7_PLUS_EN (1 << 6) | ||
| 743 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ | ||
| 744 | # define LC_LINK_WIDTH_SHIFT 0 | ||
| 745 | # define LC_LINK_WIDTH_MASK 0x7 | ||
| 746 | # define LC_LINK_WIDTH_X0 0 | ||
| 747 | # define LC_LINK_WIDTH_X1 1 | ||
| 748 | # define LC_LINK_WIDTH_X2 2 | ||
| 749 | # define LC_LINK_WIDTH_X4 3 | ||
| 750 | # define LC_LINK_WIDTH_X8 4 | ||
| 751 | # define LC_LINK_WIDTH_X16 6 | ||
| 752 | # define LC_LINK_WIDTH_RD_SHIFT 4 | ||
| 753 | # define LC_LINK_WIDTH_RD_MASK 0x70 | ||
| 754 | # define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
| 755 | # define LC_RECONFIG_NOW (1 << 8) | ||
| 756 | # define LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
| 757 | # define LC_RENEGOTIATE_EN (1 << 10) | ||
| 758 | # define LC_SHORT_RECONFIG_EN (1 << 11) | ||
| 759 | # define LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
| 760 | # define LC_UPCONFIGURE_DIS (1 << 13) | ||
| 761 | #define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ | ||
| 762 | # define LC_GEN2_EN_STRAP (1 << 0) | ||
| 763 | # define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) | ||
| 764 | # define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) | ||
| 765 | # define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) | ||
| 766 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) | ||
| 767 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 | ||
| 768 | # define LC_CURRENT_DATA_RATE (1 << 11) | ||
| 769 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) | ||
| 770 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) | ||
| 771 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) | ||
| 772 | # define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) | ||
| 773 | #define MM_CFGREGS_CNTL 0x544c | ||
| 774 | # define MM_WR_TO_CFG_EN (1 << 3) | ||
| 775 | #define LINK_CNTL2 0x88 /* F0 */ | ||
| 776 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | ||
| 777 | # define SELECTABLE_DEEMPHASIS (1 << 6) | ||
| 778 | |||
| 731 | /* | 779 | /* |
| 732 | * PM4 | 780 | * PM4 |
| 733 | */ | 781 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3a7095743d44..e9486630a467 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -69,6 +69,7 @@ | |||
| 69 | #include <ttm/ttm_bo_driver.h> | 69 | #include <ttm/ttm_bo_driver.h> |
| 70 | #include <ttm/ttm_placement.h> | 70 | #include <ttm/ttm_placement.h> |
| 71 | #include <ttm/ttm_module.h> | 71 | #include <ttm/ttm_module.h> |
| 72 | #include <ttm/ttm_execbuf_util.h> | ||
| 72 | 73 | ||
| 73 | #include "radeon_family.h" | 74 | #include "radeon_family.h" |
| 74 | #include "radeon_mode.h" | 75 | #include "radeon_mode.h" |
| @@ -180,6 +181,7 @@ void rs690_pm_info(struct radeon_device *rdev); | |||
| 180 | extern u32 rv6xx_get_temp(struct radeon_device *rdev); | 181 | extern u32 rv6xx_get_temp(struct radeon_device *rdev); |
| 181 | extern u32 rv770_get_temp(struct radeon_device *rdev); | 182 | extern u32 rv770_get_temp(struct radeon_device *rdev); |
| 182 | extern u32 evergreen_get_temp(struct radeon_device *rdev); | 183 | extern u32 evergreen_get_temp(struct radeon_device *rdev); |
| 184 | extern u32 sumo_get_temp(struct radeon_device *rdev); | ||
| 183 | 185 | ||
| 184 | /* | 186 | /* |
| 185 | * Fences. | 187 | * Fences. |
| @@ -259,13 +261,12 @@ struct radeon_bo { | |||
| 259 | }; | 261 | }; |
| 260 | 262 | ||
| 261 | struct radeon_bo_list { | 263 | struct radeon_bo_list { |
| 262 | struct list_head list; | 264 | struct ttm_validate_buffer tv; |
| 263 | struct radeon_bo *bo; | 265 | struct radeon_bo *bo; |
| 264 | uint64_t gpu_offset; | 266 | uint64_t gpu_offset; |
| 265 | unsigned rdomain; | 267 | unsigned rdomain; |
| 266 | unsigned wdomain; | 268 | unsigned wdomain; |
| 267 | u32 tiling_flags; | 269 | u32 tiling_flags; |
| 268 | bool reserved; | ||
| 269 | }; | 270 | }; |
| 270 | 271 | ||
| 271 | /* | 272 | /* |
| @@ -377,11 +378,56 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg); | |||
| 377 | /* | 378 | /* |
| 378 | * IRQS. | 379 | * IRQS. |
| 379 | */ | 380 | */ |
| 381 | |||
| 382 | struct radeon_unpin_work { | ||
| 383 | struct work_struct work; | ||
| 384 | struct radeon_device *rdev; | ||
| 385 | int crtc_id; | ||
| 386 | struct radeon_fence *fence; | ||
| 387 | struct drm_pending_vblank_event *event; | ||
| 388 | struct radeon_bo *old_rbo; | ||
| 389 | u64 new_crtc_base; | ||
| 390 | }; | ||
| 391 | |||
| 392 | struct r500_irq_stat_regs { | ||
| 393 | u32 disp_int; | ||
| 394 | }; | ||
| 395 | |||
| 396 | struct r600_irq_stat_regs { | ||
| 397 | u32 disp_int; | ||
| 398 | u32 disp_int_cont; | ||
| 399 | u32 disp_int_cont2; | ||
| 400 | u32 d1grph_int; | ||
| 401 | u32 d2grph_int; | ||
| 402 | }; | ||
| 403 | |||
| 404 | struct evergreen_irq_stat_regs { | ||
| 405 | u32 disp_int; | ||
| 406 | u32 disp_int_cont; | ||
| 407 | u32 disp_int_cont2; | ||
| 408 | u32 disp_int_cont3; | ||
| 409 | u32 disp_int_cont4; | ||
| 410 | u32 disp_int_cont5; | ||
| 411 | u32 d1grph_int; | ||
| 412 | u32 d2grph_int; | ||
| 413 | u32 d3grph_int; | ||
| 414 | u32 d4grph_int; | ||
| 415 | u32 d5grph_int; | ||
| 416 | u32 d6grph_int; | ||
| 417 | }; | ||
| 418 | |||
| 419 | union radeon_irq_stat_regs { | ||
| 420 | struct r500_irq_stat_regs r500; | ||
| 421 | struct r600_irq_stat_regs r600; | ||
| 422 | struct evergreen_irq_stat_regs evergreen; | ||
| 423 | }; | ||
| 424 | |||
| 380 | struct radeon_irq { | 425 | struct radeon_irq { |
| 381 | bool installed; | 426 | bool installed; |
| 382 | bool sw_int; | 427 | bool sw_int; |
| 383 | /* FIXME: use a define max crtc rather than hardcode it */ | 428 | /* FIXME: use a define max crtc rather than hardcode it */ |
| 384 | bool crtc_vblank_int[6]; | 429 | bool crtc_vblank_int[6]; |
| 430 | bool pflip[6]; | ||
| 385 | wait_queue_head_t vblank_queue; | 431 | wait_queue_head_t vblank_queue; |
| 386 | /* FIXME: use defines for max hpd/dacs */ | 432 | /* FIXME: use defines for max hpd/dacs */ |
| 387 | bool hpd[6]; | 433 | bool hpd[6]; |
| @@ -392,12 +438,17 @@ struct radeon_irq { | |||
| 392 | bool hdmi[2]; | 438 | bool hdmi[2]; |
| 393 | spinlock_t sw_lock; | 439 | spinlock_t sw_lock; |
| 394 | int sw_refcount; | 440 | int sw_refcount; |
| 441 | union radeon_irq_stat_regs stat_regs; | ||
| 442 | spinlock_t pflip_lock[6]; | ||
| 443 | int pflip_refcount[6]; | ||
| 395 | }; | 444 | }; |
| 396 | 445 | ||
| 397 | int radeon_irq_kms_init(struct radeon_device *rdev); | 446 | int radeon_irq_kms_init(struct radeon_device *rdev); |
| 398 | void radeon_irq_kms_fini(struct radeon_device *rdev); | 447 | void radeon_irq_kms_fini(struct radeon_device *rdev); |
| 399 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev); | 448 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev); |
| 400 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev); | 449 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev); |
| 450 | void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); | ||
| 451 | void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); | ||
| 401 | 452 | ||
| 402 | /* | 453 | /* |
| 403 | * CP & ring. | 454 | * CP & ring. |
| @@ -687,6 +738,8 @@ enum radeon_int_thermal_type { | |||
| 687 | THERMAL_TYPE_RV6XX, | 738 | THERMAL_TYPE_RV6XX, |
| 688 | THERMAL_TYPE_RV770, | 739 | THERMAL_TYPE_RV770, |
| 689 | THERMAL_TYPE_EVERGREEN, | 740 | THERMAL_TYPE_EVERGREEN, |
| 741 | THERMAL_TYPE_SUMO, | ||
| 742 | THERMAL_TYPE_NI, | ||
| 690 | }; | 743 | }; |
| 691 | 744 | ||
| 692 | struct radeon_voltage { | 745 | struct radeon_voltage { |
| @@ -770,6 +823,9 @@ struct radeon_pm { | |||
| 770 | u32 current_sclk; | 823 | u32 current_sclk; |
| 771 | u32 current_mclk; | 824 | u32 current_mclk; |
| 772 | u32 current_vddc; | 825 | u32 current_vddc; |
| 826 | u32 default_sclk; | ||
| 827 | u32 default_mclk; | ||
| 828 | u32 default_vddc; | ||
| 773 | struct radeon_i2c_chan *i2c_bus; | 829 | struct radeon_i2c_chan *i2c_bus; |
| 774 | /* selected pm method */ | 830 | /* selected pm method */ |
| 775 | enum radeon_pm_method pm_method; | 831 | enum radeon_pm_method pm_method; |
| @@ -881,6 +937,10 @@ struct radeon_asic { | |||
| 881 | void (*pm_finish)(struct radeon_device *rdev); | 937 | void (*pm_finish)(struct radeon_device *rdev); |
| 882 | void (*pm_init_profile)(struct radeon_device *rdev); | 938 | void (*pm_init_profile)(struct radeon_device *rdev); |
| 883 | void (*pm_get_dynpm_state)(struct radeon_device *rdev); | 939 | void (*pm_get_dynpm_state)(struct radeon_device *rdev); |
| 940 | /* pageflipping */ | ||
| 941 | void (*pre_page_flip)(struct radeon_device *rdev, int crtc); | ||
| 942 | u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base); | ||
| 943 | void (*post_page_flip)(struct radeon_device *rdev, int crtc); | ||
| 884 | }; | 944 | }; |
| 885 | 945 | ||
| 886 | /* | 946 | /* |
| @@ -975,6 +1035,7 @@ struct evergreen_asic { | |||
| 975 | unsigned tiling_npipes; | 1035 | unsigned tiling_npipes; |
| 976 | unsigned tiling_group_size; | 1036 | unsigned tiling_group_size; |
| 977 | unsigned tile_config; | 1037 | unsigned tile_config; |
| 1038 | struct r100_gpu_lockup lockup; | ||
| 978 | }; | 1039 | }; |
| 979 | 1040 | ||
| 980 | union radeon_asic_config { | 1041 | union radeon_asic_config { |
| @@ -1091,11 +1152,11 @@ struct radeon_device { | |||
| 1091 | const struct firmware *me_fw; /* all family ME firmware */ | 1152 | const struct firmware *me_fw; /* all family ME firmware */ |
| 1092 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | 1153 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
| 1093 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1154 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
| 1155 | const struct firmware *mc_fw; /* NI MC firmware */ | ||
| 1094 | struct r600_blit r600_blit; | 1156 | struct r600_blit r600_blit; |
| 1095 | struct r700_vram_scratch vram_scratch; | 1157 | struct r700_vram_scratch vram_scratch; |
| 1096 | int msi_enabled; /* msi enabled */ | 1158 | int msi_enabled; /* msi enabled */ |
| 1097 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1159 | struct r600_ih ih; /* r6/700 interrupt ring */ |
| 1098 | struct workqueue_struct *wq; | ||
| 1099 | struct work_struct hotplug_work; | 1160 | struct work_struct hotplug_work; |
| 1100 | int num_crtc; /* number of crtcs */ | 1161 | int num_crtc; /* number of crtcs */ |
| 1101 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ | 1162 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ |
| @@ -1110,10 +1171,10 @@ struct radeon_device { | |||
| 1110 | uint8_t audio_status_bits; | 1171 | uint8_t audio_status_bits; |
| 1111 | uint8_t audio_category_code; | 1172 | uint8_t audio_category_code; |
| 1112 | 1173 | ||
| 1113 | bool powered_down; | ||
| 1114 | struct notifier_block acpi_nb; | 1174 | struct notifier_block acpi_nb; |
| 1115 | /* only one userspace can use Hyperz features at a time */ | 1175 | /* only one userspace can use Hyperz features or CMASK at a time */ |
| 1116 | struct drm_file *hyperz_filp; | 1176 | struct drm_file *hyperz_filp; |
| 1177 | struct drm_file *cmask_filp; | ||
| 1117 | /* i2c buses */ | 1178 | /* i2c buses */ |
| 1118 | struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS]; | 1179 | struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS]; |
| 1119 | }; | 1180 | }; |
| @@ -1188,6 +1249,8 @@ static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
| 1188 | */ | 1249 | */ |
| 1189 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) | 1250 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) |
| 1190 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) | 1251 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) |
| 1252 | #define RREG16(reg) readw(((void __iomem *)rdev->rmmio) + (reg)) | ||
| 1253 | #define WREG16(reg, v) writew(v, ((void __iomem *)rdev->rmmio) + (reg)) | ||
| 1191 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) | 1254 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) |
| 1192 | #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) | 1255 | #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) |
| 1193 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) | 1256 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) |
| @@ -1261,6 +1324,14 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); | |||
| 1261 | (rdev->family == CHIP_RV410) || \ | 1324 | (rdev->family == CHIP_RV410) || \ |
| 1262 | (rdev->family == CHIP_RS400) || \ | 1325 | (rdev->family == CHIP_RS400) || \ |
| 1263 | (rdev->family == CHIP_RS480)) | 1326 | (rdev->family == CHIP_RS480)) |
| 1327 | #define ASIC_IS_X2(rdev) ((rdev->ddev->pdev->device == 0x9441) || \ | ||
| 1328 | (rdev->ddev->pdev->device == 0x9443) || \ | ||
| 1329 | (rdev->ddev->pdev->device == 0x944B) || \ | ||
| 1330 | (rdev->ddev->pdev->device == 0x9506) || \ | ||
| 1331 | (rdev->ddev->pdev->device == 0x9509) || \ | ||
| 1332 | (rdev->ddev->pdev->device == 0x950F) || \ | ||
| 1333 | (rdev->ddev->pdev->device == 0x689C) || \ | ||
| 1334 | (rdev->ddev->pdev->device == 0x689D)) | ||
| 1264 | #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) | 1335 | #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) |
| 1265 | #define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \ | 1336 | #define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \ |
| 1266 | (rdev->family == CHIP_RS690) || \ | 1337 | (rdev->family == CHIP_RS690) || \ |
| @@ -1269,6 +1340,9 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); | |||
| 1269 | #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) | 1340 | #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) |
| 1270 | #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) | 1341 | #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) |
| 1271 | #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) | 1342 | #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) |
| 1343 | #define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM) && \ | ||
| 1344 | (rdev->flags & RADEON_IS_IGP)) | ||
| 1345 | #define ASIC_IS_DCE5(rdev) ((rdev->family >= CHIP_BARTS)) | ||
| 1272 | 1346 | ||
| 1273 | /* | 1347 | /* |
| 1274 | * BIOS helpers. | 1348 | * BIOS helpers. |
| @@ -1344,6 +1418,9 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
| 1344 | #define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev)) | 1418 | #define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev)) |
| 1345 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm_init_profile((rdev)) | 1419 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm_init_profile((rdev)) |
| 1346 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm_get_dynpm_state((rdev)) | 1420 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm_get_dynpm_state((rdev)) |
| 1421 | #define radeon_pre_page_flip(rdev, crtc) rdev->asic->pre_page_flip((rdev), (crtc)) | ||
| 1422 | #define radeon_page_flip(rdev, crtc, base) rdev->asic->page_flip((rdev), (crtc), (base)) | ||
| 1423 | #define radeon_post_page_flip(rdev, crtc) rdev->asic->post_page_flip((rdev), (crtc)) | ||
| 1347 | 1424 | ||
| 1348 | /* Common functions */ | 1425 | /* Common functions */ |
| 1349 | /* AGP */ | 1426 | /* AGP */ |
| @@ -1372,67 +1449,7 @@ extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc | |||
| 1372 | extern int radeon_resume_kms(struct drm_device *dev); | 1449 | extern int radeon_resume_kms(struct drm_device *dev); |
| 1373 | extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | 1450 | extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); |
| 1374 | 1451 | ||
| 1375 | /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ | ||
| 1376 | extern void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp); | ||
| 1377 | extern bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp); | ||
| 1378 | |||
| 1379 | /* rv200,rv250,rv280 */ | ||
| 1380 | extern void r200_set_safe_registers(struct radeon_device *rdev); | ||
| 1381 | |||
| 1382 | /* r300,r350,rv350,rv370,rv380 */ | ||
| 1383 | extern void r300_set_reg_safe(struct radeon_device *rdev); | ||
| 1384 | extern void r300_mc_program(struct radeon_device *rdev); | ||
| 1385 | extern void r300_mc_init(struct radeon_device *rdev); | ||
| 1386 | extern void r300_clock_startup(struct radeon_device *rdev); | ||
| 1387 | extern int r300_mc_wait_for_idle(struct radeon_device *rdev); | ||
| 1388 | extern int rv370_pcie_gart_init(struct radeon_device *rdev); | ||
| 1389 | extern void rv370_pcie_gart_fini(struct radeon_device *rdev); | ||
| 1390 | extern int rv370_pcie_gart_enable(struct radeon_device *rdev); | ||
| 1391 | extern void rv370_pcie_gart_disable(struct radeon_device *rdev); | ||
| 1392 | |||
| 1393 | /* r420,r423,rv410 */ | ||
| 1394 | extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg); | ||
| 1395 | extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v); | ||
| 1396 | extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev); | ||
| 1397 | extern void r420_pipes_init(struct radeon_device *rdev); | ||
| 1398 | |||
| 1399 | /* rv515 */ | ||
| 1400 | struct rv515_mc_save { | ||
| 1401 | u32 d1vga_control; | ||
| 1402 | u32 d2vga_control; | ||
| 1403 | u32 vga_render_control; | ||
| 1404 | u32 vga_hdp_control; | ||
| 1405 | u32 d1crtc_control; | ||
| 1406 | u32 d2crtc_control; | ||
| 1407 | }; | ||
| 1408 | extern void rv515_bandwidth_avivo_update(struct radeon_device *rdev); | ||
| 1409 | extern void rv515_vga_render_disable(struct radeon_device *rdev); | ||
| 1410 | extern void rv515_set_safe_registers(struct radeon_device *rdev); | ||
| 1411 | extern void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save); | ||
| 1412 | extern void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save); | ||
| 1413 | extern void rv515_clock_startup(struct radeon_device *rdev); | ||
| 1414 | extern void rv515_debugfs(struct radeon_device *rdev); | ||
| 1415 | extern int rv515_suspend(struct radeon_device *rdev); | ||
| 1416 | |||
| 1417 | /* rs400 */ | ||
| 1418 | extern int rs400_gart_init(struct radeon_device *rdev); | ||
| 1419 | extern int rs400_gart_enable(struct radeon_device *rdev); | ||
| 1420 | extern void rs400_gart_adjust_size(struct radeon_device *rdev); | ||
| 1421 | extern void rs400_gart_disable(struct radeon_device *rdev); | ||
| 1422 | extern void rs400_gart_fini(struct radeon_device *rdev); | ||
| 1423 | |||
| 1424 | /* rs600 */ | ||
| 1425 | extern void rs600_set_safe_registers(struct radeon_device *rdev); | ||
| 1426 | extern int rs600_irq_set(struct radeon_device *rdev); | ||
| 1427 | extern void rs600_irq_disable(struct radeon_device *rdev); | ||
| 1428 | |||
| 1429 | /* rs690, rs740 */ | ||
| 1430 | extern void rs690_line_buffer_adjust(struct radeon_device *rdev, | ||
| 1431 | struct drm_display_mode *mode1, | ||
| 1432 | struct drm_display_mode *mode2); | ||
| 1433 | |||
| 1434 | /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */ | 1452 | /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */ |
| 1435 | extern void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | ||
| 1436 | extern bool r600_card_posted(struct radeon_device *rdev); | 1453 | extern bool r600_card_posted(struct radeon_device *rdev); |
| 1437 | extern void r600_cp_stop(struct radeon_device *rdev); | 1454 | extern void r600_cp_stop(struct radeon_device *rdev); |
| 1438 | extern int r600_cp_start(struct radeon_device *rdev); | 1455 | extern int r600_cp_start(struct radeon_device *rdev); |
| @@ -1478,6 +1495,7 @@ extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mo | |||
| 1478 | extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); | 1495 | extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); |
| 1479 | extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); | 1496 | extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); |
| 1480 | 1497 | ||
| 1498 | extern void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | ||
| 1481 | extern void r700_cp_stop(struct radeon_device *rdev); | 1499 | extern void r700_cp_stop(struct radeon_device *rdev); |
| 1482 | extern void r700_cp_fini(struct radeon_device *rdev); | 1500 | extern void r700_cp_fini(struct radeon_device *rdev); |
| 1483 | extern void evergreen_disable_interrupt_state(struct radeon_device *rdev); | 1501 | extern void evergreen_disable_interrupt_state(struct radeon_device *rdev); |
| @@ -1485,6 +1503,9 @@ extern int evergreen_irq_set(struct radeon_device *rdev); | |||
| 1485 | extern int evergreen_blit_init(struct radeon_device *rdev); | 1503 | extern int evergreen_blit_init(struct radeon_device *rdev); |
| 1486 | extern void evergreen_blit_fini(struct radeon_device *rdev); | 1504 | extern void evergreen_blit_fini(struct radeon_device *rdev); |
| 1487 | 1505 | ||
| 1506 | extern int ni_init_microcode(struct radeon_device *rdev); | ||
| 1507 | extern int btc_mc_load_microcode(struct radeon_device *rdev); | ||
| 1508 | |||
| 1488 | /* radeon_acpi.c */ | 1509 | /* radeon_acpi.c */ |
| 1489 | #if defined(CONFIG_ACPI) | 1510 | #if defined(CONFIG_ACPI) |
| 1490 | extern int radeon_acpi_init(struct radeon_device *rdev); | 1511 | extern int radeon_acpi_init(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 64fb89ecbf74..3a1b16186224 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
| @@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) | |||
| 94 | rdev->mc_rreg = &rs600_mc_rreg; | 94 | rdev->mc_rreg = &rs600_mc_rreg; |
| 95 | rdev->mc_wreg = &rs600_mc_wreg; | 95 | rdev->mc_wreg = &rs600_mc_wreg; |
| 96 | } | 96 | } |
| 97 | if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { | 97 | if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) { |
| 98 | rdev->pciep_rreg = &r600_pciep_rreg; | 98 | rdev->pciep_rreg = &r600_pciep_rreg; |
| 99 | rdev->pciep_wreg = &r600_pciep_wreg; | 99 | rdev->pciep_wreg = &r600_pciep_wreg; |
| 100 | } | 100 | } |
| @@ -171,6 +171,9 @@ static struct radeon_asic r100_asic = { | |||
| 171 | .pm_finish = &r100_pm_finish, | 171 | .pm_finish = &r100_pm_finish, |
| 172 | .pm_init_profile = &r100_pm_init_profile, | 172 | .pm_init_profile = &r100_pm_init_profile, |
| 173 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 173 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 174 | .pre_page_flip = &r100_pre_page_flip, | ||
| 175 | .page_flip = &r100_page_flip, | ||
| 176 | .post_page_flip = &r100_post_page_flip, | ||
| 174 | }; | 177 | }; |
| 175 | 178 | ||
| 176 | static struct radeon_asic r200_asic = { | 179 | static struct radeon_asic r200_asic = { |
| @@ -215,6 +218,9 @@ static struct radeon_asic r200_asic = { | |||
| 215 | .pm_finish = &r100_pm_finish, | 218 | .pm_finish = &r100_pm_finish, |
| 216 | .pm_init_profile = &r100_pm_init_profile, | 219 | .pm_init_profile = &r100_pm_init_profile, |
| 217 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 220 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 221 | .pre_page_flip = &r100_pre_page_flip, | ||
| 222 | .page_flip = &r100_page_flip, | ||
| 223 | .post_page_flip = &r100_post_page_flip, | ||
| 218 | }; | 224 | }; |
| 219 | 225 | ||
| 220 | static struct radeon_asic r300_asic = { | 226 | static struct radeon_asic r300_asic = { |
| @@ -260,6 +266,9 @@ static struct radeon_asic r300_asic = { | |||
| 260 | .pm_finish = &r100_pm_finish, | 266 | .pm_finish = &r100_pm_finish, |
| 261 | .pm_init_profile = &r100_pm_init_profile, | 267 | .pm_init_profile = &r100_pm_init_profile, |
| 262 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 268 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 269 | .pre_page_flip = &r100_pre_page_flip, | ||
| 270 | .page_flip = &r100_page_flip, | ||
| 271 | .post_page_flip = &r100_post_page_flip, | ||
| 263 | }; | 272 | }; |
| 264 | 273 | ||
| 265 | static struct radeon_asic r300_asic_pcie = { | 274 | static struct radeon_asic r300_asic_pcie = { |
| @@ -304,6 +313,9 @@ static struct radeon_asic r300_asic_pcie = { | |||
| 304 | .pm_finish = &r100_pm_finish, | 313 | .pm_finish = &r100_pm_finish, |
| 305 | .pm_init_profile = &r100_pm_init_profile, | 314 | .pm_init_profile = &r100_pm_init_profile, |
| 306 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 315 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 316 | .pre_page_flip = &r100_pre_page_flip, | ||
| 317 | .page_flip = &r100_page_flip, | ||
| 318 | .post_page_flip = &r100_post_page_flip, | ||
| 307 | }; | 319 | }; |
| 308 | 320 | ||
| 309 | static struct radeon_asic r420_asic = { | 321 | static struct radeon_asic r420_asic = { |
| @@ -349,6 +361,9 @@ static struct radeon_asic r420_asic = { | |||
| 349 | .pm_finish = &r100_pm_finish, | 361 | .pm_finish = &r100_pm_finish, |
| 350 | .pm_init_profile = &r420_pm_init_profile, | 362 | .pm_init_profile = &r420_pm_init_profile, |
| 351 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 363 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 364 | .pre_page_flip = &r100_pre_page_flip, | ||
| 365 | .page_flip = &r100_page_flip, | ||
| 366 | .post_page_flip = &r100_post_page_flip, | ||
| 352 | }; | 367 | }; |
| 353 | 368 | ||
| 354 | static struct radeon_asic rs400_asic = { | 369 | static struct radeon_asic rs400_asic = { |
| @@ -394,6 +409,9 @@ static struct radeon_asic rs400_asic = { | |||
| 394 | .pm_finish = &r100_pm_finish, | 409 | .pm_finish = &r100_pm_finish, |
| 395 | .pm_init_profile = &r100_pm_init_profile, | 410 | .pm_init_profile = &r100_pm_init_profile, |
| 396 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 411 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 412 | .pre_page_flip = &r100_pre_page_flip, | ||
| 413 | .page_flip = &r100_page_flip, | ||
| 414 | .post_page_flip = &r100_post_page_flip, | ||
| 397 | }; | 415 | }; |
| 398 | 416 | ||
| 399 | static struct radeon_asic rs600_asic = { | 417 | static struct radeon_asic rs600_asic = { |
| @@ -439,6 +457,9 @@ static struct radeon_asic rs600_asic = { | |||
| 439 | .pm_finish = &rs600_pm_finish, | 457 | .pm_finish = &rs600_pm_finish, |
| 440 | .pm_init_profile = &r420_pm_init_profile, | 458 | .pm_init_profile = &r420_pm_init_profile, |
| 441 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 459 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 460 | .pre_page_flip = &rs600_pre_page_flip, | ||
| 461 | .page_flip = &rs600_page_flip, | ||
| 462 | .post_page_flip = &rs600_post_page_flip, | ||
| 442 | }; | 463 | }; |
| 443 | 464 | ||
| 444 | static struct radeon_asic rs690_asic = { | 465 | static struct radeon_asic rs690_asic = { |
| @@ -484,6 +505,9 @@ static struct radeon_asic rs690_asic = { | |||
| 484 | .pm_finish = &rs600_pm_finish, | 505 | .pm_finish = &rs600_pm_finish, |
| 485 | .pm_init_profile = &r420_pm_init_profile, | 506 | .pm_init_profile = &r420_pm_init_profile, |
| 486 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 507 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 508 | .pre_page_flip = &rs600_pre_page_flip, | ||
| 509 | .page_flip = &rs600_page_flip, | ||
| 510 | .post_page_flip = &rs600_post_page_flip, | ||
| 487 | }; | 511 | }; |
| 488 | 512 | ||
| 489 | static struct radeon_asic rv515_asic = { | 513 | static struct radeon_asic rv515_asic = { |
| @@ -529,6 +553,9 @@ static struct radeon_asic rv515_asic = { | |||
| 529 | .pm_finish = &rs600_pm_finish, | 553 | .pm_finish = &rs600_pm_finish, |
| 530 | .pm_init_profile = &r420_pm_init_profile, | 554 | .pm_init_profile = &r420_pm_init_profile, |
| 531 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 555 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 556 | .pre_page_flip = &rs600_pre_page_flip, | ||
| 557 | .page_flip = &rs600_page_flip, | ||
| 558 | .post_page_flip = &rs600_post_page_flip, | ||
| 532 | }; | 559 | }; |
| 533 | 560 | ||
| 534 | static struct radeon_asic r520_asic = { | 561 | static struct radeon_asic r520_asic = { |
| @@ -574,6 +601,9 @@ static struct radeon_asic r520_asic = { | |||
| 574 | .pm_finish = &rs600_pm_finish, | 601 | .pm_finish = &rs600_pm_finish, |
| 575 | .pm_init_profile = &r420_pm_init_profile, | 602 | .pm_init_profile = &r420_pm_init_profile, |
| 576 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, | 603 | .pm_get_dynpm_state = &r100_pm_get_dynpm_state, |
| 604 | .pre_page_flip = &rs600_pre_page_flip, | ||
| 605 | .page_flip = &rs600_page_flip, | ||
| 606 | .post_page_flip = &rs600_post_page_flip, | ||
| 577 | }; | 607 | }; |
| 578 | 608 | ||
| 579 | static struct radeon_asic r600_asic = { | 609 | static struct radeon_asic r600_asic = { |
| @@ -601,8 +631,8 @@ static struct radeon_asic r600_asic = { | |||
| 601 | .set_engine_clock = &radeon_atom_set_engine_clock, | 631 | .set_engine_clock = &radeon_atom_set_engine_clock, |
| 602 | .get_memory_clock = &radeon_atom_get_memory_clock, | 632 | .get_memory_clock = &radeon_atom_get_memory_clock, |
| 603 | .set_memory_clock = &radeon_atom_set_memory_clock, | 633 | .set_memory_clock = &radeon_atom_set_memory_clock, |
| 604 | .get_pcie_lanes = &rv370_get_pcie_lanes, | 634 | .get_pcie_lanes = &r600_get_pcie_lanes, |
| 605 | .set_pcie_lanes = NULL, | 635 | .set_pcie_lanes = &r600_set_pcie_lanes, |
| 606 | .set_clock_gating = NULL, | 636 | .set_clock_gating = NULL, |
| 607 | .set_surface_reg = r600_set_surface_reg, | 637 | .set_surface_reg = r600_set_surface_reg, |
| 608 | .clear_surface_reg = r600_clear_surface_reg, | 638 | .clear_surface_reg = r600_clear_surface_reg, |
| @@ -618,6 +648,9 @@ static struct radeon_asic r600_asic = { | |||
| 618 | .pm_finish = &rs600_pm_finish, | 648 | .pm_finish = &rs600_pm_finish, |
| 619 | .pm_init_profile = &r600_pm_init_profile, | 649 | .pm_init_profile = &r600_pm_init_profile, |
| 620 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | 650 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, |
| 651 | .pre_page_flip = &rs600_pre_page_flip, | ||
| 652 | .page_flip = &rs600_page_flip, | ||
| 653 | .post_page_flip = &rs600_post_page_flip, | ||
| 621 | }; | 654 | }; |
| 622 | 655 | ||
| 623 | static struct radeon_asic rs780_asic = { | 656 | static struct radeon_asic rs780_asic = { |
| @@ -662,6 +695,9 @@ static struct radeon_asic rs780_asic = { | |||
| 662 | .pm_finish = &rs600_pm_finish, | 695 | .pm_finish = &rs600_pm_finish, |
| 663 | .pm_init_profile = &rs780_pm_init_profile, | 696 | .pm_init_profile = &rs780_pm_init_profile, |
| 664 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | 697 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, |
| 698 | .pre_page_flip = &rs600_pre_page_flip, | ||
| 699 | .page_flip = &rs600_page_flip, | ||
| 700 | .post_page_flip = &rs600_post_page_flip, | ||
| 665 | }; | 701 | }; |
| 666 | 702 | ||
| 667 | static struct radeon_asic rv770_asic = { | 703 | static struct radeon_asic rv770_asic = { |
| @@ -689,8 +725,8 @@ static struct radeon_asic rv770_asic = { | |||
| 689 | .set_engine_clock = &radeon_atom_set_engine_clock, | 725 | .set_engine_clock = &radeon_atom_set_engine_clock, |
| 690 | .get_memory_clock = &radeon_atom_get_memory_clock, | 726 | .get_memory_clock = &radeon_atom_get_memory_clock, |
| 691 | .set_memory_clock = &radeon_atom_set_memory_clock, | 727 | .set_memory_clock = &radeon_atom_set_memory_clock, |
| 692 | .get_pcie_lanes = &rv370_get_pcie_lanes, | 728 | .get_pcie_lanes = &r600_get_pcie_lanes, |
| 693 | .set_pcie_lanes = NULL, | 729 | .set_pcie_lanes = &r600_set_pcie_lanes, |
| 694 | .set_clock_gating = &radeon_atom_set_clock_gating, | 730 | .set_clock_gating = &radeon_atom_set_clock_gating, |
| 695 | .set_surface_reg = r600_set_surface_reg, | 731 | .set_surface_reg = r600_set_surface_reg, |
| 696 | .clear_surface_reg = r600_clear_surface_reg, | 732 | .clear_surface_reg = r600_clear_surface_reg, |
| @@ -706,6 +742,9 @@ static struct radeon_asic rv770_asic = { | |||
| 706 | .pm_finish = &rs600_pm_finish, | 742 | .pm_finish = &rs600_pm_finish, |
| 707 | .pm_init_profile = &r600_pm_init_profile, | 743 | .pm_init_profile = &r600_pm_init_profile, |
| 708 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | 744 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, |
| 745 | .pre_page_flip = &rs600_pre_page_flip, | ||
| 746 | .page_flip = &rv770_page_flip, | ||
| 747 | .post_page_flip = &rs600_post_page_flip, | ||
| 709 | }; | 748 | }; |
| 710 | 749 | ||
| 711 | static struct radeon_asic evergreen_asic = { | 750 | static struct radeon_asic evergreen_asic = { |
| @@ -733,6 +772,95 @@ static struct radeon_asic evergreen_asic = { | |||
| 733 | .set_engine_clock = &radeon_atom_set_engine_clock, | 772 | .set_engine_clock = &radeon_atom_set_engine_clock, |
| 734 | .get_memory_clock = &radeon_atom_get_memory_clock, | 773 | .get_memory_clock = &radeon_atom_get_memory_clock, |
| 735 | .set_memory_clock = &radeon_atom_set_memory_clock, | 774 | .set_memory_clock = &radeon_atom_set_memory_clock, |
| 775 | .get_pcie_lanes = &r600_get_pcie_lanes, | ||
| 776 | .set_pcie_lanes = &r600_set_pcie_lanes, | ||
| 777 | .set_clock_gating = NULL, | ||
| 778 | .set_surface_reg = r600_set_surface_reg, | ||
| 779 | .clear_surface_reg = r600_clear_surface_reg, | ||
| 780 | .bandwidth_update = &evergreen_bandwidth_update, | ||
| 781 | .hpd_init = &evergreen_hpd_init, | ||
| 782 | .hpd_fini = &evergreen_hpd_fini, | ||
| 783 | .hpd_sense = &evergreen_hpd_sense, | ||
| 784 | .hpd_set_polarity = &evergreen_hpd_set_polarity, | ||
| 785 | .gui_idle = &r600_gui_idle, | ||
| 786 | .pm_misc = &evergreen_pm_misc, | ||
| 787 | .pm_prepare = &evergreen_pm_prepare, | ||
| 788 | .pm_finish = &evergreen_pm_finish, | ||
| 789 | .pm_init_profile = &r600_pm_init_profile, | ||
| 790 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | ||
| 791 | .pre_page_flip = &evergreen_pre_page_flip, | ||
| 792 | .page_flip = &evergreen_page_flip, | ||
| 793 | .post_page_flip = &evergreen_post_page_flip, | ||
| 794 | }; | ||
| 795 | |||
| 796 | static struct radeon_asic sumo_asic = { | ||
| 797 | .init = &evergreen_init, | ||
| 798 | .fini = &evergreen_fini, | ||
| 799 | .suspend = &evergreen_suspend, | ||
| 800 | .resume = &evergreen_resume, | ||
| 801 | .cp_commit = &r600_cp_commit, | ||
| 802 | .gpu_is_lockup = &evergreen_gpu_is_lockup, | ||
| 803 | .asic_reset = &evergreen_asic_reset, | ||
| 804 | .vga_set_state = &r600_vga_set_state, | ||
| 805 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, | ||
| 806 | .gart_set_page = &rs600_gart_set_page, | ||
| 807 | .ring_test = &r600_ring_test, | ||
| 808 | .ring_ib_execute = &r600_ring_ib_execute, | ||
| 809 | .irq_set = &evergreen_irq_set, | ||
| 810 | .irq_process = &evergreen_irq_process, | ||
| 811 | .get_vblank_counter = &evergreen_get_vblank_counter, | ||
| 812 | .fence_ring_emit = &r600_fence_ring_emit, | ||
| 813 | .cs_parse = &evergreen_cs_parse, | ||
| 814 | .copy_blit = &evergreen_copy_blit, | ||
| 815 | .copy_dma = &evergreen_copy_blit, | ||
| 816 | .copy = &evergreen_copy_blit, | ||
| 817 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
| 818 | .set_engine_clock = &radeon_atom_set_engine_clock, | ||
| 819 | .get_memory_clock = NULL, | ||
| 820 | .set_memory_clock = NULL, | ||
| 821 | .get_pcie_lanes = NULL, | ||
| 822 | .set_pcie_lanes = NULL, | ||
| 823 | .set_clock_gating = NULL, | ||
| 824 | .set_surface_reg = r600_set_surface_reg, | ||
| 825 | .clear_surface_reg = r600_clear_surface_reg, | ||
| 826 | .bandwidth_update = &evergreen_bandwidth_update, | ||
| 827 | .hpd_init = &evergreen_hpd_init, | ||
| 828 | .hpd_fini = &evergreen_hpd_fini, | ||
| 829 | .hpd_sense = &evergreen_hpd_sense, | ||
| 830 | .hpd_set_polarity = &evergreen_hpd_set_polarity, | ||
| 831 | .gui_idle = &r600_gui_idle, | ||
| 832 | .pm_misc = &evergreen_pm_misc, | ||
| 833 | .pm_prepare = &evergreen_pm_prepare, | ||
| 834 | .pm_finish = &evergreen_pm_finish, | ||
| 835 | .pm_init_profile = &rs780_pm_init_profile, | ||
| 836 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | ||
| 837 | }; | ||
| 838 | |||
| 839 | static struct radeon_asic btc_asic = { | ||
| 840 | .init = &evergreen_init, | ||
| 841 | .fini = &evergreen_fini, | ||
| 842 | .suspend = &evergreen_suspend, | ||
| 843 | .resume = &evergreen_resume, | ||
| 844 | .cp_commit = &r600_cp_commit, | ||
| 845 | .gpu_is_lockup = &evergreen_gpu_is_lockup, | ||
| 846 | .asic_reset = &evergreen_asic_reset, | ||
| 847 | .vga_set_state = &r600_vga_set_state, | ||
| 848 | .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, | ||
| 849 | .gart_set_page = &rs600_gart_set_page, | ||
| 850 | .ring_test = &r600_ring_test, | ||
| 851 | .ring_ib_execute = &r600_ring_ib_execute, | ||
| 852 | .irq_set = &evergreen_irq_set, | ||
| 853 | .irq_process = &evergreen_irq_process, | ||
| 854 | .get_vblank_counter = &evergreen_get_vblank_counter, | ||
| 855 | .fence_ring_emit = &r600_fence_ring_emit, | ||
| 856 | .cs_parse = &evergreen_cs_parse, | ||
| 857 | .copy_blit = &evergreen_copy_blit, | ||
| 858 | .copy_dma = &evergreen_copy_blit, | ||
| 859 | .copy = &evergreen_copy_blit, | ||
| 860 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
| 861 | .set_engine_clock = &radeon_atom_set_engine_clock, | ||
| 862 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
| 863 | .set_memory_clock = &radeon_atom_set_memory_clock, | ||
| 736 | .get_pcie_lanes = NULL, | 864 | .get_pcie_lanes = NULL, |
| 737 | .set_pcie_lanes = NULL, | 865 | .set_pcie_lanes = NULL, |
| 738 | .set_clock_gating = NULL, | 866 | .set_clock_gating = NULL, |
| @@ -749,6 +877,9 @@ static struct radeon_asic evergreen_asic = { | |||
| 749 | .pm_finish = &evergreen_pm_finish, | 877 | .pm_finish = &evergreen_pm_finish, |
| 750 | .pm_init_profile = &r600_pm_init_profile, | 878 | .pm_init_profile = &r600_pm_init_profile, |
| 751 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | 879 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, |
| 880 | .pre_page_flip = &evergreen_pre_page_flip, | ||
| 881 | .page_flip = &evergreen_page_flip, | ||
| 882 | .post_page_flip = &evergreen_post_page_flip, | ||
| 752 | }; | 883 | }; |
| 753 | 884 | ||
| 754 | int radeon_asic_init(struct radeon_device *rdev) | 885 | int radeon_asic_init(struct radeon_device *rdev) |
| @@ -835,6 +966,14 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
| 835 | case CHIP_HEMLOCK: | 966 | case CHIP_HEMLOCK: |
| 836 | rdev->asic = &evergreen_asic; | 967 | rdev->asic = &evergreen_asic; |
| 837 | break; | 968 | break; |
| 969 | case CHIP_PALM: | ||
| 970 | rdev->asic = &sumo_asic; | ||
| 971 | break; | ||
| 972 | case CHIP_BARTS: | ||
| 973 | case CHIP_TURKS: | ||
| 974 | case CHIP_CAICOS: | ||
| 975 | rdev->asic = &btc_asic; | ||
| 976 | break; | ||
| 838 | default: | 977 | default: |
| 839 | /* FIXME: not supported yet */ | 978 | /* FIXME: not supported yet */ |
| 840 | return -EINVAL; | 979 | return -EINVAL; |
| @@ -849,7 +988,9 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
| 849 | if (rdev->flags & RADEON_SINGLE_CRTC) | 988 | if (rdev->flags & RADEON_SINGLE_CRTC) |
| 850 | rdev->num_crtc = 1; | 989 | rdev->num_crtc = 1; |
| 851 | else { | 990 | else { |
| 852 | if (ASIC_IS_DCE4(rdev)) | 991 | if (ASIC_IS_DCE41(rdev)) |
| 992 | rdev->num_crtc = 2; | ||
| 993 | else if (ASIC_IS_DCE4(rdev)) | ||
| 853 | rdev->num_crtc = 6; | 994 | rdev->num_crtc = 6; |
| 854 | else | 995 | else |
| 855 | rdev->num_crtc = 2; | 996 | rdev->num_crtc = 2; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 740988244143..e01f07718539 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -102,6 +102,11 @@ int r100_pci_gart_enable(struct radeon_device *rdev); | |||
| 102 | void r100_pci_gart_disable(struct radeon_device *rdev); | 102 | void r100_pci_gart_disable(struct radeon_device *rdev); |
| 103 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); | 103 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); |
| 104 | int r100_gui_wait_for_idle(struct radeon_device *rdev); | 104 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
| 105 | void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, | ||
| 106 | struct radeon_cp *cp); | ||
| 107 | bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, | ||
| 108 | struct r100_gpu_lockup *lockup, | ||
| 109 | struct radeon_cp *cp); | ||
| 105 | void r100_ib_fini(struct radeon_device *rdev); | 110 | void r100_ib_fini(struct radeon_device *rdev); |
| 106 | int r100_ib_init(struct radeon_device *rdev); | 111 | int r100_ib_init(struct radeon_device *rdev); |
| 107 | void r100_irq_disable(struct radeon_device *rdev); | 112 | void r100_irq_disable(struct radeon_device *rdev); |
| @@ -130,15 +135,19 @@ extern void r100_pm_prepare(struct radeon_device *rdev); | |||
| 130 | extern void r100_pm_finish(struct radeon_device *rdev); | 135 | extern void r100_pm_finish(struct radeon_device *rdev); |
| 131 | extern void r100_pm_init_profile(struct radeon_device *rdev); | 136 | extern void r100_pm_init_profile(struct radeon_device *rdev); |
| 132 | extern void r100_pm_get_dynpm_state(struct radeon_device *rdev); | 137 | extern void r100_pm_get_dynpm_state(struct radeon_device *rdev); |
| 138 | extern void r100_pre_page_flip(struct radeon_device *rdev, int crtc); | ||
| 139 | extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | ||
| 140 | extern void r100_post_page_flip(struct radeon_device *rdev, int crtc); | ||
| 133 | 141 | ||
| 134 | /* | 142 | /* |
| 135 | * r200,rv250,rs300,rv280 | 143 | * r200,rv250,rs300,rv280 |
| 136 | */ | 144 | */ |
| 137 | extern int r200_copy_dma(struct radeon_device *rdev, | 145 | extern int r200_copy_dma(struct radeon_device *rdev, |
| 138 | uint64_t src_offset, | 146 | uint64_t src_offset, |
| 139 | uint64_t dst_offset, | 147 | uint64_t dst_offset, |
| 140 | unsigned num_pages, | 148 | unsigned num_pages, |
| 141 | struct radeon_fence *fence); | 149 | struct radeon_fence *fence); |
| 150 | void r200_set_safe_registers(struct radeon_device *rdev); | ||
| 142 | 151 | ||
| 143 | /* | 152 | /* |
| 144 | * r300,r350,rv350,rv380 | 153 | * r300,r350,rv350,rv380 |
| @@ -159,6 +168,15 @@ extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg); | |||
| 159 | extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 168 | extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 160 | extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); | 169 | extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); |
| 161 | extern int rv370_get_pcie_lanes(struct radeon_device *rdev); | 170 | extern int rv370_get_pcie_lanes(struct radeon_device *rdev); |
| 171 | extern void r300_set_reg_safe(struct radeon_device *rdev); | ||
| 172 | extern void r300_mc_program(struct radeon_device *rdev); | ||
| 173 | extern void r300_mc_init(struct radeon_device *rdev); | ||
| 174 | extern void r300_clock_startup(struct radeon_device *rdev); | ||
| 175 | extern int r300_mc_wait_for_idle(struct radeon_device *rdev); | ||
| 176 | extern int rv370_pcie_gart_init(struct radeon_device *rdev); | ||
| 177 | extern void rv370_pcie_gart_fini(struct radeon_device *rdev); | ||
| 178 | extern int rv370_pcie_gart_enable(struct radeon_device *rdev); | ||
| 179 | extern void rv370_pcie_gart_disable(struct radeon_device *rdev); | ||
| 162 | 180 | ||
| 163 | /* | 181 | /* |
| 164 | * r420,r423,rv410 | 182 | * r420,r423,rv410 |
| @@ -168,6 +186,10 @@ extern void r420_fini(struct radeon_device *rdev); | |||
| 168 | extern int r420_suspend(struct radeon_device *rdev); | 186 | extern int r420_suspend(struct radeon_device *rdev); |
| 169 | extern int r420_resume(struct radeon_device *rdev); | 187 | extern int r420_resume(struct radeon_device *rdev); |
| 170 | extern void r420_pm_init_profile(struct radeon_device *rdev); | 188 | extern void r420_pm_init_profile(struct radeon_device *rdev); |
| 189 | extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg); | ||
| 190 | extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v); | ||
| 191 | extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev); | ||
| 192 | extern void r420_pipes_init(struct radeon_device *rdev); | ||
| 171 | 193 | ||
| 172 | /* | 194 | /* |
| 173 | * rs400,rs480 | 195 | * rs400,rs480 |
| @@ -180,6 +202,12 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev); | |||
| 180 | int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | 202 | int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); |
| 181 | uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 203 | uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 182 | void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 204 | void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 205 | int rs400_gart_init(struct radeon_device *rdev); | ||
| 206 | int rs400_gart_enable(struct radeon_device *rdev); | ||
| 207 | void rs400_gart_adjust_size(struct radeon_device *rdev); | ||
| 208 | void rs400_gart_disable(struct radeon_device *rdev); | ||
| 209 | void rs400_gart_fini(struct radeon_device *rdev); | ||
| 210 | |||
| 183 | 211 | ||
| 184 | /* | 212 | /* |
| 185 | * rs600. | 213 | * rs600. |
| @@ -191,6 +219,7 @@ extern int rs600_suspend(struct radeon_device *rdev); | |||
| 191 | extern int rs600_resume(struct radeon_device *rdev); | 219 | extern int rs600_resume(struct radeon_device *rdev); |
| 192 | int rs600_irq_set(struct radeon_device *rdev); | 220 | int rs600_irq_set(struct radeon_device *rdev); |
| 193 | int rs600_irq_process(struct radeon_device *rdev); | 221 | int rs600_irq_process(struct radeon_device *rdev); |
| 222 | void rs600_irq_disable(struct radeon_device *rdev); | ||
| 194 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); | 223 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); |
| 195 | void rs600_gart_tlb_flush(struct radeon_device *rdev); | 224 | void rs600_gart_tlb_flush(struct radeon_device *rdev); |
| 196 | int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | 225 | int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); |
| @@ -205,6 +234,11 @@ void rs600_hpd_set_polarity(struct radeon_device *rdev, | |||
| 205 | extern void rs600_pm_misc(struct radeon_device *rdev); | 234 | extern void rs600_pm_misc(struct radeon_device *rdev); |
| 206 | extern void rs600_pm_prepare(struct radeon_device *rdev); | 235 | extern void rs600_pm_prepare(struct radeon_device *rdev); |
| 207 | extern void rs600_pm_finish(struct radeon_device *rdev); | 236 | extern void rs600_pm_finish(struct radeon_device *rdev); |
| 237 | extern void rs600_pre_page_flip(struct radeon_device *rdev, int crtc); | ||
| 238 | extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | ||
| 239 | extern void rs600_post_page_flip(struct radeon_device *rdev, int crtc); | ||
| 240 | void rs600_set_safe_registers(struct radeon_device *rdev); | ||
| 241 | |||
| 208 | 242 | ||
| 209 | /* | 243 | /* |
| 210 | * rs690,rs740 | 244 | * rs690,rs740 |
| @@ -216,10 +250,21 @@ int rs690_suspend(struct radeon_device *rdev); | |||
| 216 | uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 250 | uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 217 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 251 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 218 | void rs690_bandwidth_update(struct radeon_device *rdev); | 252 | void rs690_bandwidth_update(struct radeon_device *rdev); |
| 253 | void rs690_line_buffer_adjust(struct radeon_device *rdev, | ||
| 254 | struct drm_display_mode *mode1, | ||
| 255 | struct drm_display_mode *mode2); | ||
| 219 | 256 | ||
| 220 | /* | 257 | /* |
| 221 | * rv515 | 258 | * rv515 |
| 222 | */ | 259 | */ |
| 260 | struct rv515_mc_save { | ||
| 261 | u32 d1vga_control; | ||
| 262 | u32 d2vga_control; | ||
| 263 | u32 vga_render_control; | ||
| 264 | u32 vga_hdp_control; | ||
| 265 | u32 d1crtc_control; | ||
| 266 | u32 d2crtc_control; | ||
| 267 | }; | ||
| 223 | int rv515_init(struct radeon_device *rdev); | 268 | int rv515_init(struct radeon_device *rdev); |
| 224 | void rv515_fini(struct radeon_device *rdev); | 269 | void rv515_fini(struct radeon_device *rdev); |
| 225 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 270 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| @@ -230,6 +275,14 @@ void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | |||
| 230 | void rv515_bandwidth_update(struct radeon_device *rdev); | 275 | void rv515_bandwidth_update(struct radeon_device *rdev); |
| 231 | int rv515_resume(struct radeon_device *rdev); | 276 | int rv515_resume(struct radeon_device *rdev); |
| 232 | int rv515_suspend(struct radeon_device *rdev); | 277 | int rv515_suspend(struct radeon_device *rdev); |
| 278 | void rv515_bandwidth_avivo_update(struct radeon_device *rdev); | ||
| 279 | void rv515_vga_render_disable(struct radeon_device *rdev); | ||
| 280 | void rv515_set_safe_registers(struct radeon_device *rdev); | ||
| 281 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save); | ||
| 282 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save); | ||
| 283 | void rv515_clock_startup(struct radeon_device *rdev); | ||
| 284 | void rv515_debugfs(struct radeon_device *rdev); | ||
| 285 | |||
| 233 | 286 | ||
| 234 | /* | 287 | /* |
| 235 | * r520,rv530,rv560,rv570,r580 | 288 | * r520,rv530,rv560,rv570,r580 |
| @@ -278,6 +331,8 @@ extern void r600_pm_misc(struct radeon_device *rdev); | |||
| 278 | extern void r600_pm_init_profile(struct radeon_device *rdev); | 331 | extern void r600_pm_init_profile(struct radeon_device *rdev); |
| 279 | extern void rs780_pm_init_profile(struct radeon_device *rdev); | 332 | extern void rs780_pm_init_profile(struct radeon_device *rdev); |
| 280 | extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); | 333 | extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); |
| 334 | extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes); | ||
| 335 | extern int r600_get_pcie_lanes(struct radeon_device *rdev); | ||
| 281 | 336 | ||
| 282 | /* | 337 | /* |
| 283 | * rv770,rv730,rv710,rv740 | 338 | * rv770,rv730,rv710,rv740 |
| @@ -287,6 +342,7 @@ void rv770_fini(struct radeon_device *rdev); | |||
| 287 | int rv770_suspend(struct radeon_device *rdev); | 342 | int rv770_suspend(struct radeon_device *rdev); |
| 288 | int rv770_resume(struct radeon_device *rdev); | 343 | int rv770_resume(struct radeon_device *rdev); |
| 289 | extern void rv770_pm_misc(struct radeon_device *rdev); | 344 | extern void rv770_pm_misc(struct radeon_device *rdev); |
| 345 | extern u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | ||
| 290 | 346 | ||
| 291 | /* | 347 | /* |
| 292 | * evergreen | 348 | * evergreen |
| @@ -314,5 +370,8 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p); | |||
| 314 | extern void evergreen_pm_misc(struct radeon_device *rdev); | 370 | extern void evergreen_pm_misc(struct radeon_device *rdev); |
| 315 | extern void evergreen_pm_prepare(struct radeon_device *rdev); | 371 | extern void evergreen_pm_prepare(struct radeon_device *rdev); |
| 316 | extern void evergreen_pm_finish(struct radeon_device *rdev); | 372 | extern void evergreen_pm_finish(struct radeon_device *rdev); |
| 373 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); | ||
| 374 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | ||
| 375 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); | ||
| 317 | 376 | ||
| 318 | #endif | 377 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index bc5a2c3382d9..1573202a6418 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -37,7 +37,7 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, | |||
| 37 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 37 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
| 38 | extern void | 38 | extern void |
| 39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, | 39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, |
| 40 | uint32_t supported_device); | 40 | uint32_t supported_device, u16 caps); |
| 41 | 41 | ||
| 42 | /* from radeon_connector.c */ | 42 | /* from radeon_connector.c */ |
| 43 | extern void | 43 | extern void |
| @@ -313,7 +313,6 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
| 313 | uint16_t *line_mux, | 313 | uint16_t *line_mux, |
| 314 | struct radeon_hpd *hpd) | 314 | struct radeon_hpd *hpd) |
| 315 | { | 315 | { |
| 316 | struct radeon_device *rdev = dev->dev_private; | ||
| 317 | 316 | ||
| 318 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ | 317 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ |
| 319 | if ((dev->pdev->device == 0x791e) && | 318 | if ((dev->pdev->device == 0x791e) && |
| @@ -388,6 +387,17 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
| 388 | *line_mux = 0x90; | 387 | *line_mux = 0x90; |
| 389 | } | 388 | } |
| 390 | 389 | ||
| 390 | /* mac rv630 */ | ||
| 391 | if ((dev->pdev->device == 0x9588) && | ||
| 392 | (dev->pdev->subsystem_vendor == 0x106b) && | ||
| 393 | (dev->pdev->subsystem_device == 0x00a6)) { | ||
| 394 | if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) && | ||
| 395 | (*connector_type == DRM_MODE_CONNECTOR_DVII)) { | ||
| 396 | *connector_type = DRM_MODE_CONNECTOR_9PinDIN; | ||
| 397 | *line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 391 | /* ASUS HD 3600 XT board lists the DVI port as HDMI */ | 401 | /* ASUS HD 3600 XT board lists the DVI port as HDMI */ |
| 392 | if ((dev->pdev->device == 0x9598) && | 402 | if ((dev->pdev->device == 0x9598) && |
| 393 | (dev->pdev->subsystem_vendor == 0x1043) && | 403 | (dev->pdev->subsystem_vendor == 0x1043) && |
| @@ -425,21 +435,23 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
| 425 | } | 435 | } |
| 426 | } | 436 | } |
| 427 | 437 | ||
| 428 | /* Acer laptop reports DVI-D as DVI-I and hpd pins reversed */ | 438 | /* Acer laptop (Acer TravelMate 5730G) has an HDMI port |
| 439 | * on the laptop and a DVI port on the docking station and | ||
| 440 | * both share the same encoder, hpd pin, and ddc line. | ||
| 441 | * So while the bios table is technically correct, | ||
| 442 | * we drop the DVI port here since xrandr has no concept of | ||
| 443 | * encoders and will try and drive both connectors | ||
| 444 | * with different crtcs which isn't possible on the hardware | ||
| 445 | * side and leaves no crtcs for LVDS or VGA. | ||
| 446 | */ | ||
| 429 | if ((dev->pdev->device == 0x95c4) && | 447 | if ((dev->pdev->device == 0x95c4) && |
| 430 | (dev->pdev->subsystem_vendor == 0x1025) && | 448 | (dev->pdev->subsystem_vendor == 0x1025) && |
| 431 | (dev->pdev->subsystem_device == 0x013c)) { | 449 | (dev->pdev->subsystem_device == 0x013c)) { |
| 432 | struct radeon_gpio_rec gpio; | ||
| 433 | |||
| 434 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && | 450 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && |
| 435 | (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) { | 451 | (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) { |
| 436 | gpio = radeon_lookup_gpio(rdev, 6); | 452 | /* actually it's a DVI-D port not DVI-I */ |
| 437 | *hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); | ||
| 438 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 453 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
| 439 | } else if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) && | 454 | return false; |
| 440 | (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) { | ||
| 441 | gpio = radeon_lookup_gpio(rdev, 7); | ||
| 442 | *hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); | ||
| 443 | } | 455 | } |
| 444 | } | 456 | } |
| 445 | 457 | ||
| @@ -525,6 +537,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 525 | u16 size, data_offset; | 537 | u16 size, data_offset; |
| 526 | u8 frev, crev; | 538 | u8 frev, crev; |
| 527 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; | 539 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; |
| 540 | ATOM_ENCODER_OBJECT_TABLE *enc_obj; | ||
| 528 | ATOM_OBJECT_TABLE *router_obj; | 541 | ATOM_OBJECT_TABLE *router_obj; |
| 529 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; | 542 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; |
| 530 | ATOM_OBJECT_HEADER *obj_header; | 543 | ATOM_OBJECT_HEADER *obj_header; |
| @@ -549,6 +562,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 549 | con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) | 562 | con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) |
| 550 | (ctx->bios + data_offset + | 563 | (ctx->bios + data_offset + |
| 551 | le16_to_cpu(obj_header->usConnectorObjectTableOffset)); | 564 | le16_to_cpu(obj_header->usConnectorObjectTableOffset)); |
| 565 | enc_obj = (ATOM_ENCODER_OBJECT_TABLE *) | ||
| 566 | (ctx->bios + data_offset + | ||
| 567 | le16_to_cpu(obj_header->usEncoderObjectTableOffset)); | ||
| 552 | router_obj = (ATOM_OBJECT_TABLE *) | 568 | router_obj = (ATOM_OBJECT_TABLE *) |
| 553 | (ctx->bios + data_offset + | 569 | (ctx->bios + data_offset + |
| 554 | le16_to_cpu(obj_header->usRouterObjectTableOffset)); | 570 | le16_to_cpu(obj_header->usRouterObjectTableOffset)); |
| @@ -654,14 +670,35 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 654 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 670 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
| 655 | 671 | ||
| 656 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { | 672 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { |
| 657 | u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]); | 673 | for (k = 0; k < enc_obj->ucNumberOfObjects; k++) { |
| 658 | 674 | u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID); | |
| 659 | radeon_add_atom_encoder(dev, | 675 | if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) { |
| 660 | encoder_obj, | 676 | ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) |
| 661 | le16_to_cpu | 677 | (ctx->bios + data_offset + |
| 662 | (path-> | 678 | le16_to_cpu(enc_obj->asObjects[k].usRecordOffset)); |
| 663 | usDeviceTag)); | 679 | ATOM_ENCODER_CAP_RECORD *cap_record; |
| 680 | u16 caps = 0; | ||
| 664 | 681 | ||
| 682 | while (record->ucRecordType > 0 && | ||
| 683 | record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { | ||
| 684 | switch (record->ucRecordType) { | ||
| 685 | case ATOM_ENCODER_CAP_RECORD_TYPE: | ||
| 686 | cap_record =(ATOM_ENCODER_CAP_RECORD *) | ||
| 687 | record; | ||
| 688 | caps = le16_to_cpu(cap_record->usEncoderCap); | ||
| 689 | break; | ||
| 690 | } | ||
| 691 | record = (ATOM_COMMON_RECORD_HEADER *) | ||
| 692 | ((char *)record + record->ucRecordSize); | ||
| 693 | } | ||
| 694 | radeon_add_atom_encoder(dev, | ||
| 695 | encoder_obj, | ||
| 696 | le16_to_cpu | ||
| 697 | (path-> | ||
| 698 | usDeviceTag), | ||
| 699 | caps); | ||
| 700 | } | ||
| 701 | } | ||
| 665 | } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { | 702 | } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { |
| 666 | for (k = 0; k < router_obj->ucNumberOfObjects; k++) { | 703 | for (k = 0; k < router_obj->ucNumberOfObjects; k++) { |
| 667 | u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID); | 704 | u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID); |
| @@ -995,7 +1032,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 995 | radeon_get_encoder_enum(dev, | 1032 | radeon_get_encoder_enum(dev, |
| 996 | (1 << i), | 1033 | (1 << i), |
| 997 | dac), | 1034 | dac), |
| 998 | (1 << i)); | 1035 | (1 << i), |
| 1036 | 0); | ||
| 999 | else | 1037 | else |
| 1000 | radeon_add_legacy_encoder(dev, | 1038 | radeon_add_legacy_encoder(dev, |
| 1001 | radeon_get_encoder_enum(dev, | 1039 | radeon_get_encoder_enum(dev, |
| @@ -1074,6 +1112,7 @@ union firmware_info { | |||
| 1074 | ATOM_FIRMWARE_INFO_V1_3 info_13; | 1112 | ATOM_FIRMWARE_INFO_V1_3 info_13; |
| 1075 | ATOM_FIRMWARE_INFO_V1_4 info_14; | 1113 | ATOM_FIRMWARE_INFO_V1_4 info_14; |
| 1076 | ATOM_FIRMWARE_INFO_V2_1 info_21; | 1114 | ATOM_FIRMWARE_INFO_V2_1 info_21; |
| 1115 | ATOM_FIRMWARE_INFO_V2_2 info_22; | ||
| 1077 | }; | 1116 | }; |
| 1078 | 1117 | ||
| 1079 | bool radeon_atom_get_clock_info(struct drm_device *dev) | 1118 | bool radeon_atom_get_clock_info(struct drm_device *dev) |
| @@ -1148,8 +1187,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
| 1148 | *p2pll = *p1pll; | 1187 | *p2pll = *p1pll; |
| 1149 | 1188 | ||
| 1150 | /* system clock */ | 1189 | /* system clock */ |
| 1151 | spll->reference_freq = | 1190 | if (ASIC_IS_DCE4(rdev)) |
| 1152 | le16_to_cpu(firmware_info->info.usReferenceClock); | 1191 | spll->reference_freq = |
| 1192 | le16_to_cpu(firmware_info->info_21.usCoreReferenceClock); | ||
| 1193 | else | ||
| 1194 | spll->reference_freq = | ||
| 1195 | le16_to_cpu(firmware_info->info.usReferenceClock); | ||
| 1153 | spll->reference_div = 0; | 1196 | spll->reference_div = 0; |
| 1154 | 1197 | ||
| 1155 | spll->pll_out_min = | 1198 | spll->pll_out_min = |
| @@ -1171,8 +1214,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
| 1171 | le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input); | 1214 | le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input); |
| 1172 | 1215 | ||
| 1173 | /* memory clock */ | 1216 | /* memory clock */ |
| 1174 | mpll->reference_freq = | 1217 | if (ASIC_IS_DCE4(rdev)) |
| 1175 | le16_to_cpu(firmware_info->info.usReferenceClock); | 1218 | mpll->reference_freq = |
| 1219 | le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock); | ||
| 1220 | else | ||
| 1221 | mpll->reference_freq = | ||
| 1222 | le16_to_cpu(firmware_info->info.usReferenceClock); | ||
| 1176 | mpll->reference_div = 0; | 1223 | mpll->reference_div = 0; |
| 1177 | 1224 | ||
| 1178 | mpll->pll_out_min = | 1225 | mpll->pll_out_min = |
| @@ -1201,8 +1248,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
| 1201 | if (ASIC_IS_DCE4(rdev)) { | 1248 | if (ASIC_IS_DCE4(rdev)) { |
| 1202 | rdev->clock.default_dispclk = | 1249 | rdev->clock.default_dispclk = |
| 1203 | le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); | 1250 | le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); |
| 1204 | if (rdev->clock.default_dispclk == 0) | 1251 | if (rdev->clock.default_dispclk == 0) { |
| 1205 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ | 1252 | if (ASIC_IS_DCE5(rdev)) |
| 1253 | rdev->clock.default_dispclk = 54000; /* 540 Mhz */ | ||
| 1254 | else | ||
| 1255 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ | ||
| 1256 | } | ||
| 1206 | rdev->clock.dp_extclk = | 1257 | rdev->clock.dp_extclk = |
| 1207 | le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); | 1258 | le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); |
| 1208 | } | 1259 | } |
| @@ -1337,6 +1388,43 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, | |||
| 1337 | return false; | 1388 | return false; |
| 1338 | } | 1389 | } |
| 1339 | 1390 | ||
| 1391 | static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, | ||
| 1392 | struct radeon_atom_ss *ss, | ||
| 1393 | int id) | ||
| 1394 | { | ||
| 1395 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
| 1396 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | ||
| 1397 | u16 data_offset, size; | ||
| 1398 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; | ||
| 1399 | u8 frev, crev; | ||
| 1400 | u16 percentage = 0, rate = 0; | ||
| 1401 | |||
| 1402 | /* get any igp specific overrides */ | ||
| 1403 | if (atom_parse_data_header(mode_info->atom_context, index, &size, | ||
| 1404 | &frev, &crev, &data_offset)) { | ||
| 1405 | igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) | ||
| 1406 | (mode_info->atom_context->bios + data_offset); | ||
| 1407 | switch (id) { | ||
| 1408 | case ASIC_INTERNAL_SS_ON_TMDS: | ||
| 1409 | percentage = le16_to_cpu(igp_info->usDVISSPercentage); | ||
| 1410 | rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); | ||
| 1411 | break; | ||
| 1412 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
| 1413 | percentage = le16_to_cpu(igp_info->usHDMISSPercentage); | ||
| 1414 | rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); | ||
| 1415 | break; | ||
| 1416 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
| 1417 | percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); | ||
| 1418 | rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); | ||
| 1419 | break; | ||
| 1420 | } | ||
| 1421 | if (percentage) | ||
| 1422 | ss->percentage = percentage; | ||
| 1423 | if (rate) | ||
| 1424 | ss->rate = rate; | ||
| 1425 | } | ||
| 1426 | } | ||
| 1427 | |||
| 1340 | union asic_ss_info { | 1428 | union asic_ss_info { |
| 1341 | struct _ATOM_ASIC_INTERNAL_SS_INFO info; | 1429 | struct _ATOM_ASIC_INTERNAL_SS_INFO info; |
| 1342 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; | 1430 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; |
| @@ -1401,6 +1489,8 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
| 1401 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1489 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
| 1402 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1490 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
| 1403 | ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); | 1491 | ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); |
| 1492 | if (rdev->flags & RADEON_IS_IGP) | ||
| 1493 | radeon_atombios_get_igp_ss_overrides(rdev, ss, id); | ||
| 1404 | return true; | 1494 | return true; |
| 1405 | } | 1495 | } |
| 1406 | } | 1496 | } |
| @@ -1477,6 +1567,9 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
| 1477 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | 1567 | if (misc & ATOM_DOUBLE_CLOCK_MODE) |
| 1478 | lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; | 1568 | lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; |
| 1479 | 1569 | ||
| 1570 | lvds->native_mode.width_mm = lvds_info->info.sLCDTiming.usImageHSize; | ||
| 1571 | lvds->native_mode.height_mm = lvds_info->info.sLCDTiming.usImageVSize; | ||
| 1572 | |||
| 1480 | /* set crtc values */ | 1573 | /* set crtc values */ |
| 1481 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); | 1574 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); |
| 1482 | 1575 | ||
| @@ -1489,6 +1582,59 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
| 1489 | else | 1582 | else |
| 1490 | lvds->linkb = false; | 1583 | lvds->linkb = false; |
| 1491 | 1584 | ||
| 1585 | /* parse the lcd record table */ | ||
| 1586 | if (lvds_info->info.usModePatchTableOffset) { | ||
| 1587 | ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; | ||
| 1588 | ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; | ||
| 1589 | bool bad_record = false; | ||
| 1590 | u8 *record = (u8 *)(mode_info->atom_context->bios + | ||
| 1591 | data_offset + | ||
| 1592 | lvds_info->info.usModePatchTableOffset); | ||
| 1593 | while (*record != ATOM_RECORD_END_TYPE) { | ||
| 1594 | switch (*record) { | ||
| 1595 | case LCD_MODE_PATCH_RECORD_MODE_TYPE: | ||
| 1596 | record += sizeof(ATOM_PATCH_RECORD_MODE); | ||
| 1597 | break; | ||
| 1598 | case LCD_RTS_RECORD_TYPE: | ||
| 1599 | record += sizeof(ATOM_LCD_RTS_RECORD); | ||
| 1600 | break; | ||
| 1601 | case LCD_CAP_RECORD_TYPE: | ||
| 1602 | record += sizeof(ATOM_LCD_MODE_CONTROL_CAP); | ||
| 1603 | break; | ||
| 1604 | case LCD_FAKE_EDID_PATCH_RECORD_TYPE: | ||
| 1605 | fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; | ||
| 1606 | if (fake_edid_record->ucFakeEDIDLength) { | ||
| 1607 | struct edid *edid; | ||
| 1608 | int edid_size = | ||
| 1609 | max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength); | ||
| 1610 | edid = kmalloc(edid_size, GFP_KERNEL); | ||
| 1611 | if (edid) { | ||
| 1612 | memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], | ||
| 1613 | fake_edid_record->ucFakeEDIDLength); | ||
| 1614 | |||
| 1615 | if (drm_edid_is_valid(edid)) | ||
| 1616 | rdev->mode_info.bios_hardcoded_edid = edid; | ||
| 1617 | else | ||
| 1618 | kfree(edid); | ||
| 1619 | } | ||
| 1620 | } | ||
| 1621 | record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); | ||
| 1622 | break; | ||
| 1623 | case LCD_PANEL_RESOLUTION_RECORD_TYPE: | ||
| 1624 | panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; | ||
| 1625 | lvds->native_mode.width_mm = panel_res_record->usHSize; | ||
| 1626 | lvds->native_mode.height_mm = panel_res_record->usVSize; | ||
| 1627 | record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD); | ||
| 1628 | break; | ||
| 1629 | default: | ||
| 1630 | DRM_ERROR("Bad LCD record %d\n", *record); | ||
| 1631 | bad_record = true; | ||
| 1632 | break; | ||
| 1633 | } | ||
| 1634 | if (bad_record) | ||
| 1635 | break; | ||
| 1636 | } | ||
| 1637 | } | ||
| 1492 | } | 1638 | } |
| 1493 | return lvds; | 1639 | return lvds; |
| 1494 | } | 1640 | } |
| @@ -1740,496 +1886,614 @@ static const char *pp_lib_thermal_controller_names[] = { | |||
| 1740 | "RV6xx", | 1886 | "RV6xx", |
| 1741 | "RV770", | 1887 | "RV770", |
| 1742 | "adt7473", | 1888 | "adt7473", |
| 1889 | "NONE", | ||
| 1743 | "External GPIO", | 1890 | "External GPIO", |
| 1744 | "Evergreen", | 1891 | "Evergreen", |
| 1745 | "adt7473 with internal", | 1892 | "emc2103", |
| 1746 | 1893 | "Sumo", | |
| 1894 | "Northern Islands", | ||
| 1747 | }; | 1895 | }; |
| 1748 | 1896 | ||
| 1749 | union power_info { | 1897 | union power_info { |
| 1750 | struct _ATOM_POWERPLAY_INFO info; | 1898 | struct _ATOM_POWERPLAY_INFO info; |
| 1751 | struct _ATOM_POWERPLAY_INFO_V2 info_2; | 1899 | struct _ATOM_POWERPLAY_INFO_V2 info_2; |
| 1752 | struct _ATOM_POWERPLAY_INFO_V3 info_3; | 1900 | struct _ATOM_POWERPLAY_INFO_V3 info_3; |
| 1753 | struct _ATOM_PPLIB_POWERPLAYTABLE info_4; | 1901 | struct _ATOM_PPLIB_POWERPLAYTABLE pplib; |
| 1902 | struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2; | ||
| 1903 | struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3; | ||
| 1754 | }; | 1904 | }; |
| 1755 | 1905 | ||
| 1756 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | 1906 | union pplib_clock_info { |
| 1907 | struct _ATOM_PPLIB_R600_CLOCK_INFO r600; | ||
| 1908 | struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; | ||
| 1909 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; | ||
| 1910 | struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo; | ||
| 1911 | }; | ||
| 1912 | |||
| 1913 | union pplib_power_state { | ||
| 1914 | struct _ATOM_PPLIB_STATE v1; | ||
| 1915 | struct _ATOM_PPLIB_STATE_V2 v2; | ||
| 1916 | }; | ||
| 1917 | |||
| 1918 | static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev, | ||
| 1919 | int state_index, | ||
| 1920 | u32 misc, u32 misc2) | ||
| 1921 | { | ||
| 1922 | rdev->pm.power_state[state_index].misc = misc; | ||
| 1923 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
| 1924 | /* order matters! */ | ||
| 1925 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
| 1926 | rdev->pm.power_state[state_index].type = | ||
| 1927 | POWER_STATE_TYPE_POWERSAVE; | ||
| 1928 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
| 1929 | rdev->pm.power_state[state_index].type = | ||
| 1930 | POWER_STATE_TYPE_BATTERY; | ||
| 1931 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
| 1932 | rdev->pm.power_state[state_index].type = | ||
| 1933 | POWER_STATE_TYPE_BATTERY; | ||
| 1934 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
| 1935 | rdev->pm.power_state[state_index].type = | ||
| 1936 | POWER_STATE_TYPE_BALANCED; | ||
| 1937 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
| 1938 | rdev->pm.power_state[state_index].type = | ||
| 1939 | POWER_STATE_TYPE_PERFORMANCE; | ||
| 1940 | rdev->pm.power_state[state_index].flags &= | ||
| 1941 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1942 | } | ||
| 1943 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
| 1944 | rdev->pm.power_state[state_index].type = | ||
| 1945 | POWER_STATE_TYPE_BALANCED; | ||
| 1946 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
| 1947 | rdev->pm.power_state[state_index].type = | ||
| 1948 | POWER_STATE_TYPE_DEFAULT; | ||
| 1949 | rdev->pm.default_power_state_index = state_index; | ||
| 1950 | rdev->pm.power_state[state_index].default_clock_mode = | ||
| 1951 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
| 1952 | } else if (state_index == 0) { | ||
| 1953 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
| 1954 | RADEON_PM_MODE_NO_DISPLAY; | ||
| 1955 | } | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | ||
| 1757 | { | 1959 | { |
| 1758 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1960 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
| 1961 | u32 misc, misc2 = 0; | ||
| 1962 | int num_modes = 0, i; | ||
| 1963 | int state_index = 0; | ||
| 1964 | struct radeon_i2c_bus_rec i2c_bus; | ||
| 1965 | union power_info *power_info; | ||
| 1759 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | 1966 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); |
| 1760 | u16 data_offset; | 1967 | u16 data_offset; |
| 1761 | u8 frev, crev; | 1968 | u8 frev, crev; |
| 1762 | u32 misc, misc2 = 0, sclk, mclk; | ||
| 1763 | union power_info *power_info; | ||
| 1764 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
| 1765 | struct _ATOM_PPLIB_STATE *power_state; | ||
| 1766 | int num_modes = 0, i, j; | ||
| 1767 | int state_index = 0, mode_index = 0; | ||
| 1768 | struct radeon_i2c_bus_rec i2c_bus; | ||
| 1769 | |||
| 1770 | rdev->pm.default_power_state_index = -1; | ||
| 1771 | 1969 | ||
| 1772 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1970 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, |
| 1773 | &frev, &crev, &data_offset)) { | 1971 | &frev, &crev, &data_offset)) |
| 1774 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | 1972 | return state_index; |
| 1775 | if (frev < 4) { | 1973 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
| 1776 | /* add the i2c bus for thermal/fan chip */ | 1974 | |
| 1777 | if (power_info->info.ucOverdriveThermalController > 0) { | 1975 | /* add the i2c bus for thermal/fan chip */ |
| 1778 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", | 1976 | if (power_info->info.ucOverdriveThermalController > 0) { |
| 1779 | thermal_controller_names[power_info->info.ucOverdriveThermalController], | 1977 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", |
| 1780 | power_info->info.ucOverdriveControllerAddress >> 1); | 1978 | thermal_controller_names[power_info->info.ucOverdriveThermalController], |
| 1781 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); | 1979 | power_info->info.ucOverdriveControllerAddress >> 1); |
| 1782 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | 1980 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); |
| 1783 | if (rdev->pm.i2c_bus) { | 1981 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); |
| 1784 | struct i2c_board_info info = { }; | 1982 | if (rdev->pm.i2c_bus) { |
| 1785 | const char *name = thermal_controller_names[power_info->info. | 1983 | struct i2c_board_info info = { }; |
| 1786 | ucOverdriveThermalController]; | 1984 | const char *name = thermal_controller_names[power_info->info. |
| 1787 | info.addr = power_info->info.ucOverdriveControllerAddress >> 1; | 1985 | ucOverdriveThermalController]; |
| 1788 | strlcpy(info.type, name, sizeof(info.type)); | 1986 | info.addr = power_info->info.ucOverdriveControllerAddress >> 1; |
| 1789 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | 1987 | strlcpy(info.type, name, sizeof(info.type)); |
| 1790 | } | 1988 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); |
| 1989 | } | ||
| 1990 | } | ||
| 1991 | num_modes = power_info->info.ucNumOfPowerModeEntries; | ||
| 1992 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | ||
| 1993 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | ||
| 1994 | /* last mode is usually default, array is low to high */ | ||
| 1995 | for (i = 0; i < num_modes; i++) { | ||
| 1996 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | ||
| 1997 | switch (frev) { | ||
| 1998 | case 1: | ||
| 1999 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
| 2000 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
| 2001 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | ||
| 2002 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
| 2003 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | ||
| 2004 | /* skip invalid modes */ | ||
| 2005 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
| 2006 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
| 2007 | continue; | ||
| 2008 | rdev->pm.power_state[state_index].pcie_lanes = | ||
| 2009 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | ||
| 2010 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | ||
| 2011 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
| 2012 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
| 2013 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 2014 | VOLTAGE_GPIO; | ||
| 2015 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
| 2016 | radeon_lookup_gpio(rdev, | ||
| 2017 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
| 2018 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
| 2019 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 2020 | true; | ||
| 2021 | else | ||
| 2022 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 2023 | false; | ||
| 2024 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
| 2025 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 2026 | VOLTAGE_VDDC; | ||
| 2027 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
| 2028 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
| 1791 | } | 2029 | } |
| 1792 | num_modes = power_info->info.ucNumOfPowerModeEntries; | 2030 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
| 1793 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | 2031 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0); |
| 1794 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | 2032 | state_index++; |
| 1795 | /* last mode is usually default, array is low to high */ | 2033 | break; |
| 1796 | for (i = 0; i < num_modes; i++) { | 2034 | case 2: |
| 1797 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 2035 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
| 1798 | switch (frev) { | 2036 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
| 1799 | case 1: | 2037 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); |
| 1800 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 2038 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
| 1801 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 2039 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); |
| 1802 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | 2040 | /* skip invalid modes */ |
| 1803 | rdev->pm.power_state[state_index].clock_info[0].sclk = | 2041 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || |
| 1804 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | 2042 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) |
| 1805 | /* skip invalid modes */ | 2043 | continue; |
| 1806 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | 2044 | rdev->pm.power_state[state_index].pcie_lanes = |
| 1807 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | 2045 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; |
| 1808 | continue; | 2046 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); |
| 1809 | rdev->pm.power_state[state_index].pcie_lanes = | 2047 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); |
| 1810 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | 2048 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || |
| 1811 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | 2049 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { |
| 1812 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | 2050 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
| 1813 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | 2051 | VOLTAGE_GPIO; |
| 1814 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 2052 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = |
| 1815 | VOLTAGE_GPIO; | 2053 | radeon_lookup_gpio(rdev, |
| 1816 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | 2054 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); |
| 1817 | radeon_lookup_gpio(rdev, | 2055 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) |
| 1818 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | 2056 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = |
| 1819 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | 2057 | true; |
| 1820 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | 2058 | else |
| 1821 | true; | 2059 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = |
| 1822 | else | 2060 | false; |
| 1823 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | 2061 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { |
| 1824 | false; | 2062 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
| 1825 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | 2063 | VOLTAGE_VDDC; |
| 1826 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 2064 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = |
| 1827 | VOLTAGE_VDDC; | 2065 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; |
| 1828 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
| 1829 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
| 1830 | } | ||
| 1831 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1832 | rdev->pm.power_state[state_index].misc = misc; | ||
| 1833 | /* order matters! */ | ||
| 1834 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
| 1835 | rdev->pm.power_state[state_index].type = | ||
| 1836 | POWER_STATE_TYPE_POWERSAVE; | ||
| 1837 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
| 1838 | rdev->pm.power_state[state_index].type = | ||
| 1839 | POWER_STATE_TYPE_BATTERY; | ||
| 1840 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
| 1841 | rdev->pm.power_state[state_index].type = | ||
| 1842 | POWER_STATE_TYPE_BATTERY; | ||
| 1843 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
| 1844 | rdev->pm.power_state[state_index].type = | ||
| 1845 | POWER_STATE_TYPE_BALANCED; | ||
| 1846 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
| 1847 | rdev->pm.power_state[state_index].type = | ||
| 1848 | POWER_STATE_TYPE_PERFORMANCE; | ||
| 1849 | rdev->pm.power_state[state_index].flags &= | ||
| 1850 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1851 | } | ||
| 1852 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
| 1853 | rdev->pm.power_state[state_index].type = | ||
| 1854 | POWER_STATE_TYPE_DEFAULT; | ||
| 1855 | rdev->pm.default_power_state_index = state_index; | ||
| 1856 | rdev->pm.power_state[state_index].default_clock_mode = | ||
| 1857 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
| 1858 | rdev->pm.power_state[state_index].flags &= | ||
| 1859 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1860 | } else if (state_index == 0) { | ||
| 1861 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
| 1862 | RADEON_PM_MODE_NO_DISPLAY; | ||
| 1863 | } | ||
| 1864 | state_index++; | ||
| 1865 | break; | ||
| 1866 | case 2: | ||
| 1867 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
| 1868 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
| 1869 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); | ||
| 1870 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
| 1871 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); | ||
| 1872 | /* skip invalid modes */ | ||
| 1873 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
| 1874 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
| 1875 | continue; | ||
| 1876 | rdev->pm.power_state[state_index].pcie_lanes = | ||
| 1877 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; | ||
| 1878 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); | ||
| 1879 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); | ||
| 1880 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
| 1881 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
| 1882 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 1883 | VOLTAGE_GPIO; | ||
| 1884 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
| 1885 | radeon_lookup_gpio(rdev, | ||
| 1886 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
| 1887 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
| 1888 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 1889 | true; | ||
| 1890 | else | ||
| 1891 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 1892 | false; | ||
| 1893 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
| 1894 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 1895 | VOLTAGE_VDDC; | ||
| 1896 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
| 1897 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
| 1898 | } | ||
| 1899 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1900 | rdev->pm.power_state[state_index].misc = misc; | ||
| 1901 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
| 1902 | /* order matters! */ | ||
| 1903 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
| 1904 | rdev->pm.power_state[state_index].type = | ||
| 1905 | POWER_STATE_TYPE_POWERSAVE; | ||
| 1906 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
| 1907 | rdev->pm.power_state[state_index].type = | ||
| 1908 | POWER_STATE_TYPE_BATTERY; | ||
| 1909 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
| 1910 | rdev->pm.power_state[state_index].type = | ||
| 1911 | POWER_STATE_TYPE_BATTERY; | ||
| 1912 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
| 1913 | rdev->pm.power_state[state_index].type = | ||
| 1914 | POWER_STATE_TYPE_BALANCED; | ||
| 1915 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
| 1916 | rdev->pm.power_state[state_index].type = | ||
| 1917 | POWER_STATE_TYPE_PERFORMANCE; | ||
| 1918 | rdev->pm.power_state[state_index].flags &= | ||
| 1919 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1920 | } | ||
| 1921 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
| 1922 | rdev->pm.power_state[state_index].type = | ||
| 1923 | POWER_STATE_TYPE_BALANCED; | ||
| 1924 | if (misc2 & ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT) | ||
| 1925 | rdev->pm.power_state[state_index].flags &= | ||
| 1926 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1927 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
| 1928 | rdev->pm.power_state[state_index].type = | ||
| 1929 | POWER_STATE_TYPE_DEFAULT; | ||
| 1930 | rdev->pm.default_power_state_index = state_index; | ||
| 1931 | rdev->pm.power_state[state_index].default_clock_mode = | ||
| 1932 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
| 1933 | rdev->pm.power_state[state_index].flags &= | ||
| 1934 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1935 | } else if (state_index == 0) { | ||
| 1936 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
| 1937 | RADEON_PM_MODE_NO_DISPLAY; | ||
| 1938 | } | ||
| 1939 | state_index++; | ||
| 1940 | break; | ||
| 1941 | case 3: | ||
| 1942 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
| 1943 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
| 1944 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); | ||
| 1945 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
| 1946 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); | ||
| 1947 | /* skip invalid modes */ | ||
| 1948 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
| 1949 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
| 1950 | continue; | ||
| 1951 | rdev->pm.power_state[state_index].pcie_lanes = | ||
| 1952 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
| 1953 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
| 1954 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
| 1955 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
| 1956 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
| 1957 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 1958 | VOLTAGE_GPIO; | ||
| 1959 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
| 1960 | radeon_lookup_gpio(rdev, | ||
| 1961 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
| 1962 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
| 1963 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 1964 | true; | ||
| 1965 | else | ||
| 1966 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 1967 | false; | ||
| 1968 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
| 1969 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 1970 | VOLTAGE_VDDC; | ||
| 1971 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
| 1972 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
| 1973 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
| 1974 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
| 1975 | true; | ||
| 1976 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
| 1977 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
| 1978 | } | ||
| 1979 | } | ||
| 1980 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 1981 | rdev->pm.power_state[state_index].misc = misc; | ||
| 1982 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
| 1983 | /* order matters! */ | ||
| 1984 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
| 1985 | rdev->pm.power_state[state_index].type = | ||
| 1986 | POWER_STATE_TYPE_POWERSAVE; | ||
| 1987 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
| 1988 | rdev->pm.power_state[state_index].type = | ||
| 1989 | POWER_STATE_TYPE_BATTERY; | ||
| 1990 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
| 1991 | rdev->pm.power_state[state_index].type = | ||
| 1992 | POWER_STATE_TYPE_BATTERY; | ||
| 1993 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
| 1994 | rdev->pm.power_state[state_index].type = | ||
| 1995 | POWER_STATE_TYPE_BALANCED; | ||
| 1996 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
| 1997 | rdev->pm.power_state[state_index].type = | ||
| 1998 | POWER_STATE_TYPE_PERFORMANCE; | ||
| 1999 | rdev->pm.power_state[state_index].flags &= | ||
| 2000 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 2001 | } | ||
| 2002 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
| 2003 | rdev->pm.power_state[state_index].type = | ||
| 2004 | POWER_STATE_TYPE_BALANCED; | ||
| 2005 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
| 2006 | rdev->pm.power_state[state_index].type = | ||
| 2007 | POWER_STATE_TYPE_DEFAULT; | ||
| 2008 | rdev->pm.default_power_state_index = state_index; | ||
| 2009 | rdev->pm.power_state[state_index].default_clock_mode = | ||
| 2010 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
| 2011 | } else if (state_index == 0) { | ||
| 2012 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
| 2013 | RADEON_PM_MODE_NO_DISPLAY; | ||
| 2014 | } | ||
| 2015 | state_index++; | ||
| 2016 | break; | ||
| 2017 | } | ||
| 2018 | } | 2066 | } |
| 2019 | /* last mode is usually default */ | 2067 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
| 2020 | if (rdev->pm.default_power_state_index == -1) { | 2068 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); |
| 2021 | rdev->pm.power_state[state_index - 1].type = | 2069 | state_index++; |
| 2022 | POWER_STATE_TYPE_DEFAULT; | 2070 | break; |
| 2023 | rdev->pm.default_power_state_index = state_index - 1; | 2071 | case 3: |
| 2024 | rdev->pm.power_state[state_index - 1].default_clock_mode = | 2072 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
| 2025 | &rdev->pm.power_state[state_index - 1].clock_info[0]; | 2073 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
| 2026 | rdev->pm.power_state[state_index].flags &= | 2074 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); |
| 2027 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | 2075 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
| 2028 | rdev->pm.power_state[state_index].misc = 0; | 2076 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); |
| 2029 | rdev->pm.power_state[state_index].misc2 = 0; | 2077 | /* skip invalid modes */ |
| 2078 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
| 2079 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
| 2080 | continue; | ||
| 2081 | rdev->pm.power_state[state_index].pcie_lanes = | ||
| 2082 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
| 2083 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
| 2084 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
| 2085 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
| 2086 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
| 2087 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 2088 | VOLTAGE_GPIO; | ||
| 2089 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
| 2090 | radeon_lookup_gpio(rdev, | ||
| 2091 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
| 2092 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
| 2093 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 2094 | true; | ||
| 2095 | else | ||
| 2096 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
| 2097 | false; | ||
| 2098 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
| 2099 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
| 2100 | VOLTAGE_VDDC; | ||
| 2101 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
| 2102 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
| 2103 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
| 2104 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
| 2105 | true; | ||
| 2106 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
| 2107 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
| 2108 | } | ||
| 2030 | } | 2109 | } |
| 2110 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 2111 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); | ||
| 2112 | state_index++; | ||
| 2113 | break; | ||
| 2114 | } | ||
| 2115 | } | ||
| 2116 | /* last mode is usually default */ | ||
| 2117 | if (rdev->pm.default_power_state_index == -1) { | ||
| 2118 | rdev->pm.power_state[state_index - 1].type = | ||
| 2119 | POWER_STATE_TYPE_DEFAULT; | ||
| 2120 | rdev->pm.default_power_state_index = state_index - 1; | ||
| 2121 | rdev->pm.power_state[state_index - 1].default_clock_mode = | ||
| 2122 | &rdev->pm.power_state[state_index - 1].clock_info[0]; | ||
| 2123 | rdev->pm.power_state[state_index].flags &= | ||
| 2124 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 2125 | rdev->pm.power_state[state_index].misc = 0; | ||
| 2126 | rdev->pm.power_state[state_index].misc2 = 0; | ||
| 2127 | } | ||
| 2128 | return state_index; | ||
| 2129 | } | ||
| 2130 | |||
| 2131 | static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev, | ||
| 2132 | ATOM_PPLIB_THERMALCONTROLLER *controller) | ||
| 2133 | { | ||
| 2134 | struct radeon_i2c_bus_rec i2c_bus; | ||
| 2135 | |||
| 2136 | /* add the i2c bus for thermal/fan chip */ | ||
| 2137 | if (controller->ucType > 0) { | ||
| 2138 | if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { | ||
| 2139 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
| 2140 | (controller->ucFanParameters & | ||
| 2141 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2142 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; | ||
| 2143 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { | ||
| 2144 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
| 2145 | (controller->ucFanParameters & | ||
| 2146 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2147 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; | ||
| 2148 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { | ||
| 2149 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
| 2150 | (controller->ucFanParameters & | ||
| 2151 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2152 | rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; | ||
| 2153 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) { | ||
| 2154 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
| 2155 | (controller->ucFanParameters & | ||
| 2156 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2157 | rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO; | ||
| 2158 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) { | ||
| 2159 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
| 2160 | (controller->ucFanParameters & | ||
| 2161 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2162 | rdev->pm.int_thermal_type = THERMAL_TYPE_NI; | ||
| 2163 | } else if ((controller->ucType == | ||
| 2164 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | ||
| 2165 | (controller->ucType == | ||
| 2166 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) || | ||
| 2167 | (controller->ucType == | ||
| 2168 | ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) { | ||
| 2169 | DRM_INFO("Special thermal controller config\n"); | ||
| 2031 | } else { | 2170 | } else { |
| 2032 | int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); | 2171 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", |
| 2033 | uint8_t fw_frev, fw_crev; | 2172 | pp_lib_thermal_controller_names[controller->ucType], |
| 2034 | uint16_t fw_data_offset, vddc = 0; | 2173 | controller->ucI2cAddress >> 1, |
| 2035 | union firmware_info *firmware_info; | 2174 | (controller->ucFanParameters & |
| 2036 | ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; | 2175 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
| 2037 | 2176 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); | |
| 2038 | if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, | 2177 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); |
| 2039 | &fw_frev, &fw_crev, &fw_data_offset)) { | 2178 | if (rdev->pm.i2c_bus) { |
| 2040 | firmware_info = | 2179 | struct i2c_board_info info = { }; |
| 2041 | (union firmware_info *)(mode_info->atom_context->bios + | 2180 | const char *name = pp_lib_thermal_controller_names[controller->ucType]; |
| 2042 | fw_data_offset); | 2181 | info.addr = controller->ucI2cAddress >> 1; |
| 2043 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; | 2182 | strlcpy(info.type, name, sizeof(info.type)); |
| 2183 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | ||
| 2044 | } | 2184 | } |
| 2185 | } | ||
| 2186 | } | ||
| 2187 | } | ||
| 2045 | 2188 | ||
| 2046 | /* add the i2c bus for thermal/fan chip */ | 2189 | static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) |
| 2047 | if (controller->ucType > 0) { | 2190 | { |
| 2048 | if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { | 2191 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
| 2049 | DRM_INFO("Internal thermal controller %s fan control\n", | 2192 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); |
| 2050 | (controller->ucFanParameters & | 2193 | u8 frev, crev; |
| 2051 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | 2194 | u16 data_offset; |
| 2052 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; | 2195 | union firmware_info *firmware_info; |
| 2053 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { | 2196 | u16 vddc = 0; |
| 2054 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
| 2055 | (controller->ucFanParameters & | ||
| 2056 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2057 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; | ||
| 2058 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { | ||
| 2059 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
| 2060 | (controller->ucFanParameters & | ||
| 2061 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2062 | rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; | ||
| 2063 | } else if ((controller->ucType == | ||
| 2064 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | ||
| 2065 | (controller->ucType == | ||
| 2066 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { | ||
| 2067 | DRM_INFO("Special thermal controller config\n"); | ||
| 2068 | } else { | ||
| 2069 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", | ||
| 2070 | pp_lib_thermal_controller_names[controller->ucType], | ||
| 2071 | controller->ucI2cAddress >> 1, | ||
| 2072 | (controller->ucFanParameters & | ||
| 2073 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
| 2074 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); | ||
| 2075 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | ||
| 2076 | if (rdev->pm.i2c_bus) { | ||
| 2077 | struct i2c_board_info info = { }; | ||
| 2078 | const char *name = pp_lib_thermal_controller_names[controller->ucType]; | ||
| 2079 | info.addr = controller->ucI2cAddress >> 1; | ||
| 2080 | strlcpy(info.type, name, sizeof(info.type)); | ||
| 2081 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | ||
| 2082 | } | ||
| 2083 | 2197 | ||
| 2084 | } | 2198 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
| 2085 | } | 2199 | &frev, &crev, &data_offset)) { |
| 2086 | /* first mode is usually default, followed by low to high */ | 2200 | firmware_info = |
| 2087 | for (i = 0; i < power_info->info_4.ucNumStates; i++) { | 2201 | (union firmware_info *)(mode_info->atom_context->bios + |
| 2088 | mode_index = 0; | 2202 | data_offset); |
| 2089 | power_state = (struct _ATOM_PPLIB_STATE *) | 2203 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; |
| 2090 | (mode_info->atom_context->bios + | 2204 | } |
| 2091 | data_offset + | 2205 | |
| 2092 | le16_to_cpu(power_info->info_4.usStateArrayOffset) + | 2206 | return vddc; |
| 2093 | i * power_info->info_4.ucStateEntrySize); | 2207 | } |
| 2094 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | 2208 | |
| 2095 | (mode_info->atom_context->bios + | 2209 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, |
| 2096 | data_offset + | 2210 | int state_index, int mode_index, |
| 2097 | le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) + | 2211 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info) |
| 2098 | (power_state->ucNonClockStateIndex * | 2212 | { |
| 2099 | power_info->info_4.ucNonClockSize)); | 2213 | int j; |
| 2100 | for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) { | 2214 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); |
| 2101 | if (rdev->flags & RADEON_IS_IGP) { | 2215 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); |
| 2102 | struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info = | 2216 | u16 vddc = radeon_atombios_get_default_vddc(rdev); |
| 2103 | (struct _ATOM_PPLIB_RS780_CLOCK_INFO *) | 2217 | |
| 2104 | (mode_info->atom_context->bios + | 2218 | rdev->pm.power_state[state_index].misc = misc; |
| 2105 | data_offset + | 2219 | rdev->pm.power_state[state_index].misc2 = misc2; |
| 2106 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2220 | rdev->pm.power_state[state_index].pcie_lanes = |
| 2107 | (power_state->ucClockStateIndices[j] * | 2221 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> |
| 2108 | power_info->info_4.ucClockInfoSize)); | 2222 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; |
| 2109 | sclk = le16_to_cpu(clock_info->usLowEngineClockLow); | 2223 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { |
| 2110 | sclk |= clock_info->ucLowEngineClockHigh << 16; | 2224 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: |
| 2111 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2225 | rdev->pm.power_state[state_index].type = |
| 2112 | /* skip invalid modes */ | 2226 | POWER_STATE_TYPE_BATTERY; |
| 2113 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | 2227 | break; |
| 2114 | continue; | 2228 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: |
| 2115 | /* voltage works differently on IGPs */ | 2229 | rdev->pm.power_state[state_index].type = |
| 2116 | mode_index++; | 2230 | POWER_STATE_TYPE_BALANCED; |
| 2117 | } else if (ASIC_IS_DCE4(rdev)) { | 2231 | break; |
| 2118 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info = | 2232 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: |
| 2119 | (struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *) | 2233 | rdev->pm.power_state[state_index].type = |
| 2120 | (mode_info->atom_context->bios + | 2234 | POWER_STATE_TYPE_PERFORMANCE; |
| 2121 | data_offset + | 2235 | break; |
| 2122 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2236 | case ATOM_PPLIB_CLASSIFICATION_UI_NONE: |
| 2123 | (power_state->ucClockStateIndices[j] * | 2237 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) |
| 2124 | power_info->info_4.ucClockInfoSize)); | 2238 | rdev->pm.power_state[state_index].type = |
| 2125 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | 2239 | POWER_STATE_TYPE_PERFORMANCE; |
| 2126 | sclk |= clock_info->ucEngineClockHigh << 16; | 2240 | break; |
| 2127 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | 2241 | } |
| 2128 | mclk |= clock_info->ucMemoryClockHigh << 16; | 2242 | rdev->pm.power_state[state_index].flags = 0; |
| 2129 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | 2243 | if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) |
| 2130 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2244 | rdev->pm.power_state[state_index].flags |= |
| 2131 | /* skip invalid modes */ | 2245 | RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
| 2132 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | 2246 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { |
| 2133 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | 2247 | rdev->pm.power_state[state_index].type = |
| 2134 | continue; | 2248 | POWER_STATE_TYPE_DEFAULT; |
| 2135 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 2249 | rdev->pm.default_power_state_index = state_index; |
| 2136 | VOLTAGE_SW; | 2250 | rdev->pm.power_state[state_index].default_clock_mode = |
| 2137 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2251 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; |
| 2138 | clock_info->usVDDC; | 2252 | if (ASIC_IS_DCE5(rdev)) { |
| 2139 | /* XXX usVDDCI */ | 2253 | /* NI chips post without MC ucode, so default clocks are strobe mode only */ |
| 2140 | mode_index++; | 2254 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; |
| 2141 | } else { | 2255 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; |
| 2142 | struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info = | 2256 | rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; |
| 2143 | (struct _ATOM_PPLIB_R600_CLOCK_INFO *) | 2257 | } else { |
| 2144 | (mode_info->atom_context->bios + | 2258 | /* patch the table values with the default slck/mclk from firmware info */ |
| 2145 | data_offset + | 2259 | for (j = 0; j < mode_index; j++) { |
| 2146 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2260 | rdev->pm.power_state[state_index].clock_info[j].mclk = |
| 2147 | (power_state->ucClockStateIndices[j] * | 2261 | rdev->clock.default_mclk; |
| 2148 | power_info->info_4.ucClockInfoSize)); | 2262 | rdev->pm.power_state[state_index].clock_info[j].sclk = |
| 2149 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | 2263 | rdev->clock.default_sclk; |
| 2150 | sclk |= clock_info->ucEngineClockHigh << 16; | 2264 | if (vddc) |
| 2151 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | 2265 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = |
| 2152 | mclk |= clock_info->ucMemoryClockHigh << 16; | 2266 | vddc; |
| 2153 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | ||
| 2154 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
| 2155 | /* skip invalid modes */ | ||
| 2156 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | ||
| 2157 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | ||
| 2158 | continue; | ||
| 2159 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | ||
| 2160 | VOLTAGE_SW; | ||
| 2161 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
| 2162 | clock_info->usVDDC; | ||
| 2163 | mode_index++; | ||
| 2164 | } | ||
| 2165 | } | ||
| 2166 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
| 2167 | if (mode_index) { | ||
| 2168 | misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); | ||
| 2169 | misc2 = le16_to_cpu(non_clock_info->usClassification); | ||
| 2170 | rdev->pm.power_state[state_index].misc = misc; | ||
| 2171 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
| 2172 | rdev->pm.power_state[state_index].pcie_lanes = | ||
| 2173 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> | ||
| 2174 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; | ||
| 2175 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { | ||
| 2176 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: | ||
| 2177 | rdev->pm.power_state[state_index].type = | ||
| 2178 | POWER_STATE_TYPE_BATTERY; | ||
| 2179 | break; | ||
| 2180 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: | ||
| 2181 | rdev->pm.power_state[state_index].type = | ||
| 2182 | POWER_STATE_TYPE_BALANCED; | ||
| 2183 | break; | ||
| 2184 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: | ||
| 2185 | rdev->pm.power_state[state_index].type = | ||
| 2186 | POWER_STATE_TYPE_PERFORMANCE; | ||
| 2187 | break; | ||
| 2188 | case ATOM_PPLIB_CLASSIFICATION_UI_NONE: | ||
| 2189 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) | ||
| 2190 | rdev->pm.power_state[state_index].type = | ||
| 2191 | POWER_STATE_TYPE_PERFORMANCE; | ||
| 2192 | break; | ||
| 2193 | } | ||
| 2194 | rdev->pm.power_state[state_index].flags = 0; | ||
| 2195 | if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) | ||
| 2196 | rdev->pm.power_state[state_index].flags |= | ||
| 2197 | RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
| 2198 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { | ||
| 2199 | rdev->pm.power_state[state_index].type = | ||
| 2200 | POWER_STATE_TYPE_DEFAULT; | ||
| 2201 | rdev->pm.default_power_state_index = state_index; | ||
| 2202 | rdev->pm.power_state[state_index].default_clock_mode = | ||
| 2203 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | ||
| 2204 | /* patch the table values with the default slck/mclk from firmware info */ | ||
| 2205 | for (j = 0; j < mode_index; j++) { | ||
| 2206 | rdev->pm.power_state[state_index].clock_info[j].mclk = | ||
| 2207 | rdev->clock.default_mclk; | ||
| 2208 | rdev->pm.power_state[state_index].clock_info[j].sclk = | ||
| 2209 | rdev->clock.default_sclk; | ||
| 2210 | if (vddc) | ||
| 2211 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = | ||
| 2212 | vddc; | ||
| 2213 | } | ||
| 2214 | } | ||
| 2215 | state_index++; | ||
| 2216 | } | ||
| 2217 | } | ||
| 2218 | /* if multiple clock modes, mark the lowest as no display */ | ||
| 2219 | for (i = 0; i < state_index; i++) { | ||
| 2220 | if (rdev->pm.power_state[i].num_clock_modes > 1) | ||
| 2221 | rdev->pm.power_state[i].clock_info[0].flags |= | ||
| 2222 | RADEON_PM_MODE_NO_DISPLAY; | ||
| 2223 | } | ||
| 2224 | /* first mode is usually default */ | ||
| 2225 | if (rdev->pm.default_power_state_index == -1) { | ||
| 2226 | rdev->pm.power_state[0].type = | ||
| 2227 | POWER_STATE_TYPE_DEFAULT; | ||
| 2228 | rdev->pm.default_power_state_index = 0; | ||
| 2229 | rdev->pm.power_state[0].default_clock_mode = | ||
| 2230 | &rdev->pm.power_state[0].clock_info[0]; | ||
| 2231 | } | 2267 | } |
| 2232 | } | 2268 | } |
| 2269 | } | ||
| 2270 | } | ||
| 2271 | |||
| 2272 | static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, | ||
| 2273 | int state_index, int mode_index, | ||
| 2274 | union pplib_clock_info *clock_info) | ||
| 2275 | { | ||
| 2276 | u32 sclk, mclk; | ||
| 2277 | |||
| 2278 | if (rdev->flags & RADEON_IS_IGP) { | ||
| 2279 | if (rdev->family >= CHIP_PALM) { | ||
| 2280 | sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); | ||
| 2281 | sclk |= clock_info->sumo.ucEngineClockHigh << 16; | ||
| 2282 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
| 2283 | } else { | ||
| 2284 | sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); | ||
| 2285 | sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; | ||
| 2286 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
| 2287 | } | ||
| 2288 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 2289 | sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow); | ||
| 2290 | sclk |= clock_info->evergreen.ucEngineClockHigh << 16; | ||
| 2291 | mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow); | ||
| 2292 | mclk |= clock_info->evergreen.ucMemoryClockHigh << 16; | ||
| 2293 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | ||
| 2294 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
| 2295 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | ||
| 2296 | VOLTAGE_SW; | ||
| 2297 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
| 2298 | clock_info->evergreen.usVDDC; | ||
| 2299 | } else { | ||
| 2300 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); | ||
| 2301 | sclk |= clock_info->r600.ucEngineClockHigh << 16; | ||
| 2302 | mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow); | ||
| 2303 | mclk |= clock_info->r600.ucMemoryClockHigh << 16; | ||
| 2304 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | ||
| 2305 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
| 2306 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | ||
| 2307 | VOLTAGE_SW; | ||
| 2308 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
| 2309 | clock_info->r600.usVDDC; | ||
| 2310 | } | ||
| 2311 | |||
| 2312 | if (rdev->flags & RADEON_IS_IGP) { | ||
| 2313 | /* skip invalid modes */ | ||
| 2314 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | ||
| 2315 | return false; | ||
| 2316 | } else { | ||
| 2317 | /* skip invalid modes */ | ||
| 2318 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | ||
| 2319 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | ||
| 2320 | return false; | ||
| 2321 | } | ||
| 2322 | return true; | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) | ||
| 2326 | { | ||
| 2327 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
| 2328 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
| 2329 | union pplib_power_state *power_state; | ||
| 2330 | int i, j; | ||
| 2331 | int state_index = 0, mode_index = 0; | ||
| 2332 | union pplib_clock_info *clock_info; | ||
| 2333 | bool valid; | ||
| 2334 | union power_info *power_info; | ||
| 2335 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | ||
| 2336 | u16 data_offset; | ||
| 2337 | u8 frev, crev; | ||
| 2338 | |||
| 2339 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
| 2340 | &frev, &crev, &data_offset)) | ||
| 2341 | return state_index; | ||
| 2342 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | ||
| 2343 | |||
| 2344 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); | ||
| 2345 | /* first mode is usually default, followed by low to high */ | ||
| 2346 | for (i = 0; i < power_info->pplib.ucNumStates; i++) { | ||
| 2347 | mode_index = 0; | ||
| 2348 | power_state = (union pplib_power_state *) | ||
| 2349 | (mode_info->atom_context->bios + data_offset + | ||
| 2350 | le16_to_cpu(power_info->pplib.usStateArrayOffset) + | ||
| 2351 | i * power_info->pplib.ucStateEntrySize); | ||
| 2352 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | ||
| 2353 | (mode_info->atom_context->bios + data_offset + | ||
| 2354 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + | ||
| 2355 | (power_state->v1.ucNonClockStateIndex * | ||
| 2356 | power_info->pplib.ucNonClockSize)); | ||
| 2357 | for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { | ||
| 2358 | clock_info = (union pplib_clock_info *) | ||
| 2359 | (mode_info->atom_context->bios + data_offset + | ||
| 2360 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + | ||
| 2361 | (power_state->v1.ucClockStateIndices[j] * | ||
| 2362 | power_info->pplib.ucClockInfoSize)); | ||
| 2363 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
| 2364 | state_index, mode_index, | ||
| 2365 | clock_info); | ||
| 2366 | if (valid) | ||
| 2367 | mode_index++; | ||
| 2368 | } | ||
| 2369 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
| 2370 | if (mode_index) { | ||
| 2371 | radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, | ||
| 2372 | non_clock_info); | ||
| 2373 | state_index++; | ||
| 2374 | } | ||
| 2375 | } | ||
| 2376 | /* if multiple clock modes, mark the lowest as no display */ | ||
| 2377 | for (i = 0; i < state_index; i++) { | ||
| 2378 | if (rdev->pm.power_state[i].num_clock_modes > 1) | ||
| 2379 | rdev->pm.power_state[i].clock_info[0].flags |= | ||
| 2380 | RADEON_PM_MODE_NO_DISPLAY; | ||
| 2381 | } | ||
| 2382 | /* first mode is usually default */ | ||
| 2383 | if (rdev->pm.default_power_state_index == -1) { | ||
| 2384 | rdev->pm.power_state[0].type = | ||
| 2385 | POWER_STATE_TYPE_DEFAULT; | ||
| 2386 | rdev->pm.default_power_state_index = 0; | ||
| 2387 | rdev->pm.power_state[0].default_clock_mode = | ||
| 2388 | &rdev->pm.power_state[0].clock_info[0]; | ||
| 2389 | } | ||
| 2390 | return state_index; | ||
| 2391 | } | ||
| 2392 | |||
| 2393 | static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) | ||
| 2394 | { | ||
| 2395 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
| 2396 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
| 2397 | union pplib_power_state *power_state; | ||
| 2398 | int i, j, non_clock_array_index, clock_array_index; | ||
| 2399 | int state_index = 0, mode_index = 0; | ||
| 2400 | union pplib_clock_info *clock_info; | ||
| 2401 | struct StateArray *state_array; | ||
| 2402 | struct ClockInfoArray *clock_info_array; | ||
| 2403 | struct NonClockInfoArray *non_clock_info_array; | ||
| 2404 | bool valid; | ||
| 2405 | union power_info *power_info; | ||
| 2406 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | ||
| 2407 | u16 data_offset; | ||
| 2408 | u8 frev, crev; | ||
| 2409 | |||
| 2410 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
| 2411 | &frev, &crev, &data_offset)) | ||
| 2412 | return state_index; | ||
| 2413 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | ||
| 2414 | |||
| 2415 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); | ||
| 2416 | state_array = (struct StateArray *) | ||
| 2417 | (mode_info->atom_context->bios + data_offset + | ||
| 2418 | power_info->pplib.usStateArrayOffset); | ||
| 2419 | clock_info_array = (struct ClockInfoArray *) | ||
| 2420 | (mode_info->atom_context->bios + data_offset + | ||
| 2421 | power_info->pplib.usClockInfoArrayOffset); | ||
| 2422 | non_clock_info_array = (struct NonClockInfoArray *) | ||
| 2423 | (mode_info->atom_context->bios + data_offset + | ||
| 2424 | power_info->pplib.usNonClockInfoArrayOffset); | ||
| 2425 | for (i = 0; i < state_array->ucNumEntries; i++) { | ||
| 2426 | mode_index = 0; | ||
| 2427 | power_state = (union pplib_power_state *)&state_array->states[i]; | ||
| 2428 | /* XXX this might be an inagua bug... */ | ||
| 2429 | non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ | ||
| 2430 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | ||
| 2431 | &non_clock_info_array->nonClockInfo[non_clock_array_index]; | ||
| 2432 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { | ||
| 2433 | clock_array_index = power_state->v2.clockInfoIndex[j]; | ||
| 2434 | /* XXX this might be an inagua bug... */ | ||
| 2435 | if (clock_array_index >= clock_info_array->ucNumEntries) | ||
| 2436 | continue; | ||
| 2437 | clock_info = (union pplib_clock_info *) | ||
| 2438 | &clock_info_array->clockInfo[clock_array_index]; | ||
| 2439 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
| 2440 | state_index, mode_index, | ||
| 2441 | clock_info); | ||
| 2442 | if (valid) | ||
| 2443 | mode_index++; | ||
| 2444 | } | ||
| 2445 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
| 2446 | if (mode_index) { | ||
| 2447 | radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, | ||
| 2448 | non_clock_info); | ||
| 2449 | state_index++; | ||
| 2450 | } | ||
| 2451 | } | ||
| 2452 | /* if multiple clock modes, mark the lowest as no display */ | ||
| 2453 | for (i = 0; i < state_index; i++) { | ||
| 2454 | if (rdev->pm.power_state[i].num_clock_modes > 1) | ||
| 2455 | rdev->pm.power_state[i].clock_info[0].flags |= | ||
| 2456 | RADEON_PM_MODE_NO_DISPLAY; | ||
| 2457 | } | ||
| 2458 | /* first mode is usually default */ | ||
| 2459 | if (rdev->pm.default_power_state_index == -1) { | ||
| 2460 | rdev->pm.power_state[0].type = | ||
| 2461 | POWER_STATE_TYPE_DEFAULT; | ||
| 2462 | rdev->pm.default_power_state_index = 0; | ||
| 2463 | rdev->pm.power_state[0].default_clock_mode = | ||
| 2464 | &rdev->pm.power_state[0].clock_info[0]; | ||
| 2465 | } | ||
| 2466 | return state_index; | ||
| 2467 | } | ||
| 2468 | |||
| 2469 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | ||
| 2470 | { | ||
| 2471 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
| 2472 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | ||
| 2473 | u16 data_offset; | ||
| 2474 | u8 frev, crev; | ||
| 2475 | int state_index = 0; | ||
| 2476 | |||
| 2477 | rdev->pm.default_power_state_index = -1; | ||
| 2478 | |||
| 2479 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
| 2480 | &frev, &crev, &data_offset)) { | ||
| 2481 | switch (frev) { | ||
| 2482 | case 1: | ||
| 2483 | case 2: | ||
| 2484 | case 3: | ||
| 2485 | state_index = radeon_atombios_parse_power_table_1_3(rdev); | ||
| 2486 | break; | ||
| 2487 | case 4: | ||
| 2488 | case 5: | ||
| 2489 | state_index = radeon_atombios_parse_power_table_4_5(rdev); | ||
| 2490 | break; | ||
| 2491 | case 6: | ||
| 2492 | state_index = radeon_atombios_parse_power_table_6(rdev); | ||
| 2493 | break; | ||
| 2494 | default: | ||
| 2495 | break; | ||
| 2496 | } | ||
| 2233 | } else { | 2497 | } else { |
| 2234 | /* add the default mode */ | 2498 | /* add the default mode */ |
| 2235 | rdev->pm.power_state[state_index].type = | 2499 | rdev->pm.power_state[state_index].type = |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 8f2c7b50dcf5..1aba85cad1a8 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
| @@ -131,6 +131,45 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
| 131 | return true; | 131 | return true; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | static bool ni_read_disabled_bios(struct radeon_device *rdev) | ||
| 135 | { | ||
| 136 | u32 bus_cntl; | ||
| 137 | u32 d1vga_control; | ||
| 138 | u32 d2vga_control; | ||
| 139 | u32 vga_render_control; | ||
| 140 | u32 rom_cntl; | ||
| 141 | bool r; | ||
| 142 | |||
| 143 | bus_cntl = RREG32(R600_BUS_CNTL); | ||
| 144 | d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); | ||
| 145 | d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); | ||
| 146 | vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); | ||
| 147 | rom_cntl = RREG32(R600_ROM_CNTL); | ||
| 148 | |||
| 149 | /* enable the rom */ | ||
| 150 | WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); | ||
| 151 | /* Disable VGA mode */ | ||
| 152 | WREG32(AVIVO_D1VGA_CONTROL, | ||
| 153 | (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | | ||
| 154 | AVIVO_DVGA_CONTROL_TIMING_SELECT))); | ||
| 155 | WREG32(AVIVO_D2VGA_CONTROL, | ||
| 156 | (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | | ||
| 157 | AVIVO_DVGA_CONTROL_TIMING_SELECT))); | ||
| 158 | WREG32(AVIVO_VGA_RENDER_CONTROL, | ||
| 159 | (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); | ||
| 160 | WREG32(R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE); | ||
| 161 | |||
| 162 | r = radeon_read_bios(rdev); | ||
| 163 | |||
| 164 | /* restore regs */ | ||
| 165 | WREG32(R600_BUS_CNTL, bus_cntl); | ||
| 166 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); | ||
| 167 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); | ||
| 168 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); | ||
| 169 | WREG32(R600_ROM_CNTL, rom_cntl); | ||
| 170 | return r; | ||
| 171 | } | ||
| 172 | |||
| 134 | static bool r700_read_disabled_bios(struct radeon_device *rdev) | 173 | static bool r700_read_disabled_bios(struct radeon_device *rdev) |
| 135 | { | 174 | { |
| 136 | uint32_t viph_control; | 175 | uint32_t viph_control; |
| @@ -416,6 +455,8 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) | |||
| 416 | { | 455 | { |
| 417 | if (rdev->flags & RADEON_IS_IGP) | 456 | if (rdev->flags & RADEON_IS_IGP) |
| 418 | return igp_read_bios_from_vram(rdev); | 457 | return igp_read_bios_from_vram(rdev); |
| 458 | else if (rdev->family >= CHIP_BARTS) | ||
| 459 | return ni_read_disabled_bios(rdev); | ||
| 419 | else if (rdev->family >= CHIP_RV770) | 460 | else if (rdev->family >= CHIP_RV770) |
| 420 | return r700_read_disabled_bios(rdev); | 461 | return r700_read_disabled_bios(rdev); |
| 421 | else if (rdev->family >= CHIP_R600) | 462 | else if (rdev->family >= CHIP_R600) |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 137b8075f6e7..591fcae8f224 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -471,8 +471,9 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) | |||
| 471 | return true; | 471 | return true; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | /* this is used for atom LCDs as well */ | ||
| 474 | struct edid * | 475 | struct edid * |
| 475 | radeon_combios_get_hardcoded_edid(struct radeon_device *rdev) | 476 | radeon_bios_get_hardcoded_edid(struct radeon_device *rdev) |
| 476 | { | 477 | { |
| 477 | if (rdev->mode_info.bios_hardcoded_edid) | 478 | if (rdev->mode_info.bios_hardcoded_edid) |
| 478 | return rdev->mode_info.bios_hardcoded_edid; | 479 | return rdev->mode_info.bios_hardcoded_edid; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 8afaf7a7459e..22b7e3dc0eca 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -472,6 +472,9 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) | |||
| 472 | if (mode) { | 472 | if (mode) { |
| 473 | ret = 1; | 473 | ret = 1; |
| 474 | drm_mode_probed_add(connector, mode); | 474 | drm_mode_probed_add(connector, mode); |
| 475 | /* add the width/height from vbios tables if available */ | ||
| 476 | connector->display_info.width_mm = mode->width_mm; | ||
| 477 | connector->display_info.height_mm = mode->height_mm; | ||
| 475 | /* add scaled modes */ | 478 | /* add scaled modes */ |
| 476 | radeon_add_common_modes(encoder, connector); | 479 | radeon_add_common_modes(encoder, connector); |
| 477 | } | 480 | } |
| @@ -1216,7 +1219,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1216 | if (ASIC_IS_AVIVO(rdev)) { | 1219 | if (ASIC_IS_AVIVO(rdev)) { |
| 1217 | drm_connector_attach_property(&radeon_connector->base, | 1220 | drm_connector_attach_property(&radeon_connector->base, |
| 1218 | rdev->mode_info.underscan_property, | 1221 | rdev->mode_info.underscan_property, |
| 1219 | UNDERSCAN_AUTO); | 1222 | UNDERSCAN_OFF); |
| 1220 | drm_connector_attach_property(&radeon_connector->base, | 1223 | drm_connector_attach_property(&radeon_connector->base, |
| 1221 | rdev->mode_info.underscan_hborder_property, | 1224 | rdev->mode_info.underscan_hborder_property, |
| 1222 | 0); | 1225 | 0); |
| @@ -1256,7 +1259,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1256 | if (ASIC_IS_AVIVO(rdev)) { | 1259 | if (ASIC_IS_AVIVO(rdev)) { |
| 1257 | drm_connector_attach_property(&radeon_connector->base, | 1260 | drm_connector_attach_property(&radeon_connector->base, |
| 1258 | rdev->mode_info.underscan_property, | 1261 | rdev->mode_info.underscan_property, |
| 1259 | UNDERSCAN_AUTO); | 1262 | UNDERSCAN_OFF); |
| 1260 | drm_connector_attach_property(&radeon_connector->base, | 1263 | drm_connector_attach_property(&radeon_connector->base, |
| 1261 | rdev->mode_info.underscan_hborder_property, | 1264 | rdev->mode_info.underscan_hborder_property, |
| 1262 | 0); | 1265 | 0); |
| @@ -1299,7 +1302,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1299 | if (ASIC_IS_AVIVO(rdev)) { | 1302 | if (ASIC_IS_AVIVO(rdev)) { |
| 1300 | drm_connector_attach_property(&radeon_connector->base, | 1303 | drm_connector_attach_property(&radeon_connector->base, |
| 1301 | rdev->mode_info.underscan_property, | 1304 | rdev->mode_info.underscan_property, |
| 1302 | UNDERSCAN_AUTO); | 1305 | UNDERSCAN_OFF); |
| 1303 | drm_connector_attach_property(&radeon_connector->base, | 1306 | drm_connector_attach_property(&radeon_connector->base, |
| 1304 | rdev->mode_info.underscan_hborder_property, | 1307 | rdev->mode_info.underscan_hborder_property, |
| 1305 | 0); | 1308 | 0); |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 6d64a2705f12..35b5eb8fbe2a 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -77,13 +77,13 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
| 77 | p->relocs_ptr[i] = &p->relocs[i]; | 77 | p->relocs_ptr[i] = &p->relocs[i]; |
| 78 | p->relocs[i].robj = p->relocs[i].gobj->driver_private; | 78 | p->relocs[i].robj = p->relocs[i].gobj->driver_private; |
| 79 | p->relocs[i].lobj.bo = p->relocs[i].robj; | 79 | p->relocs[i].lobj.bo = p->relocs[i].robj; |
| 80 | p->relocs[i].lobj.rdomain = r->read_domains; | ||
| 81 | p->relocs[i].lobj.wdomain = r->write_domain; | 80 | p->relocs[i].lobj.wdomain = r->write_domain; |
| 81 | p->relocs[i].lobj.rdomain = r->read_domains; | ||
| 82 | p->relocs[i].lobj.tv.bo = &p->relocs[i].robj->tbo; | ||
| 82 | p->relocs[i].handle = r->handle; | 83 | p->relocs[i].handle = r->handle; |
| 83 | p->relocs[i].flags = r->flags; | 84 | p->relocs[i].flags = r->flags; |
| 84 | INIT_LIST_HEAD(&p->relocs[i].lobj.list); | ||
| 85 | radeon_bo_list_add_object(&p->relocs[i].lobj, | 85 | radeon_bo_list_add_object(&p->relocs[i].lobj, |
| 86 | &p->validated); | 86 | &p->validated); |
| 87 | } | 87 | } |
| 88 | } | 88 | } |
| 89 | return radeon_bo_list_validate(&p->validated); | 89 | return radeon_bo_list_validate(&p->validated); |
| @@ -189,10 +189,13 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
| 189 | { | 189 | { |
| 190 | unsigned i; | 190 | unsigned i; |
| 191 | 191 | ||
| 192 | if (!error && parser->ib) { | 192 | |
| 193 | radeon_bo_list_fence(&parser->validated, parser->ib->fence); | 193 | if (!error && parser->ib) |
| 194 | } | 194 | ttm_eu_fence_buffer_objects(&parser->validated, |
| 195 | radeon_bo_list_unreserve(&parser->validated); | 195 | parser->ib->fence); |
| 196 | else | ||
| 197 | ttm_eu_backoff_reservation(&parser->validated); | ||
| 198 | |||
| 196 | if (parser->relocs != NULL) { | 199 | if (parser->relocs != NULL) { |
| 197 | for (i = 0; i < parser->nrelocs; i++) { | 200 | for (i = 0; i < parser->nrelocs; i++) { |
| 198 | if (parser->relocs[i].gobj) | 201 | if (parser->relocs[i].gobj) |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 501966a13f48..26091d602b84 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -81,6 +81,10 @@ static const char radeon_family_name[][16] = { | |||
| 81 | "JUNIPER", | 81 | "JUNIPER", |
| 82 | "CYPRESS", | 82 | "CYPRESS", |
| 83 | "HEMLOCK", | 83 | "HEMLOCK", |
| 84 | "PALM", | ||
| 85 | "BARTS", | ||
| 86 | "TURKS", | ||
| 87 | "CAICOS", | ||
| 84 | "LAST", | 88 | "LAST", |
| 85 | }; | 89 | }; |
| 86 | 90 | ||
| @@ -224,6 +228,11 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
| 224 | rdev->wb.use_event = true; | 228 | rdev->wb.use_event = true; |
| 225 | } | 229 | } |
| 226 | } | 230 | } |
| 231 | /* always use writeback/events on NI */ | ||
| 232 | if (ASIC_IS_DCE5(rdev)) { | ||
| 233 | rdev->wb.enabled = true; | ||
| 234 | rdev->wb.use_event = true; | ||
| 235 | } | ||
| 227 | 236 | ||
| 228 | dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis"); | 237 | dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis"); |
| 229 | 238 | ||
| @@ -335,7 +344,12 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
| 335 | uint32_t reg; | 344 | uint32_t reg; |
| 336 | 345 | ||
| 337 | /* first check CRTCs */ | 346 | /* first check CRTCs */ |
| 338 | if (ASIC_IS_DCE4(rdev)) { | 347 | if (ASIC_IS_DCE41(rdev)) { |
| 348 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | | ||
| 349 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
| 350 | if (reg & EVERGREEN_CRTC_MASTER_EN) | ||
| 351 | return true; | ||
| 352 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 339 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | | 353 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | |
| 340 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | | 354 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | |
| 341 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | | 355 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | |
| @@ -636,20 +650,20 @@ void radeon_check_arguments(struct radeon_device *rdev) | |||
| 636 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) | 650 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) |
| 637 | { | 651 | { |
| 638 | struct drm_device *dev = pci_get_drvdata(pdev); | 652 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 639 | struct radeon_device *rdev = dev->dev_private; | ||
| 640 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; | 653 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
| 641 | if (state == VGA_SWITCHEROO_ON) { | 654 | if (state == VGA_SWITCHEROO_ON) { |
| 642 | printk(KERN_INFO "radeon: switched on\n"); | 655 | printk(KERN_INFO "radeon: switched on\n"); |
| 643 | /* don't suspend or resume card normally */ | 656 | /* don't suspend or resume card normally */ |
| 644 | rdev->powered_down = false; | 657 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
| 645 | radeon_resume_kms(dev); | 658 | radeon_resume_kms(dev); |
| 659 | dev->switch_power_state = DRM_SWITCH_POWER_ON; | ||
| 646 | drm_kms_helper_poll_enable(dev); | 660 | drm_kms_helper_poll_enable(dev); |
| 647 | } else { | 661 | } else { |
| 648 | printk(KERN_INFO "radeon: switched off\n"); | 662 | printk(KERN_INFO "radeon: switched off\n"); |
| 649 | drm_kms_helper_poll_disable(dev); | 663 | drm_kms_helper_poll_disable(dev); |
| 664 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
| 650 | radeon_suspend_kms(dev, pmm); | 665 | radeon_suspend_kms(dev, pmm); |
| 651 | /* don't suspend or resume card normally */ | 666 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; |
| 652 | rdev->powered_down = true; | ||
| 653 | } | 667 | } |
| 654 | } | 668 | } |
| 655 | 669 | ||
| @@ -704,11 +718,6 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 704 | init_waitqueue_head(&rdev->irq.vblank_queue); | 718 | init_waitqueue_head(&rdev->irq.vblank_queue); |
| 705 | init_waitqueue_head(&rdev->irq.idle_queue); | 719 | init_waitqueue_head(&rdev->irq.idle_queue); |
| 706 | 720 | ||
| 707 | /* setup workqueue */ | ||
| 708 | rdev->wq = create_workqueue("radeon"); | ||
| 709 | if (rdev->wq == NULL) | ||
| 710 | return -ENOMEM; | ||
| 711 | |||
| 712 | /* Set asic functions */ | 721 | /* Set asic functions */ |
| 713 | r = radeon_asic_init(rdev); | 722 | r = radeon_asic_init(rdev); |
| 714 | if (r) | 723 | if (r) |
| @@ -773,6 +782,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 773 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); | 782 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); |
| 774 | vga_switcheroo_register_client(rdev->pdev, | 783 | vga_switcheroo_register_client(rdev->pdev, |
| 775 | radeon_switcheroo_set_state, | 784 | radeon_switcheroo_set_state, |
| 785 | NULL, | ||
| 776 | radeon_switcheroo_can_switch); | 786 | radeon_switcheroo_can_switch); |
| 777 | 787 | ||
| 778 | r = radeon_init(rdev); | 788 | r = radeon_init(rdev); |
| @@ -806,7 +816,6 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
| 806 | /* evict vram memory */ | 816 | /* evict vram memory */ |
| 807 | radeon_bo_evict_vram(rdev); | 817 | radeon_bo_evict_vram(rdev); |
| 808 | radeon_fini(rdev); | 818 | radeon_fini(rdev); |
| 809 | destroy_workqueue(rdev->wq); | ||
| 810 | vga_switcheroo_unregister_client(rdev->pdev); | 819 | vga_switcheroo_unregister_client(rdev->pdev); |
| 811 | vga_client_register(rdev->pdev, NULL, NULL, NULL); | 820 | vga_client_register(rdev->pdev, NULL, NULL, NULL); |
| 812 | if (rdev->rio_mem) | 821 | if (rdev->rio_mem) |
| @@ -835,7 +844,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
| 835 | } | 844 | } |
| 836 | rdev = dev->dev_private; | 845 | rdev = dev->dev_private; |
| 837 | 846 | ||
| 838 | if (rdev->powered_down) | 847 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 839 | return 0; | 848 | return 0; |
| 840 | 849 | ||
| 841 | /* turn off display hw */ | 850 | /* turn off display hw */ |
| @@ -893,7 +902,7 @@ int radeon_resume_kms(struct drm_device *dev) | |||
| 893 | struct drm_connector *connector; | 902 | struct drm_connector *connector; |
| 894 | struct radeon_device *rdev = dev->dev_private; | 903 | struct radeon_device *rdev = dev->dev_private; |
| 895 | 904 | ||
| 896 | if (rdev->powered_down) | 905 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 897 | return 0; | 906 | return 0; |
| 898 | 907 | ||
| 899 | acquire_console_sem(); | 908 | acquire_console_sem(); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1df4dc6c063c..d26dabf878d9 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -68,7 +68,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) | |||
| 68 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); | 68 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static void evergreen_crtc_load_lut(struct drm_crtc *crtc) | 71 | static void dce4_crtc_load_lut(struct drm_crtc *crtc) |
| 72 | { | 72 | { |
| 73 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 73 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 74 | struct drm_device *dev = crtc->dev; | 74 | struct drm_device *dev = crtc->dev; |
| @@ -98,6 +98,66 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc) | |||
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static void dce5_crtc_load_lut(struct drm_crtc *crtc) | ||
| 102 | { | ||
| 103 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 104 | struct drm_device *dev = crtc->dev; | ||
| 105 | struct radeon_device *rdev = dev->dev_private; | ||
| 106 | int i; | ||
| 107 | |||
| 108 | DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); | ||
| 109 | |||
| 110 | WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset, | ||
| 111 | (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) | | ||
| 112 | NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS))); | ||
| 113 | WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset, | ||
| 114 | NI_GRPH_PRESCALE_BYPASS); | ||
| 115 | WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset, | ||
| 116 | NI_OVL_PRESCALE_BYPASS); | ||
| 117 | WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset, | ||
| 118 | (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) | | ||
| 119 | NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT))); | ||
| 120 | |||
| 121 | WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); | ||
| 122 | |||
| 123 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); | ||
| 124 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); | ||
| 125 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); | ||
| 126 | |||
| 127 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); | ||
| 128 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); | ||
| 129 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); | ||
| 130 | |||
| 131 | WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0); | ||
| 132 | WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); | ||
| 133 | |||
| 134 | WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); | ||
| 135 | for (i = 0; i < 256; i++) { | ||
| 136 | WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, | ||
| 137 | (radeon_crtc->lut_r[i] << 20) | | ||
| 138 | (radeon_crtc->lut_g[i] << 10) | | ||
| 139 | (radeon_crtc->lut_b[i] << 0)); | ||
| 140 | } | ||
| 141 | |||
| 142 | WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset, | ||
| 143 | (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | | ||
| 144 | NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | | ||
| 145 | NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | | ||
| 146 | NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS))); | ||
| 147 | WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset, | ||
| 148 | (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) | | ||
| 149 | NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS))); | ||
| 150 | WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset, | ||
| 151 | (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) | | ||
| 152 | NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS))); | ||
| 153 | WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset, | ||
| 154 | (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) | | ||
| 155 | NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS))); | ||
| 156 | /* XXX match this to the depth of the crtc fmt block, move to modeset? */ | ||
| 157 | WREG32(0x6940 + radeon_crtc->crtc_offset, 0); | ||
| 158 | |||
| 159 | } | ||
| 160 | |||
| 101 | static void legacy_crtc_load_lut(struct drm_crtc *crtc) | 161 | static void legacy_crtc_load_lut(struct drm_crtc *crtc) |
| 102 | { | 162 | { |
| 103 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 163 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| @@ -130,8 +190,10 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc) | |||
| 130 | if (!crtc->enabled) | 190 | if (!crtc->enabled) |
| 131 | return; | 191 | return; |
| 132 | 192 | ||
| 133 | if (ASIC_IS_DCE4(rdev)) | 193 | if (ASIC_IS_DCE5(rdev)) |
| 134 | evergreen_crtc_load_lut(crtc); | 194 | dce5_crtc_load_lut(crtc); |
| 195 | else if (ASIC_IS_DCE4(rdev)) | ||
| 196 | dce4_crtc_load_lut(crtc); | ||
| 135 | else if (ASIC_IS_AVIVO(rdev)) | 197 | else if (ASIC_IS_AVIVO(rdev)) |
| 136 | avivo_crtc_load_lut(crtc); | 198 | avivo_crtc_load_lut(crtc); |
| 137 | else | 199 | else |
| @@ -183,12 +245,272 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc) | |||
| 183 | kfree(radeon_crtc); | 245 | kfree(radeon_crtc); |
| 184 | } | 246 | } |
| 185 | 247 | ||
| 248 | /* | ||
| 249 | * Handle unpin events outside the interrupt handler proper. | ||
| 250 | */ | ||
| 251 | static void radeon_unpin_work_func(struct work_struct *__work) | ||
| 252 | { | ||
| 253 | struct radeon_unpin_work *work = | ||
| 254 | container_of(__work, struct radeon_unpin_work, work); | ||
| 255 | int r; | ||
| 256 | |||
| 257 | /* unpin of the old buffer */ | ||
| 258 | r = radeon_bo_reserve(work->old_rbo, false); | ||
| 259 | if (likely(r == 0)) { | ||
| 260 | r = radeon_bo_unpin(work->old_rbo); | ||
| 261 | if (unlikely(r != 0)) { | ||
| 262 | DRM_ERROR("failed to unpin buffer after flip\n"); | ||
| 263 | } | ||
| 264 | radeon_bo_unreserve(work->old_rbo); | ||
| 265 | } else | ||
| 266 | DRM_ERROR("failed to reserve buffer after flip\n"); | ||
| 267 | kfree(work); | ||
| 268 | } | ||
| 269 | |||
| 270 | void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) | ||
| 271 | { | ||
| 272 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
| 273 | struct radeon_unpin_work *work; | ||
| 274 | struct drm_pending_vblank_event *e; | ||
| 275 | struct timeval now; | ||
| 276 | unsigned long flags; | ||
| 277 | u32 update_pending; | ||
| 278 | int vpos, hpos; | ||
| 279 | |||
| 280 | spin_lock_irqsave(&rdev->ddev->event_lock, flags); | ||
| 281 | work = radeon_crtc->unpin_work; | ||
| 282 | if (work == NULL || | ||
| 283 | !radeon_fence_signaled(work->fence)) { | ||
| 284 | spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); | ||
| 285 | return; | ||
| 286 | } | ||
| 287 | /* New pageflip, or just completion of a previous one? */ | ||
| 288 | if (!radeon_crtc->deferred_flip_completion) { | ||
| 289 | /* do the flip (mmio) */ | ||
| 290 | update_pending = radeon_page_flip(rdev, crtc_id, work->new_crtc_base); | ||
| 291 | } else { | ||
| 292 | /* This is just a completion of a flip queued in crtc | ||
| 293 | * at last invocation. Make sure we go directly to | ||
| 294 | * completion routine. | ||
| 295 | */ | ||
| 296 | update_pending = 0; | ||
| 297 | radeon_crtc->deferred_flip_completion = 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | /* Has the pageflip already completed in crtc, or is it certain | ||
| 301 | * to complete in this vblank? | ||
| 302 | */ | ||
| 303 | if (update_pending && | ||
| 304 | (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, | ||
| 305 | &vpos, &hpos)) && | ||
| 306 | (vpos >=0) && | ||
| 307 | (vpos < (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100)) { | ||
| 308 | /* crtc didn't flip in this target vblank interval, | ||
| 309 | * but flip is pending in crtc. It will complete it | ||
| 310 | * in next vblank interval, so complete the flip at | ||
| 311 | * next vblank irq. | ||
| 312 | */ | ||
| 313 | radeon_crtc->deferred_flip_completion = 1; | ||
| 314 | spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); | ||
| 315 | return; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* Pageflip (will be) certainly completed in this vblank. Clean up. */ | ||
| 319 | radeon_crtc->unpin_work = NULL; | ||
| 320 | |||
| 321 | /* wakeup userspace */ | ||
| 322 | if (work->event) { | ||
| 323 | e = work->event; | ||
| 324 | e->event.sequence = drm_vblank_count_and_time(rdev->ddev, crtc_id, &now); | ||
| 325 | e->event.tv_sec = now.tv_sec; | ||
| 326 | e->event.tv_usec = now.tv_usec; | ||
| 327 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); | ||
| 328 | wake_up_interruptible(&e->base.file_priv->event_wait); | ||
| 329 | } | ||
| 330 | spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); | ||
| 331 | |||
| 332 | drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id); | ||
| 333 | radeon_fence_unref(&work->fence); | ||
| 334 | radeon_post_page_flip(work->rdev, work->crtc_id); | ||
| 335 | schedule_work(&work->work); | ||
| 336 | } | ||
| 337 | |||
| 338 | static int radeon_crtc_page_flip(struct drm_crtc *crtc, | ||
| 339 | struct drm_framebuffer *fb, | ||
| 340 | struct drm_pending_vblank_event *event) | ||
| 341 | { | ||
| 342 | struct drm_device *dev = crtc->dev; | ||
| 343 | struct radeon_device *rdev = dev->dev_private; | ||
| 344 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 345 | struct radeon_framebuffer *old_radeon_fb; | ||
| 346 | struct radeon_framebuffer *new_radeon_fb; | ||
| 347 | struct drm_gem_object *obj; | ||
| 348 | struct radeon_bo *rbo; | ||
| 349 | struct radeon_fence *fence; | ||
| 350 | struct radeon_unpin_work *work; | ||
| 351 | unsigned long flags; | ||
| 352 | u32 tiling_flags, pitch_pixels; | ||
| 353 | u64 base; | ||
| 354 | int r; | ||
| 355 | |||
| 356 | work = kzalloc(sizeof *work, GFP_KERNEL); | ||
| 357 | if (work == NULL) | ||
| 358 | return -ENOMEM; | ||
| 359 | |||
| 360 | r = radeon_fence_create(rdev, &fence); | ||
| 361 | if (unlikely(r != 0)) { | ||
| 362 | kfree(work); | ||
| 363 | DRM_ERROR("flip queue: failed to create fence.\n"); | ||
| 364 | return -ENOMEM; | ||
| 365 | } | ||
| 366 | work->event = event; | ||
| 367 | work->rdev = rdev; | ||
| 368 | work->crtc_id = radeon_crtc->crtc_id; | ||
| 369 | work->fence = radeon_fence_ref(fence); | ||
| 370 | old_radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
| 371 | new_radeon_fb = to_radeon_framebuffer(fb); | ||
| 372 | /* schedule unpin of the old buffer */ | ||
| 373 | obj = old_radeon_fb->obj; | ||
| 374 | rbo = obj->driver_private; | ||
| 375 | work->old_rbo = rbo; | ||
| 376 | INIT_WORK(&work->work, radeon_unpin_work_func); | ||
| 377 | |||
| 378 | /* We borrow the event spin lock for protecting unpin_work */ | ||
| 379 | spin_lock_irqsave(&dev->event_lock, flags); | ||
| 380 | if (radeon_crtc->unpin_work) { | ||
| 381 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 382 | kfree(work); | ||
| 383 | radeon_fence_unref(&fence); | ||
| 384 | |||
| 385 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
| 386 | return -EBUSY; | ||
| 387 | } | ||
| 388 | radeon_crtc->unpin_work = work; | ||
| 389 | radeon_crtc->deferred_flip_completion = 0; | ||
| 390 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 391 | |||
| 392 | /* pin the new buffer */ | ||
| 393 | obj = new_radeon_fb->obj; | ||
| 394 | rbo = obj->driver_private; | ||
| 395 | |||
| 396 | DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n", | ||
| 397 | work->old_rbo, rbo); | ||
| 398 | |||
| 399 | r = radeon_bo_reserve(rbo, false); | ||
| 400 | if (unlikely(r != 0)) { | ||
| 401 | DRM_ERROR("failed to reserve new rbo buffer before flip\n"); | ||
| 402 | goto pflip_cleanup; | ||
| 403 | } | ||
| 404 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base); | ||
| 405 | if (unlikely(r != 0)) { | ||
| 406 | radeon_bo_unreserve(rbo); | ||
| 407 | r = -EINVAL; | ||
| 408 | DRM_ERROR("failed to pin new rbo buffer before flip\n"); | ||
| 409 | goto pflip_cleanup; | ||
| 410 | } | ||
| 411 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | ||
| 412 | radeon_bo_unreserve(rbo); | ||
| 413 | |||
| 414 | if (!ASIC_IS_AVIVO(rdev)) { | ||
| 415 | /* crtc offset is from display base addr not FB location */ | ||
| 416 | base -= radeon_crtc->legacy_display_base_addr; | ||
| 417 | pitch_pixels = fb->pitch / (fb->bits_per_pixel / 8); | ||
| 418 | |||
| 419 | if (tiling_flags & RADEON_TILING_MACRO) { | ||
| 420 | if (ASIC_IS_R300(rdev)) { | ||
| 421 | base &= ~0x7ff; | ||
| 422 | } else { | ||
| 423 | int byteshift = fb->bits_per_pixel >> 4; | ||
| 424 | int tile_addr = (((crtc->y >> 3) * pitch_pixels + crtc->x) >> (8 - byteshift)) << 11; | ||
| 425 | base += tile_addr + ((crtc->x << byteshift) % 256) + ((crtc->y % 8) << 8); | ||
| 426 | } | ||
| 427 | } else { | ||
| 428 | int offset = crtc->y * pitch_pixels + crtc->x; | ||
| 429 | switch (fb->bits_per_pixel) { | ||
| 430 | case 8: | ||
| 431 | default: | ||
| 432 | offset *= 1; | ||
| 433 | break; | ||
| 434 | case 15: | ||
| 435 | case 16: | ||
| 436 | offset *= 2; | ||
| 437 | break; | ||
| 438 | case 24: | ||
| 439 | offset *= 3; | ||
| 440 | break; | ||
| 441 | case 32: | ||
| 442 | offset *= 4; | ||
| 443 | break; | ||
| 444 | } | ||
| 445 | base += offset; | ||
| 446 | } | ||
| 447 | base &= ~7; | ||
| 448 | } | ||
| 449 | |||
| 450 | spin_lock_irqsave(&dev->event_lock, flags); | ||
| 451 | work->new_crtc_base = base; | ||
| 452 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 453 | |||
| 454 | /* update crtc fb */ | ||
| 455 | crtc->fb = fb; | ||
| 456 | |||
| 457 | r = drm_vblank_get(dev, radeon_crtc->crtc_id); | ||
| 458 | if (r) { | ||
| 459 | DRM_ERROR("failed to get vblank before flip\n"); | ||
| 460 | goto pflip_cleanup1; | ||
| 461 | } | ||
| 462 | |||
| 463 | /* 32 ought to cover us */ | ||
| 464 | r = radeon_ring_lock(rdev, 32); | ||
| 465 | if (r) { | ||
| 466 | DRM_ERROR("failed to lock the ring before flip\n"); | ||
| 467 | goto pflip_cleanup2; | ||
| 468 | } | ||
| 469 | |||
| 470 | /* emit the fence */ | ||
| 471 | radeon_fence_emit(rdev, fence); | ||
| 472 | /* set the proper interrupt */ | ||
| 473 | radeon_pre_page_flip(rdev, radeon_crtc->crtc_id); | ||
| 474 | /* fire the ring */ | ||
| 475 | radeon_ring_unlock_commit(rdev); | ||
| 476 | |||
| 477 | return 0; | ||
| 478 | |||
| 479 | pflip_cleanup2: | ||
| 480 | drm_vblank_put(dev, radeon_crtc->crtc_id); | ||
| 481 | |||
| 482 | pflip_cleanup1: | ||
| 483 | r = radeon_bo_reserve(rbo, false); | ||
| 484 | if (unlikely(r != 0)) { | ||
| 485 | DRM_ERROR("failed to reserve new rbo in error path\n"); | ||
| 486 | goto pflip_cleanup; | ||
| 487 | } | ||
| 488 | r = radeon_bo_unpin(rbo); | ||
| 489 | if (unlikely(r != 0)) { | ||
| 490 | radeon_bo_unreserve(rbo); | ||
| 491 | r = -EINVAL; | ||
| 492 | DRM_ERROR("failed to unpin new rbo in error path\n"); | ||
| 493 | goto pflip_cleanup; | ||
| 494 | } | ||
| 495 | radeon_bo_unreserve(rbo); | ||
| 496 | |||
| 497 | pflip_cleanup: | ||
| 498 | spin_lock_irqsave(&dev->event_lock, flags); | ||
| 499 | radeon_crtc->unpin_work = NULL; | ||
| 500 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 501 | radeon_fence_unref(&fence); | ||
| 502 | kfree(work); | ||
| 503 | |||
| 504 | return r; | ||
| 505 | } | ||
| 506 | |||
| 186 | static const struct drm_crtc_funcs radeon_crtc_funcs = { | 507 | static const struct drm_crtc_funcs radeon_crtc_funcs = { |
| 187 | .cursor_set = radeon_crtc_cursor_set, | 508 | .cursor_set = radeon_crtc_cursor_set, |
| 188 | .cursor_move = radeon_crtc_cursor_move, | 509 | .cursor_move = radeon_crtc_cursor_move, |
| 189 | .gamma_set = radeon_crtc_gamma_set, | 510 | .gamma_set = radeon_crtc_gamma_set, |
| 190 | .set_config = drm_crtc_helper_set_config, | 511 | .set_config = drm_crtc_helper_set_config, |
| 191 | .destroy = radeon_crtc_destroy, | 512 | .destroy = radeon_crtc_destroy, |
| 513 | .page_flip = radeon_crtc_page_flip, | ||
| 192 | }; | 514 | }; |
| 193 | 515 | ||
| 194 | static void radeon_crtc_init(struct drm_device *dev, int index) | 516 | static void radeon_crtc_init(struct drm_device *dev, int index) |
| @@ -225,7 +547,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) | |||
| 225 | radeon_legacy_init_crtc(dev, radeon_crtc); | 547 | radeon_legacy_init_crtc(dev, radeon_crtc); |
| 226 | } | 548 | } |
| 227 | 549 | ||
| 228 | static const char *encoder_names[34] = { | 550 | static const char *encoder_names[36] = { |
| 229 | "NONE", | 551 | "NONE", |
| 230 | "INTERNAL_LVDS", | 552 | "INTERNAL_LVDS", |
| 231 | "INTERNAL_TMDS1", | 553 | "INTERNAL_TMDS1", |
| @@ -260,6 +582,8 @@ static const char *encoder_names[34] = { | |||
| 260 | "INTERNAL_KLDSCP_LVTMA", | 582 | "INTERNAL_KLDSCP_LVTMA", |
| 261 | "INTERNAL_UNIPHY1", | 583 | "INTERNAL_UNIPHY1", |
| 262 | "INTERNAL_UNIPHY2", | 584 | "INTERNAL_UNIPHY2", |
| 585 | "NUTMEG", | ||
| 586 | "TRAVIS", | ||
| 263 | }; | 587 | }; |
| 264 | 588 | ||
| 265 | static const char *connector_names[15] = { | 589 | static const char *connector_names[15] = { |
| @@ -417,9 +741,17 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
| 417 | if (!radeon_connector->edid) { | 741 | if (!radeon_connector->edid) { |
| 418 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 742 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
| 419 | } | 743 | } |
| 420 | /* some servers provide a hardcoded edid in rom for KVMs */ | 744 | |
| 421 | if (!radeon_connector->edid) | 745 | if (!radeon_connector->edid) { |
| 422 | radeon_connector->edid = radeon_combios_get_hardcoded_edid(rdev); | 746 | if (rdev->is_atom_bios) { |
| 747 | /* some laptops provide a hardcoded edid in rom for LCDs */ | ||
| 748 | if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) || | ||
| 749 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP))) | ||
| 750 | radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); | ||
| 751 | } else | ||
| 752 | /* some servers provide a hardcoded edid in rom for KVMs */ | ||
| 753 | radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); | ||
| 754 | } | ||
| 423 | if (radeon_connector->edid) { | 755 | if (radeon_connector->edid) { |
| 424 | drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); | 756 | drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); |
| 425 | ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); | 757 | ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); |
| @@ -849,7 +1181,10 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
| 849 | 1181 | ||
| 850 | rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs; | 1182 | rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs; |
| 851 | 1183 | ||
| 852 | if (ASIC_IS_AVIVO(rdev)) { | 1184 | if (ASIC_IS_DCE5(rdev)) { |
| 1185 | rdev->ddev->mode_config.max_width = 16384; | ||
| 1186 | rdev->ddev->mode_config.max_height = 16384; | ||
| 1187 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
| 853 | rdev->ddev->mode_config.max_width = 8192; | 1188 | rdev->ddev->mode_config.max_width = 8192; |
| 854 | rdev->ddev->mode_config.max_height = 8192; | 1189 | rdev->ddev->mode_config.max_height = 8192; |
| 855 | } else { | 1190 | } else { |
| @@ -1019,7 +1354,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
| 1019 | /* | 1354 | /* |
| 1020 | * Retrieve current video scanout position of crtc on a given gpu. | 1355 | * Retrieve current video scanout position of crtc on a given gpu. |
| 1021 | * | 1356 | * |
| 1022 | * \param rdev Device to query. | 1357 | * \param dev Device to query. |
| 1023 | * \param crtc Crtc to query. | 1358 | * \param crtc Crtc to query. |
| 1024 | * \param *vpos Location where vertical scanout position should be stored. | 1359 | * \param *vpos Location where vertical scanout position should be stored. |
| 1025 | * \param *hpos Location where horizontal scanout position should go. | 1360 | * \param *hpos Location where horizontal scanout position should go. |
| @@ -1031,72 +1366,74 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
| 1031 | * | 1366 | * |
| 1032 | * \return Flags, or'ed together as follows: | 1367 | * \return Flags, or'ed together as follows: |
| 1033 | * | 1368 | * |
| 1034 | * RADEON_SCANOUTPOS_VALID = Query successfull. | 1369 | * DRM_SCANOUTPOS_VALID = Query successfull. |
| 1035 | * RADEON_SCANOUTPOS_INVBL = Inside vblank. | 1370 | * DRM_SCANOUTPOS_INVBL = Inside vblank. |
| 1036 | * RADEON_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of | 1371 | * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of |
| 1037 | * this flag means that returned position may be offset by a constant but | 1372 | * this flag means that returned position may be offset by a constant but |
| 1038 | * unknown small number of scanlines wrt. real scanout position. | 1373 | * unknown small number of scanlines wrt. real scanout position. |
| 1039 | * | 1374 | * |
| 1040 | */ | 1375 | */ |
| 1041 | int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, int *hpos) | 1376 | int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos) |
| 1042 | { | 1377 | { |
| 1043 | u32 stat_crtc = 0, vbl = 0, position = 0; | 1378 | u32 stat_crtc = 0, vbl = 0, position = 0; |
| 1044 | int vbl_start, vbl_end, vtotal, ret = 0; | 1379 | int vbl_start, vbl_end, vtotal, ret = 0; |
| 1045 | bool in_vbl = true; | 1380 | bool in_vbl = true; |
| 1046 | 1381 | ||
| 1382 | struct radeon_device *rdev = dev->dev_private; | ||
| 1383 | |||
| 1047 | if (ASIC_IS_DCE4(rdev)) { | 1384 | if (ASIC_IS_DCE4(rdev)) { |
| 1048 | if (crtc == 0) { | 1385 | if (crtc == 0) { |
| 1049 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1386 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
| 1050 | EVERGREEN_CRTC0_REGISTER_OFFSET); | 1387 | EVERGREEN_CRTC0_REGISTER_OFFSET); |
| 1051 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1388 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
| 1052 | EVERGREEN_CRTC0_REGISTER_OFFSET); | 1389 | EVERGREEN_CRTC0_REGISTER_OFFSET); |
| 1053 | ret |= RADEON_SCANOUTPOS_VALID; | 1390 | ret |= DRM_SCANOUTPOS_VALID; |
| 1054 | } | 1391 | } |
| 1055 | if (crtc == 1) { | 1392 | if (crtc == 1) { |
| 1056 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1393 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
| 1057 | EVERGREEN_CRTC1_REGISTER_OFFSET); | 1394 | EVERGREEN_CRTC1_REGISTER_OFFSET); |
| 1058 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1395 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
| 1059 | EVERGREEN_CRTC1_REGISTER_OFFSET); | 1396 | EVERGREEN_CRTC1_REGISTER_OFFSET); |
| 1060 | ret |= RADEON_SCANOUTPOS_VALID; | 1397 | ret |= DRM_SCANOUTPOS_VALID; |
| 1061 | } | 1398 | } |
| 1062 | if (crtc == 2) { | 1399 | if (crtc == 2) { |
| 1063 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1400 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
| 1064 | EVERGREEN_CRTC2_REGISTER_OFFSET); | 1401 | EVERGREEN_CRTC2_REGISTER_OFFSET); |
| 1065 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1402 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
| 1066 | EVERGREEN_CRTC2_REGISTER_OFFSET); | 1403 | EVERGREEN_CRTC2_REGISTER_OFFSET); |
| 1067 | ret |= RADEON_SCANOUTPOS_VALID; | 1404 | ret |= DRM_SCANOUTPOS_VALID; |
| 1068 | } | 1405 | } |
| 1069 | if (crtc == 3) { | 1406 | if (crtc == 3) { |
| 1070 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1407 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
| 1071 | EVERGREEN_CRTC3_REGISTER_OFFSET); | 1408 | EVERGREEN_CRTC3_REGISTER_OFFSET); |
| 1072 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1409 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
| 1073 | EVERGREEN_CRTC3_REGISTER_OFFSET); | 1410 | EVERGREEN_CRTC3_REGISTER_OFFSET); |
| 1074 | ret |= RADEON_SCANOUTPOS_VALID; | 1411 | ret |= DRM_SCANOUTPOS_VALID; |
| 1075 | } | 1412 | } |
| 1076 | if (crtc == 4) { | 1413 | if (crtc == 4) { |
| 1077 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1414 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
| 1078 | EVERGREEN_CRTC4_REGISTER_OFFSET); | 1415 | EVERGREEN_CRTC4_REGISTER_OFFSET); |
| 1079 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1416 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
| 1080 | EVERGREEN_CRTC4_REGISTER_OFFSET); | 1417 | EVERGREEN_CRTC4_REGISTER_OFFSET); |
| 1081 | ret |= RADEON_SCANOUTPOS_VALID; | 1418 | ret |= DRM_SCANOUTPOS_VALID; |
| 1082 | } | 1419 | } |
| 1083 | if (crtc == 5) { | 1420 | if (crtc == 5) { |
| 1084 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1421 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
| 1085 | EVERGREEN_CRTC5_REGISTER_OFFSET); | 1422 | EVERGREEN_CRTC5_REGISTER_OFFSET); |
| 1086 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1423 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
| 1087 | EVERGREEN_CRTC5_REGISTER_OFFSET); | 1424 | EVERGREEN_CRTC5_REGISTER_OFFSET); |
| 1088 | ret |= RADEON_SCANOUTPOS_VALID; | 1425 | ret |= DRM_SCANOUTPOS_VALID; |
| 1089 | } | 1426 | } |
| 1090 | } else if (ASIC_IS_AVIVO(rdev)) { | 1427 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 1091 | if (crtc == 0) { | 1428 | if (crtc == 0) { |
| 1092 | vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); | 1429 | vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); |
| 1093 | position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); | 1430 | position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); |
| 1094 | ret |= RADEON_SCANOUTPOS_VALID; | 1431 | ret |= DRM_SCANOUTPOS_VALID; |
| 1095 | } | 1432 | } |
| 1096 | if (crtc == 1) { | 1433 | if (crtc == 1) { |
| 1097 | vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); | 1434 | vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); |
| 1098 | position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); | 1435 | position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); |
| 1099 | ret |= RADEON_SCANOUTPOS_VALID; | 1436 | ret |= DRM_SCANOUTPOS_VALID; |
| 1100 | } | 1437 | } |
| 1101 | } else { | 1438 | } else { |
| 1102 | /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ | 1439 | /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ |
| @@ -1112,7 +1449,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
| 1112 | if (!(stat_crtc & 1)) | 1449 | if (!(stat_crtc & 1)) |
| 1113 | in_vbl = false; | 1450 | in_vbl = false; |
| 1114 | 1451 | ||
| 1115 | ret |= RADEON_SCANOUTPOS_VALID; | 1452 | ret |= DRM_SCANOUTPOS_VALID; |
| 1116 | } | 1453 | } |
| 1117 | if (crtc == 1) { | 1454 | if (crtc == 1) { |
| 1118 | vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & | 1455 | vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & |
| @@ -1122,7 +1459,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
| 1122 | if (!(stat_crtc & 1)) | 1459 | if (!(stat_crtc & 1)) |
| 1123 | in_vbl = false; | 1460 | in_vbl = false; |
| 1124 | 1461 | ||
| 1125 | ret |= RADEON_SCANOUTPOS_VALID; | 1462 | ret |= DRM_SCANOUTPOS_VALID; |
| 1126 | } | 1463 | } |
| 1127 | } | 1464 | } |
| 1128 | 1465 | ||
| @@ -1133,13 +1470,13 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
| 1133 | /* Valid vblank area boundaries from gpu retrieved? */ | 1470 | /* Valid vblank area boundaries from gpu retrieved? */ |
| 1134 | if (vbl > 0) { | 1471 | if (vbl > 0) { |
| 1135 | /* Yes: Decode. */ | 1472 | /* Yes: Decode. */ |
| 1136 | ret |= RADEON_SCANOUTPOS_ACCURATE; | 1473 | ret |= DRM_SCANOUTPOS_ACCURATE; |
| 1137 | vbl_start = vbl & 0x1fff; | 1474 | vbl_start = vbl & 0x1fff; |
| 1138 | vbl_end = (vbl >> 16) & 0x1fff; | 1475 | vbl_end = (vbl >> 16) & 0x1fff; |
| 1139 | } | 1476 | } |
| 1140 | else { | 1477 | else { |
| 1141 | /* No: Fake something reasonable which gives at least ok results. */ | 1478 | /* No: Fake something reasonable which gives at least ok results. */ |
| 1142 | vbl_start = rdev->mode_info.crtcs[crtc]->base.mode.crtc_vdisplay; | 1479 | vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; |
| 1143 | vbl_end = 0; | 1480 | vbl_end = 0; |
| 1144 | } | 1481 | } |
| 1145 | 1482 | ||
| @@ -1155,7 +1492,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
| 1155 | 1492 | ||
| 1156 | /* Inside "upper part" of vblank area? Apply corrective offset if so: */ | 1493 | /* Inside "upper part" of vblank area? Apply corrective offset if so: */ |
| 1157 | if (in_vbl && (*vpos >= vbl_start)) { | 1494 | if (in_vbl && (*vpos >= vbl_start)) { |
| 1158 | vtotal = rdev->mode_info.crtcs[crtc]->base.mode.crtc_vtotal; | 1495 | vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; |
| 1159 | *vpos = *vpos - vtotal; | 1496 | *vpos = *vpos - vtotal; |
| 1160 | } | 1497 | } |
| 1161 | 1498 | ||
| @@ -1164,7 +1501,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
| 1164 | 1501 | ||
| 1165 | /* In vblank? */ | 1502 | /* In vblank? */ |
| 1166 | if (in_vbl) | 1503 | if (in_vbl) |
| 1167 | ret |= RADEON_SCANOUTPOS_INVBL; | 1504 | ret |= DRM_SCANOUTPOS_INVBL; |
| 1168 | 1505 | ||
| 1169 | return ret; | 1506 | return ret; |
| 1170 | } | 1507 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 60e689f2d048..be5cb4f28c29 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -48,9 +48,10 @@ | |||
| 48 | * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen | 48 | * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen |
| 49 | * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) | 49 | * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) |
| 50 | * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs | 50 | * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs |
| 51 | * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK | ||
| 51 | */ | 52 | */ |
| 52 | #define KMS_DRIVER_MAJOR 2 | 53 | #define KMS_DRIVER_MAJOR 2 |
| 53 | #define KMS_DRIVER_MINOR 7 | 54 | #define KMS_DRIVER_MINOR 8 |
| 54 | #define KMS_DRIVER_PATCHLEVEL 0 | 55 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 55 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 56 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
| 56 | int radeon_driver_unload_kms(struct drm_device *dev); | 57 | int radeon_driver_unload_kms(struct drm_device *dev); |
| @@ -66,6 +67,10 @@ int radeon_resume_kms(struct drm_device *dev); | |||
| 66 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); | 67 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); |
| 67 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); | 68 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); |
| 68 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); | 69 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); |
| 70 | int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, | ||
| 71 | int *max_error, | ||
| 72 | struct timeval *vblank_time, | ||
| 73 | unsigned flags); | ||
| 69 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev); | 74 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev); |
| 70 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev); | 75 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev); |
| 71 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev); | 76 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev); |
| @@ -74,6 +79,8 @@ int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, | |||
| 74 | struct drm_file *file_priv); | 79 | struct drm_file *file_priv); |
| 75 | int radeon_gem_object_init(struct drm_gem_object *obj); | 80 | int radeon_gem_object_init(struct drm_gem_object *obj); |
| 76 | void radeon_gem_object_free(struct drm_gem_object *obj); | 81 | void radeon_gem_object_free(struct drm_gem_object *obj); |
| 82 | extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, | ||
| 83 | int *vpos, int *hpos); | ||
| 77 | extern struct drm_ioctl_desc radeon_ioctls_kms[]; | 84 | extern struct drm_ioctl_desc radeon_ioctls_kms[]; |
| 78 | extern int radeon_max_kms_ioctl; | 85 | extern int radeon_max_kms_ioctl; |
| 79 | int radeon_mmap(struct file *filp, struct vm_area_struct *vma); | 86 | int radeon_mmap(struct file *filp, struct vm_area_struct *vma); |
| @@ -296,6 +303,8 @@ static struct drm_driver kms_driver = { | |||
| 296 | .get_vblank_counter = radeon_get_vblank_counter_kms, | 303 | .get_vblank_counter = radeon_get_vblank_counter_kms, |
| 297 | .enable_vblank = radeon_enable_vblank_kms, | 304 | .enable_vblank = radeon_enable_vblank_kms, |
| 298 | .disable_vblank = radeon_disable_vblank_kms, | 305 | .disable_vblank = radeon_disable_vblank_kms, |
| 306 | .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, | ||
| 307 | .get_scanout_position = radeon_get_crtc_scanoutpos, | ||
| 299 | #if defined(CONFIG_DEBUG_FS) | 308 | #if defined(CONFIG_DEBUG_FS) |
| 300 | .debugfs_init = radeon_debugfs_init, | 309 | .debugfs_init = radeon_debugfs_init, |
| 301 | .debugfs_cleanup = radeon_debugfs_cleanup, | 310 | .debugfs_cleanup = radeon_debugfs_cleanup, |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 041943df966b..8fd184286c0b 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -641,7 +641,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 641 | switch (connector->connector_type) { | 641 | switch (connector->connector_type) { |
| 642 | case DRM_MODE_CONNECTOR_DVII: | 642 | case DRM_MODE_CONNECTOR_DVII: |
| 643 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 643 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
| 644 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { | 644 | if (drm_detect_monitor_audio(radeon_connector->edid)) { |
| 645 | /* fix me */ | 645 | /* fix me */ |
| 646 | if (ASIC_IS_DCE4(rdev)) | 646 | if (ASIC_IS_DCE4(rdev)) |
| 647 | return ATOM_ENCODER_MODE_DVI; | 647 | return ATOM_ENCODER_MODE_DVI; |
| @@ -655,7 +655,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 655 | case DRM_MODE_CONNECTOR_DVID: | 655 | case DRM_MODE_CONNECTOR_DVID: |
| 656 | case DRM_MODE_CONNECTOR_HDMIA: | 656 | case DRM_MODE_CONNECTOR_HDMIA: |
| 657 | default: | 657 | default: |
| 658 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { | 658 | if (drm_detect_monitor_audio(radeon_connector->edid)) { |
| 659 | /* fix me */ | 659 | /* fix me */ |
| 660 | if (ASIC_IS_DCE4(rdev)) | 660 | if (ASIC_IS_DCE4(rdev)) |
| 661 | return ATOM_ENCODER_MODE_DVI; | 661 | return ATOM_ENCODER_MODE_DVI; |
| @@ -673,7 +673,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 673 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 673 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
| 674 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 674 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
| 675 | return ATOM_ENCODER_MODE_DP; | 675 | return ATOM_ENCODER_MODE_DP; |
| 676 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) { | 676 | else if (drm_detect_monitor_audio(radeon_connector->edid)) { |
| 677 | /* fix me */ | 677 | /* fix me */ |
| 678 | if (ASIC_IS_DCE4(rdev)) | 678 | if (ASIC_IS_DCE4(rdev)) |
| 679 | return ATOM_ENCODER_MODE_DVI; | 679 | return ATOM_ENCODER_MODE_DVI; |
| @@ -712,8 +712,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 712 | * - 2 DIG encoder blocks. | 712 | * - 2 DIG encoder blocks. |
| 713 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | 713 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B |
| 714 | * | 714 | * |
| 715 | * DCE 4.0 | 715 | * DCE 4.0/5.0 |
| 716 | * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). | 716 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). |
| 717 | * Supports up to 6 digital outputs | 717 | * Supports up to 6 digital outputs |
| 718 | * - 6 DIG encoder blocks. | 718 | * - 6 DIG encoder blocks. |
| 719 | * - DIG to PHY mapping is hardcoded | 719 | * - DIG to PHY mapping is hardcoded |
| @@ -724,6 +724,12 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 724 | * DIG5 drives UNIPHY2 link A, A+B | 724 | * DIG5 drives UNIPHY2 link A, A+B |
| 725 | * DIG6 drives UNIPHY2 link B | 725 | * DIG6 drives UNIPHY2 link B |
| 726 | * | 726 | * |
| 727 | * DCE 4.1 | ||
| 728 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
| 729 | * Supports up to 6 digital outputs | ||
| 730 | * - 2 DIG encoder blocks. | ||
| 731 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
| 732 | * | ||
| 727 | * Routing | 733 | * Routing |
| 728 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | 734 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) |
| 729 | * Examples: | 735 | * Examples: |
| @@ -737,6 +743,7 @@ union dig_encoder_control { | |||
| 737 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | 743 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; |
| 738 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | 744 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; |
| 739 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | 745 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; |
| 746 | DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; | ||
| 740 | }; | 747 | }; |
| 741 | 748 | ||
| 742 | void | 749 | void |
| @@ -752,6 +759,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 752 | uint8_t frev, crev; | 759 | uint8_t frev, crev; |
| 753 | int dp_clock = 0; | 760 | int dp_clock = 0; |
| 754 | int dp_lane_count = 0; | 761 | int dp_lane_count = 0; |
| 762 | int hpd_id = RADEON_HPD_NONE; | ||
| 755 | 763 | ||
| 756 | if (connector) { | 764 | if (connector) { |
| 757 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 765 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| @@ -760,6 +768,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 760 | 768 | ||
| 761 | dp_clock = dig_connector->dp_clock; | 769 | dp_clock = dig_connector->dp_clock; |
| 762 | dp_lane_count = dig_connector->dp_lane_count; | 770 | dp_lane_count = dig_connector->dp_lane_count; |
| 771 | hpd_id = radeon_connector->hpd.hpd; | ||
| 763 | } | 772 | } |
| 764 | 773 | ||
| 765 | /* no dig encoder assigned */ | 774 | /* no dig encoder assigned */ |
| @@ -784,19 +793,36 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 784 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 793 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| 785 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | 794 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); |
| 786 | 795 | ||
| 787 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | 796 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || |
| 788 | if (dp_clock == 270000) | 797 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) |
| 789 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
| 790 | args.v1.ucLaneNum = dp_lane_count; | 798 | args.v1.ucLaneNum = dp_lane_count; |
| 791 | } else if (radeon_encoder->pixel_clock > 165000) | 799 | else if (radeon_encoder->pixel_clock > 165000) |
| 792 | args.v1.ucLaneNum = 8; | 800 | args.v1.ucLaneNum = 8; |
| 793 | else | 801 | else |
| 794 | args.v1.ucLaneNum = 4; | 802 | args.v1.ucLaneNum = 4; |
| 795 | 803 | ||
| 796 | if (ASIC_IS_DCE4(rdev)) { | 804 | if (ASIC_IS_DCE5(rdev)) { |
| 805 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || | ||
| 806 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) { | ||
| 807 | if (dp_clock == 270000) | ||
| 808 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; | ||
| 809 | else if (dp_clock == 540000) | ||
| 810 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | ||
| 811 | } | ||
| 812 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | ||
| 813 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 814 | if (hpd_id == RADEON_HPD_NONE) | ||
| 815 | args.v4.ucHPD_ID = 0; | ||
| 816 | else | ||
| 817 | args.v4.ucHPD_ID = hpd_id + 1; | ||
| 818 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 819 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | ||
| 820 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
| 797 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | 821 | args.v3.acConfig.ucDigSel = dig->dig_encoder; |
| 798 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | 822 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; |
| 799 | } else { | 823 | } else { |
| 824 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | ||
| 825 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
| 800 | switch (radeon_encoder->encoder_id) { | 826 | switch (radeon_encoder->encoder_id) { |
| 801 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 827 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| 802 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | 828 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; |
| @@ -823,6 +849,7 @@ union dig_transmitter_control { | |||
| 823 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | 849 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; |
| 824 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | 850 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
| 825 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | 851 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; |
| 852 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; | ||
| 826 | }; | 853 | }; |
| 827 | 854 | ||
| 828 | void | 855 | void |
| @@ -917,10 +944,18 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 917 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 944 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
| 918 | pll_id = radeon_crtc->pll_id; | 945 | pll_id = radeon_crtc->pll_id; |
| 919 | } | 946 | } |
| 920 | if (is_dp && rdev->clock.dp_extclk) | 947 | |
| 921 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | 948 | if (ASIC_IS_DCE5(rdev)) { |
| 922 | else | 949 | if (is_dp && rdev->clock.dp_extclk) |
| 923 | args.v3.acConfig.ucRefClkSource = pll_id; | 950 | args.v4.acConfig.ucRefClkSource = 3; /* external src */ |
| 951 | else | ||
| 952 | args.v4.acConfig.ucRefClkSource = pll_id; | ||
| 953 | } else { | ||
| 954 | if (is_dp && rdev->clock.dp_extclk) | ||
| 955 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
| 956 | else | ||
| 957 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
| 958 | } | ||
| 924 | 959 | ||
| 925 | switch (radeon_encoder->encoder_id) { | 960 | switch (radeon_encoder->encoder_id) { |
| 926 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 961 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| @@ -1044,6 +1079,7 @@ atombios_set_edp_panel_power(struct drm_connector *connector, int action) | |||
| 1044 | 1079 | ||
| 1045 | union external_encoder_control { | 1080 | union external_encoder_control { |
| 1046 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; | 1081 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; |
| 1082 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3; | ||
| 1047 | }; | 1083 | }; |
| 1048 | 1084 | ||
| 1049 | static void | 1085 | static void |
| @@ -1054,6 +1090,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1054 | struct drm_device *dev = encoder->dev; | 1090 | struct drm_device *dev = encoder->dev; |
| 1055 | struct radeon_device *rdev = dev->dev_private; | 1091 | struct radeon_device *rdev = dev->dev_private; |
| 1056 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1092 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1093 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | ||
| 1057 | union external_encoder_control args; | 1094 | union external_encoder_control args; |
| 1058 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1095 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 1059 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); | 1096 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); |
| @@ -1061,6 +1098,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1061 | int dp_clock = 0; | 1098 | int dp_clock = 0; |
| 1062 | int dp_lane_count = 0; | 1099 | int dp_lane_count = 0; |
| 1063 | int connector_object_id = 0; | 1100 | int connector_object_id = 0; |
| 1101 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
| 1064 | 1102 | ||
| 1065 | if (connector) { | 1103 | if (connector) { |
| 1066 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1104 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| @@ -1099,6 +1137,37 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1099 | else | 1137 | else |
| 1100 | args.v1.sDigEncoder.ucLaneNum = 4; | 1138 | args.v1.sDigEncoder.ucLaneNum = 4; |
| 1101 | break; | 1139 | break; |
| 1140 | case 3: | ||
| 1141 | args.v3.sExtEncoder.ucAction = action; | ||
| 1142 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
| 1143 | args.v3.sExtEncoder.usConnectorId = connector_object_id; | ||
| 1144 | else | ||
| 1145 | args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 1146 | args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 1147 | |||
| 1148 | if (args.v3.sExtEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
| 1149 | if (dp_clock == 270000) | ||
| 1150 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
| 1151 | else if (dp_clock == 540000) | ||
| 1152 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | ||
| 1153 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | ||
| 1154 | } else if (radeon_encoder->pixel_clock > 165000) | ||
| 1155 | args.v3.sExtEncoder.ucLaneNum = 8; | ||
| 1156 | else | ||
| 1157 | args.v3.sExtEncoder.ucLaneNum = 4; | ||
| 1158 | switch (ext_enum) { | ||
| 1159 | case GRAPH_OBJECT_ENUM_ID1: | ||
| 1160 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1; | ||
| 1161 | break; | ||
| 1162 | case GRAPH_OBJECT_ENUM_ID2: | ||
| 1163 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2; | ||
| 1164 | break; | ||
| 1165 | case GRAPH_OBJECT_ENUM_ID3: | ||
| 1166 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | ||
| 1167 | break; | ||
| 1168 | } | ||
| 1169 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 1170 | break; | ||
| 1102 | default: | 1171 | default: |
| 1103 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | 1172 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); |
| 1104 | return; | 1173 | return; |
| @@ -1158,6 +1227,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1158 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | 1227 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; |
| 1159 | int index = 0; | 1228 | int index = 0; |
| 1160 | bool is_dig = false; | 1229 | bool is_dig = false; |
| 1230 | bool is_dce5_dac = false; | ||
| 1231 | bool is_dce5_dvo = false; | ||
| 1161 | 1232 | ||
| 1162 | memset(&args, 0, sizeof(args)); | 1233 | memset(&args, 0, sizeof(args)); |
| 1163 | 1234 | ||
| @@ -1180,7 +1251,9 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1180 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | 1251 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); |
| 1181 | break; | 1252 | break; |
| 1182 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1253 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
| 1183 | if (ASIC_IS_DCE3(rdev)) | 1254 | if (ASIC_IS_DCE5(rdev)) |
| 1255 | is_dce5_dvo = true; | ||
| 1256 | else if (ASIC_IS_DCE3(rdev)) | ||
| 1184 | is_dig = true; | 1257 | is_dig = true; |
| 1185 | else | 1258 | else |
| 1186 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | 1259 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); |
| @@ -1196,12 +1269,16 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1196 | break; | 1269 | break; |
| 1197 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 1270 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
| 1198 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1271 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
| 1199 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | 1272 | if (ASIC_IS_DCE5(rdev)) |
| 1200 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | 1273 | is_dce5_dac = true; |
| 1201 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | 1274 | else { |
| 1202 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | 1275 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
| 1203 | else | 1276 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
| 1204 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | 1277 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
| 1278 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
| 1279 | else | ||
| 1280 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | ||
| 1281 | } | ||
| 1205 | break; | 1282 | break; |
| 1206 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 1283 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
| 1207 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 1284 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
| @@ -1260,6 +1337,28 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1260 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); | 1337 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); |
| 1261 | break; | 1338 | break; |
| 1262 | } | 1339 | } |
| 1340 | } else if (is_dce5_dac) { | ||
| 1341 | switch (mode) { | ||
| 1342 | case DRM_MODE_DPMS_ON: | ||
| 1343 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
| 1344 | break; | ||
| 1345 | case DRM_MODE_DPMS_STANDBY: | ||
| 1346 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1347 | case DRM_MODE_DPMS_OFF: | ||
| 1348 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
| 1349 | break; | ||
| 1350 | } | ||
| 1351 | } else if (is_dce5_dvo) { | ||
| 1352 | switch (mode) { | ||
| 1353 | case DRM_MODE_DPMS_ON: | ||
| 1354 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
| 1355 | break; | ||
| 1356 | case DRM_MODE_DPMS_STANDBY: | ||
| 1357 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1358 | case DRM_MODE_DPMS_OFF: | ||
| 1359 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
| 1360 | break; | ||
| 1361 | } | ||
| 1263 | } else { | 1362 | } else { |
| 1264 | switch (mode) { | 1363 | switch (mode) { |
| 1265 | case DRM_MODE_DPMS_ON: | 1364 | case DRM_MODE_DPMS_ON: |
| @@ -1289,12 +1388,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1289 | switch (mode) { | 1388 | switch (mode) { |
| 1290 | case DRM_MODE_DPMS_ON: | 1389 | case DRM_MODE_DPMS_ON: |
| 1291 | default: | 1390 | default: |
| 1292 | action = ATOM_ENABLE; | 1391 | if (ASIC_IS_DCE41(rdev)) |
| 1392 | action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT; | ||
| 1393 | else | ||
| 1394 | action = ATOM_ENABLE; | ||
| 1293 | break; | 1395 | break; |
| 1294 | case DRM_MODE_DPMS_STANDBY: | 1396 | case DRM_MODE_DPMS_STANDBY: |
| 1295 | case DRM_MODE_DPMS_SUSPEND: | 1397 | case DRM_MODE_DPMS_SUSPEND: |
| 1296 | case DRM_MODE_DPMS_OFF: | 1398 | case DRM_MODE_DPMS_OFF: |
| 1297 | action = ATOM_DISABLE; | 1399 | if (ASIC_IS_DCE41(rdev)) |
| 1400 | action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT; | ||
| 1401 | else | ||
| 1402 | action = ATOM_DISABLE; | ||
| 1298 | break; | 1403 | break; |
| 1299 | } | 1404 | } |
| 1300 | atombios_external_encoder_setup(encoder, ext_encoder, action); | 1405 | atombios_external_encoder_setup(encoder, ext_encoder, action); |
| @@ -1483,27 +1588,35 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
| 1483 | struct radeon_encoder_atom_dig *dig; | 1588 | struct radeon_encoder_atom_dig *dig; |
| 1484 | uint32_t dig_enc_in_use = 0; | 1589 | uint32_t dig_enc_in_use = 0; |
| 1485 | 1590 | ||
| 1591 | /* DCE4/5 */ | ||
| 1486 | if (ASIC_IS_DCE4(rdev)) { | 1592 | if (ASIC_IS_DCE4(rdev)) { |
| 1487 | dig = radeon_encoder->enc_priv; | 1593 | dig = radeon_encoder->enc_priv; |
| 1488 | switch (radeon_encoder->encoder_id) { | 1594 | if (ASIC_IS_DCE41(rdev)) { |
| 1489 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1490 | if (dig->linkb) | 1595 | if (dig->linkb) |
| 1491 | return 1; | 1596 | return 1; |
| 1492 | else | 1597 | else |
| 1493 | return 0; | 1598 | return 0; |
| 1494 | break; | 1599 | } else { |
| 1495 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1600 | switch (radeon_encoder->encoder_id) { |
| 1496 | if (dig->linkb) | 1601 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| 1497 | return 3; | 1602 | if (dig->linkb) |
| 1498 | else | 1603 | return 1; |
| 1499 | return 2; | 1604 | else |
| 1500 | break; | 1605 | return 0; |
| 1501 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1606 | break; |
| 1502 | if (dig->linkb) | 1607 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 1503 | return 5; | 1608 | if (dig->linkb) |
| 1504 | else | 1609 | return 3; |
| 1505 | return 4; | 1610 | else |
| 1506 | break; | 1611 | return 2; |
| 1612 | break; | ||
| 1613 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1614 | if (dig->linkb) | ||
| 1615 | return 5; | ||
| 1616 | else | ||
| 1617 | return 4; | ||
| 1618 | break; | ||
| 1619 | } | ||
| 1507 | } | 1620 | } |
| 1508 | } | 1621 | } |
| 1509 | 1622 | ||
| @@ -1610,7 +1723,13 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1610 | } | 1723 | } |
| 1611 | 1724 | ||
| 1612 | if (ext_encoder) { | 1725 | if (ext_encoder) { |
| 1613 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | 1726 | if (ASIC_IS_DCE41(rdev)) { |
| 1727 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1728 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); | ||
| 1729 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1730 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
| 1731 | } else | ||
| 1732 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
| 1614 | } | 1733 | } |
| 1615 | 1734 | ||
| 1616 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1735 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
| @@ -1927,7 +2046,10 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | |||
| 1927 | } | 2046 | } |
| 1928 | 2047 | ||
| 1929 | void | 2048 | void |
| 1930 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) | 2049 | radeon_add_atom_encoder(struct drm_device *dev, |
| 2050 | uint32_t encoder_enum, | ||
| 2051 | uint32_t supported_device, | ||
| 2052 | u16 caps) | ||
| 1931 | { | 2053 | { |
| 1932 | struct radeon_device *rdev = dev->dev_private; | 2054 | struct radeon_device *rdev = dev->dev_private; |
| 1933 | struct drm_encoder *encoder; | 2055 | struct drm_encoder *encoder; |
| @@ -1970,6 +2092,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t | |||
| 1970 | radeon_encoder->rmx_type = RMX_OFF; | 2092 | radeon_encoder->rmx_type = RMX_OFF; |
| 1971 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | 2093 | radeon_encoder->underscan_type = UNDERSCAN_OFF; |
| 1972 | radeon_encoder->is_ext_encoder = false; | 2094 | radeon_encoder->is_ext_encoder = false; |
| 2095 | radeon_encoder->caps = caps; | ||
| 1973 | 2096 | ||
| 1974 | switch (radeon_encoder->encoder_id) { | 2097 | switch (radeon_encoder->encoder_id) { |
| 1975 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | 2098 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: |
| @@ -2029,6 +2152,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t | |||
| 2029 | case ENCODER_OBJECT_ID_TITFP513: | 2152 | case ENCODER_OBJECT_ID_TITFP513: |
| 2030 | case ENCODER_OBJECT_ID_VT1623: | 2153 | case ENCODER_OBJECT_ID_VT1623: |
| 2031 | case ENCODER_OBJECT_ID_HDMI_SI1930: | 2154 | case ENCODER_OBJECT_ID_HDMI_SI1930: |
| 2155 | case ENCODER_OBJECT_ID_TRAVIS: | ||
| 2156 | case ENCODER_OBJECT_ID_NUTMEG: | ||
| 2032 | /* these are handled by the primary encoders */ | 2157 | /* these are handled by the primary encoders */ |
| 2033 | radeon_encoder->is_ext_encoder = true; | 2158 | radeon_encoder->is_ext_encoder = true; |
| 2034 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | 2159 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index e329066dcabd..1ca55eb09ad3 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h | |||
| @@ -80,6 +80,10 @@ enum radeon_family { | |||
| 80 | CHIP_JUNIPER, | 80 | CHIP_JUNIPER, |
| 81 | CHIP_CYPRESS, | 81 | CHIP_CYPRESS, |
| 82 | CHIP_HEMLOCK, | 82 | CHIP_HEMLOCK, |
| 83 | CHIP_PALM, | ||
| 84 | CHIP_BARTS, | ||
| 85 | CHIP_TURKS, | ||
| 86 | CHIP_CAICOS, | ||
| 83 | CHIP_LAST, | 87 | CHIP_LAST, |
| 84 | }; | 88 | }; |
| 85 | 89 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 6abea32be5e8..ca32e9c1e91d 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
| @@ -225,8 +225,6 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
| 225 | 225 | ||
| 226 | strcpy(info->fix.id, "radeondrmfb"); | 226 | strcpy(info->fix.id, "radeondrmfb"); |
| 227 | 227 | ||
| 228 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); | ||
| 229 | |||
| 230 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; | 228 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
| 231 | info->fbops = &radeonfb_ops; | 229 | info->fbops = &radeonfb_ops; |
| 232 | 230 | ||
| @@ -247,8 +245,6 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
| 247 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; | 245 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; |
| 248 | info->apertures->ranges[0].size = rdev->mc.aper_size; | 246 | info->apertures->ranges[0].size = rdev->mc.aper_size; |
| 249 | 247 | ||
| 250 | info->fix.mmio_start = 0; | ||
| 251 | info->fix.mmio_len = 0; | ||
| 252 | info->pixmap.size = 64*1024; | 248 | info->pixmap.size = 64*1024; |
| 253 | info->pixmap.buf_align = 8; | 249 | info->pixmap.buf_align = 8; |
| 254 | info->pixmap.access_align = 32; | 250 | info->pixmap.access_align = 32; |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index daacb281dfaf..171b0b2e3a64 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "drm.h" | 38 | #include "drm.h" |
| 39 | #include "radeon_reg.h" | 39 | #include "radeon_reg.h" |
| 40 | #include "radeon.h" | 40 | #include "radeon.h" |
| 41 | #include "radeon_trace.h" | ||
| 41 | 42 | ||
| 42 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) | 43 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) |
| 43 | { | 44 | { |
| @@ -57,6 +58,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) | |||
| 57 | } else | 58 | } else |
| 58 | radeon_fence_ring_emit(rdev, fence); | 59 | radeon_fence_ring_emit(rdev, fence); |
| 59 | 60 | ||
| 61 | trace_radeon_fence_emit(rdev->ddev, fence->seq); | ||
| 60 | fence->emited = true; | 62 | fence->emited = true; |
| 61 | list_del(&fence->list); | 63 | list_del(&fence->list); |
| 62 | list_add_tail(&fence->list, &rdev->fence_drv.emited); | 64 | list_add_tail(&fence->list, &rdev->fence_drv.emited); |
| @@ -213,6 +215,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) | |||
| 213 | retry: | 215 | retry: |
| 214 | /* save current sequence used to check for GPU lockup */ | 216 | /* save current sequence used to check for GPU lockup */ |
| 215 | seq = rdev->fence_drv.last_seq; | 217 | seq = rdev->fence_drv.last_seq; |
| 218 | trace_radeon_fence_wait_begin(rdev->ddev, seq); | ||
| 216 | if (intr) { | 219 | if (intr) { |
| 217 | radeon_irq_kms_sw_irq_get(rdev); | 220 | radeon_irq_kms_sw_irq_get(rdev); |
| 218 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, | 221 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
| @@ -227,6 +230,7 @@ retry: | |||
| 227 | radeon_fence_signaled(fence), timeout); | 230 | radeon_fence_signaled(fence), timeout); |
| 228 | radeon_irq_kms_sw_irq_put(rdev); | 231 | radeon_irq_kms_sw_irq_put(rdev); |
| 229 | } | 232 | } |
| 233 | trace_radeon_fence_wait_end(rdev->ddev, seq); | ||
| 230 | if (unlikely(!radeon_fence_signaled(fence))) { | 234 | if (unlikely(!radeon_fence_signaled(fence))) { |
| 231 | /* we were interrupted for some reason and fence isn't | 235 | /* we were interrupted for some reason and fence isn't |
| 232 | * isn't signaled yet, resume wait | 236 | * isn't signaled yet, resume wait |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index a108c7ed14f5..a289646e8aa4 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -64,15 +64,15 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | |||
| 64 | struct radeon_device *rdev = dev->dev_private; | 64 | struct radeon_device *rdev = dev->dev_private; |
| 65 | unsigned i; | 65 | unsigned i; |
| 66 | 66 | ||
| 67 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | ||
| 68 | |||
| 69 | /* Disable *all* interrupts */ | 67 | /* Disable *all* interrupts */ |
| 70 | rdev->irq.sw_int = false; | 68 | rdev->irq.sw_int = false; |
| 71 | rdev->irq.gui_idle = false; | 69 | rdev->irq.gui_idle = false; |
| 72 | for (i = 0; i < rdev->num_crtc; i++) | 70 | for (i = 0; i < rdev->num_crtc; i++) |
| 73 | rdev->irq.crtc_vblank_int[i] = false; | 71 | rdev->irq.crtc_vblank_int[i] = false; |
| 74 | for (i = 0; i < 6; i++) | 72 | for (i = 0; i < 6; i++) { |
| 75 | rdev->irq.hpd[i] = false; | 73 | rdev->irq.hpd[i] = false; |
| 74 | rdev->irq.pflip[i] = false; | ||
| 75 | } | ||
| 76 | radeon_irq_set(rdev); | 76 | radeon_irq_set(rdev); |
| 77 | /* Clear bits */ | 77 | /* Clear bits */ |
| 78 | radeon_irq_process(rdev); | 78 | radeon_irq_process(rdev); |
| @@ -101,8 +101,10 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | |||
| 101 | rdev->irq.gui_idle = false; | 101 | rdev->irq.gui_idle = false; |
| 102 | for (i = 0; i < rdev->num_crtc; i++) | 102 | for (i = 0; i < rdev->num_crtc; i++) |
| 103 | rdev->irq.crtc_vblank_int[i] = false; | 103 | rdev->irq.crtc_vblank_int[i] = false; |
| 104 | for (i = 0; i < 6; i++) | 104 | for (i = 0; i < 6; i++) { |
| 105 | rdev->irq.hpd[i] = false; | 105 | rdev->irq.hpd[i] = false; |
| 106 | rdev->irq.pflip[i] = false; | ||
| 107 | } | ||
| 106 | radeon_irq_set(rdev); | 108 | radeon_irq_set(rdev); |
| 107 | } | 109 | } |
| 108 | 110 | ||
| @@ -110,6 +112,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
| 110 | { | 112 | { |
| 111 | int r = 0; | 113 | int r = 0; |
| 112 | 114 | ||
| 115 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | ||
| 116 | |||
| 113 | spin_lock_init(&rdev->irq.sw_lock); | 117 | spin_lock_init(&rdev->irq.sw_lock); |
| 114 | r = drm_vblank_init(rdev->ddev, rdev->num_crtc); | 118 | r = drm_vblank_init(rdev->ddev, rdev->num_crtc); |
| 115 | if (r) { | 119 | if (r) { |
| @@ -121,7 +125,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
| 121 | * chips. Disable MSI on them for now. | 125 | * chips. Disable MSI on them for now. |
| 122 | */ | 126 | */ |
| 123 | if ((rdev->family >= CHIP_RV380) && | 127 | if ((rdev->family >= CHIP_RV380) && |
| 124 | (!(rdev->flags & RADEON_IS_IGP)) && | 128 | ((!(rdev->flags & RADEON_IS_IGP)) || (rdev->family >= CHIP_PALM)) && |
| 125 | (!(rdev->flags & RADEON_IS_AGP))) { | 129 | (!(rdev->flags & RADEON_IS_AGP))) { |
| 126 | int ret = pci_enable_msi(rdev->pdev); | 130 | int ret = pci_enable_msi(rdev->pdev); |
| 127 | if (!ret) { | 131 | if (!ret) { |
| @@ -148,6 +152,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) | |||
| 148 | if (rdev->msi_enabled) | 152 | if (rdev->msi_enabled) |
| 149 | pci_disable_msi(rdev->pdev); | 153 | pci_disable_msi(rdev->pdev); |
| 150 | } | 154 | } |
| 155 | flush_work_sync(&rdev->hotplug_work); | ||
| 151 | } | 156 | } |
| 152 | 157 | ||
| 153 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev) | 158 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev) |
| @@ -175,3 +180,34 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev) | |||
| 175 | spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); | 180 | spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); |
| 176 | } | 181 | } |
| 177 | 182 | ||
| 183 | void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) | ||
| 184 | { | ||
| 185 | unsigned long irqflags; | ||
| 186 | |||
| 187 | if (crtc < 0 || crtc >= rdev->num_crtc) | ||
| 188 | return; | ||
| 189 | |||
| 190 | spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); | ||
| 191 | if (rdev->ddev->irq_enabled && (++rdev->irq.pflip_refcount[crtc] == 1)) { | ||
| 192 | rdev->irq.pflip[crtc] = true; | ||
| 193 | radeon_irq_set(rdev); | ||
| 194 | } | ||
| 195 | spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); | ||
| 196 | } | ||
| 197 | |||
| 198 | void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) | ||
| 199 | { | ||
| 200 | unsigned long irqflags; | ||
| 201 | |||
| 202 | if (crtc < 0 || crtc >= rdev->num_crtc) | ||
| 203 | return; | ||
| 204 | |||
| 205 | spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); | ||
| 206 | BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); | ||
| 207 | if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == 0)) { | ||
| 208 | rdev->irq.pflip[crtc] = false; | ||
| 209 | radeon_irq_set(rdev); | ||
| 210 | } | ||
| 211 | spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); | ||
| 212 | } | ||
| 213 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 8fbbe1c6ebbd..28a53e4a925f 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -96,9 +96,27 @@ out: | |||
| 96 | return r; | 96 | return r; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static void radeon_set_filp_rights(struct drm_device *dev, | ||
| 100 | struct drm_file **owner, | ||
| 101 | struct drm_file *applier, | ||
| 102 | uint32_t *value) | ||
| 103 | { | ||
| 104 | mutex_lock(&dev->struct_mutex); | ||
| 105 | if (*value == 1) { | ||
| 106 | /* wants rights */ | ||
| 107 | if (!*owner) | ||
| 108 | *owner = applier; | ||
| 109 | } else if (*value == 0) { | ||
| 110 | /* revokes rights */ | ||
| 111 | if (*owner == applier) | ||
| 112 | *owner = NULL; | ||
| 113 | } | ||
| 114 | *value = *owner == applier ? 1 : 0; | ||
| 115 | mutex_unlock(&dev->struct_mutex); | ||
| 116 | } | ||
| 99 | 117 | ||
| 100 | /* | 118 | /* |
| 101 | * Userspace get informations ioctl | 119 | * Userspace get information ioctl |
| 102 | */ | 120 | */ |
| 103 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 121 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
| 104 | { | 122 | { |
| @@ -173,18 +191,15 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 173 | DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value); | 191 | DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value); |
| 174 | return -EINVAL; | 192 | return -EINVAL; |
| 175 | } | 193 | } |
| 176 | mutex_lock(&dev->struct_mutex); | 194 | radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value); |
| 177 | if (value == 1) { | 195 | break; |
| 178 | /* wants hyper-z */ | 196 | case RADEON_INFO_WANT_CMASK: |
| 179 | if (!rdev->hyperz_filp) | 197 | /* The same logic as Hyper-Z. */ |
| 180 | rdev->hyperz_filp = filp; | 198 | if (value >= 2) { |
| 181 | } else if (value == 0) { | 199 | DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", value); |
| 182 | /* revokes hyper-z */ | 200 | return -EINVAL; |
| 183 | if (rdev->hyperz_filp == filp) | ||
| 184 | rdev->hyperz_filp = NULL; | ||
| 185 | } | 201 | } |
| 186 | value = rdev->hyperz_filp == filp ? 1 : 0; | 202 | radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value); |
| 187 | mutex_unlock(&dev->struct_mutex); | ||
| 188 | break; | 203 | break; |
| 189 | default: | 204 | default: |
| 190 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); | 205 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); |
| @@ -203,10 +218,6 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 203 | */ | 218 | */ |
| 204 | int radeon_driver_firstopen_kms(struct drm_device *dev) | 219 | int radeon_driver_firstopen_kms(struct drm_device *dev) |
| 205 | { | 220 | { |
| 206 | struct radeon_device *rdev = dev->dev_private; | ||
| 207 | |||
| 208 | if (rdev->powered_down) | ||
| 209 | return -EINVAL; | ||
| 210 | return 0; | 221 | return 0; |
| 211 | } | 222 | } |
| 212 | 223 | ||
| @@ -277,6 +288,27 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) | |||
| 277 | radeon_irq_set(rdev); | 288 | radeon_irq_set(rdev); |
| 278 | } | 289 | } |
| 279 | 290 | ||
| 291 | int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, | ||
| 292 | int *max_error, | ||
| 293 | struct timeval *vblank_time, | ||
| 294 | unsigned flags) | ||
| 295 | { | ||
| 296 | struct drm_crtc *drmcrtc; | ||
| 297 | struct radeon_device *rdev = dev->dev_private; | ||
| 298 | |||
| 299 | if (crtc < 0 || crtc >= dev->num_crtcs) { | ||
| 300 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
| 301 | return -EINVAL; | ||
| 302 | } | ||
| 303 | |||
| 304 | /* Get associated drm_crtc: */ | ||
| 305 | drmcrtc = &rdev->mode_info.crtcs[crtc]->base; | ||
| 306 | |||
| 307 | /* Helper routine in DRM core does all the work: */ | ||
| 308 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, | ||
| 309 | vblank_time, flags, | ||
| 310 | drmcrtc); | ||
| 311 | } | ||
| 280 | 312 | ||
| 281 | /* | 313 | /* |
| 282 | * IOCTL. | 314 | * IOCTL. |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index e301c6f9e059..12bdeab91c86 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -277,6 +277,9 @@ struct radeon_crtc { | |||
| 277 | fixed20_12 hsc; | 277 | fixed20_12 hsc; |
| 278 | struct drm_display_mode native_mode; | 278 | struct drm_display_mode native_mode; |
| 279 | int pll_id; | 279 | int pll_id; |
| 280 | /* page flipping */ | ||
| 281 | struct radeon_unpin_work *unpin_work; | ||
| 282 | int deferred_flip_completion; | ||
| 280 | }; | 283 | }; |
| 281 | 284 | ||
| 282 | struct radeon_encoder_primary_dac { | 285 | struct radeon_encoder_primary_dac { |
| @@ -376,6 +379,7 @@ struct radeon_encoder { | |||
| 376 | int hdmi_audio_workaround; | 379 | int hdmi_audio_workaround; |
| 377 | int hdmi_buffer_status; | 380 | int hdmi_buffer_status; |
| 378 | bool is_ext_encoder; | 381 | bool is_ext_encoder; |
| 382 | u16 caps; | ||
| 379 | }; | 383 | }; |
| 380 | 384 | ||
| 381 | struct radeon_connector_atom_dig { | 385 | struct radeon_connector_atom_dig { |
| @@ -442,10 +446,6 @@ struct radeon_framebuffer { | |||
| 442 | struct drm_gem_object *obj; | 446 | struct drm_gem_object *obj; |
| 443 | }; | 447 | }; |
| 444 | 448 | ||
| 445 | /* radeon_get_crtc_scanoutpos() return flags */ | ||
| 446 | #define RADEON_SCANOUTPOS_VALID (1 << 0) | ||
| 447 | #define RADEON_SCANOUTPOS_INVBL (1 << 1) | ||
| 448 | #define RADEON_SCANOUTPOS_ACCURATE (1 << 2) | ||
| 449 | 449 | ||
| 450 | extern enum radeon_tv_std | 450 | extern enum radeon_tv_std |
| 451 | radeon_combios_get_tv_info(struct radeon_device *rdev); | 451 | radeon_combios_get_tv_info(struct radeon_device *rdev); |
| @@ -562,11 +562,12 @@ extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 562 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, | 562 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, |
| 563 | int x, int y); | 563 | int x, int y); |
| 564 | 564 | ||
| 565 | extern int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, int *hpos); | 565 | extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, |
| 566 | int *vpos, int *hpos); | ||
| 566 | 567 | ||
| 567 | extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); | 568 | extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); |
| 568 | extern struct edid * | 569 | extern struct edid * |
| 569 | radeon_combios_get_hardcoded_edid(struct radeon_device *rdev); | 570 | radeon_bios_get_hardcoded_edid(struct radeon_device *rdev); |
| 570 | extern bool radeon_atom_get_clock_info(struct drm_device *dev); | 571 | extern bool radeon_atom_get_clock_info(struct drm_device *dev); |
| 571 | extern bool radeon_combios_get_clock_info(struct drm_device *dev); | 572 | extern bool radeon_combios_get_clock_info(struct drm_device *dev); |
| 572 | extern struct radeon_encoder_atom_dig * | 573 | extern struct radeon_encoder_atom_dig * |
| @@ -662,4 +663,7 @@ int radeon_fbdev_total_size(struct radeon_device *rdev); | |||
| 662 | bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); | 663 | bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); |
| 663 | 664 | ||
| 664 | void radeon_fb_output_poll_changed(struct radeon_device *rdev); | 665 | void radeon_fb_output_poll_changed(struct radeon_device *rdev); |
| 666 | |||
| 667 | void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id); | ||
| 668 | |||
| 665 | #endif | 669 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index a598d0049aa5..7d6b8e88f746 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <drm/drmP.h> | 34 | #include <drm/drmP.h> |
| 35 | #include "radeon_drm.h" | 35 | #include "radeon_drm.h" |
| 36 | #include "radeon.h" | 36 | #include "radeon.h" |
| 37 | #include "radeon_trace.h" | ||
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | int radeon_ttm_init(struct radeon_device *rdev); | 40 | int radeon_ttm_init(struct radeon_device *rdev); |
| @@ -146,6 +147,7 @@ retry: | |||
| 146 | list_add_tail(&bo->list, &rdev->gem.objects); | 147 | list_add_tail(&bo->list, &rdev->gem.objects); |
| 147 | mutex_unlock(&bo->rdev->gem.mutex); | 148 | mutex_unlock(&bo->rdev->gem.mutex); |
| 148 | } | 149 | } |
| 150 | trace_radeon_bo_create(bo); | ||
| 149 | return 0; | 151 | return 0; |
| 150 | } | 152 | } |
| 151 | 153 | ||
| @@ -302,34 +304,9 @@ void radeon_bo_list_add_object(struct radeon_bo_list *lobj, | |||
| 302 | struct list_head *head) | 304 | struct list_head *head) |
| 303 | { | 305 | { |
| 304 | if (lobj->wdomain) { | 306 | if (lobj->wdomain) { |
| 305 | list_add(&lobj->list, head); | 307 | list_add(&lobj->tv.head, head); |
| 306 | } else { | 308 | } else { |
| 307 | list_add_tail(&lobj->list, head); | 309 | list_add_tail(&lobj->tv.head, head); |
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | int radeon_bo_list_reserve(struct list_head *head) | ||
| 312 | { | ||
| 313 | struct radeon_bo_list *lobj; | ||
| 314 | int r; | ||
| 315 | |||
| 316 | list_for_each_entry(lobj, head, list){ | ||
| 317 | r = radeon_bo_reserve(lobj->bo, false); | ||
| 318 | if (unlikely(r != 0)) | ||
| 319 | return r; | ||
| 320 | lobj->reserved = true; | ||
| 321 | } | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | void radeon_bo_list_unreserve(struct list_head *head) | ||
| 326 | { | ||
| 327 | struct radeon_bo_list *lobj; | ||
| 328 | |||
| 329 | list_for_each_entry(lobj, head, list) { | ||
| 330 | /* only unreserve object we successfully reserved */ | ||
| 331 | if (lobj->reserved && radeon_bo_is_reserved(lobj->bo)) | ||
| 332 | radeon_bo_unreserve(lobj->bo); | ||
| 333 | } | 310 | } |
| 334 | } | 311 | } |
| 335 | 312 | ||
| @@ -340,14 +317,11 @@ int radeon_bo_list_validate(struct list_head *head) | |||
| 340 | u32 domain; | 317 | u32 domain; |
| 341 | int r; | 318 | int r; |
| 342 | 319 | ||
| 343 | list_for_each_entry(lobj, head, list) { | 320 | r = ttm_eu_reserve_buffers(head); |
| 344 | lobj->reserved = false; | ||
| 345 | } | ||
| 346 | r = radeon_bo_list_reserve(head); | ||
| 347 | if (unlikely(r != 0)) { | 321 | if (unlikely(r != 0)) { |
| 348 | return r; | 322 | return r; |
| 349 | } | 323 | } |
| 350 | list_for_each_entry(lobj, head, list) { | 324 | list_for_each_entry(lobj, head, tv.head) { |
| 351 | bo = lobj->bo; | 325 | bo = lobj->bo; |
| 352 | if (!bo->pin_count) { | 326 | if (!bo->pin_count) { |
| 353 | domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; | 327 | domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; |
| @@ -370,25 +344,6 @@ int radeon_bo_list_validate(struct list_head *head) | |||
| 370 | return 0; | 344 | return 0; |
| 371 | } | 345 | } |
| 372 | 346 | ||
| 373 | void radeon_bo_list_fence(struct list_head *head, void *fence) | ||
| 374 | { | ||
| 375 | struct radeon_bo_list *lobj; | ||
| 376 | struct radeon_bo *bo; | ||
| 377 | struct radeon_fence *old_fence = NULL; | ||
| 378 | |||
| 379 | list_for_each_entry(lobj, head, list) { | ||
| 380 | bo = lobj->bo; | ||
| 381 | spin_lock(&bo->tbo.lock); | ||
| 382 | old_fence = (struct radeon_fence *)bo->tbo.sync_obj; | ||
| 383 | bo->tbo.sync_obj = radeon_fence_ref(fence); | ||
| 384 | bo->tbo.sync_obj_arg = NULL; | ||
| 385 | spin_unlock(&bo->tbo.lock); | ||
| 386 | if (old_fence) { | ||
| 387 | radeon_fence_unref(&old_fence); | ||
| 388 | } | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | 347 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, |
| 393 | struct vm_area_struct *vma) | 348 | struct vm_area_struct *vma) |
| 394 | { | 349 | { |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index d143702b244a..22d4c237dea5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
| @@ -126,12 +126,12 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, | |||
| 126 | r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); | 126 | r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); |
| 127 | if (unlikely(r != 0)) | 127 | if (unlikely(r != 0)) |
| 128 | return r; | 128 | return r; |
| 129 | spin_lock(&bo->tbo.lock); | 129 | spin_lock(&bo->tbo.bdev->fence_lock); |
| 130 | if (mem_type) | 130 | if (mem_type) |
| 131 | *mem_type = bo->tbo.mem.mem_type; | 131 | *mem_type = bo->tbo.mem.mem_type; |
| 132 | if (bo->tbo.sync_obj) | 132 | if (bo->tbo.sync_obj) |
| 133 | r = ttm_bo_wait(&bo->tbo, true, true, no_wait); | 133 | r = ttm_bo_wait(&bo->tbo, true, true, no_wait); |
| 134 | spin_unlock(&bo->tbo.lock); | 134 | spin_unlock(&bo->tbo.bdev->fence_lock); |
| 135 | ttm_bo_unreserve(&bo->tbo); | 135 | ttm_bo_unreserve(&bo->tbo); |
| 136 | return r; | 136 | return r; |
| 137 | } | 137 | } |
| @@ -152,10 +152,7 @@ extern int radeon_bo_init(struct radeon_device *rdev); | |||
| 152 | extern void radeon_bo_fini(struct radeon_device *rdev); | 152 | extern void radeon_bo_fini(struct radeon_device *rdev); |
| 153 | extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, | 153 | extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, |
| 154 | struct list_head *head); | 154 | struct list_head *head); |
| 155 | extern int radeon_bo_list_reserve(struct list_head *head); | ||
| 156 | extern void radeon_bo_list_unreserve(struct list_head *head); | ||
| 157 | extern int radeon_bo_list_validate(struct list_head *head); | 155 | extern int radeon_bo_list_validate(struct list_head *head); |
| 158 | extern void radeon_bo_list_fence(struct list_head *head, void *fence); | ||
| 159 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | 156 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, |
| 160 | struct vm_area_struct *vma); | 157 | struct vm_area_struct *vma); |
| 161 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, | 158 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 8c9b2ef32c68..3b1b2bf9cdd5 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -167,13 +167,13 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
| 167 | if (radeon_gui_idle(rdev)) { | 167 | if (radeon_gui_idle(rdev)) { |
| 168 | sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 168 | sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
| 169 | clock_info[rdev->pm.requested_clock_mode_index].sclk; | 169 | clock_info[rdev->pm.requested_clock_mode_index].sclk; |
| 170 | if (sclk > rdev->clock.default_sclk) | 170 | if (sclk > rdev->pm.default_sclk) |
| 171 | sclk = rdev->clock.default_sclk; | 171 | sclk = rdev->pm.default_sclk; |
| 172 | 172 | ||
| 173 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 173 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
| 174 | clock_info[rdev->pm.requested_clock_mode_index].mclk; | 174 | clock_info[rdev->pm.requested_clock_mode_index].mclk; |
| 175 | if (mclk > rdev->clock.default_mclk) | 175 | if (mclk > rdev->pm.default_mclk) |
| 176 | mclk = rdev->clock.default_mclk; | 176 | mclk = rdev->pm.default_mclk; |
| 177 | 177 | ||
| 178 | /* upvolt before raising clocks, downvolt after lowering clocks */ | 178 | /* upvolt before raising clocks, downvolt after lowering clocks */ |
| 179 | if (sclk < rdev->pm.current_sclk) | 179 | if (sclk < rdev->pm.current_sclk) |
| @@ -405,20 +405,13 @@ static ssize_t radeon_set_pm_method(struct device *dev, | |||
| 405 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; | 405 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; |
| 406 | mutex_unlock(&rdev->pm.mutex); | 406 | mutex_unlock(&rdev->pm.mutex); |
| 407 | } else if (strncmp("profile", buf, strlen("profile")) == 0) { | 407 | } else if (strncmp("profile", buf, strlen("profile")) == 0) { |
| 408 | bool flush_wq = false; | ||
| 409 | |||
| 410 | mutex_lock(&rdev->pm.mutex); | 408 | mutex_lock(&rdev->pm.mutex); |
| 411 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | ||
| 412 | cancel_delayed_work(&rdev->pm.dynpm_idle_work); | ||
| 413 | flush_wq = true; | ||
| 414 | } | ||
| 415 | /* disable dynpm */ | 409 | /* disable dynpm */ |
| 416 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; | 410 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; |
| 417 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; | 411 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; |
| 418 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 412 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
| 419 | mutex_unlock(&rdev->pm.mutex); | 413 | mutex_unlock(&rdev->pm.mutex); |
| 420 | if (flush_wq) | 414 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); |
| 421 | flush_workqueue(rdev->wq); | ||
| 422 | } else { | 415 | } else { |
| 423 | DRM_ERROR("invalid power method!\n"); | 416 | DRM_ERROR("invalid power method!\n"); |
| 424 | goto fail; | 417 | goto fail; |
| @@ -447,8 +440,12 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, | |||
| 447 | temp = rv770_get_temp(rdev); | 440 | temp = rv770_get_temp(rdev); |
| 448 | break; | 441 | break; |
| 449 | case THERMAL_TYPE_EVERGREEN: | 442 | case THERMAL_TYPE_EVERGREEN: |
| 443 | case THERMAL_TYPE_NI: | ||
| 450 | temp = evergreen_get_temp(rdev); | 444 | temp = evergreen_get_temp(rdev); |
| 451 | break; | 445 | break; |
| 446 | case THERMAL_TYPE_SUMO: | ||
| 447 | temp = sumo_get_temp(rdev); | ||
| 448 | break; | ||
| 452 | default: | 449 | default: |
| 453 | temp = 0; | 450 | temp = 0; |
| 454 | break; | 451 | break; |
| @@ -487,6 +484,7 @@ static int radeon_hwmon_init(struct radeon_device *rdev) | |||
| 487 | case THERMAL_TYPE_RV6XX: | 484 | case THERMAL_TYPE_RV6XX: |
| 488 | case THERMAL_TYPE_RV770: | 485 | case THERMAL_TYPE_RV770: |
| 489 | case THERMAL_TYPE_EVERGREEN: | 486 | case THERMAL_TYPE_EVERGREEN: |
| 487 | case THERMAL_TYPE_SUMO: | ||
| 490 | rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); | 488 | rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); |
| 491 | if (IS_ERR(rdev->pm.int_hwmon_dev)) { | 489 | if (IS_ERR(rdev->pm.int_hwmon_dev)) { |
| 492 | err = PTR_ERR(rdev->pm.int_hwmon_dev); | 490 | err = PTR_ERR(rdev->pm.int_hwmon_dev); |
| @@ -520,34 +518,39 @@ static void radeon_hwmon_fini(struct radeon_device *rdev) | |||
| 520 | 518 | ||
| 521 | void radeon_pm_suspend(struct radeon_device *rdev) | 519 | void radeon_pm_suspend(struct radeon_device *rdev) |
| 522 | { | 520 | { |
| 523 | bool flush_wq = false; | ||
| 524 | |||
| 525 | mutex_lock(&rdev->pm.mutex); | 521 | mutex_lock(&rdev->pm.mutex); |
| 526 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | 522 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { |
| 527 | cancel_delayed_work(&rdev->pm.dynpm_idle_work); | ||
| 528 | if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) | 523 | if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) |
| 529 | rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED; | 524 | rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED; |
| 530 | flush_wq = true; | ||
| 531 | } | 525 | } |
| 532 | mutex_unlock(&rdev->pm.mutex); | 526 | mutex_unlock(&rdev->pm.mutex); |
| 533 | if (flush_wq) | 527 | |
| 534 | flush_workqueue(rdev->wq); | 528 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); |
| 535 | } | 529 | } |
| 536 | 530 | ||
| 537 | void radeon_pm_resume(struct radeon_device *rdev) | 531 | void radeon_pm_resume(struct radeon_device *rdev) |
| 538 | { | 532 | { |
| 533 | /* set up the default clocks if the MC ucode is loaded */ | ||
| 534 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | ||
| 535 | if (rdev->pm.default_vddc) | ||
| 536 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc); | ||
| 537 | if (rdev->pm.default_sclk) | ||
| 538 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); | ||
| 539 | if (rdev->pm.default_mclk) | ||
| 540 | radeon_set_memory_clock(rdev, rdev->pm.default_mclk); | ||
| 541 | } | ||
| 539 | /* asic init will reset the default power state */ | 542 | /* asic init will reset the default power state */ |
| 540 | mutex_lock(&rdev->pm.mutex); | 543 | mutex_lock(&rdev->pm.mutex); |
| 541 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; | 544 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; |
| 542 | rdev->pm.current_clock_mode_index = 0; | 545 | rdev->pm.current_clock_mode_index = 0; |
| 543 | rdev->pm.current_sclk = rdev->clock.default_sclk; | 546 | rdev->pm.current_sclk = rdev->pm.default_sclk; |
| 544 | rdev->pm.current_mclk = rdev->clock.default_mclk; | 547 | rdev->pm.current_mclk = rdev->pm.default_mclk; |
| 545 | rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; | 548 | rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; |
| 546 | if (rdev->pm.pm_method == PM_METHOD_DYNPM | 549 | if (rdev->pm.pm_method == PM_METHOD_DYNPM |
| 547 | && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { | 550 | && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { |
| 548 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; | 551 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; |
| 549 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 552 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
| 550 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 553 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
| 551 | } | 554 | } |
| 552 | mutex_unlock(&rdev->pm.mutex); | 555 | mutex_unlock(&rdev->pm.mutex); |
| 553 | radeon_pm_compute_clocks(rdev); | 556 | radeon_pm_compute_clocks(rdev); |
| @@ -564,6 +567,8 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
| 564 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; | 567 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; |
| 565 | rdev->pm.dynpm_can_upclock = true; | 568 | rdev->pm.dynpm_can_upclock = true; |
| 566 | rdev->pm.dynpm_can_downclock = true; | 569 | rdev->pm.dynpm_can_downclock = true; |
| 570 | rdev->pm.default_sclk = rdev->clock.default_sclk; | ||
| 571 | rdev->pm.default_mclk = rdev->clock.default_mclk; | ||
| 567 | rdev->pm.current_sclk = rdev->clock.default_sclk; | 572 | rdev->pm.current_sclk = rdev->clock.default_sclk; |
| 568 | rdev->pm.current_mclk = rdev->clock.default_mclk; | 573 | rdev->pm.current_mclk = rdev->clock.default_mclk; |
| 569 | rdev->pm.int_thermal_type = THERMAL_TYPE_NONE; | 574 | rdev->pm.int_thermal_type = THERMAL_TYPE_NONE; |
| @@ -575,12 +580,24 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
| 575 | radeon_combios_get_power_modes(rdev); | 580 | radeon_combios_get_power_modes(rdev); |
| 576 | radeon_pm_print_states(rdev); | 581 | radeon_pm_print_states(rdev); |
| 577 | radeon_pm_init_profile(rdev); | 582 | radeon_pm_init_profile(rdev); |
| 583 | /* set up the default clocks if the MC ucode is loaded */ | ||
| 584 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | ||
| 585 | if (rdev->pm.default_vddc) | ||
| 586 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc); | ||
| 587 | if (rdev->pm.default_sclk) | ||
| 588 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); | ||
| 589 | if (rdev->pm.default_mclk) | ||
| 590 | radeon_set_memory_clock(rdev, rdev->pm.default_mclk); | ||
| 591 | } | ||
| 578 | } | 592 | } |
| 579 | 593 | ||
| 580 | /* set up the internal thermal sensor if applicable */ | 594 | /* set up the internal thermal sensor if applicable */ |
| 581 | ret = radeon_hwmon_init(rdev); | 595 | ret = radeon_hwmon_init(rdev); |
| 582 | if (ret) | 596 | if (ret) |
| 583 | return ret; | 597 | return ret; |
| 598 | |||
| 599 | INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); | ||
| 600 | |||
| 584 | if (rdev->pm.num_power_states > 1) { | 601 | if (rdev->pm.num_power_states > 1) { |
| 585 | /* where's the best place to put these? */ | 602 | /* where's the best place to put these? */ |
| 586 | ret = device_create_file(rdev->dev, &dev_attr_power_profile); | 603 | ret = device_create_file(rdev->dev, &dev_attr_power_profile); |
| @@ -594,8 +611,6 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
| 594 | rdev->acpi_nb.notifier_call = radeon_acpi_event; | 611 | rdev->acpi_nb.notifier_call = radeon_acpi_event; |
| 595 | register_acpi_notifier(&rdev->acpi_nb); | 612 | register_acpi_notifier(&rdev->acpi_nb); |
| 596 | #endif | 613 | #endif |
| 597 | INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); | ||
| 598 | |||
| 599 | if (radeon_debugfs_pm_init(rdev)) { | 614 | if (radeon_debugfs_pm_init(rdev)) { |
| 600 | DRM_ERROR("Failed to register debugfs file for PM!\n"); | 615 | DRM_ERROR("Failed to register debugfs file for PM!\n"); |
| 601 | } | 616 | } |
| @@ -609,25 +624,20 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
| 609 | void radeon_pm_fini(struct radeon_device *rdev) | 624 | void radeon_pm_fini(struct radeon_device *rdev) |
| 610 | { | 625 | { |
| 611 | if (rdev->pm.num_power_states > 1) { | 626 | if (rdev->pm.num_power_states > 1) { |
| 612 | bool flush_wq = false; | ||
| 613 | |||
| 614 | mutex_lock(&rdev->pm.mutex); | 627 | mutex_lock(&rdev->pm.mutex); |
| 615 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { | 628 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { |
| 616 | rdev->pm.profile = PM_PROFILE_DEFAULT; | 629 | rdev->pm.profile = PM_PROFILE_DEFAULT; |
| 617 | radeon_pm_update_profile(rdev); | 630 | radeon_pm_update_profile(rdev); |
| 618 | radeon_pm_set_clocks(rdev); | 631 | radeon_pm_set_clocks(rdev); |
| 619 | } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | 632 | } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { |
| 620 | /* cancel work */ | ||
| 621 | cancel_delayed_work(&rdev->pm.dynpm_idle_work); | ||
| 622 | flush_wq = true; | ||
| 623 | /* reset default clocks */ | 633 | /* reset default clocks */ |
| 624 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; | 634 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; |
| 625 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; | 635 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; |
| 626 | radeon_pm_set_clocks(rdev); | 636 | radeon_pm_set_clocks(rdev); |
| 627 | } | 637 | } |
| 628 | mutex_unlock(&rdev->pm.mutex); | 638 | mutex_unlock(&rdev->pm.mutex); |
| 629 | if (flush_wq) | 639 | |
| 630 | flush_workqueue(rdev->wq); | 640 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); |
| 631 | 641 | ||
| 632 | device_remove_file(rdev->dev, &dev_attr_power_profile); | 642 | device_remove_file(rdev->dev, &dev_attr_power_profile); |
| 633 | device_remove_file(rdev->dev, &dev_attr_power_method); | 643 | device_remove_file(rdev->dev, &dev_attr_power_method); |
| @@ -686,12 +696,12 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) | |||
| 686 | radeon_pm_get_dynpm_state(rdev); | 696 | radeon_pm_get_dynpm_state(rdev); |
| 687 | radeon_pm_set_clocks(rdev); | 697 | radeon_pm_set_clocks(rdev); |
| 688 | 698 | ||
| 689 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 699 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
| 690 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 700 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
| 691 | } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) { | 701 | } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) { |
| 692 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; | 702 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; |
| 693 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 703 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
| 694 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 704 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
| 695 | DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); | 705 | DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); |
| 696 | } | 706 | } |
| 697 | } else { /* count == 0 */ | 707 | } else { /* count == 0 */ |
| @@ -720,9 +730,9 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev) | |||
| 720 | */ | 730 | */ |
| 721 | for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { | 731 | for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { |
| 722 | if (rdev->pm.active_crtcs & (1 << crtc)) { | 732 | if (rdev->pm.active_crtcs & (1 << crtc)) { |
| 723 | vbl_status = radeon_get_crtc_scanoutpos(rdev, crtc, &vpos, &hpos); | 733 | vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos); |
| 724 | if ((vbl_status & RADEON_SCANOUTPOS_VALID) && | 734 | if ((vbl_status & DRM_SCANOUTPOS_VALID) && |
| 725 | !(vbl_status & RADEON_SCANOUTPOS_INVBL)) | 735 | !(vbl_status & DRM_SCANOUTPOS_INVBL)) |
| 726 | in_vbl = false; | 736 | in_vbl = false; |
| 727 | } | 737 | } |
| 728 | } | 738 | } |
| @@ -796,8 +806,8 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) | |||
| 796 | radeon_pm_set_clocks(rdev); | 806 | radeon_pm_set_clocks(rdev); |
| 797 | } | 807 | } |
| 798 | 808 | ||
| 799 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 809 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
| 800 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 810 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
| 801 | } | 811 | } |
| 802 | mutex_unlock(&rdev->pm.mutex); | 812 | mutex_unlock(&rdev->pm.mutex); |
| 803 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 813 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
| @@ -814,9 +824,9 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) | |||
| 814 | struct drm_device *dev = node->minor->dev; | 824 | struct drm_device *dev = node->minor->dev; |
| 815 | struct radeon_device *rdev = dev->dev_private; | 825 | struct radeon_device *rdev = dev->dev_private; |
| 816 | 826 | ||
| 817 | seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk); | 827 | seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk); |
| 818 | seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); | 828 | seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); |
| 819 | seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); | 829 | seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk); |
| 820 | if (rdev->asic->get_memory_clock) | 830 | if (rdev->asic->get_memory_clock) |
| 821 | seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); | 831 | seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); |
| 822 | if (rdev->pm.current_vddc) | 832 | if (rdev->pm.current_vddc) |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 64928814de53..3cd4dace57c7 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #include "r500_reg.h" | 55 | #include "r500_reg.h" |
| 56 | #include "r600_reg.h" | 56 | #include "r600_reg.h" |
| 57 | #include "evergreen_reg.h" | 57 | #include "evergreen_reg.h" |
| 58 | #include "ni_reg.h" | ||
| 58 | 59 | ||
| 59 | #define RADEON_MC_AGP_LOCATION 0x014c | 60 | #define RADEON_MC_AGP_LOCATION 0x014c |
| 60 | #define RADEON_MC_AGP_START_MASK 0x0000FFFF | 61 | #define RADEON_MC_AGP_START_MASK 0x0000FFFF |
| @@ -320,6 +321,15 @@ | |||
| 320 | # define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) | 321 | # define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) |
| 321 | # define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) | 322 | # define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) |
| 322 | # define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) | 323 | # define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) |
| 324 | # define R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
| 325 | # define R600_PCIE_LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
| 326 | # define R600_PCIE_LC_RENEGOTIATE_EN (1 << 10) | ||
| 327 | # define R600_PCIE_LC_SHORT_RECONFIG_EN (1 << 11) | ||
| 328 | # define R600_PCIE_LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
| 329 | # define R600_PCIE_LC_UPCONFIGURE_DIS (1 << 13) | ||
| 330 | |||
| 331 | #define R600_TARGET_AND_CURRENT_PROFILE_INDEX 0x70c | ||
| 332 | #define R700_TARGET_AND_CURRENT_PROFILE_INDEX 0x66c | ||
| 323 | 333 | ||
| 324 | #define RADEON_CACHE_CNTL 0x1724 | 334 | #define RADEON_CACHE_CNTL 0x1724 |
| 325 | #define RADEON_CACHE_LINE 0x0f0c /* PCI */ | 335 | #define RADEON_CACHE_LINE 0x0f0c /* PCI */ |
| @@ -422,6 +432,7 @@ | |||
| 422 | # define RADEON_CRTC_CSYNC_EN (1 << 4) | 432 | # define RADEON_CRTC_CSYNC_EN (1 << 4) |
| 423 | # define RADEON_CRTC_ICON_EN (1 << 15) | 433 | # define RADEON_CRTC_ICON_EN (1 << 15) |
| 424 | # define RADEON_CRTC_CUR_EN (1 << 16) | 434 | # define RADEON_CRTC_CUR_EN (1 << 16) |
| 435 | # define RADEON_CRTC_VSTAT_MODE_MASK (3 << 17) | ||
| 425 | # define RADEON_CRTC_CUR_MODE_MASK (7 << 20) | 436 | # define RADEON_CRTC_CUR_MODE_MASK (7 << 20) |
| 426 | # define RADEON_CRTC_CUR_MODE_SHIFT 20 | 437 | # define RADEON_CRTC_CUR_MODE_SHIFT 20 |
| 427 | # define RADEON_CRTC_CUR_MODE_MONO 0 | 438 | # define RADEON_CRTC_CUR_MODE_MONO 0 |
| @@ -509,6 +520,8 @@ | |||
| 509 | # define RADEON_CRTC_TILE_EN (1 << 15) | 520 | # define RADEON_CRTC_TILE_EN (1 << 15) |
| 510 | # define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) | 521 | # define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) |
| 511 | # define RADEON_CRTC_STEREO_OFFSET_EN (1 << 17) | 522 | # define RADEON_CRTC_STEREO_OFFSET_EN (1 << 17) |
| 523 | # define RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN (1 << 28) | ||
| 524 | # define RADEON_CRTC_GUI_TRIG_OFFSET_RIGHT_EN (1 << 29) | ||
| 512 | 525 | ||
| 513 | #define R300_CRTC_TILE_X0_Y0 0x0350 | 526 | #define R300_CRTC_TILE_X0_Y0 0x0350 |
| 514 | #define R300_CRTC2_TILE_X0_Y0 0x0358 | 527 | #define R300_CRTC2_TILE_X0_Y0 0x0358 |
diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h new file mode 100644 index 000000000000..eafd8160a155 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_trace.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | #if !defined(_RADEON_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 2 | #define _RADEON_TRACE_H_ | ||
| 3 | |||
| 4 | #include <linux/stringify.h> | ||
| 5 | #include <linux/types.h> | ||
| 6 | #include <linux/tracepoint.h> | ||
| 7 | |||
| 8 | #include <drm/drmP.h> | ||
| 9 | |||
| 10 | #undef TRACE_SYSTEM | ||
| 11 | #define TRACE_SYSTEM radeon | ||
| 12 | #define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) | ||
| 13 | #define TRACE_INCLUDE_FILE radeon_trace | ||
| 14 | |||
| 15 | TRACE_EVENT(radeon_bo_create, | ||
| 16 | TP_PROTO(struct radeon_bo *bo), | ||
| 17 | TP_ARGS(bo), | ||
| 18 | TP_STRUCT__entry( | ||
| 19 | __field(struct radeon_bo *, bo) | ||
| 20 | __field(u32, pages) | ||
| 21 | ), | ||
| 22 | |||
| 23 | TP_fast_assign( | ||
| 24 | __entry->bo = bo; | ||
| 25 | __entry->pages = bo->tbo.num_pages; | ||
| 26 | ), | ||
| 27 | TP_printk("bo=%p, pages=%u", __entry->bo, __entry->pages) | ||
| 28 | ); | ||
| 29 | |||
| 30 | DECLARE_EVENT_CLASS(radeon_fence_request, | ||
| 31 | |||
| 32 | TP_PROTO(struct drm_device *dev, u32 seqno), | ||
| 33 | |||
| 34 | TP_ARGS(dev, seqno), | ||
| 35 | |||
| 36 | TP_STRUCT__entry( | ||
| 37 | __field(u32, dev) | ||
| 38 | __field(u32, seqno) | ||
| 39 | ), | ||
| 40 | |||
| 41 | TP_fast_assign( | ||
| 42 | __entry->dev = dev->primary->index; | ||
| 43 | __entry->seqno = seqno; | ||
| 44 | ), | ||
| 45 | |||
| 46 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) | ||
| 47 | ); | ||
| 48 | |||
| 49 | DEFINE_EVENT(radeon_fence_request, radeon_fence_emit, | ||
| 50 | |||
| 51 | TP_PROTO(struct drm_device *dev, u32 seqno), | ||
| 52 | |||
| 53 | TP_ARGS(dev, seqno) | ||
| 54 | ); | ||
| 55 | |||
| 56 | DEFINE_EVENT(radeon_fence_request, radeon_fence_retire, | ||
| 57 | |||
| 58 | TP_PROTO(struct drm_device *dev, u32 seqno), | ||
| 59 | |||
| 60 | TP_ARGS(dev, seqno) | ||
| 61 | ); | ||
| 62 | |||
| 63 | DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_begin, | ||
| 64 | |||
| 65 | TP_PROTO(struct drm_device *dev, u32 seqno), | ||
| 66 | |||
| 67 | TP_ARGS(dev, seqno) | ||
| 68 | ); | ||
| 69 | |||
| 70 | DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_end, | ||
| 71 | |||
| 72 | TP_PROTO(struct drm_device *dev, u32 seqno), | ||
| 73 | |||
| 74 | TP_ARGS(dev, seqno) | ||
| 75 | ); | ||
| 76 | |||
| 77 | #endif | ||
| 78 | |||
| 79 | /* This part must be outside protection */ | ||
| 80 | #undef TRACE_INCLUDE_PATH | ||
| 81 | #define TRACE_INCLUDE_PATH . | ||
| 82 | #include <trace/define_trace.h> | ||
diff --git a/drivers/gpu/drm/radeon/radeon_trace_points.c b/drivers/gpu/drm/radeon/radeon_trace_points.c new file mode 100644 index 000000000000..8175993df84d --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_trace_points.c | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* Copyright Red Hat Inc 2010. | ||
| 2 | * Author : Dave Airlie <airlied@redhat.com> | ||
| 3 | */ | ||
| 4 | #include <drm/drmP.h> | ||
| 5 | #include "radeon_drm.h" | ||
| 6 | #include "radeon.h" | ||
| 7 | |||
| 8 | #define CREATE_TRACE_POINTS | ||
| 9 | #include "radeon_trace.h" | ||
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index b3f9f1d92005..ef422bbacfc1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 | |||
| @@ -304,6 +304,22 @@ rv515 0x6d40 | |||
| 304 | 0x4630 US_CODE_ADDR | 304 | 0x4630 US_CODE_ADDR |
| 305 | 0x4634 US_CODE_RANGE | 305 | 0x4634 US_CODE_RANGE |
| 306 | 0x4638 US_CODE_OFFSET | 306 | 0x4638 US_CODE_OFFSET |
| 307 | 0x4640 US_FORMAT0_0 | ||
| 308 | 0x4644 US_FORMAT0_1 | ||
| 309 | 0x4648 US_FORMAT0_2 | ||
| 310 | 0x464C US_FORMAT0_3 | ||
| 311 | 0x4650 US_FORMAT0_4 | ||
| 312 | 0x4654 US_FORMAT0_5 | ||
| 313 | 0x4658 US_FORMAT0_6 | ||
| 314 | 0x465C US_FORMAT0_7 | ||
| 315 | 0x4660 US_FORMAT0_8 | ||
| 316 | 0x4664 US_FORMAT0_9 | ||
| 317 | 0x4668 US_FORMAT0_10 | ||
| 318 | 0x466C US_FORMAT0_11 | ||
| 319 | 0x4670 US_FORMAT0_12 | ||
| 320 | 0x4674 US_FORMAT0_13 | ||
| 321 | 0x4678 US_FORMAT0_14 | ||
| 322 | 0x467C US_FORMAT0_15 | ||
| 307 | 0x46A4 US_OUT_FMT_0 | 323 | 0x46A4 US_OUT_FMT_0 |
| 308 | 0x46A8 US_OUT_FMT_1 | 324 | 0x46A8 US_OUT_FMT_1 |
| 309 | 0x46AC US_OUT_FMT_2 | 325 | 0x46AC US_OUT_FMT_2 |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index f1c6e02c2e6b..b4192acaab5f 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -46,6 +46,56 @@ | |||
| 46 | void rs600_gpu_init(struct radeon_device *rdev); | 46 | void rs600_gpu_init(struct radeon_device *rdev); |
| 47 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); | 47 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); |
| 48 | 48 | ||
| 49 | void rs600_pre_page_flip(struct radeon_device *rdev, int crtc) | ||
| 50 | { | ||
| 51 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | ||
| 52 | u32 tmp; | ||
| 53 | |||
| 54 | /* make sure flip is at vb rather than hb */ | ||
| 55 | tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); | ||
| 56 | tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; | ||
| 57 | WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); | ||
| 58 | |||
| 59 | /* set pageflip to happen anywhere in vblank interval */ | ||
| 60 | WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); | ||
| 61 | |||
| 62 | /* enable the pflip int */ | ||
| 63 | radeon_irq_kms_pflip_irq_get(rdev, crtc); | ||
| 64 | } | ||
| 65 | |||
| 66 | void rs600_post_page_flip(struct radeon_device *rdev, int crtc) | ||
| 67 | { | ||
| 68 | /* disable the pflip int */ | ||
| 69 | radeon_irq_kms_pflip_irq_put(rdev, crtc); | ||
| 70 | } | ||
| 71 | |||
| 72 | u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | ||
| 73 | { | ||
| 74 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
| 75 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); | ||
| 76 | |||
| 77 | /* Lock the graphics update lock */ | ||
| 78 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; | ||
| 79 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
| 80 | |||
| 81 | /* update the scanout addresses */ | ||
| 82 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
| 83 | (u32)crtc_base); | ||
| 84 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
| 85 | (u32)crtc_base); | ||
| 86 | |||
| 87 | /* Wait for update_pending to go high. */ | ||
| 88 | while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); | ||
| 89 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | ||
| 90 | |||
| 91 | /* Unlock the lock, so double-buffering can take place inside vblank */ | ||
| 92 | tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; | ||
| 93 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
| 94 | |||
| 95 | /* Return current update_pending status: */ | ||
| 96 | return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; | ||
| 97 | } | ||
| 98 | |||
| 49 | void rs600_pm_misc(struct radeon_device *rdev) | 99 | void rs600_pm_misc(struct radeon_device *rdev) |
| 50 | { | 100 | { |
| 51 | int requested_index = rdev->pm.requested_power_state_index; | 101 | int requested_index = rdev->pm.requested_power_state_index; |
| @@ -515,10 +565,12 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
| 515 | if (rdev->irq.gui_idle) { | 565 | if (rdev->irq.gui_idle) { |
| 516 | tmp |= S_000040_GUI_IDLE(1); | 566 | tmp |= S_000040_GUI_IDLE(1); |
| 517 | } | 567 | } |
| 518 | if (rdev->irq.crtc_vblank_int[0]) { | 568 | if (rdev->irq.crtc_vblank_int[0] || |
| 569 | rdev->irq.pflip[0]) { | ||
| 519 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); | 570 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); |
| 520 | } | 571 | } |
| 521 | if (rdev->irq.crtc_vblank_int[1]) { | 572 | if (rdev->irq.crtc_vblank_int[1] || |
| 573 | rdev->irq.pflip[1]) { | ||
| 522 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); | 574 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); |
| 523 | } | 575 | } |
| 524 | if (rdev->irq.hpd[0]) { | 576 | if (rdev->irq.hpd[0]) { |
| @@ -534,7 +586,7 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
| 534 | return 0; | 586 | return 0; |
| 535 | } | 587 | } |
| 536 | 588 | ||
| 537 | static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) | 589 | static inline u32 rs600_irq_ack(struct radeon_device *rdev) |
| 538 | { | 590 | { |
| 539 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); | 591 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); |
| 540 | uint32_t irq_mask = S_000044_SW_INT(1); | 592 | uint32_t irq_mask = S_000044_SW_INT(1); |
| @@ -547,27 +599,27 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
| 547 | } | 599 | } |
| 548 | 600 | ||
| 549 | if (G_000044_DISPLAY_INT_STAT(irqs)) { | 601 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
| 550 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); | 602 | rdev->irq.stat_regs.r500.disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
| 551 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) { | 603 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 552 | WREG32(R_006534_D1MODE_VBLANK_STATUS, | 604 | WREG32(R_006534_D1MODE_VBLANK_STATUS, |
| 553 | S_006534_D1MODE_VBLANK_ACK(1)); | 605 | S_006534_D1MODE_VBLANK_ACK(1)); |
| 554 | } | 606 | } |
| 555 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(*r500_disp_int)) { | 607 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 556 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, | 608 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, |
| 557 | S_006D34_D2MODE_VBLANK_ACK(1)); | 609 | S_006D34_D2MODE_VBLANK_ACK(1)); |
| 558 | } | 610 | } |
| 559 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) { | 611 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 560 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | 612 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); |
| 561 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); | 613 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); |
| 562 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | 614 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); |
| 563 | } | 615 | } |
| 564 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) { | 616 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 565 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | 617 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); |
| 566 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); | 618 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); |
| 567 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | 619 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); |
| 568 | } | 620 | } |
| 569 | } else { | 621 | } else { |
| 570 | *r500_disp_int = 0; | 622 | rdev->irq.stat_regs.r500.disp_int = 0; |
| 571 | } | 623 | } |
| 572 | 624 | ||
| 573 | if (irqs) { | 625 | if (irqs) { |
| @@ -578,32 +630,30 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
| 578 | 630 | ||
| 579 | void rs600_irq_disable(struct radeon_device *rdev) | 631 | void rs600_irq_disable(struct radeon_device *rdev) |
| 580 | { | 632 | { |
| 581 | u32 tmp; | ||
| 582 | |||
| 583 | WREG32(R_000040_GEN_INT_CNTL, 0); | 633 | WREG32(R_000040_GEN_INT_CNTL, 0); |
| 584 | WREG32(R_006540_DxMODE_INT_MASK, 0); | 634 | WREG32(R_006540_DxMODE_INT_MASK, 0); |
| 585 | /* Wait and acknowledge irq */ | 635 | /* Wait and acknowledge irq */ |
| 586 | mdelay(1); | 636 | mdelay(1); |
| 587 | rs600_irq_ack(rdev, &tmp); | 637 | rs600_irq_ack(rdev); |
| 588 | } | 638 | } |
| 589 | 639 | ||
| 590 | int rs600_irq_process(struct radeon_device *rdev) | 640 | int rs600_irq_process(struct radeon_device *rdev) |
| 591 | { | 641 | { |
| 592 | uint32_t status, msi_rearm; | 642 | u32 status, msi_rearm; |
| 593 | uint32_t r500_disp_int; | ||
| 594 | bool queue_hotplug = false; | 643 | bool queue_hotplug = false; |
| 595 | 644 | ||
| 596 | /* reset gui idle ack. the status bit is broken */ | 645 | /* reset gui idle ack. the status bit is broken */ |
| 597 | rdev->irq.gui_idle_acked = false; | 646 | rdev->irq.gui_idle_acked = false; |
| 598 | 647 | ||
| 599 | status = rs600_irq_ack(rdev, &r500_disp_int); | 648 | status = rs600_irq_ack(rdev); |
| 600 | if (!status && !r500_disp_int) { | 649 | if (!status && !rdev->irq.stat_regs.r500.disp_int) { |
| 601 | return IRQ_NONE; | 650 | return IRQ_NONE; |
| 602 | } | 651 | } |
| 603 | while (status || r500_disp_int) { | 652 | while (status || rdev->irq.stat_regs.r500.disp_int) { |
| 604 | /* SW interrupt */ | 653 | /* SW interrupt */ |
| 605 | if (G_000044_SW_INT(status)) | 654 | if (G_000044_SW_INT(status)) { |
| 606 | radeon_fence_process(rdev); | 655 | radeon_fence_process(rdev); |
| 656 | } | ||
| 607 | /* GUI idle */ | 657 | /* GUI idle */ |
| 608 | if (G_000040_GUI_IDLE(status)) { | 658 | if (G_000040_GUI_IDLE(status)) { |
| 609 | rdev->irq.gui_idle_acked = true; | 659 | rdev->irq.gui_idle_acked = true; |
| @@ -611,30 +661,38 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
| 611 | wake_up(&rdev->irq.idle_queue); | 661 | wake_up(&rdev->irq.idle_queue); |
| 612 | } | 662 | } |
| 613 | /* Vertical blank interrupts */ | 663 | /* Vertical blank interrupts */ |
| 614 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) { | 664 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 615 | drm_handle_vblank(rdev->ddev, 0); | 665 | if (rdev->irq.crtc_vblank_int[0]) { |
| 616 | rdev->pm.vblank_sync = true; | 666 | drm_handle_vblank(rdev->ddev, 0); |
| 617 | wake_up(&rdev->irq.vblank_queue); | 667 | rdev->pm.vblank_sync = true; |
| 668 | wake_up(&rdev->irq.vblank_queue); | ||
| 669 | } | ||
| 670 | if (rdev->irq.pflip[0]) | ||
| 671 | radeon_crtc_handle_flip(rdev, 0); | ||
| 618 | } | 672 | } |
| 619 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) { | 673 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 620 | drm_handle_vblank(rdev->ddev, 1); | 674 | if (rdev->irq.crtc_vblank_int[1]) { |
| 621 | rdev->pm.vblank_sync = true; | 675 | drm_handle_vblank(rdev->ddev, 1); |
| 622 | wake_up(&rdev->irq.vblank_queue); | 676 | rdev->pm.vblank_sync = true; |
| 677 | wake_up(&rdev->irq.vblank_queue); | ||
| 678 | } | ||
| 679 | if (rdev->irq.pflip[1]) | ||
| 680 | radeon_crtc_handle_flip(rdev, 1); | ||
| 623 | } | 681 | } |
| 624 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { | 682 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 625 | queue_hotplug = true; | 683 | queue_hotplug = true; |
| 626 | DRM_DEBUG("HPD1\n"); | 684 | DRM_DEBUG("HPD1\n"); |
| 627 | } | 685 | } |
| 628 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) { | 686 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
| 629 | queue_hotplug = true; | 687 | queue_hotplug = true; |
| 630 | DRM_DEBUG("HPD2\n"); | 688 | DRM_DEBUG("HPD2\n"); |
| 631 | } | 689 | } |
| 632 | status = rs600_irq_ack(rdev, &r500_disp_int); | 690 | status = rs600_irq_ack(rdev); |
| 633 | } | 691 | } |
| 634 | /* reset gui idle ack. the status bit is broken */ | 692 | /* reset gui idle ack. the status bit is broken */ |
| 635 | rdev->irq.gui_idle_acked = false; | 693 | rdev->irq.gui_idle_acked = false; |
| 636 | if (queue_hotplug) | 694 | if (queue_hotplug) |
| 637 | queue_work(rdev->wq, &rdev->hotplug_work); | 695 | schedule_work(&rdev->hotplug_work); |
| 638 | if (rdev->msi_enabled) { | 696 | if (rdev->msi_enabled) { |
| 639 | switch (rdev->family) { | 697 | switch (rdev->family) { |
| 640 | case CHIP_RS600: | 698 | case CHIP_RS600: |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4dfead8cee33..3a264aa3a79a 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -41,6 +41,41 @@ | |||
| 41 | 41 | ||
| 42 | static void rv770_gpu_init(struct radeon_device *rdev); | 42 | static void rv770_gpu_init(struct radeon_device *rdev); |
| 43 | void rv770_fini(struct radeon_device *rdev); | 43 | void rv770_fini(struct radeon_device *rdev); |
| 44 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev); | ||
| 45 | |||
| 46 | u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | ||
| 47 | { | ||
| 48 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
| 49 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); | ||
| 50 | |||
| 51 | /* Lock the graphics update lock */ | ||
| 52 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; | ||
| 53 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
| 54 | |||
| 55 | /* update the scanout addresses */ | ||
| 56 | if (radeon_crtc->crtc_id) { | ||
| 57 | WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
| 58 | WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
| 59 | } else { | ||
| 60 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
| 61 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
| 62 | } | ||
| 63 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
| 64 | (u32)crtc_base); | ||
| 65 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
| 66 | (u32)crtc_base); | ||
| 67 | |||
| 68 | /* Wait for update_pending to go high. */ | ||
| 69 | while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); | ||
| 70 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | ||
| 71 | |||
| 72 | /* Unlock the lock, so double-buffering can take place inside vblank */ | ||
| 73 | tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; | ||
| 74 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
| 75 | |||
| 76 | /* Return current update_pending status: */ | ||
| 77 | return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; | ||
| 78 | } | ||
| 44 | 79 | ||
| 45 | /* get temperature in millidegrees */ | 80 | /* get temperature in millidegrees */ |
| 46 | u32 rv770_get_temp(struct radeon_device *rdev) | 81 | u32 rv770_get_temp(struct radeon_device *rdev) |
| @@ -489,6 +524,49 @@ static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
| 489 | return backend_map; | 524 | return backend_map; |
| 490 | } | 525 | } |
| 491 | 526 | ||
| 527 | static void rv770_program_channel_remap(struct radeon_device *rdev) | ||
| 528 | { | ||
| 529 | u32 tcp_chan_steer, mc_shared_chremap, tmp; | ||
| 530 | bool force_no_swizzle; | ||
| 531 | |||
| 532 | switch (rdev->family) { | ||
| 533 | case CHIP_RV770: | ||
| 534 | case CHIP_RV730: | ||
| 535 | force_no_swizzle = false; | ||
| 536 | break; | ||
| 537 | case CHIP_RV710: | ||
| 538 | case CHIP_RV740: | ||
| 539 | default: | ||
| 540 | force_no_swizzle = true; | ||
| 541 | break; | ||
| 542 | } | ||
| 543 | |||
| 544 | tmp = RREG32(MC_SHARED_CHMAP); | ||
| 545 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
| 546 | case 0: | ||
| 547 | case 1: | ||
| 548 | default: | ||
| 549 | /* default mapping */ | ||
| 550 | mc_shared_chremap = 0x00fac688; | ||
| 551 | break; | ||
| 552 | case 2: | ||
| 553 | case 3: | ||
| 554 | if (force_no_swizzle) | ||
| 555 | mc_shared_chremap = 0x00fac688; | ||
| 556 | else | ||
| 557 | mc_shared_chremap = 0x00bbc298; | ||
| 558 | break; | ||
| 559 | } | ||
| 560 | |||
| 561 | if (rdev->family == CHIP_RV740) | ||
| 562 | tcp_chan_steer = 0x00ef2a60; | ||
| 563 | else | ||
| 564 | tcp_chan_steer = 0x00fac688; | ||
| 565 | |||
| 566 | WREG32(TCP_CHAN_STEER, tcp_chan_steer); | ||
| 567 | WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); | ||
| 568 | } | ||
| 569 | |||
| 492 | static void rv770_gpu_init(struct radeon_device *rdev) | 570 | static void rv770_gpu_init(struct radeon_device *rdev) |
| 493 | { | 571 | { |
| 494 | int i, j, num_qd_pipes; | 572 | int i, j, num_qd_pipes; |
| @@ -688,6 +766,8 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
| 688 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | 766 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); |
| 689 | WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | 767 | WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); |
| 690 | 768 | ||
| 769 | rv770_program_channel_remap(rdev); | ||
| 770 | |||
| 691 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); | 771 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); |
| 692 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | 772 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
| 693 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | 773 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
| @@ -956,6 +1036,45 @@ static void rv770_vram_scratch_fini(struct radeon_device *rdev) | |||
| 956 | radeon_bo_unref(&rdev->vram_scratch.robj); | 1036 | radeon_bo_unref(&rdev->vram_scratch.robj); |
| 957 | } | 1037 | } |
| 958 | 1038 | ||
| 1039 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | ||
| 1040 | { | ||
| 1041 | u64 size_bf, size_af; | ||
| 1042 | |||
| 1043 | if (mc->mc_vram_size > 0xE0000000) { | ||
| 1044 | /* leave room for at least 512M GTT */ | ||
| 1045 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
| 1046 | mc->real_vram_size = 0xE0000000; | ||
| 1047 | mc->mc_vram_size = 0xE0000000; | ||
| 1048 | } | ||
| 1049 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 1050 | size_bf = mc->gtt_start; | ||
| 1051 | size_af = 0xFFFFFFFF - mc->gtt_end + 1; | ||
| 1052 | if (size_bf > size_af) { | ||
| 1053 | if (mc->mc_vram_size > size_bf) { | ||
| 1054 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
| 1055 | mc->real_vram_size = size_bf; | ||
| 1056 | mc->mc_vram_size = size_bf; | ||
| 1057 | } | ||
| 1058 | mc->vram_start = mc->gtt_start - mc->mc_vram_size; | ||
| 1059 | } else { | ||
| 1060 | if (mc->mc_vram_size > size_af) { | ||
| 1061 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
| 1062 | mc->real_vram_size = size_af; | ||
| 1063 | mc->mc_vram_size = size_af; | ||
| 1064 | } | ||
| 1065 | mc->vram_start = mc->gtt_end; | ||
| 1066 | } | ||
| 1067 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | ||
| 1068 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | ||
| 1069 | mc->mc_vram_size >> 20, mc->vram_start, | ||
| 1070 | mc->vram_end, mc->real_vram_size >> 20); | ||
| 1071 | } else { | ||
| 1072 | radeon_vram_location(rdev, &rdev->mc, 0); | ||
| 1073 | rdev->mc.gtt_base_align = 0; | ||
| 1074 | radeon_gtt_location(rdev, mc); | ||
| 1075 | } | ||
| 1076 | } | ||
| 1077 | |||
| 959 | int rv770_mc_init(struct radeon_device *rdev) | 1078 | int rv770_mc_init(struct radeon_device *rdev) |
| 960 | { | 1079 | { |
| 961 | u32 tmp; | 1080 | u32 tmp; |
| @@ -996,7 +1115,7 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
| 996 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1115 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
| 997 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1116 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 998 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 1117 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; |
| 999 | r600_vram_gtt_location(rdev, &rdev->mc); | 1118 | r700_vram_gtt_location(rdev, &rdev->mc); |
| 1000 | radeon_update_bandwidth_info(rdev); | 1119 | radeon_update_bandwidth_info(rdev); |
| 1001 | 1120 | ||
| 1002 | return 0; | 1121 | return 0; |
| @@ -1006,6 +1125,9 @@ static int rv770_startup(struct radeon_device *rdev) | |||
| 1006 | { | 1125 | { |
| 1007 | int r; | 1126 | int r; |
| 1008 | 1127 | ||
| 1128 | /* enable pcie gen2 link */ | ||
| 1129 | rv770_pcie_gen2_enable(rdev); | ||
| 1130 | |||
| 1009 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 1131 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
| 1010 | r = r600_init_microcode(rdev); | 1132 | r = r600_init_microcode(rdev); |
| 1011 | if (r) { | 1133 | if (r) { |
| @@ -1244,3 +1366,75 @@ void rv770_fini(struct radeon_device *rdev) | |||
| 1244 | rdev->bios = NULL; | 1366 | rdev->bios = NULL; |
| 1245 | radeon_dummy_page_fini(rdev); | 1367 | radeon_dummy_page_fini(rdev); |
| 1246 | } | 1368 | } |
| 1369 | |||
| 1370 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev) | ||
| 1371 | { | ||
| 1372 | u32 link_width_cntl, lanes, speed_cntl, tmp; | ||
| 1373 | u16 link_cntl2; | ||
| 1374 | |||
| 1375 | if (rdev->flags & RADEON_IS_IGP) | ||
| 1376 | return; | ||
| 1377 | |||
| 1378 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
| 1379 | return; | ||
| 1380 | |||
| 1381 | /* x2 cards have a special sequence */ | ||
| 1382 | if (ASIC_IS_X2(rdev)) | ||
| 1383 | return; | ||
| 1384 | |||
| 1385 | /* advertise upconfig capability */ | ||
| 1386 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 1387 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
| 1388 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 1389 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 1390 | if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { | ||
| 1391 | lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; | ||
| 1392 | link_width_cntl &= ~(LC_LINK_WIDTH_MASK | | ||
| 1393 | LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
| 1394 | link_width_cntl |= lanes | LC_RECONFIG_NOW | | ||
| 1395 | LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT; | ||
| 1396 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 1397 | } else { | ||
| 1398 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
| 1399 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 1403 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
| 1404 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
| 1405 | |||
| 1406 | tmp = RREG32(0x541c); | ||
| 1407 | WREG32(0x541c, tmp | 0x8); | ||
| 1408 | WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); | ||
| 1409 | link_cntl2 = RREG16(0x4088); | ||
| 1410 | link_cntl2 &= ~TARGET_LINK_SPEED_MASK; | ||
| 1411 | link_cntl2 |= 0x2; | ||
| 1412 | WREG16(0x4088, link_cntl2); | ||
| 1413 | WREG32(MM_CFGREGS_CNTL, 0); | ||
| 1414 | |||
| 1415 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 1416 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
| 1417 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 1418 | |||
| 1419 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 1420 | speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
| 1421 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 1422 | |||
| 1423 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 1424 | speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
| 1425 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 1426 | |||
| 1427 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
| 1428 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
| 1429 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
| 1430 | |||
| 1431 | } else { | ||
| 1432 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
| 1433 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
| 1434 | if (1) | ||
| 1435 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
| 1436 | else | ||
| 1437 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
| 1438 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
| 1439 | } | ||
| 1440 | } | ||
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index b7a5a20e81dc..abc8cf5a3672 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
| @@ -138,6 +138,7 @@ | |||
| 138 | #define MC_SHARED_CHMAP 0x2004 | 138 | #define MC_SHARED_CHMAP 0x2004 |
| 139 | #define NOOFCHAN_SHIFT 12 | 139 | #define NOOFCHAN_SHIFT 12 |
| 140 | #define NOOFCHAN_MASK 0x00003000 | 140 | #define NOOFCHAN_MASK 0x00003000 |
| 141 | #define MC_SHARED_CHREMAP 0x2008 | ||
| 141 | 142 | ||
| 142 | #define MC_ARB_RAMCFG 0x2760 | 143 | #define MC_ARB_RAMCFG 0x2760 |
| 143 | #define NOOFBANK_SHIFT 0 | 144 | #define NOOFBANK_SHIFT 0 |
| @@ -303,6 +304,7 @@ | |||
| 303 | #define BILINEAR_PRECISION_8_BIT (1 << 31) | 304 | #define BILINEAR_PRECISION_8_BIT (1 << 31) |
| 304 | 305 | ||
| 305 | #define TCP_CNTL 0x9610 | 306 | #define TCP_CNTL 0x9610 |
| 307 | #define TCP_CHAN_STEER 0x9614 | ||
| 306 | 308 | ||
| 307 | #define VGT_CACHE_INVALIDATION 0x88C4 | 309 | #define VGT_CACHE_INVALIDATION 0x88C4 |
| 308 | #define CACHE_INVALIDATION(x) ((x)<<0) | 310 | #define CACHE_INVALIDATION(x) ((x)<<0) |
| @@ -351,4 +353,49 @@ | |||
| 351 | 353 | ||
| 352 | #define SRBM_STATUS 0x0E50 | 354 | #define SRBM_STATUS 0x0E50 |
| 353 | 355 | ||
| 356 | #define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 | ||
| 357 | #define D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 | ||
| 358 | #define D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 | ||
| 359 | #define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 | ||
| 360 | #define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c | ||
| 361 | #define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c | ||
| 362 | |||
| 363 | /* PCIE link stuff */ | ||
| 364 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ | ||
| 365 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ | ||
| 366 | # define LC_LINK_WIDTH_SHIFT 0 | ||
| 367 | # define LC_LINK_WIDTH_MASK 0x7 | ||
| 368 | # define LC_LINK_WIDTH_X0 0 | ||
| 369 | # define LC_LINK_WIDTH_X1 1 | ||
| 370 | # define LC_LINK_WIDTH_X2 2 | ||
| 371 | # define LC_LINK_WIDTH_X4 3 | ||
| 372 | # define LC_LINK_WIDTH_X8 4 | ||
| 373 | # define LC_LINK_WIDTH_X16 6 | ||
| 374 | # define LC_LINK_WIDTH_RD_SHIFT 4 | ||
| 375 | # define LC_LINK_WIDTH_RD_MASK 0x70 | ||
| 376 | # define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) | ||
| 377 | # define LC_RECONFIG_NOW (1 << 8) | ||
| 378 | # define LC_RENEGOTIATION_SUPPORT (1 << 9) | ||
| 379 | # define LC_RENEGOTIATE_EN (1 << 10) | ||
| 380 | # define LC_SHORT_RECONFIG_EN (1 << 11) | ||
| 381 | # define LC_UPCONFIGURE_SUPPORT (1 << 12) | ||
| 382 | # define LC_UPCONFIGURE_DIS (1 << 13) | ||
| 383 | #define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ | ||
| 384 | # define LC_GEN2_EN_STRAP (1 << 0) | ||
| 385 | # define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) | ||
| 386 | # define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) | ||
| 387 | # define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) | ||
| 388 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) | ||
| 389 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 | ||
| 390 | # define LC_CURRENT_DATA_RATE (1 << 11) | ||
| 391 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) | ||
| 392 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) | ||
| 393 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) | ||
| 394 | # define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) | ||
| 395 | #define MM_CFGREGS_CNTL 0x544c | ||
| 396 | # define MM_WR_TO_CFG_EN (1 << 3) | ||
| 397 | #define LINK_CNTL2 0x88 /* F0 */ | ||
| 398 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | ||
| 399 | # define SELECTABLE_DEEMPHASIS (1 << 6) | ||
| 400 | |||
| 354 | #endif | 401 | #endif |
