Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mgag200_main.c
Go to the documentation of this file.
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 
17 static void mga_user_framebuffer_destroy(struct drm_framebuffer *fb)
18 {
19  struct mga_framebuffer *mga_fb = to_mga_framebuffer(fb);
20  if (mga_fb->obj)
21  drm_gem_object_unreference_unlocked(mga_fb->obj);
23  kfree(fb);
24 }
25 
26 static int mga_user_framebuffer_create_handle(struct drm_framebuffer *fb,
27  struct drm_file *file_priv,
28  unsigned int *handle)
29 {
30  return 0;
31 }
32 
33 static const struct drm_framebuffer_funcs mga_fb_funcs = {
34  .destroy = mga_user_framebuffer_destroy,
35  .create_handle = mga_user_framebuffer_create_handle,
36 };
37 
39  struct mga_framebuffer *gfb,
40  struct drm_mode_fb_cmd2 *mode_cmd,
41  struct drm_gem_object *obj)
42 {
43  int ret = drm_framebuffer_init(dev, &gfb->base, &mga_fb_funcs);
44  if (ret) {
45  DRM_ERROR("drm_framebuffer_init failed: %d\n", ret);
46  return ret;
47  }
48  drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
49  gfb->obj = obj;
50  return 0;
51 }
52 
53 static struct drm_framebuffer *
54 mgag200_user_framebuffer_create(struct drm_device *dev,
55  struct drm_file *filp,
56  struct drm_mode_fb_cmd2 *mode_cmd)
57 {
58  struct drm_gem_object *obj;
59  struct mga_framebuffer *mga_fb;
60  int ret;
61 
62  obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
63  if (obj == NULL)
64  return ERR_PTR(-ENOENT);
65 
66  mga_fb = kzalloc(sizeof(*mga_fb), GFP_KERNEL);
67  if (!mga_fb) {
68  drm_gem_object_unreference_unlocked(obj);
69  return ERR_PTR(-ENOMEM);
70  }
71 
72  ret = mgag200_framebuffer_init(dev, mga_fb, mode_cmd, obj);
73  if (ret) {
74  drm_gem_object_unreference_unlocked(obj);
75  kfree(mga_fb);
76  return ERR_PTR(ret);
77  }
78  return &mga_fb->base;
79 }
80 
81 static const struct drm_mode_config_funcs mga_mode_funcs = {
82  .fb_create = mgag200_user_framebuffer_create,
83 };
84 
85 /* Unmap the framebuffer from the core and release the memory */
86 static void mga_vram_fini(struct mga_device *mdev)
87 {
88  pci_iounmap(mdev->dev->pdev, mdev->rmmio);
89  mdev->rmmio = NULL;
90  if (mdev->mc.vram_base)
91  release_mem_region(mdev->mc.vram_base, mdev->mc.vram_window);
92 }
93 
94 static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem)
95 {
96  int offset;
97  int orig;
98  int test1, test2;
99  int orig1, orig2;
100 
101  /* Probe */
102  orig = ioread16(mem);
103  iowrite16(0, mem);
104 
105  for (offset = 0x100000; offset < mdev->mc.vram_window; offset += 0x4000) {
106  orig1 = ioread8(mem + offset);
107  orig2 = ioread8(mem + offset + 0x100);
108 
109  iowrite16(0xaa55, mem + offset);
110  iowrite16(0xaa55, mem + offset + 0x100);
111 
112  test1 = ioread16(mem + offset);
113  test2 = ioread16(mem);
114 
115  iowrite16(orig1, mem + offset);
116  iowrite16(orig2, mem + offset + 0x100);
117 
118  if (test1 != 0xaa55) {
119  break;
120  }
121 
122  if (test2) {
123  break;
124  }
125  }
126 
127  iowrite16(orig, mem);
128  return offset - 65536;
129 }
130 
131 /* Map the framebuffer from the card and configure the core */
132 static int mga_vram_init(struct mga_device *mdev)
133 {
134  void __iomem *mem;
135  struct apertures_struct *aper = alloc_apertures(1);
136 
137  /* BAR 0 is VRAM */
138  mdev->mc.vram_base = pci_resource_start(mdev->dev->pdev, 0);
139  mdev->mc.vram_window = pci_resource_len(mdev->dev->pdev, 0);
140 
141  aper->ranges[0].base = mdev->mc.vram_base;
142  aper->ranges[0].size = mdev->mc.vram_window;
143  aper->count = 1;
144 
145  remove_conflicting_framebuffers(aper, "mgafb", true);
146 
147  if (!request_mem_region(mdev->mc.vram_base, mdev->mc.vram_window,
148  "mgadrmfb_vram")) {
149  DRM_ERROR("can't reserve VRAM\n");
150  return -ENXIO;
151  }
152 
153  mem = pci_iomap(mdev->dev->pdev, 0, 0);
154 
155  mdev->mc.vram_size = mga_probe_vram(mdev, mem);
156 
157  pci_iounmap(mdev->dev->pdev, mem);
158 
159  return 0;
160 }
161 
162 static int mgag200_device_init(struct drm_device *dev,
163  uint32_t flags)
164 {
165  struct mga_device *mdev = dev->dev_private;
166  int ret, option;
167 
168  mdev->type = flags;
169 
170  /* Hardcode the number of CRTCs to 1 */
171  mdev->num_crtc = 1;
172 
173  pci_read_config_dword(dev->pdev, PCI_MGA_OPTION, &option);
174  mdev->has_sdram = !(option & (1 << 14));
175 
176  /* BAR 0 is the framebuffer, BAR 1 contains registers */
177  mdev->rmmio_base = pci_resource_start(mdev->dev->pdev, 1);
178  mdev->rmmio_size = pci_resource_len(mdev->dev->pdev, 1);
179 
180  if (!request_mem_region(mdev->rmmio_base, mdev->rmmio_size,
181  "mgadrmfb_mmio")) {
182  DRM_ERROR("can't reserve mmio registers\n");
183  return -ENOMEM;
184  }
185 
186  mdev->rmmio = pci_iomap(dev->pdev, 1, 0);
187  if (mdev->rmmio == NULL)
188  return -ENOMEM;
189 
190  /* stash G200 SE model number for later use */
191  if (IS_G200_SE(mdev))
192  mdev->reg_1e24 = RREG32(0x1e24);
193 
194  ret = mga_vram_init(mdev);
195  if (ret) {
197  return ret;
198  }
199 
200  mdev->bpp_shifts[0] = 0;
201  mdev->bpp_shifts[1] = 1;
202  mdev->bpp_shifts[2] = 0;
203  mdev->bpp_shifts[3] = 2;
204  return 0;
205 }
206 
207 void mgag200_device_fini(struct mga_device *mdev)
208 {
210  mga_vram_fini(mdev);
211 }
212 
213 /*
214  * Functions here will be called by the core once it's bound the driver to
215  * a PCI device
216  */
217 
218 
219 int mgag200_driver_load(struct drm_device *dev, unsigned long flags)
220 {
221  struct mga_device *mdev;
222  int r;
223 
224  mdev = kzalloc(sizeof(struct mga_device), GFP_KERNEL);
225  if (mdev == NULL)
226  return -ENOMEM;
227  dev->dev_private = (void *)mdev;
228  mdev->dev = dev;
229 
230  r = mgag200_device_init(dev, flags);
231  if (r) {
232  dev_err(&dev->pdev->dev, "Fatal error during GPU init: %d\n", r);
233  goto out;
234  }
235  r = mgag200_mm_init(mdev);
236  if (r)
237  goto out;
238 
240  dev->mode_config.funcs = (void *)&mga_mode_funcs;
241  dev->mode_config.min_width = 0;
242  dev->mode_config.min_height = 0;
243  dev->mode_config.preferred_depth = 24;
244  dev->mode_config.prefer_shadow = 1;
245 
246  r = mgag200_modeset_init(mdev);
247  if (r)
248  dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);
249 out:
250  if (r)
252  return r;
253 }
254 
256 {
257  struct mga_device *mdev = dev->dev_private;
258 
259  if (mdev == NULL)
260  return 0;
261  mgag200_modeset_fini(mdev);
262  mgag200_fbdev_fini(mdev);
264  mgag200_mm_fini(mdev);
265  mgag200_device_fini(mdev);
266  kfree(mdev);
267  dev->dev_private = NULL;
268  return 0;
269 }
270 
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 
294 int 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_unreference_unlocked(gobj);
312  if (ret)
313  return ret;
314 
315  args->handle = handle;
316  return 0;
317 }
318 
319 int mgag200_dumb_destroy(struct drm_file *file,
320  struct drm_device *dev,
322 {
323  return drm_gem_handle_delete(file, handle);
324 }
325 
326 int mgag200_gem_init_object(struct drm_gem_object *obj)
327 {
328  BUG();
329  return 0;
330 }
331 
332 void mgag200_bo_unref(struct mgag200_bo **bo)
333 {
334  struct ttm_buffer_object *tbo;
335 
336  if ((*bo) == NULL)
337  return;
338 
339  tbo = &((*bo)->bo);
340  ttm_bo_unref(&tbo);
341  if (tbo == NULL)
342  *bo = NULL;
343 
344 }
345 
346 void mgag200_gem_free_object(struct drm_gem_object *obj)
347 {
348  struct mgag200_bo *mgag200_bo = gem_to_mga_bo(obj);
349 
350  if (!mgag200_bo)
351  return;
352  mgag200_bo_unref(&mgag200_bo);
353 }
354 
355 
356 static inline u64 mgag200_bo_mmap_offset(struct mgag200_bo *bo)
357 {
358  return bo->bo.addr_space_offset;
359 }
360 
361 int
363  struct drm_device *dev,
365  uint64_t *offset)
366 {
367  struct drm_gem_object *obj;
368  int ret;
369  struct mgag200_bo *bo;
370 
371  mutex_lock(&dev->struct_mutex);
372  obj = drm_gem_object_lookup(dev, file, handle);
373  if (obj == NULL) {
374  ret = -ENOENT;
375  goto out_unlock;
376  }
377 
378  bo = gem_to_mga_bo(obj);
379  *offset = mgag200_bo_mmap_offset(bo);
380 
381  drm_gem_object_unreference(obj);
382  ret = 0;
383 out_unlock:
384  mutex_unlock(&dev->struct_mutex);
385  return ret;
386 
387 }