Commit f2978651e3045e22702838cbc805589fa3d0e4d3
Committed by
Jacob Stiffler
1 parent
92ff8b63b6
Exists in
smarc-ti-linux-3.14.y
and in
1 other branch
drm/omap: Add omapdrm plugin API
This work is based on Rob Clark's patch : http://dev.omapzoom.org/?p=integration/kernel-ubuntu.git;a=commit;h=6a42bc1660b06464f9da796604ecd4934bb31acd WIP: drm/omap: V2: add plugin API from the GLP kernel tree available at http://dev.omapzoom.org/?p=integration/kernel-ubuntu.git;a=summary Omapdrm is fixed so that it can accept plugins. Plugin add functions like load/unload etc are added in omap_drv.c In omap_gem.c GEM object mapping functions has been added This patch is required for gfx driver to be built as a drm plugin Subhajit : k3.12: removed const from ioctls table Anand : k3.14 : rebased with LCPD baseline Signed-off-by: Rob Clark <rob@ti.com> Signed-off-by: Subhajit Paul <subhajit_paul@ti.com> Signed-off-by: Anand Balagopalakrishnan <anandb@ti.com> Conflicts: drivers/gpu/drm/omapdrm/omap_drv.c drivers/gpu/drm/omapdrm/omap_drv.h Change-Id: I72133ad08ddd4682320fa2e7f5f4dd017ee92dae Signed-off-by: Anand Balagopalakrishnan <anandb@ti.com>
Showing 4 changed files with 331 additions and 8 deletions Side-by-side Diff
drivers/gpu/drm/omapdrm/omap_drv.c
... | ... | @@ -30,11 +30,24 @@ |
30 | 30 | #define DRIVER_MINOR 0 |
31 | 31 | #define DRIVER_PATCHLEVEL 0 |
32 | 32 | |
33 | +struct drm_device *drm_device; | |
34 | + | |
33 | 35 | static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS; |
34 | 36 | |
35 | 37 | MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs"); |
36 | 38 | module_param(num_crtc, int, 0600); |
37 | 39 | |
40 | +/* TODO: think about how to handle more than one plugin.. ie. some ops | |
41 | + * me might want to stop on the first plugin that doesn't return an | |
42 | + * error, etc.. | |
43 | + */ | |
44 | +LIST_HEAD(plugin_list); | |
45 | + | |
46 | +/* keep track of whether we are already loaded.. we may need to call | |
47 | + * plugin's load() if they register after we are already loaded | |
48 | + */ | |
49 | +static __read_mostly bool loaded = false; | |
50 | + | |
38 | 51 | /* |
39 | 52 | * mode config funcs |
40 | 53 | */ |
... | ... | @@ -387,6 +400,27 @@ |
387 | 400 | return 0; |
388 | 401 | } |
389 | 402 | |
403 | +static int ioctl_get_base(struct drm_device *dev, void *data, | |
404 | + struct drm_file *file_priv) | |
405 | +{ | |
406 | + struct drm_omap_get_base *args = data; | |
407 | + struct omap_drm_plugin *plugin; | |
408 | + | |
409 | + /* be safe: */ | |
410 | + args->plugin_name[ARRAY_SIZE(args->plugin_name) - 1] = '\0'; | |
411 | + | |
412 | + DBG("%p: plugin_name=%s", dev, args->plugin_name); | |
413 | + | |
414 | + list_for_each_entry(plugin, &plugin_list, list) { | |
415 | + if (!strcmp(args->plugin_name, plugin->name)) { | |
416 | + args->ioctl_base = plugin->ioctl_base; | |
417 | + return 0; | |
418 | + } | |
419 | + } | |
420 | + | |
421 | + return -EINVAL; | |
422 | +} | |
423 | + | |
390 | 424 | static int ioctl_gem_new(struct drm_device *dev, void *data, |
391 | 425 | struct drm_file *file_priv) |
392 | 426 | { |
393 | 427 | |
... | ... | @@ -465,9 +499,10 @@ |
465 | 499 | return ret; |
466 | 500 | } |
467 | 501 | |
468 | -static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { | |
502 | +static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { | |
469 | 503 | DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
470 | 504 | DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
505 | + DRM_IOCTL_DEF_DRV(OMAP_GET_BASE, ioctl_get_base, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), | |
471 | 506 | DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
472 | 507 | DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
473 | 508 | DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
474 | 509 | |
... | ... | @@ -492,10 +527,13 @@ |
492 | 527 | { |
493 | 528 | struct omap_drm_platform_data *pdata = dev->dev->platform_data; |
494 | 529 | struct omap_drm_private *priv; |
530 | + struct omap_drm_plugin *plugin; | |
495 | 531 | int ret; |
496 | 532 | |
497 | 533 | DBG("load: dev=%p", dev); |
498 | 534 | |
535 | + drm_device = dev; | |
536 | + | |
499 | 537 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
500 | 538 | if (!priv) |
501 | 539 | return -ENOMEM; |
... | ... | @@ -534,6 +572,12 @@ |
534 | 572 | |
535 | 573 | drm_kms_helper_poll_init(dev); |
536 | 574 | |
575 | + loaded = true; | |
576 | + | |
577 | + list_for_each_entry(plugin, &plugin_list, list) { | |
578 | + ret = plugin->load(dev, flags); | |
579 | + } | |
580 | + | |
537 | 581 | return 0; |
538 | 582 | } |
539 | 583 | |
540 | 584 | |
... | ... | @@ -541,9 +585,15 @@ |
541 | 585 | { |
542 | 586 | struct omap_drm_private *priv = dev->dev_private; |
543 | 587 | int i; |
588 | + struct omap_drm_plugin *plugin; | |
589 | + int ret; | |
544 | 590 | |
545 | 591 | DBG("unload: dev=%p", dev); |
546 | 592 | |
593 | + list_for_each_entry(plugin, &plugin_list, list) { | |
594 | + ret = plugin->unload(dev); | |
595 | + } | |
596 | + | |
547 | 597 | drm_kms_helper_poll_fini(dev); |
548 | 598 | |
549 | 599 | if (priv->fbdev) |
550 | 600 | |
551 | 601 | |
552 | 602 | |
... | ... | @@ -566,15 +616,37 @@ |
566 | 616 | |
567 | 617 | dev_set_drvdata(dev->dev, NULL); |
568 | 618 | |
619 | + loaded = false; | |
620 | + | |
569 | 621 | return 0; |
570 | 622 | } |
571 | 623 | |
572 | 624 | static int dev_open(struct drm_device *dev, struct drm_file *file) |
573 | 625 | { |
574 | - file->driver_priv = NULL; | |
626 | + struct omap_drm_plugin *plugin; | |
627 | + bool found_pvr = false; | |
628 | + int ret; | |
575 | 629 | |
630 | + file->driver_priv = kzalloc(sizeof(void *) * MAX_MAPPERS, GFP_KERNEL); | |
631 | + | |
576 | 632 | DBG("open: dev=%p, file=%p", dev, file); |
577 | 633 | |
634 | + list_for_each_entry(plugin, &plugin_list, list) { | |
635 | + if (!strcmp(DRIVER_NAME "_pvr", plugin->name)) { | |
636 | + found_pvr = true; | |
637 | + break; | |
638 | + } | |
639 | + } | |
640 | + | |
641 | + if (!found_pvr) { | |
642 | + DBG("open: PVR submodule not loaded.. let's try now"); | |
643 | + request_module(DRIVER_NAME "_pvr"); | |
644 | + } | |
645 | + | |
646 | + list_for_each_entry(plugin, &plugin_list, list) { | |
647 | + ret = plugin->open(dev, file); | |
648 | + } | |
649 | + | |
578 | 650 | return 0; |
579 | 651 | } |
580 | 652 | |
581 | 653 | |
... | ... | @@ -635,9 +707,15 @@ |
635 | 707 | { |
636 | 708 | struct omap_drm_private *priv = dev->dev_private; |
637 | 709 | int i; |
710 | + struct omap_drm_plugin *plugin; | |
711 | + int ret; | |
638 | 712 | |
639 | 713 | DBG("preclose: dev=%p", dev); |
640 | 714 | |
715 | + list_for_each_entry(plugin, &plugin_list, list) { | |
716 | + ret = plugin->release(dev, file); | |
717 | + } | |
718 | + | |
641 | 719 | /* |
642 | 720 | * Flush crtcs to finish any pending work. |
643 | 721 | * Note: this may not be correct if there are multiple applications |
... | ... | @@ -647,6 +725,8 @@ |
647 | 725 | */ |
648 | 726 | for (i = 0; i < priv->num_crtcs; i++) |
649 | 727 | omap_crtc_flush(priv->crtcs[i]); |
728 | + | |
729 | + kfree(file->driver_priv); | |
650 | 730 | } |
651 | 731 | |
652 | 732 | static void dev_postclose(struct drm_device *dev, struct drm_file *file) |
... | ... | @@ -656,8 +736,8 @@ |
656 | 736 | |
657 | 737 | static const struct vm_operations_struct omap_gem_vm_ops = { |
658 | 738 | .fault = omap_gem_fault, |
659 | - .open = drm_gem_vm_open, | |
660 | - .close = drm_gem_vm_close, | |
739 | + .open = omap_gem_vm_open, | |
740 | + .close = omap_gem_vm_close, | |
661 | 741 | }; |
662 | 742 | |
663 | 743 | static const struct file_operations omapdriver_fops = { |
... | ... | @@ -710,6 +790,93 @@ |
710 | 790 | .minor = DRIVER_MINOR, |
711 | 791 | .patchlevel = DRIVER_PATCHLEVEL, |
712 | 792 | }; |
793 | + | |
794 | +int omap_drm_register_plugin(struct omap_drm_plugin *plugin) | |
795 | +{ | |
796 | + struct drm_device *dev = drm_device; | |
797 | + static int ioctl_base = DRM_OMAP_NUM_IOCTLS; | |
798 | + int i; | |
799 | + | |
800 | + DBG("register plugin: %p (%s)", plugin, plugin->name); | |
801 | + | |
802 | + plugin->ioctl_base = ioctl_base; | |
803 | + | |
804 | + list_add_tail(&plugin->list, &plugin_list); | |
805 | + | |
806 | + /* register the plugin's ioctl's */ | |
807 | + for (i = 0; i < plugin->num_ioctls; i++) { | |
808 | + int nr = i + ioctl_base; | |
809 | + | |
810 | + /* check for out of bounds ioctl nr or | |
811 | + already registered ioctl */ | |
812 | + if (nr > ARRAY_SIZE(ioctls) || ioctls[nr].func) { | |
813 | + dev_err(dev->dev, "invalid ioctl: %d (nr=%d)\n", i, nr); | |
814 | + return -EINVAL; | |
815 | + } | |
816 | + | |
817 | + DBG("register ioctl: %d %08x", nr, plugin->ioctls[i].cmd); | |
818 | + | |
819 | + ioctls[nr] = plugin->ioctls[i]; | |
820 | + | |
821 | + if (nr >= omap_drm_driver.num_ioctls) | |
822 | + omap_drm_driver.num_ioctls = nr + 1; | |
823 | + | |
824 | + } | |
825 | + | |
826 | + ioctl_base += plugin->num_ioctls; | |
827 | + | |
828 | + if (loaded) | |
829 | + plugin->load(dev, 0); | |
830 | + | |
831 | + return 0; | |
832 | +} | |
833 | +EXPORT_SYMBOL(omap_drm_register_plugin); | |
834 | + | |
835 | +int omap_drm_unregister_plugin(struct omap_drm_plugin *plugin) | |
836 | +{ | |
837 | + list_del(&plugin->list); | |
838 | + /* TODO remove ioctl fxns */ | |
839 | + return 0; | |
840 | +} | |
841 | +EXPORT_SYMBOL(omap_drm_unregister_plugin); | |
842 | + | |
843 | +static int nmappers = 0; | |
844 | + | |
845 | +/* create buffer mapper id, to access per-mapper private data. See | |
846 | + * omap_gem_{get,set}_priv(). | |
847 | + */ | |
848 | +int omap_drm_register_mapper(void) | |
849 | +{ | |
850 | + if (nmappers >= MAX_MAPPERS) | |
851 | + return -ENOMEM; | |
852 | + return nmappers++; | |
853 | +} | |
854 | +EXPORT_SYMBOL(omap_drm_register_mapper); | |
855 | + | |
856 | +/* retire a mapper id, previously acquired from omap_drm_register_mapper() | |
857 | + */ | |
858 | +void omap_drm_unregister_mapper(int mapper_id) | |
859 | +{ | |
860 | + /* currently no-op.. */ | |
861 | +} | |
862 | +EXPORT_SYMBOL(omap_drm_unregister_mapper); | |
863 | + | |
864 | +void *omap_drm_file_priv(struct drm_file *file, int mapper_id) | |
865 | +{ | |
866 | + BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0)); | |
867 | + if (file->driver_priv) | |
868 | + return ((void **)file->driver_priv)[mapper_id]; | |
869 | + return NULL; | |
870 | +} | |
871 | +EXPORT_SYMBOL(omap_drm_file_priv); | |
872 | + | |
873 | +void omap_drm_file_set_priv(struct drm_file *file, int mapper_id, void *priv) | |
874 | +{ | |
875 | + BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0)); | |
876 | + ((void **)file->driver_priv)[mapper_id] = priv; | |
877 | +} | |
878 | +EXPORT_SYMBOL(omap_drm_file_set_priv); | |
879 | + | |
713 | 880 | |
714 | 881 | static int pdev_probe(struct platform_device *device) |
715 | 882 | { |
drivers/gpu/drm/omapdrm/omap_drv.h
... | ... | @@ -311,5 +311,64 @@ |
311 | 311 | return -ENOENT; |
312 | 312 | } |
313 | 313 | |
314 | +/****** PLUGIN API specific ******/ | |
315 | + | |
316 | +/* interface that plug-in drivers (for now just PVR) can implement */ | |
317 | +struct omap_drm_plugin { | |
318 | + const char *name; | |
319 | + | |
320 | + /* drm functions */ | |
321 | + int (*load)(struct drm_device *dev, unsigned long flags); | |
322 | + int (*unload)(struct drm_device *dev); | |
323 | + int (*open)(struct drm_device *dev, struct drm_file *file); | |
324 | + int (*release)(struct drm_device *dev, struct drm_file *file); | |
325 | + | |
326 | + struct drm_ioctl_desc *ioctls; | |
327 | + int num_ioctls; | |
328 | + int ioctl_base; | |
329 | + | |
330 | + struct list_head list; /* note, this means struct can't be const.. */ | |
331 | +}; | |
332 | + | |
333 | +int omap_drm_register_plugin(struct omap_drm_plugin *plugin); | |
334 | +int omap_drm_unregister_plugin(struct omap_drm_plugin *plugin); | |
335 | + | |
336 | +int omap_drm_register_mapper(void); | |
337 | +void omap_drm_unregister_mapper(int id); | |
338 | + | |
339 | +void *omap_drm_file_priv(struct drm_file *file, int mapper_id); | |
340 | +void omap_drm_file_set_priv(struct drm_file *file, int mapper_id, void *priv); | |
341 | + | |
342 | +void *omap_gem_priv(struct drm_gem_object *obj, int mapper_id); | |
343 | +void omap_gem_set_priv(struct drm_gem_object *obj, int mapper_id, void *priv); | |
344 | +void omap_gem_vm_open(struct vm_area_struct *vma); | |
345 | +void omap_gem_vm_close(struct vm_area_struct *vma); | |
346 | + | |
347 | +/* for external plugin buffers wrapped as GEM object (via. omap_gem_new_ext()) | |
348 | + * a vm_ops struct can be provided to get callback notification of various | |
349 | + * events.. | |
350 | + */ | |
351 | +struct omap_gem_vm_ops { | |
352 | + void (*open)(struct vm_area_struct *area); | |
353 | + void (*close)(struct vm_area_struct *area); | |
354 | + /*maybe: int (*fault)(struct vm_area_struct *vma, | |
355 | + struct vm_fault *vmf)*/ | |
356 | + | |
357 | + /* note: mmap isn't expected to do anything. it is just to allow buffer | |
358 | + * allocate to update it's own internal state | |
359 | + */ | |
360 | + void (*mmap)(struct file *, struct vm_area_struct *); | |
361 | +}; | |
362 | + | |
363 | +struct drm_gem_object *omap_gem_new_ext(struct drm_device *dev, | |
364 | + union omap_gem_size gsize, uint32_t flags, | |
365 | + dma_addr_t paddr, struct page **pages, | |
366 | + struct omap_gem_vm_ops *ops); | |
367 | + | |
368 | +void omap_gem_op_update(void); | |
369 | +int omap_gem_set_sync_object(struct drm_gem_object *obj, void *syncobj); | |
370 | +/*********************************/ | |
371 | + | |
372 | + | |
314 | 373 | #endif /* __OMAP_DRV_H__ */ |
drivers/gpu/drm/omapdrm/omap_gem.c
... | ... | @@ -117,6 +117,18 @@ |
117 | 117 | uint32_t read_pending; |
118 | 118 | uint32_t read_complete; |
119 | 119 | } *sync; |
120 | + | |
121 | + struct omap_gem_vm_ops *ops; | |
122 | + | |
123 | + /** | |
124 | + * per-mapper private data.. | |
125 | + * | |
126 | + * TODO maybe there can be a more flexible way to store per-mapper | |
127 | + * data.. for now I just keep it simple, and since this is only | |
128 | + * accessible externally via omap_gem_priv()/omap_get_set_priv() | |
129 | + */ | |
130 | + void *priv[MAX_MAPPERS]; | |
131 | + | |
120 | 132 | }; |
121 | 133 | |
122 | 134 | static int get_pages(struct drm_gem_object *obj, struct page ***pages); |
... | ... | @@ -304,6 +316,7 @@ |
304 | 316 | { |
305 | 317 | return to_omap_bo(obj)->flags; |
306 | 318 | } |
319 | +EXPORT_SYMBOL(omap_gem_flags); | |
307 | 320 | |
308 | 321 | /** get mmap offset */ |
309 | 322 | static uint64_t mmap_offset(struct drm_gem_object *obj) |
... | ... | @@ -333,6 +346,7 @@ |
333 | 346 | mutex_unlock(&obj->dev->struct_mutex); |
334 | 347 | return offset; |
335 | 348 | } |
349 | +EXPORT_SYMBOL(omap_gem_mmap_offset); | |
336 | 350 | |
337 | 351 | /** get mmap size */ |
338 | 352 | size_t omap_gem_mmap_size(struct drm_gem_object *obj) |
... | ... | @@ -365,6 +379,7 @@ |
365 | 379 | } |
366 | 380 | return -EINVAL; |
367 | 381 | } |
382 | +EXPORT_SYMBOL(omap_gem_tiled_size); | |
368 | 383 | |
369 | 384 | /* Normal handling for the case of faulting in non-tiled buffers */ |
370 | 385 | static int fault_1d(struct drm_gem_object *obj, |
... | ... | @@ -597,6 +612,9 @@ |
597 | 612 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
598 | 613 | } |
599 | 614 | |
615 | + if (omap_obj->ops && omap_obj->ops->mmap) | |
616 | + omap_obj->ops->mmap(obj->filp, vma); | |
617 | + | |
600 | 618 | return 0; |
601 | 619 | } |
602 | 620 | |
... | ... | @@ -809,6 +827,7 @@ |
809 | 827 | |
810 | 828 | return ret; |
811 | 829 | } |
830 | +EXPORT_SYMBOL(omap_gem_get_paddr); | |
812 | 831 | |
813 | 832 | /* Release physical address, when DMA is no longer being performed.. this |
814 | 833 | * could potentially unpin and unmap buffers from TILER |
... | ... | @@ -839,6 +858,7 @@ |
839 | 858 | |
840 | 859 | mutex_unlock(&obj->dev->struct_mutex); |
841 | 860 | } |
861 | +EXPORT_SYMBOL(omap_gem_put_paddr); | |
842 | 862 | |
843 | 863 | /* Get rotated scanout address (only valid if already pinned), at the |
844 | 864 | * specified orientation and x,y offset from top-left corner of buffer |
... | ... | @@ -869,6 +889,7 @@ |
869 | 889 | ret = tiler_stride(gem2fmt(omap_obj->flags), orient); |
870 | 890 | return ret; |
871 | 891 | } |
892 | +EXPORT_SYMBOL(omap_gem_tiled_stride); | |
872 | 893 | |
873 | 894 | /* acquire pages when needed (for example, for DMA where physically |
874 | 895 | * contiguous buffer is not required |
... | ... | @@ -918,6 +939,7 @@ |
918 | 939 | mutex_unlock(&obj->dev->struct_mutex); |
919 | 940 | return ret; |
920 | 941 | } |
942 | +EXPORT_SYMBOL(omap_gem_get_pages); | |
921 | 943 | |
922 | 944 | /* release pages when DMA no longer being performed */ |
923 | 945 | int omap_gem_put_pages(struct drm_gem_object *obj) |
... | ... | @@ -928,6 +950,7 @@ |
928 | 950 | */ |
929 | 951 | return 0; |
930 | 952 | } |
953 | +EXPORT_SYMBOL(omap_gem_put_pages); | |
931 | 954 | |
932 | 955 | /* Get kernel virtual address for CPU access.. this more or less only |
933 | 956 | * exists for omap_fbdev. This should be called with struct_mutex |
934 | 957 | |
935 | 958 | |
... | ... | @@ -1123,17 +1146,20 @@ |
1123 | 1146 | sync_op_update(); |
1124 | 1147 | spin_unlock(&sync_lock); |
1125 | 1148 | } |
1149 | +EXPORT_SYMBOL(omap_gem_op_update); | |
1126 | 1150 | |
1127 | 1151 | /* mark the start of read and/or write operation */ |
1128 | 1152 | int omap_gem_op_start(struct drm_gem_object *obj, enum omap_gem_op op) |
1129 | 1153 | { |
1130 | 1154 | return sync_op(obj, op, true); |
1131 | 1155 | } |
1156 | +EXPORT_SYMBOL(omap_gem_op_start); | |
1132 | 1157 | |
1133 | 1158 | int omap_gem_op_finish(struct drm_gem_object *obj, enum omap_gem_op op) |
1134 | 1159 | { |
1135 | 1160 | return sync_op(obj, op, false); |
1136 | 1161 | } |
1162 | +EXPORT_SYMBOL(omap_gem_op_finish); | |
1137 | 1163 | |
1138 | 1164 | static DECLARE_WAIT_QUEUE_HEAD(sync_event); |
1139 | 1165 | |
... | ... | @@ -1188,6 +1214,7 @@ |
1188 | 1214 | } |
1189 | 1215 | return ret; |
1190 | 1216 | } |
1217 | +EXPORT_SYMBOL(omap_gem_op_sync); | |
1191 | 1218 | |
1192 | 1219 | /* call fxn(arg), either synchronously or asynchronously if the op |
1193 | 1220 | * is currently blocked.. fxn() can be called from any context |
... | ... | @@ -1234,6 +1261,7 @@ |
1234 | 1261 | |
1235 | 1262 | return 0; |
1236 | 1263 | } |
1264 | +EXPORT_SYMBOL(omap_gem_op_async); | |
1237 | 1265 | |
1238 | 1266 | /* special API so PVR can update the buffer to use a sync-object allocated |
1239 | 1267 | * from it's sync-obj heap. Only used for a newly allocated (from PVR's |
... | ... | @@ -1271,6 +1299,7 @@ |
1271 | 1299 | spin_unlock(&sync_lock); |
1272 | 1300 | return ret; |
1273 | 1301 | } |
1302 | +EXPORT_SYMBOL(omap_gem_set_sync_object); | |
1274 | 1303 | |
1275 | 1304 | /* don't call directly.. called from GEM core when it is time to actually |
1276 | 1305 | * free the object.. |
... | ... | @@ -1495,4 +1524,70 @@ |
1495 | 1524 | */ |
1496 | 1525 | kfree(usergart); |
1497 | 1526 | } |
1527 | + | |
1528 | +/****** PLUGIN API specific ******/ | |
1529 | + | |
1530 | +/* This constructor is mainly to give plugins a way to wrap their | |
1531 | + * own allocations | |
1532 | + */ | |
1533 | +struct drm_gem_object *omap_gem_new_ext(struct drm_device *dev, | |
1534 | + union omap_gem_size gsize, uint32_t flags, | |
1535 | + dma_addr_t paddr, struct page **pages, | |
1536 | + struct omap_gem_vm_ops *ops) | |
1537 | +{ | |
1538 | + struct drm_gem_object *obj; | |
1539 | + | |
1540 | + BUG_ON((flags & OMAP_BO_TILED) && !pages); | |
1541 | + | |
1542 | + if (paddr) | |
1543 | + flags |= OMAP_BO_DMA; | |
1544 | + | |
1545 | + obj = omap_gem_new(dev, gsize, flags | OMAP_BO_EXT_MEM); | |
1546 | + if (obj) { | |
1547 | + struct omap_gem_object *omap_obj = to_omap_bo(obj); | |
1548 | + omap_obj->paddr = paddr; | |
1549 | + omap_obj->pages = pages; | |
1550 | + omap_obj->ops = ops; | |
1551 | + } | |
1552 | + return obj; | |
1553 | +} | |
1554 | +EXPORT_SYMBOL(omap_gem_new_ext); | |
1555 | + | |
1556 | +void omap_gem_vm_open(struct vm_area_struct *vma) | |
1557 | +{ | |
1558 | + struct drm_gem_object *obj = vma->vm_private_data; | |
1559 | + struct omap_gem_object *omap_obj = to_omap_bo(obj); | |
1560 | + | |
1561 | + if (omap_obj->ops && omap_obj->ops->open) | |
1562 | + omap_obj->ops->open(vma); | |
1563 | + else | |
1564 | + drm_gem_vm_open(vma); | |
1565 | + | |
1566 | +} | |
1567 | + | |
1568 | +void omap_gem_vm_close(struct vm_area_struct *vma) | |
1569 | +{ | |
1570 | + struct drm_gem_object *obj = vma->vm_private_data; | |
1571 | + struct omap_gem_object *omap_obj = to_omap_bo(obj); | |
1572 | + | |
1573 | + if (omap_obj->ops && omap_obj->ops->close) | |
1574 | + omap_obj->ops->close(vma); | |
1575 | + else | |
1576 | + drm_gem_vm_close(vma); | |
1577 | + | |
1578 | +} | |
1579 | + | |
1580 | +void *omap_gem_priv(struct drm_gem_object *obj, int mapper_id) | |
1581 | +{ | |
1582 | + BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0)); | |
1583 | + return to_omap_bo(obj)->priv[mapper_id]; | |
1584 | +} | |
1585 | +EXPORT_SYMBOL(omap_gem_priv); | |
1586 | + | |
1587 | +void omap_gem_set_priv(struct drm_gem_object *obj, int mapper_id, void *priv) | |
1588 | +{ | |
1589 | + BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0)); | |
1590 | + to_omap_bo(obj)->priv[mapper_id] = priv; | |
1591 | +} | |
1592 | +EXPORT_SYMBOL(omap_gem_set_priv); |
include/uapi/drm/omap_drm.h
... | ... | @@ -33,6 +33,12 @@ |
33 | 33 | uint64_t value; /* in (set_param), out (get_param) */ |
34 | 34 | }; |
35 | 35 | |
36 | +struct drm_omap_get_base { | |
37 | + char plugin_name[64]; /* in */ | |
38 | + uint32_t ioctl_base; /* out */ | |
39 | + uint32_t __pad; | |
40 | +}; | |
41 | + | |
36 | 42 | #define OMAP_BO_SCANOUT 0x00000001 /* scanout capable (phys contiguous) */ |
37 | 43 | #define OMAP_BO_CACHE_MASK 0x00000006 /* cache type mask, see cache modes */ |
38 | 44 | #define OMAP_BO_TILED_MASK 0x00000f00 /* tiled mapping mask, see tiled modes */ |
39 | 45 | |
... | ... | @@ -101,9 +107,7 @@ |
101 | 107 | |
102 | 108 | #define DRM_OMAP_GET_PARAM 0x00 |
103 | 109 | #define DRM_OMAP_SET_PARAM 0x01 |
104 | -/* placeholder for plugin-api | |
105 | 110 | #define DRM_OMAP_GET_BASE 0x02 |
106 | -*/ | |
107 | 111 | #define DRM_OMAP_GEM_NEW 0x03 |
108 | 112 | #define DRM_OMAP_GEM_CPU_PREP 0x04 |
109 | 113 | #define DRM_OMAP_GEM_CPU_FINI 0x05 |
110 | 114 | |
... | ... | @@ -112,9 +116,7 @@ |
112 | 116 | |
113 | 117 | #define DRM_IOCTL_OMAP_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GET_PARAM, struct drm_omap_param) |
114 | 118 | #define DRM_IOCTL_OMAP_SET_PARAM DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_SET_PARAM, struct drm_omap_param) |
115 | -/* placeholder for plugin-api | |
116 | 119 | #define DRM_IOCTL_OMAP_GET_BASE DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GET_BASE, struct drm_omap_get_base) |
117 | -*/ | |
118 | 120 | #define DRM_IOCTL_OMAP_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GEM_NEW, struct drm_omap_gem_new) |
119 | 121 | #define DRM_IOCTL_OMAP_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_GEM_CPU_PREP, struct drm_omap_gem_cpu_prep) |
120 | 122 | #define DRM_IOCTL_OMAP_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_GEM_CPU_FINI, struct drm_omap_gem_cpu_fini) |