diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 121 |
1 files changed, 31 insertions, 90 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index fe33d35dae8c..fb44e7e49083 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -139,9 +139,9 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | tmp |= tile_flags; | 141 | tmp |= tile_flags; |
142 | p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; | 142 | p->ib.ptr[idx] = (value & 0x3fc00000) | tmp; |
143 | } else | 143 | } else |
144 | p->ib->ptr[idx] = (value & 0xffc00000) | tmp; | 144 | p->ib.ptr[idx] = (value & 0xffc00000) | tmp; |
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
@@ -156,7 +156,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, | |||
156 | volatile uint32_t *ib; | 156 | volatile uint32_t *ib; |
157 | u32 idx_value; | 157 | u32 idx_value; |
158 | 158 | ||
159 | ib = p->ib->ptr; | 159 | ib = p->ib.ptr; |
160 | track = (struct r100_cs_track *)p->track; | 160 | track = (struct r100_cs_track *)p->track; |
161 | c = radeon_get_ib_value(p, idx++) & 0x1F; | 161 | c = radeon_get_ib_value(p, idx++) & 0x1F; |
162 | if (c > 16) { | 162 | if (c > 16) { |
@@ -660,7 +660,7 @@ int r100_pci_gart_enable(struct radeon_device *rdev) | |||
660 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; | 660 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; |
661 | WREG32(RADEON_AIC_CNTL, tmp); | 661 | WREG32(RADEON_AIC_CNTL, tmp); |
662 | r100_pci_gart_tlb_flush(rdev); | 662 | r100_pci_gart_tlb_flush(rdev); |
663 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 663 | DRM_INFO("PCI GART of %uM enabled (table at 0x%016llX).\n", |
664 | (unsigned)(rdev->mc.gtt_size >> 20), | 664 | (unsigned)(rdev->mc.gtt_size >> 20), |
665 | (unsigned long long)rdev->gart.table_addr); | 665 | (unsigned long long)rdev->gart.table_addr); |
666 | rdev->gart.ready = true; | 666 | rdev->gart.ready = true; |
@@ -1180,6 +1180,10 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
1180 | WREG32(RADEON_CP_RB_WPTR_DELAY, 0); | 1180 | WREG32(RADEON_CP_RB_WPTR_DELAY, 0); |
1181 | WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); | 1181 | WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); |
1182 | WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); | 1182 | WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
1183 | |||
1184 | /* at this point everything should be setup correctly to enable master */ | ||
1185 | pci_set_master(rdev->pdev); | ||
1186 | |||
1183 | radeon_ring_start(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 1187 | radeon_ring_start(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); |
1184 | r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); | 1188 | r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); |
1185 | if (r) { | 1189 | if (r) { |
@@ -1271,7 +1275,7 @@ void r100_cs_dump_packet(struct radeon_cs_parser *p, | |||
1271 | unsigned i; | 1275 | unsigned i; |
1272 | unsigned idx; | 1276 | unsigned idx; |
1273 | 1277 | ||
1274 | ib = p->ib->ptr; | 1278 | ib = p->ib.ptr; |
1275 | idx = pkt->idx; | 1279 | idx = pkt->idx; |
1276 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { | 1280 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { |
1277 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); | 1281 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); |
@@ -1350,7 +1354,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | |||
1350 | uint32_t header, h_idx, reg; | 1354 | uint32_t header, h_idx, reg; |
1351 | volatile uint32_t *ib; | 1355 | volatile uint32_t *ib; |
1352 | 1356 | ||
1353 | ib = p->ib->ptr; | 1357 | ib = p->ib.ptr; |
1354 | 1358 | ||
1355 | /* parse the wait until */ | 1359 | /* parse the wait until */ |
1356 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); | 1360 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); |
@@ -1529,7 +1533,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1529 | u32 tile_flags = 0; | 1533 | u32 tile_flags = 0; |
1530 | u32 idx_value; | 1534 | u32 idx_value; |
1531 | 1535 | ||
1532 | ib = p->ib->ptr; | 1536 | ib = p->ib.ptr; |
1533 | track = (struct r100_cs_track *)p->track; | 1537 | track = (struct r100_cs_track *)p->track; |
1534 | 1538 | ||
1535 | idx_value = radeon_get_ib_value(p, idx); | 1539 | idx_value = radeon_get_ib_value(p, idx); |
@@ -1885,7 +1889,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
1885 | volatile uint32_t *ib; | 1889 | volatile uint32_t *ib; |
1886 | int r; | 1890 | int r; |
1887 | 1891 | ||
1888 | ib = p->ib->ptr; | 1892 | ib = p->ib.ptr; |
1889 | idx = pkt->idx + 1; | 1893 | idx = pkt->idx + 1; |
1890 | track = (struct r100_cs_track *)p->track; | 1894 | track = (struct r100_cs_track *)p->track; |
1891 | switch (pkt->opcode) { | 1895 | switch (pkt->opcode) { |
@@ -2004,6 +2008,8 @@ int r100_cs_parse(struct radeon_cs_parser *p) | |||
2004 | int r; | 2008 | int r; |
2005 | 2009 | ||
2006 | track = kzalloc(sizeof(*track), GFP_KERNEL); | 2010 | track = kzalloc(sizeof(*track), GFP_KERNEL); |
2011 | if (!track) | ||
2012 | return -ENOMEM; | ||
2007 | r100_cs_track_clear(p->rdev, track); | 2013 | r100_cs_track_clear(p->rdev, track); |
2008 | p->track = track; | 2014 | p->track = track; |
2009 | do { | 2015 | do { |
@@ -2155,79 +2161,18 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev) | |||
2155 | return -1; | 2161 | return -1; |
2156 | } | 2162 | } |
2157 | 2163 | ||
2158 | void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_ring *ring) | ||
2159 | { | ||
2160 | lockup->last_cp_rptr = ring->rptr; | ||
2161 | lockup->last_jiffies = jiffies; | ||
2162 | } | ||
2163 | |||
2164 | /** | ||
2165 | * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information | ||
2166 | * @rdev: radeon device structure | ||
2167 | * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations | ||
2168 | * @cp: radeon_cp structure holding CP information | ||
2169 | * | ||
2170 | * We don't need to initialize the lockup tracking information as we will either | ||
2171 | * have CP rptr to a different value of jiffies wrap around which will force | ||
2172 | * initialization of the lockup tracking informations. | ||
2173 | * | ||
2174 | * A possible false positivie is if we get call after while and last_cp_rptr == | ||
2175 | * the current CP rptr, even if it's unlikely it might happen. To avoid this | ||
2176 | * if the elapsed time since last call is bigger than 2 second than we return | ||
2177 | * false and update the tracking information. Due to this the caller must call | ||
2178 | * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported | ||
2179 | * the fencing code should be cautious about that. | ||
2180 | * | ||
2181 | * Caller should write to the ring to force CP to do something so we don't get | ||
2182 | * false positive when CP is just gived nothing to do. | ||
2183 | * | ||
2184 | **/ | ||
2185 | bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_ring *ring) | ||
2186 | { | ||
2187 | unsigned long cjiffies, elapsed; | ||
2188 | |||
2189 | cjiffies = jiffies; | ||
2190 | if (!time_after(cjiffies, lockup->last_jiffies)) { | ||
2191 | /* likely a wrap around */ | ||
2192 | lockup->last_cp_rptr = ring->rptr; | ||
2193 | lockup->last_jiffies = jiffies; | ||
2194 | return false; | ||
2195 | } | ||
2196 | if (ring->rptr != lockup->last_cp_rptr) { | ||
2197 | /* CP is still working no lockup */ | ||
2198 | lockup->last_cp_rptr = ring->rptr; | ||
2199 | lockup->last_jiffies = jiffies; | ||
2200 | return false; | ||
2201 | } | ||
2202 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); | ||
2203 | if (elapsed >= 10000) { | ||
2204 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); | ||
2205 | return true; | ||
2206 | } | ||
2207 | /* give a chance to the GPU ... */ | ||
2208 | return false; | ||
2209 | } | ||
2210 | |||
2211 | bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | 2164 | bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) |
2212 | { | 2165 | { |
2213 | u32 rbbm_status; | 2166 | u32 rbbm_status; |
2214 | int r; | ||
2215 | 2167 | ||
2216 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); | 2168 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
2217 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { | 2169 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
2218 | r100_gpu_lockup_update(&rdev->config.r100.lockup, ring); | 2170 | radeon_ring_lockup_update(ring); |
2219 | return false; | 2171 | return false; |
2220 | } | 2172 | } |
2221 | /* force CP activities */ | 2173 | /* force CP activities */ |
2222 | r = radeon_ring_lock(rdev, ring, 2); | 2174 | radeon_ring_force_activity(rdev, ring); |
2223 | if (!r) { | 2175 | return radeon_ring_test_lockup(rdev, ring); |
2224 | /* PACKET2 NOP */ | ||
2225 | radeon_ring_write(ring, 0x80000000); | ||
2226 | radeon_ring_write(ring, 0x80000000); | ||
2227 | radeon_ring_unlock_commit(rdev, ring); | ||
2228 | } | ||
2229 | ring->rptr = RREG32(ring->rptr_reg); | ||
2230 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, ring); | ||
2231 | } | 2176 | } |
2232 | 2177 | ||
2233 | void r100_bm_disable(struct radeon_device *rdev) | 2178 | void r100_bm_disable(struct radeon_device *rdev) |
@@ -2296,7 +2241,6 @@ int r100_asic_reset(struct radeon_device *rdev) | |||
2296 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || | 2241 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || |
2297 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { | 2242 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { |
2298 | dev_err(rdev->dev, "failed to reset GPU\n"); | 2243 | dev_err(rdev->dev, "failed to reset GPU\n"); |
2299 | rdev->gpu_lockup = true; | ||
2300 | ret = -1; | 2244 | ret = -1; |
2301 | } else | 2245 | } else |
2302 | dev_info(rdev->dev, "GPU reset succeed\n"); | 2246 | dev_info(rdev->dev, "GPU reset succeed\n"); |
@@ -3742,7 +3686,7 @@ void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
3742 | 3686 | ||
3743 | int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | 3687 | int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) |
3744 | { | 3688 | { |
3745 | struct radeon_ib *ib; | 3689 | struct radeon_ib ib; |
3746 | uint32_t scratch; | 3690 | uint32_t scratch; |
3747 | uint32_t tmp = 0; | 3691 | uint32_t tmp = 0; |
3748 | unsigned i; | 3692 | unsigned i; |
@@ -3758,22 +3702,22 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
3758 | if (r) { | 3702 | if (r) { |
3759 | return r; | 3703 | return r; |
3760 | } | 3704 | } |
3761 | ib->ptr[0] = PACKET0(scratch, 0); | 3705 | ib.ptr[0] = PACKET0(scratch, 0); |
3762 | ib->ptr[1] = 0xDEADBEEF; | 3706 | ib.ptr[1] = 0xDEADBEEF; |
3763 | ib->ptr[2] = PACKET2(0); | 3707 | ib.ptr[2] = PACKET2(0); |
3764 | ib->ptr[3] = PACKET2(0); | 3708 | ib.ptr[3] = PACKET2(0); |
3765 | ib->ptr[4] = PACKET2(0); | 3709 | ib.ptr[4] = PACKET2(0); |
3766 | ib->ptr[5] = PACKET2(0); | 3710 | ib.ptr[5] = PACKET2(0); |
3767 | ib->ptr[6] = PACKET2(0); | 3711 | ib.ptr[6] = PACKET2(0); |
3768 | ib->ptr[7] = PACKET2(0); | 3712 | ib.ptr[7] = PACKET2(0); |
3769 | ib->length_dw = 8; | 3713 | ib.length_dw = 8; |
3770 | r = radeon_ib_schedule(rdev, ib); | 3714 | r = radeon_ib_schedule(rdev, &ib); |
3771 | if (r) { | 3715 | if (r) { |
3772 | radeon_scratch_free(rdev, scratch); | 3716 | radeon_scratch_free(rdev, scratch); |
3773 | radeon_ib_free(rdev, &ib); | 3717 | radeon_ib_free(rdev, &ib); |
3774 | return r; | 3718 | return r; |
3775 | } | 3719 | } |
3776 | r = radeon_fence_wait(ib->fence, false); | 3720 | r = radeon_fence_wait(ib.fence, false); |
3777 | if (r) { | 3721 | if (r) { |
3778 | return r; | 3722 | return r; |
3779 | } | 3723 | } |
@@ -3965,12 +3909,9 @@ static int r100_startup(struct radeon_device *rdev) | |||
3965 | if (r) | 3909 | if (r) |
3966 | return r; | 3910 | return r; |
3967 | 3911 | ||
3968 | r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 3912 | r = radeon_ib_ring_tests(rdev); |
3969 | if (r) { | 3913 | if (r) |
3970 | dev_err(rdev->dev, "failed testing IB (%d).\n", r); | ||
3971 | rdev->accel_working = false; | ||
3972 | return r; | 3914 | return r; |
3973 | } | ||
3974 | 3915 | ||
3975 | return 0; | 3916 | return 0; |
3976 | } | 3917 | } |