From: YiPeng Chai <[email protected]>

Ras mp1 introduces common interfaces to manage mp1 data
obtained from different ASICs.

v2:
  Add mutex to ensure complete data transactions with MP1.

Signed-off-by: YiPeng Chai <[email protected]>
Reviewed-by: Hawking Zhang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/ras/core/ras_mp1.c | 122 ++++++++++++++++++++++++-
 drivers/gpu/drm/amd/ras/core/ras_mp1.h |  44 +++++++++
 2 files changed, 161 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/core/ras_mp1.c 
b/drivers/gpu/drm/amd/ras/core/ras_mp1.c
index 12c9e20098c43..eccd6f16c35a7 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_mp1.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_mp1.c
@@ -50,23 +50,127 @@ int ras_mp1_get_bank_count(struct ras_core_context 
*ras_core,
                            enum ras_err_type type, u32 *count)
 {
        struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
 
        if (!mp1->ip_func || !mp1->ip_func->get_valid_bank_count)
                return 0;
 
-       return mp1->ip_func->get_valid_bank_count(ras_core, type, count);
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->get_valid_bank_count(ras_core, type, count);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
 }
 
 int ras_mp1_dump_bank(struct ras_core_context *ras_core,
                u32 type, u32 idx, u64 *regs, u32 regs_sz)
 {
        struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
 
        if (!mp1->ip_func || !mp1->ip_func->dump_valid_bank)
                return 0;
 
-       return mp1->ip_func->dump_valid_bank(ras_core,
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->dump_valid_bank(ras_core,
                                type, idx, regs, regs_sz);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
+}
+
+int ras_mp1_get_table_version(struct ras_core_context *ras_core,
+               u32 *table_version)
+{
+       struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
+
+       if (!mp1->ip_func || !mp1->ip_func->get_table_version)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->get_table_version(ras_core, table_version);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
+}
+
+bool ras_mp1_rma_detected(struct ras_core_context *ras_core)
+{
+       struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
+
+       if (!mp1->ip_func || !mp1->ip_func->rma_detected)
+               return false;
+
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->rma_detected(ras_core);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
+}
+
+int ras_mp1_set_timestamp(struct ras_core_context *ras_core,
+               u32 timestamp)
+{
+       struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
+
+       if (!mp1->ip_func || !mp1->ip_func->set_timestamp)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->set_timestamp(ras_core, timestamp);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
+}
+
+int ras_mp1_reset_ras_table(struct ras_core_context *ras_core,
+               u32 *result)
+{
+       struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
+
+       if (!result || !mp1->ip_func || !mp1->ip_func->reset_ras_table)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->reset_ras_table(ras_core, result);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
+}
+
+int ras_mp1_get_record_count(struct ras_core_context *ras_core, u32 *count)
+{
+       struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
+
+       if (!count || !mp1->ip_func || !mp1->ip_func->get_record_count)
+               return 0;
+
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->get_record_count(ras_core, count);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
+}
+
+int ras_mp1_get_record(struct ras_core_context *ras_core,
+               u32 idx, struct eeprom_err_record *rec)
+{
+       struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+       int ret;
+
+       if (!rec || !mp1->ip_func || !mp1->ip_func->get_record)
+               return -EOPNOTSUPP;
+
+       mutex_lock(&mp1->op_mutex);
+       ret = mp1->ip_func->get_record(ras_core, idx, rec);
+       mutex_unlock(&mp1->op_mutex);
+
+       return ret;
 }
 
 int ras_mp1_set_debug_mode(struct ras_core_context *ras_core, bool enable)
@@ -86,21 +190,29 @@ int ras_mp1_hw_init(struct ras_core_context *ras_core)
 
        mp1->mp1_ip_version = ras_core->config->mp1_ip_version;
 
-       if (ras_core->config->mp1_cfg.mp1_sys_fn)
+       if (ras_core->config && ras_core->config->mp1_cfg.mp1_sys_fn)
                mp1->sys_func = ras_core->config->mp1_cfg.mp1_sys_fn;
 
        mp1->ip_func = ras_mp1_get_ip_funcs(ras_core, mp1->mp1_ip_version);
        if (!mp1->ip_func)
                return -EINVAL;
 
+       mutex_init(&mp1->op_mutex);
+
        ret = ras_mp1_set_debug_mode(ras_core, false);
-       if (ret)
-               return -EINVAL;
+       if (ret) {
+               mutex_destroy(&mp1->op_mutex);
+               return ret;
+       }
 
        return ret;
 }
 
 int ras_mp1_hw_fini(struct ras_core_context *ras_core)
 {
+       struct ras_mp1 *mp1 = &ras_core->ras_mp1;
+
+       mutex_destroy(&mp1->op_mutex);
+
        return 0;
 }
