From 1d895c493c07d194a68bd4486c22210c5e5f65b3 Mon Sep 17 00:00:00 2001 From: Armaan Siddiqui Date: Thu, 1 Apr 2021 23:43:33 +0530 Subject: [PATCH] ipa: save registers on graceful shutdown Save registers - when gsi channel setup fails in post init - on graceful shutdown Handle printing registers when ipahal is not intialized. --- drivers/platform/msm/gsi/gsi.c | 10 +++- drivers/platform/msm/ipa/ipa_v3/ipa.c | 15 ++++++ .../platform/msm/ipa/ipa_v3/ipahal/ipahal.c | 18 ++++--- .../msm/ipa/ipa_v3/ipahal/ipahal_reg.c | 48 ++++++++++++++++--- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 5725a40c1ea7..93a644eda17b 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -1820,6 +1820,7 @@ int gsi_alloc_evt_ring(struct gsi_evt_ring_props *props, unsigned long dev_hdl, ((op << GSI_EE_n_EV_CH_CMD_OPCODE_SHFT) & GSI_EE_n_EV_CH_CMD_OPCODE_BMSK)); ee = gsi_ctx->per.ee; + GSIDBG("Sending alloc evt command for %lu\n", evt_id); gsi_writel(val, gsi_ctx->base + GSI_EE_n_EV_CH_CMD_OFFS(ee)); res = wait_for_completion_timeout(&ctx->compl, GSI_CMD_TIMEOUT); @@ -3035,7 +3036,14 @@ EXPORT_SYMBOL(gsi_query_channel_db_addr); int gsi_pending_irq_type(void) { - int ee = gsi_ctx->per.ee; + int ee; + + if (!gsi_ctx->per_registered) { + GSIERR("no client registered\n"); + return 0; + } + + ee = gsi_ctx->per.ee; return gsi_readl(gsi_ctx->base + GSI_EE_n_CNTXT_TYPE_IRQ_OFFS(ee)); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index ce8a234e16f5..80e9558cd675 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -154,6 +154,7 @@ static struct clk *ipa3_clk; struct ipa3_context *ipa3_ctx = NULL; +void ipa3_plat_drv_shutdown(struct platform_device *pdev_p); int ipa3_plat_drv_probe(struct platform_device *pdev_p); int ipa3_pci_drv_probe( struct pci_dev *pci_dev, @@ -443,6 +444,7 @@ static const struct dev_pm_ops ipa_pm_ops = { static struct platform_driver ipa_plat_drv = { .probe = ipa3_plat_drv_probe, + .shutdown = ipa3_plat_drv_shutdown, .driver = { .name = DRV_NAME, .pm = &ipa_pm_ops, @@ -6524,6 +6526,8 @@ fail_teth_bridge_driver_init: ipa3_teardown_apps_pipes(); fail_alloc_gsi_channel: fail_setup_apps_pipes: + ipahal_print_all_regs(false); + ipa_save_registers(); gsi_deregister_device(ipa3_ctx->gsi_dev_hdl, false); fail_register_device: ipa3_destroy_flt_tbl_idrs(); @@ -8998,6 +9002,17 @@ static void ipa_smmu_update_fw_loader(void) } } +void ipa3_plat_drv_shutdown(struct platform_device *pdev_p) +{ + pr_debug("ipa: driver shutdown invoked for %s\n", + pdev_p->dev.of_node->name); + if (ipa3_ctx && atomic_read(&ipa3_ctx->ipa_clk_vote)) { + ipahal_print_all_regs(false); + ipa_save_registers(); + } + return; +} + int ipa3_plat_drv_probe(struct platform_device *pdev_p) { int result; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c index 4fdd04437455..d7233b9e218b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c @@ -617,8 +617,9 @@ static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_ip_v4_filter_init( static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_dummy( enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx) { - IPAHAL_ERR("no construct function for IMM_CMD=%s, IPA ver %d\n", - ipahal_imm_cmd_name_str(cmd), ipahal_ctx->hw_type); + IPAHAL_ERR("no construct function for IMM_CMD=%s IPA ver=%d\n", + ipahal_imm_cmd_name_str(cmd), ipahal_ctx?ipahal_ctx->hw_type:-1); + WARN_ON(1); return NULL; } @@ -779,6 +780,11 @@ static u16 ipahal_imm_cmd_get_opcode(enum ipahal_imm_cmd_name cmd) { u32 opcode; + if (!ipahal_ctx) { + IPAHAL_ERR("Invalid ctx\n"); + return -EFAULT; + } + if (cmd >= IPA_IMM_CMD_MAX) { IPAHAL_ERR("Invalid immediate command imm_cmd=%u\n", cmd); ipa_assert(); @@ -813,8 +819,8 @@ struct ipahal_imm_cmd_pyld *ipahal_construct_imm_cmd( return NULL; } - if (cmd >= IPA_IMM_CMD_MAX) { - IPAHAL_ERR("Invalid immediate command %u\n", cmd); + if (!ipahal_ctx || cmd >= IPA_IMM_CMD_MAX) { + IPAHAL_ERR("Invalid ctx/immediate command %u\n", cmd); return NULL; } @@ -1196,7 +1202,7 @@ u32 ipahal_pkt_status_get_size(void) void ipahal_pkt_status_parse(const void *unparsed_status, struct ipahal_pkt_status *status) { - if (!unparsed_status || !status) { + if (!ipahal_ctx || !unparsed_status || !status) { IPAHAL_ERR("Input Error: unparsed_status=%pK status=%pK\n", unparsed_status, status); return; @@ -1218,7 +1224,7 @@ void ipahal_pkt_status_parse(const void *unparsed_status, void ipahal_pkt_status_parse_thin(const void *unparsed_status, struct ipahal_pkt_status_thin *status) { - if (!unparsed_status || !status) { + if (!ipahal_ctx || !unparsed_status || !status) { IPAHAL_ERR("Input Error: unparsed_status=%pK status=%pK\n", unparsed_status, status); return; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c index 5bead393638c..0e053455de79 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c @@ -3068,8 +3068,11 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = { ipareg_construct_single_ndp_mode, ipareg_parse_single_ndp_mode, -1, 0, 0, 0, 0}, [IPA_HW_v4_0][IPA_QSB_MAX_READS] = { - ipareg_construct_qsb_max_reads_v4_0, ipareg_parse_dummy, + ipareg_construct_qsb_max_reads_v4_0, ipareg_parse_qsb_max_reads, 0x00000078, 0, 0, 0, 0}, + [IPA_HW_v4_0][IPA_QSB_MAX_WRITES] = { + ipareg_construct_qsb_max_writes, ipareg_parse_qsb_max_writes, + 0x00000074, 0, 0, 0, 0}, [IPA_HW_v4_0][IPA_FILT_ROUT_HASH_FLUSH] = { ipareg_construct_dummy, ipareg_parse_dummy, 0x0000014c, 0, 0, 0, 0}, @@ -3629,15 +3632,16 @@ void ipahal_print_all_regs(bool print_to_dmesg) int i, j; struct ipahal_reg_obj *reg; - IPAHAL_DBG("Printing all registers for ipa_hw_type %d\n", - ipahal_ctx->hw_type); - - if ((ipahal_ctx->hw_type < IPA_HW_v4_0) || + if (!ipahal_ctx || (ipahal_ctx->hw_type < IPA_HW_v4_0) || (ipahal_ctx->hw_type >= IPA_HW_MAX)) { - IPAHAL_ERR("invalid IPA HW type (%d)\n", ipahal_ctx->hw_type); + IPAHAL_ERR("invalid IPA HW type (%d)\n", + ipahal_ctx?ipahal_ctx->hw_type:-1); return; } + IPAHAL_DBG("Printing all registers for ipa_hw_type %d\n", + ipahal_ctx->hw_type); + for (i = 0; i < IPA_REG_MAX ; i++) { reg = &(ipahal_reg_objs[ipahal_ctx->hw_type][i]); @@ -3753,6 +3757,11 @@ u32 ipahal_read_reg_n(enum ipahal_reg_name reg, u32 n) { u32 offset; + if (!ipahal_ctx) { + IPAHAL_DBG("Invalid ipahal context\n"); + return -EINVAL; + } + if (reg >= IPA_REG_MAX) { IPAHAL_ERR("Invalid register reg=%u\n", reg); WARN_ON(1); @@ -3780,6 +3789,11 @@ u32 ipahal_read_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n) { u32 offset; + if (!ipahal_ctx) { + IPAHAL_DBG("Invalid ipahal context\n"); + return -EINVAL; + } + if (reg >= IPA_REG_MAX) { IPAHAL_ERR("Invalid register reg=%u\n", reg); WARN_ON(1); @@ -3813,6 +3827,11 @@ void ipahal_write_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n, u32 val) { u32 offset; + if (!ipahal_ctx) { + IPAHAL_DBG("Invalid ipahal context\n"); + return; + } + if (reg >= IPA_REG_MAX) { IPAHAL_ERR("Invalid register reg=%u\n", reg); WARN_ON(1); @@ -3847,6 +3866,11 @@ u32 ipahal_read_reg_n_fields(enum ipahal_reg_name reg, u32 n, void *fields) u32 val = 0; u32 offset; + if (!ipahal_ctx) { + IPAHAL_DBG("Invalid ipahal context\n"); + return -EINVAL; + } + if (!fields) { IPAHAL_ERR("Input error fields\n"); WARN_ON(1); @@ -3884,6 +3908,11 @@ void ipahal_write_reg_n_fields(enum ipahal_reg_name reg, u32 n, u32 val = 0; u32 offset; + if (!ipahal_ctx) { + IPAHAL_DBG("Invalid ipahal context\n"); + return; + } + if (!fields) { IPAHAL_ERR("Input error fields=%pK\n", fields); WARN_ON(1); @@ -3918,6 +3947,11 @@ u32 ipahal_get_reg_mn_ofst(enum ipahal_reg_name reg, u32 m, u32 n) { u32 offset; + if (!ipahal_ctx) { + IPAHAL_DBG("Invalid ipahal context\n"); + return -EINVAL; + } + if (reg >= IPA_REG_MAX) { IPAHAL_ERR("Invalid register reg=%u\n", reg); WARN_ON(1); @@ -3967,7 +4001,7 @@ void ipahal_get_aggr_force_close_valmask(int ep_idx, u32 shft = 0; u32 bmsk = 0; - if (!valmask) { + if (!ipahal_ctx || !valmask) { IPAHAL_ERR("Input error\n"); return; }