Commit 34b6beb6 authored by Fabien Dessenne's avatar Fabien Dessenne Committed by Mauro Carvalho Chehab

[media] bdisp: add debug file system

Creates 5 debugfs entries to dump the last HW request, the last HW node
(=command), the HW registers and the recent HW performance (time & fps)
Signed-off-by: default avatarFabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 28ffeebb
obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o
bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-debug.o
This diff is collapsed.
...@@ -740,6 +740,43 @@ static int bdisp_hw_build_all_nodes(struct bdisp_ctx *ctx) ...@@ -740,6 +740,43 @@ static int bdisp_hw_build_all_nodes(struct bdisp_ctx *ctx)
return 0; return 0;
} }
/**
* bdisp_hw_save_request
* @ctx: device context
*
* Save a copy of the request and of the built nodes
*
* RETURNS:
* None
*/
static void bdisp_hw_save_request(struct bdisp_ctx *ctx)
{
struct bdisp_node **copy_node = ctx->bdisp_dev->dbg.copy_node;
struct bdisp_request *request = &ctx->bdisp_dev->dbg.copy_request;
struct bdisp_node **node = ctx->node;
int i;
/* Request copy */
request->src = ctx->src;
request->dst = ctx->dst;
request->hflip = ctx->hflip;
request->vflip = ctx->vflip;
request->nb_req++;
/* Nodes copy */
for (i = 0; i < MAX_NB_NODE; i++) {
/* Allocate memory if not done yet */
if (!copy_node[i]) {
copy_node[i] = devm_kzalloc(ctx->bdisp_dev->dev,
sizeof(*copy_node),
GFP_KERNEL);
if (!copy_node[i])
return;
}
copy_node[i] = node[i];
}
}
/** /**
* bdisp_hw_update * bdisp_hw_update
* @ctx: device context * @ctx: device context
...@@ -765,6 +802,9 @@ int bdisp_hw_update(struct bdisp_ctx *ctx) ...@@ -765,6 +802,9 @@ int bdisp_hw_update(struct bdisp_ctx *ctx)
return ret; return ret;
} }
/* Save a copy of the request */
bdisp_hw_save_request(ctx);
/* Configure interrupt to 'Last Node Reached for AQ1' */ /* Configure interrupt to 'Last Node Reached for AQ1' */
writel(BLT_AQ1_CTL_CFG, bdisp->regs + BLT_AQ1_CTL); writel(BLT_AQ1_CTL_CFG, bdisp->regs + BLT_AQ1_CTL);
writel(BLT_ITS_AQ1_LNA, bdisp->regs + BLT_ITM0); writel(BLT_ITS_AQ1_LNA, bdisp->regs + BLT_ITM0);
......
...@@ -336,6 +336,8 @@ static void bdisp_device_run(void *priv) ...@@ -336,6 +336,8 @@ static void bdisp_device_run(void *priv)
goto out; goto out;
} }
bdisp_dbg_perf_begin(bdisp);
err = bdisp_hw_reset(bdisp); err = bdisp_hw_reset(bdisp);
if (err) { if (err) {
dev_err(bdisp->dev, "could not get HW ready\n"); dev_err(bdisp->dev, "could not get HW ready\n");
...@@ -1075,6 +1077,8 @@ static irqreturn_t bdisp_irq_thread(int irq, void *priv) ...@@ -1075,6 +1077,8 @@ static irqreturn_t bdisp_irq_thread(int irq, void *priv)
spin_lock(&bdisp->slock); spin_lock(&bdisp->slock);
bdisp_dbg_perf_end(bdisp);
cancel_delayed_work(&bdisp->timeout_work); cancel_delayed_work(&bdisp->timeout_work);
if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state)) if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state))
...@@ -1247,6 +1251,8 @@ static int bdisp_remove(struct platform_device *pdev) ...@@ -1247,6 +1251,8 @@ static int bdisp_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
bdisp_debugfs_remove(bdisp);
v4l2_device_unregister(&bdisp->v4l2_dev); v4l2_device_unregister(&bdisp->v4l2_dev);
if (!IS_ERR(bdisp->clock)) if (!IS_ERR(bdisp->clock))
...@@ -1328,12 +1334,19 @@ static int bdisp_probe(struct platform_device *pdev) ...@@ -1328,12 +1334,19 @@ static int bdisp_probe(struct platform_device *pdev)
goto err_clk; goto err_clk;
} }
/* Debug */
ret = bdisp_debugfs_create(bdisp);
if (ret) {
dev_err(dev, "failed to create debugfs\n");
goto err_v4l2;
}
/* Power management */ /* Power management */
pm_runtime_enable(dev); pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "failed to set PM\n"); dev_err(dev, "failed to set PM\n");
goto err_v4l2; goto err_dbg;
} }
/* Continuous memory allocator */ /* Continuous memory allocator */
...@@ -1370,6 +1383,8 @@ static int bdisp_probe(struct platform_device *pdev) ...@@ -1370,6 +1383,8 @@ static int bdisp_probe(struct platform_device *pdev)
vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx); vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx);
err_pm: err_pm:
pm_runtime_put(dev); pm_runtime_put(dev);
err_dbg:
bdisp_debugfs_remove(bdisp);
err_v4l2: err_v4l2:
v4l2_device_unregister(&bdisp->v4l2_dev); v4l2_device_unregister(&bdisp->v4l2_dev);
err_clk: err_clk:
......
...@@ -140,6 +140,29 @@ struct bdisp_m2m_device { ...@@ -140,6 +140,29 @@ struct bdisp_m2m_device {
int refcnt; int refcnt;
}; };
/**
* struct bdisp_dbg - debug info
*
* @debugfs_entry: debugfs
* @copy_node: array of last used nodes
* @copy_request: last bdisp request
* @hw_start: start time of last HW request
* @last_duration: last HW processing duration in microsecs
* @min_duration: min HW processing duration in microsecs
* @max_duration: max HW processing duration in microsecs
* @tot_duration: total HW processing duration in microsecs
*/
struct bdisp_dbg {
struct dentry *debugfs_entry;
struct bdisp_node *copy_node[MAX_NB_NODE];
struct bdisp_request copy_request;
ktime_t hw_start;
s64 last_duration;
s64 min_duration;
s64 max_duration;
s64 tot_duration;
};
/** /**
* struct bdisp_dev - abstraction for bdisp entity * struct bdisp_dev - abstraction for bdisp entity
* *
...@@ -158,6 +181,7 @@ struct bdisp_m2m_device { ...@@ -158,6 +181,7 @@ struct bdisp_m2m_device {
* @irq_queue: interrupt handler waitqueue * @irq_queue: interrupt handler waitqueue
* @work_queue: workqueue to handle timeouts * @work_queue: workqueue to handle timeouts
* @timeout_work: IRQ timeout structure * @timeout_work: IRQ timeout structure
* @dbg: debug info
*/ */
struct bdisp_dev { struct bdisp_dev {
struct v4l2_device v4l2_dev; struct v4l2_device v4l2_dev;
...@@ -175,6 +199,7 @@ struct bdisp_dev { ...@@ -175,6 +199,7 @@ struct bdisp_dev {
wait_queue_head_t irq_queue; wait_queue_head_t irq_queue;
struct workqueue_struct *work_queue; struct workqueue_struct *work_queue;
struct delayed_work timeout_work; struct delayed_work timeout_work;
struct bdisp_dbg dbg;
}; };
void bdisp_hw_free_nodes(struct bdisp_ctx *ctx); void bdisp_hw_free_nodes(struct bdisp_ctx *ctx);
...@@ -184,3 +209,8 @@ int bdisp_hw_alloc_filters(struct device *dev); ...@@ -184,3 +209,8 @@ int bdisp_hw_alloc_filters(struct device *dev);
int bdisp_hw_reset(struct bdisp_dev *bdisp); int bdisp_hw_reset(struct bdisp_dev *bdisp);
int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp); int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp);
int bdisp_hw_update(struct bdisp_ctx *ctx); int bdisp_hw_update(struct bdisp_ctx *ctx);
void bdisp_debugfs_remove(struct bdisp_dev *bdisp);
int bdisp_debugfs_create(struct bdisp_dev *bdisp);
void bdisp_dbg_perf_begin(struct bdisp_dev *bdisp);
void bdisp_dbg_perf_end(struct bdisp_dev *bdisp);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment