[Freedreno] [PATCH 2/2] drm/msm: subclass work object for vblank events

2018-10-31 Thread Jeykumar Sankaran
msm maintains a separate structure to define vblank
work definitions and a list to track events submitted
to the display worker thread. We can avoid these
redundant list and its protection mechanism, if we
subclass the work object to encapsulate vblank
event parameters.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 70 ---
 drivers/gpu/drm/msm/msm_drv.h |  7 -
 2 files changed, 19 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1f384b3..67a96ee 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -203,61 +203,44 @@ u32 msm_readl(const void __iomem *addr)
return val;
 }
 
-struct vblank_event {
-   struct list_head node;
+struct msm_vblank_work {
+   struct kthread_work work;
int crtc_id;
bool enable;
+   struct msm_drm_private *priv;
 };
 
 static void vblank_ctrl_worker(struct kthread_work *work)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
-   struct msm_vblank_ctrl, work);
-   struct msm_drm_private *priv = container_of(vbl_ctrl,
-   struct msm_drm_private, vblank_ctrl);
+   struct msm_vblank_work *vbl_work = container_of(work,
+   struct msm_vblank_work, work);
+   struct msm_drm_private *priv = vbl_work->priv;
struct msm_kms *kms = priv->kms;
-   struct vblank_event *vbl_ev, *tmp;
-   unsigned long flags;
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
-
-   if (vbl_ev->enable)
-   kms->funcs->enable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
-   else
-   kms->funcs->disable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
 
-   kfree(vbl_ev);
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   }
+   if (vbl_work->enable)
+   kms->funcs->enable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
+   else
+   kms->funcs->disable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
 
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   kfree(vbl_work);
 }
 
 static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
int crtc_id, bool enable)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev;
-   unsigned long flags;
+   struct msm_vblank_work *vbl_work;
 
-   vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);
-   if (!vbl_ev)
+   vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
+   if (!vbl_work)
return -ENOMEM;
 
-   vbl_ev->crtc_id = crtc_id;
-   vbl_ev->enable = enable;
+   kthread_init_work(_work->work, vblank_ctrl_worker);
 
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_add_tail(_ev->node, _ctrl->event_list);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   vbl_work->crtc_id = crtc_id;
+   vbl_work->enable = enable;
+   vbl_work->priv = priv;
 
-   kthread_queue_work(>disp_thread.worker, _ctrl->work);
+   kthread_queue_work(>disp_thread.worker, _work->work);
 
return 0;
 }
@@ -269,20 +252,8 @@ static int msm_drm_uninit(struct device *dev)
struct msm_drm_private *priv = ddev->dev_private;
struct msm_kms *kms = priv->kms;
struct msm_mdss *mdss = priv->mdss;
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev, *tmp;
int i;
 
-   /* We must cancel and cleanup any pending vblank enable/disable
-* work before drm_irq_uninstall() to avoid work re-enabling an
-* irq after uninstall has disabled it.
-*/
-   kthread_flush_work(_ctrl->work);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   kfree(vbl_ev);
-   }
-
kthread_flush_worker(>disp_thread.worker);
kthread_stop(priv->disp_thread.thread);
priv->disp_thread.thread = NULL;
@@ -474,9 +445,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
priv->wq = alloc_ordered_workqueue("msm", 0);
 
INIT_LIST_HEAD(>inactive_list);
-   INIT_LIST_HEAD(>vblank_ctrl.event_list);
-   kthread_init_work(>vblank_ctrl.work, vblank_ctrl_worker);
-   spin_lock_init(>vblank_ctrl.lock);
 
drm_mode_config_init(ddev);
 
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index e81b1fa..b91e306 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -77,12 

[Freedreno] [PATCH 1/2] drm/msm: use common display thread for dispatching vblank events

2018-10-31 Thread Jeykumar Sankaran
DPU was using one thread per display to dispatch async
commits and vblank requests. Since clean up already happened
in msm to use the common thread for all the display commits,
display threads are only used to cater vblank requests. Single
thread is sufficient to do the job without any performance hits.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  6 +---
 drivers/gpu/drm/msm/msm_drv.c   | 50 -
 drivers/gpu/drm/msm/msm_drv.h   |  2 +-
 3 files changed, 23 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 82c55ef..aff20f5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -753,11 +753,7 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
is_vid_mode = dpu_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE;
 
-   if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
-   DPU_ERROR("invalid crtc index\n");
-   return -EINVAL;
-   }
-   disp_thread = >disp_thread[drm_enc->crtc->index];
+   disp_thread = >disp_thread;
 
