drm/radeon/kms: add wait_for_vblank asic callback
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 23 Feb 2012 22:53:37 +0000 (17:53 -0500)
committerDave Airlie <airlied@redhat.com>
Mon, 27 Feb 2012 14:46:13 +0000 (14:46 +0000)
Required for future functionality.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r500_reg.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_reg.h
drivers/gpu/drm/radeon/rs600.c

index 1a816ea51226d70b7a5102240981bd9421deb1f8..c8dae3f9fa09895d700e55e9d8350ee9bfebec1f 100644 (file)
@@ -99,6 +99,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 */
index 4215de95477e4a863c83183d90133c9d07358ee4..96c10b3991aade56f69ec9eef3258dc867670022 100644 (file)
 #       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
index 99bb006493570ae6da356193684fffeeb7712afa..65fe8e092a1856c52aa4bfb47389a98f897bdd21 100644 (file)
@@ -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
  */
index 3bd8f1b1c606f4098fa959b33bf2b753bded93fe..ec576aaafb7347b74f5f223f31a0273ffb8215fe 100644 (file)
 #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
index 884e0d4b114f8ce23abfd3438e57f456f7743479..e19a430d3443f6a7acac74b9e6e0b9d2b6cd750e 100644 (file)
@@ -1204,6 +1204,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);
 };
 
 /*
@@ -1692,6 +1694,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 */
index 36a6192ce862b5955356aed3466724cb0a696153..c6636085996196a2a407c8d1e0b1b06e93623a9b 100644 (file)
@@ -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 = {
@@ -1024,6 +1040,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)
index 6304aef0d9b27339ad44a020ac8a86ca282a631b..d9df84f9ebb68afbc9f5c72535bac546ad5c15a5 100644 (file)
@@ -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);
 
index b4ce86455707a9ed73889b7757f32dfc76f8d764..509863411285541ba87b1bb1469f17ef8fd747a9 100644 (file)
 
 #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
index ec46eb45e34cd8b7534deb5f75353496424756f7..fdb56b44dcd08b7f477823099b2a275a07390c7d 100644 (file)
 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 */