summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2017-04-25 02:52:56 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-06-23 04:14:18 -0400
commitbe04b9b1b56d6dd478fe521277c079367c03f39d (patch)
tree779f867a3511743ca776064e09ee88d59f2d24ce
parent5efa7c8d5ef74eba4fa33881eb64176f5a97de11 (diff)
gpu: nvgpu: falcon reset support
- Added flacon reset dependent interface & HAL methods to perform falcon reset. - method to wait for idle - method to reset falcon - method to set irq - method to read status of CPU - Updated falcon ops pointer to point gk20a falcon HAL methods - Added members to know support of falcon & interrupt. - Added falcon dependency ops member to support flacon speicifc methods JIRA NVGPU-99 JIRA NVGPU-101 Change-Id: I411477e5696a61ee73caebfdab625763b522c255 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1469453 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/common/falcon/falcon.c103
-rw-r--r--drivers/gpu/nvgpu/gk20a/flcn_gk20a.c137
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/falcon.h47
3 files changed, 238 insertions, 49 deletions
diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c
index bcc24355..9e832985 100644
--- a/drivers/gpu/nvgpu/common/falcon/falcon.c
+++ b/drivers/gpu/nvgpu/common/falcon/falcon.c
@@ -16,6 +16,106 @@
16 16
17#include "gk20a/gk20a.h" 17#include "gk20a/gk20a.h"
18 18
19int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn)
20{
21 struct gk20a *g = flcn->g;
22 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops;
23 struct nvgpu_timeout timeout;
24 u32 idle_stat;
25
26 if (!flcn_ops->is_falcon_idle) {
27 nvgpu_warn(g, "Invalid op on falcon 0x%x ", flcn->flcn_id);
28 return -EINVAL;
29 }
30
31 nvgpu_timeout_init(g, &timeout, 2000, NVGPU_TIMER_RETRY_TIMER);
32
33 /* wait for falcon idle */
34 do {
35 idle_stat = flcn_ops->is_falcon_idle(flcn);
36
37 if (idle_stat)
38 break;
39
40 if (nvgpu_timeout_expired_msg(&timeout,
41 "waiting for falcon idle: 0x%08x", idle_stat))
42 return -EBUSY;
43
44 nvgpu_usleep_range(100, 200);
45 } while (1);
46
47 return 0;
48}
49
50int nvgpu_flcn_reset(struct nvgpu_falcon *flcn)
51{
52 int status = -EINVAL;
53
54 if (flcn->flcn_ops.reset)
55 status = flcn->flcn_ops.reset(flcn);
56 else
57 nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ",
58 flcn->flcn_id);
59
60 return status;
61}
62
63void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable,
64 u32 intr_mask, u32 intr_dest)
65{
66 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops;
67
68 if (flcn_ops->set_irq) {
69 flcn->intr_mask = intr_mask;
70 flcn->intr_dest = intr_dest;
71 flcn_ops->set_irq(flcn, enable);
72 } else
73 nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ",
74 flcn->flcn_id);
75}
76
77bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn)
78{
79 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops;
80 bool status = false;
81
82 if (flcn_ops->is_falcon_scrubbing_done)
83 status = flcn_ops->is_falcon_scrubbing_done(flcn);
84 else
85 nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ",
86 flcn->flcn_id);
87
88 return status;
89}
90
91bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn)
92{
93 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops;
94 bool status = false;
95
96 if (flcn_ops->is_falcon_cpu_halted)
97 status = flcn_ops->is_falcon_cpu_halted(flcn);
98 else
99 nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ",
100 flcn->flcn_id);
101
102 return status;
103}
104
105bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn)
106{
107 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops;
108 bool status = false;
109
110 if (flcn_ops->is_falcon_idle)
111 status = flcn_ops->is_falcon_idle(flcn);
112 else
113 nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ",
114 flcn->flcn_id);
115
116 return status;
117}
118
19void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) 119void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id)
20{ 120{
21 struct nvgpu_falcon *flcn = NULL; 121 struct nvgpu_falcon *flcn = NULL;
@@ -25,6 +125,7 @@ void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id)
25 case FALCON_ID_PMU: 125 case FALCON_ID_PMU:
26 flcn = &g->pmu_flcn; 126 flcn = &g->pmu_flcn;
27 flcn->flcn_id = flcn_id; 127 flcn->flcn_id = flcn_id;
128 g->pmu.flcn = &g->pmu_flcn;
28 break; 129 break;
29 case FALCON_ID_SEC2: 130 case FALCON_ID_SEC2:
30 flcn = &g->sec2_flcn; 131 flcn = &g->sec2_flcn;
@@ -37,7 +138,7 @@ void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id)
37 case FALCON_ID_GPCCS: 138 case FALCON_ID_GPCCS:
38 flcn = &g->gpccs_flcn; 139 flcn = &g->gpccs_flcn;
39 flcn->flcn_id = flcn_id; 140 flcn->flcn_id = flcn_id;
40 break; 141 break;
41 default: 142 default:
42 nvgpu_err(g, "Invalid/Unsupported falcon ID %x", flcn_id); 143 nvgpu_err(g, "Invalid/Unsupported falcon ID %x", flcn_id);
43 break; 144 break;
diff --git a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
index f36b9e32..9568b979 100644
--- a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
@@ -10,56 +10,145 @@
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details. 11 * more details.
12 */ 12 */
13#include <nvgpu/falcon.h>
14
13#include "gk20a/gk20a.h" 15#include "gk20a/gk20a.h"
14 16
17#include <nvgpu/hw/gk20a/hw_falcon_gk20a.h>
18
19static int gk20a_flcn_reset(struct nvgpu_falcon *flcn)
20{
21 struct gk20a *g = flcn->g;
22 u32 base_addr = flcn->flcn_base;
23 u32 unit_status = 0;
24 int status = 0;
25
26 if (flcn->flcn_engine_dep_ops.reset_eng)
27 /* falcon & engine reset */
28 status = flcn->flcn_engine_dep_ops.reset_eng(g);
29 else {
30 /* do falcon CPU hard reset */
31 unit_status = gk20a_readl(g, base_addr +
32 falcon_falcon_cpuctl_r());
33 gk20a_writel(g, base_addr + falcon_falcon_cpuctl_r(),
34 (unit_status | falcon_falcon_cpuctl_hreset_f(1)));
35 }
36
37 return status;
38}
39
40static void gk20a_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable)
41{
42 struct gk20a *g = flcn->g;
43 u32 base_addr = flcn->flcn_base;
44
45 if (!flcn->is_interrupt_enabled) {
46 nvgpu_warn(g, "Interrupt not supported on flcn 0x%x ",
47 flcn->flcn_id);
48 /* Keep interrupt disabled */
49 enable = false;
50 }
51
52 if (enable) {
53 gk20a_writel(g, base_addr + falcon_falcon_irqmset_r(),
54 flcn->intr_mask);
55 gk20a_writel(g, base_addr + falcon_falcon_irqdest_r(),
56 flcn->intr_dest);
57 } else
58 gk20a_writel(g, base_addr + falcon_falcon_irqmclr_r(),
59 0xffffffff);
60}
61
62static bool gk20a_is_falcon_cpu_halted(struct nvgpu_falcon *flcn)
63{
64 struct gk20a *g = flcn->g;
65 u32 base_addr = flcn->flcn_base;
66
67 return (gk20a_readl(g, base_addr + falcon_falcon_cpuctl_r()) &
68 falcon_falcon_cpuctl_halt_intr_m() ?
69 true : false);
70}
71
72static bool gk20a_is_falcon_idle(struct nvgpu_falcon *flcn)
73{
74 struct gk20a *g = flcn->g;
75 u32 base_addr = flcn->flcn_base;
76 u32 unit_status = 0;
77 bool status = false;
78
79 unit_status = gk20a_readl(g,
80 base_addr + falcon_falcon_idlestate_r());
81
82 if (falcon_falcon_idlestate_falcon_busy_v(unit_status) == 0 &&
83 falcon_falcon_idlestate_ext_busy_v(unit_status) == 0)
84 status = true;
85 else
86 status = false;
87
88 return status;
89}
90
91static bool gk20a_is_falcon_scrubbing_done(struct nvgpu_falcon *flcn)
92{
93 struct gk20a *g = flcn->g;
94 u32 base_addr = flcn->flcn_base;
95 u32 unit_status = 0;
96 bool status = false;
97
98 unit_status = gk20a_readl(g,
99 base_addr + falcon_falcon_dmactl_r());
100
101 if (unit_status & (falcon_falcon_dmactl_dmem_scrubbing_m() |
102 falcon_falcon_dmactl_imem_scrubbing_m()))
103 status = false;
104 else
105 status = true;
106
107 return status;
108}
109
15static void gk20a_falcon_ops(struct nvgpu_falcon *flcn) 110static void gk20a_falcon_ops(struct nvgpu_falcon *flcn)
16{ 111{
17 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; 112 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops;
18 struct nvgpu_falcon_version_ops *flcn_vops = &flcn->flcn_vops; 113
19 114 flcn_ops->reset = gk20a_flcn_reset;
20 flcn_ops->reset = NULL; 115 flcn_ops->set_irq = gk20a_flcn_set_irq;
21 flcn_ops->enable_irq = NULL; 116 flcn_ops->is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted;
22 flcn_ops->fbif_transcfg = NULL; 117 flcn_ops->is_falcon_idle = gk20a_is_falcon_idle;
23 flcn_ops->read_hwcfg = NULL; 118 flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done;
24 flcn_ops->write_hwcfg = NULL;
25 flcn_ops->copy_from_dmem = NULL;
26 flcn_ops->copy_to_dmem = NULL;
27 flcn_ops->dma_copy = NULL;
28 flcn_ops->mailbox_read = NULL;
29 flcn_ops->mailbox_write = NULL;
30 flcn_ops->get_unit_status = NULL;
31 flcn_ops->dump_falcon_stats = NULL;
32
33 flcn_vops->start_cpu_secure = NULL;
34 flcn_vops->write_dmatrfbase = NULL;
35} 119}
36 120
37static void gk20a_falcon_hal_sw_init(struct nvgpu_falcon *flcn) 121static void gk20a_falcon_hal_sw_init(struct nvgpu_falcon *flcn)
38{ 122{
39 struct gk20a *g = flcn->g; 123 struct gk20a *g = flcn->g;
40 124
41
42 switch (flcn->flcn_id) { 125 switch (flcn->flcn_id) {
43 case FALCON_ID_PMU: 126 case FALCON_ID_PMU:
44 flcn->flcn_base = FALCON_PWR_BASE; 127 flcn->flcn_base = FALCON_PWR_BASE;
128 flcn->is_falcon_supported = true;
129 flcn->is_interrupt_enabled = true;
45 break; 130 break;
46 case FALCON_ID_SEC2:
47 flcn->flcn_base = FALCON_SEC_BASE;
48 break;
49 case FALCON_ID_FECS: 131 case FALCON_ID_FECS:
50 flcn->flcn_base = FALCON_FECS_BASE; 132 flcn->flcn_base = FALCON_FECS_BASE;
133 flcn->is_falcon_supported = true;
134 flcn->is_interrupt_enabled = false;
51 break; 135 break;
52 case FALCON_ID_GPCCS: 136 case FALCON_ID_GPCCS:
53 flcn->flcn_base = FALCON_GPCCS_BASE; 137 flcn->flcn_base = FALCON_GPCCS_BASE;
138 flcn->is_falcon_supported = true;
139 flcn->is_interrupt_enabled = false;
54 break; 140 break;
55 default: 141 default:
142 flcn->is_falcon_supported = false;
56 nvgpu_err(g, "Invalid flcn request"); 143 nvgpu_err(g, "Invalid flcn request");
57 break; 144 break;
58 } 145 }
59 146
60 nvgpu_mutex_init(&flcn->copy_lock); 147 if (flcn->is_falcon_supported) {
61 148 gk20a_falcon_ops(flcn);
62 gk20a_falcon_ops(flcn); 149 } else
150 nvgpu_info(g, "flcn-Id 0x%x not supported on current chip",
151 flcn->flcn_id);
63} 152}
64 153
65void gk20a_falcon_init_hal(struct gpu_ops *gops) 154void gk20a_falcon_init_hal(struct gpu_ops *gops)
diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h
index 17b811dd..860efa1b 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h
@@ -14,6 +14,9 @@
14#ifndef __FALCON_H__ 14#ifndef __FALCON_H__
15#define __FALCON_H__ 15#define __FALCON_H__
16 16
17#include <nvgpu/types.h>
18#include <nvgpu/lock.h>
19
17/* 20/*
18 * Falcon Id Defines 21 * Falcon Id Defines
19 */ 22 */
@@ -86,16 +89,6 @@ enum flcn_hwcfg_write {
86 FALCON_ITF_EN 89 FALCON_ITF_EN
87}; 90};
88 91
89/*
90 * Falcon sub unit Id Defines
91 */
92enum flcn_unit_status {
93 IS_FALCON_IN_RESET = 0x0,
94 IS_FALCON_CPU_HALTED,
95 IS_FALCON_IDLE,
96 IS_FALCON_MEM_SURBBING_DONE
97};
98
99#define FALCON_MEM_SCRUBBING_TIMEOUT_MAX 1000 92#define FALCON_MEM_SCRUBBING_TIMEOUT_MAX 1000
100#define FALCON_MEM_SCRUBBING_TIMEOUT_DEFAULT 10 93#define FALCON_MEM_SCRUBBING_TIMEOUT_DEFAULT 10
101 94
@@ -128,16 +121,17 @@ struct nvgpu_falcon_version_ops {
128 void (*write_dmatrfbase)(struct nvgpu_falcon *flcn, u32 addr); 121 void (*write_dmatrfbase)(struct nvgpu_falcon *flcn, u32 addr);
129}; 122};
130 123
124/* ops which are falcon engine specific */
125struct nvgpu_falcon_engine_dependency_ops {
126 int (*reset_eng)(struct gk20a *g);
127};
128
131struct nvgpu_falcon_ops { 129struct nvgpu_falcon_ops {
132 void (*reset)(struct nvgpu_falcon *flcn, bool enable); 130 int (*reset)(struct nvgpu_falcon *flcn);
133 void (*enable_irq)(struct nvgpu_falcon *flcn, bool enable); 131 void (*set_irq)(struct nvgpu_falcon *flcn, bool enable);
134 void (*fbif_transcfg)(struct nvgpu_falcon *flcn); 132 bool (*is_falcon_cpu_halted)(struct nvgpu_falcon *flcn);
135 u32 (*read_hwcfg)(struct nvgpu_falcon *flcn, 133 bool (*is_falcon_idle)(struct nvgpu_falcon *flcn);
136 enum flcn_hwcfg_read cfg_type); 134 bool (*is_falcon_scrubbing_done)(struct nvgpu_falcon *flcn);
137 void (*write_hwcfg)(struct nvgpu_falcon *flcn,
138 enum flcn_hwcfg_write cfg_type, u32 cfg_data);
139 bool (*get_unit_status)(struct nvgpu_falcon *flcn,
140 enum flcn_unit_status unit_id);
141 int (*copy_from_dmem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst, 135 int (*copy_from_dmem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst,
142 u32 size, u8 port); 136 u32 size, u8 port);
143 int (*copy_to_dmem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src, 137 int (*copy_to_dmem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src,
@@ -159,20 +153,25 @@ struct nvgpu_falcon {
159 u32 flcn_id; 153 u32 flcn_id;
160 u32 flcn_base; 154 u32 flcn_base;
161 u32 flcn_core_rev; 155 u32 flcn_core_rev;
156 bool is_falcon_supported;
157 bool is_interrupt_enabled;
158 u32 intr_mask;
159 u32 intr_dest;
162 bool isr_enabled; 160 bool isr_enabled;
163 struct nvgpu_mutex isr_mutex; 161 struct nvgpu_mutex isr_mutex;
164 struct nvgpu_mutex copy_lock; 162 struct nvgpu_mutex copy_lock;
165 struct nvgpu_falcon_ops flcn_ops; 163 struct nvgpu_falcon_ops flcn_ops;
166 struct nvgpu_falcon_version_ops flcn_vops; 164 struct nvgpu_falcon_version_ops flcn_vops;
165 struct nvgpu_falcon_engine_dependency_ops flcn_engine_dep_ops;
167}; 166};
168 167
169int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn); 168int nvgpu_flcn_wait_idle(struct nvgpu_falcon *flcn);
170int nvgpu_flcn_enable_hw(struct nvgpu_falcon *flcn, bool enable);
171int nvgpu_flcn_reset(struct nvgpu_falcon *flcn); 169int nvgpu_flcn_reset(struct nvgpu_falcon *flcn);
172void nvgpu_flcn_enable_irq(struct nvgpu_falcon *flcn, bool enable); 170void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable,
173void nvgpu_flcn_fbif_transcfg(struct nvgpu_falcon *flcn); 171 u32 intr_mask, u32 intr_dest);
174bool nvgpu_flcn_get_unit_status(struct nvgpu_falcon *flcn, 172bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn);
175 enum flcn_unit_status unit_id); 173bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn);
174bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn);
176int nvgpu_flcn_copy_from_mem(struct nvgpu_falcon *flcn, 175int nvgpu_flcn_copy_from_mem(struct nvgpu_falcon *flcn,
177 enum flcn_mem_type mem_type, u32 src, u8 *dst, u32 size, u8 port); 176 enum flcn_mem_type mem_type, u32 src, u8 *dst, u32 size, u8 port);
178int nvgpu_flcn_copy_to_mem(struct nvgpu_falcon *flcn, 177int nvgpu_flcn_copy_to_mem(struct nvgpu_falcon *flcn,