diff options
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 98 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 391 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600d.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/reg_srcs/cayman | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/reg_srcs/evergreen | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/reg_srcs/r600 | 1 |
7 files changed, 385 insertions, 123 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index a58b37a2e65a..70089d32b80f 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -80,6 +80,9 @@ struct evergreen_cs_track { | |||
80 | bool cb_dirty; | 80 | bool cb_dirty; |
81 | bool db_dirty; | 81 | bool db_dirty; |
82 | bool streamout_dirty; | 82 | bool streamout_dirty; |
83 | u32 htile_offset; | ||
84 | u32 htile_surface; | ||
85 | struct radeon_bo *htile_bo; | ||
83 | }; | 86 | }; |
84 | 87 | ||
85 | static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) | 88 | static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) |
@@ -144,6 +147,9 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track) | |||
144 | track->db_s_read_bo = NULL; | 147 | track->db_s_read_bo = NULL; |
145 | track->db_s_write_bo = NULL; | 148 | track->db_s_write_bo = NULL; |
146 | track->db_dirty = true; | 149 | track->db_dirty = true; |
150 | track->htile_bo = NULL; | ||
151 | track->htile_offset = 0xFFFFFFFF; | ||
152 | track->htile_surface = 0; | ||
147 | 153 | ||
148 | for (i = 0; i < 4; i++) { | 154 | for (i = 0; i < 4; i++) { |
149 | track->vgt_strmout_size[i] = 0; | 155 | track->vgt_strmout_size[i] = 0; |
@@ -444,6 +450,62 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i | |||
444 | return 0; | 450 | return 0; |
445 | } | 451 | } |
446 | 452 | ||
453 | static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p, | ||
454 | unsigned nbx, unsigned nby) | ||
455 | { | ||
456 | struct evergreen_cs_track *track = p->track; | ||
457 | unsigned long size; | ||
458 | |||
459 | if (track->htile_bo == NULL) { | ||
460 | dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n", | ||
461 | __func__, __LINE__, track->db_z_info); | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | |||
465 | if (G_028ABC_LINEAR(track->htile_surface)) { | ||
466 | /* pitch must be 16 htiles aligned == 16 * 8 pixel aligned */ | ||
467 | nbx = round_up(nbx, 16 * 8); | ||
468 | /* height is npipes htiles aligned == npipes * 8 pixel aligned */ | ||
469 | nby = round_up(nby, track->npipes * 8); | ||
470 | } else { | ||
471 | switch (track->npipes) { | ||
472 | case 8: | ||
473 | nbx = round_up(nbx, 64 * 8); | ||
474 | nby = round_up(nby, 64 * 8); | ||
475 | break; | ||
476 | case 4: | ||
477 | nbx = round_up(nbx, 64 * 8); | ||
478 | nby = round_up(nby, 32 * 8); | ||
479 | break; | ||
480 | case 2: | ||
481 | nbx = round_up(nbx, 32 * 8); | ||
482 | nby = round_up(nby, 32 * 8); | ||
483 | break; | ||
484 | case 1: | ||
485 | nbx = round_up(nbx, 32 * 8); | ||
486 | nby = round_up(nby, 16 * 8); | ||
487 | break; | ||
488 | default: | ||
489 | dev_warn(p->dev, "%s:%d invalid num pipes %d\n", | ||
490 | __func__, __LINE__, track->npipes); | ||
491 | return -EINVAL; | ||
492 | } | ||
493 | } | ||
494 | /* compute number of htile */ | ||
495 | nbx = nbx / 8; | ||
496 | nby = nby / 8; | ||
497 | size = nbx * nby * 4; | ||
498 | size += track->htile_offset; | ||
499 | |||
500 | if (size > radeon_bo_size(track->htile_bo)) { | ||
501 | dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n", | ||
502 | __func__, __LINE__, radeon_bo_size(track->htile_bo), | ||
503 | size, nbx, nby); | ||
504 | return -EINVAL; | ||
505 | } | ||
506 | return 0; | ||
507 | } | ||
508 | |||
447 | static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p) | 509 | static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p) |
448 | { | 510 | { |
449 | struct evergreen_cs_track *track = p->track; | 511 | struct evergreen_cs_track *track = p->track; |
@@ -530,6 +592,14 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p) | |||
530 | return -EINVAL; | 592 | return -EINVAL; |
531 | } | 593 | } |
532 | 594 | ||
595 | /* hyperz */ | ||
596 | if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) { | ||
597 | r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby); | ||
598 | if (r) { | ||
599 | return r; | ||
600 | } | ||
601 | } | ||
602 | |||
533 | return 0; | 603 | return 0; |
534 | } | 604 | } |
535 | 605 | ||
@@ -617,6 +687,14 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p) | |||
617 | return -EINVAL; | 687 | return -EINVAL; |
618 | } | 688 | } |
619 | 689 | ||
690 | /* hyperz */ | ||
691 | if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) { | ||
692 | r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby); | ||
693 | if (r) { | ||
694 | return r; | ||
695 | } | ||
696 | } | ||
697 | |||
620 | return 0; | 698 | return 0; |
621 | } | 699 | } |
622 | 700 | ||
@@ -850,7 +928,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) | |||
850 | return r; | 928 | return r; |
851 | } | 929 | } |
852 | /* Check depth buffer */ | 930 | /* Check depth buffer */ |
853 | if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) { | 931 | if (G_028800_Z_ENABLE(track->db_depth_control)) { |
854 | r = evergreen_cs_track_validate_depth(p); | 932 | r = evergreen_cs_track_validate_depth(p); |
855 | if (r) | 933 | if (r) |
856 | return r; | 934 | return r; |
@@ -1616,6 +1694,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1616 | track->cb_color_bo[tmp] = reloc->robj; | 1694 | track->cb_color_bo[tmp] = reloc->robj; |
1617 | track->cb_dirty = true; | 1695 | track->cb_dirty = true; |
1618 | break; | 1696 | break; |
1697 | case DB_HTILE_DATA_BASE: | ||
1698 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
1699 | if (r) { | ||
1700 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
1701 | "0x%04X\n", reg); | ||
1702 | return -EINVAL; | ||
1703 | } | ||
1704 | track->htile_offset = radeon_get_ib_value(p, idx); | ||
1705 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1706 | track->htile_bo = reloc->robj; | ||
1707 | track->db_dirty = true; | ||
1708 | break; | ||
1709 | case DB_HTILE_SURFACE: | ||
1710 | /* 8x8 only */ | ||
1711 | track->htile_surface = radeon_get_ib_value(p, idx); | ||
1712 | track->db_dirty = true; | ||
1713 | break; | ||
1619 | case CB_IMMED0_BASE: | 1714 | case CB_IMMED0_BASE: |
1620 | case CB_IMMED1_BASE: | 1715 | case CB_IMMED1_BASE: |
1621 | case CB_IMMED2_BASE: | 1716 | case CB_IMMED2_BASE: |
@@ -1628,7 +1723,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1628 | case CB_IMMED9_BASE: | 1723 | case CB_IMMED9_BASE: |
1629 | case CB_IMMED10_BASE: | 1724 | case CB_IMMED10_BASE: |
1630 | case CB_IMMED11_BASE: | 1725 | case CB_IMMED11_BASE: |
1631 | case DB_HTILE_DATA_BASE: | ||
1632 | case SQ_PGM_START_FS: | 1726 | case SQ_PGM_START_FS: |
1633 | case SQ_PGM_START_ES: | 1727 | case SQ_PGM_START_ES: |
1634 | case SQ_PGM_START_VS: | 1728 | case SQ_PGM_START_VS: |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index eb5708c7159d..b4eefc355f16 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -991,6 +991,14 @@ | |||
991 | #define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF) | 991 | #define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF) |
992 | #define C_028008_SLICE_MAX 0xFF001FFF | 992 | #define C_028008_SLICE_MAX 0xFF001FFF |
993 | #define DB_HTILE_DATA_BASE 0x28014 | 993 | #define DB_HTILE_DATA_BASE 0x28014 |
994 | #define DB_HTILE_SURFACE 0x28abc | ||
995 | #define S_028ABC_HTILE_WIDTH(x) (((x) & 0x1) << 0) | ||
996 | #define G_028ABC_HTILE_WIDTH(x) (((x) >> 0) & 0x1) | ||
997 | #define C_028ABC_HTILE_WIDTH 0xFFFFFFFE | ||
998 | #define S_028ABC_HTILE_HEIGHT(x) (((x) & 0x1) << 1) | ||
999 | #define G_028ABC_HTILE_HEIGHT(x) (((x) >> 1) & 0x1) | ||
1000 | #define C_028ABC_HTILE_HEIGHT 0xFFFFFFFD | ||
1001 | #define G_028ABC_LINEAR(x) (((x) >> 2) & 0x1) | ||
994 | #define DB_Z_INFO 0x28040 | 1002 | #define DB_Z_INFO 0x28040 |
995 | # define Z_ARRAY_MODE(x) ((x) << 4) | 1003 | # define Z_ARRAY_MODE(x) ((x) << 4) |
996 | # define DB_TILE_SPLIT(x) (((x) & 0x7) << 8) | 1004 | # define DB_TILE_SPLIT(x) (((x) & 0x7) << 8) |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0ec3f205f9c4..b8e12af304a9 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -78,6 +78,9 @@ struct r600_cs_track { | |||
78 | bool cb_dirty; | 78 | bool cb_dirty; |
79 | bool db_dirty; | 79 | bool db_dirty; |
80 | bool streamout_dirty; | 80 | bool streamout_dirty; |
81 | struct radeon_bo *htile_bo; | ||
82 | u64 htile_offset; | ||
83 | u32 htile_surface; | ||
81 | }; | 84 | }; |
82 | 85 | ||
83 | #define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } | 86 | #define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } |
@@ -321,6 +324,9 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
321 | track->db_depth_size_idx = 0; | 324 | track->db_depth_size_idx = 0; |
322 | track->db_depth_control = 0xFFFFFFFF; | 325 | track->db_depth_control = 0xFFFFFFFF; |
323 | track->db_dirty = true; | 326 | track->db_dirty = true; |
327 | track->htile_bo = NULL; | ||
328 | track->htile_offset = 0xFFFFFFFF; | ||
329 | track->htile_surface = 0; | ||
324 | 330 | ||
325 | for (i = 0; i < 4; i++) { | 331 | for (i = 0; i < 4; i++) { |
326 | track->vgt_strmout_size[i] = 0; | 332 | track->vgt_strmout_size[i] = 0; |
@@ -455,12 +461,256 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
455 | return 0; | 461 | return 0; |
456 | } | 462 | } |
457 | 463 | ||
464 | static int r600_cs_track_validate_db(struct radeon_cs_parser *p) | ||
465 | { | ||
466 | struct r600_cs_track *track = p->track; | ||
467 | u32 nviews, bpe, ntiles, size, slice_tile_max, tmp; | ||
468 | u32 height_align, pitch_align, depth_align; | ||
469 | u32 pitch = 8192; | ||
470 | u32 height = 8192; | ||
471 | u64 base_offset, base_align; | ||
472 | struct array_mode_checker array_check; | ||
473 | int array_mode; | ||
474 | volatile u32 *ib = p->ib->ptr; | ||
475 | |||
476 | |||
477 | if (track->db_bo == NULL) { | ||
478 | dev_warn(p->dev, "z/stencil with no depth buffer\n"); | ||
479 | return -EINVAL; | ||
480 | } | ||
481 | switch (G_028010_FORMAT(track->db_depth_info)) { | ||
482 | case V_028010_DEPTH_16: | ||
483 | bpe = 2; | ||
484 | break; | ||
485 | case V_028010_DEPTH_X8_24: | ||
486 | case V_028010_DEPTH_8_24: | ||
487 | case V_028010_DEPTH_X8_24_FLOAT: | ||
488 | case V_028010_DEPTH_8_24_FLOAT: | ||
489 | case V_028010_DEPTH_32_FLOAT: | ||
490 | bpe = 4; | ||
491 | break; | ||
492 | case V_028010_DEPTH_X24_8_32_FLOAT: | ||
493 | bpe = 8; | ||
494 | break; | ||
495 | default: | ||
496 | dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info)); | ||
497 | return -EINVAL; | ||
498 | } | ||
499 | if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) { | ||
500 | if (!track->db_depth_size_idx) { | ||
501 | dev_warn(p->dev, "z/stencil buffer size not set\n"); | ||
502 | return -EINVAL; | ||
503 | } | ||
504 | tmp = radeon_bo_size(track->db_bo) - track->db_offset; | ||
505 | tmp = (tmp / bpe) >> 6; | ||
506 | if (!tmp) { | ||
507 | dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n", | ||
508 | track->db_depth_size, bpe, track->db_offset, | ||
509 | radeon_bo_size(track->db_bo)); | ||
510 | return -EINVAL; | ||
511 | } | ||
512 | ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); | ||
513 | } else { | ||
514 | size = radeon_bo_size(track->db_bo); | ||
515 | /* pitch in pixels */ | ||
516 | pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; | ||
517 | slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | ||
518 | slice_tile_max *= 64; | ||
519 | height = slice_tile_max / pitch; | ||
520 | if (height > 8192) | ||
521 | height = 8192; | ||
522 | base_offset = track->db_bo_mc + track->db_offset; | ||
523 | array_mode = G_028010_ARRAY_MODE(track->db_depth_info); | ||
524 | array_check.array_mode = array_mode; | ||
525 | array_check.group_size = track->group_size; | ||
526 | array_check.nbanks = track->nbanks; | ||
527 | array_check.npipes = track->npipes; | ||
528 | array_check.nsamples = track->nsamples; | ||
529 | array_check.blocksize = bpe; | ||
530 | if (r600_get_array_mode_alignment(&array_check, | ||
531 | &pitch_align, &height_align, &depth_align, &base_align)) { | ||
532 | dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, | ||
533 | G_028010_ARRAY_MODE(track->db_depth_info), | ||
534 | track->db_depth_info); | ||
535 | return -EINVAL; | ||
536 | } | ||
537 | switch (array_mode) { | ||
538 | case V_028010_ARRAY_1D_TILED_THIN1: | ||
539 | /* don't break userspace */ | ||
540 | height &= ~0x7; | ||
541 | break; | ||
542 | case V_028010_ARRAY_2D_TILED_THIN1: | ||
543 | break; | ||
544 | default: | ||
545 | dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, | ||
546 | G_028010_ARRAY_MODE(track->db_depth_info), | ||
547 | track->db_depth_info); | ||
548 | return -EINVAL; | ||
549 | } | ||
550 | |||
551 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
552 | dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n", | ||
553 | __func__, __LINE__, pitch, pitch_align, array_mode); | ||
554 | return -EINVAL; | ||
555 | } | ||
556 | if (!IS_ALIGNED(height, height_align)) { | ||
557 | dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n", | ||
558 | __func__, __LINE__, height, height_align, array_mode); | ||
559 | return -EINVAL; | ||
560 | } | ||
561 | if (!IS_ALIGNED(base_offset, base_align)) { | ||
562 | dev_warn(p->dev, "%s offset 0x%llx, 0x%llx, %d not aligned\n", __func__, | ||
563 | base_offset, base_align, array_mode); | ||
564 | return -EINVAL; | ||
565 | } | ||
566 | |||
567 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | ||
568 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | ||
569 | tmp = ntiles * bpe * 64 * nviews; | ||
570 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { | ||
571 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", | ||
572 | array_mode, | ||
573 | track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, | ||
574 | radeon_bo_size(track->db_bo)); | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | /* hyperz */ | ||
580 | if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) { | ||
581 | unsigned long size; | ||
582 | unsigned nbx, nby; | ||
583 | |||
584 | if (track->htile_bo == NULL) { | ||
585 | dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n", | ||
586 | __func__, __LINE__, track->db_depth_info); | ||
587 | return -EINVAL; | ||
588 | } | ||
589 | if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) { | ||
590 | dev_warn(p->dev, "%s:%d htile can't be enabled with bogus db_depth_size 0x%08x\n", | ||
591 | __func__, __LINE__, track->db_depth_size); | ||
592 | return -EINVAL; | ||
593 | } | ||
594 | |||
595 | nbx = pitch; | ||
596 | nby = height; | ||
597 | if (G_028D24_LINEAR(track->htile_surface)) { | ||
598 | /* nbx must be 16 htiles aligned == 16 * 8 pixel aligned */ | ||
599 | nbx = round_up(nbx, 16 * 8); | ||
600 | /* nby is npipes htiles aligned == npipes * 8 pixel aligned */ | ||
601 | nby = round_up(nby, track->npipes * 8); | ||
602 | } else { | ||
603 | /* htile widht & nby (8 or 4) make 2 bits number */ | ||
604 | tmp = track->htile_surface & 3; | ||
605 | /* align is htile align * 8, htile align vary according to | ||
606 | * number of pipe and tile width and nby | ||
607 | */ | ||
608 | switch (track->npipes) { | ||
609 | case 8: | ||
610 | switch (tmp) { | ||
611 | case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
612 | nbx = round_up(nbx, 64 * 8); | ||
613 | nby = round_up(nby, 64 * 8); | ||
614 | break; | ||
615 | case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ | ||
616 | case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ | ||
617 | nbx = round_up(nbx, 64 * 8); | ||
618 | nby = round_up(nby, 32 * 8); | ||
619 | break; | ||
620 | case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ | ||
621 | nbx = round_up(nbx, 32 * 8); | ||
622 | nby = round_up(nby, 32 * 8); | ||
623 | break; | ||
624 | default: | ||
625 | return -EINVAL; | ||
626 | } | ||
627 | break; | ||
628 | case 4: | ||
629 | switch (tmp) { | ||
630 | case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
631 | nbx = round_up(nbx, 64 * 8); | ||
632 | nby = round_up(nby, 32 * 8); | ||
633 | break; | ||
634 | case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ | ||
635 | case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ | ||
636 | nbx = round_up(nbx, 32 * 8); | ||
637 | nby = round_up(nby, 32 * 8); | ||
638 | break; | ||
639 | case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ | ||
640 | nbx = round_up(nbx, 32 * 8); | ||
641 | nby = round_up(nby, 16 * 8); | ||
642 | break; | ||
643 | default: | ||
644 | return -EINVAL; | ||
645 | } | ||
646 | break; | ||
647 | case 2: | ||
648 | switch (tmp) { | ||
649 | case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
650 | nbx = round_up(nbx, 32 * 8); | ||
651 | nby = round_up(nby, 32 * 8); | ||
652 | break; | ||
653 | case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ | ||
654 | case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ | ||
655 | nbx = round_up(nbx, 32 * 8); | ||
656 | nby = round_up(nby, 16 * 8); | ||
657 | break; | ||
658 | case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ | ||
659 | nbx = round_up(nbx, 16 * 8); | ||
660 | nby = round_up(nby, 16 * 8); | ||
661 | break; | ||
662 | default: | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | break; | ||
666 | case 1: | ||
667 | switch (tmp) { | ||
668 | case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
669 | nbx = round_up(nbx, 32 * 8); | ||
670 | nby = round_up(nby, 16 * 8); | ||
671 | break; | ||
672 | case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ | ||
673 | case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ | ||
674 | nbx = round_up(nbx, 16 * 8); | ||
675 | nby = round_up(nby, 16 * 8); | ||
676 | break; | ||
677 | case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ | ||
678 | nbx = round_up(nbx, 16 * 8); | ||
679 | nby = round_up(nby, 8 * 8); | ||
680 | break; | ||
681 | default: | ||
682 | return -EINVAL; | ||
683 | } | ||
684 | break; | ||
685 | default: | ||
686 | dev_warn(p->dev, "%s:%d invalid num pipes %d\n", | ||
687 | __func__, __LINE__, track->npipes); | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | } | ||
691 | /* compute number of htile */ | ||
692 | nbx = G_028D24_HTILE_WIDTH(track->htile_surface) ? nbx / 8 : nbx / 4; | ||
693 | nby = G_028D24_HTILE_HEIGHT(track->htile_surface) ? nby / 8 : nby / 4; | ||
694 | size = nbx * nby * 4; | ||
695 | size += track->htile_offset; | ||
696 | |||
697 | if (size > radeon_bo_size(track->htile_bo)) { | ||
698 | dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n", | ||
699 | __func__, __LINE__, radeon_bo_size(track->htile_bo), | ||
700 | size, nbx, nby); | ||
701 | return -EINVAL; | ||
702 | } | ||
703 | } | ||
704 | |||
705 | track->db_dirty = false; | ||
706 | return 0; | ||
707 | } | ||
708 | |||
458 | static int r600_cs_track_check(struct radeon_cs_parser *p) | 709 | static int r600_cs_track_check(struct radeon_cs_parser *p) |
459 | { | 710 | { |
460 | struct r600_cs_track *track = p->track; | 711 | struct r600_cs_track *track = p->track; |
461 | u32 tmp; | 712 | u32 tmp; |
462 | int r, i; | 713 | int r, i; |
463 | volatile u32 *ib = p->ib->ptr; | ||
464 | 714 | ||
465 | /* on legacy kernel we don't perform advanced check */ | 715 | /* on legacy kernel we don't perform advanced check */ |
466 | if (p->rdev == NULL) | 716 | if (p->rdev == NULL) |
@@ -513,124 +763,14 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
513 | track->cb_dirty = false; | 763 | track->cb_dirty = false; |
514 | } | 764 | } |
515 | 765 | ||
516 | if (track->db_dirty) { | 766 | /* Check depth buffer */ |
517 | /* Check depth buffer */ | 767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || |
518 | if (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 768 | G_028800_Z_ENABLE(track->db_depth_control))) { |
519 | G_028800_Z_ENABLE(track->db_depth_control)) { | 769 | r = r600_cs_track_validate_db(p); |
520 | u32 nviews, bpe, ntiles, size, slice_tile_max; | 770 | if (r) |
521 | u32 height, height_align, pitch, pitch_align, depth_align; | 771 | return r; |
522 | u64 base_offset, base_align; | ||
523 | struct array_mode_checker array_check; | ||
524 | int array_mode; | ||
525 | |||
526 | if (track->db_bo == NULL) { | ||
527 | dev_warn(p->dev, "z/stencil with no depth buffer\n"); | ||
528 | return -EINVAL; | ||
529 | } | ||
530 | if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) { | ||
531 | dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n"); | ||
532 | return -EINVAL; | ||
533 | } | ||
534 | switch (G_028010_FORMAT(track->db_depth_info)) { | ||
535 | case V_028010_DEPTH_16: | ||
536 | bpe = 2; | ||
537 | break; | ||
538 | case V_028010_DEPTH_X8_24: | ||
539 | case V_028010_DEPTH_8_24: | ||
540 | case V_028010_DEPTH_X8_24_FLOAT: | ||
541 | case V_028010_DEPTH_8_24_FLOAT: | ||
542 | case V_028010_DEPTH_32_FLOAT: | ||
543 | bpe = 4; | ||
544 | break; | ||
545 | case V_028010_DEPTH_X24_8_32_FLOAT: | ||
546 | bpe = 8; | ||
547 | break; | ||
548 | default: | ||
549 | dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info)); | ||
550 | return -EINVAL; | ||
551 | } | ||
552 | if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) { | ||
553 | if (!track->db_depth_size_idx) { | ||
554 | dev_warn(p->dev, "z/stencil buffer size not set\n"); | ||
555 | return -EINVAL; | ||
556 | } | ||
557 | tmp = radeon_bo_size(track->db_bo) - track->db_offset; | ||
558 | tmp = (tmp / bpe) >> 6; | ||
559 | if (!tmp) { | ||
560 | dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n", | ||
561 | track->db_depth_size, bpe, track->db_offset, | ||
562 | radeon_bo_size(track->db_bo)); | ||
563 | return -EINVAL; | ||
564 | } | ||
565 | ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); | ||
566 | } else { | ||
567 | size = radeon_bo_size(track->db_bo); | ||
568 | /* pitch in pixels */ | ||
569 | pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; | ||
570 | slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | ||
571 | slice_tile_max *= 64; | ||
572 | height = slice_tile_max / pitch; | ||
573 | if (height > 8192) | ||
574 | height = 8192; | ||
575 | base_offset = track->db_bo_mc + track->db_offset; | ||
576 | array_mode = G_028010_ARRAY_MODE(track->db_depth_info); | ||
577 | array_check.array_mode = array_mode; | ||
578 | array_check.group_size = track->group_size; | ||
579 | array_check.nbanks = track->nbanks; | ||
580 | array_check.npipes = track->npipes; | ||
581 | array_check.nsamples = track->nsamples; | ||
582 | array_check.blocksize = bpe; | ||
583 | if (r600_get_array_mode_alignment(&array_check, | ||
584 | &pitch_align, &height_align, &depth_align, &base_align)) { | ||
585 | dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, | ||
586 | G_028010_ARRAY_MODE(track->db_depth_info), | ||
587 | track->db_depth_info); | ||
588 | return -EINVAL; | ||
589 | } | ||
590 | switch (array_mode) { | ||
591 | case V_028010_ARRAY_1D_TILED_THIN1: | ||
592 | /* don't break userspace */ | ||
593 | height &= ~0x7; | ||
594 | break; | ||
595 | case V_028010_ARRAY_2D_TILED_THIN1: | ||
596 | break; | ||
597 | default: | ||
598 | dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, | ||
599 | G_028010_ARRAY_MODE(track->db_depth_info), | ||
600 | track->db_depth_info); | ||
601 | return -EINVAL; | ||
602 | } | ||
603 | |||
604 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
605 | dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n", | ||
606 | __func__, __LINE__, pitch, pitch_align, array_mode); | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | if (!IS_ALIGNED(height, height_align)) { | ||
610 | dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n", | ||
611 | __func__, __LINE__, height, height_align, array_mode); | ||
612 | return -EINVAL; | ||
613 | } | ||
614 | if (!IS_ALIGNED(base_offset, base_align)) { | ||
615 | dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i, | ||
616 | base_offset, base_align, array_mode); | ||
617 | return -EINVAL; | ||
618 | } | ||
619 | |||
620 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | ||
621 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | ||
622 | tmp = ntiles * bpe * 64 * nviews; | ||
623 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { | ||
624 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", | ||
625 | array_mode, | ||
626 | track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, | ||
627 | radeon_bo_size(track->db_bo)); | ||
628 | return -EINVAL; | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | track->db_dirty = false; | ||
633 | } | 772 | } |
773 | |||
634 | return 0; | 774 | return 0; |
635 | } | 775 | } |
636 | 776 | ||
@@ -1244,6 +1384,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1244 | track->db_dirty = true; | 1384 | track->db_dirty = true; |
1245 | break; | 1385 | break; |
1246 | case DB_HTILE_DATA_BASE: | 1386 | case DB_HTILE_DATA_BASE: |
1387 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1388 | if (r) { | ||
1389 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
1390 | "0x%04X\n", reg); | ||
1391 | return -EINVAL; | ||
1392 | } | ||
1393 | track->htile_offset = radeon_get_ib_value(p, idx) << 8; | ||
1394 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1395 | track->htile_bo = reloc->robj; | ||
1396 | track->db_dirty = true; | ||
1397 | break; | ||
1398 | case DB_HTILE_SURFACE: | ||
1399 | track->htile_surface = radeon_get_ib_value(p, idx); | ||
1400 | track->db_dirty = true; | ||
1401 | break; | ||
1247 | case SQ_PGM_START_FS: | 1402 | case SQ_PGM_START_FS: |
1248 | case SQ_PGM_START_ES: | 1403 | case SQ_PGM_START_ES: |
1249 | case SQ_PGM_START_VS: | 1404 | case SQ_PGM_START_VS: |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 3568a2e345fa..59f9c993cc31 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -195,6 +195,14 @@ | |||
195 | #define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) | 195 | #define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) |
196 | #define DB_DEPTH_BASE 0x2800C | 196 | #define DB_DEPTH_BASE 0x2800C |
197 | #define DB_HTILE_DATA_BASE 0x28014 | 197 | #define DB_HTILE_DATA_BASE 0x28014 |
198 | #define DB_HTILE_SURFACE 0x28D24 | ||
199 | #define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0) | ||
200 | #define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1) | ||
201 | #define C_028D24_HTILE_WIDTH 0xFFFFFFFE | ||
202 | #define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1) | ||
203 | #define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1) | ||
204 | #define C_028D24_HTILE_HEIGHT 0xFFFFFFFD | ||
205 | #define G_028D24_LINEAR(x) (((x) >> 2) & 0x1) | ||
198 | #define DB_WATERMARKS 0x9838 | 206 | #define DB_WATERMARKS 0x9838 |
199 | #define DEPTH_FREE(x) ((x) << 0) | 207 | #define DEPTH_FREE(x) ((x) << 0) |
200 | #define DEPTH_FLUSH(x) ((x) << 5) | 208 | #define DEPTH_FLUSH(x) ((x) << 5) |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman index aea63c415852..0f656b111c15 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/cayman +++ b/drivers/gpu/drm/radeon/reg_srcs/cayman | |||
@@ -509,7 +509,6 @@ cayman 0x9400 | |||
509 | 0x00028AA8 IA_MULTI_VGT_PARAM | 509 | 0x00028AA8 IA_MULTI_VGT_PARAM |
510 | 0x00028AB4 VGT_REUSE_OFF | 510 | 0x00028AB4 VGT_REUSE_OFF |
511 | 0x00028AB8 VGT_VTX_CNT_EN | 511 | 0x00028AB8 VGT_VTX_CNT_EN |
512 | 0x00028ABC DB_HTILE_SURFACE | ||
513 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 | 512 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 |
514 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 | 513 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 |
515 | 0x00028AC8 DB_PRELOAD_CONTROL | 514 | 0x00028AC8 DB_PRELOAD_CONTROL |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen index 77c37202376f..b912a37689bf 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/evergreen +++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen | |||
@@ -519,7 +519,6 @@ evergreen 0x9400 | |||
519 | 0x00028AA4 VGT_INSTANCE_STEP_RATE_1 | 519 | 0x00028AA4 VGT_INSTANCE_STEP_RATE_1 |
520 | 0x00028AB4 VGT_REUSE_OFF | 520 | 0x00028AB4 VGT_REUSE_OFF |
521 | 0x00028AB8 VGT_VTX_CNT_EN | 521 | 0x00028AB8 VGT_VTX_CNT_EN |
522 | 0x00028ABC DB_HTILE_SURFACE | ||
523 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 | 522 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 |
524 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 | 523 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 |
525 | 0x00028AC8 DB_PRELOAD_CONTROL | 524 | 0x00028AC8 DB_PRELOAD_CONTROL |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 626c24ea0b56..5e659b034d9a 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -713,7 +713,6 @@ r600 0x9400 | |||
713 | 0x0000A710 TD_VS_SAMPLER17_BORDER_RED | 713 | 0x0000A710 TD_VS_SAMPLER17_BORDER_RED |
714 | 0x00009508 TA_CNTL_AUX | 714 | 0x00009508 TA_CNTL_AUX |
715 | 0x0002802C DB_DEPTH_CLEAR | 715 | 0x0002802C DB_DEPTH_CLEAR |
716 | 0x00028D24 DB_HTILE_SURFACE | ||
717 | 0x00028D34 DB_PREFETCH_LIMIT | 716 | 0x00028D34 DB_PREFETCH_LIMIT |
718 | 0x00028D30 DB_PRELOAD_CONTROL | 717 | 0x00028D30 DB_PRELOAD_CONTROL |
719 | 0x00028D0C DB_RENDER_CONTROL | 718 | 0x00028D0C DB_RENDER_CONTROL |