/*
 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9c9f7ff..1f384b3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -257,8 +257,7 @@ static int vblank_ctrl_queue_work(struct msm_drm_private 
*priv,
list_add_tail(_ev->node, _ctrl->event_list);
spin_unlock_irqrestore(_ctrl->lock, flags);
 
-   kthread_queue_work(>disp_thread[crtc_id].worker,
-   _ctrl->work);
+   kthread_queue_work(>disp_thread.worker, _ctrl->work);
 
return 0;
 }
@@ -284,14 +283,12 @@ static int msm_drm_uninit(struct device *dev)
kfree(vbl_ev);
}
 
+   kthread_flush_worker(>disp_thread.worker);
+   kthread_stop(priv->disp_thread.thread);
+   priv->disp_thread.thread = NULL;
+
/* clean up display commit/event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
-   if (priv->disp_thread[i].thread) {
-   kthread_flush_worker(>disp_thread[i].worker);
-   kthread_stop(priv->disp_thread[i].thread);
-   priv->disp_thread[i].thread = NULL;
-   }
-
if (priv->event_thread[i].thread) {
kthread_flush_worker(>event_thread[i].worker);
kthread_stop(priv->event_thread[i].thread);
@@ -537,6 +534,22 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
ddev->mode_config.funcs = _config_funcs;
ddev->mode_config.helper_private = _config_helper_funcs;
 
+   /* initialize display thread */
+   kthread_init_worker(>disp_thread.worker);
+   priv->disp_thread.dev = ddev;
+   priv->disp_thread.thread = kthread_run(kthread_worker_fn,
+  >disp_thread.worker,
+  "disp_thread");
+   if (IS_ERR(priv->disp_thread.thread)) {
+   DRM_DEV_ERROR(dev, "failed to create crtc_commit kthread\n");
+   priv->disp_thread.thread = NULL;
+   goto err_msm_uninit;
+   }
+
+   ret = sched_setscheduler(priv->disp_thread.thread, SCHED_FIFO, );
+   if (ret)
+   pr_warn("display thread priority update failed: %d\n", ret);
+
/**
 * this priority was found during empiric testing to have appropriate
 * realtime scheduling to process display updates and interact with
@@ -544,27 +557,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
 */
param.sched_priority = 16;
for (i = 0; i < priv->num_crtcs; i++) {
-
-   /* initialize display thread */
-   priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id;
-   kthread_init_worker(>disp_thread[i].worker);
-   priv->disp_thread[i].dev = ddev;
-   priv->disp_thread[i].thread =
-   kthread_run(kthread_worker_fn,
-   >disp_thread[i].worker,
-   "crtc_commit:%d", priv->disp_thread[i].crtc_id);
-   if (IS_ERR(priv->disp_thread[i].thread)) {
-   DRM_DEV_ERROR(dev, "failed to create crtc_commit 
kthread\n");
-   priv->disp_thread[i].thread = NULL;
-   goto err_msm_uninit;
-   }
-
-   ret = sched_setscheduler(priv->disp_thread[i].thread,
-SCHED_FIFO, );
-   if (ret)
-   dev_warn(dev, "disp_thread set priority 

[Freedreno] [PATCH 6/6] drm/msm: Count how many times iova memory is pinned

2018-10-31 Thread Jordan Crouse
Add a reference count to track how many times a particular
chunk of iova memory is pinned (mapped) in the iomu and
add msm_gem_unpin_iova to give up references.

It is important to note that msm_gem_unpin_iova replaces
msm_gem_put_iova because the new implicit behavior
that an assigned iova in a given vma is now valid for the
life of the buffer and what we are really focusing on is
the use of that iova.

For now the unmappings are lazy; once the reference counts
go to zero they *COULD* be unmapped dynamically but that
will require an outside force such as a shrinker or
mm_notifiers.  For now, we're just focusing on getting
the counting right and setting ourselves up to be ready
for the future.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/a5xx_debugfs.c |  6 +--
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  9 ++--
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c |  3 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c |  2 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c  |  2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c |  2 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c|  2 +-
 drivers/gpu/drm/msm/msm_drv.h |  8 +++-
 drivers/gpu/drm/msm/msm_fb.c  |  2 +-
 drivers/gpu/drm/msm/msm_gem.c | 43 ---
 drivers/gpu/drm/msm/msm_gem.h |  1 +
 drivers/gpu/drm/msm/msm_gem_submit.c  |  2 +-
 drivers/gpu/drm/msm/msm_gem_vma.c | 51 +--
 drivers/gpu/drm/msm/msm_gpu.c |  2 +-
 14 files changed, 87 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c 
b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
index 6983cd9102bd..d9af3aff690f 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
@@ -130,15 +130,13 @@ reset_set(void *data, u64 val)
adreno_gpu->fw[ADRENO_FW_PFP] = NULL;
 
if (a5xx_gpu->pm4_bo) {
-   if (a5xx_gpu->pm4_iova)
-   msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
+   msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);
drm_gem_object_put(a5xx_gpu->pm4_bo);
a5xx_gpu->pm4_bo = NULL;
}
 
if (a5xx_gpu->pfp_bo) {
-   if (a5xx_gpu->pfp_iova)
-   msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace);
+   msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);
drm_gem_object_put(a5xx_gpu->pfp_bo);
a5xx_gpu->pfp_bo = NULL;
}
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index d6f8dedc028a..135496393cf3 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -841,20 +841,17 @@ static void a5xx_destroy(struct msm_gpu *gpu)
a5xx_preempt_fini(gpu);
 
