From 640d0e2c3b58294cd11f420a5fc8377d490c43d3 Mon Sep 17 00:00:00 2001 From: Supriya Date: Thu, 10 Dec 2015 12:54:38 +0530 Subject: 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 Reviewed-on: http://git-master/r/921252 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Vijayakumar Subbu GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gp10b/pmu_gp10b.c | 76 ++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu/gp10b/pmu_gp10b.c') 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 @@ * GP10B PMU * * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. -* + * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -14,6 +14,7 @@ */ #include /* for udelay */ +#include #include "gk20a/gk20a.h" #include "gk20a/pmu_gk20a.h" #include "gm20b/acr_gm20b.h" @@ -21,6 +22,7 @@ #include "pmu_gp10b.h" #include "hw_pwr_gp10b.h" +#include "gp10b_sysfs.h" #define gp10b_dbg_pmu(fmt, arg...) \ gk20a_dbg(gpu_dbg_pmu, fmt, ##arg) @@ -324,6 +326,76 @@ static int gp10b_init_pmu_setup_hw1(struct gk20a *g) } +static void pmu_handle_ecc_en_dis_msg(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct pmu_gk20a *pmu = &g->pmu; + struct pmu_msg_lrf_tex_ltc_dram_en_dis *ecc = + &msg->msg.lrf_tex_ltc_dram.en_dis; + gk20a_dbg_fn(""); + + if (status != 0) { + gk20a_err(dev_from_gk20a(g), "ECC en dis cmd aborted"); + return; + } + if (msg->msg.lrf_tex_ltc_dram.msg_type != + PMU_LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS) { + gk20a_err(dev_from_gk20a(g), + "Invalid msg for LRF_TEX_LTC_DRAM_CMD_ID_EN_DIS cmd"); + return; + } else if (ecc->pmu_status != 0) { + gk20a_err(dev_from_gk20a(g), + "LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS msg status = %x", + ecc->pmu_status); + gk20a_err(dev_from_gk20a(g), + "LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS msg en fail = %x", + ecc->en_fail_mask); + gk20a_err(dev_from_gk20a(g), + "LRF_TEX_LTC_DRAM_MSG_ID_EN_DIS msg dis fail = %x", + ecc->dis_fail_mask); + } else + pmu->override_done = 1; + gk20a_dbg_fn("done"); +} + +static int send_ecc_overide_en_dis_cmd(struct gk20a *g, u32 bitmask) +{ + struct pmu_gk20a *pmu = &g->pmu; + struct pmu_cmd cmd; + u32 seq; + int status; + gk20a_dbg_fn(""); + + if (!tegra_fuse_readl(FUSE_OPT_ECC_EN)) { + gk20a_err(dev_from_gk20a(g), "Board not ECC capable"); + return -1; + } + if (!(g->acr.capabilities & + ACR_LRF_TEX_LTC_DRAM_PRIV_MASK_ENABLE_LS_OVERRIDE)) { + gk20a_err(dev_from_gk20a(g), "check ACR capabilities"); + return -1; + } + memset(&cmd, 0, sizeof(struct pmu_cmd)); + cmd.hdr.unit_id = PMU_UNIT_FECS_MEM_OVERRIDE; + cmd.hdr.size = PMU_CMD_HDR_SIZE + + sizeof(struct pmu_cmd_lrf_tex_ltc_dram_en_dis); + cmd.cmd.lrf_tex_ltc_dram.en_dis.cmd_type = + PMU_LRF_TEX_LTC_DRAM_CMD_ID_EN_DIS; + cmd.cmd.lrf_tex_ltc_dram.en_dis.en_dis_mask = (u8)(bitmask & 0xff); + + gp10b_dbg_pmu("cmd post PMU_ECC_CMD_ID_EN_DIS_ECC"); + pmu->override_done = 0; + status = gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ, + pmu_handle_ecc_en_dis_msg, NULL, &seq, ~0); + if (status) + gk20a_err(dev_from_gk20a(g), "ECC override failed"); + else + pmu_wait_message_cond(pmu, gk20a_get_gr_idle_timeout(g), + &pmu->override_done, 1); + gk20a_dbg_fn("done"); + return status; +} + void gp10b_init_pmu_ops(struct gpu_ops *gops) { if (gops->privsecurity) { @@ -342,4 +414,6 @@ void gp10b_init_pmu_ops(struct gpu_ops *gops) gops->pmu.write_dmatrfbase = gp10b_write_dmatrfbase; gops->pmu.pmu_elpg_statistics = gp10b_pmu_elpg_statistics; gops->pmu.pmu_pg_grinit_param = gp10b_pg_gr_init; + gops->pmu.send_lrf_tex_ltc_dram_overide_en_dis_cmd = + send_ecc_overide_en_dis_cmd; } -- cgit v1.2.2