From a3802a2ae9d5ffeaec038a9ce7fc9fa333f1a68c Mon Sep 17 00:00:00 2001 From: Mahantesh Kumbar Date: Tue, 4 Jul 2017 23:36:55 +0530 Subject: gpu: nvgpu: falcon copy to IMEM support - Added falcon interface/HAL copy to IMEM method - Deleted copy to IMEM code & then replaced with nvgpu_flcn_copy_to_imem() in multiple files - Code cleanup JIRA NVGPU-117 Change-Id: Ic47197ef7dc449e5bf1f418ac02598500c96da21 Signed-off-by: Mahantesh Kumbar Reviewed-on: https://git-master/r/1513273 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/common/falcon/falcon.c | 16 ++++++++++ drivers/gpu/nvgpu/gk20a/flcn_gk20a.c | 55 ++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gm206/bios_gm206.c | 37 ++------------------- drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 45 +++++++------------------- drivers/gpu/nvgpu/gp106/sec2_gp106.c | 54 +++++++------------------------ drivers/gpu/nvgpu/include/nvgpu/falcon.h | 4 ++- 6 files changed, 99 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index 3795dd09..74d78e86 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -180,6 +180,22 @@ int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn, return flcn_ops->copy_to_dmem(flcn, dst, src, size, port); } +int nvgpu_flcn_copy_to_imem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag) +{ + struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops; + int status = -EINVAL; + + if (flcn_ops->copy_to_imem) + status = flcn_ops->copy_to_imem(flcn, dst, src, size, port, + sec, tag); + else + nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ", + flcn->flcn_id); + + return status; +} + void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) { struct nvgpu_falcon *flcn = NULL; diff --git a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c index b52652e2..158f4d8b 100644 --- a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c @@ -269,6 +269,60 @@ static int gk20a_flcn_copy_to_dmem(struct nvgpu_falcon *flcn, return 0; } +static int gk20a_flcn_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst, + u8 *src, u32 size, u8 port, bool sec, u32 tag) +{ + struct gk20a *g = flcn->g; + u32 base_addr = flcn->flcn_base; + u32 *src_u32 = (u32 *)src; + u32 words = 0; + u32 blk = 0; + u32 i = 0; + + nvgpu_log_info(g, "upload %d bytes to 0x%x", size, dst); + + if (flcn_mem_overflow_check(flcn, dst, size, MEM_IMEM)) { + nvgpu_err(g, "incorrect parameters"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&flcn->copy_lock); + + words = size >> 2; + blk = dst >> 8; + + nvgpu_log_info(g, "upload %d words to 0x%x block %d, tag 0x%x", + words, dst, blk, tag); + + gk20a_writel(g, base_addr + falcon_falcon_imemc_r(port), + falcon_falcon_imemc_offs_f(dst >> 2) | + falcon_falcon_imemc_blk_f(blk) | + /* Set Auto-Increment on write */ + falcon_falcon_imemc_aincw_f(1) | + sec << 28); + + for (i = 0; i < words; i++) { + if (i % 64 == 0) { + /* tag is always 256B aligned */ + gk20a_writel(g, base_addr + falcon_falcon_imemt_r(0), + tag); + tag++; + } + + gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port), + src_u32[i]); + } + + /* WARNING : setting remaining bytes in block to 0x0 */ + while (i % 64) { + gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port), 0); + i++; + } + + nvgpu_mutex_release(&flcn->copy_lock); + + return 0; +} static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn) { @@ -302,6 +356,7 @@ void gk20a_falcon_ops(struct nvgpu_falcon *flcn) flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done; flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem; flcn_ops->copy_to_dmem = gk20a_flcn_copy_to_dmem; + flcn_ops->copy_to_imem = gk20a_flcn_copy_to_imem; gk20a_falcon_engine_dependency_ops(flcn); } diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c index be089f2f..14610120 100644 --- a/drivers/gpu/nvgpu/gm206/bios_gm206.c +++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "gk20a/gk20a.h" #include "gk20a/platform_gk20a.h" @@ -39,40 +40,8 @@ static void upload_code(struct gk20a *g, u32 dst, u8 *src, u32 size, u8 port, bool sec) { - u32 i, words; - u32 *src_u32 = (u32 *)src; - u32 blk; - u32 tag = 0; - - gk20a_dbg_info("upload %d bytes to %x", size, dst); - - words = size >> 2; - - blk = dst >> 8; - tag = blk; - - gk20a_dbg_info("upload %d words to %x block %d", - words, dst, blk); - - gk20a_writel(g, pwr_falcon_imemc_r(port), - pwr_falcon_imemc_offs_f(dst >> 2) | - pwr_falcon_imemc_blk_f(blk) | - pwr_falcon_imemc_aincw_f(1) | - sec << 28); - - for (i = 0; i < words; i++) { - if (i % 64 == 0) { - gk20a_writel(g, 0x10a188, tag); - tag++; - } - - gk20a_writel(g, pwr_falcon_imemd_r(port), src_u32[i]); - } - - while (i % 64) { - gk20a_writel(g, pwr_falcon_imemd_r(port), 0); - i++; - } + nvgpu_flcn_copy_to_imem(g->pmu.flcn, dst, src, size, port, sec, + dst >> 8); } static void upload_data(struct gk20a *g, u32 dst, u8 *src, u32 size, u8 port) diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index ee861933..3a638373 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -1221,12 +1222,9 @@ static int bl_bootstrap(struct nvgpu_pmu *pmu, struct gk20a *g = gk20a_from_pmu(pmu); struct acr_desc *acr = &g->acr; struct mm_gk20a *mm = &g->mm; - u32 imem_dst_blk = 0; u32 virt_addr = 0; - u32 tag = 0; - u32 index = 0; struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc; - u32 *bl_ucode; + u32 dst; gk20a_dbg_fn(""); gk20a_writel(g, pwr_falcon_itfen_r(), @@ -1238,42 +1236,21 @@ static int bl_bootstrap(struct nvgpu_pmu *pmu, pwr_pmu_new_instblk_valid_f(1) | pwr_pmu_new_instblk_target_sys_coh_f()); - /* TBD: load all other surfaces */ /*copy bootloader interface structure to dmem*/ - gk20a_writel(g, pwr_falcon_dmemc_r(0), - pwr_falcon_dmemc_offs_f(0) | - pwr_falcon_dmemc_blk_f(0) | - pwr_falcon_dmemc_aincw_f(1)); nvgpu_flcn_copy_to_dmem(pmu->flcn, 0, (u8 *)pbl_desc, sizeof(struct flcn_bl_dmem_desc), 0); - /*TODO This had to be copied to bl_desc_dmem_load_off, but since - * this is 0, so ok for now*/ - - /* Now copy bootloader to TOP of IMEM */ - imem_dst_blk = (pwr_falcon_hwcfg_imem_size_v( - gk20a_readl(g, pwr_falcon_hwcfg_r()))) - bl_sz/256; - - /* Set Auto-Increment on write */ - gk20a_writel(g, pwr_falcon_imemc_r(0), - pwr_falcon_imemc_offs_f(0) | - pwr_falcon_imemc_blk_f(imem_dst_blk) | - pwr_falcon_imemc_aincw_f(1)); - virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8; - tag = virt_addr >> 8; /* tag is always 256B aligned */ - bl_ucode = (u32 *)(acr->hsbl_ucode.cpu_va); - for (index = 0; index < bl_sz/4; index++) { - if ((index % 64) == 0) { - gk20a_writel(g, pwr_falcon_imemt_r(0), - (tag & 0xffff) << 0); - tag++; - } - gk20a_writel(g, pwr_falcon_imemd_r(0), - bl_ucode[index] & 0xffffffff); - } - gk20a_writel(g, pwr_falcon_imemt_r(0), (0 & 0xffff) << 0); + /* copy bootloader to TOP of IMEM */ + dst = (pwr_falcon_hwcfg_imem_size_v( + gk20a_readl(g, pwr_falcon_hwcfg_r())) << 8) - bl_sz; + + nvgpu_flcn_copy_to_imem(pmu->flcn, dst, + (u8 *)(acr->hsbl_ucode.cpu_va), bl_sz, 0, 0, + pmu_bl_gm10x_desc->bl_start_tag); + gm20b_dbg_pmu("Before starting falcon with BL\n"); + virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8; gk20a_writel(g, pwr_falcon_bootvec_r(), pwr_falcon_bootvec_vec_f(virt_addr)); diff --git a/drivers/gpu/nvgpu/gp106/sec2_gp106.c b/drivers/gpu/nvgpu/gp106/sec2_gp106.c index 0f265710..ccd1b3ad 100644 --- a/drivers/gpu/nvgpu/gp106/sec2_gp106.c +++ b/drivers/gpu/nvgpu/gp106/sec2_gp106.c @@ -12,19 +12,11 @@ */ #include +#include #include "gk20a/gk20a.h" -#include "gk20a/pmu_gk20a.h" - -#include "gm20b/pmu_gm20b.h" - -#include "gp10b/pmu_gp10b.h" - -#include "gp106/pmu_gp106.h" - #include "sec2_gp106.h" -#include #include #include @@ -73,13 +65,10 @@ int bl_bootstrap_sec2(struct nvgpu_pmu *pmu, struct gk20a *g = gk20a_from_pmu(pmu); struct acr_desc *acr = &g->acr; struct mm_gk20a *mm = &g->mm; - u32 imem_dst_blk = 0; u32 virt_addr = 0; - u32 tag = 0; - u32 index = 0; struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc; - u32 *bl_ucode; u32 data = 0; + u32 dst; gk20a_dbg_fn(""); @@ -104,44 +93,23 @@ int bl_bootstrap_sec2(struct nvgpu_pmu *pmu, data |= (1 << 3); gk20a_writel(g, psec_falcon_engctl_r(), data); - /* TBD: load all other surfaces */ /*copy bootloader interface structure to dmem*/ - gk20a_writel(g, psec_falcon_dmemc_r(0), - psec_falcon_dmemc_offs_f(0) | - psec_falcon_dmemc_blk_f(0) | - psec_falcon_dmemc_aincw_f(1)); nvgpu_flcn_copy_to_dmem(&g->sec2_flcn, 0, (u8 *)desc, sizeof(struct flcn_bl_dmem_desc), 0); - /*TODO This had to be copied to bl_desc_dmem_load_off, but since - * this is 0, so ok for now*/ - - /* Now copy bootloader to TOP of IMEM */ - imem_dst_blk = (psec_falcon_hwcfg_imem_size_v( - gk20a_readl(g, psec_falcon_hwcfg_r()))) - bl_sz/256; - - /* Set Auto-Increment on write */ - gk20a_writel(g, psec_falcon_imemc_r(0), - psec_falcon_imemc_offs_f(0) | - psec_falcon_imemc_blk_f(imem_dst_blk) | - psec_falcon_imemc_aincw_f(1)); - virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8; - tag = virt_addr >> 8; /* tag is always 256B aligned */ - bl_ucode = (u32 *)(acr->hsbl_ucode.cpu_va); - for (index = 0; index < bl_sz/4; index++) { - if ((index % 64) == 0) { - gk20a_writel(g, psec_falcon_imemt_r(0), - (tag & 0xffff) << 0); - tag++; - } - gk20a_writel(g, psec_falcon_imemd_r(0), - bl_ucode[index] & 0xffffffff); - } - gk20a_writel(g, psec_falcon_imemt_r(0), (0 & 0xffff) << 0); + + /* copy bootloader to TOP of IMEM */ + dst = (psec_falcon_hwcfg_imem_size_v( + gk20a_readl(g, psec_falcon_hwcfg_r())) << 8) - bl_sz; + + nvgpu_flcn_copy_to_imem(&g->sec2_flcn, dst, + (u8 *)(acr->hsbl_ucode.cpu_va), bl_sz, 0, 0, + pmu_bl_gm10x_desc->bl_start_tag); gm20b_dbg_pmu("Before starting falcon with BL\n"); gk20a_writel(g, psec_falcon_mailbox0_r(), 0xDEADA5A5); + virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8; gk20a_writel(g, psec_falcon_bootvec_r(), psec_falcon_bootvec_vec_f(virt_addr)); diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h index ca61ae46..36e9ffb1 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h +++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h @@ -140,7 +140,7 @@ struct nvgpu_falcon_ops { int (*copy_from_imem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst, u32 size, u8 port); int (*copy_to_imem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src, - u32 size, u8 port); + u32 size, u8 port, bool sec, u32 tag); int (*dma_copy)(struct nvgpu_falcon *flcn, struct nvgpu_falcon_dma_info *dma_info); u32 (*mailbox_read)(struct nvgpu_falcon *flcn, u32 mailbox_index); @@ -180,6 +180,8 @@ int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn, u32 src, u8 *dst, u32 size, u8 port); int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn, u32 dst, u8 *src, u32 size, u8 port); +int nvgpu_flcn_copy_to_imem(struct nvgpu_falcon *flcn, + u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag); int nvgpu_flcn_dma_copy(struct nvgpu_falcon *flcn, struct nvgpu_falcon_dma_info *dma_info); u32 nvgpu_flcn_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index); -- cgit v1.2.2