Skip to content

Commit

Permalink
Merge tag 'drm-fixes-for-v4.9-rc2' of git://people.freedesktop.org/~a…
Browse files Browse the repository at this point in the history
…irlied/linux

Pull drm fixes from Dave Airlie:
 "Just had a couple of amdgpu fixes and one core fix I wanted to get out
  early to fix some regressions.

  I'm sure I'll have more stuff this week for -rc2"

* tag 'drm-fixes-for-v4.9-rc2' of git://people.freedesktop.org/~airlied/linux: (22 commits)
  drm: Print device information again in debugfs
  drm/amd/powerplay: fix bug stop dpm can't work on Vi.
  drm/amd/powerplay: notify smu no display by default.
  drm/amdgpu/dpm: implement thermal sensor for CZ/ST
  drm/amdgpu/powerplay: implement thermal sensor for CZ/ST
  drm/amdgpu: disable smu hw first on tear down
  drm/amdgpu: fix amdgpu_need_full_reset (v2)
  drm/amdgpu/si_dpm: Limit clocks on HD86xx part
  drm/amd/powerplay: fix static checker warnings in smu7_hwmgr.c
  drm/amdgpu: potential NULL dereference in debugfs code
  drm/amd/powerplay: fix static checker warnings in smu7_hwmgr.c
  drm/amd/powerplay: fix static checker warnings in iceland_smc.c
  drm/radeon: change vblank_time's calculation method to reduce computational error.
  drm/amdgpu: change vblank_time's calculation method to reduce computational error.
  drm/amdgpu: clarify UVD/VCE special handling for CG
  drm/amd/amdgpu: enable clockgating only after late init
  drm/radeon: allow TA_CS_BC_BASE_ADDR on SI
  drm/amdgpu: initialize the context reset_counter in amdgpu_ctx_init
  drm/amdgpu/gfx8: fix CGCG_CGLS handling
  drm/radeon: fix modeset tear down code
  ...
  • Loading branch information
torvalds committed Oct 18, 2016
2 parents 14155ca + fa860a1 commit 37c1e28
Show file tree
Hide file tree
Showing 27 changed files with 232 additions and 131 deletions.
13 changes: 12 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,14 +765,20 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
return ret;
}

static void amdgpu_connector_destroy(struct drm_connector *connector)
static void amdgpu_connector_unregister(struct drm_connector *connector)
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);

if (amdgpu_connector->ddc_bus->has_aux) {
drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);
amdgpu_connector->ddc_bus->has_aux = false;
}
}

static void amdgpu_connector_destroy(struct drm_connector *connector)
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);

amdgpu_connector_free_edid(connector);
kfree(amdgpu_connector->con_priv);
drm_connector_unregister(connector);
Expand Down Expand Up @@ -826,6 +832,7 @@ static const struct drm_connector_funcs amdgpu_connector_lvds_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = amdgpu_connector_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.early_unregister = amdgpu_connector_unregister,
.destroy = amdgpu_connector_destroy,
.set_property = amdgpu_connector_set_lcd_property,
};
Expand Down Expand Up @@ -936,6 +943,7 @@ static const struct drm_connector_funcs amdgpu_connector_vga_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = amdgpu_connector_vga_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.early_unregister = amdgpu_connector_unregister,
.destroy = amdgpu_connector_destroy,
.set_property = amdgpu_connector_set_property,
};
Expand Down Expand Up @@ -1203,6 +1211,7 @@ static const struct drm_connector_funcs amdgpu_connector_dvi_funcs = {
.detect = amdgpu_connector_dvi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = amdgpu_connector_set_property,
.early_unregister = amdgpu_connector_unregister,
.destroy = amdgpu_connector_destroy,
.force = amdgpu_connector_dvi_force,
};
Expand Down Expand Up @@ -1493,6 +1502,7 @@ static const struct drm_connector_funcs amdgpu_connector_dp_funcs = {
.detect = amdgpu_connector_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = amdgpu_connector_set_property,
.early_unregister = amdgpu_connector_unregister,
.destroy = amdgpu_connector_destroy,
.force = amdgpu_connector_dvi_force,
};
Expand All @@ -1502,6 +1512,7 @@ static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {
.detect = amdgpu_connector_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = amdgpu_connector_set_lcd_property,
.early_unregister = amdgpu_connector_unregister,
.destroy = amdgpu_connector_destroy,
.force = amdgpu_connector_dvi_force,
};
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx)
ctx->rings[i].sequence = 1;
ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i];
}

ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);

