aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-03-20 17:18:23 -0400
committerDave Airlie <airlied@redhat.com>2012-03-21 02:55:54 -0400
commit9b136d514e3537a41e506f5306cd92d6d142f8bb (patch)
tree32ba495f210170d03822a97b61e4f016d6a999e3
parent25a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475 (diff)
drm/radeon/kms: fill in startup/shutdown callbacks for SI
Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/radeon/si.c329
1 files changed, 329 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 6aecbf54cd5d..4c0d8d251dd0 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -3468,6 +3468,12 @@ static void si_irq_suspend(struct radeon_device *rdev)
3468 si_rlc_stop(rdev); 3468 si_rlc_stop(rdev);
3469} 3469}
3470 3470
3471static void si_irq_fini(struct radeon_device *rdev)
3472{
3473 si_irq_suspend(rdev);
3474 r600_ih_ring_fini(rdev);
3475}
3476
3471static inline u32 si_get_ih_wptr(struct radeon_device *rdev) 3477static inline u32 si_get_ih_wptr(struct radeon_device *rdev)
3472{ 3478{
3473 u32 wptr, tmp; 3479 u32 wptr, tmp;
@@ -3793,3 +3799,326 @@ restart_ih:
3793 return IRQ_HANDLED; 3799 return IRQ_HANDLED;
3794} 3800}
3795 3801
3802/*
3803 * startup/shutdown callbacks
3804 */
3805static int si_startup(struct radeon_device *rdev)
3806{
3807 struct radeon_ring *ring;
3808 int r;
3809
3810 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
3811 !rdev->rlc_fw || !rdev->mc_fw) {
3812 r = si_init_microcode(rdev);
3813 if (r) {
3814 DRM_ERROR("Failed to load firmware!\n");
3815 return r;
3816 }
3817 }
3818
3819 r = si_mc_load_microcode(rdev);
3820 if (r) {
3821 DRM_ERROR("Failed to load MC firmware!\n");
3822 return r;
3823 }
3824
3825 r = r600_vram_scratch_init(rdev);
3826 if (r)
3827 return r;
3828
3829 si_mc_program(rdev);
3830 r = si_pcie_gart_enable(rdev);
3831 if (r)
3832 return r;
3833 si_gpu_init(rdev);
3834
3835#if 0
3836 r = evergreen_blit_init(rdev);
3837 if (r) {
3838 r600_blit_fini(rdev);
3839 rdev->asic->copy = NULL;
3840 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
3841 }
3842#endif
3843 /* allocate rlc buffers */
3844 r = si_rlc_init(rdev);
3845 if (r) {
3846 DRM_ERROR("Failed to init rlc BOs!\n");
3847 return r;
3848 }
3849
3850 /* allocate wb buffer */
3851 r = radeon_wb_init(rdev);
3852 if (r)
3853 return r;
3854
3855 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
3856 if (r) {
3857 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
3858 return r;
3859 }
3860
3861 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
3862 if (r) {
3863 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
3864 return r;
3865 }
3866
3867 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
3868 if (r) {
3869 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
3870 return r;
3871 }
3872
3873 /* Enable IRQ */
3874 r = si_irq_init(rdev);
3875 if (r) {
3876 DRM_ERROR("radeon: IH init failed (%d).\n", r);
3877 radeon_irq_kms_fini(rdev);
3878 return r;
3879 }
3880 si_irq_set(rdev);
3881
3882 ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3883 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
3884 CP_RB0_RPTR, CP_RB0_WPTR,
3885 0, 0xfffff, RADEON_CP_PACKET2);
3886 if (r)
3887 return r;
3888
3889 ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
3890 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
3891 CP_RB1_RPTR, CP_RB1_WPTR,
3892 0, 0xfffff, RADEON_CP_PACKET2);
3893 if (r)
3894 return r;
3895
3896 ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
3897 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
3898 CP_RB2_RPTR, CP_RB2_WPTR,
3899 0, 0xfffff, RADEON_CP_PACKET2);
3900 if (r)
3901 return r;
3902
3903 r = si_cp_load_microcode(rdev);
3904 if (r)
3905 return r;
3906 r = si_cp_resume(rdev);
3907 if (r)
3908 return r;
3909
3910 r = radeon_ib_pool_start(rdev);
3911 if (r)
3912 return r;
3913
3914 r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
3915 if (r) {
3916 DRM_ERROR("radeon: failed testing IB (%d) on CP ring 0\n", r);
3917 rdev->accel_working = false;
3918 return r;
3919 }
3920
3921 r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
3922 if (r) {
3923 DRM_ERROR("radeon: failed testing IB (%d) on CP ring 1\n", r);
3924 rdev->accel_working = false;
3925 return r;
3926 }
3927
3928 r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
3929 if (r) {
3930 DRM_ERROR("radeon: failed testing IB (%d) on CP ring 2\n", r);
3931 rdev->accel_working = false;
3932 return r;
3933 }
3934
3935 r = radeon_vm_manager_start(rdev);
3936 if (r)
3937 return r;
3938
3939 return 0;
3940}
3941
3942int si_resume(struct radeon_device *rdev)
3943{
3944 int r;
3945
3946 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
3947 * posting will perform necessary task to bring back GPU into good
3948 * shape.
3949 */
3950 /* post card */
3951 atom_asic_init(rdev->mode_info.atom_context);
3952
3953 rdev->accel_working = true;
3954 r = si_startup(rdev);
3955 if (r) {
3956 DRM_ERROR("si startup failed on resume\n");
3957 rdev->accel_working = false;
3958 return r;
3959 }
3960
3961 return r;
3962
3963}
3964
3965int si_suspend(struct radeon_device *rdev)
3966{
3967 /* FIXME: we should wait for ring to be empty */
3968 radeon_ib_pool_suspend(rdev);
3969 radeon_vm_manager_suspend(rdev);
3970#if 0
3971 r600_blit_suspend(rdev);
3972#endif
3973 si_cp_enable(rdev, false);
3974 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3975 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3976 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3977 si_irq_suspend(rdev);
3978 radeon_wb_disable(rdev);
3979 si_pcie_gart_disable(rdev);