aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
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 /drivers/gpu/drm/radeon
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>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-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);
3980 return 0;
3981}
3982
3983/* Plan is to move initialization in that function and use
3984 * helper function so that radeon_device_init pretty much
3985 * do nothing more than calling asic specific function. This
3986 * should also allow to remove a bunch of callback function
3987 * like vram_info.
3988 */
3989int si_init(struct radeon_device *rdev)
3990{
3991 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3992 int r;
3993
3994 /* This don't do much */
3995 r = radeon_gem_init(rdev);
3996 if (r)
3997 return r;
3998 /* Read BIOS */
3999 if (!radeon_get_bios(rdev)) {
4000 if (ASIC_IS_AVIVO(rdev))
4001 return -EINVAL;
4002 }
4003 /* Must be an ATOMBIOS */
4004 if (!rdev->is_atom_bios) {
4005 dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
4006 return -EINVAL;
4007 }
4008 r = radeon_atombios_init(rdev);
4009 if (r)
4010 return r;
4011
4012 /* Post card if necessary */
4013 if (!radeon_card_posted(rdev)) {
4014 if (!rdev->bios) {
4015 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
4016 return -EINVAL;
4017 }
4018 DRM_INFO("GPU not posted. posting now...\n");
4019 atom_asic_init(rdev->mode_info.atom_context);
4020 }
4021 /* Initialize scratch registers */
4022 si_scratch_init(rdev);
4023 /* Initialize surface registers */
4024 radeon_surface_init(rdev);
4025 /* Initialize clocks */
4026 radeon_get_clock_info(rdev->ddev);
4027
4028 /* Fence driver */
4029 r = radeon_fence_driver_init(rdev);
4030 if (r)
4031 return r;
4032
4033 /* initialize memory controller */
4034 r = si_mc_init(rdev);
4035 if (r)
4036 return r;
4037 /* Memory manager */
4038 r = radeon_bo_init(rdev);
4039 if (r)
4040 return r;
4041
4042 r = radeon_irq_kms_init(rdev);
4043 if (r)
4044 return r;
4045
4046 ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
4047 ring->ring_obj = NULL;
4048 r600_ring_init(rdev, ring, 1024 * 1024);
4049
4050 ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
4051 ring->ring_obj = NULL;
4052 r600_ring_init(rdev, ring, 1024 * 1024);
4053
4054 ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
4055 ring->ring_obj = NULL;
4056 r600_ring_init(rdev, ring, 1024 * 1024);
4057
4058 rdev->ih.ring_obj = NULL;
4059 r600_ih_ring_init(rdev, 64 * 1024);
4060
4061 r = r600_pcie_gart_init(rdev);
4062 if (r)
4063 return r;
4064
4065 r = radeon_ib_pool_init(rdev);
4066 rdev->accel_working = true;
4067 if (r) {
4068 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
4069 rdev->accel_working = false;
4070 }
4071 r = radeon_vm_manager_init(rdev);
4072 if (r) {
4073 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
4074 }
4075
4076 r = si_startup(rdev);
4077 if (r) {
4078 dev_err(rdev->dev, "disabling GPU acceleration\n");
4079 si_cp_fini(rdev);
4080 si_irq_fini(rdev);
4081 si_rlc_fini(rdev);
4082 radeon_wb_fini(rdev);
4083 r100_ib_fini(rdev);
4084 radeon_vm_manager_fini(rdev);
4085 radeon_irq_kms_fini(rdev);
4086 si_pcie_gart_fini(rdev);
4087 rdev->accel_working = false;
4088 }
4089
4090 /* Don't start up if the MC ucode is missing.
4091 * The default clocks and voltages before the MC ucode
4092 * is loaded are not suffient for advanced operations.
4093 */
4094 if (!rdev->mc_fw) {
4095 DRM_ERROR("radeon: MC ucode required for NI+.\n");
4096 return -EINVAL;
4097 }
4098
4099 return 0;
4100}
4101
4102void si_fini(struct radeon_device *rdev)
4103{
4104#if 0
4105 r600_blit_fini(rdev);
4106#endif
4107 si_cp_fini(rdev);
4108 si_irq_fini(rdev);
4109 si_rlc_fini(rdev);
4110 radeon_wb_fini(rdev);
4111 radeon_vm_manager_fini(rdev);
4112 r100_ib_fini(rdev);
4113 radeon_irq_kms_fini(rdev);
4114 si_pcie_gart_fini(rdev);
4115 r600_vram_scratch_fini(rdev);
4116 radeon_gem_fini(rdev);
4117 radeon_semaphore_driver_fini(rdev);
4118 radeon_fence_driver_fini(rdev);
4119 radeon_bo_fini(rdev);
4120 radeon_atombios_fini(rdev);
4121 kfree(rdev->bios);
4122 rdev->bios = NULL;
4123}
4124