if (a5xx_gpu->pm4_bo) {
-   if (a5xx_gpu->pm4_iova)
-   msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
+   msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);
drm_gem_object_put_unlocked(a5xx_gpu->pm4_bo);
}
 
if (a5xx_gpu->pfp_bo) {
-   if (a5xx_gpu->pfp_iova)
-   msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace);
+   msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);
drm_gem_object_put_unlocked(a5xx_gpu->pfp_bo);
}
 
if (a5xx_gpu->gpmu_bo) {
-   if (a5xx_gpu->gpmu_iova)
-   msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
+   msm_gem_unpin_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
drm_gem_object_put_unlocked(a5xx_gpu->gpmu_bo);
}
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 38b7a5a92bfb..9acf12c21b23 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -746,8 +746,7 @@ static void a6xx_destroy(struct msm_gpu *gpu)
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
 
if (a6xx_gpu->sqe_bo) {
-   if (a6xx_gpu->sqe_iova)
-   msm_gem_put_iova(a6xx_gpu->sqe_bo, gpu->aspace);
+   msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
drm_gem_object_put_unlocked(a6xx_gpu->sqe_bo);
}
 
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
index ef6884f1fc34..8f2359dc87b4 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
@@ -128,7 +128,7 @@ static void unref_cursor_worker(struct drm_flip_work *work, 
void *val)
struct mdp4_kms *mdp4_kms = get_kms(_crtc->base);
struct msm_kms *kms = _kms->base.base;
 
-   msm_gem_put_iova(val, kms->aspace);
+   msm_gem_unpin_iova(val, kms->aspace);
drm_gem_object_put_unlocked(val);
 }
 
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c 

[Freedreno] [PATCH 5/6] drm/msm: Add msm_gem_get_and_pin_iova()

2018-10-31 Thread Jordan Crouse
Add a new function to get and pin the iova memory in one
step (basically renaming the old msm_gem_get_iova function)
and switch msm_gem_get_iova() to only allocate an iova but
not map it in the IOMMU. This is only currently used by
msm_ioctl_gem_info() since all other users of of the iova
expect that the memory be immediately available.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c   |  3 ++-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c |  4 ++--
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c  |  2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c |  2 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c|  2 +-
 drivers/gpu/drm/msm/msm_drv.c |  4 
 drivers/gpu/drm/msm/msm_drv.h |  2 ++
 drivers/gpu/drm/msm/msm_fb.c  |  2 +-
 drivers/gpu/drm/msm/msm_fbdev.c   |  2 +-
 drivers/gpu/drm/msm/msm_gem.c | 24 ++-
 drivers/gpu/drm/msm/msm_gem_submit.c  |  2 +-
 drivers/gpu/drm/msm/msm_gpu.c |  2 +-
 12 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 141062fbb4c8..3c2988514fc5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -209,7 +209,8 @@ int adreno_hw_init(struct msm_gpu *gpu)
if (!ring)
continue;
 
-   ret = msm_gem_get_iova(ring->bo, gpu->aspace, >iova);
+   ret = msm_gem_get_and_pin_iova(ring->bo, gpu->aspace,
+   >iova);
if (ret) {
ring->iova = 0;
DRM_DEV_ERROR(gpu->dev->dev,
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
index b91706cee2b8..ef6884f1fc34 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
@@ -384,7 +384,7 @@ static void update_cursor(struct drm_crtc *crtc)
if (next_bo) {
/* take a obj ref + iova ref when we start scanning 
out: */
drm_gem_object_get(next_bo);
-   msm_gem_get_iova(next_bo, kms->aspace, );
+   msm_gem_get_and_pin_iova(next_bo, kms->aspace, );
 
/* enable cursor: */
mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma),
@@ -442,7 +442,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
}
 
if (cursor_bo) {
-   ret = msm_gem_get_iova(cursor_bo, kms->aspace, );
+   ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, );
if (ret)
goto fail;
} else {
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index 481c0d231149..9fd6b9b2dbcb 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -538,7 +538,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
goto fail;
}
 
-   ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, kms->aspace,
+   ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->aspace,
_kms->blank_cursor_iova);
if (ret) {
DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", 
ret);
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 413b52211017..c7cc276575fb 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -903,7 +903,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
if (!cursor_bo)
return -ENOENT;
 
-   ret = msm_gem_get_iova(cursor_bo, kms->aspace,
+   ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace,
_crtc->cursor.iova);
if (ret)
return -EINVAL;
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index eba901584035..99122767abf4 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1248,7 +1248,7 @@ int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, 
uint64_t *dma_base)
if (!dma_base)
return -EINVAL;
 
