aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/msm_gem.c
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2013-07-19 12:59:32 -0400
committerRob Clark <robdclark@gmail.com>2013-08-24 14:57:18 -0400
commit7198e6b03155f6dadecadba004eb83b81a6ffe4c (patch)
treeed4ae3e859fd9a722524242a145008d13606a95a /drivers/gpu/drm/msm/msm_gem.c
parent902e6eb851a78ad9e3db006c1e1df71841f633e2 (diff)
drm/msm: add a3xx gpu support
Add initial support for a3xx 3d core. So far, with hardware that I've seen to date, we can have: + zero, one, or two z180 2d cores + a3xx or a2xx 3d core, which share a common CP (the firmware for the CP seems to implement some different PM4 packet types but the basics of cmdstream submission are the same) Which means that the eventual complete "class" hierarchy, once support for all past and present hw is in place, becomes: + msm_gpu + adreno_gpu + a3xx_gpu + a2xx_gpu + z180_gpu This commit splits out the parts that will eventually be common between a2xx/a3xx into adreno_gpu, and the parts that are even common to z180 into msm_gpu. Note that there is no cmdstream validation required. All memory access from the GPU is via IOMMU/MMU. So as long as you don't map silly things to the GPU, there isn't much damage that the GPU can do. Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem.c')
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c84
1 files changed, 80 insertions, 4 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index a52e6cca8403..6b5a6c8c7658 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -20,6 +20,7 @@
20 20
21#include "msm_drv.h" 21#include "msm_drv.h"
22#include "msm_gem.h" 22#include "msm_gem.h"
23#include "msm_gpu.h"
23 24
24 25
25/* called with dev->struct_mutex held */ 26/* called with dev->struct_mutex held */
@@ -375,10 +376,74 @@ int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
375{ 376{
376 struct drm_device *dev = obj->dev; 377 struct drm_device *dev = obj->dev;
377 struct msm_drm_private *priv = dev->dev_private; 378 struct msm_drm_private *priv = dev->dev_private;
379 struct msm_gem_object *msm_obj = to_msm_bo(obj);
380 int ret = 0;
381
382 mutex_lock(&dev->struct_mutex);
383 if (!list_empty(&work->entry)) {
384 ret = -EINVAL;
385 } else if (is_active(msm_obj)) {
386 list_add_tail(&work->entry, &msm_obj->inactive_work);
387 } else {
388 queue_work(priv->wq, work);
389 }
390 mutex_unlock(&dev->struct_mutex);
391
392 return ret;
393}
394
395void msm_gem_move_to_active(struct drm_gem_object *obj,
396 struct msm_gpu *gpu, uint32_t fence)
397{
398 struct msm_gem_object *msm_obj = to_msm_bo(obj);
399 msm_obj->gpu = gpu;
400 msm_obj->fence = fence;
401 list_del_init(&msm_obj->mm_list);
402 list_add_tail(&msm_obj->mm_list, &gpu->active_list);
403}
404
405void msm_gem_move_to_inactive(struct drm_gem_object *obj)
406{
407 struct drm_device *dev = obj->dev;
408 struct msm_drm_private *priv = dev->dev_private;
409 struct msm_gem_object *msm_obj = to_msm_bo(obj);
410
411 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
412
413 msm_obj->gpu = NULL;
414 msm_obj->fence = 0;
415 list_del_init(&msm_obj->mm_list);
416 list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
417
418 while (!list_empty(&msm_obj->inactive_work)) {
419 struct work_struct *work;
420
421 work = list_first_entry(&msm_obj->inactive_work,
422 struct work_struct, entry);
423
424 list_del_init(&work->entry);
425 queue_work(priv->wq, work);
426 }
427}
428
429int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
430 struct timespec *timeout)
431{
432 struct drm_device *dev = obj->dev;
433 struct msm_gem_object *msm_obj = to_msm_bo(obj);
434 int ret = 0;
435
436 if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC))
437 ret = msm_wait_fence_interruptable(dev, msm_obj->fence, timeout);
438
439 /* TODO cache maintenance */
378 440
379 /* just a place-holder until we have gpu.. */ 441 return ret;
380 queue_work(priv->wq, work); 442}
381 443
444int msm_gem_cpu_fini(struct drm_gem_object *obj)
445{
446 /* TODO cache maintenance */
382 return 0; 447 return 0;
383} 448}
384 449
@@ -390,8 +455,9 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
390 uint64_t off = drm_vma_node_start(&obj->vma_node); 455 uint64_t off = drm_vma_node_start(&obj->vma_node);
391 456
392 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 457 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
393 seq_printf(m, "%08x: %2d (%2d) %08llx %p %d\n", 458 seq_printf(m, "%08x: %c(%d) %2d (%2d) %08llx %p %d\n",
394 msm_obj->flags, obj->name, obj->refcount.refcount.counter, 459 msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
460 msm_obj->fence, obj->name, obj->refcount.refcount.counter,
395 off, msm_obj->vaddr, obj->size); 461 off, msm_obj->vaddr, obj->size);
396} 462}
397 463
@@ -421,6 +487,9 @@ void msm_gem_free_object(struct drm_gem_object *obj)
421 487
422 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 488 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
423 489
490 /* object should not be on active list: */
491 WARN_ON(is_active(msm_obj));
492
424 list_del(&msm_obj->mm_list); 493 list_del(&msm_obj->mm_list);
425 494
426 for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) { 495 for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) {
@@ -439,6 +508,9 @@ void msm_gem_free_object(struct drm_gem_object *obj)
439 508
440 put_pages(obj); 509 put_pages(obj);
441 510
511 if (msm_obj->resv == &msm_obj->_resv)
512 reservation_object_fini(msm_obj->resv);
513
442 drm_gem_object_release(obj); 514 drm_gem_object_release(obj);
443 515
444 kfree(msm_obj); 516 kfree(msm_obj);
@@ -508,7 +580,11 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev,
508 580
509 msm_obj->flags = flags; 581 msm_obj->flags = flags;
510 582
583 msm_obj->resv = &msm_obj->_resv;
584 reservation_object_init(msm_obj->resv);
511 585
586 INIT_LIST_HEAD(&msm_obj->submit_entry);
587 INIT_LIST_HEAD(&msm_obj->inactive_work);
512 list_add_tail(&msm_obj->mm_list, &priv->inactive_list); 588 list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
513 589
514 return obj; 590 return obj;