summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/acr_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c355
1 files changed, 0 insertions, 355 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index be05a8a8..87f3ef54 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -70,18 +70,6 @@ static get_ucode_details pmu_acr_supp_ucode_list[] = {
70 gpccs_ucode_details, 70 gpccs_ucode_details,
71}; 71};
72 72
73/*Once is LS mode, cpuctl_alias is only accessible*/
74static void start_gm20b_pmu(struct gk20a *g)
75{
76 /*disable irqs for hs falcon booting as we will poll for halt*/
77 nvgpu_mutex_acquire(&g->pmu.isr_mutex);
78 g->ops.pmu.pmu_enable_irq(&g->pmu, true);
79 g->pmu.isr_enabled = true;
80 nvgpu_mutex_release(&g->pmu.isr_mutex);
81 gk20a_writel(g, pwr_falcon_cpuctl_alias_r(),
82 pwr_falcon_cpuctl_startcpu_f(1));
83}
84
85void gm20b_wpr_info(struct gk20a *g, struct wpr_carveout_info *inf) 73void gm20b_wpr_info(struct gk20a *g, struct wpr_carveout_info *inf)
86{ 74{
87 g->ops.fb.read_wpr_info(g, inf); 75 g->ops.fb.read_wpr_info(g, inf);
@@ -1024,123 +1012,6 @@ static int lsf_gen_wpr_requirements(struct gk20a *g, struct ls_flcn_mgr *plsfm)
1024 return 0; 1012 return 0;
1025} 1013}
1026 1014
1027/*Loads ACR bin to FB mem and bootstraps PMU with bootloader code
1028 * start and end are addresses of ucode blob in non-WPR region*/
1029int gm20b_bootstrap_hs_flcn(struct gk20a *g)
1030{
1031 struct mm_gk20a *mm = &g->mm;
1032 struct vm_gk20a *vm = mm->pmu.vm;
1033 int err = 0;
1034 u64 *acr_dmem;
1035 u32 img_size_in_bytes = 0;
1036 u32 status, size;
1037 u64 start;
1038 struct acr_desc *acr = &g->acr;
1039 struct nvgpu_firmware *acr_fw = acr->acr_fw;
1040 struct flcn_bl_dmem_desc *bl_dmem_desc = &acr->bl_dmem_desc;
1041 u32 *acr_ucode_header_t210_load;
1042 u32 *acr_ucode_data_t210_load;
1043
1044 start = nvgpu_mem_get_addr(g, &acr->ucode_blob);
1045 size = acr->ucode_blob.size;
1046
1047 nvgpu_pmu_dbg(g, " ");
1048
1049 if (!acr_fw) {
1050 /*First time init case*/
1051 acr_fw = nvgpu_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE, 0);
1052 if (!acr_fw) {
1053 nvgpu_err(g, "pmu ucode get fail");
1054 return -ENOENT;
1055 }
1056 acr->acr_fw = acr_fw;
1057 acr->hsbin_hdr = (struct bin_hdr *)acr_fw->data;
1058 acr->fw_hdr = (struct acr_fw_header *)(acr_fw->data +
1059 acr->hsbin_hdr->header_offset);
1060 acr_ucode_data_t210_load = (u32 *)(acr_fw->data +
1061 acr->hsbin_hdr->data_offset);
1062 acr_ucode_header_t210_load = (u32 *)(acr_fw->data +
1063 acr->fw_hdr->hdr_offset);
1064 img_size_in_bytes = ALIGN((acr->hsbin_hdr->data_size), 256);
1065
1066 /* Lets patch the signatures first.. */
1067 if (acr_ucode_patch_sig(g, acr_ucode_data_t210_load,
1068 (u32 *)(acr_fw->data +
1069 acr->fw_hdr->sig_prod_offset),
1070 (u32 *)(acr_fw->data +
1071 acr->fw_hdr->sig_dbg_offset),
1072 (u32 *)(acr_fw->data +
1073 acr->fw_hdr->patch_loc),
1074 (u32 *)(acr_fw->data +
1075 acr->fw_hdr->patch_sig)) < 0) {
1076 nvgpu_err(g, "patch signatures fail");
1077 err = -1;
1078 goto err_release_acr_fw;
1079 }
1080 err = nvgpu_dma_alloc_map_sys(vm, img_size_in_bytes,
1081 &acr->acr_ucode);
1082 if (err) {
1083 err = -ENOMEM;
1084 goto err_release_acr_fw;
1085 }
1086
1087 acr_dmem = (u64 *)
1088 &(((u8 *)acr_ucode_data_t210_load)[
1089 acr_ucode_header_t210_load[2]]);
1090 acr->acr_dmem_desc = (struct flcn_acr_desc *)((u8 *)(
1091 acr->acr_ucode.cpu_va) + acr_ucode_header_t210_load[2]);
1092 ((struct flcn_acr_desc *)acr_dmem)->nonwpr_ucode_blob_start =
1093 start;
1094 ((struct flcn_acr_desc *)acr_dmem)->nonwpr_ucode_blob_size =
1095 size;
1096 ((struct flcn_acr_desc *)acr_dmem)->regions.no_regions = 2;
1097 ((struct flcn_acr_desc *)acr_dmem)->wpr_offset = 0;
1098
1099 nvgpu_mem_wr_n(g, &acr->acr_ucode, 0,
1100 acr_ucode_data_t210_load, img_size_in_bytes);
1101 /*
1102 * In order to execute this binary, we will be using
1103 * a bootloader which will load this image into PMU IMEM/DMEM.
1104 * Fill up the bootloader descriptor for PMU HAL to use..
1105 * TODO: Use standard descriptor which the generic bootloader is
1106 * checked in.
1107 */
1108
1109 bl_dmem_desc->signature[0] = 0;
1110 bl_dmem_desc->signature[1] = 0;
1111 bl_dmem_desc->signature[2] = 0;
1112 bl_dmem_desc->signature[3] = 0;
1113 bl_dmem_desc->ctx_dma = GK20A_PMU_DMAIDX_VIRT;
1114 bl_dmem_desc->code_dma_base =
1115 (unsigned int)(((u64)acr->acr_ucode.gpu_va >> 8));
1116 bl_dmem_desc->code_dma_base1 = 0x0;
1117 bl_dmem_desc->non_sec_code_off = acr_ucode_header_t210_load[0];
1118 bl_dmem_desc->non_sec_code_size = acr_ucode_header_t210_load[1];
1119 bl_dmem_desc->sec_code_off = acr_ucode_header_t210_load[5];
1120 bl_dmem_desc->sec_code_size = acr_ucode_header_t210_load[6];
1121 bl_dmem_desc->code_entry_point = 0; /* Start at 0th offset */
1122 bl_dmem_desc->data_dma_base =
1123 bl_dmem_desc->code_dma_base +
1124 ((acr_ucode_header_t210_load[2]) >> 8);
1125 bl_dmem_desc->data_dma_base1 = 0x0;
1126 bl_dmem_desc->data_size = acr_ucode_header_t210_load[3];
1127 } else {
1128 acr->acr_dmem_desc->nonwpr_ucode_blob_size = 0;
1129 }
1130 status = pmu_exec_gen_bl(g, bl_dmem_desc, 1);
1131 if (status != 0) {
1132 err = status;
1133 goto err_free_ucode_map;
1134 }
1135 return 0;
1136err_free_ucode_map:
1137 nvgpu_dma_unmap_free(vm, &acr->acr_ucode);
1138err_release_acr_fw:
1139 nvgpu_release_firmware(g, acr_fw);
1140 acr->acr_fw = NULL;
1141 return err;
1142}
1143
1144/* 1015/*
1145 * @brief Patch signatures into ucode image 1016 * @brief Patch signatures into ucode image
1146 */ 1017 */
@@ -1172,33 +1043,6 @@ int acr_ucode_patch_sig(struct gk20a *g,
1172 return 0; 1043 return 0;
1173} 1044}
1174 1045
1175static int bl_bootstrap(struct nvgpu_pmu *pmu,
1176 struct flcn_bl_dmem_desc *pbl_desc, u32 bl_sz)
1177{
1178 struct gk20a *g = gk20a_from_pmu(pmu);
1179 struct mm_gk20a *mm = &g->mm;
1180 struct nvgpu_falcon_bl_info bl_info;
1181
1182 nvgpu_log_fn(g, " ");
1183 gk20a_writel(g, pwr_falcon_itfen_r(),
1184 gk20a_readl(g, pwr_falcon_itfen_r()) |
1185 pwr_falcon_itfen_ctxen_enable_f());
1186 gk20a_writel(g, pwr_pmu_new_instblk_r(),
1187 pwr_pmu_new_instblk_ptr_f(
1188 nvgpu_inst_block_addr(g, &mm->pmu.inst_block) >> 12) |
1189 pwr_pmu_new_instblk_valid_f(1) |
1190 pwr_pmu_new_instblk_target_sys_coh_f());
1191
1192 bl_info.bl_src = g->acr.hsbl_ucode.cpu_va;
1193 bl_info.bl_desc = (u8 *)pbl_desc;
1194 bl_info.bl_desc_size = sizeof(struct flcn_bl_dmem_desc);
1195 bl_info.bl_size = bl_sz;
1196 bl_info.bl_start_tag = g->acr.pmu_hsbl_desc->bl_start_tag;
1197 nvgpu_flcn_bl_bootstrap(&g->pmu_flcn, &bl_info);
1198
1199 return 0;
1200}
1201
1202int gm20b_init_nspmu_setup_hw1(struct gk20a *g) 1046int gm20b_init_nspmu_setup_hw1(struct gk20a *g)
1203{ 1047{
1204 struct nvgpu_pmu *pmu = &g->pmu; 1048 struct nvgpu_pmu *pmu = &g->pmu;
@@ -1268,202 +1112,3 @@ void gm20b_update_lspmu_cmdline_args(struct gk20a *g)
1268 (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)), 1112 (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)),
1269 g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0); 1113 g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0);
1270} 1114}
1271
1272int gm20b_init_pmu_setup_hw1(struct gk20a *g,
1273 void *desc, u32 bl_sz)
1274{
1275
1276 struct nvgpu_pmu *pmu = &g->pmu;
1277 int err;
1278
1279 nvgpu_log_fn(g, " ");
1280
1281 nvgpu_mutex_acquire(&pmu->isr_mutex);
1282 nvgpu_flcn_reset(pmu->flcn);
1283 pmu->isr_enabled = true;
1284 nvgpu_mutex_release(&pmu->isr_mutex);
1285
1286 if (g->ops.pmu.setup_apertures) {
1287 g->ops.pmu.setup_apertures(g);
1288 }
1289 if (g->ops.pmu.update_lspmu_cmdline_args) {
1290 g->ops.pmu.update_lspmu_cmdline_args(g);
1291 }
1292
1293 /*disable irqs for hs falcon booting as we will poll for halt*/
1294 nvgpu_mutex_acquire(&pmu->isr_mutex);
1295 g->ops.pmu.pmu_enable_irq(pmu, false);
1296 pmu->isr_enabled = false;
1297 nvgpu_mutex_release(&pmu->isr_mutex);
1298 /*Clearing mailbox register used to reflect capabilities*/
1299 gk20a_writel(g, pwr_falcon_mailbox1_r(), 0);
1300 err = bl_bootstrap(pmu, desc, bl_sz);
1301 if (err) {
1302 return err;
1303 }
1304 return 0;
1305}
1306
1307/*
1308* Executes a generic bootloader and wait for PMU to halt.
1309* This BL will be used for those binaries that are loaded
1310* and executed at times other than RM PMU Binary execution.
1311*
1312* @param[in] g gk20a pointer
1313* @param[in] desc Bootloader descriptor
1314* @param[in] dma_idx DMA Index
1315* @param[in] b_wait_for_halt Wait for PMU to HALT
1316*/
1317int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1318{
1319 struct mm_gk20a *mm = &g->mm;
1320 struct vm_gk20a *vm = mm->pmu.vm;
1321 int err = 0;
1322 u32 bl_sz;
1323 struct acr_desc *acr = &g->acr;
1324 struct nvgpu_firmware *hsbl_fw = acr->hsbl_fw;
1325 struct hsflcn_bl_desc *pmu_bl_gm10x_desc;
1326 u32 *pmu_bl_gm10x = NULL;
1327 nvgpu_pmu_dbg(g, " ");
1328
1329 if (!hsbl_fw) {
1330 hsbl_fw = nvgpu_request_firmware(g,
1331 GM20B_HSBIN_PMU_BL_UCODE_IMAGE, 0);
1332 if (!hsbl_fw) {
1333 nvgpu_err(g, "pmu ucode load fail");
1334 return -ENOENT;
1335 }
1336 acr->hsbl_fw = hsbl_fw;
1337 acr->bl_bin_hdr = (struct bin_hdr *)hsbl_fw->data;
1338 acr->pmu_hsbl_desc = (struct hsflcn_bl_desc *)(hsbl_fw->data +
1339 acr->bl_bin_hdr->header_offset);
1340 pmu_bl_gm10x_desc = acr->pmu_hsbl_desc;
1341 pmu_bl_gm10x = (u32 *)(hsbl_fw->data +
1342 acr->bl_bin_hdr->data_offset);
1343 bl_sz = ALIGN(pmu_bl_gm10x_desc->bl_img_hdr.bl_code_size,
1344 256);
1345 acr->hsbl_ucode.size = bl_sz;
1346 nvgpu_pmu_dbg(g, "Executing Generic Bootloader\n");
1347
1348 /*TODO in code verify that enable PMU is done,
1349 scrubbing etc is done*/
1350 /*TODO in code verify that gmmu vm init is done*/
1351 err = nvgpu_dma_alloc_sys(g, bl_sz, &acr->hsbl_ucode);
1352 if (err) {
1353 nvgpu_err(g, "failed to allocate memory");
1354 goto err_done;
1355 }
1356
1357 acr->hsbl_ucode.gpu_va = nvgpu_gmmu_map(vm,
1358 &acr->hsbl_ucode,
1359 bl_sz,
1360 0, /* flags */
1361 gk20a_mem_flag_read_only, false,
1362 acr->hsbl_ucode.aperture);
1363 if (!acr->hsbl_ucode.gpu_va) {
1364 nvgpu_err(g, "failed to map pmu ucode memory!!");
1365 goto err_free_ucode;
1366 }
1367
1368 nvgpu_mem_wr_n(g, &acr->hsbl_ucode, 0, pmu_bl_gm10x, bl_sz);
1369 nvgpu_pmu_dbg(g, "Copied bl ucode to bl_cpuva\n");
1370 }
1371 /*
1372 * Disable interrupts to avoid kernel hitting breakpoint due
1373 * to PMU halt
1374 */
1375
1376 if (g->ops.pmu.falcon_clear_halt_interrupt_status(g,
1377 gk20a_get_gr_idle_timeout(g))) {
1378 goto err_unmap_bl;
1379 }
1380
1381 nvgpu_pmu_dbg(g, "phys sec reg %x\n", gk20a_readl(g,
1382 pwr_falcon_mmu_phys_sec_r()));
1383 nvgpu_pmu_dbg(g, "sctl reg %x\n", gk20a_readl(g, pwr_falcon_sctl_r()));
1384
1385 g->ops.pmu.init_falcon_setup_hw(g, desc, acr->hsbl_ucode.size);
1386
1387 /* Poll for HALT */
1388 if (b_wait_for_halt) {
1389 err = g->ops.pmu.falcon_wait_for_halt(g,
1390 ACR_COMPLETION_TIMEOUT_MS);
1391 if (err == 0) {
1392 /* Clear the HALT interrupt */
1393 if (g->ops.pmu.falcon_clear_halt_interrupt_status(g,
1394 gk20a_get_gr_idle_timeout(g))) {
1395 goto err_unmap_bl;
1396 }
1397 } else {
1398 goto err_unmap_bl;
1399 }
1400 }
1401 nvgpu_pmu_dbg(g, "after waiting for halt, err %x\n", err);
1402 nvgpu_pmu_dbg(g, "phys sec reg %x\n", gk20a_readl(g,
1403 pwr_falcon_mmu_phys_sec_r()));
1404 nvgpu_pmu_dbg(g, "sctl reg %x\n", gk20a_readl(g, pwr_falcon_sctl_r()));
1405 start_gm20b_pmu(g);
1406 return 0;
1407err_unmap_bl:
1408 nvgpu_gmmu_unmap(vm, &acr->hsbl_ucode, acr->hsbl_ucode.gpu_va);
1409err_free_ucode:
1410 nvgpu_dma_free(g, &acr->hsbl_ucode);
1411err_done:
1412 nvgpu_release_firmware(g, hsbl_fw);
1413 return err;
1414}
1415
1416/*!
1417* Wait for PMU to halt
1418* @param[in] g GPU object pointer
1419* @param[in] timeout_ms Timeout in msec for PMU to halt
1420* @return '0' if PMU halts
1421*/
1422int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout_ms)
1423{
1424 struct nvgpu_pmu *pmu = &g->pmu;
1425 u32 data = 0;
1426 int ret = 0;
1427
1428 ret = nvgpu_flcn_wait_for_halt(pmu->flcn, timeout_ms);
1429 if (ret) {
1430 nvgpu_err(g, "ACR boot timed out");
1431 goto exit;
1432 }
1433
1434 g->acr.capabilities = gk20a_readl(g, pwr_falcon_mailbox1_r());
1435 nvgpu_pmu_dbg(g, "ACR capabilities %x\n", g->acr.capabilities);
1436 data = gk20a_readl(g, pwr_falcon_mailbox0_r());
1437 if (data) {
1438 nvgpu_err(g, "ACR boot failed, err %x", data);
1439 ret = -EAGAIN;
1440 goto exit;
1441 }
1442
1443exit:
1444 if (ret) {
1445 nvgpu_kill_task_pg_init(g);
1446 nvgpu_pmu_state_change(g, PMU_STATE_OFF, false);
1447 nvgpu_flcn_dump_stats(pmu->flcn);
1448 }
1449
1450 return ret;
1451}
1452
1453/*!
1454* Wait for PMU halt interrupt status to be cleared
1455* @param[in] g GPU object pointer
1456* @param[in] timeout_ms Timeout in msec for halt to clear
1457* @return '0' if PMU halt irq status is clear
1458*/
1459int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout_ms)
1460{
1461 struct nvgpu_pmu *pmu = &g->pmu;
1462 int status = 0;
1463
1464 if (nvgpu_flcn_clear_halt_intr_status(pmu->flcn, timeout_ms)) {
1465 status = -EBUSY;
1466 }
1467
1468 return status;
1469}