diff options
author | Mahantesh Kumbar <mkumbar@nvidia.com> | 2017-06-21 11:06:26 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-06-27 06:57:45 -0400 |
commit | b7b38d1cd6177dec55de993b4d674948d7c587ef (patch) | |
tree | d3275df64a6e6c5785c5f2aebb2d42fdf59194ce /drivers/gpu/nvgpu | |
parent | 8b3d94ffd3e5b6d7a622c6ad54692d79bf39d1ce (diff) |
gpu: nvgpu: falcon copy from DMEM
- Added interface/HAL method for falcon
to support copy from dmem
- Method to read dmem size
- Method to check error on input parameters
JIRA NVGPU-99
Change-Id: Id27b2b7f4f338196fc3b187555718543445d35bd
Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com>
Reviewed-on: https://git-master/r/1506525
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/common/falcon/falcon.c | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/flcn_gk20a.c | 90 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/falcon.h | 4 |
3 files changed, 100 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index 9e832985..4e3ea1a8 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c | |||
@@ -116,6 +116,14 @@ bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn) | |||
116 | return status; | 116 | return status; |
117 | } | 117 | } |
118 | 118 | ||
119 | int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, | ||
120 | u32 src, u8 *dst, u32 size, u8 port) | ||
121 | { | ||
122 | struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; | ||
123 | |||
124 | return flcn_ops->copy_from_dmem(flcn, src, dst, size, port); | ||
125 | } | ||
126 | |||
119 | void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) | 127 | void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) |
120 | { | 128 | { |
121 | struct nvgpu_falcon *flcn = NULL; | 129 | struct nvgpu_falcon *flcn = NULL; |
diff --git a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c index 0b140802..cfd2b30a 100644 --- a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c | |||
@@ -107,6 +107,94 @@ static bool gk20a_is_falcon_scrubbing_done(struct nvgpu_falcon *flcn) | |||
107 | return status; | 107 | return status; |
108 | } | 108 | } |
109 | 109 | ||
110 | static u32 gk20a_falcon_get_mem_size(struct nvgpu_falcon *flcn, u32 mem_type) | ||
111 | { | ||
112 | struct gk20a *g = flcn->g; | ||
113 | u32 mem_size = 0; | ||
114 | u32 hw_cfg_reg = gk20a_readl(g, | ||
115 | flcn->flcn_base + falcon_falcon_hwcfg_r()); | ||
116 | |||
117 | if (mem_type == MEM_DMEM) | ||
118 | mem_size = falcon_falcon_hwcfg_dmem_size_v(hw_cfg_reg) | ||
119 | << GK20A_PMU_DMEM_BLKSIZE2; | ||
120 | else | ||
121 | mem_size = falcon_falcon_hwcfg_imem_size_v(hw_cfg_reg) | ||
122 | << GK20A_PMU_DMEM_BLKSIZE2; | ||
123 | |||
124 | return mem_size; | ||
125 | } | ||
126 | |||
127 | static int flcn_mem_overflow_check(struct nvgpu_falcon *flcn, | ||
128 | u32 offset, u32 size, u32 mem_type) | ||
129 | { | ||
130 | struct gk20a *g = flcn->g; | ||
131 | u32 mem_size = 0; | ||
132 | |||
133 | if (size == 0) { | ||
134 | nvgpu_err(g, "size is zero"); | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | |||
138 | if (offset & 0x3) { | ||
139 | nvgpu_err(g, "offset (0x%08x) not 4-byte aligned", offset); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | mem_size = gk20a_falcon_get_mem_size(flcn, mem_type); | ||
144 | if (!(offset <= mem_size && (offset + size) <= mem_size)) { | ||
145 | nvgpu_err(g, "flcn-id 0x%x, copy overflow ", | ||
146 | flcn->flcn_id); | ||
147 | nvgpu_err(g, "total size 0x%x, offset 0x%x, copy size 0x%x", | ||
148 | mem_size, offset, size); | ||
149 | return -EINVAL; | ||
150 | } | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int gk20a_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, | ||
156 | u32 src, u8 *dst, u32 size, u8 port) | ||
157 | { | ||
158 | struct gk20a *g = flcn->g; | ||
159 | u32 base_addr = flcn->flcn_base; | ||
160 | u32 i, words, bytes; | ||
161 | u32 data, addr_mask; | ||
162 | u32 *dst_u32 = (u32 *)dst; | ||
163 | |||
164 | nvgpu_log_fn(g, " src dmem offset - %x, size - %x", src, size); | ||
165 | |||
166 | if (flcn_mem_overflow_check(flcn, src, size, MEM_DMEM)) { | ||
167 | nvgpu_err(g, "incorrect parameters"); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | nvgpu_mutex_acquire(&flcn->copy_lock); | ||
172 | |||
173 | words = size >> 2; | ||
174 | bytes = size & 0x3; | ||
175 | |||
176 | addr_mask = falcon_falcon_dmemc_offs_m() | | ||
177 | falcon_falcon_dmemc_blk_m(); | ||
178 | |||
179 | src &= addr_mask; | ||
180 | |||
181 | gk20a_writel(g, base_addr + falcon_falcon_dmemc_r(port), | ||
182 | src | falcon_falcon_dmemc_aincr_f(1)); | ||
183 | |||
184 | for (i = 0; i < words; i++) | ||
185 | dst_u32[i] = gk20a_readl(g, | ||
186 | base_addr + falcon_falcon_dmemd_r(port)); | ||
187 | |||
188 | if (bytes > 0) { | ||
189 | data = gk20a_readl(g, base_addr + falcon_falcon_dmemd_r(port)); | ||
190 | for (i = 0; i < bytes; i++) | ||
191 | dst[(words << 2) + i] = ((u8 *)&data)[i]; | ||
192 | } | ||
193 | |||
194 | nvgpu_mutex_release(&flcn->copy_lock); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
110 | static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn) | 198 | static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn) |
111 | { | 199 | { |
112 | struct nvgpu_falcon_engine_dependency_ops *flcn_eng_dep_ops = | 200 | struct nvgpu_falcon_engine_dependency_ops *flcn_eng_dep_ops = |
@@ -135,6 +223,7 @@ static void gk20a_falcon_ops(struct nvgpu_falcon *flcn) | |||
135 | flcn_ops->is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted; | 223 | flcn_ops->is_falcon_cpu_halted = gk20a_is_falcon_cpu_halted; |
136 | flcn_ops->is_falcon_idle = gk20a_is_falcon_idle; | 224 | flcn_ops->is_falcon_idle = gk20a_is_falcon_idle; |
137 | flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done; | 225 | flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done; |
226 | flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem; | ||
138 | 227 | ||
139 | gk20a_falcon_engine_dependency_ops(flcn); | 228 | gk20a_falcon_engine_dependency_ops(flcn); |
140 | } | 229 | } |
@@ -166,6 +255,7 @@ static void gk20a_falcon_hal_sw_init(struct nvgpu_falcon *flcn) | |||
166 | } | 255 | } |
167 | 256 | ||
168 | if (flcn->is_falcon_supported) { | 257 | if (flcn->is_falcon_supported) { |
258 | nvgpu_mutex_init(&flcn->copy_lock); | ||
169 | gk20a_falcon_ops(flcn); | 259 | gk20a_falcon_ops(flcn); |
170 | } else | 260 | } else |
171 | nvgpu_info(g, "flcn-Id 0x%x not supported on current chip", | 261 | nvgpu_info(g, "flcn-Id 0x%x not supported on current chip", |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h index 860efa1b..296510bd 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h +++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h | |||
@@ -172,8 +172,8 @@ void nvgpu_flcn_set_irq(struct nvgpu_falcon *flcn, bool enable, | |||
172 | bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn); | 172 | bool nvgpu_flcn_get_mem_scrubbing_status(struct nvgpu_falcon *flcn); |
173 | bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn); | 173 | bool nvgpu_flcn_get_cpu_halted_status(struct nvgpu_falcon *flcn); |
174 | bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn); | 174 | bool nvgpu_flcn_get_idle_status(struct nvgpu_falcon *flcn); |
175 | int nvgpu_flcn_copy_from_mem(struct nvgpu_falcon *flcn, | 175 | int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, |
176 | enum flcn_mem_type mem_type, u32 src, u8 *dst, u32 size, u8 port); | 176 | u32 src, u8 *dst, u32 size, u8 port); |
177 | int nvgpu_flcn_copy_to_mem(struct nvgpu_falcon *flcn, | 177 | int nvgpu_flcn_copy_to_mem(struct nvgpu_falcon *flcn, |
178 | enum flcn_mem_type mem_type, u32 dst, u8 *src, u32 size, u8 port); | 178 | enum flcn_mem_type mem_type, u32 dst, u8 *src, u32 size, u8 port); |
179 | int nvgpu_flcn_dma_copy(struct nvgpu_falcon *flcn, | 179 | int nvgpu_flcn_dma_copy(struct nvgpu_falcon *flcn, |