1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <autoconf.h> 8#include <elfloader.h> 9#include <printf.h> 10 11/* The code for enabling SError is from L4T (Linux for Tegra). 12 * Read the Parker TRM 17.12 and 17.13 for NVIDIA-specific 13 * SError extensions and the ARI (abstract request interface). 14 */ 15 16 17#define SMC_SIP_INVOKE_MCE 0xc2ffff00 18#define MCE_SMC_ENUM_MAX 0xff 19#define ARI_MCA_GLOBAL_CONFIG 0x12 20#define ARI_MCA_WRITE_SERR 0x2 21#define NR_SMC_REGS 6 22 23typedef union { 24 struct { 25 uint8_t cmd; 26 uint8_t subidx; 27 uint8_t idx; 28 uint8_t inst; 29 }; 30 struct { 31 uint32_t low; 32 uint32_t high; 33 }; 34 uint64_t data; 35} mca_cmd_t; 36 37struct mce_regs { 38 uint64_t args[NR_SMC_REGS]; 39}; 40 41static __attribute__((noinline)) int send_smc(uint8_t func, struct mce_regs *regs) 42{ 43 uint32_t ret = SMC_SIP_INVOKE_MCE | (func & MCE_SMC_ENUM_MAX); 44 asm volatile( 45 "mov x0, %x0\n" 46 "ldp x1, x2, [%1, #16 * 0] \n" 47 "ldp x3, x4, [%1, #16 * 1] \n" 48 "ldp x5, x6, [%1, #16 * 2] \n" 49 "isb\n" 50 "smc #0\n" 51 "mov %x0, x0\n" 52 "stp x0, x1, [%1, #16 * 0]\n" 53 "stp x2, x3, [%1, #16 * 1]\n" 54 : "+r"(ret) 55 : "r"(regs) 56 : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", 57 "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); 58 return ret; 59} 60 61 62static void tegra_mce_write_uncore_mca(mca_cmd_t cmd, uint64_t data, uint32_t *err) 63{ 64 struct mce_regs regs; 65 regs.args[0] = cmd.data; 66 regs.args[1] = data; 67 send_smc(13, ®s); 68 *err = (uint32_t)regs.args[3]; 69} 70 71static void enable_serr(void) 72{ 73 uint32_t err; 74 mca_cmd_t cmd; 75 cmd.data = 0; 76 cmd.cmd = ARI_MCA_WRITE_SERR; 77 cmd.idx = ARI_MCA_GLOBAL_CONFIG; 78 tegra_mce_write_uncore_mca(cmd, 1, &err); 79 printf("Enabling TX2 SError result %d\n", err); 80} 81 82/* Enable SError report for TX2 */ 83void platform_init(void) 84{ 85 enable_serr(); 86} 87 88