[drm-next 01/14] drm/radeon/kms: add wait_for_vblank asic callback

alexdeucher at gmail.com alexdeucher at gmail.com
Thu Feb 23 14:53:37 PST 2012


From: Alex Deucher <alexander.deucher at amd.com>

Required for future functionality.

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/evergreen.c     |   19 +++++++++++++++++
 drivers/gpu/drm/radeon/evergreen_reg.h |    1 +
 drivers/gpu/drm/radeon/r100.c          |   34 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/r500_reg.h      |    2 +
 drivers/gpu/drm/radeon/radeon.h        |    3 ++
 drivers/gpu/drm/radeon/radeon_asic.c   |   17 ++++++++++++++++
 drivers/gpu/drm/radeon/radeon_asic.h   |    4 ++-
 drivers/gpu/drm/radeon/radeon_reg.h    |    2 +
 drivers/gpu/drm/radeon/rs600.c         |   19 +++++++++++++++++
 9 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index f58254a..158ff59 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -68,6 +68,25 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
 	}
 }
 
+void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
+	int i;
+
+	if (RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_MASTER_EN) {
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (!(RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK))
+				break;
+			udelay(1);
+		}
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK)
+				break;
+			udelay(1);
+		}
+	}
+}
+
 void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
 {
 	/* enable the pflip int */
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 4215de9..96c10b3 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -219,6 +219,7 @@
 #       define EVERGREEN_CRTC_MASTER_EN                 (1 << 0)
 #       define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24)
 #define EVERGREEN_CRTC_STATUS                           0x6e8c
+#       define EVERGREEN_CRTC_V_BLANK                   (1 << 0)
 #define EVERGREEN_CRTC_STATUS_POSITION                  0x6e90
 #define EVERGREEN_MASTER_UPDATE_MODE                    0x6ef8
 #define EVERGREEN_CRTC_UPDATE_LOCK                      0x6ed4
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 333cde9..bff612a 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -65,6 +65,40 @@ MODULE_FIRMWARE(FIRMWARE_R520);
 
 #include "r100_track.h"
 
+void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
+	int i;
+
+	if (radeon_crtc->crtc_id == 0) {
+		if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) {
+			for (i = 0; i < rdev->usec_timeout; i++) {
+				if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR))
+					break;
+				udelay(1);
+			}
+			for (i = 0; i < rdev->usec_timeout; i++) {
+				if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
+					break;
+				udelay(1);
+			}
+		}
+	} else {
+		if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN) {
+			for (i = 0; i < rdev->usec_timeout; i++) {
+				if (!(RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR))
+					break;
+				udelay(1);
+			}
+			for (i = 0; i < rdev->usec_timeout; i++) {
+				if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)
+					break;
+				udelay(1);
+			}
+		}
+	}
+}
+
 /* This files gather functions specifics to:
  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
  */
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h
index 3bd8f1b..ec576aa 100644
--- a/drivers/gpu/drm/radeon/r500_reg.h
+++ b/drivers/gpu/drm/radeon/r500_reg.h
@@ -351,6 +351,8 @@
 #define AVIVO_D1CRTC_BLANK_CONTROL                              0x6084
 #define AVIVO_D1CRTC_INTERLACE_CONTROL                          0x6088
 #define AVIVO_D1CRTC_INTERLACE_STATUS                           0x608c
+#define AVIVO_D1CRTC_STATUS                                     0x609c
+#       define AVIVO_D1CRTC_V_BLANK                             (1 << 0)
 #define AVIVO_D1CRTC_STATUS_POSITION                            0x60a0
 #define AVIVO_D1CRTC_FRAME_COUNT                                0x60a4
 #define AVIVO_D1CRTC_STEREO_CONTROL                             0x60c4
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 509b03d..76d08d8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1201,6 +1201,8 @@ struct radeon_asic {
 	void (*pre_page_flip)(struct radeon_device *rdev, int crtc);
 	u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base);
 	void (*post_page_flip)(struct radeon_device *rdev, int crtc);
