drivers: edac: Add NXP EDAC driver
Add edac driver for NXP's ERM and EIM peripherals. It can inject ECC error to specific channel within EIM and then report the error address, syndrome and count within ERM. Signed-off-by: Yves Wang <zhengjia.wang@nxp.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# Copyright (c) 2020 Intel Corporation
|
||||
# Copyright 2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
@@ -7,5 +8,6 @@ zephyr_library_sources_ifdef(CONFIG_EDAC_SHELL shell.c)
|
||||
|
||||
# zephyr-keep-sorted-start
|
||||
zephyr_library_sources_ifdef(CONFIG_EDAC_IBECC edac_ibecc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EDAC_NXP_ERM edac_mcux_erm.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EDAC_SYNOPSYS edac_synopsys.c)
|
||||
# zephyr-keep-sorted-stop
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (c) 2020 Intel Corp.
|
||||
# Copyright 2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# EDAC configuration options
|
||||
@@ -35,6 +36,7 @@ config EDAC_SYNOPSYS
|
||||
help
|
||||
Enable the Synopsys DDR controller EDAC driver.
|
||||
|
||||
source "drivers/edac/Kconfig.mcux_erm"
|
||||
module = EDAC
|
||||
module-str = edac
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
38
drivers/edac/Kconfig.mcux_erm
Normal file
38
drivers/edac/Kconfig.mcux_erm
Normal file
@@ -0,0 +1,38 @@
|
||||
# Copyright 2025 NXP
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config EDAC_NXP_ERM
|
||||
bool "NXP ERM driver"
|
||||
default y
|
||||
depends on DT_HAS_NXP_ERM_ENABLED
|
||||
help
|
||||
Enable the NXP Error Reporting Module driver.
|
||||
|
||||
config EDAC_NXP_ERM_DEFAULT_CHANNEL
|
||||
int "NXP ERM default channel"
|
||||
default 0
|
||||
depends on EDAC_NXP_ERM
|
||||
help
|
||||
Set the NXP Error Reporting Module default channel.
|
||||
|
||||
config EDAC_NXP_EIM
|
||||
bool "NXP EIM driver"
|
||||
default y
|
||||
depends on DT_HAS_NXP_EIM_ENABLED
|
||||
help
|
||||
Enable the NXP Error Injection Module driver.
|
||||
|
||||
config EDAC_NXP_ERROR_INJECT
|
||||
bool
|
||||
default y if EDAC_ERROR_INJECT && EDAC_NXP_EIM
|
||||
help
|
||||
This is a helper configuration that is enabled when both
|
||||
EDAC_ERROR_INJECT and EDAC_NXP_EIM are enabled.
|
||||
|
||||
config EDAC_NXP_ERM_VARY_WITH_EIM_CHANNEL
|
||||
bool "Update EIM channel based on EIM channel"
|
||||
default y
|
||||
depends on EDAC_NXP_EIM && EDAC_NXP_ERM
|
||||
help
|
||||
Allow ERM channel to dynamically adapt based on the selected EIM channel.
|
||||
355
drivers/edac/edac_mcux_erm.c
Normal file
355
drivers/edac/edac_mcux_erm.c
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Copyright 2025 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/edac.h>
|
||||
#include <zephyr/drivers/edac/edac_mcux_erm.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <fsl_erm.h>
|
||||
|
||||
LOG_MODULE_REGISTER(edac_mcux_erm, CONFIG_EDAC_LOG_LEVEL);
|
||||
|
||||
#ifdef EDAC_NXP_ERROR_INJECT
|
||||
#include <fsl_eim.h>
|
||||
|
||||
#define EDAC_NXP_SINGLE_BIT_ERROR_MASK 0x1
|
||||
#define EDAC_NXP_DOUBLE_BIT_ERROR_MASK 0x3
|
||||
|
||||
#define EIM_CHANNEL_ENABLE(CHANNEL_ID) (0x80000000U >> (CHANNEL_ID))
|
||||
|
||||
struct edac_nxp_eim_channel {
|
||||
uint32_t start_address;
|
||||
uint32_t size;
|
||||
uint32_t ecc_enable;
|
||||
uint8_t channel_id;
|
||||
uint8_t erm_channel_id;
|
||||
};
|
||||
#endif /* CONFIG_EDAC_ERROR_INJECT */
|
||||
|
||||
struct edac_nxp_config {
|
||||
ERM_Type *erm_base;
|
||||
#ifdef EDAC_NXP_ERROR_INJECT
|
||||
EIM_Type *eim_base;
|
||||
const struct edac_nxp_eim_channel *eim_channels;
|
||||
uint8_t eim_channel_num;
|
||||
#endif /* CONFIG_EDAC_ERROR_INJECT */
|
||||
const int *erm_channels;
|
||||
uint8_t erm_channel_num;
|
||||
void (*irq_config_func)(const struct device *dev);
|
||||
};
|
||||
|
||||
struct edac_nxp_data {
|
||||
edac_notify_callback_f cb;
|
||||
#ifdef EDAC_NXP_ERROR_INJECT
|
||||
uint32_t eim_channel;
|
||||
uint32_t eim_channel_word;
|
||||
uint32_t inject_error_type;
|
||||
#endif /* CONFIG_EDAC_ERROR_INJECT */
|
||||
uint32_t erm_channel;
|
||||
};
|
||||
|
||||
__weak void enable_ecc(uint32_t mask)
|
||||
{
|
||||
ARG_UNUSED(mask);
|
||||
}
|
||||
|
||||
static bool check_erm_channel(const int *erm_channels, size_t size, uint32_t value)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (erm_channels[i] == value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef EDAC_NXP_ERROR_INJECT
|
||||
static bool check_eim_channel(const struct edac_nxp_eim_channel *eim_channels, size_t size,
|
||||
uint32_t value)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (eim_channels[i].channel_id == value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline const struct edac_nxp_eim_channel *
|
||||
get_eim_channel(const struct edac_nxp_eim_channel *eim_channels, size_t size, uint32_t value)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (eim_channels[i].channel_id == value) {
|
||||
return &eim_channels[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int inject_set_param1(const struct device *dev, uint64_t channel)
|
||||
{
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
const struct edac_nxp_config *config = dev->config;
|
||||
|
||||
if (!check_eim_channel(config->eim_channels, config->eim_channel_num, (uint32_t)channel)) {
|
||||
LOG_ERR("Invalid EIM channel %llx", channel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->eim_channel = (uint32_t)(channel & 0xFFFFFFFFU);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inject_get_param1(const struct device *dev, uint64_t *value)
|
||||
{
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
|
||||
*value = (uint64_t)data->eim_channel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inject_set_param2(const struct device *dev, uint64_t word)
|
||||
{
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
|
||||
data->eim_channel_word = (uint32_t)(word & 0xFU);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inject_get_param2(const struct device *dev, uint64_t *word)
|
||||
{
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
|
||||
*word = (uint64_t)data->eim_channel_word;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inject_set_error_type(const struct device *dev, uint32_t inject_error_type)
|
||||
{
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
|
||||
data->inject_error_type = inject_error_type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inject_get_error_type(const struct device *dev, uint32_t *inject_error_type)
|
||||
{
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
|
||||
*inject_error_type = data->inject_error_type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inject_error_trigger(const struct device *dev)
|
||||
{
|
||||
const struct edac_nxp_config *config = dev->config;
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
uint32_t inject_data;
|
||||
const struct edac_nxp_eim_channel *eim_channel_data =
|
||||
get_eim_channel(config->eim_channels, config->eim_channel_num, data->eim_channel);
|
||||
|
||||
switch (data->inject_error_type) {
|
||||
case EDAC_ERROR_TYPE_DRAM_COR:
|
||||
inject_data = EDAC_NXP_SINGLE_BIT_ERROR_MASK;
|
||||
break;
|
||||
case EDAC_ERROR_TYPE_DRAM_UC:
|
||||
inject_data = EDAC_NXP_DOUBLE_BIT_ERROR_MASK;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("No error type found.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_EDAC_NXP_ERM_VARY_WITH_EIM_CHANNEL) && CONFIG_EDAC_NXP_ERM_VARY_WITH_EIM_CHANNEL
|
||||
if (!check_erm_channel(config->erm_channels, config->erm_channel_num,
|
||||
eim_channel_data->erm_channel_id)) {
|
||||
LOG_WRN("Invalid ERM channel %d", eim_channel_data->erm_channel_id);
|
||||
} else {
|
||||
LOG_DBG("Setting ERM channel %d for error reporting",
|
||||
eim_channel_data->erm_channel_id);
|
||||
data->erm_channel = eim_channel_data->erm_channel_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (eim_channel_data->ecc_enable) {
|
||||
enable_ecc(eim_channel_data->ecc_enable);
|
||||
}
|
||||
|
||||
if (data->eim_channel_word == 0U) {
|
||||
EIM_InjectCheckBitError(config->eim_base, data->eim_channel, inject_data);
|
||||
} else {
|
||||
EIM_InjectDataWordBitError(config->eim_base, data->eim_channel, inject_data,
|
||||
data->eim_channel_word);
|
||||
}
|
||||
|
||||
EIM_EnableErrorInjectionChannels(config->eim_base, EIM_CHANNEL_ENABLE(data->eim_channel));
|
||||
ERM_EnableInterrupts(config->erm_base, data->erm_channel, kERM_AllInterruptsEnable);
|
||||
LOG_INF("EIM channel %d, range 0x%x - 0x%x ECC error injection triggered.",
|
||||
data->eim_channel, eim_channel_data->start_address,
|
||||
eim_channel_data->start_address + eim_channel_data->size - 1);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_EDAC_ERROR_INJECT */
|
||||
|
||||
static int errors_cor_get(const struct device *dev)
|
||||
{
|
||||
#if defined(ERM_CORR_ERR_CNT0_COUNT_MASK) && ERM_CORR_ERR_CNT0_COUNT_MASK
|
||||
const struct edac_nxp_config *config = dev->config;
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
|
||||
return (int)ERM_GetErrorCount(config->erm_base, data->erm_channel);
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int notify_callback_set(const struct device *dev, edac_notify_callback_f cb)
|
||||
{
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
data->cb = cb;
|
||||
irq_unlock(key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void edac_nxp_isr(const struct device *dev)
|
||||
{
|
||||
const struct edac_nxp_config *config = dev->config;
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
uint32_t status = ERM_GetInterruptStatus(config->erm_base, data->erm_channel);
|
||||
#if defined(ERM_SYN0_SYNDROME_MASK) && ERM_SYN0_SYNDROME_MASK
|
||||
uint32_t syndrome = ERM_GetSyndrome(config->erm_base, data->erm_channel);
|
||||
#else
|
||||
uint32_t syndrome = -ENOSYS;
|
||||
#endif
|
||||
struct edac_nxp_callback_data cb_data = {
|
||||
.corr_err_count = errors_cor_get(dev),
|
||||
.err_syndrome = syndrome,
|
||||
.err_addr = ERM_GetMemoryErrorAddr(config->erm_base, data->erm_channel),
|
||||
.err_status = status,
|
||||
};
|
||||
|
||||
if (kERM_SingleBitCorrectionIntFlag == (status & kERM_SingleBitCorrectionIntFlag)) {
|
||||
LOG_ERR("ERM channel %d correctable ECC error detected, address/offset 0x%x, "
|
||||
"syndrome "
|
||||
"0x%02x, correctable ECC count %d",
|
||||
data->erm_channel, cb_data.err_addr, cb_data.err_syndrome,
|
||||
cb_data.corr_err_count);
|
||||
ERM_ClearInterruptStatus(config->erm_base, data->erm_channel,
|
||||
kERM_SingleBitCorrectionIntFlag);
|
||||
} else if (kERM_NonCorrectableErrorIntFlag == (status & kERM_NonCorrectableErrorIntFlag)) {
|
||||
LOG_ERR("ERM channel %d uncorrectable ECC error detected, address/offset 0x%x",
|
||||
data->erm_channel, cb_data.err_addr);
|
||||
ERM_ClearInterruptStatus(config->erm_base, data->erm_channel,
|
||||
kERM_NonCorrectableErrorIntFlag);
|
||||
} else {
|
||||
LOG_ERR("ERM unknown ECC error status detected, it may caused by unaligned ERM "
|
||||
"channel");
|
||||
ERM_ClearInterruptStatus(config->erm_base, data->erm_channel, kERM_AllIntsFlag);
|
||||
}
|
||||
if (data->cb) {
|
||||
data->cb(dev, &cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
static DEVICE_API(edac, edac_nxp_api) = {
|
||||
#ifdef EDAC_NXP_ERROR_INJECT
|
||||
/* Error Injection functions */
|
||||
.inject_set_param1 = inject_set_param1,
|
||||
.inject_get_param1 = inject_get_param1,
|
||||
.inject_set_param2 = inject_set_param2,
|
||||
.inject_get_param2 = inject_get_param2,
|
||||
.inject_set_error_type = inject_set_error_type,
|
||||
.inject_get_error_type = inject_get_error_type,
|
||||
.inject_error_trigger = inject_error_trigger,
|
||||
#endif /* CONFIG_EDAC_ERROR_INJECT */
|
||||
|
||||
/* Get error stats */
|
||||
.errors_cor_get = errors_cor_get,
|
||||
|
||||
/* Notification callback set */
|
||||
.notify_cb_set = notify_callback_set,
|
||||
};
|
||||
|
||||
static int edac_nxp_init(const struct device *dev)
|
||||
{
|
||||
const struct edac_nxp_config *config = dev->config;
|
||||
struct edac_nxp_data *data = dev->data;
|
||||
|
||||
#ifdef EDAC_NXP_ERROR_INJECT
|
||||
EIM_Init(config->eim_base);
|
||||
EIM_EnableGlobalErrorInjection(config->eim_base, true);
|
||||
data->eim_channel_word = 1U;
|
||||
LOG_INF("EIM driver initialized");
|
||||
#endif /* CONFIG_EDAC_ERROR_INJECT */
|
||||
|
||||
ERM_Init(config->erm_base);
|
||||
if (!check_erm_channel(config->erm_channels, config->erm_channel_num,
|
||||
CONFIG_EDAC_NXP_ERM_DEFAULT_CHANNEL)) {
|
||||
LOG_ERR("Invalid ERM channel %d", CONFIG_EDAC_NXP_ERM_DEFAULT_CHANNEL);
|
||||
return -EINVAL;
|
||||
}
|
||||
data->erm_channel = CONFIG_EDAC_NXP_ERM_DEFAULT_CHANNEL;
|
||||
|
||||
/* Clear any latched status before enabling interrupts */
|
||||
ERM_ClearInterruptStatus(config->erm_base, data->erm_channel, kERM_AllIntsFlag);
|
||||
config->irq_config_func(dev);
|
||||
ERM_EnableInterrupts(config->erm_base, data->erm_channel, kERM_AllInterruptsEnable);
|
||||
LOG_INF("ERM driver initialized");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DT_DRV_COMPAT nxp_erm
|
||||
|
||||
#ifdef EDAC_NXP_ERROR_INJECT
|
||||
/* Initializes an element of the eim channel device pointer array */
|
||||
#define NXP_EIM_CHANNEL_DEV_ARRAY_INIT(node) \
|
||||
{ \
|
||||
.channel_id = DT_PROP(node, channel_id), \
|
||||
.erm_channel_id = DT_PROP_OR(node, erm_channel_id, 0xFFU), \
|
||||
.start_address = DT_PROP(node, start_address), \
|
||||
.ecc_enable = DT_PROP_OR(node, ecc_enable, 0), \
|
||||
.size = DT_PROP(node, size), \
|
||||
},
|
||||
const struct edac_nxp_eim_channel edac_nxp_eim_0_channels[] = {
|
||||
DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(eim0), NXP_EIM_CHANNEL_DEV_ARRAY_INIT)};
|
||||
|
||||
#define EDAC_NXP_EIM_CONFIG_FIELDS \
|
||||
.eim_base = (EIM_Type *)DT_REG_ADDR(DT_NODELABEL(eim0)), \
|
||||
.eim_channels = edac_nxp_eim_0_channels, \
|
||||
.eim_channel_num = ARRAY_SIZE(edac_nxp_eim_0_channels),
|
||||
#else
|
||||
#define EDAC_NXP_EIM_CHANNELS
|
||||
#define EDAC_NXP_EIM_CONFIG_FIELDS
|
||||
#endif
|
||||
|
||||
static const int edac_nxp_erm_0_channels[] = DT_INST_PROP(0, channels);
|
||||
|
||||
static void edac_nxp_irq_0(const struct device *dev)
|
||||
{
|
||||
IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 0, irq), DT_INST_IRQ_BY_IDX(0, 0, priority), edac_nxp_isr,
|
||||
DEVICE_DT_INST_GET(0), 0);
|
||||
irq_enable(DT_INST_IRQ_BY_IDX(0, 0, irq));
|
||||
IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, 1, irq), DT_INST_IRQ_BY_IDX(0, 1, priority), edac_nxp_isr,
|
||||
DEVICE_DT_INST_GET(0), 0);
|
||||
irq_enable(DT_INST_IRQ_BY_IDX(0, 1, irq));
|
||||
}
|
||||
|
||||
static const struct edac_nxp_config edac_nxp_config_0 = {
|
||||
.erm_base = (ERM_Type *)DT_INST_REG_ADDR(0),
|
||||
EDAC_NXP_EIM_CONFIG_FIELDS.erm_channels = edac_nxp_erm_0_channels,
|
||||
.erm_channel_num = ARRAY_SIZE(edac_nxp_erm_0_channels),
|
||||
.irq_config_func = edac_nxp_irq_0,
|
||||
};
|
||||
|
||||
static struct edac_nxp_data edac_nxp_data_0;
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, &edac_nxp_init, NULL, &edac_nxp_data_0, &edac_nxp_config_0, POST_KERNEL,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &edac_nxp_api);
|
||||
32
dts/bindings/edac/nxp,eim.yaml
Normal file
32
dts/bindings/edac/nxp,eim.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright 2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: NXP Error Injection Module
|
||||
|
||||
compatible: "nxp,eim"
|
||||
|
||||
include: [reset-device.yaml, base.yaml]
|
||||
|
||||
child-binding:
|
||||
properties:
|
||||
channel-id:
|
||||
required: true
|
||||
type: int
|
||||
|
||||
erm-channel-id:
|
||||
type: int
|
||||
description: erm channel id for current eim channel.
|
||||
|
||||
size:
|
||||
required: true
|
||||
type: int
|
||||
description: size of the memory channel.
|
||||
|
||||
start-address:
|
||||
required: true
|
||||
type: int
|
||||
description: start address of the memory channel.
|
||||
|
||||
ecc-enable:
|
||||
type: int
|
||||
description: ecc enable magic number for the memory channel.
|
||||
16
dts/bindings/edac/nxp,erm.yaml
Normal file
16
dts/bindings/edac/nxp,erm.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright 2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: NXP Error Reporting Module
|
||||
|
||||
compatible: "nxp,erm"
|
||||
|
||||
include: [reset-device.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
interrupts:
|
||||
required: true
|
||||
|
||||
channels:
|
||||
type: array
|
||||
required: true
|
||||
37
include/zephyr/drivers/edac/edac_mcux_erm.h
Normal file
37
include/zephyr/drivers/edac/edac_mcux_erm.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2025 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Header file for extended EDAC API of NXP Error Reporting Module (ERM)
|
||||
* @ingroup edac_interface_ext
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_EDAC_NXP_ERM_H_
|
||||
#define ZEPHYR_DRIVERS_EDAC_NXP_ERM_H_
|
||||
|
||||
/**
|
||||
* @brief NXP ERM EDAC driver
|
||||
* @defgroup edac_nxp_erm_interface NXP ERM EDAC
|
||||
* @ingroup edac_interface_ext
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Callback data provided to function passed to @ref edac_notify_callback_set */
|
||||
struct edac_nxp_callback_data {
|
||||
/** Number of corrected errors */
|
||||
uint8_t corr_err_count;
|
||||
/** Syndrome ECC bits for last single bit ECC event */
|
||||
uint8_t err_syndrome;
|
||||
/** Address of last ECC event */
|
||||
uint32_t err_addr;
|
||||
/** Type of last ECC event */
|
||||
uint32_t err_status;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_EDAC_NXP_ERM_H_ */
|
||||
@@ -64,6 +64,8 @@ set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V3 CONFIG_MCUX_COMPONENT_driver.dma
|
||||
set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V4 CONFIG_MCUX_COMPONENT_driver.edma4)
|
||||
set_variable_ifdef(CONFIG_DMA_NXP_EDMA CONFIG_MCUX_COMPONENT_driver.edma_rev2)
|
||||
set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V5 CONFIG_MCUX_COMPONENT_driver.edma4)
|
||||
set_variable_ifdef(CONFIG_EDAC_NXP_EIM CONFIG_MCUX_COMPONENT_driver.eim)
|
||||
set_variable_ifdef(CONFIG_EDAC_NXP_ERM CONFIG_MCUX_COMPONENT_driver.erm)
|
||||
set_variable_ifdef(CONFIG_ENTROPY_MCUX_RNGA CONFIG_MCUX_COMPONENT_driver.rnga)
|
||||
set_variable_ifdef(CONFIG_ENTROPY_MCUX_TRNG CONFIG_MCUX_COMPONENT_driver.trng)
|
||||
set_variable_ifdef(CONFIG_ENTROPY_MCUX_CAAM CONFIG_MCUX_COMPONENT_driver.caam)
|
||||
|
||||
@@ -8,3 +8,4 @@ io_rw_32
|
||||
Pwm
|
||||
FILE
|
||||
NRF_GPIO_Type
|
||||
EIM_Type
|
||||
|
||||
Reference in New Issue
Block a user