summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c
diff options
context:
space:
mode:
authorSupriya <ssharatkumar@nvidia.com>2015-12-10 02:24:38 -0500
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:52:10 -0500
commit640d0e2c3b58294cd11f420a5fc8377d490c43d3 (patch)
tree1ea4161fcb84d264c9e3dd8e8d0a446e8aff590e /drivers/gpu/nvgpu/gp10b/pmu_gp10b.c
parent02ee4d418834c99746487b72b04d5f10139eea90 (diff)
gpu: nvgpu: ECC override
-sysfs functions to call into LS PMU and modify ECC overide register Bug 1699676 Change-Id: Iaf6cc3a86160b806e52ab168577caad42b2c5d22 Signed-off-by: Supriya <ssharatkumar@nvidia.com> Reviewed-on: http://git-master/r/921252 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b/pmu_gp10b.c')
-rw-r--r--drivers/gpu/nvgpu/gp10b/pmu_gp10b.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c
index 00701a50..6a704813 100644
--- a/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c
@@ -2,7 +2,7 @@
2 * GP10B PMU 2 * GP10B PMU
3 * 3 *
4 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
5* 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation. 8 * version 2, as published by the Free Software Foundation.
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/delay.h> /* for udelay */ 16#include <linux/delay.h> /* for udelay */
17#include <linux/tegra-fuse.h>
17#include "gk20a/gk20a.h" 18#include "gk20a/gk20a.h"
18#include "gk20a/pmu_gk20a.h" 19#include "gk20a/pmu_gk20a.h"
19#include "gm20b/acr_gm20b.h" 20#include "gm20b/acr_gm20b.h"
@@ -21,6 +22,7 @@
21 22
22#include "pmu_gp10b.h" 23#include "pmu_gp10b.h"
23#include "hw_pwr_gp10b.h" 24#include "hw_pwr_gp10b.h"
25#include "gp10b_sysfs.h"
24 26
25#define gp10b_dbg_pmu(fmt, arg...) \ 27#define gp10b_dbg_pmu(fmt, arg...) \
26 gk20a_dbg(gpu_dbg_pmu, fmt, ##arg) 28 gk20a_dbg(gpu_dbg_pmu, fmt, ##arg)
@@ -324,6 +326,76 @@ static int gp10b_init_pmu_setup_hw1(struct gk20a *g)
324 326
325} 327}
326 328
329static void pmu_handle_ecc_en_dis_msg(struct gk20a *g, struct pmu_msg *msg,
330 void *param, u32 handle, u32 status)
331{
332 struct pmu_gk20a *pmu = &g->pmu;
333 struct pmu_msg_lrf_tex_ltc_dram_en_dis *ecc =
334 &msg->msg.lrf_tex_ltc_dram.en_dis;
335 gk20a_dbg_fn("");
336
337 if (status != 0) {
338 gk20a_err(dev_from_gk20a(g), "ECC en dis cmd aborted");
339 return;
340 }
341 if (msg->msg.lrf_tex_ltc_dram.msg_type !=
342 PMU_LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS) {
343 gk20a_err(dev_from_gk20a(g),
344 "Invalid msg for LRF_TEX_LTC_DRAM_CMD_ID_EN_DIS cmd");
345 return;
346 } else if (ecc->pmu_status != 0) {
347 gk20a_err(dev_from_gk20a(g),
348 "LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS msg status = %x",
349 ecc->pmu_status);
350 gk20a_err(dev_from_gk20a(g),
351 "LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS msg en fail = %x",
352 ecc->en_fail_mask);
353 gk20a_err(dev_from_gk20a(g),
354 "LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS msg dis fail = %x",
355 ecc->dis_fail_mask);
356 } else
357 pmu->override_done = 1;
358 gk20a_dbg_fn("done");
359}
360
361static int send_ecc_overide_en_dis_cmd(struct gk20a *g, u32 bitmask)
362{
363 struct pmu_gk20a *pmu = &g->pmu;
364 struct pmu_cmd cmd;
365 u32 seq;
366 int status;
367 gk20a_dbg_fn("");
368
369 if (!tegra_fuse_readl(FUSE_OPT_ECC_EN)) {
370 gk20a_err(dev_from_gk20a(g), "Board not ECC capable");
371 return -1;
372 }
373 if (!(g->acr.capabilities &
374 ACR_LRF_TEX_LTC_DRAM_PRIV_MASK_ENABLE_LS_OVERRIDE)) {
375 gk20a_err(dev_from_gk20a(g), "check ACR capabilities");
376 return -1;
377 }
378 memset(&cmd, 0, sizeof(struct pmu_cmd));
379 cmd.hdr.unit_id = PMU_UNIT_FECS_MEM_OVERRIDE;
380 cmd.hdr.size = PMU_CMD_HDR_SIZE +
381 sizeof(struct pmu_cmd_lrf_tex_ltc_dram_en_dis);
382 cmd.cmd.lrf_tex_ltc_dram.en_dis.cmd_type =
383 PMU_LRF_TEX_LTC_DRAM_CMD_ID_EN_DIS;
384 cmd.cmd.lrf_tex_ltc_dram.en_dis.en_dis_mask = (u8)(bitmask & 0xff);
385
386 gp10b_dbg_pmu("cmd post PMU_ECC_CMD_ID_EN_DIS_ECC");
387 pmu->override_done = 0;
388 status = gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ,
389 pmu_handle_ecc_en_dis_msg, NULL, &seq, ~0);
390 if (status)
391 gk20a_err(dev_from_gk20a(g), "ECC override failed");
392 else
393 pmu_wait_message_cond(pmu, gk20a_get_gr_idle_timeout(g),
394 &pmu->override_done, 1);
395 gk20a_dbg_fn("done");
396 return status;
397}
398
327void gp10b_init_pmu_ops(struct gpu_ops *gops) 399void gp10b_init_pmu_ops(struct gpu_ops *gops)
328{ 400{
329 if (gops->privsecurity) { 401 if (gops->privsecurity) {
@@ -342,4 +414,6 @@ void gp10b_init_pmu_ops(struct gpu_ops *gops)
342 gops->pmu.write_dmatrfbase = gp10b_write_dmatrfbase; 414 gops->pmu.write_dmatrfbase = gp10b_write_dmatrfbase;
343 gops->pmu.pmu_elpg_statistics = gp10b_pmu_elpg_statistics; 415 gops->pmu.pmu_elpg_statistics = gp10b_pmu_elpg_statistics;
344 gops->pmu.pmu_pg_grinit_param = gp10b_pg_gr_init; 416 gops->pmu.pmu_pg_grinit_param = gp10b_pg_gr_init;
417 gops->pmu.send_lrf_tex_ltc_dram_overide_en_dis_cmd =
418 send_ecc_overide_en_dis_cmd;
345} 419}