diff options
Diffstat (limited to 'include/gk20a/fifo_gk20a.c')
-rw-r--r-- | include/gk20a/fifo_gk20a.c | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/include/gk20a/fifo_gk20a.c b/include/gk20a/fifo_gk20a.c index 4477f7c..77babc7 100644 --- a/include/gk20a/fifo_gk20a.c +++ b/include/gk20a/fifo_gk20a.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * GK20A Graphics FIFO (gr host) | 2 | * GK20A Graphics FIFO (gr host) |
3 | * | 3 | * |
4 | * Copyright (c) 2011-2020, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2011-2021, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the "Software"), | 7 | * copy of this software and associated documentation files (the "Software"), |
@@ -58,8 +58,6 @@ | |||
58 | #include <nvgpu/hw/gk20a/hw_top_gk20a.h> | 58 | #include <nvgpu/hw/gk20a/hw_top_gk20a.h> |
59 | #include <nvgpu/hw/gk20a/hw_gr_gk20a.h> | 59 | #include <nvgpu/hw/gk20a/hw_gr_gk20a.h> |
60 | 60 | ||
61 | #include <os/linux/os_linux.h> | ||
62 | |||
63 | #define FECS_METHOD_WFI_RESTORE 0x80000 | 61 | #define FECS_METHOD_WFI_RESTORE 0x80000 |
64 | #define FECS_MAILBOX_0_ACK_RESTORE 0x4 | 62 | #define FECS_MAILBOX_0_ACK_RESTORE 0x4 |
65 | 63 | ||
@@ -1409,6 +1407,7 @@ static void gk20a_fifo_handle_chsw_fault(struct gk20a *g) | |||
1409 | intr = gk20a_readl(g, fifo_intr_chsw_error_r()); | 1407 | intr = gk20a_readl(g, fifo_intr_chsw_error_r()); |
1410 | nvgpu_err(g, "chsw: %08x", intr); | 1408 | nvgpu_err(g, "chsw: %08x", intr); |
1411 | gk20a_fecs_dump_falcon_stats(g); | 1409 | gk20a_fecs_dump_falcon_stats(g); |
1410 | gk20a_gpccs_dump_falcon_stats(g); | ||
1412 | gk20a_writel(g, fifo_intr_chsw_error_r(), intr); | 1411 | gk20a_writel(g, fifo_intr_chsw_error_r(), intr); |
1413 | } | 1412 | } |
1414 | 1413 | ||
@@ -1604,6 +1603,7 @@ int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch) | |||
1604 | engines = gk20a_fifo_engines_on_id(g, tsg->tsgid, true); | 1603 | engines = gk20a_fifo_engines_on_id(g, tsg->tsgid, true); |
1605 | } else { | 1604 | } else { |
1606 | nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); | 1605 | nvgpu_err(g, "chid: %d is not bound to tsg", ch->chid); |
1606 | engines = g->fifo.deferred_fault_engines; | ||
1607 | } | 1607 | } |
1608 | 1608 | ||
1609 | if (engines == 0U) { | 1609 | if (engines == 0U) { |
@@ -1724,6 +1724,7 @@ static bool gk20a_fifo_handle_mmu_fault_locked( | |||
1724 | 1724 | ||
1725 | if (ctxsw) { | 1725 | if (ctxsw) { |
1726 | gk20a_fecs_dump_falcon_stats(g); | 1726 | gk20a_fecs_dump_falcon_stats(g); |
1727 | gk20a_gpccs_dump_falcon_stats(g); | ||
1727 | nvgpu_err(g, "gr_status_r : 0x%x", | 1728 | nvgpu_err(g, "gr_status_r : 0x%x", |
1728 | gk20a_readl(g, gr_status_r())); | 1729 | gk20a_readl(g, gr_status_r())); |
1729 | } | 1730 | } |
@@ -2198,9 +2199,9 @@ int gk20a_fifo_tsg_unbind_channel_verify_status(struct channel_gk20a *ch) | |||
2198 | struct gk20a *g = ch->g; | 2199 | struct gk20a *g = ch->g; |
2199 | 2200 | ||
2200 | if (gk20a_fifo_channel_status_is_next(g, ch->chid)) { | 2201 | if (gk20a_fifo_channel_status_is_next(g, ch->chid)) { |
2201 | nvgpu_err(g, "Channel %d to be removed from TSG %d has NEXT set!", | 2202 | nvgpu_log_info(g, "Channel %d to be removed from TSG %d has NEXT set!", |
2202 | ch->chid, ch->tsgid); | 2203 | ch->chid, ch->tsgid); |
2203 | return -EINVAL; | 2204 | return -EAGAIN; |
2204 | } | 2205 | } |
2205 | 2206 | ||
2206 | if (g->ops.fifo.tsg_verify_status_ctx_reload) { | 2207 | if (g->ops.fifo.tsg_verify_status_ctx_reload) { |
@@ -2983,7 +2984,7 @@ static u32 gk20a_fifo_get_preempt_timeout(struct gk20a *g) | |||
2983 | } | 2984 | } |
2984 | 2985 | ||
2985 | int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, | 2986 | int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, |
2986 | unsigned int id_type) | 2987 | unsigned int id_type, bool preempt_retries_left) |
2987 | { | 2988 | { |
2988 | struct nvgpu_timeout timeout; | 2989 | struct nvgpu_timeout timeout; |
2989 | u32 delay = GR_IDLE_CHECK_DEFAULT; | 2990 | u32 delay = GR_IDLE_CHECK_DEFAULT; |
@@ -3039,7 +3040,8 @@ void gk20a_fifo_preempt_timeout_rc(struct gk20a *g, struct channel_gk20a *ch) | |||
3039 | RC_TYPE_PREEMPT_TIMEOUT); | 3040 | RC_TYPE_PREEMPT_TIMEOUT); |
3040 | } | 3041 | } |
3041 | 3042 | ||
3042 | int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) | 3043 | int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg, |
3044 | bool preempt_retries_left) | ||
3043 | { | 3045 | { |
3044 | int ret; | 3046 | int ret; |
3045 | unsigned int id_type; | 3047 | unsigned int id_type; |
@@ -3051,8 +3053,17 @@ int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) | |||
3051 | 3053 | ||
3052 | id_type = is_tsg ? ID_TYPE_TSG : ID_TYPE_CHANNEL; | 3054 | id_type = is_tsg ? ID_TYPE_TSG : ID_TYPE_CHANNEL; |
3053 | 3055 | ||
3054 | /* wait for preempt */ | 3056 | /* |
3055 | ret = g->ops.fifo.is_preempt_pending(g, id, id_type); | 3057 | * Poll for preempt done. if stalling interrupts are pending |
3058 | * while preempt is in progress we poll for stalling interrupts | ||
3059 | * to finish based on return value from this function and | ||
3060 | * retry preempt again. | ||
3061 | * If HW is hung, on the last retry instance we try to identify | ||
3062 | * the engines hung and set the runlist reset_eng_bitmask | ||
3063 | * and mark preemption completion. | ||
3064 | */ | ||
3065 | ret = g->ops.fifo.is_preempt_pending(g, id, id_type, | ||
3066 | preempt_retries_left); | ||
3056 | 3067 | ||
3057 | return ret; | 3068 | return ret; |
3058 | } | 3069 | } |
@@ -3074,7 +3085,7 @@ int gk20a_fifo_preempt_channel(struct gk20a *g, struct channel_gk20a *ch) | |||
3074 | 3085 | ||
3075 | mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); | 3086 | mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); |
3076 | 3087 | ||
3077 | ret = __locked_fifo_preempt(g, ch->chid, false); | 3088 | ret = __locked_fifo_preempt(g, ch->chid, false, false); |
3078 | 3089 | ||
3079 | if (!mutex_ret) { | 3090 | if (!mutex_ret) { |
3080 | nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); | 3091 | nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); |
@@ -3114,7 +3125,7 @@ int gk20a_fifo_preempt_tsg(struct gk20a *g, struct tsg_gk20a *tsg) | |||
3114 | 3125 | ||
3115 | mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); | 3126 | mutex_ret = nvgpu_pmu_mutex_acquire(&g->pmu, PMU_MUTEX_ID_FIFO, &token); |
3116 | 3127 | ||
3117 | ret = __locked_fifo_preempt(g, tsg->tsgid, true); | 3128 | ret = __locked_fifo_preempt(g, tsg->tsgid, true, false); |
3118 | 3129 | ||
3119 | if (!mutex_ret) { | 3130 | if (!mutex_ret) { |
3120 | nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); | 3131 | nvgpu_pmu_mutex_release(&g->pmu, PMU_MUTEX_ID_FIFO, &token); |
@@ -3584,36 +3595,17 @@ void gk20a_fifo_runlist_hw_submit(struct gk20a *g, u32 runlist_id, | |||
3584 | { | 3595 | { |
3585 | struct fifo_runlist_info_gk20a *runlist = NULL; | 3596 | struct fifo_runlist_info_gk20a *runlist = NULL; |
3586 | u64 runlist_iova; | 3597 | u64 runlist_iova; |
3587 | u32 val_wrote; | ||
3588 | struct nvgpu_os_linux *l; | ||
3589 | 3598 | ||
3590 | runlist = &g->fifo.runlist_info[runlist_id]; | 3599 | runlist = &g->fifo.runlist_info[runlist_id]; |
3591 | runlist_iova = nvgpu_mem_get_addr(g, &runlist->mem[buffer_index]); | 3600 | runlist_iova = nvgpu_mem_get_addr(g, &runlist->mem[buffer_index]); |
3592 | 3601 | ||
3593 | |||
3594 | if (count != 0) { | 3602 | if (count != 0) { |
3595 | printk(KERN_INFO "Runlist base register: %0x\n", fifo_runlist_base_r()); | ||
3596 | printk(KERN_INFO "Runlist KVA: %px\n", (void*)(runlist->mem[buffer_index].cpu_va)); | ||
3597 | printk(KERN_INFO "Runlist PA: %px\n", (void*)virt_to_phys((runlist->mem[buffer_index].cpu_va))); | ||
3598 | printk(KERN_INFO "Runlist dma_address: %px\n", (void*)(runlist->mem[buffer_index].priv.sgt->sgl->dma_address)); | ||
3599 | printk(KERN_INFO "Runlist pages KVA: %px\n", (void*)(runlist->mem[buffer_index].priv.pages)); | ||
3600 | printk(KERN_INFO "Runlist pages PA: %px\n", (void*)virt_to_phys(runlist->mem[buffer_index].priv.pages)); | ||
3601 | printk(KERN_INFO "Runlist dma_address: %px\n", (void*)(runlist->mem[buffer_index].priv.sgt->sgl->dma_address)); | ||
3602 | printk(KERN_INFO "Runlist page_to_phys %px + offset %px\n", (void*)(page_to_phys(sg_page(runlist->mem[buffer_index].priv.sgt->sgl))), (void*)(runlist->mem[buffer_index].priv.sgt->sgl->offset)); | ||
3603 | printk(KERN_INFO "Runlist IOVA: %px\n", (void*)runlist_iova); | ||
3604 | printk(KERN_INFO "Using struct gk20* %px\n", g); | ||
3605 | printk(KERN_INFO "g->name: %s, g->power_on: %d, g->sw_ready: %d, g->is_virtual %d\n", g->name, g->power_on, g->sw_ready, g->is_virtual); | ||
3606 | printk(KERN_INFO "COHERENT_SYSMEM? %d, iommuable? %d\n", nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM), nvgpu_iommuable(g)); | ||
3607 | l = container_of(g, struct nvgpu_os_linux, g); | ||
3608 | printk(KERN_INFO "l->regs %px\n", l->regs); | ||
3609 | gk20a_writel(g, fifo_runlist_base_r(), | 3603 | gk20a_writel(g, fifo_runlist_base_r(), |
3610 | fifo_runlist_base_ptr_f(u64_lo32(runlist_iova >> 12)) | | 3604 | fifo_runlist_base_ptr_f(u64_lo32(runlist_iova >> 12)) | |
3611 | nvgpu_aperture_mask(g, &runlist->mem[buffer_index], | 3605 | nvgpu_aperture_mask(g, &runlist->mem[buffer_index], |
3612 | fifo_runlist_base_target_sys_mem_ncoh_f(), | 3606 | fifo_runlist_base_target_sys_mem_ncoh_f(), |
3613 | fifo_runlist_base_target_sys_mem_coh_f(), | 3607 | fifo_runlist_base_target_sys_mem_coh_f(), |
3614 | fifo_runlist_base_target_vid_mem_f())); | 3608 | fifo_runlist_base_target_vid_mem_f())); |
3615 | val_wrote = nvgpu_readl(g, 0x2270); | ||
3616 | printk(KERN_INFO "Wrote runlist base as %0llx\n", (u64)(val_wrote & 0x0fffffff) << 12); | ||
3617 | } | 3609 | } |
3618 | 3610 | ||
3619 | gk20a_writel(g, fifo_runlist_r(), | 3611 | gk20a_writel(g, fifo_runlist_r(), |
@@ -3806,7 +3798,7 @@ static int __locked_fifo_reschedule_preempt_next(struct channel_gk20a *ch, | |||
3806 | gk20a_readl(g, fifo_preempt_r())); | 3798 | gk20a_readl(g, fifo_preempt_r())); |
3807 | #endif | 3799 | #endif |
3808 | if (wait_preempt) { | 3800 | if (wait_preempt) { |
3809 | g->ops.fifo.is_preempt_pending(g, preempt_id, preempt_type); | 3801 | g->ops.fifo.is_preempt_pending(g, preempt_id, preempt_type, false); |
3810 | } | 3802 | } |
3811 | #ifdef TRACEPOINTS_ENABLED | 3803 | #ifdef TRACEPOINTS_ENABLED |
3812 | trace_gk20a_reschedule_preempted_next(ch->chid); | 3804 | trace_gk20a_reschedule_preempted_next(ch->chid); |