/* create context entity for each ring */
for (i = 0; i < adev->num_rings; i++) {
struct amdgpu_ring *ring = adev->rings[i];
Expand Down
69 changes: 52 additions & 17 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1408,16 +1408,6 @@ static int amdgpu_late_init(struct amdgpu_device *adev)
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_block_status[i].valid)
continue;
if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_UVD ||
adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_VCE)
continue;
/* enable clockgating to save power */
r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
AMD_CG_STATE_GATE);
if (r) {
DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
return r;
}
if (adev->ip_blocks[i].funcs->late_init) {
r = adev->ip_blocks[i].funcs->late_init((void *)adev);
if (r) {
Expand All @@ -1426,6 +1416,18 @@ static int amdgpu_late_init(struct amdgpu_device *adev)
}
adev->ip_block_status[i].late_initialized = true;
}
/* skip CG for VCE/UVD, it's handled specially */
if (adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_UVD &&
adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_VCE) {
/* enable clockgating to save power */
r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
AMD_CG_STATE_GATE);
if (r) {
DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n",
adev->ip_blocks[i].funcs->name, r);
return r;
}
}
}

return 0;
Expand All @@ -1435,6 +1437,30 @@ static int amdgpu_fini(struct amdgpu_device *adev)
{
int i, r;

/* need to disable SMC first */
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_block_status[i].hw)
continue;
if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) {
/* ungate blocks before hw fini so that we can shutdown the blocks safely */
r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
AMD_CG_STATE_UNGATE);
if (r) {
DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n",
adev->ip_blocks[i].funcs->name, r);
return r;
}
r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
/* XXX handle errors */
if (r) {
DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
adev->ip_blocks[i].funcs->name, r);
}
adev->ip_block_status[i].hw = false;
break;
}
}

for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_block_status[i].hw)
continue;
Expand Down Expand Up @@ -2073,7 +2099,8 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev)
if (!adev->ip_block_status[i].valid)
continue;
if (adev->ip_blocks[i].funcs->check_soft_reset)
adev->ip_blocks[i].funcs->check_soft_reset(adev);
adev->ip_block_status[i].hang =
adev->ip_blocks[i].funcs->check_soft_reset(adev);
if (adev->ip_block_status[i].hang) {
DRM_INFO("IP block:%d is hang!\n", i);
asic_hang = true;
Expand Down Expand Up @@ -2102,12 +2129,20 @@ static int amdgpu_pre_soft_reset(struct amdgpu_device *adev)

static bool amdgpu_need_full_reset(struct amdgpu_device *adev)
{
if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang ||
adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang ||
adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang ||
adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) {
DRM_INFO("Some block need full reset!\n");
return true;
int i;

for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_block_status[i].valid)
continue;
if ((adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) ||
(adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) ||
(adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_ACP) ||
(adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_DCE)) {
if (adev->ip_block_status[i].hang) {
DRM_INFO("Some block need full reset!\n");
return true;
}
}
}
return false;
}
Expand Down
14 changes: 8 additions & 6 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
printk("\n");
}


u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
{
struct drm_device *dev = adev->ddev;
struct drm_crtc *crtc;
struct amdgpu_crtc *amdgpu_crtc;
u32 line_time_us, vblank_lines;
u32 vblank_in_pixels;
u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */

if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
amdgpu_crtc = to_amdgpu_crtc(crtc);
if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
amdgpu_crtc->hw_mode.clock;
vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
vblank_in_pixels =
amdgpu_crtc->hw_mode.crtc_htotal *
(amdgpu_crtc->hw_mode.crtc_vblank_end -
amdgpu_crtc->hw_mode.crtc_vdisplay +
(amdgpu_crtc->v_border * 2);
vblank_time_us = vblank_lines * line_time_us;
(amdgpu_crtc->v_border * 2));

vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,8 @@ static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
ent = debugfs_create_file(name,
S_IFREG | S_IRUGO, root,
ring, &amdgpu_debugfs_ring_fops);
if (IS_ERR(ent))
return PTR_ERR(ent);
if (!ent)
return -ENOMEM;

i_size_write(ent->d_inode, ring->ring_size + 12);
ring->ent = ent;
Expand Down
8 changes: 5 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/cz_dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1514,14 +1514,16 @@ static int cz_dpm_set_powergating_state(void *handle,
return 0;
}

/* borrowed from KV, need future unify */
static int cz_dpm_get_temperature(struct amdgpu_device *adev)
{
int actual_temp = 0;
uint32_t temp = RREG32_SMC(0xC0300E0C);
uint32_t val = RREG32_SMC(ixTHM_TCON_CUR_TMP);
uint32_t temp = REG_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP);

if (temp)
if (REG_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP_RANGE_SEL))
actual_temp = 1000 * ((temp / 8) - 49);
else
actual_temp = 1000 * (temp / 8);

