diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 195 |
1 files changed, 150 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 7fdfa8ea7570..cd4590aae154 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 { | |||
38 | u32 group_size; | 38 | u32 group_size; |
39 | u32 nbanks; | 39 | u32 nbanks; |
40 | u32 npipes; | 40 | u32 npipes; |
41 | u32 row_size; | ||
41 | /* value we track */ | 42 | /* value we track */ |
42 | u32 nsamples; | 43 | u32 nsamples; |
43 | u32 cb_color_base_last[12]; | 44 | u32 cb_color_base_last[12]; |
@@ -77,6 +78,44 @@ struct evergreen_cs_track { | |||
77 | struct radeon_bo *db_s_write_bo; | 78 | struct radeon_bo *db_s_write_bo; |
78 | }; | 79 | }; |
79 | 80 | ||
81 | static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) | ||
82 | { | ||
83 | if (tiling_flags & RADEON_TILING_MACRO) | ||
84 | return ARRAY_2D_TILED_THIN1; | ||
85 | else if (tiling_flags & RADEON_TILING_MICRO) | ||
86 | return ARRAY_1D_TILED_THIN1; | ||
87 | else | ||
88 | return ARRAY_LINEAR_GENERAL; | ||
89 | } | ||
90 | |||
91 | static u32 evergreen_cs_get_num_banks(u32 nbanks) | ||
92 | { | ||
93 | switch (nbanks) { | ||
94 | case 2: | ||
95 | return ADDR_SURF_2_BANK; | ||
96 | case 4: | ||
97 | return ADDR_SURF_4_BANK; | ||
98 | case 8: | ||
99 | default: | ||
100 | return ADDR_SURF_8_BANK; | ||
101 | case 16: | ||
102 | return ADDR_SURF_16_BANK; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | static u32 evergreen_cs_get_tile_split(u32 row_size) | ||
107 | { | ||
108 | switch (row_size) { | ||
109 | case 1: | ||
110 | default: | ||
111 | return ADDR_SURF_TILE_SPLIT_1KB; | ||
112 | case 2: | ||
113 | return ADDR_SURF_TILE_SPLIT_2KB; | ||
114 | case 4: | ||
115 | return ADDR_SURF_TILE_SPLIT_4KB; | ||
116 | } | ||
117 | } | ||
118 | |||
80 | static void evergreen_cs_track_init(struct evergreen_cs_track *track) | 119 | static void evergreen_cs_track_init(struct evergreen_cs_track *track) |
81 | { | 120 | { |
82 | int i; | 121 | int i; |
@@ -480,21 +519,22 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
480 | } | 519 | } |
481 | break; | 520 | break; |
482 | case DB_Z_INFO: | 521 | case DB_Z_INFO: |
483 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
484 | if (r) { | ||
485 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
486 | "0x%04X\n", reg); | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | track->db_z_info = radeon_get_ib_value(p, idx); | 522 | track->db_z_info = radeon_get_ib_value(p, idx); |
490 | ib[idx] &= ~Z_ARRAY_MODE(0xf); | 523 | if (!p->keep_tiling_flags) { |
491 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); | 524 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
492 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 525 | if (r) { |
493 | ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 526 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
494 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 527 | "0x%04X\n", reg); |
495 | } else { | 528 | return -EINVAL; |
496 | ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 529 | } |
497 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 530 | ib[idx] &= ~Z_ARRAY_MODE(0xf); |
531 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); | ||
532 | ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
533 | track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
534 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
535 | ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | ||
536 | ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | ||
537 | } | ||
498 | } | 538 | } |
499 | break; | 539 | break; |
500 | case DB_STENCIL_INFO: | 540 | case DB_STENCIL_INFO: |
@@ -607,40 +647,34 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
607 | case CB_COLOR5_INFO: | 647 | case CB_COLOR5_INFO: |
608 | case CB_COLOR6_INFO: | 648 | case CB_COLOR6_INFO: |
609 | case CB_COLOR7_INFO: | 649 | case CB_COLOR7_INFO: |
610 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
611 | if (r) { | ||
612 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
613 | "0x%04X\n", reg); | ||
614 | return -EINVAL; | ||
615 | } | ||
616 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; | 650 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; |
617 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 651 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
618 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 652 | if (!p->keep_tiling_flags) { |
619 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 653 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
620 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 654 | if (r) { |
621 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | 655 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
622 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 656 | "0x%04X\n", reg); |
623 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 657 | return -EINVAL; |
658 | } | ||
659 | ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
660 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
624 | } | 661 | } |
625 | break; | 662 | break; |
626 | case CB_COLOR8_INFO: | 663 | case CB_COLOR8_INFO: |
627 | case CB_COLOR9_INFO: | 664 | case CB_COLOR9_INFO: |
628 | case CB_COLOR10_INFO: | 665 | case CB_COLOR10_INFO: |
629 | case CB_COLOR11_INFO: | 666 | case CB_COLOR11_INFO: |
630 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
631 | if (r) { | ||
632 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
633 | "0x%04X\n", reg); | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; | 667 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; |
637 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 668 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
638 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 669 | if (!p->keep_tiling_flags) { |
639 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 670 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
640 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 671 | if (r) { |
641 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | 672 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
642 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 673 | "0x%04X\n", reg); |
643 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 674 | return -EINVAL; |
675 | } | ||
676 | ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
677 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
644 | } | 678 | } |
645 | break; | 679 | break; |
646 | case CB_COLOR0_PITCH: | 680 | case CB_COLOR0_PITCH: |
@@ -695,6 +729,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
695 | case CB_COLOR9_ATTRIB: | 729 | case CB_COLOR9_ATTRIB: |
696 | case CB_COLOR10_ATTRIB: | 730 | case CB_COLOR10_ATTRIB: |
697 | case CB_COLOR11_ATTRIB: | 731 | case CB_COLOR11_ATTRIB: |
732 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
733 | if (r) { | ||
734 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
735 | "0x%04X\n", reg); | ||
736 | return -EINVAL; | ||
737 | } | ||
738 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
739 | ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | ||
740 | ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | ||
741 | } | ||
698 | break; | 742 | break; |
699 | case CB_COLOR0_DIM: | 743 | case CB_COLOR0_DIM: |
700 | case CB_COLOR1_DIM: | 744 | case CB_COLOR1_DIM: |
@@ -1311,10 +1355,16 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
1311 | return -EINVAL; | 1355 | return -EINVAL; |
1312 | } | 1356 | } |
1313 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1357 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1314 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 1358 | if (!p->keep_tiling_flags) { |
1315 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 1359 | ib[idx+1+(i*8)+1] |= |
1316 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1360 | TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
1317 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 1361 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { |
1362 | ib[idx+1+(i*8)+6] |= | ||
1363 | TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | ||
1364 | ib[idx+1+(i*8)+7] |= | ||
1365 | TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | ||
1366 | } | ||
1367 | } | ||
1318 | texture = reloc->robj; | 1368 | texture = reloc->robj; |
1319 | /* tex mip base */ | 1369 | /* tex mip base */ |
1320 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1370 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
@@ -1414,6 +1464,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
1414 | { | 1464 | { |
1415 | struct radeon_cs_packet pkt; | 1465 | struct radeon_cs_packet pkt; |
1416 | struct evergreen_cs_track *track; | 1466 | struct evergreen_cs_track *track; |
1467 | u32 tmp; | ||
1417 | int r; | 1468 | int r; |
1418 | 1469 | ||
1419 | if (p->track == NULL) { | 1470 | if (p->track == NULL) { |
@@ -1422,9 +1473,63 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
1422 | if (track == NULL) | 1473 | if (track == NULL) |
1423 | return -ENOMEM; | 1474 | return -ENOMEM; |
1424 | evergreen_cs_track_init(track); | 1475 | evergreen_cs_track_init(track); |
1425 | track->npipes = p->rdev->config.evergreen.tiling_npipes; | 1476 | if (p->rdev->family >= CHIP_CAYMAN) |
1426 | track->nbanks = p->rdev->config.evergreen.tiling_nbanks; | 1477 | tmp = p->rdev->config.cayman.tile_config; |
1427 | track->group_size = p->rdev->config.evergreen.tiling_group_size; | 1478 | else |
1479 | tmp = p->rdev->config.evergreen.tile_config; | ||
1480 | |||
1481 | switch (tmp & 0xf) { | ||
1482 | case 0: | ||
1483 | track->npipes = 1; | ||
1484 | break; | ||
1485 | case 1: | ||
1486 | default: | ||
1487 | track->npipes = 2; | ||
1488 | break; | ||
1489 | case 2: | ||
1490 | track->npipes = 4; | ||
1491 | break; | ||
1492 | case 3: | ||
1493 | track->npipes = 8; | ||
1494 | break; | ||
1495 | } | ||
1496 | |||
1497 | switch ((tmp & 0xf0) >> 4) { | ||
1498 | case 0: | ||
1499 | track->nbanks = 4; | ||
1500 | break; | ||
1501 | case 1: | ||
1502 | default: | ||
1503 | track->nbanks = 8; | ||
1504 | break; | ||
1505 | case 2: | ||
1506 | track->nbanks = 16; | ||
1507 | break; | ||
1508 | } | ||
1509 | |||
1510 | switch ((tmp & 0xf00) >> 8) { | ||
1511 | case 0: | ||
1512 | track->group_size = 256; | ||
1513 | break; | ||
1514 | case 1: | ||
1515 | default: | ||
1516 | track->group_size = 512; | ||
1517 | break; | ||
1518 | } | ||
1519 | |||
1520 | switch ((tmp & 0xf000) >> 12) { | ||
1521 | case 0: | ||
1522 | track->row_size = 1; | ||
1523 | break; | ||
1524 | case 1: | ||
1525 | default: | ||
1526 | track->row_size = 2; | ||
1527 | break; | ||
1528 | case 2: | ||
1529 | track->row_size = 4; | ||
1530 | break; | ||
1531 | } | ||
1532 | |||
1428 | p->track = track; | 1533 | p->track = track; |
1429 | } | 1534 | } |
1430 | do { | 1535 | do { |