summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArto Merilainen <amerilainen@nvidia.com>2017-06-14 09:25:11 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-06-21 07:35:02 -0400
commit2a36ed7bacd91e3bc8e9291da10462704af3003d (patch)
tree3d660ec58f2e730aec39a29bd242fa2bc36afb4a
parent66245cde287c73bcab0eed57bfc7af2a6c9fb550 (diff)
video: tegra: host: Recover engine on abort
Currently PVA cannot be recovered if there is a critical error (i.e. abort from the engine). This change modifies code to reset the PVA and abort existing work if: * PVA issues abort ISR * Communication through mailbox interface times out * Communication through CCQ interface times out JIRA PVA-51 Change-Id: I448d231737a122fe5bf6787e5fa1794c2a7b1a33 Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Reviewed-on: http://git-master/r/1502343 GVS: Gerrit_Virtual_Submit Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com>
-rw-r--r--drivers/video/tegra/host/nvhost_queue.c10
-rw-r--r--drivers/video/tegra/host/nvhost_queue.h7
-rw-r--r--drivers/video/tegra/host/pva/Makefile1
-rw-r--r--drivers/video/tegra/host/pva/pva-interface.h1
-rw-r--r--drivers/video/tegra/host/pva/pva.c19
-rw-r--r--drivers/video/tegra/host/pva/pva.h25
-rw-r--r--drivers/video/tegra/host/pva/pva_abort.c89
-rw-r--r--drivers/video/tegra/host/pva/pva_ccq.c16
-rw-r--r--drivers/video/tegra/host/pva/pva_isr.c10
-rw-r--r--drivers/video/tegra/host/pva/pva_mailbox.c44
-rw-r--r--drivers/video/tegra/host/pva/pva_mailbox.h14
-rw-r--r--drivers/video/tegra/host/pva/pva_queue.c93
-rw-r--r--drivers/video/tegra/host/pva/pva_queue.h3
13 files changed, 299 insertions, 33 deletions
diff --git a/drivers/video/tegra/host/nvhost_queue.c b/drivers/video/tegra/host/nvhost_queue.c
index c9ba3cf02..03cf795eb 100644
--- a/drivers/video/tegra/host/nvhost_queue.c
+++ b/drivers/video/tegra/host/nvhost_queue.c
@@ -227,6 +227,16 @@ void nvhost_queue_deinit(struct nvhost_queue_pool *pool)
227 pool = NULL; 227 pool = NULL;
228} 228}
229 229
230void nvhost_queue_abort_all(struct nvhost_queue_pool *pool)
231{
232 u32 id;
233
234 mutex_lock(&pool->queue_lock);
235 for_each_set_bit(id, &pool->alloc_table, pool->max_queue_cnt)
236 nvhost_queue_abort(&pool->queues[id]);
237 mutex_unlock(&pool->queue_lock);
238}
239
230static void nvhost_queue_release(struct kref *ref) 240static void nvhost_queue_release(struct kref *ref)
231{ 241{
232 struct nvhost_queue *queue = container_of(ref, struct nvhost_queue, 242 struct nvhost_queue *queue = container_of(ref, struct nvhost_queue,
diff --git a/drivers/video/tegra/host/nvhost_queue.h b/drivers/video/tegra/host/nvhost_queue.h
index 510508d54..73b167ab9 100644
--- a/drivers/video/tegra/host/nvhost_queue.h
+++ b/drivers/video/tegra/host/nvhost_queue.h
@@ -185,6 +185,13 @@ struct nvhost_queue *nvhost_queue_alloc(struct nvhost_queue_pool *pool,
185 bool use_channel); 185 bool use_channel);
186 186
187/** 187/**
188 * @brief Abort all active queues
189 *
190 * @param pool Pointer to a queue pool table
191 */
192void nvhost_queue_abort_all(struct nvhost_queue_pool *pool);
193
194/**
188 * @brief Abort tasks within a client queue 195 * @brief Abort tasks within a client queue
189 * 196 *
190 * This function aborts all tasks from the given clinet queue. If there is no 197 * This function aborts all tasks from the given clinet queue. If there is no
diff --git a/drivers/video/tegra/host/pva/Makefile b/drivers/video/tegra/host/pva/Makefile
index a1503925b..517da1196 100644
--- a/drivers/video/tegra/host/pva/Makefile
+++ b/drivers/video/tegra/host/pva/Makefile
@@ -12,6 +12,7 @@ nvhost-pva-objs = \
12 pva_queue.o \ 12 pva_queue.o \
13 pva_debug.o \ 13 pva_debug.o \
14 pva_trace.o \ 14 pva_trace.o \
15 pva_abort.o \
15 pva_ccq.o 16 pva_ccq.o
16 17
17obj-$(CONFIG_TEGRA_GRHOST_PVA) += nvhost-pva.o 18obj-$(CONFIG_TEGRA_GRHOST_PVA) += nvhost-pva.o
diff --git a/drivers/video/tegra/host/pva/pva-interface.h b/drivers/video/tegra/host/pva/pva-interface.h
index 2157ae1e2..d272ce6dc 100644
--- a/drivers/video/tegra/host/pva/pva-interface.h
+++ b/drivers/video/tegra/host/pva/pva-interface.h
@@ -90,6 +90,7 @@
90#define PVA_AISR_LOGGING_OVERFLOW PVA_BIT(25) 90#define PVA_AISR_LOGGING_OVERFLOW PVA_BIT(25)
91#define PVA_AISR_PRINTF_OVERFLOW PVA_BIT(24) 91#define PVA_AISR_PRINTF_OVERFLOW PVA_BIT(24)
92#define PVA_AISR_CRASH_LOG PVA_BIT(23) 92#define PVA_AISR_CRASH_LOG PVA_BIT(23)
93#define PVA_AISR_ABORT PVA_BIT(0)
93 94
94#define PVA_GET_ERROR_CODE(_s_) PVA_EXTRACT(_s_, 15, 0, enum pva_errors) 95#define PVA_GET_ERROR_CODE(_s_) PVA_EXTRACT(_s_, 15, 0, enum pva_errors)
95 96
diff --git a/drivers/video/tegra/host/pva/pva.c b/drivers/video/tegra/host/pva/pva.c
index 028de9fdd..ddc09ca89 100644
--- a/drivers/video/tegra/host/pva/pva.c
+++ b/drivers/video/tegra/host/pva/pva.c
@@ -86,7 +86,6 @@ static int pva_init_fw(struct platform_device *pdev)
86 struct pva_dma_alloc_info *priv2_buffer; 86 struct pva_dma_alloc_info *priv2_buffer;
87 u32 *ucode_ptr; 87 u32 *ucode_ptr;
88 int err = 0, w; 88 int err = 0, w;
89 int timeout;
90 u64 ucode_useg_addr; 89 u64 ucode_useg_addr;
91 90
92 nvhost_dbg_fn(""); 91 nvhost_dbg_fn("");
@@ -172,16 +171,7 @@ static int pva_init_fw(struct platform_device *pdev)
172 nvhost_dbg_fn("Waiting for PVA to be READY"); 171 nvhost_dbg_fn("Waiting for PVA to be READY");
173 172
174 /* Wait PVA to report itself as ready */ 173 /* Wait PVA to report itself as ready */
175 if (tegra_platform_is_silicon()) { 174 err = pva_mailbox_wait_event(pva, 60000);
176 timeout = wait_event_timeout(pva->mailbox_waitqueue,
177 pva->mailbox_status == PVA_MBOX_STATUS_DONE,
178 msecs_to_jiffies(60000));
179 if (timeout <= 0)
180 err = -ETIMEDOUT;
181
182 } else
183 wait_event(pva->mailbox_waitqueue,
184 pva->mailbox_status == PVA_MBOX_STATUS_DONE);
185 175
186 pva->mailbox_status = PVA_MBOX_STATUS_INVALID; 176 pva->mailbox_status = PVA_MBOX_STATUS_INVALID;
187 177
@@ -422,6 +412,8 @@ int pva_finalize_poweron(struct platform_device *pdev)
422 } 412 }
423 } 413 }
424 414
415 pva->booted = true;
416
425 return err; 417 return err;
426 418
427err_poweron: 419err_poweron:
@@ -434,6 +426,8 @@ int pva_prepare_poweroff(struct platform_device *pdev)
434 struct nvhost_device_data *pdata = platform_get_drvdata(pdev); 426 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
435 struct pva *pva = pdata->private_data; 427 struct pva *pva = pdata->private_data;
436 428
429 pva->booted = false;
430
437 disable_irq(pva->irq); 431 disable_irq(pva->irq);
438 432
439 pva_free_fw(pdev, pva); 433 pva_free_fw(pdev, pva);
@@ -477,6 +471,7 @@ static int pva_probe(struct platform_device *pdev)
477 platform_set_drvdata(pdev, pdata); 471 platform_set_drvdata(pdev, pdata);
478 init_waitqueue_head(&pva->mailbox_waitqueue); 472 init_waitqueue_head(&pva->mailbox_waitqueue);
479 mutex_init(&pva->mailbox_mutex); 473 mutex_init(&pva->mailbox_mutex);
474 mutex_init(&pva->ccq_mutex);
480 pva->submit_mode = PVA_SUBMIT_MODE_MAILBOX; 475 pva->submit_mode = PVA_SUBMIT_MODE_MAILBOX;
481 476
482 /* Map MMIO range to kernel space */ 477 /* Map MMIO range to kernel space */
@@ -508,6 +503,8 @@ static int pva_probe(struct platform_device *pdev)
508 if (err < 0) 503 if (err < 0)
509 goto err_isr_init; 504 goto err_isr_init;
510 505
506 pva_abort_init(pva);
507
511 err = nvhost_syncpt_unit_interface_init(pdev); 508 err = nvhost_syncpt_unit_interface_init(pdev);
512 if (err) 509 if (err)
513 goto err_mss_init; 510 goto err_mss_init;
diff --git a/drivers/video/tegra/host/pva/pva.h b/drivers/video/tegra/host/pva/pva.h
index e1bdba1b2..1103513f1 100644
--- a/drivers/video/tegra/host/pva/pva.h
+++ b/drivers/video/tegra/host/pva/pva.h
@@ -154,6 +154,8 @@ struct pva {
154 enum pva_mailbox_status mailbox_status; 154 enum pva_mailbox_status mailbox_status;
155 struct mutex mailbox_mutex; 155 struct mutex mailbox_mutex;
156 156
157 struct mutex ccq_mutex;
158
157 struct pva_crashdump_debugfs_entry debugfs_entry_r5; 159 struct pva_crashdump_debugfs_entry debugfs_entry_r5;
158 struct pva_crashdump_debugfs_entry debugfs_entry_vpu0; 160 struct pva_crashdump_debugfs_entry debugfs_entry_vpu0;
159 struct pva_crashdump_debugfs_entry debugfs_entry_vpu1; 161 struct pva_crashdump_debugfs_entry debugfs_entry_vpu1;
@@ -163,6 +165,9 @@ struct pva {
163 165
164 struct pva_trace_log pva_trace; 166 struct pva_trace_log pva_trace;
165 u32 submit_mode; 167 u32 submit_mode;
168
169 struct work_struct pva_abort_handler_work;
170 bool booted;
166}; 171};
167 172
168/** 173/**
@@ -215,6 +220,7 @@ int pva_prepare_poweroff(struct platform_device *pdev);
215 * 220 *
216 */ 221 */
217int pva_register_isr(struct platform_device *dev); 222int pva_register_isr(struct platform_device *dev);
223
218/** 224/**