Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.0-rc8 362 lines 8.2 kB view raw
1/* 2 * Copyright 2010 Matt Turner. 3 * Copyright 2012 Red Hat 4 * 5 * This file is subject to the terms and conditions of the GNU General 6 * Public License version 2. See the file COPYING in the main 7 * directory of this archive for more details. 8 * 9 * Authors: Matthew Garrett 10 * Matt Turner 11 * Dave Airlie 12 */ 13#include <drm/drmP.h> 14#include <drm/drm_crtc_helper.h> 15#include "mgag200_drv.h" 16 17static void mga_user_framebuffer_destroy(struct drm_framebuffer *fb) 18{ 19 struct mga_framebuffer *mga_fb = to_mga_framebuffer(fb); 20 21 drm_gem_object_put_unlocked(mga_fb->obj); 22 drm_framebuffer_cleanup(fb); 23 kfree(fb); 24} 25 26static const struct drm_framebuffer_funcs mga_fb_funcs = { 27 .destroy = mga_user_framebuffer_destroy, 28}; 29 30int mgag200_framebuffer_init(struct drm_device *dev, 31 struct mga_framebuffer *gfb, 32 const struct drm_mode_fb_cmd2 *mode_cmd, 33 struct drm_gem_object *obj) 34{ 35 int ret; 36 37 drm_helper_mode_fill_fb_struct(dev, &gfb->base, mode_cmd); 38 gfb->obj = obj; 39 ret = drm_framebuffer_init(dev, &gfb->base, &mga_fb_funcs); 40 if (ret) { 41 DRM_ERROR("drm_framebuffer_init failed: %d\n", ret); 42 return ret; 43 } 44 return 0; 45} 46 47static struct drm_framebuffer * 48mgag200_user_framebuffer_create(struct drm_device *dev, 49 struct drm_file *filp, 50 const struct drm_mode_fb_cmd2 *mode_cmd) 51{ 52 struct drm_gem_object *obj; 53 struct mga_framebuffer *mga_fb; 54 int ret; 55 56 obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); 57 if (obj == NULL) 58 return ERR_PTR(-ENOENT); 59 60 mga_fb = kzalloc(sizeof(*mga_fb), GFP_KERNEL); 61 if (!mga_fb) { 62 drm_gem_object_put_unlocked(obj); 63 return ERR_PTR(-ENOMEM); 64 } 65 66 ret = mgag200_framebuffer_init(dev, mga_fb, mode_cmd, obj); 67 if (ret) { 68 drm_gem_object_put_unlocked(obj); 69 kfree(mga_fb); 70 return ERR_PTR(ret); 71 } 72 return &mga_fb->base; 73} 74 75static const struct drm_mode_config_funcs mga_mode_funcs = { 76 .fb_create = mgag200_user_framebuffer_create, 77}; 78 79static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem) 80{ 81 int offset; 82 int orig; 83 int test1, test2; 84 int orig1, orig2; 85 unsigned int vram_size; 86 87 /* Probe */ 88 orig = ioread16(mem); 89 iowrite16(0, mem); 90 91 vram_size = mdev->mc.vram_window; 92 93 if ((mdev->type == G200_EW3) && (vram_size >= 0x1000000)) { 94 vram_size = vram_size - 0x400000; 95 } 96 97 for (offset = 0x100000; offset < vram_size; offset += 0x4000) { 98 orig1 = ioread8(mem + offset); 99 orig2 = ioread8(mem + offset + 0x100); 100 101 iowrite16(0xaa55, mem + offset); 102 iowrite16(0xaa55, mem + offset + 0x100); 103 104 test1 = ioread16(mem + offset); 105 test2 = ioread16(mem); 106 107 iowrite16(orig1, mem + offset); 108 iowrite16(orig2, mem + offset + 0x100); 109 110 if (test1 != 0xaa55) { 111 break; 112 } 113 114 if (test2) { 115 break; 116 } 117 } 118 119 iowrite16(orig, mem); 120 return offset - 65536; 121} 122 123/* Map the framebuffer from the card and configure the core */ 124static int mga_vram_init(struct mga_device *mdev) 125{ 126 void __iomem *mem; 127 128 /* BAR 0 is VRAM */ 129 mdev->mc.vram_base = pci_resource_start(mdev->dev->pdev, 0); 130 mdev->mc.vram_window = pci_resource_len(mdev->dev->pdev, 0); 131 132 if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window, 133 "mgadrmfb_vram")) { 134 DRM_ERROR("can't reserve VRAM\n"); 135 return -ENXIO; 136 } 137 138 mem = pci_iomap(mdev->dev->pdev, 0, 0); 139 if (!mem) 140 return -ENOMEM; 141 142 mdev->mc.vram_size = mga_probe_vram(mdev, mem); 143 144 pci_iounmap(mdev->dev->pdev, mem); 145 146 return 0; 147} 148 149static int mgag200_device_init(struct drm_device *dev, 150 uint32_t flags) 151{ 152 struct mga_device *mdev = dev->dev_private; 153 int ret, option; 154 155 mdev->type = flags; 156 157 /* Hardcode the number of CRTCs to 1 */ 158 mdev->num_crtc = 1; 159 160 pci_read_config_dword(dev->pdev, PCI_MGA_OPTION, &option); 161 mdev->has_sdram = !(option & (1 << 14)); 162 163 /* BAR 0 is the framebuffer, BAR 1 contains registers */ 164 mdev->rmmio_base = pci_resource_start(mdev->dev->pdev, 1); 165 mdev->rmmio_size = pci_resource_len(mdev->dev->pdev, 1); 166 167 if (!devm_request_mem_region(mdev->dev->dev, mdev->rmmio_base, mdev->rmmio_size, 168 "mgadrmfb_mmio")) { 169 DRM_ERROR("can't reserve mmio registers\n"); 170 return -ENOMEM; 171 } 172 173 mdev->rmmio = pcim_iomap(dev->pdev, 1, 0); 174 if (mdev->rmmio == NULL) 175 return -ENOMEM; 176 177 /* stash G200 SE model number for later use */ 178 if (IS_G200_SE(mdev)) 179 mdev->unique_rev_id = RREG32(0x1e24); 180 181 ret = mga_vram_init(mdev); 182 if (ret) 183 return ret; 184 185 mdev->bpp_shifts[0] = 0; 186 mdev->bpp_shifts[1] = 1; 187 mdev->bpp_shifts[2] = 0; 188 mdev->bpp_shifts[3] = 2; 189 return 0; 190} 191 192/* 193 * Functions here will be called by the core once it's bound the driver to 194 * a PCI device 195 */ 196 197 198int mgag200_driver_load(struct drm_device *dev, unsigned long flags) 199{ 200 struct mga_device *mdev; 201 int r; 202 203 mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); 204 if (mdev == NULL) 205 return -ENOMEM; 206 dev->dev_private = (void *)mdev; 207 mdev->dev = dev; 208 209 r = mgag200_device_init(dev, flags); 210 if (r) { 211 dev_err(&dev->pdev->dev, "Fatal error during GPU init: %d\n", r); 212 return r; 213 } 214 r = mgag200_mm_init(mdev); 215 if (r) 216 goto err_mm; 217 218 drm_mode_config_init(dev); 219 dev->mode_config.funcs = (void *)&mga_mode_funcs; 220 if (IS_G200_SE(mdev) && mdev->mc.vram_size < (2048*1024)) 221 dev->mode_config.preferred_depth = 16; 222 else 223 dev->mode_config.preferred_depth = 24; 224 dev->mode_config.prefer_shadow = 1; 225 226 r = mgag200_modeset_init(mdev); 227 if (r) { 228 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r); 229 goto err_modeset; 230 } 231 232 /* Make small buffers to store a hardware cursor (double buffered icon updates) */ 233 mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0, 234 &mdev->cursor.pixels_1); 235 mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0, 236 &mdev->cursor.pixels_2); 237 if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1) { 238 mdev->cursor.pixels_1 = NULL; 239 mdev->cursor.pixels_2 = NULL; 240 dev_warn(&dev->pdev->dev, 241 "Could not allocate space for cursors. Not doing hardware cursors.\n"); 242 } else { 243 mdev->cursor.pixels_current = mdev->cursor.pixels_1; 244 mdev->cursor.pixels_prev = mdev->cursor.pixels_2; 245 } 246 247 return 0; 248 249err_modeset: 250 drm_mode_config_cleanup(dev); 251 mgag200_mm_fini(mdev); 252err_mm: 253 dev->dev_private = NULL; 254 255 return r; 256} 257 258void mgag200_driver_unload(struct drm_device *dev) 259{ 260 struct mga_device *mdev = dev->dev_private; 261 262 if (mdev == NULL) 263 return; 264 mgag200_modeset_fini(mdev); 265 mgag200_fbdev_fini(mdev); 266 drm_mode_config_cleanup(dev); 267 mgag200_mm_fini(mdev); 268 dev->dev_private = NULL; 269} 270 271int mgag200_gem_create(struct drm_device *dev, 272 u32 size, bool iskernel, 273 struct drm_gem_object **obj) 274{ 275 struct mgag200_bo *astbo; 276 int ret; 277 278 *obj = NULL; 279 280 size = roundup(size, PAGE_SIZE); 281 if (size == 0) 282 return -EINVAL; 283 284 ret = mgag200_bo_create(dev, size, 0, 0, &astbo); 285 if (ret) { 286 if (ret != -ERESTARTSYS) 287 DRM_ERROR("failed to allocate GEM object\n"); 288 return ret; 289 } 290 *obj = &astbo->gem; 291 return 0; 292} 293 294int mgag200_dumb_create(struct drm_file *file, 295 struct drm_device *dev, 296 struct drm_mode_create_dumb *args) 297{ 298 int ret; 299 struct drm_gem_object *gobj; 300 u32 handle; 301 302 args->pitch = args->width * ((args->bpp + 7) / 8); 303 args->size = args->pitch * args->height; 304 305 ret = mgag200_gem_create(dev, args->size, false, 306 &gobj); 307 if (ret) 308 return ret; 309 310 ret = drm_gem_handle_create(file, gobj, &handle); 311 drm_gem_object_put_unlocked(gobj); 312 if (ret) 313 return ret; 314 315 args->handle = handle; 316 return 0; 317} 318 319static void mgag200_bo_unref(struct mgag200_bo **bo) 320{ 321 struct ttm_buffer_object *tbo; 322 323 if ((*bo) == NULL) 324 return; 325 326 tbo = &((*bo)->bo); 327 ttm_bo_unref(&tbo); 328 *bo = NULL; 329} 330 331void mgag200_gem_free_object(struct drm_gem_object *obj) 332{ 333 struct mgag200_bo *mgag200_bo = gem_to_mga_bo(obj); 334 335 mgag200_bo_unref(&mgag200_bo); 336} 337 338 339static inline u64 mgag200_bo_mmap_offset(struct mgag200_bo *bo) 340{ 341 return drm_vma_node_offset_addr(&bo->bo.vma_node); 342} 343 344int 345mgag200_dumb_mmap_offset(struct drm_file *file, 346 struct drm_device *dev, 347 uint32_t handle, 348 uint64_t *offset) 349{ 350 struct drm_gem_object *obj; 351 struct mgag200_bo *bo; 352 353 obj = drm_gem_object_lookup(file, handle); 354 if (obj == NULL) 355 return -ENOENT; 356 357 bo = gem_to_mga_bo(obj); 358 *offset = mgag200_bo_mmap_offset(bo); 359 360 drm_gem_object_put_unlocked(obj); 361 return 0; 362}