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