linux/drivers/gpu/drm/ast/ast_mm.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012 Red Hat Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the
   6 * "Software"), to deal in the Software without restriction, including
   7 * without limitation the rights to use, copy, modify, merge, publish,
   8 * distribute, sub license, and/or sell copies of the Software, and to
   9 * permit persons to whom the Software is furnished to do so, subject to
  10 * the following conditions:
  11 *
  12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  18 * USE OR OTHER DEALINGS IN THE SOFTWARE.
  19 *
  20 * The above copyright notice and this permission notice (including the
  21 * next paragraph) shall be included in all copies or substantial portions
  22 * of the Software.
  23 *
  24 */
  25/*
  26 * Authors: Dave Airlie <airlied@redhat.com>
  27 */
  28
  29#include <linux/pci.h>
  30
  31#include <drm/drm_gem_vram_helper.h>
  32#include <drm/drm_managed.h>
  33#include <drm/drm_print.h>
  34
  35#include "ast_drv.h"
  36
  37static u32 ast_get_vram_size(struct ast_private *ast)
  38{
  39        u8 jreg;
  40        u32 vram_size;
  41
  42        ast_open_key(ast);
  43
  44        vram_size = AST_VIDMEM_DEFAULT_SIZE;
  45        jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
  46        switch (jreg & 3) {
  47        case 0:
  48                vram_size = AST_VIDMEM_SIZE_8M;
  49                break;
  50        case 1:
  51                vram_size = AST_VIDMEM_SIZE_16M;
  52                break;
  53        case 2:
  54                vram_size = AST_VIDMEM_SIZE_32M;
  55                break;
  56        case 3:
  57                vram_size = AST_VIDMEM_SIZE_64M;
  58                break;
  59        }
  60
  61        jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
  62        switch (jreg & 0x03) {
  63        case 1:
  64                vram_size -= 0x100000;
  65                break;
  66        case 2:
  67                vram_size -= 0x200000;
  68                break;
  69        case 3:
  70                vram_size -= 0x400000;
  71                break;
  72        }
  73
  74        return vram_size;
  75}
  76
  77static void ast_mm_release(struct drm_device *dev, void *ptr)
  78{
  79        struct ast_private *ast = to_ast_private(dev);
  80        struct pci_dev *pdev = to_pci_dev(dev->dev);
  81
  82        arch_phys_wc_del(ast->fb_mtrr);
  83        arch_io_free_memtype_wc(pci_resource_start(pdev, 0),
  84                                pci_resource_len(pdev, 0));
  85}
  86
  87int ast_mm_init(struct ast_private *ast)
  88{
  89        struct drm_device *dev = &ast->base;
  90        struct pci_dev *pdev = to_pci_dev(dev->dev);
  91        u32 vram_size;
  92        int ret;
  93
  94        vram_size = ast_get_vram_size(ast);
  95
  96        ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0), vram_size);
  97        if (ret) {
  98                drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
  99                return ret;
 100        }
 101
 102        arch_io_reserve_memtype_wc(pci_resource_start(pdev, 0),
 103                                   pci_resource_len(pdev, 0));
 104        ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(pdev, 0),
 105                                        pci_resource_len(pdev, 0));
 106
 107        return drmm_add_action_or_reset(dev, ast_mm_release, NULL);
 108}
 109