Loading Documentation/devicetree/bindings/platform/msm/ipa.txt +4 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,10 @@ memory allocation over a PCIe bridge registers, collected upon crash, reside. - qcom,ipa-endp-delay-wa: Boolean context flag to indicate end point delay work around supported or not. - qcom,secure-debug-check-action: Drives secure memory debug check. Three values allowed: 0 (use scm call), 1 (override scm call as though it returned true), and 2 (override scm call as though it returned false) IPA pipe sub nodes (A2 static pipes configurations): Loading arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ qcom,register-collection-on-crash; qcom,testbus-collection-on-crash; qcom,non-tn-collection-on-crash; qcom,secure-debug-check-action = <0>; }; qcom,ipa_fws { Loading drivers/platform/msm/ipa/ipa_v3/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -16,4 +16,6 @@ obj-$(CONFIG_IPA_ETH) += ethernet/ ipat-$(CONFIG_IPA3_REGDUMP) += dump/ipa_reg_dump.o ccflags-$(CONFIG_IPA3_REGDUMP) += -Idrivers/platform/msm/ipa/ipa_v3/dump ccflags-$(CONFIG_IPA3_REGDUMP_SM8150) += -Idrivers/platform/msm/ipa/ipa_v3/dump/sm8150 drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c +119 −35 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ * GNU General Public License for more details. */ #include "ipa_reg_dump.h" #include "ipa_access_control.h" /* Total size required for test bus */ #define IPA_MEM_OVERLAY_SIZE 0x66000 Loading Loading @@ -338,13 +339,13 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { ipa_dst_rsrc_grp_23_rsrc_type_n), /* Source Resource Group Count Registers */ IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_CNT_GRP (IPA_SRC_RSRC_GRP_0123_RSRC_TYPE_CNT_n, IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_CNT_GRP( IPA_SRC_RSRC_GRP_0123_RSRC_TYPE_CNT_n, ipa_src_rsrc_grp_0123_rsrc_type_cnt_n), /* Destination Resource Group Count Registers */ IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_CNT_GRP (IPA_DST_RSRC_GRP_0123_RSRC_TYPE_CNT_n, IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_CNT_GRP( IPA_DST_RSRC_GRP_0123_RSRC_TYPE_CNT_n, ipa_dst_rsrc_grp_0123_rsrc_type_cnt_n), /* Loading @@ -360,6 +361,9 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { GEN_SRC_DST_ADDR_MAP(GSI_REE_CFG, gsi.gen, gsi_ree_cfg), IPA_REG_SAVE_GSI_VER( IPA_GSI_TOP_GSI_INST_RAM_n, ipa_gsi_top_gsi_inst_ram_n), /* GSI Debug Registers */ GEN_SRC_DST_ADDR_MAP(IPA_GSI_TOP_GSI_DEBUG_BUSY_REG, Loading Loading @@ -651,6 +655,73 @@ static void ipa_hal_save_regs_ipa_cmdq(void); static void ipa_hal_save_regs_rsrc_db(void); static void ipa_reg_save_anomaly_check(void); static struct reg_access_funcs_s *get_access_funcs(u32 addr) { u32 i, asub = ipa3_ctx->sd_state; for (i = 0; i < ARRAY_SIZE(mem_access_map); i++) { if (addr >= mem_access_map[i].addr_range_begin && addr <= mem_access_map[i].addr_range_end) { return mem_access_map[i].access[asub]; } } IPAERR("Unknown register offset(0x%08X). Using dflt access methods\n", addr); return &io_matrix[AA_COMBO]; } static u32 in_dword( u32 addr) { struct reg_access_funcs_s *io = get_access_funcs(addr); return io->read(ipa3_ctx->reg_collection_base + addr); } static u32 in_dword_masked( u32 addr, u32 mask) { struct reg_access_funcs_s *io = get_access_funcs(addr); u32 val; val = io->read(ipa3_ctx->reg_collection_base + addr); if (io->read == act_read) return val & mask; return val; } static void out_dword( u32 addr, u32 val) { struct reg_access_funcs_s *io = get_access_funcs(addr); io->write(ipa3_ctx->reg_collection_base + addr, val); } /* * FUNCTION: ipa_save_gsi_ver * * Saves the gsi version * * @return * None */ void ipa_save_gsi_ver(void) { if (!ipa3_ctx->do_register_collection_on_crash) return; ipa_reg_save.gsi.fw_ver = IPA_READ_1xVECTOR_REG(IPA_GSI_TOP_GSI_INST_RAM_n, 0) & 0x0000FFFF; } /* * FUNCTION: ipa_save_registers * Loading @@ -669,7 +740,7 @@ void ipa_save_registers(void) union ipa_hwio_def_ipa_rsrc_mngr_db_rsrc_read_u ipa_rsrc_mngr_db_rsrc_read; if (ipa3_ctx->do_register_collection_on_crash == false) if (!ipa3_ctx->do_register_collection_on_crash) return; IPAERR("Commencing\n"); Loading Loading @@ -831,36 +902,49 @@ void ipa_save_registers(void) * true, via dtsi, and the collection will be done. */ if (ipa3_ctx->do_non_tn_collection_on_crash == true) { /* Copy Pkt context directly from IPA_CTX_ID register space */ u32 ofst = GEN_2xVECTOR_REG_OFST(IPA_CTX_ID_m_CTX_NUM_n, 0, 0); struct reg_access_funcs_s *io = get_access_funcs(ofst); /* * If the memory is accessible, copy pkt context directly from * IPA_CTX_ID register space */ if (io->read == act_read) { memcpy((void *)ipa_reg_save.pkt_ctntx, (void *)((u8 *) ipa3_ctx->reg_collection_base + GEN_2xVECTOR_REG_OFST( IPA_CTX_ID_m_CTX_NUM_n, 0, 0)), (const void *) (ipa3_ctx->reg_collection_base + ofst), sizeof(ipa_reg_save.pkt_ctntx)); ipa_rsrc_mngr_db_cfg.value = IPA_READ_SCALER_REG(IPA_RSRC_MNGR_DB_CFG); ipa_rsrc_mngr_db_cfg.def.rsrc_type_sel = 0; IPA_WRITE_SCALER_REG(IPA_RSRC_MNGR_DB_CFG, IPA_WRITE_SCALER_REG( IPA_RSRC_MNGR_DB_CFG, ipa_rsrc_mngr_db_cfg.value); for (i = 0; i < IPA_HW_PKT_CTNTX_MAX; i++) { ipa_rsrc_mngr_db_cfg.def.rsrc_id_sel = i; IPA_WRITE_SCALER_REG(IPA_RSRC_MNGR_DB_CFG, IPA_WRITE_SCALER_REG( IPA_RSRC_MNGR_DB_CFG, ipa_rsrc_mngr_db_cfg.value); ipa_rsrc_mngr_db_rsrc_read.value = IPA_READ_SCALER_REG(IPA_RSRC_MNGR_DB_RSRC_READ); IPA_READ_SCALER_REG( IPA_RSRC_MNGR_DB_RSRC_READ); if (ipa_rsrc_mngr_db_rsrc_read.def.rsrc_occupied == true) { if (ipa_rsrc_mngr_db_rsrc_read.def.rsrc_occupied == true) { ipa_reg_save.pkt_ctntx_active[i] = true; ipa_reg_save.pkt_cntxt_state[i] = (enum ipa_hw_pkt_cntxt_state_e) ipa_reg_save.pkt_ctntx[i].state; } } } else { IPAERR("IPA_CTX_ID is not currently accessible\n"); } } ipa_reg_save_anomaly_check(); Loading Loading @@ -1316,11 +1400,11 @@ static void ipa_hal_save_regs_save_ipa_testbus(void) * * @return */ int ipa_reg_save_init(u8 value) int ipa_reg_save_init(u32 value) { u32 i, num_regs = ARRAY_SIZE(ipa_regs_to_save_array); if (ipa3_ctx->do_register_collection_on_crash == false) if (!ipa3_ctx->do_register_collection_on_crash) return 0; memset(&ipa_reg_save, value, sizeof(ipa_reg_save)); Loading drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h +121 −20 Original line number Diff line number Diff line Loading @@ -26,21 +26,9 @@ */ #define my_in_dword(addr) \ (readl(addr)) #define in_dword(addr) \ my_in_dword((u8 *) ipa3_ctx->reg_collection_base + \ (u32)(addr)) #define my_in_dword_masked(addr, mask) \ (my_in_dword(addr) & (mask)) #define in_dword_masked(addr, mask) \ my_in_dword_masked((u8 *) ipa3_ctx->reg_collection_base + \ (u32)(addr), (mask)) #define my_out_dword(addr, val) \ ({ __iowmb(); writel_relaxed((val), (addr)); }) #define out_dword(addr, val) \ my_out_dword((u8 *) ipa3_ctx->reg_collection_base + \ (u32)(addr), (val)) #define IPA_0_IPA_WRAPPER_BASE 0 /* required by following includes */ Loading Loading @@ -238,6 +226,12 @@ struct map_src_dst_addr_s { ipa_reg_save.ipa.testbus->ep_rsrc[rsrc_type].entry_ep \ [rsrc_grp].testbus_data.value) /* * Macro to pluck the gsi version from ram. */ #define IPA_REG_SAVE_GSI_VER(reg_name, var_name) \ { GEN_1xVECTOR_REG_OFST(reg_name, 0), \ (u32 *)&ipa_reg_save.gsi.gen.var_name } /* * Macro to define a particular register cfg entry for all 3 EE * indexed register Loading Loading @@ -916,6 +910,8 @@ struct ipa_reg_save_gsi_gen_s { gsi_cfg; struct gsi_hwio_def_gsi_ree_cfg_s gsi_ree_cfg; struct ipa_hwio_def_ipa_gsi_top_gsi_inst_ram_n_s ipa_gsi_top_gsi_inst_ram_n; }; /* GSI General EE register save data struct */ Loading Loading @@ -1226,6 +1222,7 @@ struct ipa_regs_save_hierarchy_s { /* Top level GSI register save data struct */ struct gsi_regs_save_hierarchy_s { u32 fw_ver; struct ipa_reg_save_gsi_gen_s gen; struct ipa_reg_save_gsi_gen_ee_s gen_ee[IPA_REG_SAVE_GSI_NUM_EE]; struct ipa_reg_save_gsi_ch_cntxt_s ch_cntxt; Loading Loading @@ -1268,17 +1265,121 @@ struct ipa_reg_save_rsrc_cnts_s { /* Top level IPA and GSI registers save data struct */ struct regs_save_hierarchy_s { struct ipa_regs_save_hierarchy_s ipa; struct gsi_regs_save_hierarchy_s gsi; bool pkt_ctntx_active[IPA_HW_PKT_CTNTX_MAX]; union ipa_hwio_def_ipa_ctxh_ctrl_u pkt_ctntxt_lock; struct ipa_regs_save_hierarchy_s ipa; struct gsi_regs_save_hierarchy_s gsi; bool pkt_ctntx_active[IPA_HW_PKT_CTNTX_MAX]; union ipa_hwio_def_ipa_ctxh_ctrl_u pkt_ctntxt_lock; enum ipa_hw_pkt_cntxt_state_e pkt_cntxt_state[IPA_HW_PKT_CTNTX_MAX]; struct ipa_pkt_ctntx_s pkt_ctntx[IPA_HW_PKT_CTNTX_MAX]; struct ipa_reg_save_rsrc_cnts_s rsrc_cnts; struct ipa_reg_save_rsrc_cnts_s rsrc_cnts; struct ipa_reg_save_gsi_fifo_status_s gsi_fifo_status[IPA_HW_PIPE_ID_MAX]; }; /* * The following section deals with handling IPA registers' memory * access relative to pre-defined memory protection schemes * (ie. "access control"). * * In a nut shell, the intent of the data stuctures below is to allow * higher level register accessors to be unaware of what really is * going on at the lowest level (ie. real vs non-real access). This * methodology is also designed to allow for platform specific "access * maps." */ /* * Function for doing an actual read */ static inline u32 act_read(void __iomem *addr) { u32 val = my_in_dword(addr); return val; } /* * Function for doing an actual write */ static inline void act_write(void __iomem *addr, u32 val) { my_out_dword(addr, val); } /* * Function that pretends to do a read */ static inline u32 nop_read(void __iomem *addr) { return IPA_MEM_INIT_VAL; } /* * Function that pretends to do a write */ static inline void nop_write(void __iomem *addr, u32 val) { } /* * The following are used to define struct reg_access_funcs_s below... */ typedef u32 (*reg_read_func_t)( void __iomem *addr); typedef void (*reg_write_func_t)( void __iomem *addr, u32 val); /* * The following in used to define io_matrix[] below... */ struct reg_access_funcs_s { reg_read_func_t read; reg_write_func_t write; }; /* * The following will be used to appropriately index into the * read/write combos defined in io_matrix[] below... */ #define AA_COMBO 0 /* actual read, actual write */ #define AN_COMBO 1 /* actual read, no-op write */ #define NA_COMBO 2 /* no-op read, actual write */ #define NN_COMBO 3 /* no-op read, no-op write */ /* * The following will be used to dictate registers' access methods * relative to the state of secure debug...whether it's enabled or * disabled. * * NOTE: The table below defines all access combinations. */ static struct reg_access_funcs_s io_matrix[] = { { act_read, act_write }, /* the AA_COMBO */ { act_read, nop_write }, /* the AN_COMBO */ { nop_read, act_write }, /* the NA_COMBO */ { nop_read, nop_write }, /* the NN_COMBO */ }; /* * The following will be used to define and drive IPA's register * access rules. */ struct reg_mem_access_map_t { u32 addr_range_begin; u32 addr_range_end; struct reg_access_funcs_s *access[2]; }; #endif /* #if !defined(_IPA_REG_DUMP_H_) */ Loading
Documentation/devicetree/bindings/platform/msm/ipa.txt +4 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,10 @@ memory allocation over a PCIe bridge registers, collected upon crash, reside. - qcom,ipa-endp-delay-wa: Boolean context flag to indicate end point delay work around supported or not. - qcom,secure-debug-check-action: Drives secure memory debug check. Three values allowed: 0 (use scm call), 1 (override scm call as though it returned true), and 2 (override scm call as though it returned false) IPA pipe sub nodes (A2 static pipes configurations): Loading
arch/arm64/boot/dts/qcom/sm8150-sdxprairie.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ qcom,register-collection-on-crash; qcom,testbus-collection-on-crash; qcom,non-tn-collection-on-crash; qcom,secure-debug-check-action = <0>; }; qcom,ipa_fws { Loading
drivers/platform/msm/ipa/ipa_v3/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -16,4 +16,6 @@ obj-$(CONFIG_IPA_ETH) += ethernet/ ipat-$(CONFIG_IPA3_REGDUMP) += dump/ipa_reg_dump.o ccflags-$(CONFIG_IPA3_REGDUMP) += -Idrivers/platform/msm/ipa/ipa_v3/dump ccflags-$(CONFIG_IPA3_REGDUMP_SM8150) += -Idrivers/platform/msm/ipa/ipa_v3/dump/sm8150
drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.c +119 −35 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ * GNU General Public License for more details. */ #include "ipa_reg_dump.h" #include "ipa_access_control.h" /* Total size required for test bus */ #define IPA_MEM_OVERLAY_SIZE 0x66000 Loading Loading @@ -338,13 +339,13 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { ipa_dst_rsrc_grp_23_rsrc_type_n), /* Source Resource Group Count Registers */ IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_CNT_GRP (IPA_SRC_RSRC_GRP_0123_RSRC_TYPE_CNT_n, IPA_REG_SAVE_CFG_ENTRY_SRC_RSRC_CNT_GRP( IPA_SRC_RSRC_GRP_0123_RSRC_TYPE_CNT_n, ipa_src_rsrc_grp_0123_rsrc_type_cnt_n), /* Destination Resource Group Count Registers */ IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_CNT_GRP (IPA_DST_RSRC_GRP_0123_RSRC_TYPE_CNT_n, IPA_REG_SAVE_CFG_ENTRY_DST_RSRC_CNT_GRP( IPA_DST_RSRC_GRP_0123_RSRC_TYPE_CNT_n, ipa_dst_rsrc_grp_0123_rsrc_type_cnt_n), /* Loading @@ -360,6 +361,9 @@ static struct map_src_dst_addr_s ipa_regs_to_save_array[] = { GEN_SRC_DST_ADDR_MAP(GSI_REE_CFG, gsi.gen, gsi_ree_cfg), IPA_REG_SAVE_GSI_VER( IPA_GSI_TOP_GSI_INST_RAM_n, ipa_gsi_top_gsi_inst_ram_n), /* GSI Debug Registers */ GEN_SRC_DST_ADDR_MAP(IPA_GSI_TOP_GSI_DEBUG_BUSY_REG, Loading Loading @@ -651,6 +655,73 @@ static void ipa_hal_save_regs_ipa_cmdq(void); static void ipa_hal_save_regs_rsrc_db(void); static void ipa_reg_save_anomaly_check(void); static struct reg_access_funcs_s *get_access_funcs(u32 addr) { u32 i, asub = ipa3_ctx->sd_state; for (i = 0; i < ARRAY_SIZE(mem_access_map); i++) { if (addr >= mem_access_map[i].addr_range_begin && addr <= mem_access_map[i].addr_range_end) { return mem_access_map[i].access[asub]; } } IPAERR("Unknown register offset(0x%08X). Using dflt access methods\n", addr); return &io_matrix[AA_COMBO]; } static u32 in_dword( u32 addr) { struct reg_access_funcs_s *io = get_access_funcs(addr); return io->read(ipa3_ctx->reg_collection_base + addr); } static u32 in_dword_masked( u32 addr, u32 mask) { struct reg_access_funcs_s *io = get_access_funcs(addr); u32 val; val = io->read(ipa3_ctx->reg_collection_base + addr); if (io->read == act_read) return val & mask; return val; } static void out_dword( u32 addr, u32 val) { struct reg_access_funcs_s *io = get_access_funcs(addr); io->write(ipa3_ctx->reg_collection_base + addr, val); } /* * FUNCTION: ipa_save_gsi_ver * * Saves the gsi version * * @return * None */ void ipa_save_gsi_ver(void) { if (!ipa3_ctx->do_register_collection_on_crash) return; ipa_reg_save.gsi.fw_ver = IPA_READ_1xVECTOR_REG(IPA_GSI_TOP_GSI_INST_RAM_n, 0) & 0x0000FFFF; } /* * FUNCTION: ipa_save_registers * Loading @@ -669,7 +740,7 @@ void ipa_save_registers(void) union ipa_hwio_def_ipa_rsrc_mngr_db_rsrc_read_u ipa_rsrc_mngr_db_rsrc_read; if (ipa3_ctx->do_register_collection_on_crash == false) if (!ipa3_ctx->do_register_collection_on_crash) return; IPAERR("Commencing\n"); Loading Loading @@ -831,36 +902,49 @@ void ipa_save_registers(void) * true, via dtsi, and the collection will be done. */ if (ipa3_ctx->do_non_tn_collection_on_crash == true) { /* Copy Pkt context directly from IPA_CTX_ID register space */ u32 ofst = GEN_2xVECTOR_REG_OFST(IPA_CTX_ID_m_CTX_NUM_n, 0, 0); struct reg_access_funcs_s *io = get_access_funcs(ofst); /* * If the memory is accessible, copy pkt context directly from * IPA_CTX_ID register space */ if (io->read == act_read) { memcpy((void *)ipa_reg_save.pkt_ctntx, (void *)((u8 *) ipa3_ctx->reg_collection_base + GEN_2xVECTOR_REG_OFST( IPA_CTX_ID_m_CTX_NUM_n, 0, 0)), (const void *) (ipa3_ctx->reg_collection_base + ofst), sizeof(ipa_reg_save.pkt_ctntx)); ipa_rsrc_mngr_db_cfg.value = IPA_READ_SCALER_REG(IPA_RSRC_MNGR_DB_CFG); ipa_rsrc_mngr_db_cfg.def.rsrc_type_sel = 0; IPA_WRITE_SCALER_REG(IPA_RSRC_MNGR_DB_CFG, IPA_WRITE_SCALER_REG( IPA_RSRC_MNGR_DB_CFG, ipa_rsrc_mngr_db_cfg.value); for (i = 0; i < IPA_HW_PKT_CTNTX_MAX; i++) { ipa_rsrc_mngr_db_cfg.def.rsrc_id_sel = i; IPA_WRITE_SCALER_REG(IPA_RSRC_MNGR_DB_CFG, IPA_WRITE_SCALER_REG( IPA_RSRC_MNGR_DB_CFG, ipa_rsrc_mngr_db_cfg.value); ipa_rsrc_mngr_db_rsrc_read.value = IPA_READ_SCALER_REG(IPA_RSRC_MNGR_DB_RSRC_READ); IPA_READ_SCALER_REG( IPA_RSRC_MNGR_DB_RSRC_READ); if (ipa_rsrc_mngr_db_rsrc_read.def.rsrc_occupied == true) { if (ipa_rsrc_mngr_db_rsrc_read.def.rsrc_occupied == true) { ipa_reg_save.pkt_ctntx_active[i] = true; ipa_reg_save.pkt_cntxt_state[i] = (enum ipa_hw_pkt_cntxt_state_e) ipa_reg_save.pkt_ctntx[i].state; } } } else { IPAERR("IPA_CTX_ID is not currently accessible\n"); } } ipa_reg_save_anomaly_check(); Loading Loading @@ -1316,11 +1400,11 @@ static void ipa_hal_save_regs_save_ipa_testbus(void) * * @return */ int ipa_reg_save_init(u8 value) int ipa_reg_save_init(u32 value) { u32 i, num_regs = ARRAY_SIZE(ipa_regs_to_save_array); if (ipa3_ctx->do_register_collection_on_crash == false) if (!ipa3_ctx->do_register_collection_on_crash) return 0; memset(&ipa_reg_save, value, sizeof(ipa_reg_save)); Loading
drivers/platform/msm/ipa/ipa_v3/dump/ipa_reg_dump.h +121 −20 Original line number Diff line number Diff line Loading @@ -26,21 +26,9 @@ */ #define my_in_dword(addr) \ (readl(addr)) #define in_dword(addr) \ my_in_dword((u8 *) ipa3_ctx->reg_collection_base + \ (u32)(addr)) #define my_in_dword_masked(addr, mask) \ (my_in_dword(addr) & (mask)) #define in_dword_masked(addr, mask) \ my_in_dword_masked((u8 *) ipa3_ctx->reg_collection_base + \ (u32)(addr), (mask)) #define my_out_dword(addr, val) \ ({ __iowmb(); writel_relaxed((val), (addr)); }) #define out_dword(addr, val) \ my_out_dword((u8 *) ipa3_ctx->reg_collection_base + \ (u32)(addr), (val)) #define IPA_0_IPA_WRAPPER_BASE 0 /* required by following includes */ Loading Loading @@ -238,6 +226,12 @@ struct map_src_dst_addr_s { ipa_reg_save.ipa.testbus->ep_rsrc[rsrc_type].entry_ep \ [rsrc_grp].testbus_data.value) /* * Macro to pluck the gsi version from ram. */ #define IPA_REG_SAVE_GSI_VER(reg_name, var_name) \ { GEN_1xVECTOR_REG_OFST(reg_name, 0), \ (u32 *)&ipa_reg_save.gsi.gen.var_name } /* * Macro to define a particular register cfg entry for all 3 EE * indexed register Loading Loading @@ -916,6 +910,8 @@ struct ipa_reg_save_gsi_gen_s { gsi_cfg; struct gsi_hwio_def_gsi_ree_cfg_s gsi_ree_cfg; struct ipa_hwio_def_ipa_gsi_top_gsi_inst_ram_n_s ipa_gsi_top_gsi_inst_ram_n; }; /* GSI General EE register save data struct */ Loading Loading @@ -1226,6 +1222,7 @@ struct ipa_regs_save_hierarchy_s { /* Top level GSI register save data struct */ struct gsi_regs_save_hierarchy_s { u32 fw_ver; struct ipa_reg_save_gsi_gen_s gen; struct ipa_reg_save_gsi_gen_ee_s gen_ee[IPA_REG_SAVE_GSI_NUM_EE]; struct ipa_reg_save_gsi_ch_cntxt_s ch_cntxt; Loading Loading @@ -1268,17 +1265,121 @@ struct ipa_reg_save_rsrc_cnts_s { /* Top level IPA and GSI registers save data struct */ struct regs_save_hierarchy_s { struct ipa_regs_save_hierarchy_s ipa; struct gsi_regs_save_hierarchy_s gsi; bool pkt_ctntx_active[IPA_HW_PKT_CTNTX_MAX]; union ipa_hwio_def_ipa_ctxh_ctrl_u pkt_ctntxt_lock; struct ipa_regs_save_hierarchy_s ipa; struct gsi_regs_save_hierarchy_s gsi; bool pkt_ctntx_active[IPA_HW_PKT_CTNTX_MAX]; union ipa_hwio_def_ipa_ctxh_ctrl_u pkt_ctntxt_lock; enum ipa_hw_pkt_cntxt_state_e pkt_cntxt_state[IPA_HW_PKT_CTNTX_MAX]; struct ipa_pkt_ctntx_s pkt_ctntx[IPA_HW_PKT_CTNTX_MAX]; struct ipa_reg_save_rsrc_cnts_s rsrc_cnts; struct ipa_reg_save_rsrc_cnts_s rsrc_cnts; struct ipa_reg_save_gsi_fifo_status_s gsi_fifo_status[IPA_HW_PIPE_ID_MAX]; }; /* * The following section deals with handling IPA registers' memory * access relative to pre-defined memory protection schemes * (ie. "access control"). * * In a nut shell, the intent of the data stuctures below is to allow * higher level register accessors to be unaware of what really is * going on at the lowest level (ie. real vs non-real access). This * methodology is also designed to allow for platform specific "access * maps." */ /* * Function for doing an actual read */ static inline u32 act_read(void __iomem *addr) { u32 val = my_in_dword(addr); return val; } /* * Function for doing an actual write */ static inline void act_write(void __iomem *addr, u32 val) { my_out_dword(addr, val); } /* * Function that pretends to do a read */ static inline u32 nop_read(void __iomem *addr) { return IPA_MEM_INIT_VAL; } /* * Function that pretends to do a write */ static inline void nop_write(void __iomem *addr, u32 val) { } /* * The following are used to define struct reg_access_funcs_s below... */ typedef u32 (*reg_read_func_t)( void __iomem *addr); typedef void (*reg_write_func_t)( void __iomem *addr, u32 val); /* * The following in used to define io_matrix[] below... */ struct reg_access_funcs_s { reg_read_func_t read; reg_write_func_t write; }; /* * The following will be used to appropriately index into the * read/write combos defined in io_matrix[] below... */ #define AA_COMBO 0 /* actual read, actual write */ #define AN_COMBO 1 /* actual read, no-op write */ #define NA_COMBO 2 /* no-op read, actual write */ #define NN_COMBO 3 /* no-op read, no-op write */ /* * The following will be used to dictate registers' access methods * relative to the state of secure debug...whether it's enabled or * disabled. * * NOTE: The table below defines all access combinations. */ static struct reg_access_funcs_s io_matrix[] = { { act_read, act_write }, /* the AA_COMBO */ { act_read, nop_write }, /* the AN_COMBO */ { nop_read, act_write }, /* the NA_COMBO */ { nop_read, nop_write }, /* the NN_COMBO */ }; /* * The following will be used to define and drive IPA's register * access rules. */ struct reg_mem_access_map_t { u32 addr_range_begin; u32 addr_range_end; struct reg_access_funcs_s *access[2]; }; #endif /* #if !defined(_IPA_REG_DUMP_H_) */