-   return msm_gem_get_iova(msm_host->tx_gem_obj,
+   return msm_gem_get_and_pin_iova(msm_host->tx_gem_obj,
priv->kms->aspace, dma_base);
 }
 
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9c9f7ff6960b..f2ebfb9ba0e4 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -849,6 +849,10 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev,
if (!priv->gpu)
return -EINVAL;
 
+   /*
+* Don't pin the memory here - just get an address so that userspace can
+* be productive
+

[Freedreno] [PATCH 3/6] drm/msm: Split msm_gem_get_iova into two steps

2018-10-31 Thread Jordan Crouse
Split the operation of msm_gem_get_iova into two operations:
1) allocate an iova and 2) map (pin) the backing memory int the
iommu. This is the first step toward allowing memory pinning
to occur independently of the iova management.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/msm_drv.h |  2 +
 drivers/gpu/drm/msm/msm_gem.c | 80 ---
 drivers/gpu/drm/msm/msm_gem.h |  1 +
 drivers/gpu/drm/msm/msm_gem_vma.c | 44 -
 4 files changed, 86 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 3a0f2119127b..63b28b69b2ab 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -241,6 +241,8 @@ struct drm_atomic_state *msm_atomic_state_alloc(struct 
drm_device *dev);
 void msm_atomic_state_clear(struct drm_atomic_state *state);
 void msm_atomic_state_free(struct drm_atomic_state *state);
 
+int msm_gem_init_vma(struct msm_gem_address_space *aspace,
+   struct msm_gem_vma *vma, int npages);
 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma);
 int msm_gem_map_vma(struct msm_gem_address_space *aspace,
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index ff75e557b708..189d7f0f1aad 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -357,52 +357,76 @@ put_iova(struct drm_gem_object *obj)
}
 }
 
-/* get iova, taking a reference.  Should have a matching put */
-int msm_gem_get_iova(struct drm_gem_object *obj,
+static int msm_gem_get_iova_locked(struct drm_gem_object *obj,
struct msm_gem_address_space *aspace, uint64_t *iova)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
struct msm_gem_vma *vma;
int ret = 0;
 
-   mutex_lock(_obj->lock);
-
-   if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) {
-   mutex_unlock(_obj->lock);
-   return -EBUSY;
-   }
+   WARN_ON(!mutex_is_locked(_obj->lock));
 
vma = lookup_vma(obj, aspace);
 
if (!vma) {
-   struct page **pages;
-
vma = add_vma(obj, aspace);
-   if (IS_ERR(vma)) {
-   ret = PTR_ERR(vma);
-   goto unlock;
-   }
+   if (IS_ERR(vma))
+   return PTR_ERR(vma);
 
-   pages = get_pages(obj);
-   if (IS_ERR(pages)) {
-   ret = PTR_ERR(pages);
-   goto fail;
+   ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT);
+   if (ret) {
+   del_vma(vma);
+   return ret;
}
-
-   ret = msm_gem_map_vma(aspace, vma, msm_obj->sgt,
-   obj->size >> PAGE_SHIFT);
-   if (ret)
-   goto fail;
}
 
