Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/cik: fill in startup/shutdown callbacks (v5)

v2: update to latest driver changes
v3: properly tear down vm on suspend
v4: fix up irq init ordering
v5: remove outdated comment

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>

+336
+336
drivers/gpu/drm/radeon/cik.c
··· 73 73 extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); 74 74 extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); 75 75 extern void si_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); 76 + extern void si_rlc_fini(struct radeon_device *rdev); 77 + extern int si_rlc_init(struct radeon_device *rdev); 76 78 77 79 #define BONAIRE_IO_MC_REGS_SIZE 36 78 80 ··· 4682 4680 goto restart_ih; 4683 4681 4684 4682 return IRQ_HANDLED; 4683 + } 4684 + 4685 + /* 4686 + * startup/shutdown callbacks 4687 + */ 4688 + /** 4689 + * cik_startup - program the asic to a functional state 4690 + * 4691 + * @rdev: radeon_device pointer 4692 + * 4693 + * Programs the asic to a functional state (CIK). 4694 + * Called by cik_init() and cik_resume(). 4695 + * Returns 0 for success, error for failure. 4696 + */ 4697 + static int cik_startup(struct radeon_device *rdev) 4698 + { 4699 + struct radeon_ring *ring; 4700 + int r; 4701 + 4702 + if (rdev->flags & RADEON_IS_IGP) { 4703 + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || 4704 + !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) { 4705 + r = cik_init_microcode(rdev); 4706 + if (r) { 4707 + DRM_ERROR("Failed to load firmware!\n"); 4708 + return r; 4709 + } 4710 + } 4711 + } else { 4712 + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || 4713 + !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw || 4714 + !rdev->mc_fw) { 4715 + r = cik_init_microcode(rdev); 4716 + if (r) { 4717 + DRM_ERROR("Failed to load firmware!\n"); 4718 + return r; 4719 + } 4720 + } 4721 + 4722 + r = ci_mc_load_microcode(rdev); 4723 + if (r) { 4724 + DRM_ERROR("Failed to load MC firmware!\n"); 4725 + return r; 4726 + } 4727 + } 4728 + 4729 + r = r600_vram_scratch_init(rdev); 4730 + if (r) 4731 + return r; 4732 + 4733 + cik_mc_program(rdev); 4734 + r = cik_pcie_gart_enable(rdev); 4735 + if (r) 4736 + return r; 4737 + cik_gpu_init(rdev); 4738 + 4739 + /* allocate rlc buffers */ 4740 + r = si_rlc_init(rdev); 4741 + if (r) { 4742 + DRM_ERROR("Failed to init rlc BOs!\n"); 4743 + return r; 4744 + } 4745 + 4746 + /* allocate wb buffer */ 4747 + r = radeon_wb_init(rdev); 4748 + if (r) 4749 + return r; 4750 + 4751 + r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 4752 + if (r) { 4753 + dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 4754 + return r; 4755 + } 4756 + 4757 + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); 4758 + if (r) { 4759 + dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 4760 + return r; 4761 + } 4762 + 4763 + r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); 4764 + if (r) { 4765 + dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 4766 + return r; 4767 + } 4768 + 4769 + /* Enable IRQ */ 4770 + if (!rdev->irq.installed) { 4771 + r = radeon_irq_kms_init(rdev); 4772 + if (r) 4773 + return r; 4774 + } 4775 + 4776 + r = cik_irq_init(rdev); 4777 + if (r) { 4778 + DRM_ERROR("radeon: IH init failed (%d).\n", r); 4779 + radeon_irq_kms_fini(rdev); 4780 + return r; 4781 + } 4782 + cik_irq_set(rdev); 4783 + 4784 + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 4785 + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 4786 + CP_RB0_RPTR, CP_RB0_WPTR, 4787 + 0, 0xfffff, RADEON_CP_PACKET2); 4788 + if (r) 4789 + return r; 4790 + 4791 + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 4792 + r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, 4793 + SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET, 4794 + SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET, 4795 + 2, 0xfffffffc, SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); 4796 + if (r) 4797 + return r; 4798 + 4799 + ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 4800 + r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, 4801 + SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET, 4802 + SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET, 4803 + 2, 0xfffffffc, SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); 4804 + if (r) 4805 + return r; 4806 + 4807 + r = cik_cp_resume(rdev); 4808 + if (r) 4809 + return r; 4810 + 4811 + r = cik_sdma_resume(rdev); 4812 + if (r) 4813 + return r; 4814 + 4815 + r = radeon_ib_pool_init(rdev); 4816 + if (r) { 4817 + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 4818 + return r; 4819 + } 4820 + 4821 + r = radeon_vm_manager_init(rdev); 4822 + if (r) { 4823 + dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); 4824 + return r; 4825 + } 4826 + 4827 + return 0; 4828 + } 4829 + 4830 + /** 4831 + * cik_resume - resume the asic to a functional state 4832 + * 4833 + * @rdev: radeon_device pointer 4834 + * 4835 + * Programs the asic to a functional state (CIK). 4836 + * Called at resume. 4837 + * Returns 0 for success, error for failure. 4838 + */ 4839 + int cik_resume(struct radeon_device *rdev) 4840 + { 4841 + int r; 4842 + 4843 + /* post card */ 4844 + atom_asic_init(rdev->mode_info.atom_context); 4845 + 4846 + rdev->accel_working = true; 4847 + r = cik_startup(rdev); 4848 + if (r) { 4849 + DRM_ERROR("cik startup failed on resume\n"); 4850 + rdev->accel_working = false; 4851 + return r; 4852 + } 4853 + 4854 + return r; 4855 + 4856 + } 4857 + 4858 + /** 4859 + * cik_suspend - suspend the asic 4860 + * 4861 + * @rdev: radeon_device pointer 4862 + * 4863 + * Bring the chip into a state suitable for suspend (CIK). 4864 + * Called at suspend. 4865 + * Returns 0 for success. 4866 + */ 4867 + int cik_suspend(struct radeon_device *rdev) 4868 + { 4869 + radeon_vm_manager_fini(rdev); 4870 + cik_cp_enable(rdev, false); 4871 + cik_sdma_enable(rdev, false); 4872 + cik_irq_suspend(rdev); 4873 + radeon_wb_disable(rdev); 4874 + cik_pcie_gart_disable(rdev); 4875 + return 0; 4876 + } 4877 + 4878 + /* Plan is to move initialization in that function and use 4879 + * helper function so that radeon_device_init pretty much 4880 + * do nothing more than calling asic specific function. This 4881 + * should also allow to remove a bunch of callback function 4882 + * like vram_info. 4883 + */ 4884 + /** 4885 + * cik_init - asic specific driver and hw init 4886 + * 4887 + * @rdev: radeon_device pointer 4888 + * 4889 + * Setup asic specific driver variables and program the hw 4890 + * to a functional state (CIK). 4891 + * Called at driver startup. 4892 + * Returns 0 for success, errors for failure. 4893 + */ 4894 + int cik_init(struct radeon_device *rdev) 4895 + { 4896 + struct radeon_ring *ring; 4897 + int r; 4898 + 4899 + /* Read BIOS */ 4900 + if (!radeon_get_bios(rdev)) { 4901 + if (ASIC_IS_AVIVO(rdev)) 4902 + return -EINVAL; 4903 + } 4904 + /* Must be an ATOMBIOS */ 4905 + if (!rdev->is_atom_bios) { 4906 + dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); 4907 + return -EINVAL; 4908 + } 4909 + r = radeon_atombios_init(rdev); 4910 + if (r) 4911 + return r; 4912 + 4913 + /* Post card if necessary */ 4914 + if (!radeon_card_posted(rdev)) { 4915 + if (!rdev->bios) { 4916 + dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 4917 + return -EINVAL; 4918 + } 4919 + DRM_INFO("GPU not posted. posting now...\n"); 4920 + atom_asic_init(rdev->mode_info.atom_context); 4921 + } 4922 + /* Initialize scratch registers */ 4923 + cik_scratch_init(rdev); 4924 + /* Initialize surface registers */ 4925 + radeon_surface_init(rdev); 4926 + /* Initialize clocks */ 4927 + radeon_get_clock_info(rdev->ddev); 4928 + 4929 + /* Fence driver */ 4930 + r = radeon_fence_driver_init(rdev); 4931 + if (r) 4932 + return r; 4933 + 4934 + /* initialize memory controller */ 4935 + r = cik_mc_init(rdev); 4936 + if (r) 4937 + return r; 4938 + /* Memory manager */ 4939 + r = radeon_bo_init(rdev); 4940 + if (r) 4941 + return r; 4942 + 4943 + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 4944 + ring->ring_obj = NULL; 4945 + r600_ring_init(rdev, ring, 1024 * 1024); 4946 + 4947 + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 4948 + ring->ring_obj = NULL; 4949 + r600_ring_init(rdev, ring, 256 * 1024); 4950 + 4951 + ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 4952 + ring->ring_obj = NULL; 4953 + r600_ring_init(rdev, ring, 256 * 1024); 4954 + 4955 + rdev->ih.ring_obj = NULL; 4956 + r600_ih_ring_init(rdev, 64 * 1024); 4957 + 4958 + r = r600_pcie_gart_init(rdev); 4959 + if (r) 4960 + return r; 4961 + 4962 + rdev->accel_working = true; 4963 + r = cik_startup(rdev); 4964 + if (r) { 4965 + dev_err(rdev->dev, "disabling GPU acceleration\n"); 4966 + cik_cp_fini(rdev); 4967 + cik_sdma_fini(rdev); 4968 + cik_irq_fini(rdev); 4969 + si_rlc_fini(rdev); 4970 + radeon_wb_fini(rdev); 4971 + radeon_ib_pool_fini(rdev); 4972 + radeon_vm_manager_fini(rdev); 4973 + radeon_irq_kms_fini(rdev); 4974 + cik_pcie_gart_fini(rdev); 4975 + rdev->accel_working = false; 4976 + } 4977 + 4978 + /* Don't start up if the MC ucode is missing. 4979 + * The default clocks and voltages before the MC ucode 4980 + * is loaded are not suffient for advanced operations. 4981 + */ 4982 + if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { 4983 + DRM_ERROR("radeon: MC ucode required for NI+.\n"); 4984 + return -EINVAL; 4985 + } 4986 + 4987 + return 0; 4988 + } 4989 + 4990 + /** 4991 + * cik_fini - asic specific driver and hw fini 4992 + * 4993 + * @rdev: radeon_device pointer 4994 + * 4995 + * Tear down the asic specific driver variables and program the hw 4996 + * to an idle state (CIK). 4997 + * Called at driver unload. 4998 + */ 4999 + void cik_fini(struct radeon_device *rdev) 5000 + { 5001 + cik_cp_fini(rdev); 5002 + cik_sdma_fini(rdev); 5003 + cik_irq_fini(rdev); 5004 + si_rlc_fini(rdev); 5005 + radeon_wb_fini(rdev); 5006 + radeon_vm_manager_fini(rdev); 5007 + radeon_ib_pool_fini(rdev); 5008 + radeon_irq_kms_fini(rdev); 5009 + cik_pcie_gart_fini(rdev); 5010 + r600_vram_scratch_fini(rdev); 5011 + radeon_gem_fini(rdev); 5012 + radeon_fence_driver_fini(rdev); 5013 + radeon_bo_fini(rdev); 5014 + radeon_atombios_fini(rdev); 5015 + kfree(rdev->bios); 5016 + rdev->bios = NULL; 4685 5017 }