Fix dynamic command queue allocation
[kernel.git] / drivers / mfd / glamo / glamo-drm-drv.c
1 /* Smedia Glamo 336x/337x Graphics Driver
2  *
3  * Copyright (C) 2009 Openmoko, Inc. Jorge Luis Zapata <turran@openmoko.com>
4  * Copyright (C) 2008-2009 Thomas White <taw@bitwiz.org.uk>
5  * Copyright (C) 2009 Andreas Pokorny <andreas.pokorny@gmail.com>
6  *
7  * All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25
26 #include <linux/module.h>
27 #include <linux/platform_device.h>
28 #include <drm/drmP.h>
29 #include <drm/glamo_drm.h>
30 #include <linux/glamofb.h>
31
32 #include "glamo-core.h"
33 #include "glamo-cmdq.h"
34 #include "glamo-buffer.h"
35 #include "glamo-drm-private.h"
36 #include "glamo-display.h"
37 #include "glamo-kms-fb.h"
38 #include "glamo-fence.h"
39
40 #define DRIVER_AUTHOR           "Openmoko, Inc."
41 #define DRIVER_NAME             "glamo-drm"
42 #define DRIVER_DESC             "SMedia Glamo 3362"
43 #define DRIVER_DATE             "20090614"
44
45
46 static int glamo_ioctl_swap(struct drm_device *dev, void *data,
47                             struct drm_file *file_priv)
48 {
49         printk(KERN_INFO "glamo_ioctl_swap\n");
50         return 0;
51 }
52
53
54 static int glamo_ioctl_gem_info(struct drm_device *dev, void *data,
55                                 struct drm_file *file_priv)
56 {
57         printk(KERN_INFO "glamo_ioctl_gem_info\n");
58         return 0;
59 }
60
61
62 struct drm_ioctl_desc glamo_ioctls[] = {
63         DRM_IOCTL_DEF(DRM_GLAMO_CMDBUF, glamo_ioctl_cmdbuf, DRM_AUTH),
64         DRM_IOCTL_DEF(DRM_GLAMO_SWAP, glamo_ioctl_swap, DRM_AUTH),
65         DRM_IOCTL_DEF(DRM_GLAMO_CMDBURST, glamo_ioctl_cmdburst, DRM_AUTH),
66         DRM_IOCTL_DEF(DRM_GLAMO_GEM_INFO, glamo_ioctl_gem_info, DRM_AUTH),
67         DRM_IOCTL_DEF(DRM_GLAMO_GEM_CREATE, glamo_ioctl_gem_create, DRM_AUTH),
68         DRM_IOCTL_DEF(DRM_GLAMO_GEM_MMAP, glamo_ioctl_gem_mmap, DRM_AUTH),
69         DRM_IOCTL_DEF(DRM_GLAMO_GEM_PIN, glamo_ioctl_gem_pin, DRM_AUTH),
70         DRM_IOCTL_DEF(DRM_GLAMO_GEM_UNPIN, glamo_ioctl_gem_unpin, DRM_AUTH),
71         DRM_IOCTL_DEF(DRM_GLAMO_GEM_PREAD, glamo_ioctl_gem_pread, DRM_AUTH),
72         DRM_IOCTL_DEF(DRM_GLAMO_GEM_PWRITE, glamo_ioctl_gem_pwrite, DRM_AUTH),
73         DRM_IOCTL_DEF(DRM_GLAMO_GEM_WAIT_RENDERING,
74                       glamo_ioctl_wait_rendering, DRM_AUTH),
75 };
76
77
78 static int glamodrm_firstopen(struct drm_device *dev)
79 {
80         DRM_DEBUG("\n");
81         return 0;
82 }
83
84
85 static int glamodrm_open(struct drm_device *dev, struct drm_file *fh)
86 {
87         DRM_DEBUG("\n");
88         return 0;
89 }
90
91
92 static void glamodrm_preclose(struct drm_device *dev, struct drm_file *fh)
93 {
94         DRM_DEBUG("\n");
95 }
96
97 static void glamodrm_postclose(struct drm_device *dev, struct drm_file *fh)
98 {
99         DRM_DEBUG("\n");
100 }
101
102
103 static void glamodrm_lastclose(struct drm_device *dev)
104 {
105         DRM_DEBUG("\n");
106 }
107
108
109 static int glamodrm_master_create(struct drm_device *dev,
110                                   struct drm_master *master)
111 {
112         DRM_DEBUG("\n");
113
114         return 0;
115 }
116
117
118 static void glamodrm_master_destroy(struct drm_device *dev,
119                                     struct drm_master *master)
120 {
121         DRM_DEBUG("\n");
122 }
123
124
125 static int glamodrm_load(struct drm_device *dev, unsigned long flags)
126 {
127         struct glamodrm_handle *gdrm;
128         gdrm = dev->dev_private;
129
130         glamo_buffer_init(gdrm);
131         glamo_cmdq_init(dev);
132         glamo_fence_init(gdrm);
133         glamo_display_init(dev);
134
135         return 0;
136 }
137
138
139 static int glamodrm_unload(struct drm_device *dev)
140 {
141         struct glamodrm_handle *gdrm;
142
143         gdrm = dev->dev_private;
144
145         glamo_engine_disable(gdrm->glamo_core, GLAMO_ENGINE_2D);
146         glamo_engine_disable(gdrm->glamo_core, GLAMO_ENGINE_3D);
147         glamo_buffer_final(gdrm);
148         glamo_fence_shutdown(gdrm);
149
150         return 0;
151 }
152
153
154 static struct vm_operations_struct glamodrm_gem_vm_ops = {
155         .fault = glamodrm_gem_fault,
156         .open = drm_gem_vm_open,
157         .close = drm_gem_vm_close,
158 };
159
160 static struct drm_driver glamodrm_drm_driver = {
161         .driver_features = DRIVER_IS_PLATFORM | DRIVER_GEM | DRIVER_MODESET,
162         .firstopen = glamodrm_firstopen,
163         .load = glamodrm_load,
164         .unload = glamodrm_unload,
165         .open = glamodrm_open,
166         .preclose = glamodrm_preclose,
167         .postclose = glamodrm_postclose,
168         .lastclose = glamodrm_lastclose,
169         .reclaim_buffers = drm_core_reclaim_buffers,
170         .get_map_ofs = drm_core_get_map_ofs,
171         .get_reg_ofs = drm_core_get_reg_ofs,
172         .master_create = glamodrm_master_create,
173         .master_destroy = glamodrm_master_destroy,
174         .gem_init_object = glamodrm_gem_init_object,
175         .gem_free_object = glamodrm_gem_free_object,
176         .gem_vm_ops = &glamodrm_gem_vm_ops,
177         .ioctls = glamo_ioctls,
178         .fops = {
179                 .owner = THIS_MODULE,
180                 .open = drm_open,
181                 .release = drm_release,
182                 .ioctl = drm_ioctl,
183                 .mmap = drm_gem_mmap,
184                 .poll = drm_poll,
185                 .fasync = drm_fasync,
186         },
187         .major = 0,
188         .minor = 1,
189         .patchlevel = 0,
190         .name = DRIVER_NAME,
191         .desc = DRIVER_DESC,
192         .date = DRIVER_DATE,
193 };
194
195
196 static int glamodrm_probe(struct platform_device *pdev)
197 {
198         int rc;
199         struct glamodrm_handle *gdrm;
200         struct glamo_core *core = dev_get_drvdata(pdev->dev.parent);
201
202         printk(KERN_INFO "[glamo-drm] SMedia Glamo Direct Rendering Support\n");
203
204         gdrm = kzalloc(sizeof(*gdrm), GFP_KERNEL);
205         if ( !gdrm )
206                 return -ENOMEM;
207         platform_set_drvdata(pdev, gdrm);
208         gdrm->glamo_core = core;
209         gdrm->dev = &pdev->dev;
210
211         /* Find the command queue registers */
212         gdrm->reg = platform_get_resource_byname(pdev, IORESOURCE_MEM,
213                                                  "glamo-cmdq-regs");
214         if ( !gdrm->reg ) {
215                 dev_err(&pdev->dev, "Unable to find cmdq registers.\n");
216                 rc = -ENOENT;
217                 goto out_free;
218         }
219         gdrm->reg = request_mem_region(gdrm->reg->start,
220                                           resource_size(gdrm->reg), pdev->name);
221         if ( !gdrm->reg ) {
222                 dev_err(&pdev->dev, "failed to request MMIO region\n");
223                 rc = -ENOENT;
224                 goto out_free;
225         }
226         gdrm->reg_base = ioremap_nocache(gdrm->reg->start,
227                                          resource_size(gdrm->reg));
228         if ( !gdrm->reg_base ) {
229                 dev_err(&pdev->dev, "failed to ioremap() MMIO registers\n");
230                 rc = -ENOENT;
231                 goto out_release_regs;
232         }
233
234         /* Find the VRAM */
235         gdrm->vram = platform_get_resource_byname(pdev, IORESOURCE_MEM,
236                                                   "glamo-fb-mem");
237         if ( !gdrm->vram ) {
238                 dev_err(&pdev->dev, "Unable to find VRAM.\n");
239                 rc = -ENOENT;
240                 goto out_unmap_regs;
241         }
242         gdrm->vram = request_mem_region(gdrm->vram->start,
243                                         resource_size(gdrm->vram), pdev->name);
244         if ( !gdrm->vram ) {
245                 dev_err(&pdev->dev, "failed to request VRAM region\n");
246                 rc = -ENOENT;
247                 goto out_unmap_regs;
248         }
249
250         /* Find the LCD controller */
251         gdrm->lcd_regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
252                                                       "glamo-fb-regs");
253         if ( !gdrm->lcd_regs ) {
254                 dev_err(&pdev->dev, "Unable to find LCD registers.\n");
255                 rc = -ENOENT;
256                 goto out_release_vram;
257         }
258         gdrm->lcd_regs = request_mem_region(gdrm->lcd_regs->start,
259                                             resource_size(gdrm->lcd_regs),
260                                             pdev->name);
261         if ( !gdrm->lcd_regs ) {
262                 dev_err(&pdev->dev, "failed to request LCD registers\n");
263                 rc = -ENOENT;
264                 goto out_release_vram;
265         }
266         gdrm->lcd_base = ioremap_nocache(gdrm->lcd_regs->start,
267                                          resource_size(gdrm->lcd_regs));
268         if ( !gdrm->lcd_base ) {
269                 dev_err(&pdev->dev, "failed to ioremap() LCD registers\n");
270                 rc = -ENOENT;
271                 goto out_release_lcd;
272         }
273
274         /* Find the 2D engine */
275         gdrm->twod_regs = platform_get_resource(pdev, IORESOURCE_MEM, 4);
276         if ( !gdrm->twod_regs ) {
277                 dev_err(&pdev->dev, "Unable to find 2D registers.\n");
278                 rc = -ENOENT;
279                 goto out_unmap_lcd;
280         }
281         gdrm->twod_regs = request_mem_region(gdrm->twod_regs->start,
282                                              resource_size(gdrm->twod_regs),
283                                              pdev->name);
284         if ( !gdrm->twod_regs ) {
285                 dev_err(&pdev->dev, "failed to request 2D registers\n");
286                 rc = -ENOENT;
287                 goto out_unmap_lcd;
288         }
289         gdrm->twod_base = ioremap(gdrm->twod_regs->start,
290                                   resource_size(gdrm->twod_regs));
291         if ( !gdrm->twod_base ) {
292                 dev_err(&pdev->dev, "failed to ioremap() 2D registers\n");
293                 rc = -ENOENT;
294                 goto out_release_2d;
295         }
296
297         /* Hook up IRQ handle for fence processing */
298         gdrm->twod_irq = platform_get_irq_byname(pdev, "glamo-2d-irq");
299
300         gdrm->vram_size = GLAMO_FB_SIZE;
301         printk(KERN_INFO "[glamo-drm] %lli bytes of VRAM\n",
302                          (long long int)gdrm->vram_size);
303
304         /* Initialise DRM */
305         drm_platform_init(&glamodrm_drm_driver, pdev, (void *)gdrm);
306
307         return 0;
308
309 out_release_2d:
310         release_mem_region(gdrm->twod_regs->start,
311                            resource_size(gdrm->twod_regs));
312 out_unmap_lcd:
313         iounmap(gdrm->lcd_base);
314 out_release_lcd:
315         release_mem_region(gdrm->lcd_regs->start,
316                            resource_size(gdrm->lcd_regs));
317 out_release_vram:
318         release_mem_region(gdrm->vram->start, resource_size(gdrm->vram));
319 out_unmap_regs:
320         iounmap(gdrm->reg_base);
321 out_release_regs:
322         release_mem_region(gdrm->reg->start, resource_size(gdrm->reg));
323 out_free:
324         kfree(gdrm);
325         dev_set_drvdata(&pdev->dev, NULL);
326         return rc;
327 }
328
329
330 static int glamodrm_remove(struct platform_device *pdev)
331 {
332         struct glamodrm_handle *gdrm = platform_get_drvdata(pdev);
333
334         glamo_buffer_final(gdrm);
335         glamo_cmdq_shutdown(gdrm);
336
337         drm_exit(&glamodrm_drm_driver);
338
339         platform_set_drvdata(pdev, NULL);
340
341         /* Release registers */
342         iounmap(gdrm->reg_base);
343         release_mem_region(gdrm->reg->start, resource_size(gdrm->reg));
344
345         /* Release VRAM */
346         release_mem_region(gdrm->vram->start, resource_size(gdrm->vram));
347
348         /* Release LCD registers */
349         iounmap(gdrm->lcd_base);
350         release_mem_region(gdrm->lcd_regs->start,
351                            resource_size(gdrm->lcd_regs));
352
353         /* Release 2D engine  */
354         iounmap(gdrm->twod_base);
355         release_mem_region(gdrm->twod_regs->start,
356                            resource_size(gdrm->twod_regs));
357
358         kfree(gdrm);
359
360         return 0;
361 }
362
363
364 static int glamodrm_suspend(struct platform_device *pdev, pm_message_t state)
365 {
366         struct glamodrm_handle *gdrm = platform_get_drvdata(pdev);
367
368         glamo_kmsfb_suspend(gdrm);
369         glamo_display_suspend(gdrm);
370         glamo_cmdq_suspend(gdrm);
371
372         /* glamo_core.c will suspend the engines for us */
373
374         return 0;
375 }
376
377
378 static int glamodrm_resume(struct platform_device *pdev)
379 {
380         struct glamodrm_handle *gdrm = platform_get_drvdata(pdev);
381
382         glamo_cmdq_resume(gdrm);
383         glamo_display_resume(gdrm);
384         glamo_kmsfb_resume(gdrm);
385
386         return 0;
387 }
388
389
390 static struct platform_driver glamodrm_driver = {
391         .probe          = glamodrm_probe,
392         .remove         = glamodrm_remove,
393         .suspend        = glamodrm_suspend,
394         .resume         = glamodrm_resume,
395         .driver         = {
396                 .name   = "glamo-fb",
397                 .owner  = THIS_MODULE,
398         },
399 };
400
401
402 static int __devinit glamodrm_init(void)
403 {
404         glamodrm_drm_driver.num_ioctls = DRM_ARRAY_SIZE(glamo_ioctls);
405         return platform_driver_register(&glamodrm_driver);
406 }
407
408
409 static void __exit glamodrm_exit(void)
410 {
411         platform_driver_unregister(&glamodrm_driver);
412 }
413
414
415 module_init(glamodrm_init);
416 module_exit(glamodrm_exit);
417
418 MODULE_AUTHOR(DRIVER_AUTHOR);
419 MODULE_DESCRIPTION(DRIVER_DESC);
420 MODULE_LICENSE("GPL");