*iova = vma->iova;
-
-   mutex_unlock(_obj->lock);
return 0;
+}
+
+static int msm_gem_pin_iova(struct drm_gem_object *obj,
+   struct msm_gem_address_space *aspace)
+{
+   struct msm_gem_object *msm_obj = to_msm_bo(obj);
+   struct msm_gem_vma *vma;
+   struct page **pages;
+
+   WARN_ON(!mutex_is_locked(_obj->lock));
+
+   if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED))
+   return -EBUSY;
+
+   vma = lookup_vma(obj, aspace);
+   if (WARN_ON(!vma))
+   return -EINVAL;
+
+   pages = get_pages(obj);
+   if (IS_ERR(pages))
+   return PTR_ERR(pages);
+
+   return msm_gem_map_vma(aspace, vma, msm_obj->sgt,
+   obj->size >> PAGE_SHIFT);
+}
+
+
+/* get iova, taking a reference.  Should have a matching put */
+int msm_gem_get_iova(struct drm_gem_object *obj,
+   struct msm_gem_address_space *aspace, uint64_t *iova)
+{
+   struct msm_gem_object *msm_obj = to_msm_bo(obj);
+   u64 local;
+   int ret;
+
+   mutex_lock(_obj->lock);
+
+   ret = msm_gem_get_iova_locked(obj, aspace, );
+
+   if (!ret)
+   ret = msm_gem_pin_iova(obj, aspace);
+
+   if (!ret)
+   *iova = local;
 
-fail:
-   del_vma(vma);
-unlock:
mutex_unlock(_obj->lock);
return ret;
 }
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index c5d9bd3e47a8..32c13e6559b5 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -41,6 +41,7 @@ struct msm_gem_vma {
uint64_t iova;
struct msm_gem_address_space *aspace;
struct list_head list;/* node in msm_gem_object::vmas */
+   bool mapped;
 };
 
 struct msm_gem_object {
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index 704ae7e69500..c4c42bf0db0e 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -55,6 +55,7 @@ 

[Freedreno] [PATCH 0/6] RFC: drm/msm: separate iova allocation and mapping

2018-10-31 Thread Jordan Crouse
Currently in the msm driver iova addresses are mapped in the IOMMU at
allocation time and stay there for the life of the buffer. This may not
be desirable for long lived user space buffers that could be temporarily
swapped or moved.

This first set of patches breaks up the allocation and mapping into
distinct steps and adds reference counting for pinning and unpinning
the memory. Future code can use this information to manipulate the
memory when it isn't in use.

Jordan Crouse (6):
  drm/msm: Add a common function to free kernel buffer objects
  drm/msm: Remove sgt from the mmu unmap function
  drm/msm: Split msm_gem_get_iova into two steps
  drm/msm: Clean up and enhance the output of the 'gem' debugfs node
  drm/msm: Add msm_gem_get_and_pin_iova()
  drm/msm: Count how many times iova memory is pinned

 drivers/gpu/drm/msm/adreno/a5xx_debugfs.c |   6 +-
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  22 +--
 drivers/gpu/drm/msm/adreno/a5xx_power.c   |  13 +-
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c |  14 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c |   3 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c   |   3 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c |   6 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c  |   4 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c |   4 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c|   4 +-
 drivers/gpu/drm/msm/msm_drv.c |   4 +
 drivers/gpu/drm/msm/msm_drv.h |  16 ++-
 drivers/gpu/drm/msm/msm_fb.c  |   4 +-
 drivers/gpu/drm/msm/msm_fbdev.c   |   2 +-
 drivers/gpu/drm/msm/msm_gem.c | 162 --
 drivers/gpu/drm/msm/msm_gem.h |   2 +
 drivers/gpu/drm/msm/msm_gem_submit.c  |   4 +-
 drivers/gpu/drm/msm/msm_gem_vma.c |  95 +
 drivers/gpu/drm/msm/msm_gpu.c |  16 +--
 drivers/gpu/drm/msm/msm_iommu.c   |   3 +-
 drivers/gpu/drm/msm/msm_mmu.h |   3 +-
 drivers/gpu/drm/msm/msm_ringbuffer.c  |   7 +-
 22 files changed, 242 insertions(+), 155 deletions(-)

-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 1/6] drm/msm: Add a common function to free kernel buffer objects

2018-10-31 Thread Jordan Crouse
Buffer objects allocated with msm_gem_kernel_new() are mostly
freed the same way so we can save a few lines of code with a
common function.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 13 ++---
 drivers/gpu/drm/msm/adreno/a5xx_power.c   | 13 +
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 14 ++
 drivers/gpu/drm/msm/msm_drv.h |  2 ++
 drivers/gpu/drm/msm/msm_gem.c | 15 +++
 drivers/gpu/drm/msm/msm_gpu.c | 12 ++--
 drivers/gpu/drm/msm/msm_ringbuffer.c  |  7 ++-
 7 files changed, 26 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 2d34643ef2e2..d6f8dedc028a 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1228,15 +1228,6 @@ static int a5xx_crashdumper_init(struct msm_gpu *gpu,
return 0;
 }
 
-static void a5xx_crashdumper_free(struct msm_gpu *gpu,
-   struct a5xx_crashdumper *dumper)
-{
-   msm_gem_put_iova(dumper->bo, gpu->aspace);
-   msm_gem_put_vaddr(dumper->bo);
-
-   drm_gem_object_put(dumper->bo);
-}
-
 static int a5xx_crashdumper_run(struct msm_gpu *gpu,
struct a5xx_crashdumper *dumper)
 {
@@ -1329,7 +1320,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu 
*gpu,
 
if (a5xx_crashdumper_run(gpu, )) {
kfree(a5xx_state->hlsqregs);
-   a5xx_crashdumper_free(gpu, );
+   msm_gem_kernel_put(dumper.bo, gpu->aspace, true);
return;
}
 
@@ -1337,7 +1328,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu 
*gpu,
memcpy(a5xx_state->hlsqregs, dumper.ptr + (256 * SZ_1K),
count * sizeof(u32));
 
-   a5xx_crashdumper_free(gpu, );
+   msm_gem_kernel_put(dumper.bo, gpu->aspace, true);
 }
 
 static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c 
b/drivers/gpu/drm/msm/adreno/a5xx_power.c
index 7a41e1c147e4..66bcd88dd8c0 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_power.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c
@@ -298,7 +298,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace,
_gpu->gpmu_bo, _gpu->gpmu_iova);
if (IS_ERR(ptr))
-   goto err;
+   return;
 
