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 <mkumbar@nvidia.com>
Reviewed-on: https://git-master/r/1513273
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Mahantesh Kumbar
2017-07-04 23:36:55 +05:30
committed by mobile promotions
parent e768e74df8
commit a3802a2ae9
6 changed files with 95 additions and 108 deletions

View File

@@ -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); 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) void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id)
{ {
struct nvgpu_falcon *flcn = NULL; struct nvgpu_falcon *flcn = NULL;

View File

@@ -269,6 +269,60 @@ static int gk20a_flcn_copy_to_dmem(struct nvgpu_falcon *flcn,
return 0; 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) 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->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done;
flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem; flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem;
flcn_ops->copy_to_dmem = gk20a_flcn_copy_to_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); gk20a_falcon_engine_dependency_ops(flcn);
} }

View File

@@ -18,6 +18,7 @@
#include <nvgpu/nvgpu_common.h> #include <nvgpu/nvgpu_common.h>
#include <nvgpu/timers.h> #include <nvgpu/timers.h>
#include <nvgpu/firmware.h> #include <nvgpu/firmware.h>
#include <nvgpu/falcon.h>
#include "gk20a/gk20a.h" #include "gk20a/gk20a.h"
#include "gk20a/platform_gk20a.h" #include "gk20a/platform_gk20a.h"
@@ -39,40 +40,8 @@
static void upload_code(struct gk20a *g, u32 dst, static void upload_code(struct gk20a *g, u32 dst,
u8 *src, u32 size, u8 port, bool sec) u8 *src, u32 size, u8 port, bool sec)
{ {
u32 i, words; nvgpu_flcn_copy_to_imem(g->pmu.flcn, dst, src, size, port, sec,
u32 *src_u32 = (u32 *)src; dst >> 8);
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++;
}
} }
static void upload_data(struct gk20a *g, u32 dst, u8 *src, u32 size, u8 port) static void upload_data(struct gk20a *g, u32 dst, u8 *src, u32 size, u8 port)

View File

@@ -27,6 +27,7 @@
#include <nvgpu/acr/nvgpu_acr.h> #include <nvgpu/acr/nvgpu_acr.h>
#include <nvgpu/firmware.h> #include <nvgpu/firmware.h>
#include <nvgpu/pmu.h> #include <nvgpu/pmu.h>
#include <nvgpu/falcon.h>
#include <nvgpu/linux/dma.h> #include <nvgpu/linux/dma.h>
@@ -1221,12 +1222,9 @@ static int bl_bootstrap(struct nvgpu_pmu *pmu,
struct gk20a *g = gk20a_from_pmu(pmu); struct gk20a *g = gk20a_from_pmu(pmu);
struct acr_desc *acr = &g->acr; struct acr_desc *acr = &g->acr;
struct mm_gk20a *mm = &g->mm; struct mm_gk20a *mm = &g->mm;
u32 imem_dst_blk = 0;
u32 virt_addr = 0; u32 virt_addr = 0;
u32 tag = 0;
u32 index = 0;
struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc; struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc;
u32 *bl_ucode; u32 dst;
gk20a_dbg_fn(""); gk20a_dbg_fn("");
gk20a_writel(g, pwr_falcon_itfen_r(), 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_valid_f(1) |
pwr_pmu_new_instblk_target_sys_coh_f()); pwr_pmu_new_instblk_target_sys_coh_f());
/* TBD: load all other surfaces */
/*copy bootloader interface structure to dmem*/ /*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, nvgpu_flcn_copy_to_dmem(pmu->flcn, 0, (u8 *)pbl_desc,
sizeof(struct flcn_bl_dmem_desc), 0); 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 */ /* copy bootloader to TOP of IMEM */
imem_dst_blk = (pwr_falcon_hwcfg_imem_size_v( dst = (pwr_falcon_hwcfg_imem_size_v(
gk20a_readl(g, pwr_falcon_hwcfg_r()))) - bl_sz/256; gk20a_readl(g, pwr_falcon_hwcfg_r())) << 8) - bl_sz;
/* Set Auto-Increment on write */ nvgpu_flcn_copy_to_imem(pmu->flcn, dst,
gk20a_writel(g, pwr_falcon_imemc_r(0), (u8 *)(acr->hsbl_ucode.cpu_va), bl_sz, 0, 0,
pwr_falcon_imemc_offs_f(0) | pmu_bl_gm10x_desc->bl_start_tag);
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);
gm20b_dbg_pmu("Before starting falcon with BL\n"); 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(), gk20a_writel(g, pwr_falcon_bootvec_r(),
pwr_falcon_bootvec_vec_f(virt_addr)); pwr_falcon_bootvec_vec_f(virt_addr));

