diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios.h | 127 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ci_dpm.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ci_smc.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 504 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cik_sdma.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cikd.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/dce6_afmt.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_hdmi.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 94 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_family.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ucode.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_uvd.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rs690.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv515.c | 8 |
20 files changed, 870 insertions, 156 deletions
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index af10f85..92be50c 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -1711,7 +1711,9 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V6 #define PIXEL_CLOCK_V6_MISC_HDMI_BPP_MASK 0x0c #define PIXEL_CLOCK_V6_MISC_HDMI_24BPP 0x00 #define PIXEL_CLOCK_V6_MISC_HDMI_36BPP 0x04 +#define PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6 0x08 //for V6, the correct defintion for 36bpp should be 2 for 36bpp(2:1) #define PIXEL_CLOCK_V6_MISC_HDMI_30BPP 0x08 +#define PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6 0x04 //for V6, the correct defintion for 30bpp should be 1 for 36bpp(5:4) #define PIXEL_CLOCK_V6_MISC_HDMI_48BPP 0x0c #define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC 0x10 #define PIXEL_CLOCK_V6_MISC_GEN_DPREFCLK 0x40 @@ -2223,7 +2225,7 @@ typedef struct _SET_VOLTAGE_PARAMETERS_V2 USHORT usVoltageLevel; // real voltage level }SET_VOLTAGE_PARAMETERS_V2; - +// used by both SetVoltageTable v1.3 and v1.4 typedef struct _SET_VOLTAGE_PARAMETERS_V1_3 { UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI @@ -2290,15 +2292,36 @@ typedef struct _GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1 #define ATOM_GET_VOLTAGE_VID 0x00 #define ATOM_GET_VOTLAGE_INIT_SEQ 0x03 #define ATOM_GET_VOLTTAGE_PHASE_PHASE_VID 0x04 -// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state -#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10 +#define ATOM_GET_VOLTAGE_SVID2 0x07 //Get SVI2 Regulator Info +// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state +#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10 // for SI, this state map to 0xff01 voltage state in Power Play table, which is performance state #define ATOM_GET_VOLTAGE_STATE1_LEAKAGE_VID 0x11 -// undefined power state + #define ATOM_GET_VOLTAGE_STATE2_LEAKAGE_VID 0x12 #define ATOM_GET_VOLTAGE_STATE3_LEAKAGE_VID 0x13 +// New Added from CI Hawaii for GetVoltageInfoTable, input parameter structure +typedef struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 +{ + UCHAR ucVoltageType; // Input: To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI + UCHAR ucVoltageMode; // Input: Indicate action: Get voltage info + USHORT usVoltageLevel; // Input: real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) or Leakage Id + ULONG ulSCLKFreq; // Input: when ucVoltageMode= ATOM_GET_VOLTAGE_EVV_VOLTAGE, DPM state SCLK frequency, Define in PPTable SCLK/Voltage dependence table +}GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2; + +// New in GetVoltageInfo v1.2 ucVoltageMode +#define ATOM_GET_VOLTAGE_EVV_VOLTAGE 0x09 + +// New Added from CI Hawaii for EVV feature +typedef struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 +{ + USHORT usVoltageLevel; // real voltage level in unit of mv + USHORT usVoltageId; // Voltage Id programmed in Voltage Regulator + ULONG ulReseved; +}GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2; + /****************************************************************************/ // Structures used by TVEncoderControlTable /****************************************************************************/ @@ -3864,6 +3887,8 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT #define PP_AC_DC_SWITCH_GPIO_PINID 60 //from SMU7.x, if ucGPIO_ID=VDDC_REGULATOR_VRHOT_GPIO_PINID in GPIO_LUTable, VRHot feature is enable #define VDDC_VRHOT_GPIO_PINID 61 +//if ucGPIO_ID=VDDC_PCC_GPIO_PINID in GPIO_LUTable, Peak Current Control feature is enabled +#define VDDC_PCC_GPIO_PINID 62 typedef struct _ATOM_GPIO_PIN_LUT { @@ -4169,10 +4194,10 @@ typedef struct _ATOM_COMMON_RECORD_HEADER #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 #define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19 #define ATOM_ENCODER_CAP_RECORD_TYPE 20 - +#define ATOM_BRACKET_LAYOUT_RECORD_TYPE 21 //Must be updated when new record type is added,equal to that record definition! -#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_ENCODER_CAP_RECORD_TYPE +#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_BRACKET_LAYOUT_RECORD_TYPE typedef struct _ATOM_I2C_RECORD { @@ -4397,6 +4422,31 @@ typedef struct _ATOM_CONNECTOR_REMOTE_CAP_RECORD USHORT usReserved; }ATOM_CONNECTOR_REMOTE_CAP_RECORD; +typedef struct _ATOM_CONNECTOR_LAYOUT_INFO +{ + USHORT usConnectorObjectId; + UCHAR ucConnectorType; + UCHAR ucPosition; +}ATOM_CONNECTOR_LAYOUT_INFO; + +// define ATOM_CONNECTOR_LAYOUT_INFO.ucConnectorType to describe the display connector size +#define CONNECTOR_TYPE_DVI_D 1 +#define CONNECTOR_TYPE_DVI_I 2 +#define CONNECTOR_TYPE_VGA 3 +#define CONNECTOR_TYPE_HDMI 4 +#define CONNECTOR_TYPE_DISPLAY_PORT 5 +#define CONNECTOR_TYPE_MINI_DISPLAY_PORT 6 + +typedef struct _ATOM_BRACKET_LAYOUT_RECORD +{ + ATOM_COMMON_RECORD_HEADER sheader; + UCHAR ucLength; + UCHAR ucWidth; + UCHAR ucConnNum; + UCHAR ucReserved; + ATOM_CONNECTOR_LAYOUT_INFO asConnInfo[1]; +}ATOM_BRACKET_LAYOUT_RECORD; + /****************************************************************************/ // ASIC voltage data table /****************************************************************************/ @@ -4524,8 +4574,9 @@ typedef struct _ATOM_VOLTAGE_OBJECT_HEADER_V3{ #define VOLTAGE_OBJ_VR_I2C_INIT_SEQ 3 //VOLTAGE REGULATOR INIT sequece through I2C -> ATOM_I2C_VOLTAGE_OBJECT_V3 #define VOLTAGE_OBJ_PHASE_LUT 4 //Set Vregulator Phase lookup table ->ATOM_GPIO_VOLTAGE_OBJECT_V3 #define VOLTAGE_OBJ_SVID2 7 //Indicate voltage control by SVID2 ->ATOM_SVID2_VOLTAGE_OBJECT_V3 -#define VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT 0x10 //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 -#define VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT 0x11 //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 +#define VOLTAGE_OBJ_EVV 8 +#define VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT 0x10 //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 +#define VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT 0x11 //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 #define VOLTAGE_OBJ_HIGH1_STATE_LEAKAGE_LUT 0x12 //High1 voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 typedef struct _VOLTAGE_LUT_ENTRY_V2 @@ -4552,6 +4603,10 @@ typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3 VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff }ATOM_I2C_VOLTAGE_OBJECT_V3; +// ATOM_I2C_VOLTAGE_OBJECT_V3.ucVoltageControlFlag +#define VOLTAGE_DATA_ONE_BYTE 0 +#define VOLTAGE_DATA_TWO_BYTE 1 + typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3 { ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; // voltage mode = VOLTAGE_OBJ_GPIO_LUT or VOLTAGE_OBJ_PHASE_LUT @@ -4584,7 +4639,8 @@ typedef struct _ATOM_SVID2_VOLTAGE_OBJECT_V3 // 1:0 offset trim, USHORT usLoadLine_PSI; // GPU GPIO pin Id to SVID2 regulator VRHot pin. possible value 0~31. 0 means GPIO0, 31 means GPIO31 - UCHAR ucReserved[2]; + UCHAR ucSVDGpioId; //0~31 indicate GPIO0~31 + UCHAR ucSVCGpioId; //0~31 indicate GPIO0~31 ULONG ulReserved; }ATOM_SVID2_VOLTAGE_OBJECT_V3; @@ -4637,6 +4693,49 @@ typedef struct _ATOM_ASIC_PROFILING_INFO_V2_1 USHORT usElbVDDCI_LevelArrayOffset; // offset of 2 dimension voltage level USHORT array }ATOM_ASIC_PROFILING_INFO_V2_1; +typedef struct _ATOM_ASIC_PROFILING_INFO_V3_1 +{ + ATOM_COMMON_TABLE_HEADER asHeader; + ULONG ulEvvDerateTdp; + ULONG ulEvvDerateTdc; + ULONG ulBoardCoreTemp; + ULONG ulMaxVddc; + ULONG ulMinVddc; + ULONG ulLoadLineSlop; + ULONG ulLeakageTemp; + ULONG ulLeakageVoltage; + ULONG ulCACmEncodeRange; + ULONG ulCACmEncodeAverage; + ULONG ulCACbEncodeRange; + ULONG ulCACbEncodeAverage; + ULONG ulKt_bEncodeRange; + ULONG ulKt_bEncodeAverage; + ULONG ulKv_mEncodeRange; + ULONG ulKv_mEncodeAverage; + ULONG ulKv_bEncodeRange; + ULONG ulKv_bEncodeAverage; + ULONG ulLkgEncodeLn_MaxDivMin; + ULONG ulLkgEncodeMin; + ULONG ulEfuseLogisticAlpha; + USHORT usPowerDpm0; + USHORT usCurrentDpm0; + USHORT usPowerDpm1; + USHORT usCurrentDpm1; + USHORT usPowerDpm2; + USHORT usCurrentDpm2; + USHORT usPowerDpm3; + USHORT usCurrentDpm3; + USHORT usPowerDpm4; + USHORT usCurrentDpm4; + USHORT usPowerDpm5; + USHORT usCurrentDpm5; + USHORT usPowerDpm6; + USHORT usCurrentDpm6; + USHORT usPowerDpm7; + USHORT usCurrentDpm7; +}ATOM_ASIC_PROFILING_INFO_V3_1; + + typedef struct _ATOM_POWER_SOURCE_OBJECT { UCHAR ucPwrSrcId; // Power source @@ -5808,6 +5907,8 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S7_DOS_MODE_PIXEL_DEPTHb0 0x0C #define ATOM_S7_DOS_MODE_PIXEL_FORMATb0 0xF0 #define ATOM_S7_DOS_8BIT_DAC_ENb1 0x01 +#define ATOM_S7_ASIC_INIT_COMPLETEb1 0x02 +#define ATOM_S7_ASIC_INIT_COMPLETE_MASK 0x00000200 #define ATOM_S7_DOS_MODE_NUMBERw1 0x0FFFF #define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT 8 @@ -6242,6 +6343,7 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE #define _128Mx32 0x53 #define _256Mx8 0x61 #define _256Mx16 0x62 +#define _512Mx8 0x71 #define SAMSUNG 0x1 #define INFINEON 0x2 @@ -6987,9 +7089,10 @@ typedef struct _ATOM_DISP_OUT_INFO_V3 UCHAR ucMaxDispEngineNum; UCHAR ucMaxActiveDispEngineNum; UCHAR ucMaxPPLLNum; - UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE - UCHAR ucReserved[3]; - ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only + UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE + UCHAR ucDispCaps; + UCHAR ucReserved[2]; + ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only }ATOM_DISP_OUT_INFO_V3; //ucDispCaps diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 86d9ee0..80a2012 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1910,6 +1910,21 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) int i; atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + if (crtc->fb) { + int r; + struct radeon_framebuffer *radeon_fb; + struct radeon_bo *rbo; + + radeon_fb = to_radeon_framebuffer(crtc->fb); + rbo = gem_to_radeon_bo(radeon_fb->obj); + r = radeon_bo_reserve(rbo, false); + if (unlikely(r)) + DRM_ERROR("failed to reserve rbo before unpin\n"); + else { + radeon_bo_unpin(rbo); + radeon_bo_unreserve(rbo); + } + } /* disable the GRPH */ if (ASIC_IS_DCE4(rdev)) WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 0); @@ -1940,7 +1955,9 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) break; case ATOM_PPLL0: /* disable the ppll */ - if ((rdev->family == CHIP_ARUBA) || (rdev->family == CHIP_BONAIRE)) + if ((rdev->family == CHIP_ARUBA) || + (rdev->family == CHIP_BONAIRE) || + (rdev->family == CHIP_HAWAII)) atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); break; diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 51e947a..1ed4799 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -40,6 +40,20 @@ #define VOLTAGE_VID_OFFSET_SCALE1 625 #define VOLTAGE_VID_OFFSET_SCALE2 100 +static const struct ci_pt_defaults defaults_hawaii_xt = +{ + 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0xB0000, + { 0x84, 0x0, 0x0, 0x7F, 0x0, 0x0, 0x5A, 0x60, 0x51, 0x8E, 0x79, 0x6B, 0x5F, 0x90, 0x79 }, + { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC } +}; + +static const struct ci_pt_defaults defaults_hawaii_pro = +{ + 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0x65062, + { 0x93, 0x0, 0x0, 0x97, 0x0, 0x0, 0x6B, 0x60, 0x51, 0x95, 0x79, 0x6B, 0x5F, 0x90, 0x79 }, + { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC } +}; + static const struct ci_pt_defaults defaults_bonaire_xt = { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, @@ -187,22 +201,38 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev) struct ci_power_info *pi = ci_get_pi(rdev); switch (rdev->pdev->device) { - case 0x6650: - case 0x6658: - case 0x665C: - default: + case 0x6650: + case 0x6658: + case 0x665C: + default: pi->powertune_defaults = &defaults_bonaire_xt; break; - case 0x6651: - case 0x665D: + case 0x6651: + case 0x665D: pi->powertune_defaults = &defaults_bonaire_pro; break; - case 0x6640: + case 0x6640: pi->powertune_defaults = &defaults_saturn_xt; break; - case 0x6641: + case 0x6641: pi->powertune_defaults = &defaults_saturn_pro; break; + case 0x67B8: + case 0x67B0: + case 0x67A0: + case 0x67A1: + case 0x67A2: + case 0x67A8: + case 0x67A9: + case 0x67AA: + case 0x67B9: + case 0x67BE: + pi->powertune_defaults = &defaults_hawaii_xt; + break; + case 0x67BA: + case 0x67B1: + pi->powertune_defaults = &defaults_hawaii_pro; + break; } pi->dte_tj_offset = 0; @@ -5142,9 +5172,15 @@ int ci_dpm_init(struct radeon_device *rdev) rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0; rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL; - pi->thermal_temp_setting.temperature_low = 99500; - pi->thermal_temp_setting.temperature_high = 100000; - pi->thermal_temp_setting.temperature_shutdown = 104000; + if (rdev->family == CHIP_HAWAII) { + pi->thermal_temp_setting.temperature_low = 94500; + pi->thermal_temp_setting.temperature_high = 95000; + pi->thermal_temp_setting.temperature_shutdown = 104000; + } else { + pi->thermal_temp_setting.temperature_low = 99500; + pi->thermal_temp_setting.temperature_high = 100000; + pi->thermal_temp_setting.temperature_shutdown = 104000; + } pi->uvd_enabled = false; diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c index 252e10a..9c745dd 100644 --- a/drivers/gpu/drm/radeon/ci_smc.c +++ b/drivers/gpu/drm/radeon/ci_smc.c @@ -217,6 +217,10 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit) ucode_start_address = BONAIRE_SMC_UCODE_START; ucode_size = BONAIRE_SMC_UCODE_SIZE; break; + case CHIP_HAWAII: + ucode_start_address = HAWAII_SMC_UCODE_START; + ucode_size = HAWAII_SMC_UCODE_SIZE; + break; default: DRM_ERROR("unknown asic in smc ucode loader\n"); BUG(); diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e854475..ae92aa0 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -41,6 +41,14 @@ MODULE_FIRMWARE("radeon/BONAIRE_mc.bin"); MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin"); MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin"); MODULE_FIRMWARE("radeon/BONAIRE_smc.bin"); +MODULE_FIRMWARE("radeon/HAWAII_pfp.bin"); +MODULE_FIRMWARE("radeon/HAWAII_me.bin"); +MODULE_FIRMWARE("radeon/HAWAII_ce.bin"); +MODULE_FIRMWARE("radeon/HAWAII_mec.bin"); +MODULE_FIRMWARE("radeon/HAWAII_mc.bin"); +MODULE_FIRMWARE("radeon/HAWAII_rlc.bin"); +MODULE_FIRMWARE("radeon/HAWAII_sdma.bin"); +MODULE_FIRMWARE("radeon/HAWAII_smc.bin"); MODULE_FIRMWARE("radeon/KAVERI_pfp.bin"); MODULE_FIRMWARE("radeon/KAVERI_me.bin"); MODULE_FIRMWARE("radeon/KAVERI_ce.bin"); @@ -1297,6 +1305,171 @@ static const u32 kalindi_mgcg_cgcg_init[] = 0xd80c, 0xff000ff0, 0x00000100 }; +static const u32 hawaii_golden_spm_registers[] = +{ + 0x30800, 0xe0ffffff, 0xe0000000 +}; + +static const u32 hawaii_golden_common_registers[] = +{ + 0x30800, 0xffffffff, 0xe0000000, + 0x28350, 0xffffffff, 0x3a00161a, + 0x28354, 0xffffffff, 0x0000002e, + 0x9a10, 0xffffffff, 0x00018208, + 0x98f8, 0xffffffff, 0x12011003 +}; + +static const u32 hawaii_golden_registers[] = +{ + 0x3354, 0x00000333, 0x00000333, + 0x9a10, 0x00010000, 0x00058208, + 0x9830, 0xffffffff, 0x00000000, + 0x9834, 0xf00fffff, 0x00000400, + 0x9838, 0x0002021c, 0x00020200, + 0xc78, 0x00000080, 0x00000000, + 0x5bb0, 0x000000f0, 0x00000070, + 0x5bc0, 0xf0311fff, 0x80300000, + 0x350c, 0x00810000, 0x408af000, + 0x7030, 0x31000111, 0x00000011, + 0x2f48, 0x73773777, 0x12010001, + 0x2120, 0x0000007f, 0x0000001b, + 0x21dc, 0x00007fb6, 0x00002191, + 0x3628, 0x0000003f, 0x0000000a, + 0x362c, 0x0000003f, 0x0000000a, + 0x2ae4, 0x00073ffe, 0x000022a2, + 0x240c, 0x000007ff, 0x00000000, + 0x8bf0, 0x00002001, 0x00000001, + 0x8b24, 0xffffffff, 0x00ffffff, + 0x30a04, 0x0000ff0f, 0x00000000, + 0x28a4c, 0x07ffffff, 0x06000000, + 0x3e78, 0x00000001, 0x00000002, + 0xc768, 0x00000008, 0x00000008, + 0xc770, 0x00000f00, 0x00000800, + 0xc774, 0x00000f00, 0x00000800, + 0xc798, 0x00ffffff, 0x00ff7fbf, + 0xc79c, 0x00ffffff, 0x00ff7faf, + 0x8c00, 0x000000ff, 0x00000800, + 0xe40, 0x00001fff, 0x00001fff, + 0x9060, 0x0000007f, 0x00000020, + 0x9508, 0x00010000, 0x00010000, + 0xae00, 0x00100000, 0x000ff07c, + 0xac14, 0x000003ff, 0x0000000f, + 0xac10, 0xffffffff, 0x7564fdec, + 0xac0c, 0xffffffff, 0x3120b9a8, + 0xac08, 0x20000000, 0x0f9c0000 +}; + +static const u32 hawaii_mgcg_cgcg_init[] = +{ + 0xc420, 0xffffffff, 0xfffffffd, + 0x30800, 0xffffffff, 0xe0000000, + 0x3c2a0, 0xffffffff, 0x00000100, + 0x3c208, 0xffffffff, 0x00000100, + 0x3c2c0, 0xffffffff, 0x00000100, + 0x3c2c8, 0xffffffff, 0x00000100, + 0x3c2c4, 0xffffffff, 0x00000100, + 0x55e4, 0xffffffff, 0x00200100, + 0x3c280, 0xffffffff, 0x00000100, + 0x3c214, 0xffffffff, 0x06000100, + 0x3c220, 0xffffffff, 0x00000100, + 0x3c218, 0xffffffff, 0x06000100, + 0x3c204, 0xffffffff, 0x00000100, + 0x3c2e0, 0xffffffff, 0x00000100, + 0x3c224, 0xffffffff, 0x00000100, + 0x3c200, 0xffffffff, 0x00000100, + 0x3c230, 0xffffffff, 0x00000100, + 0x3c234, 0xffffffff, 0x00000100, + 0x3c250, 0xffffffff, 0x00000100, + 0x3c254, 0xffffffff, 0x00000100, + 0x3c258, 0xffffffff, 0x00000100, + 0x3c25c, 0xffffffff, 0x00000100, + 0x3c260, 0xffffffff, 0x00000100, + 0x3c27c, 0xffffffff, 0x00000100, + 0x3c278, 0xffffffff, 0x00000100, + 0x3c210, 0xffffffff, 0x06000100, + 0x3c290, 0xffffffff, 0x00000100, + 0x3c274, 0xffffffff, 0x00000100, + 0x3c2b4, 0xffffffff, 0x00000100, + 0x3c2b0, 0xffffffff, 0x00000100, + 0x3c270, 0xffffffff, 0x00000100, + 0x30800, 0xffffffff, 0xe0000000, + 0x3c020, 0xffffffff, 0x00010000, + 0x3c024, 0xffffffff, 0x00030002, + 0x3c028, 0xffffffff, 0x00040007, + 0x3c02c, 0xffffffff, 0x00060005, + 0x3c030, 0xffffffff, 0x00090008, + 0x3c034, 0xffffffff, 0x00010000, + 0x3c038, 0xffffffff, 0x00030002, + 0x3c03c, 0xffffffff, 0x00040007, + 0x3c040, 0xffffffff, 0x00060005, + 0x3c044, 0xffffffff, 0x00090008, + 0x3c048, 0xffffffff, 0x00010000, + 0x3c04c, 0xffffffff, 0x00030002, + 0x3c050, 0xffffffff, 0x00040007, + 0x3c054, 0xffffffff, 0x00060005, + 0x3c058, 0xffffffff, 0x00090008, + 0x3c05c, 0xffffffff, 0x00010000, + 0x3c060, 0xffffffff, 0x00030002, + 0x3c064, 0xffffffff, 0x00040007, + 0x3c068, 0xffffffff, 0x00060005, + 0x3c06c, 0xffffffff, 0x00090008, + 0x3c070, 0xffffffff, 0x00010000, + 0x3c074, 0xffffffff, 0x00030002, + 0x3c078, 0xffffffff, 0x00040007, + 0x3c07c, 0xffffffff, 0x00060005, + 0x3c080, 0xffffffff, 0x00090008, + 0x3c084, 0xffffffff, 0x00010000, + 0x3c088, 0xffffffff, 0x00030002, + 0x3c08c, 0xffffffff, 0x00040007, + 0x3c090, 0xffffffff, 0x00060005, + 0x3c094, 0xffffffff, 0x00090008, + 0x3c098, 0xffffffff, 0x00010000, + 0x3c09c, 0xffffffff, 0x00030002, + 0x3c0a0, 0xffffffff, 0x00040007, + 0x3c0a4, 0xffffffff, 0x00060005, + 0x3c0a8, 0xffffffff, 0x00090008, + 0x3c0ac, 0xffffffff, 0x00010000, + 0x3c0b0, 0xffffffff, 0x00030002, + 0x3c0b4, 0xffffffff, 0x00040007, + 0x3c0b8, 0xffffffff, 0x00060005, + 0x3c0bc, 0xffffffff, 0x00090008, + 0x3c0c0, 0xffffffff, 0x00010000, + 0x3c0c4, 0xffffffff, 0x00030002, + 0x3c0c8, 0xffffffff, 0x00040007, + 0x3c0cc, 0xffffffff, 0x00060005, + 0x3c0d0, 0xffffffff, 0x00090008, + 0x3c0d4, 0xffffffff, 0x00010000, + 0x3c0d8, 0xffffffff, 0x00030002, + 0x3c0dc, 0xffffffff, 0x00040007, + 0x3c0e0, 0xffffffff, 0x00060005, + 0x3c0e4, 0xffffffff, 0x00090008, + 0x3c0e8, 0xffffffff, 0x00010000, + 0x3c0ec, 0xffffffff, 0x00030002, + 0x3c0f0, 0xffffffff, 0x00040007, + 0x3c0f4, 0xffffffff, 0x00060005, + 0x3c0f8, 0xffffffff, 0x00090008, + 0xc318, 0xffffffff, 0x00020200, + 0x3350, 0xffffffff, 0x00000200, + 0x15c0, 0xffffffff, 0x00000400, + 0x55e8, 0xffffffff, 0x00000000, + 0x2f50, 0xffffffff, 0x00000902, + 0x3c000, 0xffffffff, 0x96940200, + 0x8708, 0xffffffff, 0x00900100, + 0xc424, 0xffffffff, 0x0020003f, + 0x38, 0xffffffff, 0x0140001c, + 0x3c, 0x000f0000, 0x000f0000, + 0x220, 0xffffffff, 0xc060000c, + 0x224, 0xc0000fff, 0x00000100, + 0xf90, 0xffffffff, 0x00000100, + 0xf98, 0x00000101, 0x00000000, + 0x20a8, 0xffffffff, 0x00000104, + 0x55e4, 0xff000fff, 0x00000100, + 0x30cc, 0xc0000fff, 0x00000104, + 0xc1e4, 0x00000001, 0x00000001, + 0xd00c, 0xff000ff0, 0x00000100, + 0xd80c, 0xff000ff0, 0x00000100 +}; + static void cik_init_golden_registers(struct radeon_device *rdev) { switch (rdev->family) { @@ -1342,6 +1515,20 @@ static void cik_init_golden_registers(struct radeon_device *rdev) spectre_golden_spm_registers, (const u32)ARRAY_SIZE(spectre_golden_spm_registers)); break; + case CHIP_HAWAII: + radeon_program_register_sequence(rdev, + hawaii_mgcg_cgcg_init, + (const u32)ARRAY_SIZE(hawaii_mgcg_cgcg_init)); + radeon_program_register_sequence(rdev, + hawaii_golden_registers, + (const u32)ARRAY_SIZE(hawaii_golden_registers)); + radeon_program_register_sequence(rdev, + hawaii_golden_common_registers, + (const u32)ARRAY_SIZE(hawaii_golden_common_registers)); + radeon_program_register_sequence(rdev, + hawaii_golden_spm_registers, + (const u32)ARRAY_SIZE(hawaii_golden_spm_registers)); + break; default: break; } @@ -1449,6 +1636,35 @@ static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] = {0x0000009f, 0x00b48000} }; +#define HAWAII_IO_MC_REGS_SIZE 22 + +static const u32 hawaii_io_mc_regs[HAWAII_IO_MC_REGS_SIZE][2] = +{ + {0x0000007d, 0x40000000}, + {0x0000007e, 0x40180304}, + {0x0000007f, 0x0000ff00}, + {0x00000081, 0x00000000}, + {0x00000083, 0x00000800}, + {0x00000086, 0x00000000}, + {0x00000087, 0x00000100}, + {0x00000088, 0x00020100}, + {0x00000089, 0x00000000}, + {0x0000008b, 0x00040000}, + {0x0000008c, 0x00000100}, + {0x0000008e, 0xff010000}, + {0x00000090, 0xffffefff}, + {0x00000091, 0xfff3efff}, + {0x00000092, 0xfff3efbf}, + {0x00000093, 0xf7ffffff}, + {0x00000094, 0xffffff7f}, + {0x00000095, 0x00000fff}, + {0x00000096, 0x00116fff}, + {0x00000097, 0x60010000}, + {0x00000098, 0x10010000}, + {0x0000009f, 0x00c79000} +}; + + /** * cik_srbm_select - select specific register instances * @@ -1493,11 +1709,17 @@ static int ci_mc_load_microcode(struct radeon_device *rdev) switch (rdev->family) { case CHIP_BONAIRE: - default: io_mc_regs = (u32 *)&bonaire_io_mc_regs; ucode_size = CIK_MC_UCODE_SIZE; regs_size = BONAIRE_IO_MC_REGS_SIZE; break; + case CHIP_HAWAII: + io_mc_regs = (u32 *)&hawaii_io_mc_regs; + ucode_size = HAWAII_MC_UCODE_SIZE; + regs_size = HAWAII_IO_MC_REGS_SIZE; + break; + default: + return -EINVAL; } running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; @@ -1559,8 +1781,8 @@ static int cik_init_microcode(struct radeon_device *rdev) { const char *chip_name; size_t pfp_req_size, me_req_size, ce_req_size, - mec_req_size, rlc_req_size, mc_req_size, - sdma_req_size, smc_req_size; + mec_req_size, rlc_req_size, mc_req_size = 0, + sdma_req_size, smc_req_size = 0; char fw_name[30]; int err; @@ -1578,6 +1800,17 @@ static int cik_init_microcode(struct radeon_device *rdev) sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4); break; + case CHIP_HAWAII: + chip_name = "HAWAII"; + pfp_req_size = CIK_PFP_UCODE_SIZE * 4; + me_req_size = CIK_ME_UCODE_SIZE * 4; + ce_req_size = CIK_CE_UCODE_SIZE * 4; + mec_req_size = CIK_MEC_UCODE_SIZE * 4; + rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4; + mc_req_size = HAWAII_MC_UCODE_SIZE * 4; + sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; + smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4); + break; case CHIP_KAVERI: chip_name = "KAVERI"; pfp_req_size = CIK_PFP_UCODE_SIZE * 4; @@ -1758,9 +1991,227 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev) num_pipe_configs = rdev->config.cik.max_tile_pipes; if (num_pipe_configs > 8) - num_pipe_configs = 8; /* ??? */ + num_pipe_configs = 16; - if (num_pipe_configs == 8) { + if (num_pipe_configs == 16) { + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { + switch (reg_offset) { + case 0: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B)); + break; + case 1: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B)); + break; + case 2: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); + break; + case 3: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B)); + break; + case 4: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(split_equal_to_row_size)); + break; + case 5: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + break; + case 6: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); + break; + case 7: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(split_equal_to_row_size)); + break; + case 8: + gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16)); + break; + case 9: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); + break; + case 10: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 11: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 12: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 13: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); + break; + case 14: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 16: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 17: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 27: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); + break; + case 28: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 29: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 30: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + default: + gb_tile_moden = 0; + break; + } + rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden; + WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); + } + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { + switch (reg_offset) { + case 0: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 1: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 2: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 3: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 4: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + break; + case 5: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + break; + case 6: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_2_BANK)); + break; + case 8: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 9: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 10: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 11: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + break; + case 12: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + break; + case 13: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_2_BANK)); + break; + case 14: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_2_BANK)); + break; + default: + gb_tile_moden = 0; + break; + } + WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden); + } + } else if (num_pipe_configs == 8) { for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { switch (reg_offset) { case 0: @@ -2645,7 +3096,10 @@ static void cik_setup_rb(struct radeon_device *rdev, for (j = 0; j < sh_per_se; j++) { cik_select_se_sh(rdev, i, j); data = cik_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); - disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); + if (rdev->family == CHIP_HAWAII) + disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH); + else + disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); } } cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); @@ -2662,6 +3116,12 @@ static void cik_setup_rb(struct radeon_device *rdev, data = 0; for (j = 0; j < sh_per_se; j++) { switch (enabled_rbs & 3) { + case 0: + if (j == 0) + data |= PKR_MAP(RASTER_CONFIG_RB_MAP_3); + else + data |= PKR_MAP(RASTER_CONFIG_RB_MAP_0); + break; case 1: data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2); break; @@ -2714,6 +3174,23 @@ static void cik_gpu_init(struct radeon_device *rdev) rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; break; + case CHIP_HAWAII: + rdev->config.cik.max_shader_engines = 4; + rdev->config.cik.max_tile_pipes = 16; + rdev->config.cik.max_cu_per_sh = 11; + rdev->config.cik.max_sh_per_se = 1; + rdev->config.cik.max_backends_per_se = 4; + rdev->config.cik.max_texture_channel_caches = 16; + rdev->config.cik.max_gprs = 256; + rdev->config.cik.max_gs_threads = 32; + rdev->config.cik.max_hw_contexts = 8; + + rdev->config.cik.sc_prim_fifo_size_frontend = 0x20; + rdev->config.cik.sc_prim_fifo_size_backend = 0x100; + rdev->config.cik.sc_hiz_tile_fifo_size = 0x30; + rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = HAWAII_GB_ADDR_CONFIG_GOLDEN; + break; case CHIP_KAVERI: rdev->config.cik.max_shader_engines = 1; rdev->config.cik.max_tile_pipes = 4; @@ -3477,7 +3954,8 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev) int r; WREG32(CP_SEM_WAIT_TIMER, 0x0); - WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); + if (rdev->family != CHIP_HAWAII) + WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); /* Set the write pointer delay */ WREG32(CP_RB_WPTR_DELAY, 0); @@ -4814,12 +5292,17 @@ void cik_vm_fini(struct radeon_device *rdev) static void cik_vm_decode_fault(struct radeon_device *rdev, u32 status, u32 addr, u32 mc_client) { - u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; + u32 mc_id; u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT; u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT; char block[5] = { mc_client >> 24, (mc_client >> 16) & 0xff, (mc_client >> 8) & 0xff, mc_client & 0xff, 0 }; + if (rdev->family == CHIP_HAWAII) + mc_id = (status & HAWAII_MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; + else + mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; + printk("VM fault (0x%02x, vmid %d) at page %u, %s from '%s' (0x%08x) (%d)\n", protections, vmid, addr, (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read", @@ -5076,6 +5559,7 @@ static int cik_rlc_resume(struct radeon_device *rdev) switch (rdev->family) { case CHIP_BONAIRE: + case CHIP_HAWAII: default: size = BONAIRE_RLC_UCODE_SIZE; break; @@ -5832,6 +6316,10 @@ void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ buffer[count++] = cpu_to_le32(0x00000000); break; + case CHIP_HAWAII: + buffer[count++] = 0x3a00161a; + buffer[count++] = 0x0000002e; + break; default: buffer[count++] = cpu_to_le32(0x00000000); buffer[count++] = cpu_to_le32(0x00000000); diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 8d84ebe..9c9529d 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -102,14 +102,6 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, { struct radeon_ring *ring = &rdev->ring[fence->ring]; u64 addr = rdev->fence_drv[fence->ring].gpu_addr; - u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | - SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ - u32 ref_and_mask; - - if (fence->ring == R600_RING_TYPE_DMA_INDEX) - ref_and_mask = SDMA0; - else - ref_and_mask = SDMA1; /* write the fence */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_FENCE, 0, 0)); @@ -119,12 +111,12 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, /* generate an interrupt */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0)); /* flush HDP */ - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); - radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); - radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); - radeon_ring_write(ring, ref_and_mask); /* REFERENCE */ - radeon_ring_write(ring, ref_and_mask); /* MASK */ - radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */ + /* We should be using the new POLL_REG_MEM special op packet here + * but it causes sDMA to hang sometimes + */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); + radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); + radeon_ring_write(ring, 0); } /** @@ -720,18 +712,10 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) { struct radeon_ring *ring = &rdev->ring[ridx]; - u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | - SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ - u32 ref_and_mask; if (vm == NULL) return; - if (ridx == R600_RING_TYPE_DMA_INDEX) - ref_and_mask = SDMA0; - else - ref_and_mask = SDMA1; - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); if (vm->id < 8) { radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); @@ -766,12 +750,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm radeon_ring_write(ring, VMID(0)); /* flush HDP */ - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); - radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); - radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); - radeon_ring_write(ring, ref_and_mask); /* REFERENCE */ - radeon_ring_write(ring, ref_and_mask); /* MASK */ - radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */ + /* We should be using the new POLL_REG_MEM special op packet here + * but it causes sDMA to hang sometimes + */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); + radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); + radeon_ring_write(ring, 0); /* flush TLB */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 380cea3..5964af5 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -25,8 +25,10 @@ #define CIK_H #define BONAIRE_GB_ADDR_CONFIG_GOLDEN 0x12010001 +#define HAWAII_GB_ADDR_CONFIG_GOLDEN 0x12011003 -#define CIK_RB_BITMAP_WIDTH_PER_SH 2 +#define CIK_RB_BITMAP_WIDTH_PER_SH 2 +#define HAWAII_RB_BITMAP_WIDTH_PER_SH 4 /* DIDT IND registers */ #define DIDT_SQ_CTRL0 0x0 @@ -499,6 +501,7 @@ * bit 4: write */ #define MEMORY_CLIENT_ID_MASK (0xff << 12) +#define HAWAII_MEMORY_CLIENT_ID_MASK (0x1ff << 12) #define MEMORY_CLIENT_ID_SHIFT 12 #define MEMORY_CLIENT_RW_MASK (1 << 24) #define MEMORY_CLIENT_RW_SHIFT 24 @@ -1162,6 +1165,8 @@ # define ADDR_SURF_P8_32x32_16x16 12 # define ADDR_SURF_P8_32x32_16x32 13 # define ADDR_SURF_P8_32x64_32x32 14 +# define ADDR_SURF_P16_32x32_8x16 16 +# define ADDR_SURF_P16_32x32_16x16 17 # define TILE_SPLIT(x) ((x) << 11) # define ADDR_SURF_TILE_SPLIT_64B 0 # define ADDR_SURF_TILE_SPLIT_128B 1 @@ -1455,6 +1460,7 @@ # define RASTER_CONFIG_RB_MAP_1 1 # define RASTER_CONFIG_RB_MAP_2 2 # define RASTER_CONFIG_RB_MAP_3 3 +#define PKR_MAP(x) ((x) << 8) #define VGT_EVENT_INITIATOR 0x28a90 # define SAMPLE_STREAMOUTSTATS1 (1 << 0) diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index ab92620..009f46e 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -156,9 +156,6 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) u8 *sadb; int sad_count; - /* XXX: setting this register causes hangs on some asics */ - return; - if (!dig->afmt->pin) return; @@ -244,20 +241,30 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; + u8 stereo_freqs = 0; + int max_channels = -1; int j; for (j = 0; j < sad_count; j++) { struct cea_sad *sad = &sads[j]; if (sad->format == eld_reg_to_type[i][1]) { - value = MAX_CHANNELS(sad->channels) | - DESCRIPTOR_BYTE_2(sad->byte2) | - SUPPORTED_FREQUENCIES(sad->freq); + if (sad->channels > max_channels) { + value = MAX_CHANNELS(sad->channels) | + DESCRIPTOR_BYTE_2(sad->byte2) | + SUPPORTED_FREQUENCIES(sad->freq); + max_channels = sad->channels; + } + if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) - value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); - break; + stereo_freqs |= sad->freq; + else + break; } } + + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); + WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); } diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index a82b6f7..aa695c4 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -105,9 +105,6 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) u8 *sadb; int sad_count; - /* XXX: setting this register causes hangs on some asics */ - return; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { if (connector->encoder == encoder) { radeon_connector = to_radeon_connector(connector); @@ -184,20 +181,30 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; + u8 stereo_freqs = 0; + int max_channels = -1; int j; for (j = 0; j < sad_count; j++) { struct cea_sad *sad = &sads[j]; if (sad->format == eld_reg_to_type[i][1]) { - value = MAX_CHANNELS(sad->channels) | - DESCRIPTOR_BYTE_2(sad->byte2) | - SUPPORTED_FREQUENCIES(sad->freq); + if (sad->channels > max_channels) { + value = MAX_CHANNELS(sad->channels) | + DESCRIPTOR_BYTE_2(sad->byte2) | + SUPPORTED_FREQUENCIES(sad->freq); + max_channels = sad->channels; + } + if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) - value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); - break; + stereo_freqs |= sad->freq; + else + break; } } + + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); + WREG32(eld_reg_to_type[i][0], value); } diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 0977c30..4b89262 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -24,6 +24,7 @@ * Authors: Christian König */ #include <linux/hdmi.h> +#include <linux/gcd.h> #include <drm/drmP.h> #include <drm/radeon_drm.h> #include "radeon.h" @@ -57,35 +58,57 @@ enum r600_hdmi_iec_status_bits { static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { /* 32kHz 44.1kHz 48kHz */ /* Clock N CTS N CTS N CTS */ - { 25175, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ + { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ - { 74176, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */ + { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ - { 148352, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */ + { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ - { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */ }; + /* - * calculate CTS value if it's not found in the table + * calculate CTS and N values if they are not found in the table */ -static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq) +static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) { - u64 n; - u32 d; - - if (*CTS == 0) { - n = (u64)clock * (u64)N * 1000ULL; - d = 128 * freq; - do_div(n, d); - *CTS = n; - } - DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n", - N, *CTS, freq); + int n, cts; + unsigned long div, mul; + + /* Safe, but overly large values */ + n = 128 * freq; + cts = clock * 1000; + + /* Smallest valid fraction */ + div = gcd(n, cts); + + n /= div; + cts /= div; + + /* + * The optimal N is 128*freq/1000. Calculate the closest larger + * value that doesn't truncate any bits. + */ + mul = ((128*freq/1000) + (n-1))/n; + + n *= mul; + cts *= mul; + + /* Check that we are in spec (not always possible) */ + if (n < (128*freq/1500)) + printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); + if (n > (128*freq/300)) + printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); + + *N = n; + *CTS = cts; + + DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", + *N, *CTS, freq); } struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) @@ -93,15 +116,16 @@ struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) struct radeon_hdmi_acr res; u8 i; - for (i = 0; r600_hdmi_predefined_acr[i].clock != clock && - r600_hdmi_predefined_acr[i].clock != 0; i++) - ; - res = r600_hdmi_predefined_acr[i]; + /* Precalculated values for common clocks */ + for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) { + if (r600_hdmi_predefined_acr[i].clock == clock) + return r600_hdmi_predefined_acr[i]; + } - /* In case some CTS are missing */ - r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000); - r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100); - r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000); + /* And odd clocks get manually calculated */ + r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); + r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); + r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); return res; } @@ -388,20 +412,30 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; + u8 stereo_freqs = 0; + int max_channels = -1; int j; for (j = 0; j < sad_count; j++) { struct cea_sad *sad = &sads[j]; if (sad->format == eld_reg_to_type[i][1]) { - value = MAX_CHANNELS(sad->channels) | - DESCRIPTOR_BYTE_2(sad->byte2) | - SUPPORTED_FREQUENCIES(sad->freq); + if (sad->channels > max_channels) { + value = MAX_CHANNELS(sad->channels) | + DESCRIPTOR_BYTE_2(sad->byte2) | + SUPPORTED_FREQUENCIES(sad->freq); + max_channels = sad->channels; + } + if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) - value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); - break; + stereo_freqs |= sad->freq; + else + break; } } + + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); + WREG32(eld_reg_to_type[i][0], value); } diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index d4b9167..50853c0 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2437,27 +2437,48 @@ int radeon_asic_init(struct radeon_device *rdev) } break; case CHIP_BONAIRE: + case CHIP_HAWAII: rdev->asic = &ci_asic; rdev->num_crtc = 6; rdev->has_uvd = true; - rdev->cg_flags = - RADEON_CG_SUPPORT_GFX_MGCG | - RADEON_CG_SUPPORT_GFX_MGLS | - /*RADEON_CG_SUPPORT_GFX_CGCG |*/ - RADEON_CG_SUPPORT_GFX_CGLS | - RADEON_CG_SUPPORT_GFX_CGTS | - RADEON_CG_SUPPORT_GFX_CGTS_LS | - RADEON_CG_SUPPORT_GFX_CP_LS | - RADEON_CG_SUPPORT_MC_LS | - RADEON_CG_SUPPORT_MC_MGCG | - RADEON_CG_SUPPORT_SDMA_MGCG | - RADEON_CG_SUPPORT_SDMA_LS | - RADEON_CG_SUPPORT_BIF_LS | - RADEON_CG_SUPPORT_VCE_MGCG | - RADEON_CG_SUPPORT_UVD_MGCG | - RADEON_CG_SUPPORT_HDP_LS | - RADEON_CG_SUPPORT_HDP_MGCG; - rdev->pg_flags = 0; + if (rdev->family == CHIP_BONAIRE) { + rdev->cg_flags = + RADEON_CG_SUPPORT_GFX_MGCG | + RADEON_CG_SUPPORT_GFX_MGLS | + /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGLS | + RADEON_CG_SUPPORT_GFX_CGTS | + RADEON_CG_SUPPORT_GFX_CGTS_LS | + RADEON_CG_SUPPORT_GFX_CP_LS | + RADEON_CG_SUPPORT_MC_LS | + RADEON_CG_SUPPORT_MC_MGCG | + RADEON_CG_SUPPORT_SDMA_MGCG | + RADEON_CG_SUPPORT_SDMA_LS | + RADEON_CG_SUPPORT_BIF_LS | + RADEON_CG_SUPPORT_VCE_MGCG | + RADEON_CG_SUPPORT_UVD_MGCG | + RADEON_CG_SUPPORT_HDP_LS | + RADEON_CG_SUPPORT_HDP_MGCG; + rdev->pg_flags = 0; + } else { + rdev->cg_flags = + RADEON_CG_SUPPORT_GFX_MGCG | + RADEON_CG_SUPPORT_GFX_MGLS | + /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGLS | + RADEON_CG_SUPPORT_GFX_CGTS | + RADEON_CG_SUPPORT_GFX_CP_LS | + RADEON_CG_SUPPORT_MC_LS | + RADEON_CG_SUPPORT_MC_MGCG | + RADEON_CG_SUPPORT_SDMA_MGCG | + RADEON_CG_SUPPORT_SDMA_LS | + RADEON_CG_SUPPORT_BIF_LS | + RADEON_CG_SUPPORT_VCE_MGCG | + RADEON_CG_SUPPORT_UVD_MGCG | + RADEON_CG_SUPPORT_HDP_LS | + RADEON_CG_SUPPORT_HDP_MGCG; + rdev->pg_flags = 0; + } break; case CHIP_KAVERI: case CHIP_KABINI: diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index f60b310..20a768a 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1728,9 +1728,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (radeon_audio != 0) drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = true; @@ -1828,9 +1826,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); } if (ASIC_IS_AVIVO(rdev)) { drm_object_attach_property(&radeon_connector->base.base, @@ -1880,9 +1876,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); } if (ASIC_IS_AVIVO(rdev)) { drm_object_attach_property(&radeon_connector->base.base, @@ -1931,9 +1925,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); } if (ASIC_IS_AVIVO(rdev)) { drm_object_attach_property(&radeon_connector->base.base, diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 61dbdd9..b9234c4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -98,6 +98,7 @@ static const char radeon_family_name[][16] = { "BONAIRE", "KAVERI", "KABINI", + "HAWAII", "LAST", }; diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 3c82890..614ad54 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h @@ -96,6 +96,7 @@ enum radeon_family { CHIP_BONAIRE, CHIP_KAVERI, CHIP_KABINI, + CHIP_HAWAII, CHIP_LAST, }; diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 7cb178a..0c7b8c6 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -1056,6 +1056,26 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) } } +static void radeon_crtc_disable(struct drm_crtc *crtc) +{ + radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + if (crtc->fb) { + int r; + struct radeon_framebuffer *radeon_fb; + struct radeon_bo *rbo; + + radeon_fb = to_radeon_framebuffer(crtc->fb); + rbo = gem_to_radeon_bo(radeon_fb->obj); + r = radeon_bo_reserve(rbo, false); + if (unlikely(r)) + DRM_ERROR("failed to reserve rbo before unpin\n"); + else { + radeon_bo_unpin(rbo); + radeon_bo_unreserve(rbo); + } + } +} + static const struct drm_crtc_helper_funcs legacy_helper_funcs = { .dpms = radeon_crtc_dpms, .mode_fixup = radeon_crtc_mode_fixup, @@ -1065,6 +1085,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = { .prepare = radeon_crtc_prepare, .commit = radeon_crtc_commit, .load_lut = radeon_crtc_load_lut, + .disable = radeon_crtc_disable }; diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 00bdcd3..866ace0 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1256,6 +1256,7 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_BONAIRE: case CHIP_KABINI: case CHIP_KAVERI: + case CHIP_HAWAII: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw) rdev->pm.pm_method = PM_METHOD_PROFILE; diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h index 3385836..a77cd27 100644 --- a/drivers/gpu/drm/radeon/radeon_ucode.h +++ b/drivers/gpu/drm/radeon/radeon_ucode.h @@ -59,6 +59,7 @@ #define SI_MC_UCODE_SIZE 7769 #define OLAND_MC_UCODE_SIZE 7863 #define CIK_MC_UCODE_SIZE 7866 +#define HAWAII_MC_UCODE_SIZE 7933 /* SDMA */ #define CIK_SDMA_UCODE_SIZE 1050 @@ -143,4 +144,7 @@ #define BONAIRE_SMC_UCODE_START 0x20000 #define BONAIRE_SMC_UCODE_SIZE 0x1FDEC +#define HAWAII_SMC_UCODE_START 0x20000 +#define HAWAII_SMC_UCODE_SIZE 0x1FDEC + #endif diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index ab0a172..373d088 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -97,6 +97,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_BONAIRE: case CHIP_KABINI: case CHIP_KAVERI: + case CHIP_HAWAII: fw_name = FIRMWARE_BONAIRE; break; diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 1447d79..1c56062 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -345,9 +345,11 @@ static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, if (max_bandwidth.full > rdev->pm.sideport_bandwidth.full && rdev->pm.sideport_bandwidth.full) max_bandwidth = rdev->pm.sideport_bandwidth; - read_delay_latency.full = dfixed_const(370 * 800 * 1000); - read_delay_latency.full = dfixed_div(read_delay_latency, - rdev->pm.igp_sideport_mclk); + read_delay_latency.full = dfixed_const(370 * 800); + a.full = dfixed_const(1000); + b.full = dfixed_div(rdev->pm.igp_sideport_mclk, a); + read_delay_latency.full = dfixed_div(read_delay_latency, b); + read_delay_latency.full = dfixed_mul(read_delay_latency, a); } else { if (max_bandwidth.full > rdev->pm.k8_bandwidth.full && rdev->pm.k8_bandwidth.full) @@ -488,14 +490,10 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -526,8 +524,6 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -555,8 +551,6 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev, } if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 873eb4b..5d1c316 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -1155,14 +1155,10 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -1193,8 +1189,6 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -1222,8 +1216,6 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev, } if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); |