diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 47 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.h | 1 |
4 files changed, 45 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 64b126f6..7a62f05c 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | |||
@@ -1048,7 +1048,7 @@ static int pmu_idle(struct pmu_gk20a *pmu) | |||
1048 | return 0; | 1048 | return 0; |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | static void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable) | 1051 | void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable) |
1052 | { | 1052 | { |
1053 | struct gk20a *g = gk20a_from_pmu(pmu); | 1053 | struct gk20a *g = gk20a_from_pmu(pmu); |
1054 | 1054 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h index 048520f9..bc5e474a 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | |||
@@ -1145,5 +1145,5 @@ int gk20a_pmu_ap_send_command(struct gk20a *g, | |||
1145 | union pmu_ap_cmd *p_ap_cmd, bool b_block); | 1145 | union pmu_ap_cmd *p_ap_cmd, bool b_block); |
1146 | int gk20a_aelpg_init(struct gk20a *g); | 1146 | int gk20a_aelpg_init(struct gk20a *g); |
1147 | int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id); | 1147 | int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id); |
1148 | 1148 | void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable); | |
1149 | #endif /*__PMU_GK20A_H__*/ | 1149 | #endif /*__PMU_GK20A_H__*/ |
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index b717272c..acfcf41b 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c | |||
@@ -63,6 +63,11 @@ get_ucode_details pmu_acr_supp_ucode_list[] = { | |||
63 | /*Once is LS mode, cpuctl_alias is only accessible*/ | 63 | /*Once is LS mode, cpuctl_alias is only accessible*/ |
64 | void start_gm20b_pmu(struct gk20a *g) | 64 | void start_gm20b_pmu(struct gk20a *g) |
65 | { | 65 | { |
66 | /*disable irqs for hs falcon booting as we will poll for halt*/ | ||
67 | mutex_lock(&g->pmu.isr_mutex); | ||
68 | pmu_enable_irq(&g->pmu, true); | ||
69 | g->pmu.isr_enabled = true; | ||
70 | mutex_unlock(&g->pmu.isr_mutex); | ||
66 | gk20a_writel(g, pwr_falcon_cpuctl_alias_r(), | 71 | gk20a_writel(g, pwr_falcon_cpuctl_alias_r(), |
67 | pwr_falcon_cpuctl_startcpu_f(1)); | 72 | pwr_falcon_cpuctl_startcpu_f(1)); |
68 | } | 73 | } |
@@ -1116,6 +1121,11 @@ int gm20b_init_pmu_setup_hw1(struct gk20a *g, struct flcn_bl_dmem_desc *desc, | |||
1116 | pmu_copy_to_dmem(pmu, g->acr.pmu_args, | 1121 | pmu_copy_to_dmem(pmu, g->acr.pmu_args, |
1117 | (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)), | 1122 | (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)), |
1118 | g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0); | 1123 | g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0); |
1124 | /*disable irqs for hs falcon booting as we will poll for halt*/ | ||
1125 | mutex_lock(&pmu->isr_mutex); | ||
1126 | pmu_enable_irq(pmu, false); | ||
1127 | pmu->isr_enabled = false; | ||
1128 | mutex_unlock(&pmu->isr_mutex); | ||
1119 | err = bl_bootstrap(pmu, desc, bl_sz); | 1129 | err = bl_bootstrap(pmu, desc, bl_sz); |
1120 | if (err) | 1130 | if (err) |
1121 | return err; | 1131 | return err; |
@@ -1216,8 +1226,9 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt) | |||
1216 | * to PMU halt | 1226 | * to PMU halt |
1217 | */ | 1227 | */ |
1218 | 1228 | ||
1219 | gk20a_writel(g, pwr_falcon_irqsclr_r(), | 1229 | if (clear_halt_interrupt_status(g, GPU_TIMEOUT_DEFAULT)) |
1220 | gk20a_readl(g, pwr_falcon_irqsclr_r()) & (~(0x10))); | 1230 | goto err_unmap_bl; |
1231 | |||
1221 | gm20b_dbg_pmu("err reg :%x\n", readl(mc + | 1232 | gm20b_dbg_pmu("err reg :%x\n", readl(mc + |
1222 | MC_ERR_GENERALIZED_CARVEOUT_STATUS_0)); | 1233 | MC_ERR_GENERALIZED_CARVEOUT_STATUS_0)); |
1223 | gm20b_dbg_pmu("phys sec reg %x\n", gk20a_readl(g, | 1234 | gm20b_dbg_pmu("phys sec reg %x\n", gk20a_readl(g, |
@@ -1228,10 +1239,11 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt) | |||
1228 | /* Poll for HALT */ | 1239 | /* Poll for HALT */ |
1229 | if (b_wait_for_halt) { | 1240 | if (b_wait_for_halt) { |
1230 | err = pmu_wait_for_halt(g, GPU_TIMEOUT_DEFAULT); | 1241 | err = pmu_wait_for_halt(g, GPU_TIMEOUT_DEFAULT); |
1231 | if (err == 0) | 1242 | if (err == 0) { |
1232 | /* Clear the HALT interrupt */ | 1243 | /* Clear the HALT interrupt */ |
1233 | gk20a_writel(g, pwr_falcon_irqsclr_r(), | 1244 | if (clear_halt_interrupt_status(g, GPU_TIMEOUT_DEFAULT)) |
1234 | gk20a_readl(g, pwr_falcon_irqsclr_r()) & (~(0x10))); | 1245 | goto err_unmap_bl; |
1246 | } | ||
1235 | else | 1247 | else |
1236 | goto err_unmap_bl; | 1248 | goto err_unmap_bl; |
1237 | } | 1249 | } |
@@ -1281,3 +1293,28 @@ int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout) | |||
1281 | return -EBUSY; | 1293 | return -EBUSY; |
1282 | return 0; | 1294 | return 0; |
1283 | } | 1295 | } |
1296 | |||
1297 | /*! | ||
1298 | * Wait for PMU halt interrupt status to be cleared | ||
1299 | * @param[in] g GPU object pointer | ||
1300 | * @param[in] timeout_us Timeout in Us for PMU to halt | ||
1301 | * @return '0' if PMU halt irq status is clear | ||
1302 | */ | ||
1303 | int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout) | ||
1304 | { | ||
1305 | u32 data = 0; | ||
1306 | while (timeout != 0) { | ||
1307 | gk20a_writel(g, pwr_falcon_irqsclr_r(), | ||
1308 | gk20a_readl(g, pwr_falcon_irqsclr_r()) | (0x10)); | ||
1309 | data = gk20a_readl(g, (pwr_falcon_irqstat_r())); | ||
1310 | if ((data & pwr_falcon_irqstat_halt_true_f()) != | ||
1311 | pwr_falcon_irqstat_halt_true_f()) | ||
1312 | /*halt irq is clear*/ | ||
1313 | break; | ||
1314 | timeout--; | ||
1315 | udelay(1); | ||
1316 | } | ||
1317 | if (timeout == 0) | ||
1318 | return -EBUSY; | ||
1319 | return 0; | ||
1320 | } | ||
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h index d1c42e46..5dddc0b2 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h | |||
@@ -383,4 +383,5 @@ int gm20b_bootstrap_hs_flcn(struct gk20a *g); | |||
383 | int gm20b_pmu_setup_sw(struct gk20a *g); | 383 | int gm20b_pmu_setup_sw(struct gk20a *g); |
384 | int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt); | 384 | int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt); |
385 | int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout_us); | 385 | int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout_us); |
386 | int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout); | ||
386 | #endif /*__ACR_GM20B_H_*/ | 387 | #endif /*__ACR_GM20B_H_*/ |