LCOV - code coverage report
Current view: top level - dev/pci/drm/radeon - r520.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 168 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2008 Advanced Micro Devices, Inc.
       3             :  * Copyright 2008 Red Hat Inc.
       4             :  * Copyright 2009 Jerome Glisse.
       5             :  *
       6             :  * Permission is hereby granted, free of charge, to any person obtaining a
       7             :  * copy of this software and associated documentation files (the "Software"),
       8             :  * to deal in the Software without restriction, including without limitation
       9             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      10             :  * and/or sell copies of the Software, and to permit persons to whom the
      11             :  * Software is furnished to do so, subject to the following conditions:
      12             :  *
      13             :  * The above copyright notice and this permission notice shall be included in
      14             :  * all copies or substantial portions of the Software.
      15             :  *
      16             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      17             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      18             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      19             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      20             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      21             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      22             :  * OTHER DEALINGS IN THE SOFTWARE.
      23             :  *
      24             :  * Authors: Dave Airlie
      25             :  *          Alex Deucher
      26             :  *          Jerome Glisse
      27             :  */
      28             : #include <dev/pci/drm/drmP.h>
      29             : #include "radeon.h"
      30             : #include "radeon_asic.h"
      31             : #include "atom.h"
      32             : #include "r520d.h"
      33             : 
      34             : /* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */
      35             : 
      36           0 : int r520_mc_wait_for_idle(struct radeon_device *rdev)
      37             : {
      38             :         unsigned i;
      39             :         uint32_t tmp;
      40             : 
      41           0 :         for (i = 0; i < rdev->usec_timeout; i++) {
      42             :                 /* read MC_STATUS */
      43           0 :                 tmp = RREG32_MC(R520_MC_STATUS);
      44           0 :                 if (tmp & R520_MC_STATUS_IDLE) {
      45           0 :                         return 0;
      46             :                 }
      47           0 :                 DRM_UDELAY(1);
      48             :         }
      49           0 :         return -1;
      50           0 : }
      51             : 
      52           0 : static void r520_gpu_init(struct radeon_device *rdev)
      53             : {
      54             :         unsigned pipe_select_current, gb_pipe_select, tmp;
      55             : 
      56           0 :         rv515_vga_render_disable(rdev);
      57             :         /*
      58             :          * DST_PIPE_CONFIG              0x170C
      59             :          * GB_TILE_CONFIG               0x4018
      60             :          * GB_FIFO_SIZE                 0x4024
      61             :          * GB_PIPE_SELECT               0x402C
      62             :          * GB_PIPE_SELECT2              0x4124
      63             :          *      Z_PIPE_SHIFT                    0
      64             :          *      Z_PIPE_MASK                     0x000000003
      65             :          * GB_FIFO_SIZE2                0x4128
      66             :          *      SC_SFIFO_SIZE_SHIFT             0
      67             :          *      SC_SFIFO_SIZE_MASK              0x000000003
      68             :          *      SC_MFIFO_SIZE_SHIFT             2
      69             :          *      SC_MFIFO_SIZE_MASK              0x00000000C
      70             :          *      FG_SFIFO_SIZE_SHIFT             4
      71             :          *      FG_SFIFO_SIZE_MASK              0x000000030
      72             :          *      ZB_MFIFO_SIZE_SHIFT             6
      73             :          *      ZB_MFIFO_SIZE_MASK              0x0000000C0
      74             :          * GA_ENHANCE                   0x4274
      75             :          * SU_REG_DEST                  0x42C8
      76             :          */
      77             :         /* workaround for RV530 */
      78           0 :         if (rdev->family == CHIP_RV530) {
      79           0 :                 WREG32(0x4128, 0xFF);
      80           0 :         }
      81           0 :         r420_pipes_init(rdev);
      82           0 :         gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);
      83           0 :         tmp = RREG32(R300_DST_PIPE_CONFIG);
      84           0 :         pipe_select_current = (tmp >> 2) & 3;
      85           0 :         tmp = (1 << pipe_select_current) |
      86           0 :               (((gb_pipe_select >> 8) & 0xF) << 4);
      87           0 :         WREG32_PLL(0x000D, tmp);
      88           0 :         if (r520_mc_wait_for_idle(rdev)) {
      89           0 :                 printk(KERN_WARNING "Failed to wait MC idle while "
      90             :                        "programming pipes. Bad things might happen.\n");
      91           0 :         }
      92           0 : }
      93             : 
      94           0 : static void r520_vram_get_type(struct radeon_device *rdev)
      95             : {
      96             :         uint32_t tmp;
      97             : 
      98           0 :         rdev->mc.vram_width = 128;
      99           0 :         rdev->mc.vram_is_ddr = true;
     100           0 :         tmp = RREG32_MC(R520_MC_CNTL0);
     101           0 :         switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) {
     102             :         case 0:
     103           0 :                 rdev->mc.vram_width = 32;
     104           0 :                 break;
     105             :         case 1:
     106           0 :                 rdev->mc.vram_width = 64;
     107           0 :                 break;
     108             :         case 2:
     109           0 :                 rdev->mc.vram_width = 128;
     110           0 :                 break;
     111             :         case 3:
     112           0 :                 rdev->mc.vram_width = 256;
     113           0 :                 break;
     114             :         default:
     115             :                 rdev->mc.vram_width = 128;
     116             :                 break;
     117             :         }
     118           0 :         if (tmp & R520_MC_CHANNEL_SIZE)
     119           0 :                 rdev->mc.vram_width *= 2;
     120           0 : }
     121             : 
     122           0 : static void r520_mc_init(struct radeon_device *rdev)
     123             : {
     124             : 
     125           0 :         r520_vram_get_type(rdev);
     126           0 :         r100_vram_init_sizes(rdev);
     127           0 :         radeon_vram_location(rdev, &rdev->mc, 0);
     128           0 :         rdev->mc.gtt_base_align = 0;
     129           0 :         if (!(rdev->flags & RADEON_IS_AGP))
     130           0 :                 radeon_gtt_location(rdev, &rdev->mc);
     131           0 :         radeon_update_bandwidth_info(rdev);
     132           0 : }
     133             : 
     134           0 : static void r520_mc_program(struct radeon_device *rdev)
     135             : {
     136           0 :         struct rv515_mc_save save;
     137             : 
     138             :         /* Stops all mc clients */
     139           0 :         rv515_mc_stop(rdev, &save);
     140             : 
     141             :         /* Wait for mc idle */
     142           0 :         if (r520_mc_wait_for_idle(rdev))
     143           0 :                 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
     144             :         /* Write VRAM size in case we are limiting it */
     145           0 :         WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
     146             :         /* Program MC, should be a 32bits limited address space */
     147           0 :         WREG32_MC(R_000004_MC_FB_LOCATION,
     148             :                         S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |
     149             :                         S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));
     150           0 :         WREG32(R_000134_HDP_FB_LOCATION,
     151             :                 S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
     152           0 :         if (rdev->flags & RADEON_IS_AGP) {
     153           0 :                 WREG32_MC(R_000005_MC_AGP_LOCATION,
     154             :                         S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) |
     155             :                         S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
     156           0 :                 WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
     157           0 :                 WREG32_MC(R_000007_AGP_BASE_2,
     158             :                         S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base)));
     159           0 :         } else {
     160           0 :                 WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF);
     161           0 :                 WREG32_MC(R_000006_AGP_BASE, 0);
     162           0 :                 WREG32_MC(R_000007_AGP_BASE_2, 0);
     163             :         }
     164             : 
     165           0 :         rv515_mc_resume(rdev, &save);
     166           0 : }
     167             : 
     168           0 : static int r520_startup(struct radeon_device *rdev)
     169             : {
     170             :         int r;
     171             : 
     172           0 :         r520_mc_program(rdev);
     173             :         /* Resume clock */
     174           0 :         rv515_clock_startup(rdev);
     175             :         /* Initialize GPU configuration (# pipes, ...) */
     176           0 :         r520_gpu_init(rdev);
     177             :         /* Initialize GART (initialize after TTM so we can allocate
     178             :          * memory through TTM but finalize after TTM) */
     179           0 :         if (rdev->flags & RADEON_IS_PCIE) {
     180           0 :                 r = rv370_pcie_gart_enable(rdev);
     181           0 :                 if (r)
     182           0 :                         return r;
     183             :         }
     184             : 
     185             :         /* allocate wb buffer */
     186           0 :         r = radeon_wb_init(rdev);
     187           0 :         if (r)
     188           0 :                 return r;
     189             : 
     190           0 :         r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
     191           0 :         if (r) {
     192           0 :                 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
     193           0 :                 return r;
     194             :         }
     195             : 
     196             :         /* Enable IRQ */
     197           0 :         if (!rdev->irq.installed) {
     198           0 :                 r = radeon_irq_kms_init(rdev);
     199           0 :                 if (r)
     200           0 :                         return r;
     201             :         }
     202             : 
     203           0 :         rs600_irq_set(rdev);
     204           0 :         rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
     205             :         /* 1M ring buffer */
     206           0 :         r = r100_cp_init(rdev, 1024 * 1024);
     207           0 :         if (r) {
     208           0 :                 dev_err(rdev->dev, "failed initializing CP (%d).\n", r);
     209           0 :                 return r;
     210             :         }
     211             : 
     212           0 :         r = radeon_ib_pool_init(rdev);
     213           0 :         if (r) {
     214           0 :                 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
     215           0 :                 return r;
     216             :         }
     217             : 
     218           0 :         return 0;
     219           0 : }
     220             : 
     221           0 : int r520_resume(struct radeon_device *rdev)
     222             : {
     223             :         int r;
     224             : 
     225             :         /* Make sur GART are not working */
     226           0 :         if (rdev->flags & RADEON_IS_PCIE)
     227           0 :                 rv370_pcie_gart_disable(rdev);
     228             :         /* Resume clock before doing reset */
     229           0 :         rv515_clock_startup(rdev);
     230             :         /* Reset gpu before posting otherwise ATOM will enter infinite loop */
     231           0 :         if (radeon_asic_reset(rdev)) {
     232           0 :                 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
     233             :                         RREG32(R_000E40_RBBM_STATUS),
     234             :                         RREG32(R_0007C0_CP_STAT));
     235           0 :         }
     236             :         /* post */
     237           0 :         atom_asic_init(rdev->mode_info.atom_context);
     238             :         /* Resume clock after posting */
     239           0 :         rv515_clock_startup(rdev);
     240             :         /* Initialize surface registers */
     241           0 :         radeon_surface_init(rdev);
     242             : 
     243           0 :         rdev->accel_working = true;
     244           0 :         r = r520_startup(rdev);
     245           0 :         if (r) {
     246           0 :                 rdev->accel_working = false;
     247           0 :         }
     248           0 :         return r;
     249             : }
     250             : 
     251           0 : int r520_init(struct radeon_device *rdev)
     252             : {
     253             :         int r;
     254             : 
     255             :         /* Initialize scratch registers */
     256           0 :         radeon_scratch_init(rdev);
     257             :         /* Initialize surface registers */
     258           0 :         radeon_surface_init(rdev);
     259             :         /* restore some register to sane defaults */
     260           0 :         r100_restore_sanity(rdev);
     261             :         /* TODO: disable VGA need to use VGA request */
     262             :         /* BIOS*/
     263           0 :         if (!radeon_get_bios(rdev)) {
     264           0 :                 if (ASIC_IS_AVIVO(rdev))
     265           0 :                         return -EINVAL;
     266             :         }
     267           0 :         if (rdev->is_atom_bios) {
     268           0 :                 r = radeon_atombios_init(rdev);
     269           0 :                 if (r)
     270           0 :                         return r;
     271             :         } else {
     272           0 :                 dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");
     273           0 :                 return -EINVAL;
     274             :         }
     275             :         /* Reset gpu before posting otherwise ATOM will enter infinite loop */
     276           0 :         if (radeon_asic_reset(rdev)) {
     277           0 :                 dev_warn(rdev->dev,
     278             :                         "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
     279             :                         RREG32(R_000E40_RBBM_STATUS),
     280             :                         RREG32(R_0007C0_CP_STAT));
     281           0 :         }
     282             :         /* check if cards are posted or not */
     283           0 :         if (radeon_boot_test_post_card(rdev) == false)
     284           0 :                 return -EINVAL;
     285             : 
     286           0 :         if (!radeon_card_posted(rdev) && rdev->bios) {
     287             :                 DRM_INFO("GPU not posted. posting now...\n");
     288           0 :                 atom_asic_init(rdev->mode_info.atom_context);
     289           0 :         }
     290             :         /* Initialize clocks */
     291           0 :         radeon_get_clock_info(rdev->ddev);
     292             :         /* initialize AGP */
     293           0 :         if (rdev->flags & RADEON_IS_AGP) {
     294           0 :                 r = radeon_agp_init(rdev);
     295           0 :                 if (r) {
     296           0 :                         radeon_agp_disable(rdev);
     297           0 :                 }
     298             :         }
     299             :         /* initialize memory controller */
     300           0 :         r520_mc_init(rdev);
     301           0 :         rv515_debugfs(rdev);
     302             :         /* Fence driver */
     303           0 :         r = radeon_fence_driver_init(rdev);
     304           0 :         if (r)
     305           0 :                 return r;
     306             :         /* Memory manager */
     307           0 :         r = radeon_bo_init(rdev);
     308           0 :         if (r)
     309           0 :                 return r;
     310           0 :         r = rv370_pcie_gart_init(rdev);
     311           0 :         if (r)
     312           0 :                 return r;
     313           0 :         rv515_set_safe_registers(rdev);
     314             : 
     315             :         /* Initialize power management */
     316           0 :         radeon_pm_init(rdev);
     317             : 
     318           0 :         rdev->accel_working = true;
     319           0 :         r = r520_startup(rdev);
     320           0 :         if (r) {
     321             :                 /* Somethings want wront with the accel init stop accel */
     322           0 :                 dev_err(rdev->dev, "Disabling GPU acceleration\n");
     323           0 :                 r100_cp_fini(rdev);
     324           0 :                 radeon_wb_fini(rdev);
     325           0 :                 radeon_ib_pool_fini(rdev);
     326           0 :                 radeon_irq_kms_fini(rdev);
     327           0 :                 rv370_pcie_gart_fini(rdev);
     328           0 :                 radeon_agp_fini(rdev);
     329           0 :                 rdev->accel_working = false;
     330           0 :         }
     331           0 :         return 0;
     332           0 : }

Generated by: LCOV version 1.13