2 * Copyright (C) 2015 Etnaviv Project
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <linux/component.h>
18 #include <linux/of_platform.h>
19 #include <drm/drm_of.h>
21 #include "etnaviv_drv.h"
22 #include "etnaviv_gpu.h"
23 #include "etnaviv_gem.h"
24 #include "etnaviv_mmu.h"
25 #include "etnaviv_gem.h"
27 #ifdef CONFIG_DRM_ETNAVIV_REGISTER_LOGGING
29 MODULE_PARM_DESC(reglog
, "Enable register read/write logging");
30 module_param(reglog
, bool, 0600);
35 void __iomem
*etnaviv_ioremap(struct platform_device
*pdev
, const char *name
,
42 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, name
);
44 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
46 ptr
= devm_ioremap_resource(&pdev
->dev
, res
);
48 dev_err(&pdev
->dev
, "failed to ioremap %s: %ld\n", name
,
54 dev_printk(KERN_DEBUG
, &pdev
->dev
, "IO:region %s 0x%p %08zx\n",
55 dbgname
, ptr
, (size_t)resource_size(res
));
60 void etnaviv_writel(u32 data
, void __iomem
*addr
)
63 printk(KERN_DEBUG
"IO:W %p %08x\n", addr
, data
);
68 u32
etnaviv_readl(const void __iomem
*addr
)
70 u32 val
= readl(addr
);
73 printk(KERN_DEBUG
"IO:R %p %08x\n", addr
, val
);
83 static void load_gpu(struct drm_device
*dev
)
85 struct etnaviv_drm_private
*priv
= dev
->dev_private
;
88 for (i
= 0; i
< ETNA_MAX_PIPES
; i
++) {
89 struct etnaviv_gpu
*g
= priv
->gpu
[i
];
94 ret
= etnaviv_gpu_init(g
);
101 static int etnaviv_open(struct drm_device
*dev
, struct drm_file
*file
)
103 struct etnaviv_file_private
*ctx
;
105 ctx
= kzalloc(sizeof(*ctx
), GFP_KERNEL
);
109 file
->driver_priv
= ctx
;
114 static void etnaviv_preclose(struct drm_device
*dev
, struct drm_file
*file
)
116 struct etnaviv_drm_private
*priv
= dev
->dev_private
;
117 struct etnaviv_file_private
*ctx
= file
->driver_priv
;
120 for (i
= 0; i
< ETNA_MAX_PIPES
; i
++) {
121 struct etnaviv_gpu
*gpu
= priv
->gpu
[i
];
124 mutex_lock(&gpu
->lock
);
125 if (gpu
->lastctx
== ctx
)
127 mutex_unlock(&gpu
->lock
);
138 #ifdef CONFIG_DEBUG_FS
139 static int etnaviv_gem_show(struct drm_device
*dev
, struct seq_file
*m
)
141 struct etnaviv_drm_private
*priv
= dev
->dev_private
;
143 etnaviv_gem_describe_objects(priv
, m
);
148 static int etnaviv_mm_show(struct drm_device
*dev
, struct seq_file
*m
)
150 struct drm_printer p
= drm_seq_file_printer(m
);
152 read_lock(&dev
->vma_offset_manager
->vm_lock
);
153 drm_mm_print(&dev
->vma_offset_manager
->vm_addr_space_mm
, &p
);
154 read_unlock(&dev
->vma_offset_manager
->vm_lock
);
159 static int etnaviv_mmu_show(struct etnaviv_gpu
*gpu
, struct seq_file
*m
)
161 struct drm_printer p
= drm_seq_file_printer(m
);
163 seq_printf(m
, "Active Objects (%s):\n", dev_name(gpu
->dev
));
165 mutex_lock(&gpu
->mmu
->lock
);
166 drm_mm_print(&gpu
->mmu
->mm
, &p
);
167 mutex_unlock(&gpu
->mmu
->lock
);
172 static void etnaviv_buffer_dump(struct etnaviv_gpu
*gpu
, struct seq_file
*m
)
174 struct etnaviv_cmdbuf
*buf
= gpu
->buffer
;
175 u32 size
= buf
->size
;
176 u32
*ptr
= buf
->vaddr
;
179 seq_printf(m
, "virt %p - phys 0x%llx - free 0x%08x\n",
180 buf
->vaddr
, (u64
)buf
->paddr
, size
- buf
->user_size
);
182 for (i
= 0; i
< size
/ 4; i
++) {
186 seq_printf(m
, "\t0x%p: ", ptr
+ i
);
187 seq_printf(m
, "%08x ", *(ptr
+ i
));
192 static int etnaviv_ring_show(struct etnaviv_gpu
*gpu
, struct seq_file
*m
)
194 seq_printf(m
, "Ring Buffer (%s): ", dev_name(gpu
->dev
));
196 mutex_lock(&gpu
->lock
);
197 etnaviv_buffer_dump(gpu
, m
);
198 mutex_unlock(&gpu
->lock
);
203 static int show_unlocked(struct seq_file
*m
, void *arg
)
205 struct drm_info_node
*node
= (struct drm_info_node
*) m
->private;
206 struct drm_device
*dev
= node
->minor
->dev
;
207 int (*show
)(struct drm_device
*dev
, struct seq_file
*m
) =
208 node
->info_ent
->data
;
213 static int show_each_gpu(struct seq_file
*m
, void *arg
)
215 struct drm_info_node
*node
= (struct drm_info_node
*) m
->private;
216 struct drm_device
*dev
= node
->minor
->dev
;
217 struct etnaviv_drm_private
*priv
= dev
->dev_private
;
218 struct etnaviv_gpu
*gpu
;
219 int (*show
)(struct etnaviv_gpu
*gpu
, struct seq_file
*m
) =
220 node
->info_ent
->data
;
224 for (i
= 0; i
< ETNA_MAX_PIPES
; i
++) {
237 static struct drm_info_list etnaviv_debugfs_list
[] = {
238 {"gpu", show_each_gpu
, 0, etnaviv_gpu_debugfs
},
239 {"gem", show_unlocked
, 0, etnaviv_gem_show
},
240 { "mm", show_unlocked
, 0, etnaviv_mm_show
},
241 {"mmu", show_each_gpu
, 0, etnaviv_mmu_show
},
242 {"ring", show_each_gpu
, 0, etnaviv_ring_show
},
245 static int etnaviv_debugfs_init(struct drm_minor
*minor
)
247 struct drm_device
*dev
= minor
->dev
;
250 ret
= drm_debugfs_create_files(etnaviv_debugfs_list
,
251 ARRAY_SIZE(etnaviv_debugfs_list
),
252 minor
->debugfs_root
, minor
);
255 dev_err(dev
->dev
, "could not install etnaviv_debugfs_list\n");
262 static void etnaviv_debugfs_cleanup(struct drm_minor
*minor
)
264 drm_debugfs_remove_files(etnaviv_debugfs_list
,
265 ARRAY_SIZE(etnaviv_debugfs_list
), minor
);
273 static int etnaviv_ioctl_get_param(struct drm_device
*dev
, void *data
,
274 struct drm_file
*file
)
276 struct etnaviv_drm_private
*priv
= dev
->dev_private
;
277 struct drm_etnaviv_param
*args
= data
;
278 struct etnaviv_gpu
*gpu
;
280 if (args
->pipe
>= ETNA_MAX_PIPES
)
283 gpu
= priv
->gpu
[args
->pipe
];
287 return etnaviv_gpu_get_param(gpu
, args
->param
, &args
->value
);
290 static int etnaviv_ioctl_gem_new(struct drm_device
*dev
, void *data
,
291 struct drm_file
*file
)
293 struct drm_etnaviv_gem_new
*args
= data
;
295 if (args
->flags
& ~(ETNA_BO_CACHED
| ETNA_BO_WC
| ETNA_BO_UNCACHED
|
299 return etnaviv_gem_new_handle(dev
, file
, args
->size
,
300 args
->flags
, &args
->handle
);
303 #define TS(t) ((struct timespec){ \
304 .tv_sec = (t).tv_sec, \
305 .tv_nsec = (t).tv_nsec \
308 static int etnaviv_ioctl_gem_cpu_prep(struct drm_device
*dev
, void *data
,
309 struct drm_file
*file
)
311 struct drm_etnaviv_gem_cpu_prep
*args
= data
;
312 struct drm_gem_object
*obj
;
315 if (args
->op
& ~(ETNA_PREP_READ
| ETNA_PREP_WRITE
| ETNA_PREP_NOSYNC
))
318 obj
= drm_gem_object_lookup(file
, args
->handle
);
322 ret
= etnaviv_gem_cpu_prep(obj
, args
->op
, &TS(args
->timeout
));
324 drm_gem_object_unreference_unlocked(obj
);
329 static int etnaviv_ioctl_gem_cpu_fini(struct drm_device
*dev
, void *data
,
330 struct drm_file
*file
)
332 struct drm_etnaviv_gem_cpu_fini
*args
= data
;
333 struct drm_gem_object
*obj
;
339 obj
= drm_gem_object_lookup(file
, args
->handle
);
343 ret
= etnaviv_gem_cpu_fini(obj
);
345 drm_gem_object_unreference_unlocked(obj
);
350 static int etnaviv_ioctl_gem_info(struct drm_device
*dev
, void *data
,
351 struct drm_file
*file
)
353 struct drm_etnaviv_gem_info
*args
= data
;
354 struct drm_gem_object
*obj
;
360 obj
= drm_gem_object_lookup(file
, args
->handle
);
364 ret
= etnaviv_gem_mmap_offset(obj
, &args
->offset
);
365 drm_gem_object_unreference_unlocked(obj
);
370 static int etnaviv_ioctl_wait_fence(struct drm_device
*dev
, void *data
,
371 struct drm_file
*file
)
373 struct drm_etnaviv_wait_fence
*args
= data
;
374 struct etnaviv_drm_private
*priv
= dev
->dev_private
;
375 struct timespec
*timeout
= &TS(args
->timeout
);
376 struct etnaviv_gpu
*gpu
;
378 if (args
->flags
& ~(ETNA_WAIT_NONBLOCK
))
381 if (args
->pipe
>= ETNA_MAX_PIPES
)
384 gpu
= priv
->gpu
[args
->pipe
];
388 if (args
->flags
& ETNA_WAIT_NONBLOCK
)
391 return etnaviv_gpu_wait_fence_interruptible(gpu
, args
->fence
,
395 static int etnaviv_ioctl_gem_userptr(struct drm_device
*dev
, void *data
,
396 struct drm_file
*file
)
398 struct drm_etnaviv_gem_userptr
*args
= data
;
401 if (args
->flags
& ~(ETNA_USERPTR_READ
|ETNA_USERPTR_WRITE
) ||
405 if (offset_in_page(args
->user_ptr
| args
->user_size
) ||
406 (uintptr_t)args
->user_ptr
!= args
->user_ptr
||
407 (u32
)args
->user_size
!= args
->user_size
||
408 args
->user_ptr
& ~PAGE_MASK
)
411 if (args
->flags
& ETNA_USERPTR_WRITE
)
412 access
= VERIFY_WRITE
;
414 access
= VERIFY_READ
;
416 if (!access_ok(access
, (void __user
*)(unsigned long)args
->user_ptr
,
420 return etnaviv_gem_new_userptr(dev
, file
, args
->user_ptr
,
421 args
->user_size
, args
->flags
,
425 static int etnaviv_ioctl_gem_wait(struct drm_device
*dev
, void *data
,
426 struct drm_file
*file
)
428 struct etnaviv_drm_private
*priv
= dev
->dev_private
;
429 struct drm_etnaviv_gem_wait
*args
= data
;
430 struct timespec
*timeout
= &TS(args
->timeout
);
431 struct drm_gem_object
*obj
;
432 struct etnaviv_gpu
*gpu
;
435 if (args
->flags
& ~(ETNA_WAIT_NONBLOCK
))
438 if (args
->pipe
>= ETNA_MAX_PIPES
)
441 gpu
= priv
->gpu
[args
->pipe
];
445 obj
= drm_gem_object_lookup(file
, args
->handle
);
449 if (args
->flags
& ETNA_WAIT_NONBLOCK
)
452 ret
= etnaviv_gem_wait_bo(gpu
, obj
, timeout
);
454 drm_gem_object_unreference_unlocked(obj
);
459 static const struct drm_ioctl_desc etnaviv_ioctls
[] = {
460 #define ETNA_IOCTL(n, func, flags) \
461 DRM_IOCTL_DEF_DRV(ETNAVIV_##n, etnaviv_ioctl_##func, flags)
462 ETNA_IOCTL(GET_PARAM
, get_param
, DRM_AUTH
|DRM_RENDER_ALLOW
),
463 ETNA_IOCTL(GEM_NEW
, gem_new
, DRM_AUTH
|DRM_RENDER_ALLOW
),
464 ETNA_IOCTL(GEM_INFO
, gem_info
, DRM_AUTH
|DRM_RENDER_ALLOW
),
465 ETNA_IOCTL(GEM_CPU_PREP
, gem_cpu_prep
, DRM_AUTH
|DRM_RENDER_ALLOW
),
466 ETNA_IOCTL(GEM_CPU_FINI
, gem_cpu_fini
, DRM_AUTH
|DRM_RENDER_ALLOW
),
467 ETNA_IOCTL(GEM_SUBMIT
, gem_submit
, DRM_AUTH
|DRM_RENDER_ALLOW
),
468 ETNA_IOCTL(WAIT_FENCE
, wait_fence
, DRM_AUTH
|DRM_RENDER_ALLOW
),
469 ETNA_IOCTL(GEM_USERPTR
, gem_userptr
, DRM_AUTH
|DRM_RENDER_ALLOW
),
470 ETNA_IOCTL(GEM_WAIT
, gem_wait
, DRM_AUTH
|DRM_RENDER_ALLOW
),
473 static const struct vm_operations_struct vm_ops
= {
474 .fault
= etnaviv_gem_fault
,
475 .open
= drm_gem_vm_open
,
476 .close
= drm_gem_vm_close
,
479 static const struct file_operations fops
= {
480 .owner
= THIS_MODULE
,
482 .release
= drm_release
,
483 .unlocked_ioctl
= drm_ioctl
,
484 .compat_ioctl
= drm_compat_ioctl
,
488 .mmap
= etnaviv_gem_mmap
,
491 static struct drm_driver etnaviv_drm_driver
= {
492 .driver_features
= DRIVER_GEM
|
495 .open
= etnaviv_open
,
496 .preclose
= etnaviv_preclose
,
497 .gem_free_object_unlocked
= etnaviv_gem_free_object
,
498 .gem_vm_ops
= &vm_ops
,
499 .prime_handle_to_fd
= drm_gem_prime_handle_to_fd
,
500 .prime_fd_to_handle
= drm_gem_prime_fd_to_handle
,
501 .gem_prime_export
= drm_gem_prime_export
,
502 .gem_prime_import
= drm_gem_prime_import
,
503 .gem_prime_pin
= etnaviv_gem_prime_pin
,
504 .gem_prime_unpin
= etnaviv_gem_prime_unpin
,
505 .gem_prime_get_sg_table
= etnaviv_gem_prime_get_sg_table
,
506 .gem_prime_import_sg_table
= etnaviv_gem_prime_import_sg_table
,
507 .gem_prime_vmap
= etnaviv_gem_prime_vmap
,
508 .gem_prime_vunmap
= etnaviv_gem_prime_vunmap
,
509 .gem_prime_mmap
= etnaviv_gem_prime_mmap
,
510 #ifdef CONFIG_DEBUG_FS
511 .debugfs_init
= etnaviv_debugfs_init
,
512 .debugfs_cleanup
= etnaviv_debugfs_cleanup
,
514 .ioctls
= etnaviv_ioctls
,
515 .num_ioctls
= DRM_ETNAVIV_NUM_IOCTLS
,
518 .desc
= "etnaviv DRM",
527 static int etnaviv_bind(struct device
*dev
)
529 struct etnaviv_drm_private
*priv
;
530 struct drm_device
*drm
;
533 drm
= drm_dev_alloc(&etnaviv_drm_driver
, dev
);
537 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
539 dev_err(dev
, "failed to allocate private data\n");
543 drm
->dev_private
= priv
;
545 priv
->wq
= alloc_ordered_workqueue("etnaviv", 0);
551 mutex_init(&priv
->gem_lock
);
552 INIT_LIST_HEAD(&priv
->gem_list
);
555 dev_set_drvdata(dev
, drm
);
557 ret
= component_bind_all(dev
, drm
);
563 ret
= drm_dev_register(drm
, 0);
570 component_unbind_all(dev
, drm
);
572 flush_workqueue(priv
->wq
);
573 destroy_workqueue(priv
->wq
);
582 static void etnaviv_unbind(struct device
*dev
)
584 struct drm_device
*drm
= dev_get_drvdata(dev
);
585 struct etnaviv_drm_private
*priv
= drm
->dev_private
;
587 drm_dev_unregister(drm
);
589 flush_workqueue(priv
->wq
);
590 destroy_workqueue(priv
->wq
);
592 component_unbind_all(dev
, drm
);
594 drm
->dev_private
= NULL
;
600 static const struct component_master_ops etnaviv_master_ops
= {
601 .bind
= etnaviv_bind
,
602 .unbind
= etnaviv_unbind
,
605 static int compare_of(struct device
*dev
, void *data
)
607 struct device_node
*np
= data
;
609 return dev
->of_node
== np
;
612 static int compare_str(struct device
*dev
, void *data
)
614 return !strcmp(dev_name(dev
), data
);
617 static int etnaviv_pdev_probe(struct platform_device
*pdev
)
619 struct device
*dev
= &pdev
->dev
;
620 struct device_node
*node
= dev
->of_node
;
621 struct component_match
*match
= NULL
;
623 dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
626 struct device_node
*core_node
;
630 core_node
= of_parse_phandle(node
, "cores", i
);
634 drm_of_component_match_add(&pdev
->dev
, &match
,
635 compare_of
, core_node
);
636 of_node_put(core_node
);
638 } else if (dev
->platform_data
) {
639 char **names
= dev
->platform_data
;
642 for (i
= 0; names
[i
]; i
++)
643 component_match_add(dev
, &match
, compare_str
, names
[i
]);
646 return component_master_add_with_match(dev
, &etnaviv_master_ops
, match
);
649 static int etnaviv_pdev_remove(struct platform_device
*pdev
)
651 component_master_del(&pdev
->dev
, &etnaviv_master_ops
);
656 static const struct of_device_id dt_match
[] = {
657 { .compatible
= "fsl,imx-gpu-subsystem" },
658 { .compatible
= "marvell,dove-gpu-subsystem" },
661 MODULE_DEVICE_TABLE(of
, dt_match
);
663 static struct platform_driver etnaviv_platform_driver
= {
664 .probe
= etnaviv_pdev_probe
,
665 .remove
= etnaviv_pdev_remove
,
668 .of_match_table
= dt_match
,
672 static int __init
etnaviv_init(void)
676 etnaviv_validate_init();
678 ret
= platform_driver_register(&etnaviv_gpu_driver
);
682 ret
= platform_driver_register(&etnaviv_platform_driver
);
684 platform_driver_unregister(&etnaviv_gpu_driver
);
688 module_init(etnaviv_init
);
690 static void __exit
etnaviv_exit(void)
692 platform_driver_unregister(&etnaviv_gpu_driver
);
693 platform_driver_unregister(&etnaviv_platform_driver
);
695 module_exit(etnaviv_exit
);
697 MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
698 MODULE_AUTHOR("Russell King <rmk+kernel@arm.linux.org.uk>");
699 MODULE_AUTHOR("Lucas Stach <l.stach@pengutronix.de>");
700 MODULE_DESCRIPTION("etnaviv DRM Driver");
701 MODULE_LICENSE("GPL v2");
702 MODULE_ALIAS("platform:etnaviv");