mirror of https://gitee.com/openkylin/linux.git
Merge tag 'drm-fixes-5.4-2019-09-25' of git://people.freedesktop.org/~agd5f/linux into drm-next
drm-fixes-5.4-2019-09-25: amdgpu: - Fix a 64 bit divide - Prevent a memory leak in a failure case in dc - Load proper gfx firmware on navi14 variants drm-fixes-5.4-2019-09-19: amdgpu: - Add more navi12 and navi14 PCI ids - Misc fixes for renoir - Fix bandwidth issues with multiple displays on vega20 - Support for Dali - Fix a possible oops with KFD on hawaii - Fix for backlight level after resume on some APUs - Other misc fixes Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190925213500.3490-1-alexander.deucher@amd.com
This commit is contained in:
commit
3e2cb6d893
|
@ -948,6 +948,7 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
|
|||
case AMD_IP_BLOCK_TYPE_UVD:
|
||||
case AMD_IP_BLOCK_TYPE_VCN:
|
||||
case AMD_IP_BLOCK_TYPE_VCE:
|
||||
case AMD_IP_BLOCK_TYPE_SDMA:
|
||||
if (swsmu)
|
||||
ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
|
||||
else
|
||||
|
@ -956,7 +957,6 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
|
|||
break;
|
||||
case AMD_IP_BLOCK_TYPE_GMC:
|
||||
case AMD_IP_BLOCK_TYPE_ACP:
|
||||
case AMD_IP_BLOCK_TYPE_SDMA:
|
||||
ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
|
||||
(adev)->powerplay.pp_handle, block_type, gate));
|
||||
break;
|
||||
|
|
|
@ -1011,11 +1011,16 @@ static const struct pci_device_id pciidlist[] = {
|
|||
{0x1002, 0x731B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x731F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
/* Navi14 */
|
||||
{0x1002, 0x7340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14},
|
||||
{0x1002, 0x7340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x7341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x7347, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
|
||||
|
||||
/* Renoir */
|
||||
{0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU|AMD_EXP_HW_SUPPORT},
|
||||
|
||||
/* Navi12 */
|
||||
{0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12|AMD_EXP_HW_SUPPORT},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -143,7 +143,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
/* ring tests don't use a job */
|
||||
if (job) {
|
||||
vm = job->vm;
|
||||
fence_ctx = job->base.s_fence->scheduled.context;
|
||||
fence_ctx = job->base.s_fence ?
|
||||
job->base.s_fence->scheduled.context : 0;
|
||||
} else {
|
||||
vm = NULL;
|
||||
fence_ctx = 0;
|
||||
|
|
|
@ -677,6 +677,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)
|
||||
sh_num = 0xffffffff;
|
||||
|
||||
if (info->read_mmr_reg.count > 128)
|
||||
return -EINVAL;
|
||||
|
||||
regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL);
|
||||
if (!regs)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -70,6 +70,11 @@ MODULE_FIRMWARE("amdgpu/navi10_mec.bin");
|
|||
MODULE_FIRMWARE("amdgpu/navi10_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi10_rlc.bin");
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/navi14_ce_wks.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_pfp_wks.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_me_wks.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_mec_wks.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_mec2_wks.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_ce.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_me.bin");
|
||||
|
@ -594,7 +599,8 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev)
|
|||
static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
char fw_name[40];
|
||||
char wks[10];
|
||||
int err;
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
const struct common_firmware_header *header = NULL;
|
||||
|
@ -607,12 +613,16 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
memset(wks, 0, sizeof(wks));
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
chip_name = "navi10";
|
||||
break;
|
||||
case CHIP_NAVI14:
|
||||
chip_name = "navi14";
|
||||
if (!(adev->pdev->device == 0x7340 &&
|
||||
adev->pdev->revision != 0x00))
|
||||
snprintf(wks, sizeof(wks), "_wks");
|
||||
break;
|
||||
case CHIP_NAVI12:
|
||||
chip_name = "navi12";
|
||||
|
@ -621,7 +631,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
BUG();
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name);
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -632,7 +642,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name);
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -643,7 +653,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
adev->gfx.me_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name);
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -708,7 +718,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
if (adev->gfx.rlc.is_rlc_v2_1)
|
||||
gfx_v10_0_init_rlc_ext_microcode(adev);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -719,7 +729,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
|
||||
adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2%s.bin", chip_name, wks);
|
||||
err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
|
||||
if (!err) {
|
||||
err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
|
||||
|
|
|
@ -1650,7 +1650,6 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
|
|||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
gfx_v9_0_init_lbpw(adev);
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
|
@ -3026,7 +3025,6 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev)
|
|||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
if (amdgpu_lbpw == 0)
|
||||
gfx_v9_0_enable_lbpw(adev, false);
|
||||
else
|
||||
|
|
|
@ -1889,8 +1889,9 @@ static int sdma_v4_0_hw_init(void *handle)
|
|||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_powergating_by_smu)
|
||||
if ((adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_powergating_by_smu) ||
|
||||
adev->asic_type == CHIP_RENOIR)
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false);
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
|
@ -1917,8 +1918,9 @@ static int sdma_v4_0_hw_fini(void *handle)
|
|||
sdma_v4_0_ctx_switch_enable(adev, false);
|
||||
sdma_v4_0_enable(adev, false);
|
||||
|
||||
if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs
|
||||
&& adev->powerplay.pp_funcs->set_powergating_by_smu)
|
||||
if ((adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs
|
||||
&& adev->powerplay.pp_funcs->set_powergating_by_smu) ||
|
||||
adev->asic_type == CHIP_RENOIR)
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -493,7 +493,15 @@ static void smu_v11_0_i2c_fini(struct i2c_adapter *control)
|
|||
}
|
||||
|
||||
/* Restore clock gating */
|
||||
smu_v11_0_i2c_set_clock_gating(control, true);
|
||||
|
||||
/*
|
||||
* TODO Reenabling clock gating seems to break subsequent SMU operation
|
||||
* on the I2C bus. My guess is that SMU doesn't disable clock gating like
|
||||
* we do here before working with the bus. So for now just don't restore
|
||||
* it but later work with SMU to see if they have this issue and can
|
||||
* update their code appropriately
|
||||
*/
|
||||
/* smu_v11_0_i2c_set_clock_gating(control, true); */
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -694,10 +694,10 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
|
|||
0x003f8000, 0x8f6f896f,
|
||||
0x88776f77, 0x8a6eff6e,
|
||||
0x023f8000, 0xb9eef807,
|
||||
0xb970f812, 0xb971f813,
|
||||
0x8ff08870, 0xf4051bb8,
|
||||
0xb97af812, 0xb97bf813,
|
||||
0x8ffa887a, 0xf4051bbd,
|
||||
0xfa000000, 0xbf8cc07f,
|
||||
0xf4051c38, 0xfa000008,
|
||||
0xf4051ebd, 0xfa000008,
|
||||
0xbf8cc07f, 0x87ee6e6e,
|
||||
0xbf840001, 0xbe80206e,
|
||||
0xb971f803, 0x8771ff71,
|
||||
|
|
|
@ -187,12 +187,12 @@ L_FETCH_2ND_TRAP:
|
|||
// Read second-level TBA/TMA from first-level TMA and jump if available.
|
||||
// ttmp[2:5] and ttmp12 can be used (others hold SPI-initialized debug data)
|
||||
// ttmp12 holds SQ_WAVE_STATUS
|
||||
s_getreg_b32 ttmp4, hwreg(HW_REG_SHADER_TMA_LO)
|
||||
s_getreg_b32 ttmp5, hwreg(HW_REG_SHADER_TMA_HI)
|
||||
s_lshl_b64 [ttmp4, ttmp5], [ttmp4, ttmp5], 0x8
|
||||
s_load_dwordx2 [ttmp2, ttmp3], [ttmp4, ttmp5], 0x0 glc:1 // second-level TBA
|
||||
s_getreg_b32 ttmp14, hwreg(HW_REG_SHADER_TMA_LO)
|
||||
s_getreg_b32 ttmp15, hwreg(HW_REG_SHADER_TMA_HI)
|
||||
s_lshl_b64 [ttmp14, ttmp15], [ttmp14, ttmp15], 0x8
|
||||
s_load_dwordx2 [ttmp2, ttmp3], [ttmp14, ttmp15], 0x0 glc:1 // second-level TBA
|
||||
s_waitcnt lgkmcnt(0)
|
||||
s_load_dwordx2 [ttmp4, ttmp5], [ttmp4, ttmp5], 0x8 glc:1 // second-level TMA
|
||||
s_load_dwordx2 [ttmp14, ttmp15], [ttmp14, ttmp15], 0x8 glc:1 // second-level TMA
|
||||
s_waitcnt lgkmcnt(0)
|
||||
s_and_b64 [ttmp2, ttmp3], [ttmp2, ttmp3], [ttmp2, ttmp3]
|
||||
s_cbranch_scc0 L_NO_NEXT_TRAP // second-level trap handler not been set
|
||||
|
|
|
@ -2113,6 +2113,7 @@ static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
|
|||
}
|
||||
|
||||
static const struct backlight_ops amdgpu_dm_backlight_ops = {
|
||||
.options = BL_CORE_SUSPENDRESUME,
|
||||
.get_brightness = amdgpu_dm_backlight_get_brightness,
|
||||
.update_status = amdgpu_dm_backlight_update_status,
|
||||
};
|
||||
|
@ -2384,6 +2385,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
|||
|
||||
if (adev->asic_type != CHIP_CARRIZO && adev->asic_type != CHIP_STONEY)
|
||||
dm->dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true;
|
||||
if (adev->asic_type == CHIP_RENOIR)
|
||||
dm->dc->debug.disable_stutter = true;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
|
|
|
@ -708,6 +708,10 @@ static void hack_bounding_box(struct dcn_bw_internal_vars *v,
|
|||
|
||||
unsigned int get_highest_allowed_voltage_level(uint32_t hw_internal_rev)
|
||||
{
|
||||
/* for dali, the highest voltage level we want is 0 */
|
||||
if (ASICREV_IS_DALI(hw_internal_rev))
|
||||
return 0;
|
||||
|
||||
/* we are ok with all levels */
|
||||
return 4;
|
||||
}
|
||||
|
|
|
@ -98,11 +98,14 @@ uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context)
|
|||
struct dc_stream_state *stream = context->streams[j];
|
||||
uint32_t vertical_blank_in_pixels = 0;
|
||||
uint32_t vertical_blank_time = 0;
|
||||
uint32_t vertical_total_min = stream->timing.v_total;
|
||||
struct dc_crtc_timing_adjust adjust = stream->adjust;
|
||||
if (adjust.v_total_max != adjust.v_total_min)
|
||||
vertical_total_min = adjust.v_total_min;
|
||||
|
||||
vertical_blank_in_pixels = stream->timing.h_total *
|
||||
(stream->timing.v_total
|
||||
(vertical_total_min
|
||||
- stream->timing.v_addressable);
|
||||
|
||||
vertical_blank_time = vertical_blank_in_pixels
|
||||
* 10000 / stream->timing.pix_clk_100hz;
|
||||
|
||||
|
@ -171,6 +174,10 @@ void dce11_pplib_apply_display_requirements(
|
|||
struct dc_state *context)
|
||||
{
|
||||
struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
|
||||
int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
|
||||
|
||||
if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
|
||||
memory_type_multiplier = MEMORY_TYPE_HBM;
|
||||
|
||||
pp_display_cfg->all_displays_in_sync =
|
||||
context->bw_ctx.bw.dce.all_displays_in_sync;
|
||||
|
@ -183,8 +190,20 @@ void dce11_pplib_apply_display_requirements(
|
|||
pp_display_cfg->cpu_pstate_separation_time =
|
||||
context->bw_ctx.bw.dce.blackout_recovery_time_us;
|
||||
|
||||
pp_display_cfg->min_memory_clock_khz = context->bw_ctx.bw.dce.yclk_khz
|
||||
/ MEMORY_TYPE_MULTIPLIER_CZ;
|
||||
/*
|
||||
* TODO: determine whether the bandwidth has reached memory's limitation
|
||||
* , then change minimum memory clock based on real-time bandwidth
|
||||
* limitation.
|
||||
*/
|
||||
if (ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && (context->stream_count >= 2)) {
|
||||
pp_display_cfg->min_memory_clock_khz = max(pp_display_cfg->min_memory_clock_khz,
|
||||
(uint32_t) div64_s64(
|
||||
div64_s64(dc->bw_vbios->high_yclk.value,
|
||||
memory_type_multiplier), 10000));
|
||||
} else {
|
||||
pp_display_cfg->min_memory_clock_khz = context->bw_ctx.bw.dce.yclk_khz
|
||||
/ memory_type_multiplier;
|
||||
}
|
||||
|
||||
pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box(
|
||||
dc,
|
||||
|
|
|
@ -148,7 +148,7 @@ static void dce_mi_program_pte_vm(
|
|||
pte->min_pte_before_flip_horiz_scan;
|
||||
|
||||
REG_UPDATE(GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT,
|
||||
GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT, 0xff);
|
||||
GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT, 0x7f);
|
||||
|
||||
REG_UPDATE_3(DVMM_PTE_CONTROL,
|
||||
DVMM_PAGE_WIDTH, page_width,
|
||||
|
@ -157,7 +157,7 @@ static void dce_mi_program_pte_vm(
|
|||
|
||||
REG_UPDATE_2(DVMM_PTE_ARB_CONTROL,
|
||||
DVMM_PTE_REQ_PER_CHUNK, pte->pte_req_per_chunk,
|
||||
DVMM_MAX_PTE_REQ_OUTSTANDING, 0xff);
|
||||
DVMM_MAX_PTE_REQ_OUTSTANDING, 0x7f);
|
||||
}
|
||||
|
||||
static void program_urgency_watermark(
|
||||
|
|
|
@ -1091,6 +1091,7 @@ struct resource_pool *dce100_create_resource_pool(
|
|||
if (construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1462,6 +1462,7 @@ struct resource_pool *dce110_create_resource_pool(
|
|||
if (construct(num_virtual_links, dc, pool, asic_id))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -987,6 +987,10 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
|
|||
struct dm_pp_clock_levels_with_latency mem_clks = {0};
|
||||
struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
|
||||
struct dm_pp_clock_levels clks = {0};
|
||||
int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
|
||||
|
||||
if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
|
||||
memory_type_multiplier = MEMORY_TYPE_HBM;
|
||||
|
||||
/*do system clock TODO PPLIB: after PPLIB implement,
|
||||
* then remove old way
|
||||
|
@ -1026,12 +1030,12 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
|
|||
&clks);
|
||||
|
||||
dc->bw_vbios->low_yclk = bw_frc_to_fixed(
|
||||
clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER_CZ, 1000);
|
||||
clks.clocks_in_khz[0] * memory_type_multiplier, 1000);
|
||||
dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
|
||||
clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER_CZ,
|
||||
clks.clocks_in_khz[clks.num_levels>>1] * memory_type_multiplier,
|
||||
1000);
|
||||
dc->bw_vbios->high_yclk = bw_frc_to_fixed(
|
||||
clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER_CZ,
|
||||
clks.clocks_in_khz[clks.num_levels-1] * memory_type_multiplier,
|
||||
1000);
|
||||
|
||||
return;
|
||||
|
@ -1067,12 +1071,12 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
|
|||
* YCLK = UMACLK*m_memoryTypeMultiplier
|
||||
*/
|
||||
dc->bw_vbios->low_yclk = bw_frc_to_fixed(
|
||||
mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, 1000);
|
||||
mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000);
|
||||
dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
|
||||
mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ,
|
||||
mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier,
|
||||
1000);
|
||||
dc->bw_vbios->high_yclk = bw_frc_to_fixed(
|
||||
mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ,
|
||||
mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier,
|
||||
1000);
|
||||
|
||||
/* Now notify PPLib/SMU about which Watermarks sets they should select
|
||||
|
@ -1338,6 +1342,7 @@ struct resource_pool *dce112_create_resource_pool(
|
|||
if (construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -847,6 +847,8 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
|
|||
int i;
|
||||
unsigned int clk;
|
||||
unsigned int latency;
|
||||
/*original logic in dal3*/
|
||||
int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
|
||||
|
||||
/*do system clock*/
|
||||
if (!dm_pp_get_clock_levels_by_type_with_latency(
|
||||
|
@ -905,13 +907,16 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
|
|||
* ALSO always convert UMA clock (from PPLIB) to YCLK (HW formula):
|
||||
* YCLK = UMACLK*m_memoryTypeMultiplier
|
||||
*/
|
||||
if (dc->bw_vbios->memory_type == bw_def_hbm)
|
||||
memory_type_multiplier = MEMORY_TYPE_HBM;
|
||||
|
||||
dc->bw_vbios->low_yclk = bw_frc_to_fixed(
|
||||
mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, 1000);
|
||||
mem_clks.data[0].clocks_in_khz * memory_type_multiplier, 1000);
|
||||
dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
|
||||
mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ,
|
||||
mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * memory_type_multiplier,
|
||||
1000);
|
||||
dc->bw_vbios->high_yclk = bw_frc_to_fixed(
|
||||
mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ,
|
||||
mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * memory_type_multiplier,
|
||||
1000);
|
||||
|
||||
/* Now notify PPLib/SMU about which Watermarks sets they should select
|
||||
|
@ -1203,6 +1208,7 @@ struct resource_pool *dce120_create_resource_pool(
|
|||
if (construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1570,6 +1570,7 @@ struct resource_pool *dcn10_create_resource_pool(
|
|||
if (construct(init_data->num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dc.h"
|
||||
|
||||
|
|
|
@ -35,12 +35,10 @@
|
|||
|
||||
#include "hw_factory_dcn21.h"
|
||||
|
||||
|
||||
#include "dcn/dcn_2_1_0_offset.h"
|
||||
#include "dcn/dcn_2_1_0_sh_mask.h"
|
||||
#include "renoir_ip_offset.h"
|
||||
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "../hpd_regs.h"
|
||||
/* begin *********************
|
||||
|
@ -136,6 +134,39 @@ static const struct ddc_sh_mask ddc_mask[] = {
|
|||
DDC_MASK_SH_LIST_DCN2(_MASK, 6)
|
||||
};
|
||||
|
||||
#include "../generic_regs.h"
|
||||
|
||||
/* set field name */
|
||||
#define SF_GENERIC(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
#define generic_regs(id) \
|
||||
{\
|
||||
GENERIC_REG_LIST(id)\
|
||||
}
|
||||
|
||||
static const struct generic_registers generic_regs[] = {
|
||||
generic_regs(A),
|
||||
};
|
||||
|
||||
static const struct generic_sh_mask generic_shift[] = {
|
||||
GENERIC_MASK_SH_LIST(__SHIFT, A),
|
||||
};
|
||||
|
||||
static const struct generic_sh_mask generic_mask[] = {
|
||||
GENERIC_MASK_SH_LIST(_MASK, A),
|
||||
};
|
||||
|
||||
static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en)
|
||||
{
|
||||
struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin);
|
||||
|
||||
generic->regs = &generic_regs[en];
|
||||
generic->shifts = &generic_shift[en];
|
||||
generic->masks = &generic_mask[en];
|
||||
generic->base.regs = &generic_regs[en].gpio;
|
||||
}
|
||||
|
||||
static void define_ddc_registers(
|
||||
struct hw_gpio_pin *pin,
|
||||
uint32_t en)
|
||||
|
@ -181,7 +212,8 @@ static const struct hw_factory_funcs funcs = {
|
|||
.get_hpd_pin = dal_hw_hpd_get_pin,
|
||||
.get_generic_pin = dal_hw_generic_get_pin,
|
||||
.define_hpd_registers = define_hpd_registers,
|
||||
.define_ddc_registers = define_ddc_registers
|
||||
.define_ddc_registers = define_ddc_registers,
|
||||
.define_generic_registers = define_generic_registers
|
||||
};
|
||||
/*
|
||||
* dal_hw_factory_dcn10_init
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#define SF_HPD(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
|
||||
/* macros to expend register list macro defined in HW object header file
|
||||
* end *********************/
|
||||
|
||||
|
@ -71,7 +70,7 @@ static bool offset_to_id(
|
|||
{
|
||||
switch (offset) {
|
||||
/* GENERIC */
|
||||
case REG(DC_GENERICA):
|
||||
case REG(DC_GPIO_GENERIC_A):
|
||||
*id = GPIO_ID_GENERIC;
|
||||
switch (mask) {
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "dm_pp_smu.h"
|
||||
|
||||
#define MEMORY_TYPE_MULTIPLIER_CZ 4
|
||||
#define MEMORY_TYPE_HBM 2
|
||||
|
||||
|
||||
enum dce_version resource_parse_asic_id(
|
||||
struct hw_asic_id asic_id);
|
||||
|
|
|
@ -137,10 +137,13 @@
|
|||
#define RAVEN1_F0 0xF0
|
||||
#define RAVEN_UNKNOWN 0xFF
|
||||
|
||||
#define PICASSO_15D8_REV_E3 0xE3
|
||||
#define PICASSO_15D8_REV_E4 0xE4
|
||||
|
||||
#define ASICREV_IS_RAVEN(eChipRev) ((eChipRev >= RAVEN_A0) && eChipRev < RAVEN_UNKNOWN)
|
||||
#define ASICREV_IS_PICASSO(eChipRev) ((eChipRev >= PICASSO_A0) && (eChipRev < RAVEN2_A0))
|
||||
#define ASICREV_IS_RAVEN2(eChipRev) ((eChipRev >= RAVEN2_A0) && (eChipRev < 0xF0))
|
||||
|
||||
#define ASICREV_IS_RAVEN2(eChipRev) ((eChipRev >= RAVEN2_A0) && (eChipRev < PICASSO_15D8_REV_E3))
|
||||
#define ASICREV_IS_DALI(eChipRev) ((eChipRev >= PICASSO_15D8_REV_E3) && (eChipRev < RAVEN1_F0))
|
||||
|
||||
#define ASICREV_IS_RV1_F0(eChipRev) ((eChipRev >= RAVEN1_F0) && (eChipRev < RAVEN_UNKNOWN))
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ static const struct IP_BASE MP0_BASE ={ { { { 0x00016000, 0x0243FC00, 0x00DC0000
|
|||
{ { 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0 } } } };
|
||||
static const struct IP_BASE MP1_BASE ={ { { { 0x00016200, 0x02400400, 0x00E80000, 0x00EC0000, 0x00F00000 } },
|
||||
static const struct IP_BASE MP1_BASE ={ { { { 0x00016000, 0x02400400, 0x00E80000, 0x00EC0000, 0x00F00000 } },
|
||||
{ { 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0 } },
|
||||
{ { 0, 0, 0, 0, 0 } },
|
||||
|
|
|
@ -1531,6 +1531,7 @@ static int pp_asic_reset_mode_2(void *handle)
|
|||
static int pp_smu_i2c_bus_access(void *handle, bool acquire)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr = handle;
|
||||
int ret = 0;
|
||||
|
||||
if (!hwmgr || !hwmgr->pm_en)
|
||||
return -EINVAL;
|
||||
|
@ -1540,7 +1541,11 @@ static int pp_smu_i2c_bus_access(void *handle, bool acquire)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return hwmgr->hwmgr_func->smu_i2c_bus_access(hwmgr, acquire);
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
ret = hwmgr->hwmgr_func->smu_i2c_bus_access(hwmgr, acquire);
|
||||
mutex_unlock(&hwmgr->smu_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct amd_pm_funcs pp_dpm_funcs = {
|
||||
|
|
|
@ -354,6 +354,9 @@ int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type,
|
|||
case AMD_IP_BLOCK_TYPE_GFX:
|
||||
ret = smu_gfx_off_control(smu, gate);
|
||||
break;
|
||||
case AMD_IP_BLOCK_TYPE_SDMA:
|
||||
ret = smu_powergate_sdma(smu, gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -177,12 +177,82 @@ static int renoir_get_dpm_uclk_limited(struct smu_context *smu, uint32_t *clock,
|
|||
|
||||
}
|
||||
|
||||
static int renoir_print_clk_levels(struct smu_context *smu,
|
||||
enum smu_clk_type clk_type, char *buf)
|
||||
{
|
||||
int i, size = 0, ret = 0;
|
||||
uint32_t cur_value = 0, value = 0, count = 0, min = 0, max = 0;
|
||||
DpmClocks_t *clk_table = smu->smu_table.clocks_table;
|
||||
SmuMetrics_t metrics = {0};
|
||||
|
||||
if (!clk_table || clk_type >= SMU_CLK_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
|
||||
(void *)&metrics, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
/* retirve table returned paramters unit is MHz */
|
||||
cur_value = metrics.ClockFrequency[CLOCK_GFXCLK];
|
||||
ret = smu_get_dpm_freq_range(smu, SMU_GFXCLK, &min, &max);
|
||||
if (!ret) {
|
||||
/* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
|
||||
if (cur_value == max)
|
||||
i = 2;
|
||||
else if (cur_value == min)
|
||||
i = 0;
|
||||
else
|
||||
i = 1;
|
||||
|
||||
size += sprintf(buf + size, "0: %uMhz %s\n", min,
|
||||
i == 0 ? "*" : "");
|
||||
size += sprintf(buf + size, "1: %uMhz %s\n",
|
||||
i == 1 ? cur_value : RENOIR_UMD_PSTATE_GFXCLK,
|
||||
i == 1 ? "*" : "");
|
||||
size += sprintf(buf + size, "2: %uMhz %s\n", max,
|
||||
i == 2 ? "*" : "");
|
||||
}
|
||||
return size;
|
||||
case SMU_SOCCLK:
|
||||
count = NUM_SOCCLK_DPM_LEVELS;
|
||||
cur_value = metrics.ClockFrequency[CLOCK_SOCCLK];
|
||||
break;
|
||||
case SMU_MCLK:
|
||||
count = NUM_MEMCLK_DPM_LEVELS;
|
||||
cur_value = metrics.ClockFrequency[CLOCK_UMCCLK];
|
||||
break;
|
||||
case SMU_DCEFCLK:
|
||||
count = NUM_DCFCLK_DPM_LEVELS;
|
||||
cur_value = metrics.ClockFrequency[CLOCK_DCFCLK];
|
||||
break;
|
||||
case SMU_FCLK:
|
||||
count = NUM_FCLK_DPM_LEVELS;
|
||||
cur_value = metrics.ClockFrequency[CLOCK_FCLK];
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
GET_DPM_CUR_FREQ(clk_table, clk_type, i, value);
|
||||
size += sprintf(buf + size, "%d: %uMhz %s\n", i, value,
|
||||
cur_value == value ? "*" : "");
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static const struct pptable_funcs renoir_ppt_funcs = {
|
||||
.get_smu_msg_index = renoir_get_smu_msg_index,
|
||||
.get_smu_table_index = renoir_get_smu_table_index,
|
||||
.tables_init = renoir_tables_init,
|
||||
.set_power_state = NULL,
|
||||
.get_dpm_uclk_limited = renoir_get_dpm_uclk_limited,
|
||||
.print_clk_levels = renoir_print_clk_levels,
|
||||
};
|
||||
|
||||
void renoir_set_ppt_funcs(struct smu_context *smu)
|
||||
|
|
|
@ -25,4 +25,29 @@
|
|||
|
||||
extern void renoir_set_ppt_funcs(struct smu_context *smu);
|
||||
|
||||
/* UMD PState Renoir Msg Parameters in MHz */
|
||||
#define RENOIR_UMD_PSTATE_GFXCLK 700
|
||||
#define RENOIR_UMD_PSTATE_SOCCLK 678
|
||||
#define RENOIR_UMD_PSTATE_FCLK 800
|
||||
|
||||
#define GET_DPM_CUR_FREQ(table, clk_type, dpm_level, freq) \
|
||||
do { \
|
||||
switch (clk_type) { \
|
||||
case SMU_SOCCLK: \
|
||||
freq = table->SocClocks[dpm_level].Freq; \
|
||||
break; \
|
||||
case SMU_MCLK: \
|
||||
freq = table->MemClocks[dpm_level].Freq; \
|
||||
break; \
|
||||
case SMU_DCEFCLK: \
|
||||
freq = table->DcfClocks[dpm_level].Freq; \
|
||||
break; \
|
||||
case SMU_FCLK: \
|
||||
freq = table->FClocks[dpm_level].Freq; \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -323,8 +323,39 @@ bool radeon_device_is_virtual(void);
|
|||
static int radeon_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
int ret;
|
||||
|
||||
if (!ent)
|
||||
return -ENODEV; /* Avoid NULL-ptr deref in drm_get_pci_dev */
|
||||
|
||||
flags = ent->driver_data;
|
||||
|
||||
if (!radeon_si_support) {
|
||||
switch (flags & RADEON_FAMILY_MASK) {
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
case CHIP_VERDE:
|
||||
case CHIP_OLAND:
|
||||
case CHIP_HAINAN:
|
||||
dev_info(&pdev->dev,
|
||||
"SI support disabled by module param\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
if (!radeon_cik_support) {
|
||||
switch (flags & RADEON_FAMILY_MASK) {
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
dev_info(&pdev->dev,
|
||||
"CIK support disabled by module param\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (vga_switcheroo_client_probe_defer(pdev))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
|
|
|
@ -100,31 +100,6 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
|||
struct radeon_device *rdev;
|
||||
int r, acpi_status;
|
||||
|
||||
if (!radeon_si_support) {
|
||||
switch (flags & RADEON_FAMILY_MASK) {
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
case CHIP_VERDE:
|
||||
case CHIP_OLAND:
|
||||
case CHIP_HAINAN:
|
||||
dev_info(dev->dev,
|
||||
"SI support disabled by module param\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
if (!radeon_cik_support) {
|
||||
switch (flags & RADEON_FAMILY_MASK) {
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
dev_info(dev->dev,
|
||||
"CIK support disabled by module param\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL);
|
||||
if (rdev == NULL) {
|
||||
return -ENOMEM;
|
||||
|
|
Loading…
Reference in New Issue