while (cmds_size > 0) {
int i;
@@ -317,15 +317,4 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
 
msm_gem_put_vaddr(a5xx_gpu->gpmu_bo);
a5xx_gpu->gpmu_dwords = dwords;
-
-   return;
-err:
-   if (a5xx_gpu->gpmu_iova)
-   msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
-   if (a5xx_gpu->gpmu_bo)
-   drm_gem_object_put(a5xx_gpu->gpmu_bo);
-
-   a5xx_gpu->gpmu_bo = NULL;
-   a5xx_gpu->gpmu_iova = 0;
-   a5xx_gpu->gpmu_dwords = 0;
 }
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c 
b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
index fdb08fc68c2c..48481e663685 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
@@ -267,18 +267,8 @@ void a5xx_preempt_fini(struct msm_gpu *gpu)
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
int i;
 
-   for (i = 0; i < gpu->nr_rings; i++) {
-   if (!a5xx_gpu->preempt_bo[i])
-   continue;
-
-   msm_gem_put_vaddr(a5xx_gpu->preempt_bo[i]);
-
-   if (a5xx_gpu->preempt_iova[i])
-   msm_gem_put_iova(a5xx_gpu->preempt_bo[i], gpu->aspace);
-
-   drm_gem_object_put(a5xx_gpu->preempt_bo[i]);
-   a5xx_gpu->preempt_bo[i] = NULL;
-   }
+   for (i = 0; i < gpu->nr_rings; i++)
+   msm_gem_kernel_put(a5xx_gpu->preempt_bo[i], gpu->aspace, true);
 }
 
 void a5xx_preempt_init(struct msm_gpu *gpu)
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9d11f321f5a9..3225f8fbd8c9 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -312,6 +312,8 @@ void *msm_gem_kernel_new(struct drm_device *dev, uint32_t 
size,
 void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
uint32_t flags, struct msm_gem_address_space *aspace,
struct drm_gem_object **bo, uint64_t *iova);
+void msm_gem_kernel_put(struct drm_gem_object *bo,
+   struct msm_gem_address_space *aspace, bool locked);
 struct drm_gem_object *msm_gem_import(struct drm_device *dev,
struct dma_buf *dmabuf, struct sg_table *sgt);
 
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 00c795ced02c..855f5721a14e 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1073,3 +1073,18 @@ void *msm_gem_kernel_new_locked(struct drm_device *dev, 

[Freedreno] [PATCH 2/6] drm/msm: Remove sgt from the mmu unmap function

2018-10-31 Thread Jordan Crouse
The scatter gather table doesn't need to be passed in for the
MMU unmap function.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/msm_drv.h | 2 +-
 drivers/gpu/drm/msm/msm_gem.c | 2 +-
 drivers/gpu/drm/msm/msm_gem_vma.c | 4 ++--
 drivers/gpu/drm/msm/msm_iommu.c   | 3 +--
 drivers/gpu/drm/msm/msm_mmu.h | 3 +--
 5 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 3225f8fbd8c9..3a0f2119127b 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -242,7 +242,7 @@ void msm_atomic_state_clear(struct drm_atomic_state *state);
 void msm_atomic_state_free(struct drm_atomic_state *state);
 
 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
-   struct msm_gem_vma *vma, struct sg_table *sgt);
+   struct msm_gem_vma *vma);
 int msm_gem_map_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt, int npages);
 
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 855f5721a14e..ff75e557b708 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -352,7 +352,7 @@ put_iova(struct drm_gem_object *obj)
WARN_ON(!mutex_is_locked(_obj->lock));
 
list_for_each_entry_safe(vma, tmp, _obj->vmas, list) {
-   msm_gem_unmap_vma(vma->aspace, vma, msm_obj->sgt);
+   msm_gem_unmap_vma(vma->aspace, vma);
del_vma(vma);
}
 }
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index ffbec224551b..704ae7e69500 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -40,14 +40,14 @@ void msm_gem_address_space_put(struct msm_gem_address_space 
*aspace)
 
 void
 msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
-   struct msm_gem_vma *vma, struct sg_table *sgt)
+   struct msm_gem_vma *vma)
 {
if (!aspace || !vma->iova)
return;
 
if (aspace->mmu) {
unsigned size = vma->node.size << PAGE_SHIFT;
-   aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt, size);
+   aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, size);
}
 
spin_lock(>lock);
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index b23d33622f37..9c313cb129ee 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -71,8 +71,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
return (ret == len) ? 0 : -EINVAL;
 }
 
