diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2014-04-09 08:22:49 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:09:42 -0400 |
commit | 07a90307b09ee44701ed54af21fd234eba029986 (patch) | |
tree | 4201704dac76af2be886966392e5a69ab3b067f4 | |
parent | 8a81389e6ff9350c991f0481fc2f062bc6594e0e (diff) |
gpu: nvgpu: Implement gm20b fifo recovery
Implement gm20b version of fifo recovery.
Bug 1495967
Change-Id: I2792b217178d157427f49e0c450d4ac620399962
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/394138
Reviewed-on: http://git-master/r/401402
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Shridhar Rasal <srasal@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/fifo_gm20b.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c b/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c index 83dc0f79..7e580136 100644 --- a/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/fifo_gm20b.c | |||
@@ -13,10 +13,12 @@ | |||
13 | * more details. | 13 | * more details. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/delay.h> | ||
16 | #include "gk20a/gk20a.h" | 17 | #include "gk20a/gk20a.h" |
17 | #include "fifo_gm20b.h" | 18 | #include "fifo_gm20b.h" |
18 | #include "hw_ccsr_gm20b.h" | 19 | #include "hw_ccsr_gm20b.h" |
19 | #include "hw_ram_gm20b.h" | 20 | #include "hw_ram_gm20b.h" |
21 | #include "hw_fifo_gm20b.h" | ||
20 | 22 | ||
21 | static void channel_gm20b_bind(struct channel_gk20a *ch_gk20a) | 23 | static void channel_gm20b_bind(struct channel_gk20a *ch_gk20a) |
22 | { | 24 | { |
@@ -41,7 +43,64 @@ static void channel_gm20b_bind(struct channel_gk20a *ch_gk20a) | |||
41 | ccsr_channel_enable_set_true_f()); | 43 | ccsr_channel_enable_set_true_f()); |
42 | } | 44 | } |
43 | 45 | ||
46 | static inline u32 gm20b_engine_id_to_mmu_id(u32 engine_id) | ||
47 | { | ||
48 | switch (engine_id) { | ||
49 | case ENGINE_GR_GK20A: | ||
50 | return 0; | ||
51 | case ENGINE_CE2_GK20A: | ||
52 | return 1; | ||
53 | default: | ||
54 | return ~0; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | static void gm20b_fifo_trigger_mmu_fault(struct gk20a *g, | ||
59 | unsigned long engine_ids) | ||
60 | { | ||
61 | unsigned long end_jiffies = jiffies + | ||
62 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
63 | unsigned long delay = GR_IDLE_CHECK_DEFAULT; | ||
64 | unsigned long engine_id; | ||
65 | int ret = -EBUSY; | ||
66 | |||
67 | /* trigger faults for all bad engines */ | ||
68 | for_each_set_bit(engine_id, &engine_ids, 32) { | ||
69 | u32 engine_mmu_id; | ||
70 | |||
71 | if (engine_id > g->fifo.max_engines) { | ||
72 | gk20a_err(dev_from_gk20a(g), | ||
73 | "faulting unknown engine %ld", engine_id); | ||
74 | } else { | ||
75 | engine_mmu_id = gm20b_engine_id_to_mmu_id(engine_id); | ||
76 | gk20a_writel(g, fifo_trigger_mmu_fault_r(engine_mmu_id), | ||
77 | fifo_trigger_mmu_fault_enable_f(1)); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* Wait for MMU fault to trigger */ | ||
82 | do { | ||
83 | if (gk20a_readl(g, fifo_intr_0_r()) & | ||
84 | fifo_intr_0_mmu_fault_pending_f()) { | ||
85 | ret = 0; | ||
86 | break; | ||
87 | } | ||
88 | |||
89 | usleep_range(delay, delay * 2); | ||
90 | delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); | ||
91 | } while (time_before(jiffies, end_jiffies) || | ||
92 | !tegra_platform_is_silicon()); | ||
93 | |||
94 | if (ret) | ||
95 | gk20a_err(dev_from_gk20a(g), "mmu fault timeout"); | ||
96 | |||
97 | /* release mmu fault trigger */ | ||
98 | for_each_set_bit(engine_id, &engine_ids, 32) | ||
99 | gk20a_writel(g, fifo_trigger_mmu_fault_r(engine_id), 0); | ||
100 | } | ||
101 | |||
44 | void gm20b_init_fifo(struct gpu_ops *gops) | 102 | void gm20b_init_fifo(struct gpu_ops *gops) |
45 | { | 103 | { |
46 | gops->fifo.bind_channel = channel_gm20b_bind; | 104 | gops->fifo.bind_channel = channel_gm20b_bind; |
105 | gops->fifo.trigger_mmu_fault = gm20b_fifo_trigger_mmu_fault; | ||
47 | } | 106 | } |