Loading drivers/platform/msm/gsi/gsi.c +88 −6 Original line number Diff line number Diff line Loading @@ -1909,8 +1909,6 @@ EXPORT_SYMBOL(gsi_alloc_channel); static void __gsi_write_channel_scratch(unsigned long chan_hdl, union __packed gsi_channel_scratch val) { uint32_t reg; gsi_writel(val.data.word1, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl, gsi_ctx->per.ee)); Loading @@ -1920,17 +1918,69 @@ static void __gsi_write_channel_scratch(unsigned long chan_hdl, gsi_writel(val.data.word3, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(val.data.word4, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_3_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) { union __packed gsi_channel_scratch scr; /* below sequence is not atomic. assumption is sequencer specific fields * will remain unchanged across this sequence */ reg = gsi_readl(gsi_ctx->base + /* READ */ scr.data.word1 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl, gsi_ctx->per.ee)); scr.data.word2 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_1_OFFS(chan_hdl, gsi_ctx->per.ee)); scr.data.word3 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, gsi_ctx->per.ee)); scr.data.word4 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_3_OFFS(chan_hdl, gsi_ctx->per.ee)); reg &= 0xFFFF; reg |= (val.data.word4 & 0xFFFF0000); gsi_writel(reg, gsi_ctx->base + /* UPDATE */ scr.mhi.mhi_host_wp_addr = mscr.mhi_host_wp_addr; scr.mhi.assert_bit40 = mscr.assert_bit40; scr.mhi.polling_configuration = mscr.polling_configuration; scr.mhi.burst_mode_enabled = mscr.burst_mode_enabled; scr.mhi.polling_mode = mscr.polling_mode; scr.mhi.oob_mod_threshold = mscr.oob_mod_threshold; if (gsi_ctx->per.ver < GSI_VER_2_5) { scr.mhi.max_outstanding_tre = mscr.max_outstanding_tre; scr.mhi.outstanding_threshold = mscr.outstanding_threshold; } /* WRITE */ gsi_writel(scr.data.word1, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(scr.data.word2, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_1_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(scr.data.word3, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(scr.data.word4, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_3_OFFS(chan_hdl, gsi_ctx->per.ee)); return scr; } int gsi_write_channel_scratch(unsigned long chan_hdl, Loading Loading @@ -1966,6 +2016,38 @@ int gsi_write_channel_scratch(unsigned long chan_hdl, } EXPORT_SYMBOL(gsi_write_channel_scratch); int gsi_update_mhi_channel_scratch(unsigned long chan_hdl, struct __packed gsi_mhi_channel_scratch mscr) { 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_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 = __gsi_update_mhi_channel_scratch(chan_hdl, mscr); mutex_unlock(&ctx->mlock); return GSI_STATUS_SUCCESS; } EXPORT_SYMBOL(gsi_update_mhi_channel_scratch); int gsi_query_channel_db_addr(unsigned long chan_hdl, uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb) { Loading drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +11 −5 Original line number Diff line number Diff line Loading @@ -1351,14 +1351,20 @@ static int ipa3_usb_request_xdci_channel( params->xfer_scratch.depcmd_low_addr; chan_params.chan_scratch.xdci.depcmd_hi_addr = params->xfer_scratch.depcmd_hi_addr; /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { chan_params.chan_scratch.xdci.outstanding_threshold = ((params->teth_prot == IPA_USB_MBIM) ? 1 : 2) * chan_params.chan_params.re_size; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) chan_params.chan_scratch.xdci.outstanding_threshold = 0; } /* max_outstanding_tre is set in ipa3_request_gsi_channel() */ result = ipa3_request_gsi_channel(&chan_params, out_params); if (result) { IPA_USB_ERR("failed to allocate GSI channel\n"); Loading drivers/platform/msm/ipa/ipa_v3/ipa_client.c +10 −4 Original line number Diff line number Diff line Loading @@ -823,11 +823,17 @@ int ipa3_request_gsi_channel(struct ipa_request_gsi_channel_params *params, memcpy(&ep->chan_scratch, ¶ms->chan_scratch, sizeof(union __packed gsi_channel_scratch)); /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { ep->chan_scratch.xdci.max_outstanding_tre = params->chan_params.re_size * gsi_ep_cfg_ptr->ipa_if_tlv; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) ep->chan_scratch.xdci.max_outstanding_tre = 0; } gsi_res = gsi_write_channel_scratch(ep->gsi_chan_hdl, params->chan_scratch); Loading drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +14 −9 Original line number Diff line number Diff line Loading @@ -3792,15 +3792,20 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in, goto fail_alloc_channel; memset(&ch_scratch, 0, sizeof(ch_scratch)); ch_scratch.gpi.max_outstanding_tre = gsi_ep_info->ipa_if_tlv * GSI_CHAN_RE_SIZE_16B; ch_scratch.gpi.outstanding_threshold = 2 * GSI_CHAN_RE_SIZE_16B; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { ch_scratch.gpi.max_outstanding_tre = 0; ch_scratch.gpi.outstanding_threshold = 0; } /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { ch_scratch.gpi.max_outstanding_tre = gsi_ep_info->ipa_if_tlv * GSI_CHAN_RE_SIZE_16B; ch_scratch.gpi.outstanding_threshold = 2 * GSI_CHAN_RE_SIZE_16B; } if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) ch_scratch.gpi.dl_nlo_channel = 0; result = gsi_write_channel_scratch(ep->gsi_chan_hdl, ch_scratch); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to write scratch %d\n", result); Loading drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c +19 −9 Original line number Diff line number Diff line Loading @@ -298,13 +298,18 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client, params->channel_context_addr + offsetof(struct ipa_mhi_ch_ctx, wp)); ch_scratch.mhi.assert_bit40 = params->assert_bit40; /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { ch_scratch.mhi.max_outstanding_tre = ep_cfg->ipa_if_tlv * ch_props.re_size; ch_scratch.mhi.outstanding_threshold = min(ep_cfg->ipa_if_tlv / 2, 8) * ch_props.re_size; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { ch_scratch.mhi.max_outstanding_tre = 0; ch_scratch.mhi.outstanding_threshold = 0; } ch_scratch.mhi.oob_mod_threshold = 4; if (params->ch_ctx_host->brstmode == IPA_MHI_BURST_MODE_DEFAULT || Loading Loading @@ -564,8 +569,13 @@ int ipa3_mhi_resume_channels_internal(enum ipa_client_type client, * set polling mode bit to DB mode before * resuming the channel */ res = gsi_write_channel_scratch( ep->gsi_chan_hdl, ch_scratch); ch_scratch.mhi.polling_mode = IPA_MHI_POLLING_MODE_DB_MODE; /* Use GSI update API to not affect non-SWI fields * inside the scratch while in suspend-resume operation */ res = gsi_update_mhi_channel_scratch( ep->gsi_chan_hdl, ch_scratch.mhi); if (res) { IPA_MHI_ERR("write ch scratch fail %d\n" , res); Loading Loading
drivers/platform/msm/gsi/gsi.c +88 −6 Original line number Diff line number Diff line Loading @@ -1909,8 +1909,6 @@ EXPORT_SYMBOL(gsi_alloc_channel); static void __gsi_write_channel_scratch(unsigned long chan_hdl, union __packed gsi_channel_scratch val) { uint32_t reg; gsi_writel(val.data.word1, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl, gsi_ctx->per.ee)); Loading @@ -1920,17 +1918,69 @@ static void __gsi_write_channel_scratch(unsigned long chan_hdl, gsi_writel(val.data.word3, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(val.data.word4, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_3_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) { union __packed gsi_channel_scratch scr; /* below sequence is not atomic. assumption is sequencer specific fields * will remain unchanged across this sequence */ reg = gsi_readl(gsi_ctx->base + /* READ */ scr.data.word1 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl, gsi_ctx->per.ee)); scr.data.word2 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_1_OFFS(chan_hdl, gsi_ctx->per.ee)); scr.data.word3 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, gsi_ctx->per.ee)); scr.data.word4 = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_3_OFFS(chan_hdl, gsi_ctx->per.ee)); reg &= 0xFFFF; reg |= (val.data.word4 & 0xFFFF0000); gsi_writel(reg, gsi_ctx->base + /* UPDATE */ scr.mhi.mhi_host_wp_addr = mscr.mhi_host_wp_addr; scr.mhi.assert_bit40 = mscr.assert_bit40; scr.mhi.polling_configuration = mscr.polling_configuration; scr.mhi.burst_mode_enabled = mscr.burst_mode_enabled; scr.mhi.polling_mode = mscr.polling_mode; scr.mhi.oob_mod_threshold = mscr.oob_mod_threshold; if (gsi_ctx->per.ver < GSI_VER_2_5) { scr.mhi.max_outstanding_tre = mscr.max_outstanding_tre; scr.mhi.outstanding_threshold = mscr.outstanding_threshold; } /* WRITE */ gsi_writel(scr.data.word1, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(scr.data.word2, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_1_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(scr.data.word3, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl, gsi_ctx->per.ee)); gsi_writel(scr.data.word4, gsi_ctx->base + GSI_EE_n_GSI_CH_k_SCRATCH_3_OFFS(chan_hdl, gsi_ctx->per.ee)); return scr; } int gsi_write_channel_scratch(unsigned long chan_hdl, Loading Loading @@ -1966,6 +2016,38 @@ int gsi_write_channel_scratch(unsigned long chan_hdl, } EXPORT_SYMBOL(gsi_write_channel_scratch); int gsi_update_mhi_channel_scratch(unsigned long chan_hdl, struct __packed gsi_mhi_channel_scratch mscr) { 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_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 = __gsi_update_mhi_channel_scratch(chan_hdl, mscr); mutex_unlock(&ctx->mlock); return GSI_STATUS_SUCCESS; } EXPORT_SYMBOL(gsi_update_mhi_channel_scratch); int gsi_query_channel_db_addr(unsigned long chan_hdl, uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb) { Loading
drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +11 −5 Original line number Diff line number Diff line Loading @@ -1351,14 +1351,20 @@ static int ipa3_usb_request_xdci_channel( params->xfer_scratch.depcmd_low_addr; chan_params.chan_scratch.xdci.depcmd_hi_addr = params->xfer_scratch.depcmd_hi_addr; /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { chan_params.chan_scratch.xdci.outstanding_threshold = ((params->teth_prot == IPA_USB_MBIM) ? 1 : 2) * chan_params.chan_params.re_size; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) chan_params.chan_scratch.xdci.outstanding_threshold = 0; } /* max_outstanding_tre is set in ipa3_request_gsi_channel() */ result = ipa3_request_gsi_channel(&chan_params, out_params); if (result) { IPA_USB_ERR("failed to allocate GSI channel\n"); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_client.c +10 −4 Original line number Diff line number Diff line Loading @@ -823,11 +823,17 @@ int ipa3_request_gsi_channel(struct ipa_request_gsi_channel_params *params, memcpy(&ep->chan_scratch, ¶ms->chan_scratch, sizeof(union __packed gsi_channel_scratch)); /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { ep->chan_scratch.xdci.max_outstanding_tre = params->chan_params.re_size * gsi_ep_cfg_ptr->ipa_if_tlv; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) ep->chan_scratch.xdci.max_outstanding_tre = 0; } gsi_res = gsi_write_channel_scratch(ep->gsi_chan_hdl, params->chan_scratch); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +14 −9 Original line number Diff line number Diff line Loading @@ -3792,15 +3792,20 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in, goto fail_alloc_channel; memset(&ch_scratch, 0, sizeof(ch_scratch)); ch_scratch.gpi.max_outstanding_tre = gsi_ep_info->ipa_if_tlv * GSI_CHAN_RE_SIZE_16B; ch_scratch.gpi.outstanding_threshold = 2 * GSI_CHAN_RE_SIZE_16B; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { ch_scratch.gpi.max_outstanding_tre = 0; ch_scratch.gpi.outstanding_threshold = 0; } /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { ch_scratch.gpi.max_outstanding_tre = gsi_ep_info->ipa_if_tlv * GSI_CHAN_RE_SIZE_16B; ch_scratch.gpi.outstanding_threshold = 2 * GSI_CHAN_RE_SIZE_16B; } if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) ch_scratch.gpi.dl_nlo_channel = 0; result = gsi_write_channel_scratch(ep->gsi_chan_hdl, ch_scratch); if (result != GSI_STATUS_SUCCESS) { IPAERR("failed to write scratch %d\n", result); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c +19 −9 Original line number Diff line number Diff line Loading @@ -298,13 +298,18 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client, params->channel_context_addr + offsetof(struct ipa_mhi_ch_ctx, wp)); ch_scratch.mhi.assert_bit40 = params->assert_bit40; /* * Update scratch for MCS smart prefetch: * Starting IPA4.5, smart prefetch implemented by H/W. * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch * so keep the fields zero. */ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { ch_scratch.mhi.max_outstanding_tre = ep_cfg->ipa_if_tlv * ch_props.re_size; ch_scratch.mhi.outstanding_threshold = min(ep_cfg->ipa_if_tlv / 2, 8) * ch_props.re_size; if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { ch_scratch.mhi.max_outstanding_tre = 0; ch_scratch.mhi.outstanding_threshold = 0; } ch_scratch.mhi.oob_mod_threshold = 4; if (params->ch_ctx_host->brstmode == IPA_MHI_BURST_MODE_DEFAULT || Loading Loading @@ -564,8 +569,13 @@ int ipa3_mhi_resume_channels_internal(enum ipa_client_type client, * set polling mode bit to DB mode before * resuming the channel */ res = gsi_write_channel_scratch( ep->gsi_chan_hdl, ch_scratch); ch_scratch.mhi.polling_mode = IPA_MHI_POLLING_MODE_DB_MODE; /* Use GSI update API to not affect non-SWI fields * inside the scratch while in suspend-resume operation */ res = gsi_update_mhi_channel_scratch( ep->gsi_chan_hdl, ch_scratch.mhi); if (res) { IPA_MHI_ERR("write ch scratch fail %d\n" , res); Loading