summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c115
1 files changed, 75 insertions, 40 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index d787a693..074a74c0 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -7136,6 +7136,69 @@ static int gr_gk20a_determine_ppc_configuration(struct gk20a *g,
7136 return 0; 7136 return 0;
7137} 7137}
7138 7138
7139int gr_gk20a_get_offset_in_gpccs_segment(struct gk20a *g,
7140 int addr_type,
7141 u32 num_tpcs,
7142 u32 num_ppcs,
7143 u32 reg_list_ppc_count,
7144 u32 *__offset_in_segment)
7145{
7146 u32 offset_in_segment = 0;
7147 struct gr_gk20a *gr = &g->gr;
7148
7149 if (addr_type == CTXSW_ADDR_TYPE_TPC) {
7150 /*
7151 * reg = gr->ctx_vars.ctxsw_regs.tpc.l;
7152 * offset_in_segment = 0;
7153 */
7154 } else if ((addr_type == CTXSW_ADDR_TYPE_EGPC) ||
7155 (addr_type == CTXSW_ADDR_TYPE_ETPC)) {
7156 offset_in_segment =
7157 ((gr->ctx_vars.ctxsw_regs.tpc.count *
7158 num_tpcs) << 2);
7159
7160 nvgpu_log(g, gpu_dbg_info | gpu_dbg_gpu_dbg,
7161 "egpc etpc offset_in_segment 0x%#08x",
7162 offset_in_segment);
7163 } else if (addr_type == CTXSW_ADDR_TYPE_PPC) {
7164 /*
7165 * The ucode stores TPC data before PPC data.
7166 * Advance offset past TPC data to PPC data.
7167 */
7168 offset_in_segment =
7169 (((gr->ctx_vars.ctxsw_regs.tpc.count +
7170 gr->ctx_vars.ctxsw_regs.etpc.count) *
7171 num_tpcs) << 2);
7172 } else if (addr_type == CTXSW_ADDR_TYPE_GPC) {
7173 /*
7174 * The ucode stores TPC/PPC data before GPC data.
7175 * Advance offset past TPC/PPC data to GPC data.
7176 *
7177 * Note 1 PES_PER_GPC case
7178 */
7179 u32 num_pes_per_gpc = nvgpu_get_litter_value(g,
7180 GPU_LIT_NUM_PES_PER_GPC);
7181 if (num_pes_per_gpc > 1) {
7182 offset_in_segment =
7183 ((((gr->ctx_vars.ctxsw_regs.tpc.count +
7184 gr->ctx_vars.ctxsw_regs.etpc.count) *
7185 num_tpcs) << 2) +
7186 ((reg_list_ppc_count * num_ppcs) << 2));
7187 } else {
7188 offset_in_segment =
7189 (((gr->ctx_vars.ctxsw_regs.tpc.count +
7190 gr->ctx_vars.ctxsw_regs.etpc.count) *
7191 num_tpcs) << 2);
7192 }
7193 } else {
7194 nvgpu_log_fn(g, "Unknown address type.");
7195 return -EINVAL;
7196 }
7197
7198 *__offset_in_segment = offset_in_segment;
7199 return 0;
7200}
7201
7139/* 7202/*
7140 * This function will return the 32 bit offset for a priv register if it is 7203 * This function will return the 32 bit offset for a priv register if it is
7141 * present in the context buffer. The context buffer is in CPU memory. 7204 * present in the context buffer. The context buffer is in CPU memory.
@@ -7147,7 +7210,6 @@ static int gr_gk20a_find_priv_offset_in_buffer(struct gk20a *g,
7147 u32 context_buffer_size, 7210 u32 context_buffer_size,
7148 u32 *priv_offset) 7211 u32 *priv_offset)
7149{ 7212{
7150 struct gr_gk20a *gr = &g->gr;
7151 u32 i, data32; 7213 u32 i, data32;
7152 int err; 7214 int err;
7153 int addr_type; /*enum ctxsw_addr_type */ 7215 int addr_type; /*enum ctxsw_addr_type */
@@ -7158,7 +7220,7 @@ static int gr_gk20a_find_priv_offset_in_buffer(struct gk20a *g,
7158 u32 sys_priv_offset, gpc_priv_offset; 7220 u32 sys_priv_offset, gpc_priv_offset;
7159 u32 ppc_mask, reg_list_ppc_count; 7221 u32 ppc_mask, reg_list_ppc_count;
7160 u8 *context; 7222 u8 *context;
7161 u32 offset_to_segment; 7223 u32 offset_to_segment, offset_in_segment = 0;
7162 7224
7163 nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr); 7225 nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, "addr=0x%x", addr);
7164 7226
@@ -7266,45 +7328,18 @@ static int gr_gk20a_find_priv_offset_in_buffer(struct gk20a *g,
7266 offset_to_segment = gpc_priv_offset * 7328 offset_to_segment = gpc_priv_offset *
7267 ctxsw_prog_ucode_header_size_in_bytes(); 7329 ctxsw_prog_ucode_header_size_in_bytes();
7268 7330
7269 if (addr_type == CTXSW_ADDR_TYPE_TPC) { 7331 err = g->ops.gr.get_offset_in_gpccs_segment(g,
7270 /*reg = gr->ctx_vars.ctxsw_regs.tpc.l;*/ 7332 addr_type,
7271 } else if ((addr_type == CTXSW_ADDR_TYPE_EGPC) || 7333 num_tpcs, num_ppcs, reg_list_ppc_count,
7272 (addr_type == CTXSW_ADDR_TYPE_ETPC)) { 7334 &offset_in_segment);
7273 nvgpu_log(g, gpu_dbg_info | gpu_dbg_gpu_dbg, 7335 if (err)
7274 "egpc etpc offset_to_segment 0x%#08x",
7275 offset_to_segment);
7276 offset_to_segment +=
7277 ((gr->ctx_vars.ctxsw_regs.tpc.count *
7278 num_tpcs) << 2);
7279 } else if (addr_type == CTXSW_ADDR_TYPE_PPC) {
7280 /* The ucode stores TPC data before PPC data.
7281 * Advance offset past TPC data to PPC data. */
7282 offset_to_segment +=
7283 (((gr->ctx_vars.ctxsw_regs.tpc.count +
7284 gr->ctx_vars.ctxsw_regs.etpc.count) *
7285 num_tpcs) << 2);
7286 } else if (addr_type == CTXSW_ADDR_TYPE_GPC) {
7287 /* The ucode stores TPC/PPC data before GPC data.
7288 * Advance offset past TPC/PPC data to GPC data. */
7289 /* note 1 PES_PER_GPC case */
7290 u32 num_pes_per_gpc = nvgpu_get_litter_value(g,
7291 GPU_LIT_NUM_PES_PER_GPC);
7292 if (num_pes_per_gpc > 1) {
7293 offset_to_segment +=
7294 ((((gr->ctx_vars.ctxsw_regs.tpc.count +
7295 gr->ctx_vars.ctxsw_regs.etpc.count) *
7296 num_tpcs) << 2) +
7297 ((reg_list_ppc_count * num_ppcs) << 2));
7298 } else {
7299 offset_to_segment +=
7300 (((gr->ctx_vars.ctxsw_regs.tpc.count +
7301 gr->ctx_vars.ctxsw_regs.etpc.count) *
7302 num_tpcs) << 2);
7303 }
7304 } else {
7305 nvgpu_log_fn(g, "Unknown address type.");
7306 return -EINVAL; 7336 return -EINVAL;
7307 } 7337
7338 offset_to_segment += offset_in_segment;
7339 nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg,
7340 "offset_to_segment 0x%#08x",
7341 offset_to_segment);
7342
7308 err = gr_gk20a_process_context_buffer_priv_segment(g, 7343 err = gr_gk20a_process_context_buffer_priv_segment(g,
7309 addr_type, addr, 7344 addr_type, addr,
7310 i, num_tpcs, 7345 i, num_tpcs,