diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 105 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r300.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r500_reg.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv515.c | 23 |
4 files changed, 137 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index a3db56bb013d..154648a2c027 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -752,6 +752,102 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p, | |||
752 | } | 752 | } |
753 | 753 | ||
754 | /** | 754 | /** |
755 | * r100_cs_packet_next_vline() - parse userspace VLINE packet | ||
756 | * @parser: parser structure holding parsing context. | ||
757 | * | ||
758 | * Userspace sends a special sequence for VLINE waits. | ||
759 | * PACKET0 - VLINE_START_END + value | ||
760 | * PACKET0 - WAIT_UNTIL +_value | ||
761 | * RELOC (P3) - crtc_id in reloc. | ||
762 | * | ||
763 | * This function parses this and relocates the VLINE START END | ||
764 | * and WAIT UNTIL packets to the correct crtc. | ||
765 | * It also detects a switched off crtc and nulls out the | ||
766 | * wait in that case. | ||
767 | */ | ||
768 | int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | ||
769 | { | ||
770 | struct radeon_cs_chunk *ib_chunk; | ||
771 | struct drm_mode_object *obj; | ||
772 | struct drm_crtc *crtc; | ||
773 | struct radeon_crtc *radeon_crtc; | ||
774 | struct radeon_cs_packet p3reloc, waitreloc; | ||
775 | int crtc_id; | ||
776 | int r; | ||
777 | uint32_t header, h_idx, reg; | ||
778 | |||
779 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
780 | |||
781 | /* parse the wait until */ | ||
782 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); | ||
783 | if (r) | ||
784 | return r; | ||
785 | |||
786 | /* check its a wait until and only 1 count */ | ||
787 | if (waitreloc.reg != RADEON_WAIT_UNTIL || | ||
788 | waitreloc.count != 0) { | ||
789 | DRM_ERROR("vline wait had illegal wait until segment\n"); | ||
790 | r = -EINVAL; | ||
791 | return r; | ||
792 | } | ||
793 | |||
794 | if (ib_chunk->kdata[waitreloc.idx + 1] != RADEON_WAIT_CRTC_VLINE) { | ||
795 | DRM_ERROR("vline wait had illegal wait until\n"); | ||
796 | r = -EINVAL; | ||
797 | return r; | ||
798 | } | ||
799 | |||
800 | /* jump over the NOP */ | ||
801 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); | ||
802 | if (r) | ||
803 | return r; | ||
804 | |||
805 | h_idx = p->idx - 2; | ||
806 | p->idx += waitreloc.count; | ||
807 | p->idx += p3reloc.count; | ||
808 | |||
809 | header = ib_chunk->kdata[h_idx]; | ||
810 | crtc_id = ib_chunk->kdata[h_idx + 5]; | ||
811 | reg = ib_chunk->kdata[h_idx] >> 2; | ||
812 | mutex_lock(&p->rdev->ddev->mode_config.mutex); | ||
813 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); | ||
814 | if (!obj) { | ||
815 | DRM_ERROR("cannot find crtc %d\n", crtc_id); | ||
816 | r = -EINVAL; | ||
817 | goto out; | ||
818 | } | ||
819 | crtc = obj_to_crtc(obj); | ||
820 | radeon_crtc = to_radeon_crtc(crtc); | ||
821 | crtc_id = radeon_crtc->crtc_id; | ||
822 | |||
823 | if (!crtc->enabled) { | ||
824 | /* if the CRTC isn't enabled - we need to nop out the wait until */ | ||
825 | ib_chunk->kdata[h_idx + 2] = PACKET2(0); | ||
826 | ib_chunk->kdata[h_idx + 3] = PACKET2(0); | ||
827 | } else if (crtc_id == 1) { | ||
828 | switch (reg) { | ||
829 | case AVIVO_D1MODE_VLINE_START_END: | ||
830 | header &= R300_CP_PACKET0_REG_MASK; | ||
831 | header |= AVIVO_D2MODE_VLINE_START_END >> 2; | ||
832 | break; | ||
833 | case RADEON_CRTC_GUI_TRIG_VLINE: | ||
834 | header &= R300_CP_PACKET0_REG_MASK; | ||
835 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; | ||
836 | break; | ||
837 | default: | ||
838 | DRM_ERROR("unknown crtc reloc\n"); | ||
839 | r = -EINVAL; | ||
840 | goto out; | ||
841 | } | ||
842 | ib_chunk->kdata[h_idx] = header; | ||
843 | ib_chunk->kdata[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; | ||
844 | } | ||
845 | out: | ||
846 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); | ||
847 | return r; | ||
848 | } | ||
849 | |||
850 | /** | ||
755 | * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 | 851 | * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 |
756 | * @parser: parser structure holding parsing context. | 852 | * @parser: parser structure holding parsing context. |
757 | * @data: pointer to relocation data | 853 | * @data: pointer to relocation data |
@@ -824,6 +920,15 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
824 | } | 920 | } |
825 | for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { | 921 | for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { |
826 | switch (reg) { | 922 | switch (reg) { |
923 | case RADEON_CRTC_GUI_TRIG_VLINE: | ||
924 | r = r100_cs_packet_parse_vline(p); | ||
925 | if (r) { | ||
926 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
927 | idx, reg); | ||
928 | r100_cs_dump_packet(p, pkt); | ||
929 | return r; | ||
930 | } | ||
931 | break; | ||
827 | /* FIXME: only allow PACKET3 blit? easier to check for out of | 932 | /* FIXME: only allow PACKET3 blit? easier to check for out of |
828 | * range access */ | 933 | * range access */ |
829 | case RADEON_DST_PITCH_OFFSET: | 934 | case RADEON_DST_PITCH_OFFSET: |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index cd9ea98e9c6f..656d9238bb06 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -44,6 +44,7 @@ int r100_gui_wait_for_idle(struct radeon_device *rdev); | |||
44 | int r100_cs_packet_parse(struct radeon_cs_parser *p, | 44 | int r100_cs_packet_parse(struct radeon_cs_parser *p, |
45 | struct radeon_cs_packet *pkt, | 45 | struct radeon_cs_packet *pkt, |
46 | unsigned idx); | 46 | unsigned idx); |
47 | int r100_cs_packet_parse_vline(struct radeon_cs_parser *p); | ||
47 | int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, | 48 | int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, |
48 | struct radeon_cs_reloc **cs_reloc); | 49 | struct radeon_cs_reloc **cs_reloc); |
49 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, | 50 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
@@ -972,7 +973,7 @@ static inline void r300_cs_track_clear(struct r300_cs_track *track) | |||
972 | 973 | ||
973 | static const unsigned r300_reg_safe_bm[159] = { | 974 | static const unsigned r300_reg_safe_bm[159] = { |
974 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 975 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
975 | 0xFFFFFFBF, 0xFFFFFFFF, 0xFFFFFFBF, 0xFFFFFFFF, | 976 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
976 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 977 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
977 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 978 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
978 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 979 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
@@ -1029,6 +1030,16 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
1029 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | 1030 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
1030 | track = (struct r300_cs_track*)p->track; | 1031 | track = (struct r300_cs_track*)p->track; |
1031 | switch(reg) { | 1032 | switch(reg) { |
1033 | case AVIVO_D1MODE_VLINE_START_END: | ||
1034 | case RADEON_CRTC_GUI_TRIG_VLINE: | ||
1035 | r = r100_cs_packet_parse_vline(p); | ||
1036 | if (r) { | ||
1037 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
1038 | idx, reg); | ||
1039 | r100_cs_dump_packet(p, pkt); | ||
1040 | return r; | ||
1041 | } | ||
1042 | break; | ||
1032 | case RADEON_DST_PITCH_OFFSET: | 1043 | case RADEON_DST_PITCH_OFFSET: |
1033 | case RADEON_SRC_PITCH_OFFSET: | 1044 | case RADEON_SRC_PITCH_OFFSET: |
1034 | r = r100_cs_packet_next_reloc(p, &reloc); | 1045 | r = r100_cs_packet_next_reloc(p, &reloc); |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 9070a1c2ce23..036691b38cb7 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -445,6 +445,7 @@ | |||
445 | #define AVIVO_D1MODE_DATA_FORMAT 0x6528 | 445 | #define AVIVO_D1MODE_DATA_FORMAT 0x6528 |
446 | # define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) | 446 | # define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) |
447 | #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C | 447 | #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C |
448 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 | ||
448 | #define AVIVO_D1MODE_VIEWPORT_START 0x6580 | 449 | #define AVIVO_D1MODE_VIEWPORT_START 0x6580 |
449 | #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 | 450 | #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 |
450 | #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 | 451 | #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 |
@@ -496,6 +497,7 @@ | |||
496 | #define AVIVO_D2CUR_SIZE 0x6c10 | 497 | #define AVIVO_D2CUR_SIZE 0x6c10 |
497 | #define AVIVO_D2CUR_POSITION 0x6c14 | 498 | #define AVIVO_D2CUR_POSITION 0x6c14 |
498 | 499 | ||
500 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 | ||
499 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 | 501 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 |
500 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 | 502 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 |
501 | #define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88 | 503 | #define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88 |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index ffea37b1b3e2..d1384d3991ad 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -509,9 +509,9 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
509 | /* | 509 | /* |
510 | * Asic initialization | 510 | * Asic initialization |
511 | */ | 511 | */ |
512 | static const unsigned r500_reg_safe_bm[159] = { | 512 | static const unsigned r500_reg_safe_bm[219] = { |
513 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
513 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 514 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
514 | 0xFFFFFFBF, 0xFFFFFFFF, 0xFFFFFFBF, 0xFFFFFFFF, | ||
515 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 515 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
516 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 516 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
517 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 517 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
@@ -549,11 +549,24 @@ static const unsigned r500_reg_safe_bm[159] = { | |||
549 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 549 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
550 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF, | 550 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF, |
551 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 551 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
552 | 0x0003FC01, 0x3FFFFCF8, 0xFE800B19, | 552 | 0x0003FC01, 0x3FFFFCF8, 0xFE800B19, 0xFFFFFFFF, |
553 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
554 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
555 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
556 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
557 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
558 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
559 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
560 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
561 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
562 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
563 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
564 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
565 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
566 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
567 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
553 | }; | 568 | }; |
554 | 569 | ||
555 | |||
556 | |||
557 | int rv515_init(struct radeon_device *rdev) | 570 | int rv515_init(struct radeon_device *rdev) |
558 | { | 571 | { |
559 | rdev->config.r300.reg_safe_bm = r500_reg_safe_bm; | 572 | rdev->config.r300.reg_safe_bm = r500_reg_safe_bm; |