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. /* rs600 depends on : */
  33. void r100_hdp_reset(struct radeon_device *rdev);
  34. int r100_gui_wait_for_idle(struct radeon_device *rdev);
  35. int r300_mc_wait_for_idle(struct radeon_device *rdev);
  36. void r420_pipes_init(struct radeon_device *rdev);
  37.  
  38. /* This files gather functions specifics to :
  39.  * rs600
  40.  *
  41.  * Some of these functions might be used by newer ASICs.
  42.  */
  43. void rs600_gpu_init(struct radeon_device *rdev);
  44. int rs600_mc_wait_for_idle(struct radeon_device *rdev);
  45. void rs600_disable_vga(struct radeon_device *rdev);
  46.  
  47.  
  48. /*
  49.  * GART.
  50.  */
  51. void rs600_gart_tlb_flush(struct radeon_device *rdev)
  52. {
  53.         uint32_t tmp;
  54.  
  55.         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
  56.         tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
  57.         WREG32_MC(RS600_MC_PT0_CNTL, tmp);
  58.  
  59.         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
  60.         tmp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE;
  61.         WREG32_MC(RS600_MC_PT0_CNTL, tmp);
  62.  
  63.         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
  64.         tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
  65.         WREG32_MC(RS600_MC_PT0_CNTL, tmp);
  66.         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
  67. }
  68.  
  69. int rs600_gart_enable(struct radeon_device *rdev)
  70. {
  71.         uint32_t tmp;
  72.         int i;
  73.         int r;
  74.  
  75.         /* Initialize common gart structure */
  76.         r = radeon_gart_init(rdev);
  77.         if (r) {
  78.                 return r;
  79.         }
  80.         rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
  81.         r = radeon_gart_table_vram_alloc(rdev);
  82.         if (r) {
  83.                 return r;
  84.         }
  85.         /* FIXME: setup default page */
  86.         WREG32_MC(RS600_MC_PT0_CNTL,
  87.                  (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
  88.                   RS600_EFFECTIVE_L2_QUEUE_SIZE(6)));
  89.         for (i = 0; i < 19; i++) {
  90.                 WREG32_MC(RS600_MC_PT0_CLIENT0_CNTL + i,
  91.                          (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE |
  92.                           RS600_SYSTEM_ACCESS_MODE_IN_SYS |
  93.                           RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE |
  94.                           RS600_EFFECTIVE_L1_CACHE_SIZE(3) |
  95.                           RS600_ENABLE_FRAGMENT_PROCESSING |
  96.                           RS600_EFFECTIVE_L1_QUEUE_SIZE(3)));
  97.         }
  98.  
  99.         /* System context map to GART space */
  100.         WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_location);
  101.         tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
  102.         WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, tmp);
  103.  
  104.         /* enable first context */
  105.         WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_location);
  106.         tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
  107.         WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, tmp);
  108.         WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL,
  109.                  (RS600_ENABLE_PAGE_TABLE | RS600_PAGE_TABLE_TYPE_FLAT));
  110.         /* disable all other contexts */
  111.         for (i = 1; i < 8; i++) {
  112.                 WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL + i, 0);
  113.         }
  114.  
  115.         /* setup the page table */
  116.         WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
  117.                  rdev->gart.table_addr);
  118.         WREG32_MC(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
  119.  
  120.         /* enable page tables */
  121.         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
  122.         WREG32_MC(RS600_MC_PT0_CNTL, (tmp | RS600_ENABLE_PT));
  123.         tmp = RREG32_MC(RS600_MC_CNTL1);
  124.         WREG32_MC(RS600_MC_CNTL1, (tmp | RS600_ENABLE_PAGE_TABLES));
  125.         rs600_gart_tlb_flush(rdev);
  126.         rdev->gart.ready = true;
  127.         return 0;
  128. }
  129.  
  130. void rs600_gart_disable(struct radeon_device *rdev)
  131. {
  132.         uint32_t tmp;
  133.  
  134.         /* FIXME: disable out of gart access */
  135.         WREG32_MC(RS600_MC_PT0_CNTL, 0);
  136.         tmp = RREG32_MC(RS600_MC_CNTL1);
  137.         tmp &= ~RS600_ENABLE_PAGE_TABLES;
  138.         WREG32_MC(RS600_MC_CNTL1, tmp);
  139. //   radeon_object_kunmap(rdev->gart.table.vram.robj);
  140. //   radeon_object_unpin(rdev->gart.table.vram.robj);
  141. }
  142.  
  143. #define R600_PTE_VALID     (1 << 0)
  144. #define R600_PTE_SYSTEM    (1 << 1)
  145. #define R600_PTE_SNOOPED   (1 << 2)
  146. #define R600_PTE_READABLE  (1 << 5)
  147. #define R600_PTE_WRITEABLE (1 << 6)
  148.  
  149. int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
  150. {
  151.         void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
  152.  
  153.         if (i < 0 || i > rdev->gart.num_gpu_pages) {
  154.                 return -EINVAL;
  155.         }
  156.         addr = addr & 0xFFFFFFFFFFFFF000ULL;
  157.         addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
  158.         addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
  159.         writeq(addr, ((void __iomem *)ptr) + (i * 8));
  160.         return 0;
  161. }
  162.  
  163.  
  164. /*
  165.  * MC.
  166.  */
  167. void rs600_mc_disable_clients(struct radeon_device *rdev)
  168. {
  169.         unsigned tmp;
  170.  
  171.         if (r100_gui_wait_for_idle(rdev)) {
  172.                 printk(KERN_WARNING "Failed to wait GUI idle while "
  173.                        "programming pipes. Bad things might happen.\n");
  174.         }
  175.  
  176.         tmp = RREG32(AVIVO_D1VGA_CONTROL);
  177.         WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
  178.         tmp = RREG32(AVIVO_D2VGA_CONTROL);
  179.         WREG32(AVIVO_D2VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
  180.  
  181.         tmp = RREG32(AVIVO_D1CRTC_CONTROL);
  182.         WREG32(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
  183.         tmp = RREG32(AVIVO_D2CRTC_CONTROL);
  184.         WREG32(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
  185.  
  186.         /* make sure all previous write got through */
  187.         tmp = RREG32(AVIVO_D2CRTC_CONTROL);
  188.  
  189.         mdelay(1);
  190. }
  191.  
  192. int rs600_mc_init(struct radeon_device *rdev)
  193. {
  194.         uint32_t tmp;
  195.         int r;
  196.  
  197.         if (r100_debugfs_rbbm_init(rdev)) {
  198.                 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
  199.         }
  200.  
  201.         rs600_gpu_init(rdev);
  202.         rs600_gart_disable(rdev);
  203.  
  204.         /* Setup GPU memory space */
  205.         rdev->mc.vram_location = 0xFFFFFFFFUL;
  206.         rdev->mc.gtt_location = 0xFFFFFFFFUL;
  207.         r = radeon_mc_setup(rdev);
  208.         if (r) {
  209.                 return r;
  210.         }
  211.  
  212.         /* Program GPU memory space */
  213.         /* Enable bus master */
  214.         tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
  215.         WREG32(RADEON_BUS_CNTL, tmp);
  216.         /* FIXME: What does AGP means for such chipset ? */
  217.         WREG32_MC(RS600_MC_AGP_LOCATION, 0x0FFFFFFF);
  218.         /* FIXME: are this AGP reg in indirect MC range ? */
  219.         WREG32_MC(RS600_MC_AGP_BASE, 0);
  220.         WREG32_MC(RS600_MC_AGP_BASE_2, 0);
  221.         rs600_mc_disable_clients(rdev);
  222.         if (rs600_mc_wait_for_idle(rdev)) {
  223.                 printk(KERN_WARNING "Failed to wait MC idle while "
  224.                        "programming pipes. Bad things might happen.\n");
  225.         }
  226.         tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1;
  227.         tmp = REG_SET(RS600_MC_FB_TOP, tmp >> 16);
  228.         tmp |= REG_SET(RS600_MC_FB_START, rdev->mc.vram_location >> 16);
  229.         WREG32_MC(RS600_MC_FB_LOCATION, tmp);
  230.         WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
  231.         return 0;
  232. }
  233.  
  234. void rs600_mc_fini(struct radeon_device *rdev)
  235. {
  236.         rs600_gart_disable(rdev);
  237.         radeon_gart_table_vram_free(rdev);
  238.         radeon_gart_fini(rdev);
  239. }
  240.  
  241.  
  242. /*
  243.  * Global GPU functions
  244.  */
  245. void rs600_disable_vga(struct radeon_device *rdev)
  246. {
  247.         unsigned tmp;
  248.  
  249.         WREG32(0x330, 0);
  250.         WREG32(0x338, 0);
  251.         tmp = RREG32(0x300);
  252.         tmp &= ~(3 << 16);
  253.         WREG32(0x300, tmp);
  254.         WREG32(0x308, (1 << 8));
  255.         WREG32(0x310, rdev->mc.vram_location);
  256.         WREG32(0x594, 0);
  257. }
  258.  
  259. int rs600_mc_wait_for_idle(struct radeon_device *rdev)
  260. {
  261.         unsigned i;
  262.         uint32_t tmp;
  263.  
  264.         for (i = 0; i < rdev->usec_timeout; i++) {
  265.                 /* read MC_STATUS */
  266.                 tmp = RREG32_MC(RS600_MC_STATUS);
  267.                 if (tmp & RS600_MC_STATUS_IDLE) {
  268.                         return 0;
  269.                 }
  270.                 DRM_UDELAY(1);
  271.         }
  272.         return -1;
  273. }
  274.  
  275. void rs600_errata(struct radeon_device *rdev)
  276. {
  277.         rdev->pll_errata = 0;
  278. }
  279.  
  280. void rs600_gpu_init(struct radeon_device *rdev)
  281. {
  282.         /* FIXME: HDP same place on rs600 ? */
  283.         r100_hdp_reset(rdev);
  284.         rs600_disable_vga(rdev);
  285.         /* FIXME: is this correct ? */
  286.         r420_pipes_init(rdev);
  287.         if (rs600_mc_wait_for_idle(rdev)) {
  288.                 printk(KERN_WARNING "Failed to wait MC idle while "
  289.                        "programming pipes. Bad things might happen.\n");
  290.         }
  291. }
  292.  
  293.  
  294. /*
  295.  * VRAM info.
  296.  */
  297. void rs600_vram_info(struct radeon_device *rdev)
  298. {
  299.         /* FIXME: to do or is these values sane ? */
  300.         rdev->mc.vram_is_ddr = true;
  301.         rdev->mc.vram_width = 128;
  302. }
  303.  
  304.  
  305. /*
  306.  * Indirect registers accessor
  307.  */
  308. uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg)
  309. {
  310.         uint32_t r;
  311.  
  312.         WREG32(RS600_MC_INDEX,
  313.                ((reg & RS600_MC_ADDR_MASK) | RS600_MC_IND_CITF_ARB0));
  314.         r = RREG32(RS600_MC_DATA);
  315.         return r;
  316. }
  317.  
  318. void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
  319. {
  320.         WREG32(RS600_MC_INDEX,
  321.                 RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 |
  322.                 ((reg) & RS600_MC_ADDR_MASK));
  323.         WREG32(RS600_MC_DATA, v);
  324. }
  325.