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