summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b
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
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')
-rw-r--r--drivers/gpu/nvgpu/gp10b/Makefile3
-rw-r--r--drivers/gpu/nvgpu/gp10b/gp10b_sysfs.c66
-rw-r--r--drivers/gpu/nvgpu/gp10b/gp10b_sysfs.h25
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_gp10b.c10
-rw-r--r--drivers/gpu/nvgpu/gp10b/hw_gr_gp10b.h4
-rw-r--r--drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c8
-rw-r--r--drivers/gpu/nvgpu/gp10b/pmu_gp10b.c76
7 files changed, 187 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/Makefile b/drivers/gpu/nvgpu/gp10b/Makefile
index 0542fd67..8b930bca 100644
--- a/drivers/gpu/nvgpu/gp10b/Makefile
+++ b/drivers/gpu/nvgpu/gp10b/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_GK20A) += \
25 gp10b_gating_reglist.o \ 25 gp10b_gating_reglist.o \
26 regops_gp10b.o \ 26 regops_gp10b.o \
27 cde_gp10b.o \ 27 cde_gp10b.o \
28 therm_gp10b.o 28 therm_gp10b.o \
29 gp10b_sysfs.o
29 30
30obj-$(CONFIG_TEGRA_GK20A) += platform_gp10b_tegra.o 31obj-$(CONFIG_TEGRA_GK20A) += platform_gp10b_tegra.o
diff --git a/drivers/gpu/nvgpu/gp10b/gp10b_sysfs.c b/drivers/gpu/nvgpu/gp10b/gp10b_sysfs.c
new file mode 100644
index 00000000..800f39c3
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gp10b_sysfs.c
@@ -0,0 +1,66 @@
1/*
2 * GP10B specific sysfs files
3 *
4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
5 *
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,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15
16#include <linux/platform_device.h>
17
18#include "gk20a/gk20a.h"
19#include "gp10b_sysfs.h"
20
21#define ROOTRW (S_IRWXU|S_IRGRP|S_IROTH)
22
23static ssize_t ecc_enable_store(struct device *device,
24 struct device_attribute *attr, const char *buf, size_t count)
25{
26 struct platform_device *ndev = to_platform_device(device);
27 struct gk20a *g = get_gk20a(ndev);
28 u32 ecc_mask;
29 u32 err = 0;
30
31 err = sscanf(buf, "%d", &ecc_mask);
32 if (err == 1) {
33 err = g->ops.pmu.send_lrf_tex_ltc_dram_overide_en_dis_cmd
34 (g, ecc_mask);
35 if (err)
36 dev_err(device, "ECC override did not happen\n");
37 } else
38 return -EINVAL;
39 return count;
40}
41
42static ssize_t ecc_enable_read(struct device *device,
43 struct device_attribute *attr, char *buf)
44{
45 struct platform_device *ndev = to_platform_device(device);
46 struct gk20a *g = get_gk20a(ndev);
47
48 return sprintf(buf, "ecc override =0x%x\n",
49 g->ops.gr.get_lrf_tex_ltc_dram_override(g));
50}
51
52static DEVICE_ATTR(ecc_enable, ROOTRW, ecc_enable_read, ecc_enable_store);
53
54void gp10b_create_sysfs(struct platform_device *dev)
55{
56 int error = 0;
57
58 error |= device_create_file(&dev->dev, &dev_attr_ecc_enable);
59 if (error)
60 dev_err(&dev->dev, "Failed to create sysfs attributes!\n");
61}
62
63void gp10b_remove_sysfs(struct device *dev)
64{
65 device_remove_file(dev, &dev_attr_ecc_enable);
66}
diff --git a/drivers/gpu/nvgpu/gp10b/gp10b_sysfs.h b/drivers/gpu/nvgpu/gp10b/gp10b_sysfs.h
new file mode 100644
index 00000000..c1d101da
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gp10b_sysfs.h
@@ -0,0 +1,25 @@
1/*
2 * GP10B specific sysfs files
3 *
4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
5 *
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,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15
16#ifndef _GP10B_SYSFS_H_
17#define _GP10B_SYSFS_H_
18
19/*ECC Fuse*/
20#define FUSE_OPT_ECC_EN 0x358
21
22void gp10b_create_sysfs(struct platform_device *dev);
23void gp10b_remove_sysfs(struct device *dev);
24
25#endif /*_GP10B_SYSFS_H_*/
diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
index 90d0ce8d..9eea7d43 100644
--- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
@@ -28,6 +28,7 @@
28#include "hw_proj_gp10b.h" 28#include "hw_proj_gp10b.h"
29#include "hw_ctxsw_prog_gp10b.h" 29#include "hw_ctxsw_prog_gp10b.h"
30#include "hw_mc_gp10b.h" 30#include "hw_mc_gp10b.h"
31#include "gp10b_sysfs.h"
31#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
32 33
33static bool gr_gp10b_is_valid_class(struct gk20a *g, u32 class_num) 34static bool gr_gp10b_is_valid_class(struct gk20a *g, u32 class_num)
@@ -1702,6 +1703,14 @@ static u32 gp10b_mask_hww_warp_esr(u32 hww_warp_esr)
1702 return hww_warp_esr; 1703 return hww_warp_esr;
1703} 1704}
1704 1705
1706static u32 get_ecc_override_val(struct gk20a *g)
1707{
1708 if (tegra_fuse_readl(FUSE_OPT_ECC_EN))
1709 return gk20a_readl(g, gr_fecs_feature_override_ecc_r());
1710 else
1711 return 0;
1712}
1713
1705void gp10b_init_gr(struct gpu_ops *gops) 1714void gp10b_init_gr(struct gpu_ops *gops)
1706{ 1715{
1707 gm20b_init_gr(gops); 1716 gm20b_init_gr(gops);
@@ -1739,4 +1748,5 @@ void gp10b_init_gr(struct gpu_ops *gops)
1739 gr_gp10b_pre_process_sm_exception; 1748 gr_gp10b_pre_process_sm_exception;
1740 gops->gr.handle_fecs_error = gr_gp10b_handle_fecs_error; 1749 gops->gr.handle_fecs_error = gr_gp10b_handle_fecs_error;
1741 gops->gr.create_gr_sysfs = gr_gp10b_create_sysfs; 1750 gops->gr.create_gr_sysfs = gr_gp10b_create_sysfs;
1751 gops->gr.get_lrf_tex_ltc_dram_override = get_ecc_override_val;
1742} 1752}
diff --git a/drivers/gpu/nvgpu/gp10b/hw_gr_gp10b.h b/drivers/gpu/nvgpu/gp10b/hw_gr_gp10b.h
index 0480527c..62ac1327 100644
--- a/drivers/gpu/nvgpu/gp10b/hw_gr_gp10b.h
+++ b/drivers/gpu/nvgpu/gp10b/hw_gr_gp10b.h
@@ -1478,6 +1478,10 @@ static inline u32 gr_fecs_ctxsw_idlestate_r(void)
1478{ 1478{
1479 return 0x00409420; 1479 return 0x00409420;
1480} 1480}
1481static inline u32 gr_fecs_feature_override_ecc_r(void)
1482{
1483 return 0x00409658;
1484}
1481static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void) 1485static inline u32 gr_gpc0_gpccs_ctxsw_idlestate_r(void)
1482{ 1486{
1483 return 0x00502420; 1487 return 0x00502420;
diff --git a/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c
index 3221e423..c4a5179a 100644
--- a/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c
@@ -34,6 +34,7 @@
34#include "ltc_gp10b.h" 34#include "ltc_gp10b.h"
35#include "hw_gr_gp10b.h" 35#include "hw_gr_gp10b.h"
36#include "hw_ltc_gp10b.h" 36#include "hw_ltc_gp10b.h"
37#include "gp10b_sysfs.h"
37 38
38#define GP10B_MAX_SUPPORTED_FREQS 11 39#define GP10B_MAX_SUPPORTED_FREQS 11
39static unsigned long gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS]; 40static unsigned long gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS];
@@ -142,7 +143,8 @@ static int gp10b_tegra_late_probe(struct platform_device *pdev)
142{ 143{
143 /* Make gk20a power domain a subdomain of host1x */ 144 /* Make gk20a power domain a subdomain of host1x */
144 nvhost_register_client_domain(dev_to_genpd(&pdev->dev)); 145 nvhost_register_client_domain(dev_to_genpd(&pdev->dev));
145 146 /*Create GP10B specific sysfs*/
147 gp10b_create_sysfs(pdev);
146 return 0; 148 return 0;
147} 149}
148 150
@@ -150,9 +152,9 @@ static int gp10b_tegra_remove(struct platform_device *pdev)
150{ 152{
151 /* remove gk20a power subdomain from host1x */ 153 /* remove gk20a power subdomain from host1x */
152 nvhost_unregister_client_domain(dev_to_genpd(&pdev->dev)); 154 nvhost_unregister_client_domain(dev_to_genpd(&pdev->dev));
153
154 gr_gp10b_remove_sysfs(&pdev->dev); 155 gr_gp10b_remove_sysfs(&pdev->dev);
155 156 /*Remove GP10B specific sysfs*/
157 gp10b_remove_sysfs(&pdev->dev);
156 return 0; 158 return 0;
157 159
158} 160}
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}