return actual_temp;
}
Expand Down
12 changes: 2 additions & 10 deletions drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -3188,26 +3188,18 @@ static int dce_v10_0_wait_for_idle(void *handle)
return 0;
}

static int dce_v10_0_check_soft_reset(void *handle)
static bool dce_v10_0_check_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;

if (dce_v10_0_is_display_hung(adev))
adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = true;
else
adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = false;

return 0;
return dce_v10_0_is_display_hung(adev);
}

static int dce_v10_0_soft_reset(void *handle)
{
u32 srbm_soft_reset = 0, tmp;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;

if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang)
return 0;

if (dce_v10_0_is_display_hung(adev))
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;

Expand Down
30 changes: 19 additions & 11 deletions drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -4087,14 +4087,21 @@ static int gfx_v8_0_rlc_load_microcode(struct amdgpu_device *adev)
static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
{
int r;
u32 tmp;

gfx_v8_0_rlc_stop(adev);

/* disable CG */
WREG32(mmRLC_CGCG_CGLS_CTRL, 0);
tmp = RREG32(mmRLC_CGCG_CGLS_CTRL);
tmp &= ~(RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK |
RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK);
WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);
if (adev->asic_type == CHIP_POLARIS11 ||
adev->asic_type == CHIP_POLARIS10)
WREG32(mmRLC_CGCG_CGLS_CTRL_3D, 0);
adev->asic_type == CHIP_POLARIS10) {
tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D);
tmp &= ~0x3;
WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp);
}

/* disable PG */
WREG32(mmRLC_PG_CNTL, 0);
Expand Down Expand Up @@ -5137,7 +5144,7 @@ static int gfx_v8_0_wait_for_idle(void *handle)
return -ETIMEDOUT;
}

static int gfx_v8_0_check_soft_reset(void *handle)
static bool gfx_v8_0_check_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
Expand Down Expand Up @@ -5189,16 +5196,14 @@ static int gfx_v8_0_check_soft_reset(void *handle)
SRBM_SOFT_RESET, SOFT_RESET_SEM, 1);

if (grbm_soft_reset || srbm_soft_reset) {
adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = true;
adev->gfx.grbm_soft_reset = grbm_soft_reset;
adev->gfx.srbm_soft_reset = srbm_soft_reset;
return true;
} else {
adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = false;
adev->gfx.grbm_soft_reset = 0;
adev->gfx.srbm_soft_reset = 0;
return false;
}

return 0;
}

static void gfx_v8_0_inactive_hqd(struct amdgpu_device *adev,
Expand Down Expand Up @@ -5226,7 +5231,8 @@ static int gfx_v8_0_pre_soft_reset(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
u32 grbm_soft_reset = 0, srbm_soft_reset = 0;

if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
if ((!adev->gfx.grbm_soft_reset) &&
(!adev->gfx.srbm_soft_reset))
return 0;

grbm_soft_reset = adev->gfx.grbm_soft_reset;
Expand Down Expand Up @@ -5264,7 +5270,8 @@ static int gfx_v8_0_soft_reset(void *handle)
u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
u32 tmp;

if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
if ((!adev->gfx.grbm_soft_reset) &&
(!adev->gfx.srbm_soft_reset))
return 0;

grbm_soft_reset = adev->gfx.grbm_soft_reset;
Expand Down Expand Up @@ -5334,7 +5341,8 @@ static int gfx_v8_0_post_soft_reset(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
u32 grbm_soft_reset = 0, srbm_soft_reset = 0;

if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
if ((!adev->gfx.grbm_soft_reset) &&
(!adev->gfx.srbm_soft_reset))
return 0;

grbm_soft_reset = adev->gfx.grbm_soft_reset;
Expand Down
Loading

0 comments on commit 37c1e28

Please sign in to comment.