summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
diff options
context:
space:
mode:
authorSupriya <ssharatkumar@nvidia.com>2014-07-31 09:37:41 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:42 -0400
commitcf69b50f960f4392dac6d2c169494ce7c8074ac6 (patch)
treef6973bf8a61887cb9838f55c5d929193f44b6cca /drivers/gpu/nvgpu/gm20b/acr_gm20b.c
parentf5422f80f22fd29b3e2532fa6e43b7dbc1b910a7 (diff)
nvgpu: gm20b: Changes for recovery path
Bug 200006956 Change-Id: I54b8ead007f8d671bcc731f73377986b880b9082 Signed-off-by: Supriya <ssharatkumar@nvidia.com> Reviewed-on: http://git-master/r/449343 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/acr_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c370
1 files changed, 215 insertions, 155 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index e5a3e2cd..92a89f00 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -52,6 +52,7 @@ static int acr_ucode_patch_sig(struct gk20a *g,
52 unsigned int *p_dbg_sig, 52 unsigned int *p_dbg_sig,
53 unsigned int *p_patch_loc, 53 unsigned int *p_patch_loc,
54 unsigned int *p_patch_ind); 54 unsigned int *p_patch_ind);
55static void free_acr_resources(struct gk20a *g, struct ls_flcn_mgr *plsfm);
55 56
56/*Globals*/ 57/*Globals*/
57static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); 58static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
@@ -72,11 +73,7 @@ void gm20b_init_secure_pmu(struct gpu_ops *gops)
72 gops->pmu.prepare_ucode = prepare_ucode_blob; 73 gops->pmu.prepare_ucode = prepare_ucode_blob;
73 gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_bootstrap_hs_flcn; 74 gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_bootstrap_hs_flcn;
74} 75}
75 76/* TODO - check if any free blob res needed*/
76static void free_blob_res(struct gk20a *g)
77{
78 /*TODO */
79}
80 77
81int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 78int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
82{ 79{
@@ -91,6 +88,7 @@ int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
91 gm20b_dbg_pmu("requesting PMU ucode in GM20B failed\n"); 88 gm20b_dbg_pmu("requesting PMU ucode in GM20B failed\n");
92 return -ENOENT; 89 return -ENOENT;
93 } 90 }
91 g->acr.pmu_fw = pmu_fw;
94 gm20b_dbg_pmu("Loaded PMU ucode in for blob preparation"); 92 gm20b_dbg_pmu("Loaded PMU ucode in for blob preparation");
95 93
96 gm20b_dbg_pmu("requesting PMU ucode desc in GM20B\n"); 94 gm20b_dbg_pmu("requesting PMU ucode desc in GM20B\n");
@@ -103,6 +101,7 @@ int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
103 } 101 }
104 pmu->desc = (struct pmu_ucode_desc *)pmu_desc->data; 102 pmu->desc = (struct pmu_ucode_desc *)pmu_desc->data;
105 pmu->ucode_image = (u32 *)pmu_fw->data; 103 pmu->ucode_image = (u32 *)pmu_fw->data;
104 g->acr.pmu_desc = pmu_desc;
106 105
107 err = gk20a_init_pmu(pmu); 106 err = gk20a_init_pmu(pmu);
108 if (err) { 107 if (err) {
@@ -134,7 +133,6 @@ release_img_fw:
134 133
135int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 134int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
136{ 135{
137 int err = 0;
138 struct lsf_ucode_desc *lsf_desc; 136 struct lsf_ucode_desc *lsf_desc;
139 137
140 lsf_desc = kzalloc(sizeof(struct lsf_ucode_desc), GFP_KERNEL); 138 lsf_desc = kzalloc(sizeof(struct lsf_ucode_desc), GFP_KERNEL);
@@ -190,10 +188,18 @@ int prepare_ucode_blob(struct gk20a *g)
190 u32 status; 188 u32 status;
191 void *nonwpr_addr; 189 void *nonwpr_addr;
192 struct ls_flcn_mgr lsfm_l, *plsfm; 190 struct ls_flcn_mgr lsfm_l, *plsfm;
193 struct sg_table *sgt_nonwpr; 191 struct pmu_gk20a *pmu = &g->pmu;
194 struct mm_gk20a *mm = &g->mm;
195 struct vm_gk20a *vm = &mm->pmu.vm;
196 192
193 if (g->acr.ucode_blob_start) {
194 /*Recovery case, we do not need to form
195 non WPR blob of ucodes*/
196 status = gk20a_init_pmu(pmu);
197 if (status) {
198 gm20b_dbg_pmu("failed to set function pointers\n");
199 return status;
200 }
201 return 0;
202 }
197 plsfm = &lsfm_l; 203 plsfm = &lsfm_l;
198 memset((void *)plsfm, 0, sizeof(struct ls_flcn_mgr)); 204 memset((void *)plsfm, 0, sizeof(struct ls_flcn_mgr));
199 gm20b_dbg_pmu("fetching GMMU regs\n"); 205 gm20b_dbg_pmu("fetching GMMU regs\n");
@@ -231,6 +237,7 @@ int prepare_ucode_blob(struct gk20a *g)
231 gm20b_dbg_pmu("LSFM is managing no falcons.\n"); 237 gm20b_dbg_pmu("LSFM is managing no falcons.\n");
232 } 238 }
233 gm20b_dbg_pmu("prepare ucode blob return 0\n"); 239 gm20b_dbg_pmu("prepare ucode blob return 0\n");
240 free_acr_resources(g, plsfm);
234 return 0; 241 return 0;
235} 242}
236 243
@@ -257,7 +264,7 @@ static int lsfm_discover_ucode_images(struct gk20a *g,
257 if (status == 0) { 264 if (status == 0) {
258 if (ucode_img.lsf_desc != NULL) { 265 if (ucode_img.lsf_desc != NULL) {
259 /* The falon_id is formed by grabbing the static base 266 /* The falon_id is formed by grabbing the static base
260 * falonId from the image and adding the 267 * falon_id from the image and adding the
261 * engine-designated falcon instance.*/ 268 * engine-designated falcon instance.*/
262 pmu->pmu_mode |= PMU_SECURE_MODE; 269 pmu->pmu_mode |= PMU_SECURE_MODE;
263 falcon_id = ucode_img.lsf_desc->falcon_id + 270 falcon_id = ucode_img.lsf_desc->falcon_id +
@@ -288,7 +295,7 @@ static int lsfm_discover_ucode_images(struct gk20a *g,
288 295
289 /*0th index is always PMU which is already handled in earlier 296 /*0th index is always PMU which is already handled in earlier
290 if condition*/ 297 if condition*/
291 for (i = 1; i < MAX_SUPPORTED_LSFM; i++) { 298 for (i = 1; i < (MAX_SUPPORTED_LSFM); i++) {
292 memset(&ucode_img, 0, sizeof(ucode_img)); 299 memset(&ucode_img, 0, sizeof(ucode_img));
293 if (pmu_acr_supp_ucode_list[i](g, &ucode_img) == 0) { 300 if (pmu_acr_supp_ucode_list[i](g, &ucode_img) == 0) {
294 if (ucode_img.lsf_desc != NULL) { 301 if (ucode_img.lsf_desc != NULL) {
@@ -729,6 +736,23 @@ static void lsfm_free_nonpmu_ucode_img_res(struct flcn_ucode_img *p_img)
729 } 736 }
730} 737}
731 738
739static void free_acr_resources(struct gk20a *g, struct ls_flcn_mgr *plsfm)
740{
741 u32 cnt = plsfm->managed_flcn_cnt;
742 struct lsfm_managed_ucode_img *mg_ucode_img;
743 while (cnt) {
744 mg_ucode_img = plsfm->ucode_img_list;
745 if (mg_ucode_img->ucode_img.lsf_desc->falcon_id ==
746 LSF_FALCON_ID_PMU)
747 lsfm_free_ucode_img_res(&mg_ucode_img->ucode_img);
748 else
749 lsfm_free_nonpmu_ucode_img_res(
750 &mg_ucode_img->ucode_img);
751 plsfm->ucode_img_list = mg_ucode_img->next;
752 kfree(mg_ucode_img);
753 cnt--;
754 }
755}
732 756
733/* Generate WPR requirements for ACR allocation request */ 757/* Generate WPR requirements for ACR allocation request */
734static int lsf_gen_wpr_requirements(struct gk20a *g, struct ls_flcn_mgr *plsfm) 758static int lsf_gen_wpr_requirements(struct gk20a *g, struct ls_flcn_mgr *plsfm)
@@ -811,102 +835,120 @@ int gm20b_bootstrap_hs_flcn(struct gk20a *g)
811 dma_addr_t iova; 835 dma_addr_t iova;
812 u64 *pacr_ucode_cpuva = NULL, pacr_ucode_pmu_va, *acr_dmem; 836 u64 *pacr_ucode_cpuva = NULL, pacr_ucode_pmu_va, *acr_dmem;
813 u32 img_size_in_bytes; 837 u32 img_size_in_bytes;
814 struct flcn_bl_dmem_desc bl_dmem_desc;
815 u32 status, size; 838 u32 status, size;
816 u64 start; 839 u64 start;
817 const struct firmware *acr_fw;
818 struct acr_gm20b *acr = &g->acr; 840 struct acr_gm20b *acr = &g->acr;
841 const struct firmware *acr_fw = acr->acr_fw;
842 struct flcn_bl_dmem_desc *bl_dmem_desc = &acr->bl_dmem_desc;
819 u32 *acr_ucode_header_t210_load; 843 u32 *acr_ucode_header_t210_load;
820 u32 *acr_ucode_data_t210_load; 844 u32 *acr_ucode_data_t210_load;
821 845
822 start = g->acr.ucode_blob_start; 846 start = acr->ucode_blob_start;
823 size = g->acr.ucode_blob_size; 847 size = acr->ucode_blob_size;
824 848
825 gm20b_dbg_pmu(""); 849 gm20b_dbg_pmu("");
826 850
827 acr_fw = gk20a_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE);
828 if (!acr_fw) { 851 if (!acr_fw) {
829 gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode!!"); 852 /*First time init case*/
830 return -ENOENT; 853 acr_fw = gk20a_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE);
831 } 854 if (!acr_fw) {
832 acr->hsbin_hdr = (struct bin_hdr *)acr_fw->data; 855 gk20a_err(dev_from_gk20a(g), "pmu ucode get fail");
833 acr->fw_hdr = (struct acr_fw_header *)(acr_fw->data + 856 return -ENOENT;
834 acr->hsbin_hdr->header_offset); 857 }
835 acr_ucode_data_t210_load = (u32 *)(acr_fw->data + 858 acr->acr_fw = acr_fw;
836 acr->hsbin_hdr->data_offset); 859 acr->hsbin_hdr = (struct bin_hdr *)acr_fw->data;
837 acr_ucode_header_t210_load = (u32 *)(acr_fw->data + 860 acr->fw_hdr = (struct acr_fw_header *)(acr_fw->data +
838 acr->fw_hdr->hdr_offset); 861 acr->hsbin_hdr->header_offset);
839 img_size_in_bytes = ALIGN((acr->hsbin_hdr->data_size), 256); 862 acr_ucode_data_t210_load = (u32 *)(acr_fw->data +
840 863 acr->hsbin_hdr->data_offset);
841 /* Lets patch the signatures first.. */ 864 acr_ucode_header_t210_load = (u32 *)(acr_fw->data +
842 if (acr_ucode_patch_sig(g, acr_ucode_data_t210_load, 865 acr->fw_hdr->hdr_offset);
843 (u32 *)(acr_fw->data + acr->fw_hdr->sig_prod_offset), 866 img_size_in_bytes = ALIGN((acr->hsbin_hdr->data_size), 256);
844 (u32 *)(acr_fw->data + acr->fw_hdr->sig_dbg_offset), 867
845 (u32 *)(acr_fw->data + acr->fw_hdr->patch_loc), 868 /* Lets patch the signatures first.. */
846 (u32 *)(acr_fw->data + acr->fw_hdr->patch_sig)) < 0) 869 if (acr_ucode_patch_sig(g, acr_ucode_data_t210_load,
847 return -1; 870 (u32 *)(acr_fw->data +
848 pacr_ucode_cpuva = dma_alloc_coherent(d, img_size_in_bytes, &iova, 871 acr->fw_hdr->sig_prod_offset),
849 GFP_KERNEL); 872 (u32 *)(acr_fw->data +
850 if (!pacr_ucode_cpuva) 873 acr->fw_hdr->sig_dbg_offset),
851 return -ENOMEM; 874 (u32 *)(acr_fw->data +
875 acr->fw_hdr->patch_loc),
876 (u32 *)(acr_fw->data +
877 acr->fw_hdr->patch_sig)) < 0) {
878 gk20a_err(dev_from_gk20a(g), "patch signatures fail");
879 err = -1;
880 goto err_release_acr_fw;
881 }
882 pacr_ucode_cpuva = dma_alloc_coherent(d, img_size_in_bytes,
883 &iova, GFP_KERNEL);
884 if (!pacr_ucode_cpuva) {
885 err = -ENOMEM;
886 goto err_release_acr_fw;
887 }
852 888
853 err = gk20a_get_sgtable(d, &sgt_pmu_ucode, 889 err = gk20a_get_sgtable(d, &sgt_pmu_ucode,
854 pacr_ucode_cpuva, 890 pacr_ucode_cpuva,
855 iova, 891 iova,
856 img_size_in_bytes); 892 img_size_in_bytes);
857 if (err) { 893 if (err) {
858 gk20a_err(d, "failed to allocate sg table\n"); 894 gk20a_err(d, "failed to allocate sg table\n");
859 err = -ENOMEM; 895 err = -ENOMEM;
860 goto err_free_acr_buf; 896 goto err_free_acr_buf;
861 } 897 }
862 pacr_ucode_pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_ucode, 898 pacr_ucode_pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_ucode,
863 img_size_in_bytes, 899 img_size_in_bytes,
864 0, /* flags */ 900 0, /* flags */
865 gk20a_mem_flag_read_only); 901 gk20a_mem_flag_read_only);
866 if (!pacr_ucode_pmu_va) { 902 if (!pacr_ucode_pmu_va) {
867 gk20a_err(d, "failed to map pmu ucode memory!!"); 903 gk20a_err(d, "failed to map pmu ucode memory!!");
868 err = -ENOMEM; 904 err = -ENOMEM;
869 goto err_free_ucode_sgt; 905 goto err_free_ucode_sgt;
870 } 906 }
871 acr_dmem = (u64 *) 907 acr_dmem = (u64 *)
872 &(((u8 *)acr_ucode_data_t210_load)[ 908 &(((u8 *)acr_ucode_data_t210_load)[
873 acr_ucode_header_t210_load[2]]); 909 acr_ucode_header_t210_load[2]]);
874 ((struct flcn_acr_desc *)acr_dmem)->nonwpr_ucode_blob_start = 910 ((struct flcn_acr_desc *)acr_dmem)->nonwpr_ucode_blob_start =
875 start; 911 start;
876 ((struct flcn_acr_desc *)acr_dmem)->nonwpr_ucode_blob_size = 912 ((struct flcn_acr_desc *)acr_dmem)->nonwpr_ucode_blob_size =
877 size; 913 size;
878 ((struct flcn_acr_desc *)acr_dmem)->regions.no_regions = 2; 914 ((struct flcn_acr_desc *)acr_dmem)->regions.no_regions = 2;
879 ((struct flcn_acr_desc *)acr_dmem)->wpr_offset = 0; 915 ((struct flcn_acr_desc *)acr_dmem)->wpr_offset = 0;
880 916
881 for (i = 0; i < (img_size_in_bytes/4); i++) { 917 for (i = 0; i < (img_size_in_bytes/4); i++) {
882 gk20a_mem_wr32(pacr_ucode_cpuva, i, 918 gk20a_mem_wr32(pacr_ucode_cpuva, i,
883 acr_ucode_data_t210_load[i]); 919 acr_ucode_data_t210_load[i]);
884 } 920 }
885 /* 921 acr->acr_ucode.cpuva = pacr_ucode_cpuva;
886 * In order to execute this binary, we will be using PMU HAL to run 922 acr->acr_ucode.iova = iova;
887 * a bootloader which will load this image into PMU IMEM/DMEM. 923 acr->acr_ucode.pmu_va = pacr_ucode_pmu_va;
888 * Fill up the bootloader descriptor for PMU HAL to use.. 924 acr->acr_ucode.size = img_size_in_bytes;
889 * TODO: Use standard descriptor which the generic bootloader is 925 /*
890 * checked in. 926 * In order to execute this binary, we will be using
891 */ 927 * a bootloader which will load this image into PMU IMEM/DMEM.
928 * Fill up the bootloader descriptor for PMU HAL to use..
929 * TODO: Use standard descriptor which the generic bootloader is
930 * checked in.
931 */
892 932
893 bl_dmem_desc.signature[0] = 0; 933 bl_dmem_desc->signature[0] = 0;
894 bl_dmem_desc.signature[1] = 0; 934 bl_dmem_desc->signature[1] = 0;
895 bl_dmem_desc.signature[2] = 0; 935 bl_dmem_desc->signature[2] = 0;
896 bl_dmem_desc.signature[3] = 0; 936 bl_dmem_desc->signature[3] = 0;
897 bl_dmem_desc.ctx_dma = GK20A_PMU_DMAIDX_VIRT; 937 bl_dmem_desc->ctx_dma = GK20A_PMU_DMAIDX_VIRT;
898 bl_dmem_desc.code_dma_base = 938 bl_dmem_desc->code_dma_base =
899 (unsigned int)(((u64)pacr_ucode_pmu_va >> 8)); 939 (unsigned int)(((u64)pacr_ucode_pmu_va >> 8));
900 bl_dmem_desc.non_sec_code_off = acr_ucode_header_t210_load[0]; 940 bl_dmem_desc->non_sec_code_off = acr_ucode_header_t210_load[0];
901 bl_dmem_desc.non_sec_code_size = acr_ucode_header_t210_load[1]; 941 bl_dmem_desc->non_sec_code_size = acr_ucode_header_t210_load[1];
902 bl_dmem_desc.sec_code_off = acr_ucode_header_t210_load[5]; 942 bl_dmem_desc->sec_code_off = acr_ucode_header_t210_load[5];
903 bl_dmem_desc.sec_code_size = acr_ucode_header_t210_load[6]; 943 bl_dmem_desc->sec_code_size = acr_ucode_header_t210_load[6];
904 bl_dmem_desc.code_entry_point = 0; /* Start at 0th offset */ 944 bl_dmem_desc->code_entry_point = 0; /* Start at 0th offset */
905 bl_dmem_desc.data_dma_base = 945 bl_dmem_desc->data_dma_base =
906 bl_dmem_desc.code_dma_base + 946 bl_dmem_desc->code_dma_base +
907 ((acr_ucode_header_t210_load[2]) >> 8); 947 ((acr_ucode_header_t210_load[2]) >> 8);
908 bl_dmem_desc.data_size = acr_ucode_header_t210_load[3]; 948 bl_dmem_desc->data_size = acr_ucode_header_t210_load[3];
909 status = pmu_exec_gen_bl(g, &bl_dmem_desc, 1); 949 gk20a_free_sgtable(&sgt_pmu_ucode);
950 }
951 status = pmu_exec_gen_bl(g, bl_dmem_desc, 1);
910 if (status != 0) { 952 if (status != 0) {
911 err = status; 953 err = status;
912 goto err_free_ucode_map; 954 goto err_free_ucode_map;
@@ -915,11 +957,17 @@ int gm20b_bootstrap_hs_flcn(struct gk20a *g)
915err_free_ucode_map: 957err_free_ucode_map:
916 gk20a_gmmu_unmap(vm, pacr_ucode_pmu_va, 958 gk20a_gmmu_unmap(vm, pacr_ucode_pmu_va,
917 img_size_in_bytes, gk20a_mem_flag_none); 959 img_size_in_bytes, gk20a_mem_flag_none);
960 acr->acr_ucode.pmu_va = 0;
918err_free_ucode_sgt: 961err_free_ucode_sgt:
919 gk20a_free_sgtable(&sgt_pmu_ucode); 962 gk20a_free_sgtable(&sgt_pmu_ucode);
920err_free_acr_buf: 963err_free_acr_buf:
921 dma_free_coherent(d, img_size_in_bytes, 964 dma_free_coherent(d, img_size_in_bytes,
922 pacr_ucode_cpuva, iova); 965 pacr_ucode_cpuva, iova);
966 acr->acr_ucode.cpuva = NULL;
967 acr->acr_ucode.iova = 0;
968err_release_acr_fw:
969 release_firmware(acr_fw);
970 acr->acr_fw = NULL;
923 return err; 971 return err;
924} 972}
925 973
@@ -927,7 +975,7 @@ u8 pmu_is_debug_mode_en(struct gk20a *g)
927{ 975{
928 int ctl_stat = gk20a_readl(g, pwr_pmu_scpctl_stat_r()); 976 int ctl_stat = gk20a_readl(g, pwr_pmu_scpctl_stat_r());
929 return 1; 977 return 1;
930/*TODO return (ctl_stat & pwr_pmu_scpctl_stat_debug_mode_m());*/ 978 /*TODO return (ctl_stat & pwr_pmu_scpctl_stat_debug_mode_m());*/
931} 979}
932 980
933/* 981/*
@@ -966,8 +1014,8 @@ static int bl_bootstrap(struct pmu_gk20a *pmu,
966 struct flcn_bl_dmem_desc *pbl_desc, u32 bl_sz) 1014 struct flcn_bl_dmem_desc *pbl_desc, u32 bl_sz)
967{ 1015{
968 struct gk20a *g = gk20a_from_pmu(pmu); 1016 struct gk20a *g = gk20a_from_pmu(pmu);
1017 struct acr_gm20b *acr = &g->acr;
969 struct mm_gk20a *mm = &g->mm; 1018 struct mm_gk20a *mm = &g->mm;
970 struct pmu_ucode_desc *desc = pmu->desc;
971 u32 imem_dst_blk = 0; 1019 u32 imem_dst_blk = 0;
972 u32 virt_addr = 0; 1020 u32 virt_addr = 0;
973 u32 tag = 0; 1021 u32 tag = 0;
@@ -1007,7 +1055,7 @@ static int bl_bootstrap(struct pmu_gk20a *pmu,
1007 pwr_falcon_imemc_aincw_f(1)); 1055 pwr_falcon_imemc_aincw_f(1));
1008 virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8; 1056 virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8;
1009 tag = virt_addr >> 8; /* tag is always 256B aligned */ 1057 tag = virt_addr >> 8; /* tag is always 256B aligned */
1010 bl_ucode = (u32 *)(pmu->ucode.cpuva); 1058 bl_ucode = (u32 *)(acr->hsbl_ucode.cpuva);
1011 for (index = 0; index < bl_sz/4; index++) { 1059 for (index = 0; index < bl_sz/4; index++) {
1012 if ((index % 64) == 0) { 1060 if ((index % 64) == 0) {
1013 gk20a_writel(g, pwr_falcon_imemt_r(0), 1061 gk20a_writel(g, pwr_falcon_imemt_r(0),
@@ -1027,8 +1075,6 @@ static int bl_bootstrap(struct pmu_gk20a *pmu,
1027 gk20a_writel(g, pwr_falcon_cpuctl_r(), 1075 gk20a_writel(g, pwr_falcon_cpuctl_r(),
1028 pwr_falcon_cpuctl_startcpu_f(1)); 1076 pwr_falcon_cpuctl_startcpu_f(1));
1029 1077
1030 gk20a_writel(g, pwr_falcon_os_r(), desc->app_version);
1031
1032 return 0; 1078 return 0;
1033} 1079}
1034 1080
@@ -1082,7 +1128,6 @@ int gm20b_init_pmu_setup_hw1(struct gk20a *g, struct flcn_bl_dmem_desc *desc,
1082*/ 1128*/
1083int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt) 1129int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1084{ 1130{
1085 struct pmu_gk20a *pmu = &g->pmu;
1086 struct mm_gk20a *mm = &g->mm; 1131 struct mm_gk20a *mm = &g->mm;
1087 struct vm_gk20a *vm = &mm->pmu.vm; 1132 struct vm_gk20a *vm = &mm->pmu.vm;
1088 struct device *d = dev_from_gk20a(g); 1133 struct device *d = dev_from_gk20a(g);
@@ -1092,29 +1137,73 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1092 u32 bl_sz; 1137 u32 bl_sz;
1093 void *bl_cpuva; 1138 void *bl_cpuva;
1094 u64 bl_pmu_va; 1139 u64 bl_pmu_va;
1095 const struct firmware *hsbl_fw;
1096 struct acr_gm20b *acr = &g->acr; 1140 struct acr_gm20b *acr = &g->acr;
1141 const struct firmware *hsbl_fw = acr->hsbl_fw;
1097 struct hsflcn_bl_desc *pmu_bl_gm10x_desc; 1142 struct hsflcn_bl_desc *pmu_bl_gm10x_desc;
1098 u32 *pmu_bl_gm10x = NULL; 1143 u32 *pmu_bl_gm10x = NULL;
1099 DEFINE_DMA_ATTRS(attrs); 1144 DEFINE_DMA_ATTRS(attrs);
1100 gm20b_dbg_pmu(""); 1145 gm20b_dbg_pmu("");
1101 1146
1102 hsbl_fw = gk20a_request_firmware(g, GM20B_HSBIN_PMU_BL_UCODE_IMAGE);
1103 if (!hsbl_fw) { 1147 if (!hsbl_fw) {
1104 gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode!!"); 1148 hsbl_fw = gk20a_request_firmware(g,
1105 return -ENOENT; 1149 GM20B_HSBIN_PMU_BL_UCODE_IMAGE);
1150 if (!hsbl_fw) {
1151 gk20a_err(dev_from_gk20a(g), "pmu ucode load fail");
1152 return -ENOENT;
1153 }
1154 acr->hsbl_fw = hsbl_fw;
1155 acr->bl_bin_hdr = (struct bin_hdr *)hsbl_fw->data;
1156 acr->pmu_hsbl_desc = (struct hsflcn_bl_desc *)(hsbl_fw->data +
1157 acr->bl_bin_hdr->header_offset);
1158 pmu_bl_gm10x_desc = acr->pmu_hsbl_desc;
1159 pmu_bl_gm10x = (u32 *)(hsbl_fw->data +
1160 acr->bl_bin_hdr->data_offset);
1161 bl_sz = ALIGN(pmu_bl_gm10x_desc->bl_img_hdr.bl_code_size,
1162 256);
1163 acr->hsbl_ucode.size = bl_sz;
1164 gm20b_dbg_pmu("Executing Generic Bootloader\n");
1165
1166 /*TODO in code verify that enable PMU is done,
1167 scrubbing etc is done*/
1168 /*TODO in code verify that gmmu vm init is done*/
1169 dma_set_attr(DMA_ATTR_READ_ONLY, &attrs);
1170 bl_cpuva = dma_alloc_attrs(d, bl_sz,
1171 &iova,
1172 GFP_KERNEL,
1173 &attrs);
1174 gm20b_dbg_pmu("bl size is %x\n", bl_sz);
1175 if (!bl_cpuva) {
1176 gk20a_err(d, "failed to allocate memory\n");
1177 err = -ENOMEM;
1178 goto err_done;
1179 }
1180 acr->hsbl_ucode.cpuva = bl_cpuva;
1181 acr->hsbl_ucode.iova = iova;
1182
1183 err = gk20a_get_sgtable(d, &sgt_pmu_ucode,
1184 bl_cpuva,
1185 iova,
1186 bl_sz);
1187 if (err) {
1188 gk20a_err(d, "failed to allocate sg table\n");
1189 goto err_free_cpu_va;
1190 }
1191
1192 bl_pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_ucode,
1193 bl_sz,
1194 0, /* flags */
1195 gk20a_mem_flag_read_only);
1196 if (!bl_pmu_va) {
1197 gk20a_err(d, "failed to map pmu ucode memory!!");
1198 goto err_free_ucode_sgt;
1199 }
1200 acr->hsbl_ucode.pmu_va = bl_pmu_va;
1201
1202 for (i = 0; i < (bl_sz) >> 2; i++)
1203 gk20a_mem_wr32(bl_cpuva, i, pmu_bl_gm10x[i]);
1204 gm20b_dbg_pmu("Copied bl ucode to bl_cpuva\n");
1205 gk20a_free_sgtable(&sgt_pmu_ucode);
1106 } 1206 }
1107 acr->bl_bin_hdr = (struct bin_hdr *)hsbl_fw->data;
1108 acr->pmu_hsbl_desc = (struct hsflcn_bl_desc *)(hsbl_fw->data +
1109 acr->bl_bin_hdr->header_offset);
1110 pmu_bl_gm10x_desc = acr->pmu_hsbl_desc;
1111 pmu_bl_gm10x = (u32 *)(hsbl_fw->data + acr->bl_bin_hdr->data_offset);
1112 bl_sz = ALIGN(pmu_bl_gm10x_desc->bl_img_hdr.bl_code_size,
1113 256);
1114 gm20b_dbg_pmu("Executing Generic Bootloader\n");
1115
1116 /*TODO in code verify that enable PMU is done, scrubbing etc is done*/
1117 /*TODO in code verify that gmmu vm init is done*/
1118 /* 1207 /*
1119 * Disable interrupts to avoid kernel hitting breakpoint due 1208 * Disable interrupts to avoid kernel hitting breakpoint due
1120 * to PMU halt 1209 * to PMU halt
@@ -1122,43 +1211,13 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1122 1211
1123 gk20a_writel(g, pwr_falcon_irqsclr_r(), 1212 gk20a_writel(g, pwr_falcon_irqsclr_r(),
1124 gk20a_readl(g, pwr_falcon_irqsclr_r()) & (~(0x10))); 1213 gk20a_readl(g, pwr_falcon_irqsclr_r()) & (~(0x10)));
1214 gm20b_dbg_pmu("err reg :%x\n", readl(mc +
1215 MC_ERR_GENERALIZED_CARVEOUT_STATUS_0));
1216 gm20b_dbg_pmu("phys sec reg %x\n", gk20a_readl(g,
1217 pwr_falcon_mmu_phys_sec_r()));
1218 gm20b_dbg_pmu("sctl reg %x\n", gk20a_readl(g, pwr_falcon_sctl_r()));
1125 1219
1126 dma_set_attr(DMA_ATTR_READ_ONLY, &attrs); 1220 gm20b_init_pmu_setup_hw1(g, desc, acr->hsbl_ucode.size);
1127 bl_cpuva = dma_alloc_attrs(d, bl_sz,
1128 &iova,
1129 GFP_KERNEL,
1130 &attrs);
1131 gm20b_dbg_pmu("bl size is %x\n", bl_sz);
1132 if (!bl_cpuva) {
1133 gk20a_err(d, "failed to allocate memory\n");
1134 err = -ENOMEM;
1135 goto err_done;
1136 }
1137
1138 err = gk20a_get_sgtable(d, &sgt_pmu_ucode,
1139 bl_cpuva,
1140 iova,
1141 bl_sz);
1142 if (err) {
1143 gk20a_err(d, "failed to allocate sg table\n");
1144 goto err_free_cpu_va;
1145 }
1146
1147 bl_pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_ucode,
1148 bl_sz,
1149 0, /* flags */
1150 gk20a_mem_flag_read_only);
1151 if (!bl_pmu_va) {
1152 gk20a_err(d, "failed to map pmu ucode memory!!");
1153 goto err_free_ucode_sgt;
1154 }
1155
1156 for (i = 0; i < (bl_sz) >> 2; i++)
1157 gk20a_mem_wr32(bl_cpuva, i, pmu_bl_gm10x[i]);
1158 gm20b_dbg_pmu("Copied bl ucode to bl_cpuva\n");
1159 pmu->ucode.cpuva = bl_cpuva;
1160 pmu->ucode.pmu_va = bl_pmu_va;
1161 gm20b_init_pmu_setup_hw1(g, desc, bl_sz);
1162 /* Poll for HALT */ 1221 /* Poll for HALT */
1163 if (b_wait_for_halt) { 1222 if (b_wait_for_halt) {
1164 err = pmu_wait_for_halt(g, GPU_TIMEOUT_DEFAULT); 1223 err = pmu_wait_for_halt(g, GPU_TIMEOUT_DEFAULT);
@@ -1176,16 +1235,17 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1176 pwr_falcon_mmu_phys_sec_r())); 1235 pwr_falcon_mmu_phys_sec_r()));
1177 gm20b_dbg_pmu("sctl reg %x\n", gk20a_readl(g, pwr_falcon_sctl_r())); 1236 gm20b_dbg_pmu("sctl reg %x\n", gk20a_readl(g, pwr_falcon_sctl_r()));
1178 start_gm20b_pmu(g); 1237 start_gm20b_pmu(g);
1179 err = 0; 1238 return 0;
1180err_unmap_bl: 1239err_unmap_bl:
1181 gk20a_gmmu_unmap(vm, pmu->ucode.pmu_va, 1240 gk20a_gmmu_unmap(vm, acr->hsbl_ucode.pmu_va,
1182 bl_sz, gk20a_mem_flag_none); 1241 acr->hsbl_ucode.size, gk20a_mem_flag_none);
1183err_free_ucode_sgt: 1242err_free_ucode_sgt:
1184 gk20a_free_sgtable(&sgt_pmu_ucode); 1243 gk20a_free_sgtable(&sgt_pmu_ucode);
1185err_free_cpu_va: 1244err_free_cpu_va:
1186 dma_free_attrs(d, bl_sz, 1245 dma_free_attrs(d, acr->hsbl_ucode.size,
1187 bl_cpuva, iova, &attrs); 1246 acr->hsbl_ucode.cpuva, acr->hsbl_ucode.iova, &attrs);
1188err_done: 1247err_done:
1248 release_firmware(hsbl_fw);
1189 return err; 1249 return err;
1190} 1250}
1191 1251