aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/r100.c105
-rw-r--r--drivers/gpu/drm/radeon/r300.c13
-rw-r--r--drivers/gpu/drm/radeon/r500_reg.h2
-rw-r--r--drivers/gpu/drm/radeon/rv515.c23
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 */
768int 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 }
845out:
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);
44int r100_cs_packet_parse(struct radeon_cs_parser *p, 44int 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);
47int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
47int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, 48int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
48 struct radeon_cs_reloc **cs_reloc); 49 struct radeon_cs_reloc **cs_reloc);
49int r100_cs_parse_packet0(struct radeon_cs_parser *p, 50int 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
973static const unsigned r300_reg_safe_bm[159] = { 974static 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 */
512static const unsigned r500_reg_safe_bm[159] = { 512static 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
557int rv515_init(struct radeon_device *rdev) 570int 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;