Merge "msm:ipa : enable HOLB drop timeout on MHIP producer channels"

This commit is contained in:
qctecmdr 2019-09-21 01:47:47 -07:00 • committed by Gerrit - the friendly Code Review server
commit a6ae3f7c81
2 changed files with 31 additions and 91 deletions

View file

@ -70,7 +70,7 @@
#define IPA_POLL_FOR_EMPTINESS_SLEEP_USEC 20
#define IPA_CHANNEL_STOP_IN_PROC_TO_MSEC 5
#define IPA_CHANNEL_STOP_IN_PROC_SLEEP_USEC 200
#define IPA_MHIP_HOLB_TMO 31 /* value to match granularity on ipa HW 4.5 */
enum mhip_re_type {
MHIP_RE_XFER = 0x2,
MHIP_RE_NOP = 0x4,
@ -424,8 +424,6 @@ static void ipa_mpm_change_teth_state(int probe_id,
static void ipa_mpm_change_gsi_state(int probe_id,
enum ipa_mpm_mhip_chan mhip_chan,
enum ipa_mpm_gsi_state next_state);
static int ipa_mpm_start_stop_ul_mhip_data_path(int probe_id,
enum ipa_mpm_start_stop_type start);
static int ipa_mpm_probe(struct platform_device *pdev);
static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote,
int probe_id);
@ -435,6 +433,7 @@ static enum mhip_status_type ipa_mpm_start_stop_mhip_chan(
enum ipa_mpm_mhip_chan mhip_chan,
int probe_id,
enum ipa_mpm_start_stop_type start_stop);
static int ipa_mpm_start_mhip_holb_tmo(u32 clnt_hdl);
static struct mhi_driver mhi_driver = {
.id_table = mhi_driver_match_table,
@ -500,6 +499,17 @@ static int ipa_mpm_set_dma_mode(enum ipa_client_type src_pipe,
return result;
}
static int ipa_mpm_start_mhip_holb_tmo(u32 clnt_hdl)
{
struct ipa_ep_cfg_holb holb_cfg;
memset(&holb_cfg, 0, sizeof(holb_cfg));
holb_cfg.en = IPA_HOLB_TMR_EN;
/* 31 ms timer, which is less than tag timeout */
holb_cfg.tmr_val = IPA_MHIP_HOLB_TMO;
return ipa3_cfg_ep_holb(clnt_hdl, &holb_cfg);
}
/**
* ipa_mpm_smmu_map() - SMMU maps ring and the buffer pointer.
* @va_addr: virtual address that needs to be mapped
@ -1034,6 +1044,21 @@ static int ipa_mpm_connect_mhip_gsi_pipe(enum ipa_client_type mhip_client,
goto fail_alloc_channel;
}
if (IPA_CLIENT_IS_CONS(mhip_client)) {
/*
* Enable HOLB timer one time after bootup/SSR.
* The HOLB timeout drops the packets on MHIP if
* there is a stall on MHIP TX pipe greater than
* configured timeout.
*/
result = ipa_mpm_start_mhip_holb_tmo(ipa_ep_idx);
if (result) {
IPA_MPM_ERR("HOLB config failed for %d, fail = %d\n",
ipa_ep_idx, result);
goto fail_alloc_channel;
}
}
if (IPA_CLIENT_IS_PROD(mhip_client))
ipa_mpm_change_gsi_state(mhi_idx,
IPA_MPM_MHIP_CHAN_DL,
@ -1326,11 +1351,9 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx)
get_ipa3_client(mhip_idx, &ul_prod_chan, &dl_cons_chan);
if (mhip_idx != IPA_MPM_MHIP_CH_ID_2) {
if (mhip_idx != IPA_MPM_MHIP_CH_ID_2)
/* For DPL, stop only DL channel */
ipa_mpm_start_stop_ul_mhip_data_path(mhip_idx, MPM_MHIP_STOP);
ipa_mpm_clean_mhip_chan(mhip_idx, ul_prod_chan);
}
ipa_mpm_clean_mhip_chan(mhip_idx, dl_cons_chan);
@ -1713,13 +1736,6 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state)
case MHIP_STATUS_SUCCESS:
ipa_mpm_ctx->md[probe_id].teth_state =
IPA_MPM_TETH_CONNECTED;
ret = ipa_mpm_start_stop_ul_mhip_data_path(
probe_id, MPM_MHIP_START);
if (ret) {
IPA_MPM_ERR("UL chan start err = %d\n", ret);
ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id);
return ret;
}
break;
case MHIP_STATUS_EP_NOT_READY:
case MHIP_STATUS_NO_OP:
@ -1767,8 +1783,6 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state)
switch (status) {
case MHIP_STATUS_SUCCESS:
ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INIT);
ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
MPM_MHIP_STOP);
break;
case MHIP_STATUS_NO_OP:
case MHIP_STATUS_EP_NOT_READY:
@ -1881,64 +1895,6 @@ static void ipa_mpm_read_channel(enum ipa_client_type chan)
IPA_MPM_ERR("Reading of channel failed for ep %d\n", ep);
}
static int ipa_mpm_start_stop_ul_mhip_data_path(int probe_id,
enum ipa_mpm_start_stop_type start)
{
int ipa_ep_idx;
int res = 0;
enum ipa_client_type ul_chan, dl_chan;
if (probe_id >= IPA_MPM_MHIP_CH_ID_MAX) {
IPA_MPM_ERR("Unknown probe_id\n");
return 0;
}
get_ipa3_client(probe_id, &ul_chan, &dl_chan);
IPA_MPM_DBG("Start/Stop Data Path ? = %d\n", start);
/* MHIP Start Data path:
* IPA MHIP Producer: remove HOLB
* IPA MHIP Consumer : no op as there is no delay on these pipes.
*/
if (start) {
IPA_MPM_DBG("Enabling data path\n");
if (ul_chan != IPA_CLIENT_MAX) {
/* Remove HOLB on the producer pipe */
IPA_MPM_DBG("Removing HOLB on ep = %s\n",
__stringify(ul_chan));
ipa_ep_idx = ipa3_get_ep_mapping(ul_chan);
if (ipa_ep_idx == IPA_EP_NOT_ALLOCATED) {
IPAERR("failed to get idx");
return ipa_ep_idx;
}
res = ipa3_enable_data_path(ipa_ep_idx);
if (res)
IPA_MPM_ERR("Enable data path failed res=%d\n",
res);
}
} else {
IPA_MPM_DBG("Disabling data path\n");
if (ul_chan != IPA_CLIENT_MAX) {
/* Set HOLB on the producer pipe */
ipa_ep_idx = ipa3_get_ep_mapping(ul_chan);
if (ipa_ep_idx == IPA_EP_NOT_ALLOCATED) {
IPAERR("failed to get idx");
return ipa_ep_idx;
}
res = ipa3_disable_data_path(ipa_ep_idx);
if (res)
IPA_MPM_ERR("disable data path failed res=%d\n",
res);
}
}
return res;
}
/* ipa_mpm_mhi_probe_cb is received for each MHI'/MHI channel
* Currently we have 4 MHI channels.
*/
@ -2294,12 +2250,6 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev,
/* No teth started yet, disable UL channel */
ipa_mpm_start_stop_mhip_chan(IPA_MPM_MHIP_CHAN_UL,
probe_id, MPM_MHIP_STOP);
/* Disable data path */
if (ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
MPM_MHIP_STOP)) {
IPA_MPM_ERR("MHIP Enable data path failed\n");
goto fail_start_channel;
}
}
ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id);
break;
@ -2308,14 +2258,6 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev,
IPA_MPM_DBG("UL channel is already started, continue\n");
ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_CONNECTED);
/* Enable data path */
if (ul_prod != IPA_CLIENT_MAX) {
if (ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
MPM_MHIP_START)) {
IPA_MPM_ERR("MHIP Enable data path failed\n");
goto fail_start_channel;
}
}
/* Lift the delay for rmnet USB prod pipe */
if (probe_id == IPA_MPM_MHIP_CH_ID_1) {
pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
@ -2596,8 +2538,6 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot)
case MHIP_STATUS_SUCCESS:
case MHIP_STATUS_NO_OP:
ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_CONNECTED);
ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
MPM_MHIP_START);
pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
@ -2717,7 +2657,6 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot)
case MHIP_STATUS_NO_OP:
case MHIP_STATUS_EP_NOT_READY:
ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INIT);
ipa_mpm_start_stop_ul_mhip_data_path(probe_id, MPM_MHIP_STOP);
break;
case MHIP_STATUS_FAIL:
case MHIP_STATUS_BAD_STATE:

View file

@ -38,7 +38,7 @@
#define IPA_V4_0_CLK_RATE_NOMINAL (220 * 1000 * 1000UL)
#define IPA_V4_0_CLK_RATE_TURBO (250 * 1000 * 1000UL)
#define IPA_V3_0_MAX_HOLB_TMR_VAL (4294967296 - 1)
#define IPA_MAX_HOLB_TMR_VAL (4294967296 - 1)
#define IPA_V3_0_BW_THRESHOLD_TURBO_MBPS (1000)
#define IPA_V3_0_BW_THRESHOLD_NOMINAL_MBPS (600)
@ -5985,6 +5985,7 @@ int ipa3_controller_static_bind(struct ipa3_controller *ctrl,
ctrl->ipa_init_sram = _ipa_init_sram_v3;
ctrl->ipa_sram_read_settings = _ipa_sram_settings_read_v3_0;
ctrl->ipa_init_hdr = _ipa_init_hdr_v3_0;
ctrl->max_holb_tmr_val = IPA_MAX_HOLB_TMR_VAL;
if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
ctrl->ipa3_read_ep_reg = _ipa_read_ep_reg_v4_0;