191 lines
5.7 KiB
C
191 lines
5.7 KiB
C
/*
|
|
* Copyright (c) 2016, NVIDIA Corporation. All rights reserved.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#ifndef __TEGRA18_EMC_H__
|
|
#define __TEGRA18_EMC_H__
|
|
|
|
/* HW Register offsets */
|
|
|
|
#define EMC_INTSTATUS 0x0
|
|
|
|
#define ECC_ERR_BUF_OVF_INT_MASK 0x1
|
|
#define ECC_ERR_BUF_OVF_INT_SHIFT 12
|
|
|
|
#define ECC_CORR_ERR_INT_MASK 0x1
|
|
#define ECC_CORR_ERR_INT_SHIFT 11
|
|
|
|
#define ECC_UNCORR_ERR_INT_MASK 0x1
|
|
#define ECC_UNCORR_ERR_INT_SHIFT 10
|
|
|
|
#define EMC_INTMASK 0x4
|
|
|
|
#define EMC_NONCRITICAL_INTMASK 0x514
|
|
|
|
#define EMC_CRITICAL_INTMASK 0x510
|
|
|
|
#define EMC_ECC_CONTROL 0xac0
|
|
|
|
#define ERR_BUFFER_MODE_MASK 0x1
|
|
#define ERR_BUFFER_MODE_SHIFT 0
|
|
|
|
#define ERR_BUFFER_RESET_MASK 0x1
|
|
#define ERR_BUFFER_RESET_SHIFT 1
|
|
|
|
#define ERR_BUFFER_LOAD_MASK 0x1
|
|
#define ERR_BUFFER_LOAD_SHIFT 2
|
|
|
|
#define ERR_BUFFER_LIMIT_MASK 0xFF
|
|
#define ERR_BUFFER_LIMIT_SHIFT 8
|
|
|
|
|
|
#define EMC_ECC_STATUS 0xac4
|
|
|
|
#define ERR_BUFFER_CNT_MASK 0xFF
|
|
#define ERR_BUFFER_CNT_SHIFT 16
|
|
|
|
#define ERR_BUFFER_DEPTH_MASK 0xFF
|
|
#define ERR_BUFFER_DEPTH_SHIFT 24
|
|
|
|
|
|
#define EMC_ECC_ERR_REQ 0xad4
|
|
|
|
#define ECC_ERR_CGID_MASK 0xFF
|
|
#define ECC_ERR_CGID_SHIFT 24
|
|
|
|
#define ECC_ERR_SEQ_MASK 0x3
|
|
#define ECC_ERR_SEQ_SHIFT 20
|
|
|
|
#define ECC_ERR_EMC_ID_MASK 0x3
|
|
#define ECC_ERR_EMC_ID_SHIFT 6
|
|
|
|
#define ECC_ERR_DEVICE_MASK 0x1
|
|
#define ECC_ERR_DEVICE_SHIFT 16
|
|
|
|
#define ECC_ERR_SIZE_MASK 0x3
|
|
#define ECC_ERR_SIZE_SHIFT 17
|
|
|
|
#define ECC_ERR_SWAP_MASK 0x1
|
|
#define ECC_ERR_SWAP_SHIFT 19
|
|
|
|
#define ECC_ERR_COL_SP0_MASK 0x7
|
|
#define ECC_ERR_COL_SP0_SHIFT 8
|
|
|
|
#define ECC_ERR_COL_SP1_MASK 0x7
|
|
#define ECC_ERR_COL_SP1_SHIFT 12
|
|
|
|
|
|
#define EMC_ECC_ERR_SP0 0xac8
|
|
#define EMC_ECC_ERR_SP1 0xacc
|
|
|
|
#define ECC_EERR_PAR_MASK 0x3
|
|
#define ECC_EERR_PAR_SHIFT 16
|
|
|
|
#define ECC_DERR_PAR_MASK 0x3
|
|
#define ECC_DERR_PAR_SHIFT 0
|
|
|
|
#define ECC_ERR_POISON_MASK 0x1
|
|
#define ECC_ERR_POISON_SHIFT 3
|
|
|
|
#define ECC_DERR_SYNDROME_MASK 0x3FF
|
|
#define ECC_DERR_SYNDROME_SHIFT 6
|
|
|
|
#define EMC_ECC_ERR_ADDR 0xad0
|
|
|
|
#define ECC_ERR_ROW_MASK 0xFFFF
|
|
#define ECC_ERR_ROW_SHIFT 8
|
|
|
|
#define ECC_ERR_BANK_MASK 0x7
|
|
#define ECC_ERR_BANK_SHIFT 28
|
|
|
|
#define ECC_ERR_GOB_MASK 0x3F
|
|
#define ECC_ERR_GOB_SHIFT 0
|
|
|
|
#define EMC_ECC_CONTROL 0xac0
|
|
|
|
#define MC_MEM_SCRUBBER_ECC_ADDR 0xf18
|
|
|
|
#define MC_MEM_SCRUBBER_ECC_REG_CTRL 0xf20
|
|
|
|
#define SCRUB_ECC_TRIGGER_SHIFT 0
|
|
|
|
#define SCRUB_ECC_PENDING_MASK 0x1
|
|
#define SCRUB_ECC_PENDING_SHIFT 1
|
|
|
|
#define MC_TIMING_CONTROL_DBG 0xf8
|
|
#define MC_EMEM_ARB_CFG 0x90
|
|
#define MC_EMEM_ARB_MISC1 0xdc
|
|
|
|
#define MC_ECC_CONTROL 0x1880
|
|
|
|
#define EMC_MCH_GLOBAL_NONCRITICAL_INTSTATUS 0x474
|
|
#define EMC_MCH_GLOBAL_CRITICAL_INTSTATUS 0x450
|
|
#define EMC_MCH_GLOBAL_INTSTATUS 0x44c
|
|
|
|
#define EMC_BROADCAST_CHANNEL -1
|
|
|
|
/**
|
|
* Read from the EMC.
|
|
*
|
|
* @idx The EMC channel to read from.
|
|
* @reg The offset of the register to read.
|
|
*
|
|
* Read from the specified EMC channel: 0 -> EMC0, 1 -> EMC1, etc. If @idx
|
|
* corresponds to a non-existent channel then 0 is returned.
|
|
*/
|
|
static inline u32 __emc_readl(int idx, u32 reg)
|
|
{
|
|
if (WARN(!emc, "Read before EMC init'ed"))
|
|
return 0;
|
|
|
|
if ((idx != EMC_BROADCAST_CHANNEL && idx < 0) ||
|
|
idx >= MAX_CHANNELS)
|
|
return 0;
|
|
|
|
if (idx == EMC_BROADCAST_CHANNEL)
|
|
return readl(emc + reg);
|
|
else
|
|
return readl(emc_regs[idx] + reg);
|
|
}
|
|
|
|
/**
|
|
* Write to the EMC.
|
|
*
|
|
* @idx The EMC channel to write to.
|
|
* @val Value to write.
|
|
* @reg The offset of the register to write.
|
|
*
|
|
* Write to the specified EMC channel: 0 -> EMC0, 1 -> EMC1, etc. For writes
|
|
* there is a special channel, %EMC_BROADCAST_CHANNEL, which writes to all
|
|
* channels. If @idx corresponds to a non-existent channel then the
|
|
* write is dropped.
|
|
*/
|
|
static inline void __emc_writel(int idx, u32 val, u32 reg)
|
|
{
|
|
if (WARN(!emc, "Write before EMC init'ed"))
|
|
return;
|
|
|
|
if ((idx != EMC_BROADCAST_CHANNEL && idx < 0) ||
|
|
idx >= MAX_CHANNELS)
|
|
return;
|
|
|
|
if (idx == EMC_BROADCAST_CHANNEL)
|
|
writel(val, emc + reg);
|
|
else
|
|
writel(val, emc_regs[idx] + reg);
|
|
}
|
|
|
|
#define emc_readl(reg) __emc_readl(EMC_BROADCAST_CHANNEL, reg)
|
|
#define emc_writel(val, reg) __emc_writel(EMC_BROADCAST_CHANNEL, val, reg)
|
|
|
|
#endif
|