-static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
-   struct sg_table *sgt, unsigned len)
+static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len)
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index aa2c5d4580c8..94c0b83d8026 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -25,8 +25,7 @@ struct msm_mmu_funcs {
void (*detach)(struct msm_mmu *mmu, const char * const *names, int cnt);
int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
unsigned len, int prot);
-   int (*unmap)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
-   unsigned len);
+   int (*unmap)(struct msm_mmu *mmu, uint64_t iova, unsigned len);
void (*destroy)(struct msm_mmu *mmu);
 };
 
-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 4/6] drm/msm: Clean up and enhance the output of the 'gem' debugfs node

2018-10-31 Thread Jordan Crouse
Add headers for the 'gem' debugfs file to make it easier to remember
what all the values mean and move the list of virtual address regions
to the next line and add the name and map status to make it clearer
what we are looking at.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/msm_gem.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 189d7f0f1aad..805a300f8663 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -763,16 +763,23 @@ void msm_gem_describe(struct drm_gem_object *obj, struct 
seq_file *m)
break;
}
 
-   seq_printf(m, "%08x: %c %2d (%2d) %08llx %p\t",
+   seq_printf(m, "%08x: %c %2d (%2d) %08llx %p",
msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
obj->name, kref_read(>refcount),
off, msm_obj->vaddr);
 
-   /* FIXME: we need to print the address space here too */
-   list_for_each_entry(vma, _obj->vmas, list)
-   seq_printf(m, " %08llx", vma->iova);
+   seq_printf(m, " %08zu%9s\n", obj->size, madv);
 
-   seq_printf(m, " %zu%s\n", obj->size, madv);
+   if (!list_empty(_obj->vmas)) {
+
+   seq_puts(m, "   vmas:");
+
+   list_for_each_entry(vma, _obj->vmas, list)
+   seq_printf(m, " [%s: %08llx,%s]", vma->aspace->name,
+   vma->iova, vma->mapped ? "mapped" : "unmapped");
+
+   seq_puts(m, "\n");
+   }
 
rcu_read_lock();
fobj = rcu_dereference(robj->fence);
@@ -799,9 +806,10 @@ void msm_gem_describe_objects(struct list_head *list, 
struct seq_file *m)
int count = 0;
size_t size = 0;
 
+   seq_puts(m, "   flags   id ref offset   kaddr   size
madv\n");
list_for_each_entry(msm_obj, list, mm_list) {
struct drm_gem_object *obj = _obj->base;
-   seq_printf(m, "   ");
+   seq_puts(m, "   ");
msm_gem_describe(obj, m);
count++;
size += obj->size;
-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [Mesa-dev] [RFC] freedreno: import libdrm_freedreno + redesign submit

2018-10-31 Thread Emil Velikov
On Tue, 30 Oct 2018 at 18:15, Rob Clark  wrote:
>
> On Tue, Oct 30, 2018 at 1:34 PM Emil Velikov  wrote:
> >
> > On Tue, 30 Oct 2018 at 17:19, Rob Clark  wrote:
> > > On Tue, Oct 30, 2018 at 11:27 AM Emil Velikov  
> > > wrote:
> >
> > > > > > NOTE: if bisecting a build error takes you hear, try a clean build.
> > > > > > There are a bunch of ways things can go wrong if you still have
> > > > > > libdrm_freedreno cflags.
> > > > >
> > > > > Good note!
> > > > > (and s/hear/here/)
> > > > >
> > > > Or to make the note disappear and minimise the chance to even getting
> > > > here you can try the following:
> > > >  - patch 1 - dummy copy, mention the sha used as base
> > > >  - patch 2/3/4 - wire up Autoconf/Android/meson
> > > >  - patch 5/... - polish (remove freedreno_drmif.h includes and others)
> > > >
> > >
> > > fwiw, I'm not planning to remove libdrm_freedreno any time soon,
> > > because (a) new libdrm vs old mesa combo, and (b) I do have some other
> > > small utils that use libdrm_freedreno.  I'm just planning to not
> > > change it.
> > >
> > Fair enough. I guess those tools will not benefit from the reduced CPU
> > cycled, to warrant a rewrite.
> >
> > I would greatly appreciate if you can split things as mentioned earlier 
> > though.
> > After all you've used the exact same approach to create the lot.
> >
>
> Too late on that, it is already merged.  I had considered trying to
> split up into (1) import, plus (2) redesign, but there was too much
> churn related to converting the code over to mesa utils / data
> structures / etc, so I gave up.
>
Well I'm slow - serves me right. The argument sound quite meh... as
said you've already followed that approach while preparing it.

-Emil
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 07/11] drm/msm/a6xx: Add a6xx gpu state

2018-10-31 Thread Sharat Masetty



On 10/17/2018 9:58 PM, Jordan Crouse wrote:

Add support for gathering and dumping the a6xx GPU state including
registers, GMU registers, indexed registers, shader blocks,
context clusters and debugbus.

Signed-off-by: Jordan Crouse 
---
  drivers/gpu/drm/msm/Makefile|1 +
  drivers/gpu/drm/msm/adreno/a6xx_gmu.c   |   25 +-
  drivers/gpu/drm/msm/adreno/a6xx_gmu.h   |3 +
  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   |   39 +-
  drivers/gpu/drm/msm/adreno/a6xx_gpu.h   |8 +
  drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 1159 +++
  drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h |  430 +++
  7 files changed, 1627 insertions(+), 38 deletions(-)
  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 19ab521d4c3a..33645c6539ee 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -14,6 +14,7 @@ msm-y := \
adreno/a6xx_gpu.o \
adreno/a6xx_gmu.o \
adreno/a6xx_hfi.o \
+   adreno/a6xx_gpu_state.o \
hdmi/hdmi.o \
hdmi/hdmi_audio.o \
hdmi/hdmi_bridge.o \
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index d4e98e5876bc..089b013d7bb9 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -51,10 +51,31 @@ static irqreturn_t a6xx_hfi_irq(int irq, void *data)
return IRQ_HANDLED;
  }
  
+bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu)