View File

@@ -12,19 +12,11 @@
*/ */
#include <nvgpu/pmu.h> #include <nvgpu/pmu.h>
#include <nvgpu/falcon.h>
#include "gk20a/gk20a.h" #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 "sec2_gp106.h"
#include <nvgpu/hw/gp106/hw_mc_gp106.h>
#include <nvgpu/hw/gp106/hw_pwr_gp106.h> #include <nvgpu/hw/gp106/hw_pwr_gp106.h>
#include <nvgpu/hw/gp106/hw_psec_gp106.h> #include <nvgpu/hw/gp106/hw_psec_gp106.h>
@@ -73,13 +65,10 @@ int bl_bootstrap_sec2(struct nvgpu_pmu *pmu,
struct gk20a *g = gk20a_from_pmu(pmu); struct gk20a *g = gk20a_from_pmu(pmu);
struct acr_desc *acr = &g->acr; struct acr_desc *acr = &g->acr;
struct mm_gk20a *mm = &g->mm; struct mm_gk20a *mm = &g->mm;
u32 imem_dst_blk = 0;
u32 virt_addr = 0; u32 virt_addr = 0;
u32 tag = 0;
u32 index = 0;
struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc; struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc;
u32 *bl_ucode;
u32 data = 0; u32 data = 0;
u32 dst;
gk20a_dbg_fn(""); gk20a_dbg_fn("");
@@ -104,44 +93,23 @@ int bl_bootstrap_sec2(struct nvgpu_pmu *pmu,
data |= (1 << 3); data |= (1 << 3);
gk20a_writel(g, psec_falcon_engctl_r(), data); gk20a_writel(g, psec_falcon_engctl_r(), data);
/* TBD: load all other surfaces */
/*copy bootloader interface structure to dmem*/ /*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, nvgpu_flcn_copy_to_dmem(&g->sec2_flcn, 0, (u8 *)desc,
sizeof(struct flcn_bl_dmem_desc), 0); 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 */ /* copy bootloader to TOP of IMEM */
imem_dst_blk = (psec_falcon_hwcfg_imem_size_v( dst = (psec_falcon_hwcfg_imem_size_v(
gk20a_readl(g, psec_falcon_hwcfg_r()))) - bl_sz/256; gk20a_readl(g, psec_falcon_hwcfg_r())) << 8) - bl_sz;
/* Set Auto-Increment on write */ nvgpu_flcn_copy_to_imem(&g->sec2_flcn, dst,
gk20a_writel(g, psec_falcon_imemc_r(0), (u8 *)(acr->hsbl_ucode.cpu_va), bl_sz, 0, 0,
psec_falcon_imemc_offs_f(0) | pmu_bl_gm10x_desc->bl_start_tag);
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);
gm20b_dbg_pmu("Before starting falcon with BL\n"); gm20b_dbg_pmu("Before starting falcon with BL\n");
gk20a_writel(g, psec_falcon_mailbox0_r(), 0xDEADA5A5); 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(), gk20a_writel(g, psec_falcon_bootvec_r(),
psec_falcon_bootvec_vec_f(virt_addr)); psec_falcon_bootvec_vec_f(virt_addr));

View File

@@ -140,7 +140,7 @@ struct nvgpu_falcon_ops {
int (*copy_from_imem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst, int (*copy_from_imem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst,
u32 size, u8 port); u32 size, u8 port);
int (*copy_to_imem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src, 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, int (*dma_copy)(struct nvgpu_falcon *flcn,
struct nvgpu_falcon_dma_info *dma_info); struct nvgpu_falcon_dma_info *dma_info);
u32 (*mailbox_read)(struct nvgpu_falcon *flcn, u32 mailbox_index); 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); u32 src, u8 *dst, u32 size, u8 port);
int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn, int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn,
u32 dst, u8 *src, u32 size, u8 port); 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, int nvgpu_flcn_dma_copy(struct nvgpu_falcon *flcn,
struct nvgpu_falcon_dma_info *dma_info); struct nvgpu_falcon_dma_info *dma_info);
u32 nvgpu_flcn_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index); u32 nvgpu_flcn_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index);