root/drivers/gpu/drm/mgag200/mgag200_main.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mga_probe_vram
  2. mga_vram_init
  3. mgag200_device_init
  4. mgag200_driver_load
  5. mgag200_driver_unload

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright 2010 Matt Turner.
   4  * Copyright 2012 Red Hat
   5  *
   6  * Authors: Matthew Garrett
   7  *          Matt Turner
   8  *          Dave Airlie
   9  */
  10 
  11 #include <drm/drm_crtc_helper.h>
  12 #include <drm/drm_gem_framebuffer_helper.h>
  13 #include <drm/drm_pci.h>
  14 
  15 #include "mgag200_drv.h"
  16 
  17 static const struct drm_mode_config_funcs mga_mode_funcs = {
  18         .fb_create = drm_gem_fb_create
  19 };
  20 
  21 static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem)
  22 {
  23         int offset;
  24         int orig;
  25         int test1, test2;
  26         int orig1, orig2;
  27         unsigned int vram_size;
  28 
  29         /* Probe */
  30         orig = ioread16(mem);
  31         iowrite16(0, mem);
  32 
  33         vram_size = mdev->mc.vram_window;
  34 
  35         if ((mdev->type == G200_EW3) && (vram_size >= 0x1000000)) {
  36                 vram_size = vram_size - 0x400000;
  37         }
  38 
  39         for (offset = 0x100000; offset < vram_size; offset += 0x4000) {
  40                 orig1 = ioread8(mem + offset);
  41                 orig2 = ioread8(mem + offset + 0x100);
  42 
  43                 iowrite16(0xaa55, mem + offset);
  44                 iowrite16(0xaa55, mem + offset + 0x100);
  45 
  46                 test1 = ioread16(mem + offset);
  47                 test2 = ioread16(mem);
  48 
  49                 iowrite16(orig1, mem + offset);
  50                 iowrite16(orig2, mem + offset + 0x100);
  51 
  52                 if (test1 != 0xaa55) {
  53                         break;
  54                 }
  55 
  56                 if (test2) {
  57                         break;
  58                 }
  59         }
  60 
  61         iowrite16(orig, mem);
  62         return offset - 65536;
  63 }
  64 
  65 /* Map the framebuffer from the card and configure the core */
  66 static int mga_vram_init(struct mga_device *mdev)
  67 {
  68         void __iomem *mem;
  69 
  70         /* BAR 0 is VRAM */
  71         mdev->mc.vram_base = pci_resource_start(mdev->dev->pdev, 0);
  72         mdev->mc.vram_window = pci_resource_len(mdev->dev->pdev, 0);
  73 
  74         if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window,
  75                                 "mgadrmfb_vram")) {
  76                 DRM_ERROR("can't reserve VRAM\n");
  77                 return -ENXIO;
  78         }
  79 
  80         mem = pci_iomap(mdev->dev->pdev, 0, 0);
  81         if (!mem)
  82                 return -ENOMEM;
  83 
  84         mdev->mc.vram_size = mga_probe_vram(mdev, mem);
  85 
  86         pci_iounmap(mdev->dev->pdev, mem);
  87 
  88         return 0;
  89 }
  90 
  91 static int mgag200_device_init(struct drm_device *dev,
  92                                uint32_t flags)
  93 {
  94         struct mga_device *mdev = dev->dev_private;
  95         int ret, option;
  96 
  97         mdev->flags = mgag200_flags_from_driver_data(flags);
  98         mdev->type = mgag200_type_from_driver_data(flags);
  99 
 100         /* Hardcode the number of CRTCs to 1 */
 101         mdev->num_crtc = 1;
 102 
 103         pci_read_config_dword(dev->pdev, PCI_MGA_OPTION, &option);
 104         mdev->has_sdram = !(option & (1 << 14));
 105 
 106         /* BAR 0 is the framebuffer, BAR 1 contains registers */
 107         mdev->rmmio_base = pci_resource_start(mdev->dev->pdev, 1);
 108         mdev->rmmio_size = pci_resource_len(mdev->dev->pdev, 1);
 109 
 110         if (!devm_request_mem_region(mdev->dev->dev, mdev->rmmio_base, mdev->rmmio_size,
 111                                 "mgadrmfb_mmio")) {
 112                 DRM_ERROR("can't reserve mmio registers\n");
 113                 return -ENOMEM;
 114         }
 115 
 116         mdev->rmmio = pcim_iomap(dev->pdev, 1, 0);
 117         if (mdev->rmmio == NULL)
 118                 return -ENOMEM;
 119 
 120         /* stash G200 SE model number for later use */
 121         if (IS_G200_SE(mdev))
 122                 mdev->unique_rev_id = RREG32(0x1e24);
 123 
 124         ret = mga_vram_init(mdev);
 125         if (ret)
 126                 return ret;
 127 
 128         mdev->bpp_shifts[0] = 0;
 129         mdev->bpp_shifts[1] = 1;
 130         mdev->bpp_shifts[2] = 0;
 131         mdev->bpp_shifts[3] = 2;
 132         return 0;
 133 }
 134 
 135 /*
 136  * Functions here will be called by the core once it's bound the driver to
 137  * a PCI device
 138  */
 139 
 140 
 141 int mgag200_driver_load(struct drm_device *dev, unsigned long flags)
 142 {
 143         struct mga_device *mdev;
 144         int r;
 145 
 146         mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL);
 147         if (mdev == NULL)
 148                 return -ENOMEM;
 149         dev->dev_private = (void *)mdev;
 150         mdev->dev = dev;
 151 
 152         r = mgag200_device_init(dev, flags);
 153         if (r) {
 154                 dev_err(&dev->pdev->dev, "Fatal error during GPU init: %d\n", r);
 155                 return r;
 156         }
 157         r = mgag200_mm_init(mdev);
 158         if (r)
 159                 goto err_mm;
 160 
 161         drm_mode_config_init(dev);
 162         dev->mode_config.funcs = (void *)&mga_mode_funcs;
 163         if (IS_G200_SE(mdev) && mdev->mc.vram_size < (2048*1024))
 164                 dev->mode_config.preferred_depth = 16;
 165         else
 166                 dev->mode_config.preferred_depth = 32;
 167         dev->mode_config.prefer_shadow = 1;
 168 
 169         r = mgag200_modeset_init(mdev);
 170         if (r) {
 171                 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);
 172                 goto err_modeset;
 173         }
 174 
 175         /* Make small buffers to store a hardware cursor (double buffered icon updates) */
 176         mdev->cursor.pixels_1 = drm_gem_vram_create(dev, &dev->vram_mm->bdev,
 177                                                     roundup(48*64, PAGE_SIZE),
 178                                                     0, 0);
 179         mdev->cursor.pixels_2 = drm_gem_vram_create(dev, &dev->vram_mm->bdev,
 180                                                     roundup(48*64, PAGE_SIZE),
 181                                                     0, 0);
 182         if (IS_ERR(mdev->cursor.pixels_2) || IS_ERR(mdev->cursor.pixels_1)) {
 183                 mdev->cursor.pixels_1 = NULL;
 184                 mdev->cursor.pixels_2 = NULL;
 185                 dev_warn(&dev->pdev->dev,
 186                         "Could not allocate space for cursors. Not doing hardware cursors.\n");
 187         }
 188         mdev->cursor.pixels_current = NULL;
 189 
 190         r = drm_fbdev_generic_setup(mdev->dev, 0);
 191         if (r)
 192                 goto err_modeset;
 193 
 194         return 0;
 195 
 196 err_modeset:
 197         drm_mode_config_cleanup(dev);
 198         mgag200_mm_fini(mdev);
 199 err_mm:
 200         dev->dev_private = NULL;
 201 
 202         return r;
 203 }
 204 
 205 void mgag200_driver_unload(struct drm_device *dev)
 206 {
 207         struct mga_device *mdev = dev->dev_private;
 208 
 209         if (mdev == NULL)
 210                 return;
 211         mgag200_modeset_fini(mdev);
 212         drm_mode_config_cleanup(dev);
 213         mgag200_mm_fini(mdev);
 214         dev->dev_private = NULL;
 215 }

/* [<][>][^][v][top][bottom][index][help] */