+{
+   u32 val;
+
+   /* This can be called from gpu state code so make sure GMU is valid */
+   if (IS_ERR_OR_NULL(gmu->mmio))
+   return false;
+
+   val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
+
+   return !(val &
+   (A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SPTPRAC_GDSC_POWER_OFF |
+   A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SP_CLOCK_OFF));
+}
+
  /* Check to see if the GX rail is still powered */
-static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
+bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
  {
-   u32 val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
+   u32 val;
+
+   /* This can be called from gpu state code so make sure GMU is valid */
+   if (IS_ERR_OR_NULL(gmu->mmio))
+   return false;
+
+   val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
  
  	return !(val &

(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF |
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index 35f765afae45..c721d9165d8e 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -164,4 +164,7 @@ void a6xx_hfi_init(struct a6xx_gmu *gmu);
  int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
  void a6xx_hfi_stop(struct a6xx_gmu *gmu);
  
+bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu);

+bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu);
+
  #endif
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 631257c297fd..3afd4df2e250 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -645,33 +645,6 @@ static const u32 
a6xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A6XX_CP_RB_CNTL),
  };
  
-static const u32 a6xx_registers[] = {

-   0x, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0018, 0x001b,
-   0x001e, 0x0032, 0x0038, 0x003c, 0x0042, 0x0042, 0x0044, 0x0044,
-   0x0047, 0x0047, 0x0056, 0x0056, 0x00ad, 0x00ae, 0x00b0, 0x00fb,
-   0x0100, 0x011d, 0x0200, 0x020d, 0x0210, 0x0213, 0x0218, 0x023d,
-   0x0400, 0x04f9, 0x0500, 0x0500, 0x0505, 0x050b, 0x050e, 0x0511,
-   0x0533, 0x0533, 0x0540, 0x0555, 0x0800, 0x0808, 0x0810, 0x0813,
-   0x0820, 0x0821, 0x0823, 0x0827, 0x0830, 0x0833, 0x0840, 0x0843,
-   0x084f, 0x086f, 0x0880, 0x088a, 0x08a0, 0x08ab, 0x08c0, 0x08c4,
-   0x08d0, 0x08dd, 0x08f0, 0x08f3, 0x0900, 0x0903, 0x0908, 0x0911,
-   0x0928, 0x093e, 0x0942, 0x094d, 0x0980, 0x0984, 0x098d, 0x0996,
-   0x0998, 0x099e, 0x09a0, 0x09a6, 0x09a8, 0x09ae, 0x09b0, 0x09b1,
-   0x09c2, 0x09c8, 0x0a00, 0x0a03, 0x0c00, 0x0c04, 0x0c06, 0x0c06,
-   0x0c10, 0x0cd9, 0x0e00, 0x0e0e, 0x0e10, 0x0e13, 0x0e17, 0x0e19,
-   0x0e1c, 0x0e2b, 0x0e30, 0x0e32, 0x0e38, 0x0e39, 0x8600, 0x8601,
-   0x8610, 0x861b, 0x8620, 0x8620, 0x8628, 0x862b, 0x8630, 0x8637,
-   0x8e01, 0x8e01, 0x8e04, 0x8e05, 0x8e07, 0x8e08, 0x8e0c, 0x8e0c,
-   0x8e10, 0x8e1c, 0x8e20, 0x8e25, 0x8e28, 0x8e28, 0x8e2c, 0x8e2f,
-   0x8e3b, 0x8e3e, 0x8e40, 0x8e43, 0x8e50, 0x8e5e, 0x8e70, 0x8e77,
-   0x9600, 0x9604, 0x9624, 0x9637, 0x9e00, 0x9e01, 0x9e03, 0x9e0e,
-   0x9e11, 0x9e16, 0x9e19, 0x9e19, 0x9e1c, 0x9e1c, 0x9e20, 0x9e23,
-   0x9e30, 0x9e31, 0x9e34, 0x9e34,