aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDavid Panariti <David.Panariti@amd.com>2017-09-15 16:30:08 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-12-06 12:47:48 -0500
commit02bab92328b4d4e0f688be960f0fb5fed1c07ea2 (patch)
treebc60f2920bfd3baea51730c958f3007424f9c8fd /drivers/gpu
parent26f1108525c7f085fd5e555d4b62e7bba42a723b (diff)
drm/amdgpu: Add ability to determine and report if board supports ECC.
Make initialization code check the ECC related registers, which are initialized by the VBIOS, to see if ECC is present and initialized and DRM_INFO() the result. Signed-off-by: David Panariti <David.Panariti@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index b067b46a418f..d9a91098bcb1 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -36,6 +36,7 @@
36#include "vega10/ATHUB/athub_1_0_offset.h" 36#include "vega10/ATHUB/athub_1_0_offset.h"
37 37
38#include "soc15_common.h" 38#include "soc15_common.h"
39#include "vega10/UMC/umc_6_0_sh_mask.h"
39 40
40#include "nbio_v6_1.h" 41#include "nbio_v6_1.h"
41#include "nbio_v7_0.h" 42#include "nbio_v7_0.h"
@@ -85,6 +86,121 @@ static const u32 golden_settings_athub_1_0_0[] =
85 SOC15_REG_OFFSET(ATHUB, 0, mmRPB_ARB_CNTL2), 0x00ff00ff, 0x00080008 86 SOC15_REG_OFFSET(ATHUB, 0, mmRPB_ARB_CNTL2), 0x00ff00ff, 0x00080008
86}; 87};
87 88
89/* Ecc related register addresses, (BASE + reg offset) */
90/* Universal Memory Controller caps (may be fused). */
91/* UMCCH:UmcLocalCap */
92#define UMCLOCALCAPS_ADDR0 (0x00014306 + 0x00000000)
93#define UMCLOCALCAPS_ADDR1 (0x00014306 + 0x00000800)
94#define UMCLOCALCAPS_ADDR2 (0x00014306 + 0x00001000)
95#define UMCLOCALCAPS_ADDR3 (0x00014306 + 0x00001800)
96#define UMCLOCALCAPS_ADDR4 (0x00054306 + 0x00000000)
97#define UMCLOCALCAPS_ADDR5 (0x00054306 + 0x00000800)
98#define UMCLOCALCAPS_ADDR6 (0x00054306 + 0x00001000)
99#define UMCLOCALCAPS_ADDR7 (0x00054306 + 0x00001800)
100#define UMCLOCALCAPS_ADDR8 (0x00094306 + 0x00000000)
101#define UMCLOCALCAPS_ADDR9 (0x00094306 + 0x00000800)
102#define UMCLOCALCAPS_ADDR10 (0x00094306 + 0x00001000)
103#define UMCLOCALCAPS_ADDR11 (0x00094306 + 0x00001800)
104#define UMCLOCALCAPS_ADDR12 (0x000d4306 + 0x00000000)
105#define UMCLOCALCAPS_ADDR13 (0x000d4306 + 0x00000800)
106#define UMCLOCALCAPS_ADDR14 (0x000d4306 + 0x00001000)
107#define UMCLOCALCAPS_ADDR15 (0x000d4306 + 0x00001800)
108
109/* Universal Memory Controller Channel config. */
110/* UMCCH:UMC_CONFIG */
111#define UMCCH_UMC_CONFIG_ADDR0 (0x00014040 + 0x00000000)
112#define UMCCH_UMC_CONFIG_ADDR1 (0x00014040 + 0x00000800)
113#define UMCCH_UMC_CONFIG_ADDR2 (0x00014040 + 0x00001000)
114#define UMCCH_UMC_CONFIG_ADDR3 (0x00014040 + 0x00001800)
115#define UMCCH_UMC_CONFIG_ADDR4 (0x00054040 + 0x00000000)
116#define UMCCH_UMC_CONFIG_ADDR5 (0x00054040 + 0x00000800)
117#define UMCCH_UMC_CONFIG_ADDR6 (0x00054040 + 0x00001000)
118#define UMCCH_UMC_CONFIG_ADDR7 (0x00054040 + 0x00001800)
119#define UMCCH_UMC_CONFIG_ADDR8 (0x00094040 + 0x00000000)
120#define UMCCH_UMC_CONFIG_ADDR9 (0x00094040 + 0x00000800)
121#define UMCCH_UMC_CONFIG_ADDR10 (0x00094040 + 0x00001000)
122#define UMCCH_UMC_CONFIG_ADDR11 (0x00094040 + 0x00001800)
123#define UMCCH_UMC_CONFIG_ADDR12 (0x000d4040 + 0x00000000)
124#define UMCCH_UMC_CONFIG_ADDR13 (0x000d4040 + 0x00000800)
125#define UMCCH_UMC_CONFIG_ADDR14 (0x000d4040 + 0x00001000)
126#define UMCCH_UMC_CONFIG_ADDR15 (0x000d4040 + 0x00001800)
127
128/* Universal Memory Controller Channel Ecc config. */
129/* UMCCH:EccCtrl */
130#define UMCCH_ECCCTRL_ADDR0 (0x00014053 + 0x00000000)
131#define UMCCH_ECCCTRL_ADDR1 (0x00014053 + 0x00000800)
132#define UMCCH_ECCCTRL_ADDR2 (0x00014053 + 0x00001000)
133#define UMCCH_ECCCTRL_ADDR3 (0x00014053 + 0x00001800)
134#define UMCCH_ECCCTRL_ADDR4 (0x00054053 + 0x00000000)
135#define UMCCH_ECCCTRL_ADDR5 (0x00054053 + 0x00000800)
136#define UMCCH_ECCCTRL_ADDR6 (0x00054053 + 0x00001000)
137#define UMCCH_ECCCTRL_ADDR7 (0x00054053 + 0x00001800)
138#define UMCCH_ECCCTRL_ADDR8 (0x00094053 + 0x00000000)
139#define UMCCH_ECCCTRL_ADDR9 (0x00094053 + 0x00000800)
140#define UMCCH_ECCCTRL_ADDR10 (0x00094053 + 0x00001000)
141#define UMCCH_ECCCTRL_ADDR11 (0x00094053 + 0x00001800)
142#define UMCCH_ECCCTRL_ADDR12 (0x000d4053 + 0x00000000)
143#define UMCCH_ECCCTRL_ADDR13 (0x000d4053 + 0x00000800)
144#define UMCCH_ECCCTRL_ADDR14 (0x000d4053 + 0x00001000)
145#define UMCCH_ECCCTRL_ADDR15 (0x000d4053 + 0x00001800)
146
147static const uint32_t ecc_umclocalcap_addrs[] = {
148 UMCLOCALCAPS_ADDR0,
149 UMCLOCALCAPS_ADDR1,
150 UMCLOCALCAPS_ADDR2,
151 UMCLOCALCAPS_ADDR3,
152 UMCLOCALCAPS_ADDR4,
153 UMCLOCALCAPS_ADDR5,
154 UMCLOCALCAPS_ADDR6,
155 UMCLOCALCAPS_ADDR7,
156 UMCLOCALCAPS_ADDR8,
157 UMCLOCALCAPS_ADDR9,
158 UMCLOCALCAPS_ADDR10,
159 UMCLOCALCAPS_ADDR11,
160 UMCLOCALCAPS_ADDR12,
161 UMCLOCALCAPS_ADDR13,
162 UMCLOCALCAPS_ADDR14,
163 UMCLOCALCAPS_ADDR15,
164};
165
166static const uint32_t ecc_umcch_umc_config_addrs[] = {
167 UMCCH_UMC_CONFIG_ADDR0,
168 UMCCH_UMC_CONFIG_ADDR1,
169 UMCCH_UMC_CONFIG_ADDR2,
170 UMCCH_UMC_CONFIG_ADDR3,
171 UMCCH_UMC_CONFIG_ADDR4,
172 UMCCH_UMC_CONFIG_ADDR5,
173 UMCCH_UMC_CONFIG_ADDR6,
174 UMCCH_UMC_CONFIG_ADDR7,
175 UMCCH_UMC_CONFIG_ADDR8,
176 UMCCH_UMC_CONFIG_ADDR9,
177 UMCCH_UMC_CONFIG_ADDR10,
178 UMCCH_UMC_CONFIG_ADDR11,
179 UMCCH_UMC_CONFIG_ADDR12,
180 UMCCH_UMC_CONFIG_ADDR13,
181 UMCCH_UMC_CONFIG_ADDR14,
182 UMCCH_UMC_CONFIG_ADDR15,
183};
184
185static const uint32_t ecc_umcch_eccctrl_addrs[] = {
186 UMCCH_ECCCTRL_ADDR0,
187 UMCCH_ECCCTRL_ADDR1,
188 UMCCH_ECCCTRL_ADDR2,
189 UMCCH_ECCCTRL_ADDR3,
190 UMCCH_ECCCTRL_ADDR4,
191 UMCCH_ECCCTRL_ADDR5,
192 UMCCH_ECCCTRL_ADDR6,
193 UMCCH_ECCCTRL_ADDR7,
194 UMCCH_ECCCTRL_ADDR8,
195 UMCCH_ECCCTRL_ADDR9,
196 UMCCH_ECCCTRL_ADDR10,
197 UMCCH_ECCCTRL_ADDR11,
198 UMCCH_ECCCTRL_ADDR12,
199 UMCCH_ECCCTRL_ADDR13,
200 UMCCH_ECCCTRL_ADDR14,
201 UMCCH_ECCCTRL_ADDR15,
202};
203
88static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, 204static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
89 struct amdgpu_irq_src *src, 205 struct amdgpu_irq_src *src,
90 unsigned type, 206 unsigned type,
@@ -389,6 +505,85 @@ static int gmc_v9_0_early_init(void *handle)
389 return 0; 505 return 0;
390} 506}
391 507
508static int gmc_v9_0_ecc_available(struct amdgpu_device *adev)
509{
510 uint32_t reg_val;
511 uint32_t reg_addr;
512 uint32_t field_val;
513 size_t i;
514 uint32_t fv2;
515 size_t lost_sheep;
516
517 DRM_DEBUG("ecc: gmc_v9_0_ecc_available()\n");
518
519 lost_sheep = 0;
520 for (i = 0; i < ARRAY_SIZE(ecc_umclocalcap_addrs); ++i) {
521 reg_addr = ecc_umclocalcap_addrs[i];
522 DRM_DEBUG("ecc: "
523 "UMCCH_UmcLocalCap[%zu]: reg_addr: 0x%08x\n",
524 i, reg_addr);
525 reg_val = RREG32(reg_addr);
526 field_val = REG_GET_FIELD(reg_val, UMCCH0_0_UmcLocalCap,
527 EccDis);
528 DRM_DEBUG("ecc: "
529 "reg_val: 0x%08x, "
530 "EccDis: 0x%08x, ",
531 reg_val, field_val);
532 if (field_val) {
533 DRM_ERROR("ecc: UmcLocalCap:EccDis is set.\n");
534 ++lost_sheep;
535 }
536 }
537
538 for (i = 0; i < ARRAY_SIZE(ecc_umcch_umc_config_addrs); ++i) {
539 reg_addr = ecc_umcch_umc_config_addrs[i];
540 DRM_DEBUG("ecc: "
541 "UMCCH0_0_UMC_CONFIG[%zu]: reg_addr: 0x%08x",
542 i, reg_addr);
543 reg_val = RREG32(reg_addr);
544 field_val = REG_GET_FIELD(reg_val, UMCCH0_0_UMC_CONFIG,
545 DramReady);
546 DRM_DEBUG("ecc: "
547 "reg_val: 0x%08x, "
548 "DramReady: 0x%08x\n",
549 reg_val, field_val);
550
551 if (!field_val) {
552 DRM_ERROR("ecc: UMC_CONFIG:DramReady is not set.\n");
553 ++lost_sheep;
554 }
555 }
556
557 for (i = 0; i < ARRAY_SIZE(ecc_umcch_eccctrl_addrs); ++i) {
558 reg_addr = ecc_umcch_eccctrl_addrs[i];
559 DRM_DEBUG("ecc: "
560 "UMCCH_EccCtrl[%zu]: reg_addr: 0x%08x, ",
561 i, reg_addr);
562 reg_val = RREG32(reg_addr);
563 field_val = REG_GET_FIELD(reg_val, UMCCH0_0_EccCtrl,
564 WrEccEn);
565 fv2 = REG_GET_FIELD(reg_val, UMCCH0_0_EccCtrl,
566 RdEccEn);
567 DRM_DEBUG("ecc: "
568 "reg_val: 0x%08x, "
569 "WrEccEn: 0x%08x, "
570 "RdEccEn: 0x%08x\n",
571 reg_val, field_val, fv2);
572
573 if (!field_val) {
574 DRM_ERROR("ecc: WrEccEn is not set\n");
575 ++lost_sheep;
576 }
577 if (!fv2) {
578 DRM_ERROR("ecc: RdEccEn is not set\n");
579 ++lost_sheep;
580 }
581 }
582
583 DRM_DEBUG("ecc: lost_sheep: %zu\n", lost_sheep);
584 return lost_sheep == 0;
585}
586
392static int gmc_v9_0_late_init(void *handle) 587static int gmc_v9_0_late_init(void *handle)
393{ 588{
394 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 589 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -403,6 +598,7 @@ static int gmc_v9_0_late_init(void *handle)
403 */ 598 */
404 unsigned vm_inv_eng[AMDGPU_MAX_VMHUBS] = { 4, 4 }; 599 unsigned vm_inv_eng[AMDGPU_MAX_VMHUBS] = { 4, 4 };
405 unsigned i; 600 unsigned i;
601 int r;
406 602
407 for(i = 0; i < adev->num_rings; ++i) { 603 for(i = 0; i < adev->num_rings; ++i) {
408 struct amdgpu_ring *ring = adev->rings[i]; 604 struct amdgpu_ring *ring = adev->rings[i];
@@ -418,6 +614,16 @@ static int gmc_v9_0_late_init(void *handle)
418 for(i = 0; i < AMDGPU_MAX_VMHUBS; ++i) 614 for(i = 0; i < AMDGPU_MAX_VMHUBS; ++i)
419 BUG_ON(vm_inv_eng[i] > 16); 615 BUG_ON(vm_inv_eng[i] > 16);
420 616
617 r = gmc_v9_0_ecc_available(adev);
618 if (r == 1) {
619 DRM_INFO("ECC is active.\n");
620 } else if (r == 0) {
621 DRM_INFO("ECC is not present.\n");
622 } else {
623 DRM_ERROR("gmc_v9_0_ecc_available() failed. r: %d\n", r);
624 return r;
625 }
626
421 return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); 627 return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
422} 628}
423 629