Loading drivers/platform/msm/gsi/gsi.c +89 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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) { Loading drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +9 −20 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); 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); goto exit; } result = gsi_read_wdi3_channel_scratch2_reg(ep->gsi_chan_hdl, &scratch2_reg); ch_scratch.wdi3.qmap_id = qmap_id; result = gsi_write_channel_scratch(ep->gsi_chan_hdl, ch_scratch); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to write channel scratch %d\n", result); IPAERR("failed to read channel scratch2 reg %d\n", result); goto exit; } result = gsi_start_channel(ep->gsi_chan_hdl); 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 start gsi channel %d\n", result); IPAERR("failed to write channel scratch2 reg %d\n", result); goto exit; } Loading include/linux/msm_gsi.h +63 −0 Original line number Diff line number Diff line Loading @@ -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 * Loading Loading @@ -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 Loading @@ -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 Loading Loading
drivers/platform/msm/gsi/gsi.c +89 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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) { Loading
drivers/platform/msm/ipa/ipa_v3/ipa_wdi3_i.c +9 −20 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); 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); goto exit; } result = gsi_read_wdi3_channel_scratch2_reg(ep->gsi_chan_hdl, &scratch2_reg); ch_scratch.wdi3.qmap_id = qmap_id; result = gsi_write_channel_scratch(ep->gsi_chan_hdl, ch_scratch); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to write channel scratch %d\n", result); IPAERR("failed to read channel scratch2 reg %d\n", result); goto exit; } result = gsi_start_channel(ep->gsi_chan_hdl); 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 start gsi channel %d\n", result); IPAERR("failed to write channel scratch2 reg %d\n", result); goto exit; } Loading
include/linux/msm_gsi.h +63 −0 Original line number Diff line number Diff line Loading @@ -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 * Loading Loading @@ -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 Loading @@ -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 Loading