blob: d643209492fca8b54359db1c5b00f489f4f5bf84 [file]
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <autoconf.h>
#include <mode/arm_generic_timer.h>
#include <elfloader.h>
#include <printf.h>
/* The code for enabling SError is from L4T (Linux for Tegra).
* Read the Parker TRM 17.12 and 17.13 for NVIDIA-specific
* SError extensions and the ARI (abstract request interface).
*/
#define SMC_SIP_INVOKE_MCE 0xc2ffff00
#define MCE_SMC_ENUM_MAX 0xff
#define ARI_MCA_GLOBAL_CONFIG 0x12
#define ARI_MCA_WRITE_SERR 0x2
#define NR_SMC_REGS 6
typedef union {
struct {
uint8_t cmd;
uint8_t subidx;
uint8_t idx;
uint8_t inst;
};
struct {
uint32_t low;
uint32_t high;
};
uint64_t data;
} mca_cmd_t;
struct mce_regs {
uint64_t args[NR_SMC_REGS];
};
static __attribute__((noinline)) int send_smc(uint8_t func, struct mce_regs *regs)
{
uint32_t ret = SMC_SIP_INVOKE_MCE | (func & MCE_SMC_ENUM_MAX);
asm volatile(
"mov x0, %x0\n"
"ldp x1, x2, [%1, #16 * 0] \n"
"ldp x3, x4, [%1, #16 * 1] \n"
"ldp x5, x6, [%1, #16 * 2] \n"
"isb\n"
"smc #0\n"
"mov %x0, x0\n"
"stp x0, x1, [%1, #16 * 0]\n"
"stp x2, x3, [%1, #16 * 1]\n"
: "+r"(ret)
: "r"(regs)
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8",
"x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17");
return ret;
}
static void tegra_mce_write_uncore_mca(mca_cmd_t cmd, uint64_t data, uint32_t *err)
{
struct mce_regs regs;
regs.args[0] = cmd.data;
regs.args[1] = data;
send_smc(13, &regs);
*err = (uint32_t)regs.args[3];
}
static void enable_serr(void)
{
uint32_t err;
mca_cmd_t cmd;
cmd.data = 0;
cmd.cmd = ARI_MCA_WRITE_SERR;
cmd.idx = ARI_MCA_GLOBAL_CONFIG;
tegra_mce_write_uncore_mca(cmd, 1, &err);
printf("Enabling TX2 SError result %d\n", err);
}
/* Enable SError report for TX2 */
void platform_init(void)
{
enable_serr();
/* Reset the virtual offset for the platform timer to 0 */
reset_cntvoff();
}
#if CONFIG_MAX_NUM_NODES > 1
void non_boot_init(void)
{
/* Reset the virtual offset for the platform timer to 0 */
reset_cntvoff();
}
#endif