diff --git a/drivers/gpu/drm/amd/ras/core/ras_mp1.h 
b/drivers/gpu/drm/amd/ras/core/ras_mp1.h
index 17499e1c9c54b..a00eb8117885b 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_mp1.h
+++ b/drivers/gpu/drm/amd/ras/core/ras_mp1.h
@@ -25,6 +25,26 @@
 #define __RAS_MP1_H__
 #include "ras.h"
 
+struct eeprom_err_record {
+       u32 timestamp;
+
+       union {
+               struct {
+                       u32 mca_addr_low;
+                       u32 mca_addr_high;
+               };
+               u64 mca_addr;
+       };
+
+       union {
+               struct {
+                       u32 ipid_low;
+                       u32 ipid_high;
+               };
+               u64 ipid;
+       };
+};
+
 enum ras_err_type;
 struct ras_mp1_ip_func {
        int (*get_valid_bank_count)(struct ras_core_context *ras_core,
@@ -32,12 +52,26 @@ struct ras_mp1_ip_func {
        int (*dump_valid_bank)(struct ras_core_context *ras_core,
                enum ras_err_type type, u32 idx, u64 *regs, u32 regs_sz);
        int (*set_debug_mode)(struct ras_core_context *ras_core, bool enable);
+
+       /* The following is used for firmware management of EEPROM */
+       int (*get_table_version)(struct ras_core_context *ras_core,
+                       u32 *table_version);
+       bool (*rma_detected)(struct ras_core_context *ras_core);
+       int (*set_timestamp)(struct ras_core_context *ras_core,
+                       u32 timestamp);
+       int (*reset_ras_table)(struct ras_core_context *ras_core,
+                       u32 *result);
+       int (*get_record_count)(struct ras_core_context *ras_core,
+                       u32 *count);
+       int (*get_record)(struct ras_core_context *ras_core,
+                       u32 idx, struct eeprom_err_record *rec);
 };
 
 struct ras_mp1 {
        uint32_t mp1_ip_version;
        const struct ras_mp1_ip_func *ip_func;
        const struct ras_mp1_sys_func *sys_func;
+       struct mutex op_mutex;
 };
 
 int ras_mp1_hw_init(struct ras_core_context *ras_core);
@@ -50,4 +84,14 @@ int ras_mp1_dump_bank(struct ras_core_context *ras_core,
                u32 ecc_type, u32 idx, u64 *regs, u32 regs_sz);
 
 int ras_mp1_set_debug_mode(struct ras_core_context *ras_core, bool enable);
+int ras_mp1_get_table_version(struct ras_core_context *ras_core,
+               u32 *table_version);
+bool ras_mp1_rma_detected(struct ras_core_context *ras_core);
+int ras_mp1_set_timestamp(struct ras_core_context *ras_core,
+               u32 timestamp);
+int ras_mp1_reset_ras_table(struct ras_core_context *ras_core,
+               u32 *result);
+int ras_mp1_get_record_count(struct ras_core_context *ras_core, u32 *count);
+int ras_mp1_get_record(struct ras_core_context *ras_core,
+               u32 idx, struct eeprom_err_record *rec);
 #endif
-- 
2.55.0

Reply via email to