diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 3 |
2 files changed, 22 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 250a3a918193..f82832780a7e 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -170,6 +170,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
170 | struct r600_cs_track *track = p->track; | 170 | struct r600_cs_track *track = p->track; |
171 | u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align; | 171 | u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align; |
172 | volatile u32 *ib = p->ib->ptr; | 172 | volatile u32 *ib = p->ib->ptr; |
173 | unsigned array_mode; | ||
173 | 174 | ||
174 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | 175 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { |
175 | dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); | 176 | dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); |
@@ -185,12 +186,12 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
185 | /* pitch is the number of 8x8 tiles per row */ | 186 | /* pitch is the number of 8x8 tiles per row */ |
186 | pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1; | 187 | pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1; |
187 | slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; | 188 | slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; |
188 | height = size / (pitch * 8 * bpe); | 189 | slice_tile_max *= 64; |
190 | height = slice_tile_max / (pitch * 8); | ||
189 | if (height > 8192) | 191 | if (height > 8192) |
190 | height = 8192; | 192 | height = 8192; |
191 | if (height > 7) | 193 | array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); |
192 | height &= ~0x7; | 194 | switch (array_mode) { |
193 | switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) { | ||
194 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 195 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
195 | /* technically height & 0x7 */ | 196 | /* technically height & 0x7 */ |
196 | break; | 197 | break; |
@@ -222,7 +223,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
222 | break; | 223 | break; |
223 | case V_0280A0_ARRAY_2D_TILED_THIN1: | 224 | case V_0280A0_ARRAY_2D_TILED_THIN1: |
224 | pitch_align = max((u32)track->nbanks, | 225 | pitch_align = max((u32)track->nbanks, |
225 | (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)); | 226 | (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8; |
226 | if (!IS_ALIGNED(pitch, pitch_align)) { | 227 | if (!IS_ALIGNED(pitch, pitch_align)) { |
227 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", | 228 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", |
228 | __func__, __LINE__, pitch); | 229 | __func__, __LINE__, pitch); |
@@ -243,8 +244,18 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
243 | /* check offset */ | 244 | /* check offset */ |
244 | tmp = height * pitch * 8 * bpe; | 245 | tmp = height * pitch * 8 * bpe; |
245 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { | 246 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { |
246 | dev_warn(p->dev, "%s offset[%d] %d too big\n", __func__, i, track->cb_color_bo_offset[i]); | 247 | if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { |
247 | return -EINVAL; | 248 | /* the initial DDX does bad things with the CB size occasionally */ |
249 | /* it rounds up height too far for slice tile max but the BO is smaller */ | ||
250 | tmp = (height - 7) * 8 * bpe; | ||
251 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { | ||
252 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | } else { | ||
256 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); | ||
257 | return -EINVAL; | ||
258 | } | ||
248 | } | 259 | } |
249 | if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) { | 260 | if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) { |
250 | dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]); | 261 | dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]); |
@@ -361,7 +372,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
361 | break; | 372 | break; |
362 | case V_028010_ARRAY_2D_TILED_THIN1: | 373 | case V_028010_ARRAY_2D_TILED_THIN1: |
363 | pitch_align = max((u32)track->nbanks, | 374 | pitch_align = max((u32)track->nbanks, |
364 | (u32)(((track->group_size / 8) / bpe) * track->nbanks)); | 375 | (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; |
365 | if (!IS_ALIGNED(pitch, pitch_align)) { | 376 | if (!IS_ALIGNED(pitch, pitch_align)) { |
366 | dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", | 377 | dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", |
367 | __func__, __LINE__, pitch); | 378 | __func__, __LINE__, pitch); |
@@ -1138,7 +1149,7 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i | |||
1138 | break; | 1149 | break; |
1139 | case V_038000_ARRAY_2D_TILED_THIN1: | 1150 | case V_038000_ARRAY_2D_TILED_THIN1: |
1140 | pitch_align = max((u32)track->nbanks, | 1151 | pitch_align = max((u32)track->nbanks, |
1141 | (u32)(((track->group_size / 8) / bpe) * track->nbanks)); | 1152 | (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; |
1142 | if (!IS_ALIGNED(pitch, pitch_align)) { | 1153 | if (!IS_ALIGNED(pitch, pitch_align)) { |
1143 | dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", | 1154 | dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", |
1144 | __func__, __LINE__, pitch); | 1155 | __func__, __LINE__, pitch); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index f29a2695d961..f9e228661119 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -47,9 +47,10 @@ | |||
47 | * - 2.4.0 - add crtc id query | 47 | * - 2.4.0 - add crtc id query |
48 | * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen | 48 | * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen |
49 | * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) | 49 | * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) |
50 | * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change) | ||
50 | */ | 51 | */ |
51 | #define KMS_DRIVER_MAJOR 2 | 52 | #define KMS_DRIVER_MAJOR 2 |
52 | #define KMS_DRIVER_MINOR 6 | 53 | #define KMS_DRIVER_MINOR 7 |
53 | #define KMS_DRIVER_PATCHLEVEL 0 | 54 | #define KMS_DRIVER_PATCHLEVEL 0 |
54 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 55 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
55 | int radeon_driver_unload_kms(struct drm_device *dev); | 56 | int radeon_driver_unload_kms(struct drm_device *dev); |