Subversion Repositories Kolibri OS

Rev

Rev 1128 | Rev 1179 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 "drmP.h"
  29. #include "radeon_reg.h"
  30. #include "radeon.h"
  31.  
  32. /* rs690,rs740 depends on : */
  33. void r100_hdp_reset(struct radeon_device *rdev);
  34. int r300_mc_wait_for_idle(struct radeon_device *rdev);
  35. void r420_pipes_init(struct radeon_device *rdev);
  36. void rs400_gart_disable(struct radeon_device *rdev);
  37. int rs400_gart_enable(struct radeon_device *rdev);
  38. void rs400_gart_adjust_size(struct radeon_device *rdev);
  39. void rs600_mc_disable_clients(struct radeon_device *rdev);
  40. void rs600_disable_vga(struct radeon_device *rdev);
  41.  
  42. /* This files gather functions specifics to :
  43.  * rs690,rs740
  44.  *
  45.  * Some of these functions might be used by newer ASICs.
  46.  */
  47. void rs690_gpu_init(struct radeon_device *rdev);
  48. int rs690_mc_wait_for_idle(struct radeon_device *rdev);
  49.  
  50.  
  51. /*
  52.  * MC functions.
  53.  */
  54. int rs690_mc_init(struct radeon_device *rdev)
  55. {
  56.         uint32_t tmp;
  57.         int r;
  58.  
  59.         if (r100_debugfs_rbbm_init(rdev)) {
  60.                 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
  61.         }
  62.  
  63.         rs690_gpu_init(rdev);
  64.         rs400_gart_disable(rdev);
  65.  
  66.         /* Setup GPU memory space */
  67.         rdev->mc.gtt_location = rdev->mc.vram_size;
  68.         rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
  69.         rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
  70.         rdev->mc.vram_location = 0xFFFFFFFFUL;
  71.         r = radeon_mc_setup(rdev);
  72.         if (r) {
  73.                 return r;
  74.         }
  75.  
  76.         /* Program GPU memory space */
  77.         rs600_mc_disable_clients(rdev);
  78.         if (rs690_mc_wait_for_idle(rdev)) {
  79.                 printk(KERN_WARNING "Failed to wait MC idle while "
  80.                        "programming pipes. Bad things might happen.\n");
  81.         }
  82.         tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1;
  83.         tmp = REG_SET(RS690_MC_FB_TOP, tmp >> 16);
  84.         tmp |= REG_SET(RS690_MC_FB_START, rdev->mc.vram_location >> 16);
  85.         WREG32_MC(RS690_MCCFG_FB_LOCATION, tmp);
  86.         /* FIXME: Does this reg exist on RS480,RS740 ? */
  87.         WREG32(0x310, rdev->mc.vram_location);
  88.         WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
  89.         return 0;
  90. }
  91.  
  92. void rs690_mc_fini(struct radeon_device *rdev)
  93. {
  94.         rs400_gart_disable(rdev);
  95.         radeon_gart_table_ram_free(rdev);
  96.         radeon_gart_fini(rdev);
  97. }
  98.  
  99.  
  100. /*
  101.  * Global GPU functions
  102.  */
  103. int rs690_mc_wait_for_idle(struct radeon_device *rdev)
  104. {
  105.         unsigned i;
  106.         uint32_t tmp;
  107.  
  108.         for (i = 0; i < rdev->usec_timeout; i++) {
  109.                 /* read MC_STATUS */
  110.                 tmp = RREG32_MC(RS690_MC_STATUS);
  111.                 if (tmp & RS690_MC_STATUS_IDLE) {
  112.                         return 0;
  113.                 }
  114.                 DRM_UDELAY(1);
  115.         }
  116.         return -1;
  117. }
  118.  
  119. void rs690_errata(struct radeon_device *rdev)
  120. {
  121.         rdev->pll_errata = 0;
  122. }
  123.  
  124. void rs690_gpu_init(struct radeon_device *rdev)
  125. {
  126.         /* FIXME: HDP same place on rs690 ? */
  127.         r100_hdp_reset(rdev);
  128.         rs600_disable_vga(rdev);
  129.         /* FIXME: is this correct ? */
  130.         r420_pipes_init(rdev);
  131.         if (rs690_mc_wait_for_idle(rdev)) {
  132.                 printk(KERN_WARNING "Failed to wait MC idle while "
  133.                        "programming pipes. Bad things might happen.\n");
  134.         }
  135. }
  136.  
  137.  
  138. /*
  139.  * VRAM info.
  140.  */
  141. void rs690_vram_info(struct radeon_device *rdev)
  142. {
  143.         uint32_t tmp;
  144.  
  145.         rs400_gart_adjust_size(rdev);
  146.         /* DDR for all card after R300 & IGP */
  147.         rdev->mc.vram_is_ddr = true;
  148.         /* FIXME: is this correct for RS690/RS740 ? */
  149.         tmp = RREG32(RADEON_MEM_CNTL);
  150.         if (tmp & R300_MEM_NUM_CHANNELS_MASK) {
  151.                 rdev->mc.vram_width = 128;
  152.         } else {
  153.                 rdev->mc.vram_width = 64;
  154.         }
  155.         rdev->mc.vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
  156.  
  157.         rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
  158.         rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
  159. }
  160.  
  161.  
  162. /*
  163.  * Indirect registers accessor
  164.  */
  165. uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
  166. {
  167.         uint32_t r;
  168.  
  169.         WREG32(RS690_MC_INDEX, (reg & RS690_MC_INDEX_MASK));
  170.         r = RREG32(RS690_MC_DATA);
  171.         WREG32(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
  172.         return r;
  173. }
  174.  
  175. void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
  176. {
  177.         WREG32(RS690_MC_INDEX,
  178.                RS690_MC_INDEX_WR_EN | ((reg) & RS690_MC_INDEX_MASK));
  179.         WREG32(RS690_MC_DATA, v);
  180.         WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
  181. }
  182.