diff options
| -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); |