+	/* wait for vblank */
+	void (*wait_for_vblank)(struct radeon_device *rdev, int crtc);
 };
 
 /*
@@ -1689,6 +1691,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 #define radeon_pre_page_flip(rdev, crtc) rdev->asic->pre_page_flip((rdev), (crtc))
 #define radeon_page_flip(rdev, crtc, base) rdev->asic->page_flip((rdev), (crtc), (base))
 #define radeon_post_page_flip(rdev, crtc) rdev->asic->post_page_flip((rdev), (crtc))
+#define radeon_wait_for_vblank(rdev, crtc) rdev->asic->wait_for_vblank((rdev), (crtc))
 
 /* Common functions */
 /* AGP */
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 636c68f..67f809e 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -178,6 +178,7 @@ static struct radeon_asic r100_asic = {
 	.pre_page_flip = &r100_pre_page_flip,
 	.page_flip = &r100_page_flip,
 	.post_page_flip = &r100_post_page_flip,
+	.wait_for_vblank = &r100_wait_for_vblank,
 };
 
 static struct radeon_asic r200_asic = {
@@ -229,6 +230,7 @@ static struct radeon_asic r200_asic = {
 	.pre_page_flip = &r100_pre_page_flip,
 	.page_flip = &r100_page_flip,
 	.post_page_flip = &r100_post_page_flip,
+	.wait_for_vblank = &r100_wait_for_vblank,
 };
 
 static struct radeon_asic r300_asic = {
@@ -281,6 +283,7 @@ static struct radeon_asic r300_asic = {
 	.pre_page_flip = &r100_pre_page_flip,
 	.page_flip = &r100_page_flip,
 	.post_page_flip = &r100_post_page_flip,
+	.wait_for_vblank = &r100_wait_for_vblank,
 };
 
 static struct radeon_asic r300_asic_pcie = {
@@ -332,6 +335,7 @@ static struct radeon_asic r300_asic_pcie = {
 	.pre_page_flip = &r100_pre_page_flip,
 	.page_flip = &r100_page_flip,
 	.post_page_flip = &r100_post_page_flip,
+	.wait_for_vblank = &r100_wait_for_vblank,
 };
 
 static struct radeon_asic r420_asic = {
@@ -384,6 +388,7 @@ static struct radeon_asic r420_asic = {
 	.pre_page_flip = &r100_pre_page_flip,
 	.page_flip = &r100_page_flip,
 	.post_page_flip = &r100_post_page_flip,
+	.wait_for_vblank = &r100_wait_for_vblank,
 };
 
 static struct radeon_asic rs400_asic = {
@@ -436,6 +441,7 @@ static struct radeon_asic rs400_asic = {
 	.pre_page_flip = &r100_pre_page_flip,
 	.page_flip = &r100_page_flip,
 	.post_page_flip = &r100_post_page_flip,
+	.wait_for_vblank = &r100_wait_for_vblank,
 };
 
 static struct radeon_asic rs600_asic = {
@@ -488,6 +494,7 @@ static struct radeon_asic rs600_asic = {
 	.pre_page_flip = &rs600_pre_page_flip,
 	.page_flip = &rs600_page_flip,
 	.post_page_flip = &rs600_post_page_flip,
+	.wait_for_vblank = &avivo_wait_for_vblank,
 };
 
 static struct radeon_asic rs690_asic = {
@@ -540,6 +547,7 @@ static struct radeon_asic rs690_asic = {
 	.pre_page_flip = &rs600_pre_page_flip,
 	.page_flip = &rs600_page_flip,
 	.post_page_flip = &rs600_post_page_flip,
+	.wait_for_vblank = &avivo_wait_for_vblank,
 };
 
 static struct radeon_asic rv515_asic = {
@@ -592,6 +600,7 @@ static struct radeon_asic rv515_asic = {
 	.pre_page_flip = &rs600_pre_page_flip,
 	.page_flip = &rs600_page_flip,
 	.post_page_flip = &rs600_post_page_flip,
+	.wait_for_vblank = &avivo_wait_for_vblank,
 };
 
 static struct radeon_asic r520_asic = {
@@ -644,6 +653,7 @@ static struct radeon_asic r520_asic = {
 	.pre_page_flip = &rs600_pre_page_flip,
 	.page_flip = &rs600_page_flip,
 	.post_page_flip = &rs600_post_page_flip,
+	.wait_for_vblank = &avivo_wait_for_vblank,
 };
 
 static struct radeon_asic r600_asic = {
@@ -695,6 +705,7 @@ static struct radeon_asic r600_asic = {
 	.pre_page_flip = &rs600_pre_page_flip,
 	.page_flip = &rs600_page_flip,
 	.post_page_flip = &rs600_post_page_flip,
+	.wait_for_vblank = &avivo_wait_for_vblank,
 };
 
 static struct radeon_asic rs780_asic = {
@@ -746,6 +757,7 @@ static struct radeon_asic rs780_asic = {
 	.pre_page_flip = &rs600_pre_page_flip,
 	.page_flip = &rs600_page_flip,
 	.post_page_flip = &rs600_post_page_flip,
+	.wait_for_vblank = &avivo_wait_for_vblank,
 };
 
 static struct radeon_asic rv770_asic = {
@@ -797,6 +809,7 @@ static struct radeon_asic rv770_asic = {
 	.pre_page_flip = &rs600_pre_page_flip,
 	.page_flip = &rv770_page_flip,
 	.post_page_flip = &rs600_post_page_flip,
+	.wait_for_vblank = &avivo_wait_for_vblank,
 };
 
 static struct radeon_asic evergreen_asic = {
@@ -848,6 +861,7 @@ static struct radeon_asic evergreen_asic = {
 	.pre_page_flip = &evergreen_pre_page_flip,
 	.page_flip = &evergreen_page_flip,
 	.post_page_flip = &evergreen_post_page_flip,
+	.wait_for_vblank = &dce4_wait_for_vblank,
 };
 
 static struct radeon_asic sumo_asic = {
@@ -899,6 +913,7 @@ static struct radeon_asic sumo_asic = {
 	.pre_page_flip = &evergreen_pre_page_flip,
 	.page_flip = &evergreen_page_flip,
 	.post_page_flip = &evergreen_post_page_flip,
+	.wait_for_vblank = &dce4_wait_for_vblank,
 };
 
 static struct radeon_asic btc_asic = {
@@ -950,6 +965,7 @@ static struct radeon_asic btc_asic = {
 	.pre_page_flip = &evergreen_pre_page_flip,
 	.page_flip = &evergreen_page_flip,
 	.post_page_flip = &evergreen_post_page_flip,
+	.wait_for_vblank = &dce4_wait_for_vblank,
 };
 
 static const struct radeon_vm_funcs cayman_vm_funcs = {
@@ -1026,6 +1042,7 @@ static struct radeon_asic cayman_asic = {
 	.pre_page_flip = &evergreen_pre_page_flip,
 	.page_flip = &evergreen_page_flip,
 	.post_page_flip = &evergreen_post_page_flip,
+	.wait_for_vblank = &dce4_wait_for_vblank,
 };
 
 int radeon_asic_init(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 6304aef..d9df84f 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -139,6 +139,7 @@ extern void r100_pm_get_dynpm_state(struct radeon_device *rdev);
 extern void r100_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
 extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);
+extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
 
 /*
  * r200,rv250,rs300,rv280
@@ -236,7 +237,7 @@ extern void rs600_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
 extern void rs600_post_page_flip(struct radeon_device *rdev, int crtc);
 void rs600_set_safe_registers(struct radeon_device *rdev);
-
+extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc);
 
 /*
  * rs690,rs740
@@ -423,6 +424,7 @@ extern void sumo_pm_init_profile(struct radeon_device *rdev);
 extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
 extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
+extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc);
 void evergreen_disable_interrupt_state(struct radeon_device *rdev);
 int evergreen_blit_init(struct radeon_device *rdev);
 
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index b4ce864..5098634 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -539,9 +539,11 @@
 
 #define RADEON_CRTC2_PITCH                  0x032c
 #define RADEON_CRTC_STATUS                  0x005c
+#       define RADEON_CRTC_VBLANK_CUR       (1 <<  0)
 #       define RADEON_CRTC_VBLANK_SAVE      (1 <<  1)
 #       define RADEON_CRTC_VBLANK_SAVE_CLEAR  (1 <<  1)
 #define RADEON_CRTC2_STATUS                  0x03fc
+#       define RADEON_CRTC2_VBLANK_CUR       (1 <<  0)
 #       define RADEON_CRTC2_VBLANK_SAVE      (1 <<  1)
 #       define RADEON_CRTC2_VBLANK_SAVE_CLEAR  (1 <<  1)
 #define RADEON_CRTC_V_SYNC_STRT_WID         0x020c
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 4fc7006..ab1b6da 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -46,6 +46,25 @@
 void rs600_gpu_init(struct radeon_device *rdev);
 int rs600_mc_wait_for_idle(struct radeon_device *rdev);
 
+void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
+{
+	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
+	int i;
+
+	if (RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset) & AVIVO_CRTC_EN) {
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (!(RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK))
+				break;
+			udelay(1);
+		}
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK)
+				break;
+			udelay(1);
+		}
+	}
+}
+
 void rs600_pre_page_flip(struct radeon_device *rdev, int crtc)
 {
 	/* enable the pflip int */
-- 
1.7.7.5



More information about the dri-devel mailing list