X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fradeon%2Fr600.c;h=6ea947d669e9edb91587f349fb6c46edb8124519;hb=7fff400be6fbf64f10abca9939718aaf1d61c255;hp=c52290197292a1a958d05dcd3896587055542b8b;hpb=01da47059ab54544a508b217598fb0e73b73e7a8;p=pandora-kernel.git diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c52290197292..6ea947d669e9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -25,12 +25,14 @@ * Alex Deucher * Jerome Glisse */ +#include #include #include #include #include "drmP.h" #include "radeon_drm.h" #include "radeon.h" +#include "radeon_asic.h" #include "radeon_mode.h" #include "r600d.h" #include "atom.h" @@ -491,9 +493,9 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) void r600_pcie_gart_fini(struct radeon_device *rdev) { + radeon_gart_fini(rdev); r600_pcie_gart_disable(rdev); radeon_gart_table_vram_free(rdev); - radeon_gart_fini(rdev); } void r600_agp_enable(struct radeon_device *rdev) @@ -675,7 +677,6 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) int r600_mc_init(struct radeon_device *rdev) { - fixed20_12 a; u32 tmp; int chansize, numchan; @@ -719,14 +720,10 @@ int r600_mc_init(struct radeon_device *rdev) rdev->mc.real_vram_size = rdev->mc.aper_size; } r600_vram_gtt_location(rdev, &rdev->mc); - /* FIXME: we should enforce default clock in case GPU is not in - * default setup - */ - a.full = rfixed_const(100); - rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); - rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); + if (rdev->flags & RADEON_IS_IGP) rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); + radeon_update_bandwidth_info(rdev); return 0; } @@ -753,7 +750,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); - u32 srbm_reset = 0; u32 tmp; dev_info(rdev->dev, "GPU softreset \n"); @@ -768,7 +764,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); } /* Disable CP parsing/prefetching */ - WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); + WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); /* Check if any of the rendering block is busy and reset it */ if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { @@ -787,72 +783,56 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) S_008020_SOFT_RESET_VGT(1); dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); WREG32(R_008020_GRBM_SOFT_RESET, tmp); - (void)RREG32(R_008020_GRBM_SOFT_RESET); - udelay(50); + RREG32(R_008020_GRBM_SOFT_RESET); + mdelay(15); WREG32(R_008020_GRBM_SOFT_RESET, 0); - (void)RREG32(R_008020_GRBM_SOFT_RESET); } /* Reset CP (we always reset CP) */ tmp = S_008020_SOFT_RESET_CP(1); dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); WREG32(R_008020_GRBM_SOFT_RESET, tmp); - (void)RREG32(R_008020_GRBM_SOFT_RESET); - udelay(50); + RREG32(R_008020_GRBM_SOFT_RESET); + mdelay(15); WREG32(R_008020_GRBM_SOFT_RESET, 0); - (void)RREG32(R_008020_GRBM_SOFT_RESET); - /* Reset others GPU block if necessary */ - if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_RLC(1); - if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_GRBM(1); - if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_IH(1); - if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_VMC(1); - if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_MC(1); - if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_MC(1); - if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_MC(1); - if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_MC(1); - if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_MC(1); - if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_RLC(1); - if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_SEM(1); - if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS))) - srbm_reset |= S_000E60_SOFT_RESET_BIF(1); - dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset); - WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); - (void)RREG32(R_000E60_SRBM_SOFT_RESET); - udelay(50); - WREG32(R_000E60_SRBM_SOFT_RESET, 0); - (void)RREG32(R_000E60_SRBM_SOFT_RESET); - WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); - (void)RREG32(R_000E60_SRBM_SOFT_RESET); - udelay(50); - WREG32(R_000E60_SRBM_SOFT_RESET, 0); - (void)RREG32(R_000E60_SRBM_SOFT_RESET); /* Wait a little for things to settle down */ - udelay(50); + mdelay(1); dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", RREG32(R_008010_GRBM_STATUS)); dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", RREG32(R_008014_GRBM_STATUS2)); dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", RREG32(R_000E50_SRBM_STATUS)); - /* After reset we need to reinit the asic as GPU often endup in an - * incoherent state. - */ - atom_asic_init(rdev->mode_info.atom_context); rv515_mc_resume(rdev, &save); return 0; } -int r600_gpu_reset(struct radeon_device *rdev) +bool r600_gpu_is_lockup(struct radeon_device *rdev) +{ + u32 srbm_status; + u32 grbm_status; + u32 grbm_status2; + int r; + + srbm_status = RREG32(R_000E50_SRBM_STATUS); + grbm_status = RREG32(R_008010_GRBM_STATUS); + grbm_status2 = RREG32(R_008014_GRBM_STATUS2); + if (!G_008010_GUI_ACTIVE(grbm_status)) { + r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp); + return false; + } + /* force CP activities */ + r = radeon_ring_lock(rdev, 2); + if (!r) { + /* PACKET2 NOP */ + radeon_ring_write(rdev, 0x80000000); + radeon_ring_write(rdev, 0x80000000); + radeon_ring_unlock_commit(rdev); + } + rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp); +} + +int r600_asic_reset(struct radeon_device *rdev) { return r600_gpu_soft_reset(rdev); } @@ -1132,6 +1112,7 @@ void r600_gpu_init(struct radeon_device *rdev) /* Setup pipes */ WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); + WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); @@ -2119,6 +2100,7 @@ int r600_init(struct radeon_device *rdev) void r600_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r600_audio_fini(rdev); r600_blit_fini(rdev); r600_cp_fini(rdev); @@ -2398,19 +2380,19 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) WREG32(DC_HPD4_INT_CONTROL, tmp); if (ASIC_IS_DCE32(rdev)) { tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD5_INT_CONTROL, 0); + WREG32(DC_HPD5_INT_CONTROL, tmp); tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD6_INT_CONTROL, 0); + WREG32(DC_HPD6_INT_CONTROL, tmp); } } else { WREG32(DACA_AUTODETECT_INT_CONTROL, 0); WREG32(DACB_AUTODETECT_INT_CONTROL, 0); tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0); + WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0); + WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0); + WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); } } @@ -2765,6 +2747,7 @@ restart_ih: case 0: /* D1 vblank */ if (disp_int & LB_D1_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); @@ -2786,6 +2769,7 @@ restart_ih: case 0: /* D2 vblank */ if (disp_int & LB_D2_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); @@ -2834,14 +2818,14 @@ restart_ih: break; case 10: if (disp_int_cont2 & DC_HPD5_INTERRUPT) { - disp_int_cont &= ~DC_HPD5_INTERRUPT; + disp_int_cont2 &= ~DC_HPD5_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD5\n"); } break; case 12: if (disp_int_cont2 & DC_HPD6_INTERRUPT) { - disp_int_cont &= ~DC_HPD6_INTERRUPT; + disp_int_cont2 &= ~DC_HPD6_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD6\n"); }