Loading drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +29 −90 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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: Loading Loading @@ -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: Loading Loading @@ -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. */ Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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: Loading drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +2 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,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) Loading Loading @@ -5986,6 +5986,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; Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +29 −90 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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: Loading Loading @@ -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: Loading Loading @@ -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. */ Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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: Loading
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +2 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,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) Loading Loading @@ -5986,6 +5986,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; Loading