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
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)
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
* @ctx: device context
......@@ -765,6 +802,9 @@ int bdisp_hw_update(struct bdisp_ctx *ctx)
return ret;
}
/* Save a copy of the request */
bdisp_hw_save_request(ctx);
/* Configure interrupt to 'Last Node Reached for AQ1' */
writel(BLT_AQ1_CTL_CFG, bdisp->regs + BLT_AQ1_CTL);
writel(BLT_ITS_AQ1_LNA, bdisp->regs + BLT_ITM0);
......
......@@ -336,6 +336,8 @@ static void bdisp_device_run(void *priv)
goto out;
}
bdisp_dbg_perf_begin(bdisp);
err = bdisp_hw_reset(bdisp);
if (err) {
dev_err(bdisp->dev, "could not get HW ready\n");
......@@ -1075,6 +1077,8 @@ static irqreturn_t bdisp_irq_thread(int irq, void *priv)
spin_lock(&bdisp->slock);
bdisp_dbg_perf_end(bdisp);
cancel_delayed_work(&bdisp->timeout_work);
if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state))
......@@ -1247,6 +1251,8 @@ static int bdisp_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
bdisp_debugfs_remove(bdisp);
v4l2_device_unregister(&bdisp->v4l2_dev);
if (!IS_ERR(bdisp->clock))
......@@ -1328,12 +1334,19 @@ static int bdisp_probe(struct platform_device *pdev)
goto err_clk;
}
/* Debug */
ret = bdisp_debugfs_create(bdisp);
if (ret) {
dev_err(dev, "failed to create debugfs\n");
goto err_v4l2;
}
/* Power management */
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
dev_err(dev, "failed to set PM\n");
goto err_v4l2;
goto err_dbg;
}
/* Continuous memory allocator */
......@@ -1370,6 +1383,8 @@ static int bdisp_probe(struct platform_device *pdev)
vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx);
err_pm:
pm_runtime_put(dev);
err_dbg:
bdisp_debugfs_remove(bdisp);
err_v4l2:
v4l2_device_unregister(&bdisp->v4l2_dev);
err_clk:
......
......@@ -140,6 +140,29 @@ struct bdisp_m2m_device {
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
*
......@@ -158,6 +181,7 @@ struct bdisp_m2m_device {
* @irq_queue: interrupt handler waitqueue
* @work_queue: workqueue to handle timeouts
* @timeout_work: IRQ timeout structure
* @dbg: debug info
*/
struct bdisp_dev {
struct v4l2_device v4l2_dev;
......@@ -175,6 +199,7 @@ struct bdisp_dev {
wait_queue_head_t irq_queue;
struct workqueue_struct *work_queue;
struct delayed_work timeout_work;
struct bdisp_dbg dbg;
};
void bdisp_hw_free_nodes(struct bdisp_ctx *ctx);
......@@ -184,3 +209,8 @@ int bdisp_hw_alloc_filters(struct device *dev);
int bdisp_hw_reset(struct bdisp_dev *bdisp);
int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp);
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