From 2f2eea29bcd891eee26f35d9ff5a2168c5b67044 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Sat, 16 Nov 2019 22:00:03 -0800 Subject: [PATCH] msm: ipa: add support to updated wdi3 scratch register2 alone To update QMAP ID there is no need to start and stop the GSI channel. Make changes to read only scratch2 register for WDI3 protocol and update the QMAP ID without affecting other registers. Change-Id: I7f873386fd01d624629fed15b841c6abd558a9ce Signed-off-by: Chaitanya Pratapa --- drivers/platform/msm/gsi/gsi.c | 89 ++++++++++++++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c | 29 ++----- include/linux/msm_gsi.h | 63 ++++++++++++++ 3 files changed, 161 insertions(+), 20 deletions(-) diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index dafcb2910428..5289d3a4afdb 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -2562,6 +2562,15 @@ static void __gsi_write_channel_scratch(unsigned long chan_hdl, gsi_ctx->per.ee)); } +static void __gsi_write_wdi3_channel_scratch2_reg(unsigned long chan_hdl, + union __packed gsi_wdi3_channel_scratch2_reg val) +{ + gsi_writel(val.data.word1, gsi_ctx->base + + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, + gsi_ctx->per.ee)); +} + + int gsi_write_channel_scratch3_reg(unsigned long chan_hdl, union __packed gsi_wdi_channel_scratch3_reg val) { @@ -2645,6 +2654,17 @@ static void __gsi_read_channel_scratch(unsigned long chan_hdl, gsi_ctx->per.ee)); } +static void __gsi_read_wdi3_channel_scratch2_reg(unsigned long chan_hdl, + union __packed gsi_wdi3_channel_scratch2_reg * val) +{ + + val->data.word1 = gsi_readl(gsi_ctx->base + + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, + gsi_ctx->per.ee)); + +} + + static union __packed gsi_channel_scratch __gsi_update_mhi_channel_scratch( unsigned long chan_hdl, struct __packed gsi_mhi_channel_scratch mscr) { @@ -2737,6 +2757,41 @@ int gsi_write_channel_scratch(unsigned long chan_hdl, } EXPORT_SYMBOL(gsi_write_channel_scratch); +int gsi_write_wdi3_channel_scratch2_reg(unsigned long chan_hdl, + union __packed gsi_wdi3_channel_scratch2_reg val) +{ + struct gsi_chan_ctx *ctx; + + if (!gsi_ctx) { + pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__); + return -GSI_STATUS_NODEV; + } + + if (chan_hdl >= gsi_ctx->max_ch) { + GSIERR("bad params chan_hdl=%lu\n", chan_hdl); + return -GSI_STATUS_INVALID_PARAMS; + } + + if (gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_ALLOCATED && + gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_STARTED && + gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_STOPPED) { + GSIERR("bad state %d\n", + gsi_ctx->chan[chan_hdl].state); + return -GSI_STATUS_UNSUPPORTED_OP; + } + + ctx = &gsi_ctx->chan[chan_hdl]; + + mutex_lock(&ctx->mlock); + ctx->scratch.data.word3 = val.data.word1; + __gsi_write_wdi3_channel_scratch2_reg(chan_hdl, val); + mutex_unlock(&ctx->mlock); + + return GSI_STATUS_SUCCESS; +} +EXPORT_SYMBOL(gsi_write_wdi3_channel_scratch2_reg); + + int gsi_read_channel_scratch(unsigned long chan_hdl, union __packed gsi_channel_scratch *val) { @@ -2770,6 +2825,40 @@ int gsi_read_channel_scratch(unsigned long chan_hdl, } EXPORT_SYMBOL(gsi_read_channel_scratch); +int gsi_read_wdi3_channel_scratch2_reg(unsigned long chan_hdl, + union __packed gsi_wdi3_channel_scratch2_reg * val) +{ + struct gsi_chan_ctx *ctx; + + if (!gsi_ctx) { + pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__); + return -GSI_STATUS_NODEV; + } + + if (chan_hdl >= gsi_ctx->max_ch) { + GSIERR("bad params chan_hdl=%lu\n", chan_hdl); + return -GSI_STATUS_INVALID_PARAMS; + } + + if (gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_ALLOCATED && + gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_STARTED && + gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_STOPPED) { + GSIERR("bad state %d\n", + gsi_ctx->chan[chan_hdl].state); + return -GSI_STATUS_UNSUPPORTED_OP; + } + + ctx = &gsi_ctx->chan[chan_hdl]; + + mutex_lock(&ctx->mlock); + __gsi_read_wdi3_channel_scratch2_reg(chan_hdl, val); + mutex_unlock(&ctx->mlock); + + return GSI_STATUS_SUCCESS; +} +EXPORT_SYMBOL(gsi_read_wdi3_channel_scratch2_reg); + + int gsi_update_mhi_channel_scratch(unsigned long chan_hdl, struct __packed gsi_mhi_channel_scratch mscr) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c index 843cf0b37a41..281558599e0f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c @@ -908,9 +908,9 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id) { int result = 0; struct ipa3_ep_context *ep; - union __packed gsi_channel_scratch ch_scratch; + union __packed gsi_wdi3_channel_scratch2_reg scratch2_reg; - memset(&ch_scratch, 0, sizeof(ch_scratch)); + memset(&scratch2_reg, 0, sizeof(scratch2_reg)); if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || ipa3_ctx->ep[clnt_hdl].valid == 0) { IPAERR_RL("bad parm, %d\n", clnt_hdl); @@ -918,30 +918,19 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id) } ep = &ipa3_ctx->ep[clnt_hdl]; IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl)); - result = gsi_read_channel_scratch(ep->gsi_chan_hdl, &ch_scratch); + result = gsi_read_wdi3_channel_scratch2_reg(ep->gsi_chan_hdl, + &scratch2_reg); if (result != GSI_STATUS_SUCCESS) { - IPAERR("failed to read channel scratch %d\n", result); - goto exit; - } - result = gsi_stop_channel(ep->gsi_chan_hdl); - if (result != GSI_STATUS_SUCCESS && result != -GSI_STATUS_AGAIN && - result != -GSI_STATUS_TIMED_OUT) { - IPAERR("failed to stop gsi channel %d\n", result); + IPAERR("failed to read channel scratch2 reg %d\n", result); goto exit; } - ch_scratch.wdi3.qmap_id = qmap_id; - result = gsi_write_channel_scratch(ep->gsi_chan_hdl, - ch_scratch); + scratch2_reg.wdi.qmap_id = qmap_id; + result = gsi_write_wdi3_channel_scratch2_reg(ep->gsi_chan_hdl, + scratch2_reg); if (result != GSI_STATUS_SUCCESS) { - IPAERR("failed to write channel scratch %d\n", result); - goto exit; - } - - result = gsi_start_channel(ep->gsi_chan_hdl); - if (result != GSI_STATUS_SUCCESS) { - IPAERR("failed to start gsi channel %d\n", result); + IPAERR("failed to write channel scratch2 reg %d\n", result); goto exit; } diff --git a/include/linux/msm_gsi.h b/include/linux/msm_gsi.h index 394c93b6d50b..e01b492e5361 100644 --- a/include/linux/msm_gsi.h +++ b/include/linux/msm_gsi.h @@ -867,6 +867,43 @@ struct __packed gsi_wdi3_channel_scratch { uint32_t reserved2 : 16; }; +/** + * gsi_wdi3_channel_scratch2 - WDI3 protocol SW config area of + * channel scratch2 + * + * @update_ri_moderation_threshold: Threshold N for Transfer ring Read Index + * N is the number of packets that IPA will + * process before Wifi transfer ring Ri will + * be updated. + * @qmap_id: Rx only, used for setting metadata register in IPA. Read only + * field for MCS. Write for SW. + * @resv: reserved bits. + * @endp_metadata_reg_offset: Rx only, the offset of + * IPA_ENDP_INIT_HDR_METADATA_n of the + * corresponding endpoint in 4B words from IPA + * base address. + */ + +struct __packed gsi_wdi3_channel_scratch2 { + uint32_t update_rp_moderation_threshold : 5; + uint32_t qmap_id : 8; + uint32_t reserved1 : 3; + uint32_t endp_metadata_reg_offset : 16; +}; + +/** + * gsi_wdi3_channel_scratch2_reg - channel scratch2 SW config area + * + */ + +union __packed gsi_wdi3_channel_scratch2_reg { + struct __packed gsi_wdi3_channel_scratch2 wdi; + struct __packed { + uint32_t word1; + } data; +}; + + /** * gsi_channel_scratch - channel scratch SW config area * @@ -1305,6 +1342,19 @@ int gsi_write_channel_scratch3_reg(unsigned long chan_hdl, int gsi_write_channel_scratch2_reg(unsigned long chan_hdl, union __packed gsi_wdi2_channel_scratch2_reg val); +/** + * gsi_write_wdi3_channel_scratch2_reg - Peripheral should call this function + * to write to the WDI3 scratch 3 register area of the channel context + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @val: Read value + * + * @Return gsi_status + */ +int gsi_write_wdi3_channel_scratch2_reg(unsigned long chan_hdl, + union __packed gsi_wdi3_channel_scratch2_reg val); + /** * gsi_read_channel_scratch - Peripheral should call this function to * read to the scratch area of the channel context @@ -1318,6 +1368,19 @@ int gsi_write_channel_scratch2_reg(unsigned long chan_hdl, int gsi_read_channel_scratch(unsigned long chan_hdl, union __packed gsi_channel_scratch *val); +/** + * gsi_read_wdi3_channel_scratch2_reg - Peripheral should call this function to + * read to the WDI3 scratch 2 register area of the channel context + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @val: Read value + * + * @Return gsi_status + */ +int gsi_read_wdi3_channel_scratch2_reg(unsigned long chan_hdl, + union __packed gsi_wdi3_channel_scratch2_reg *val); + /** * gsi_update_mhi_channel_scratch - MHI Peripheral should call this * function to update the scratch area of the channel context. Updating