* [PATCH 2/3] drm/radeon/kms: fix scanout of 2D tiled buffers on EG/CM
2011-11-28 19:49 [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code alexdeucher
@ 2011-11-28 19:49 ` alexdeucher
2011-11-28 19:49 ` [PATCH 3/3] drm/radeon/kms: fix 2D tiling CS support " alexdeucher
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: alexdeucher @ 2011-11-28 19:49 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher
From: Alex Deucher <alexander.deucher@amd.com>
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=43191
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/radeon/atombios_crtc.c | 35 ++++++++++++++++++++++++++++++-
drivers/gpu/drm/radeon/evergreen_reg.h | 29 ++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 87631fe..2b97262 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1107,9 +1107,40 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
return -EINVAL;
}
- if (tiling_flags & RADEON_TILING_MACRO)
+ if (tiling_flags & RADEON_TILING_MACRO) {
+ if (rdev->family >= CHIP_CAYMAN)
+ tmp = rdev->config.cayman.tile_config;
+ else
+ tmp = rdev->config.evergreen.tile_config;
+
+ switch ((tmp & 0xf0) >> 4) {
+ case 0: /* 4 banks */
+ fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
+ break;
+ case 1: /* 8 banks */
+ default:
+ fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
+ break;
+ case 2: /* 16 banks */
+ fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
+ break;
+ }
+
+ switch ((tmp & 0xf000) >> 12) {
+ case 0: /* 1KB rows */
+ default:
+ fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
+ break;
+ case 1: /* 2KB rows */
+ fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
+ break;
+ case 2: /* 4KB rows */
+ fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
+ break;
+ }
+
fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
- else if (tiling_flags & RADEON_TILING_MICRO)
+ } else if (tiling_flags & RADEON_TILING_MICRO)
fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
switch (radeon_crtc->crtc_id) {
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index c781c92..7d7f215 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -42,6 +42,17 @@
# define EVERGREEN_GRPH_DEPTH_8BPP 0
# define EVERGREEN_GRPH_DEPTH_16BPP 1
# define EVERGREEN_GRPH_DEPTH_32BPP 2
+# define EVERGREEN_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2)
+# define EVERGREEN_ADDR_SURF_2_BANK 0
+# define EVERGREEN_ADDR_SURF_4_BANK 1
+# define EVERGREEN_ADDR_SURF_8_BANK 2
+# define EVERGREEN_ADDR_SURF_16_BANK 3
+# define EVERGREEN_GRPH_Z(x) (((x) & 0x3) << 4)
+# define EVERGREEN_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6)
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_1 0
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_2 1
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_4 2
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_8 3
# define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8)
/* 8 BPP */
# define EVERGREEN_GRPH_FORMAT_INDEXED 0
@@ -61,6 +72,24 @@
# define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5
# define EVERGREEN_GRPH_FORMAT_RGB111110 6
# define EVERGREEN_GRPH_FORMAT_BGR101111 7
+# define EVERGREEN_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11)
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_1 0
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_2 1
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_4 2
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_8 3
+# define EVERGREEN_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13)
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_64B 0
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_128B 1
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_256B 2
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_512B 3
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB 4
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB 5
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB 6
+# define EVERGREEN_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18)
+# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1 0
+# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2 1
+# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4 2
+# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8 3
# define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20)
# define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0
# define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1
--
1.7.3.4
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] drm/radeon/kms: fix 2D tiling CS support on EG/CM
2011-11-28 19:49 [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code alexdeucher
2011-11-28 19:49 ` [PATCH 2/3] drm/radeon/kms: fix scanout of 2D tiled buffers on EG/CM alexdeucher
@ 2011-11-28 19:49 ` alexdeucher
2011-11-28 21:12 ` [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code Mario Kleiner
2011-11-29 11:10 ` Simon Farnsworth
3 siblings, 0 replies; 5+ messages in thread
From: alexdeucher @ 2011-11-28 19:49 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher
From: Alex Deucher <alexander.deucher@amd.com>
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=43191
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/radeon/evergreen_cs.c | 149 +++++++++++++++++++++++++++------
drivers/gpu/drm/radeon/evergreend.h | 31 +++++++
2 files changed, 154 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 38e1bda..cd4590a 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -38,6 +38,7 @@ struct evergreen_cs_track {
u32 group_size;
u32 nbanks;
u32 npipes;
+ u32 row_size;
/* value we track */
u32 nsamples;
u32 cb_color_base_last[12];
@@ -77,6 +78,44 @@ struct evergreen_cs_track {
struct radeon_bo *db_s_write_bo;
};
+static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
+{
+ if (tiling_flags & RADEON_TILING_MACRO)
+ return ARRAY_2D_TILED_THIN1;
+ else if (tiling_flags & RADEON_TILING_MICRO)
+ return ARRAY_1D_TILED_THIN1;
+ else
+ return ARRAY_LINEAR_GENERAL;
+}
+
+static u32 evergreen_cs_get_num_banks(u32 nbanks)
+{
+ switch (nbanks) {
+ case 2:
+ return ADDR_SURF_2_BANK;
+ case 4:
+ return ADDR_SURF_4_BANK;
+ case 8:
+ default:
+ return ADDR_SURF_8_BANK;
+ case 16:
+ return ADDR_SURF_16_BANK;
+ }
+}
+
+static u32 evergreen_cs_get_tile_split(u32 row_size)
+{
+ switch (row_size) {
+ case 1:
+ default:
+ return ADDR_SURF_TILE_SPLIT_1KB;
+ case 2:
+ return ADDR_SURF_TILE_SPLIT_2KB;
+ case 4:
+ return ADDR_SURF_TILE_SPLIT_4KB;
+ }
+}
+
static void evergreen_cs_track_init(struct evergreen_cs_track *track)
{
int i;
@@ -490,12 +529,11 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
}
ib[idx] &= ~Z_ARRAY_MODE(0xf);
track->db_z_info &= ~Z_ARRAY_MODE(0xf);
+ ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+ track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
- ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- } else {
- ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+ ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+ ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
}
}
break;
@@ -618,13 +656,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
"0x%04X\n", reg);
return -EINVAL;
}
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- }
+ ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+ track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
}
break;
case CB_COLOR8_INFO:
@@ -640,13 +673,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
"0x%04X\n", reg);
return -EINVAL;
}
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- }
+ ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+ track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
}
break;
case CB_COLOR0_PITCH:
@@ -701,6 +729,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
case CB_COLOR9_ATTRIB:
case CB_COLOR10_ATTRIB:
case CB_COLOR11_ATTRIB:
+ r = evergreen_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ dev_warn(p->dev, "bad SET_CONTEXT_REG "
+ "0x%04X\n", reg);
+ return -EINVAL;
+ }
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+ ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+ ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+ }
break;
case CB_COLOR0_DIM:
case CB_COLOR1_DIM:
@@ -1318,10 +1356,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
}
ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
if (!p->keep_tiling_flags) {
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
- ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
- ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+ ib[idx+1+(i*8)+1] |=
+ TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+ ib[idx+1+(i*8)+6] |=
+ TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+ ib[idx+1+(i*8)+7] |=
+ TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+ }
}
texture = reloc->robj;
/* tex mip base */
@@ -1422,6 +1464,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
{
struct radeon_cs_packet pkt;
struct evergreen_cs_track *track;
+ u32 tmp;
int r;
if (p->track == NULL) {
@@ -1430,9 +1473,63 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
if (track == NULL)
return -ENOMEM;
evergreen_cs_track_init(track);
- track->npipes = p->rdev->config.evergreen.tiling_npipes;
- track->nbanks = p->rdev->config.evergreen.tiling_nbanks;
- track->group_size = p->rdev->config.evergreen.tiling_group_size;
+ if (p->rdev->family >= CHIP_CAYMAN)
+ tmp = p->rdev->config.cayman.tile_config;
+ else
+ tmp = p->rdev->config.evergreen.tile_config;
+
+ switch (tmp & 0xf) {
+ case 0:
+ track->npipes = 1;
+ break;
+ case 1:
+ default:
+ track->npipes = 2;
+ break;
+ case 2:
+ track->npipes = 4;
+ break;
+ case 3:
+ track->npipes = 8;
+ break;
+ }
+
+ switch ((tmp & 0xf0) >> 4) {
+ case 0:
+ track->nbanks = 4;
+ break;
+ case 1:
+ default:
+ track->nbanks = 8;
+ break;
+ case 2:
+ track->nbanks = 16;
+ break;
+ }
+
+ switch ((tmp & 0xf00) >> 8) {
+ case 0:
+ track->group_size = 256;
+ break;
+ case 1:
+ default:
+ track->group_size = 512;
+ break;
+ }
+
+ switch ((tmp & 0xf000) >> 12) {
+ case 0:
+ track->row_size = 1;
+ break;
+ case 1:
+ default:
+ track->row_size = 2;
+ break;
+ case 2:
+ track->row_size = 4;
+ break;
+ }
+
p->track = track;
}
do {
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index b937c49..e00039e 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -899,6 +899,10 @@
#define DB_HTILE_DATA_BASE 0x28014
#define DB_Z_INFO 0x28040
# define Z_ARRAY_MODE(x) ((x) << 4)
+# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8)
+# define DB_NUM_BANKS(x) (((x) & 0x3) << 12)
+# define DB_BANK_WIDTH(x) (((x) & 0x3) << 16)
+# define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20)
#define DB_STENCIL_INFO 0x28044
#define DB_Z_READ_BASE 0x28048
#define DB_STENCIL_READ_BASE 0x2804c
@@ -951,6 +955,29 @@
# define CB_SF_EXPORT_FULL 0
# define CB_SF_EXPORT_NORM 1
#define CB_COLOR0_ATTRIB 0x28c74
+# define CB_TILE_SPLIT(x) (((x) & 0x7) << 5)
+# define ADDR_SURF_TILE_SPLIT_64B 0
+# define ADDR_SURF_TILE_SPLIT_128B 1
+# define ADDR_SURF_TILE_SPLIT_256B 2
+# define ADDR_SURF_TILE_SPLIT_512B 3
+# define ADDR_SURF_TILE_SPLIT_1KB 4
+# define ADDR_SURF_TILE_SPLIT_2KB 5
+# define ADDR_SURF_TILE_SPLIT_4KB 6
+# define CB_NUM_BANKS(x) (((x) & 0x3) << 10)
+# define ADDR_SURF_2_BANK 0
+# define ADDR_SURF_4_BANK 1
+# define ADDR_SURF_8_BANK 2
+# define ADDR_SURF_16_BANK 3
+# define CB_BANK_WIDTH(x) (((x) & 0x3) << 13)
+# define ADDR_SURF_BANK_WIDTH_1 0
+# define ADDR_SURF_BANK_WIDTH_2 1
+# define ADDR_SURF_BANK_WIDTH_4 2
+# define ADDR_SURF_BANK_WIDTH_8 3
+# define CB_BANK_HEIGHT(x) (((x) & 0x3) << 16)
+# define ADDR_SURF_BANK_HEIGHT_1 0
+# define ADDR_SURF_BANK_HEIGHT_2 1
+# define ADDR_SURF_BANK_HEIGHT_4 2
+# define ADDR_SURF_BANK_HEIGHT_8 3
#define CB_COLOR0_DIM 0x28c78
/* only CB0-7 blocks have these regs */
#define CB_COLOR0_CMASK 0x28c7c
@@ -1137,7 +1164,11 @@
# define SQ_SEL_1 5
#define SQ_TEX_RESOURCE_WORD5_0 0x30014
#define SQ_TEX_RESOURCE_WORD6_0 0x30018
+# define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29)
#define SQ_TEX_RESOURCE_WORD7_0 0x3001c
+# define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8)
+# define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10)
+# define TEX_NUM_BANKS(x) (((x) & 0x3) << 16)
#define SQ_VTX_CONSTANT_WORD0_0 0x30000
#define SQ_VTX_CONSTANT_WORD1_0 0x30004
--
1.7.3.4
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code
2011-11-28 19:49 [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code alexdeucher
2011-11-28 19:49 ` [PATCH 2/3] drm/radeon/kms: fix scanout of 2D tiled buffers on EG/CM alexdeucher
2011-11-28 19:49 ` [PATCH 3/3] drm/radeon/kms: fix 2D tiling CS support " alexdeucher
@ 2011-11-28 21:12 ` Mario Kleiner
2011-11-29 11:10 ` Simon Farnsworth
3 siblings, 0 replies; 5+ messages in thread
From: Mario Kleiner @ 2011-11-28 21:12 UTC (permalink / raw)
To: alexdeucher; +Cc: Alex Deucher, stable, dri-devel
On Nov 28, 2011, at 8:49 PM, alexdeucher@gmail.com wrote:
> From: Alex Deucher <alexander.deucher@amd.com>
>
> Avoid infinite loops waiting for surface updates if a GPU
> reset happens while waiting for a page flip.
>
> See:
> https://bugs.freedesktop.org/show_bug.cgi?id=43191
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: stable@kernel.org
> Cc: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
> ---
> drivers/gpu/drm/radeon/evergreen.c | 7 ++++++-
> drivers/gpu/drm/radeon/r100.c | 7 ++++++-
> drivers/gpu/drm/radeon/rs600.c | 7 ++++++-
> drivers/gpu/drm/radeon/rv770.c | 7 ++++++-
> 4 files changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/
> radeon/evergreen.c
> index 99cdc5d..e78feab 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -84,6 +84,7 @@ u32 evergreen_page_flip(struct radeon_device
> *rdev, int crtc_id, u64 crtc_base)
> {
> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
> + int i;
>
> /* Lock the graphics update lock */
> tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
> @@ -101,7 +102,11 @@ u32 evergreen_page_flip(struct radeon_device
> *rdev, int crtc_id, u64 crtc_base)
> (u32)crtc_base);
>
> /* Wait for update_pending to go high. */
> - while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset)
> & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING));
> + for (i = 0; i < rdev->usec_timeout; i++) {
> + if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
> EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
> + break;
> + udelay(1);
> + }
> DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
>
> /* Unlock the lock, so double-buffering can take place inside
> vblank */
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/
> r100.c
> index 4e71da0..d7fd5aa 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -187,13 +187,18 @@ u32 r100_page_flip(struct radeon_device
> *rdev, int crtc_id, u64 crtc_base)
> {
> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
> + int i;
>
> /* Lock the graphics update lock */
> /* update the scanout addresses */
> WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
>
> /* Wait for update_pending to go high. */
> - while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
> RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
> + for (i = 0; i < rdev->usec_timeout; i++) {
> + if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
> RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
> + break;
> + udelay(1);
> + }
> DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
>
> /* Unlock the lock, so double-buffering can take place inside
> vblank */
> diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/
> radeon/rs600.c
> index 8ce17ed..8a52cf0 100644
> --- a/drivers/gpu/drm/radeon/rs600.c
> +++ b/drivers/gpu/drm/radeon/rs600.c
> @@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device *rdev,
> int crtc_id, u64 crtc_base)
> {
> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
> + int i;
>
> /* Lock the graphics update lock */
> tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
> @@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device *rdev,
> int crtc_id, u64 crtc_base)
> (u32)crtc_base);
>
> /* Wait for update_pending to go high. */
> - while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
> + for (i = 0; i < rdev->usec_timeout; i++) {
> + if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
> + break;
> + udelay(1);
> + }
> DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
>
> /* Unlock the lock, so double-buffering can take place inside
> vblank */
> diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/
> radeon/rv770.c
> index a9242e6..7bec3f4 100644
> --- a/drivers/gpu/drm/radeon/rv770.c
> +++ b/drivers/gpu/drm/radeon/rv770.c
> @@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device *rdev,
> int crtc_id, u64 crtc_base)
> {
> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
> u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
> + int i;
>
> /* Lock the graphics update lock */
> tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
> @@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device *rdev,
> int crtc_id, u64 crtc_base)
> (u32)crtc_base);
>
> /* Wait for update_pending to go high. */
> - while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
> + for (i = 0; i < rdev->usec_timeout; i++) {
> + if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
> AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
> + break;
> + udelay(1);
> + }
> DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
>
> /* Unlock the lock, so double-buffering can take place inside
> vblank */
> --
> 1.7.3.4
>
Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
*********************************************************************
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner@tuebingen.mpg.de
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code
2011-11-28 19:49 [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code alexdeucher
` (2 preceding siblings ...)
2011-11-28 21:12 ` [PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code Mario Kleiner
@ 2011-11-29 11:10 ` Simon Farnsworth
3 siblings, 0 replies; 5+ messages in thread
From: Simon Farnsworth @ 2011-11-29 11:10 UTC (permalink / raw)
To: dri-devel; +Cc: Alex Deucher, stable, Mario Kleiner
I've tested all three patches in this series, on an AMD E-350 platform.
1/3 is essential to prevent a complete system hang if the GPU needs
resetting during a page flip; the disaster case is this endless loop running
on core 0, and RCU on core 1 waiting for core 0 to idle.
The remaining two need matching patches to the DDX to be useful, and expose
bugs in Mesa as well.
Tested-by: Simon Farnsworth <simon.farnsworth@onelan.co.uk>
On Monday 28 November 2011, alexdeucher@gmail.com wrote:
> From: Alex Deucher <alexander.deucher@amd.com>
>
> Avoid infinite loops waiting for surface updates if a GPU
> reset happens while waiting for a page flip.
>
> See:
> https://bugs.freedesktop.org/show_bug.cgi?id=43191
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: stable@kernel.org
> Cc: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
> ---
> drivers/gpu/drm/radeon/evergreen.c | 7 ++++++-
> drivers/gpu/drm/radeon/r100.c | 7 ++++++-
> drivers/gpu/drm/radeon/rs600.c | 7 ++++++-
> drivers/gpu/drm/radeon/rv770.c | 7 ++++++-
> 4 files changed, 24 insertions(+), 4 deletions(-)
>
--
Simon Farnsworth
Software Engineer
ONELAN Limited
http://www.onelan.com/
^ permalink raw reply [flat|nested] 5+ messages in thread