Loading Documentation/devicetree/bindings/platform/msm/usb-bam.txt +6 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,10 @@ Optional properties : - qcom,usb-bam-override-threshold: If present then the default 512 byte threshold is overriden. This threshold configures the threshold value for Read/Write event generation by the BAM towards another BAM. - qcom,usb-bam-max-mbps-highspeed: max mbps in high speed connection for either rx or tx direction. - qcom,usb-bam-max-mbps-superspeed: max mbps in super speed connection for either rx or tx direction. Example USB BAM controller device node: Loading @@ -99,6 +103,8 @@ Example USB BAM controller device node: qcom,usb-bam-num-pipes = <16>; qcom,ignore-core-reset-ack; qcom,disable-clk-gating; qcom,usb-bam-max-mbps-highspeed = <400>; qcom,usb-bam-max-mbps-superspeed = <3600>; qcom,pipe0 { label = "hsusb-ipa-out-0"; Loading drivers/platform/msm/usb_bam.c +70 −7 Original line number Diff line number Diff line Loading @@ -2031,6 +2031,50 @@ void msm_bam_hsic_host_notify_on_resume(void) _msm_bam_host_notify_on_resume(HSIC_CTRL); } static int usb_bam_set_ipa_perf(enum usb_ctrl cur_bam, enum usb_bam_pipe_dir dir, enum usb_device_speed usb_connection_speed) { int ret; struct ipa_rm_perf_profile ipa_rm_perf_prof; struct msm_usb_bam_platform_data *pdata = ctx.usb_bam_pdev->dev.platform_data; if (usb_connection_speed == USB_SPEED_SUPER) ipa_rm_perf_prof.max_supported_bandwidth_mbps = pdata->max_mbps_superspeed; else /* Bam2Bam is supported only for SS and HS (HW limitation) */ ipa_rm_perf_prof.max_supported_bandwidth_mbps = pdata->max_mbps_highspeed; /* * Having a max mbps property in dtsi file is a must * for target with IPA capability. */ if (!ipa_rm_perf_prof.max_supported_bandwidth_mbps) { pr_err("%s: Max mbps is required for speed %d\n", __func__, usb_connection_speed); return -EINVAL; } if (dir == USB_TO_PEER_PERIPHERAL) { pr_debug("%s: vote ipa_perf resource=%d perf=%d mbps\n", __func__, ipa_rm_resource_prod[cur_bam], ipa_rm_perf_prof.max_supported_bandwidth_mbps); ret = ipa_rm_set_perf_profile(ipa_rm_resource_prod[cur_bam], &ipa_rm_perf_prof); } else { pr_debug("%s: vote ipa_perf resource=%d perf=%d mbps\n", __func__, ipa_rm_resource_cons[cur_bam], ipa_rm_perf_prof.max_supported_bandwidth_mbps); ret = ipa_rm_set_perf_profile(ipa_rm_resource_cons[cur_bam], &ipa_rm_perf_prof); } return ret; } int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params) { u8 idx; Loading Loading @@ -2061,13 +2105,6 @@ int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params) return -EINVAL; } pipe_connect = &usb_bam_connections[idx]; cur_bam = pipe_connect->bam_type; cur_mode = pipe_connect->bam_mode; bam2bam = (pdata->connections[idx].pipe_type == USB_BAM_PIPE_BAM2BAM); /* Set the BAM mode (host/device) according to connected pipe */ info[cur_bam].cur_bam_mode = pipe_connect->bam_mode; if (pipe_connect->enabled) { pr_err("%s: connection %d was already established\n", Loading @@ -2075,8 +2112,24 @@ int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params) return 0; } ret = usb_bam_set_ipa_perf(pipe_connect->bam_type, ipa_params->dir, ipa_params->usb_connection_speed); if (ret) { pr_err("%s: call to usb_bam_set_ipa_perf failed %d\n", __func__, ret); return ret; } pr_debug("%s: enter", __func__); cur_bam = pipe_connect->bam_type; cur_mode = pipe_connect->bam_mode; bam2bam = (pdata->connections[idx].pipe_type == USB_BAM_PIPE_BAM2BAM); /* Set the BAM mode (host/device) according to connected pipe */ info[cur_bam].cur_bam_mode = pipe_connect->bam_mode; if (cur_mode == USB_BAM_DEVICE) { mutex_lock(&info[cur_bam].suspend_resume_mutex); Loading Loading @@ -2800,6 +2853,16 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata( return NULL; } rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-highspeed", &pdata->max_mbps_highspeed); if (rc) pdata->max_mbps_highspeed = 0; rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-superspeed", &pdata->max_mbps_superspeed); if (rc) pdata->max_mbps_superspeed = 0; rc = of_property_read_u32(node, "qcom,usb-bam-fifo-baseaddr", &addr); if (rc) Loading drivers/usb/gadget/u_bam.c +8 −0 Original line number Diff line number Diff line Loading @@ -1079,6 +1079,11 @@ static void gbam2bam_connect_work(struct work_struct *w) if (dev && dev->cdev) gadget = dev->cdev->gadget; if (!gadget) { pr_err("%s: NULL gadget\n", __func__); return; } spin_lock_irqsave(&port->port_lock_ul, flags); spin_lock(&port->port_lock_dl); if (!port->port_usb) { Loading Loading @@ -1128,6 +1133,9 @@ static void gbam2bam_connect_work(struct work_struct *w) return; } } else if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { d->ipa_params.usb_connection_speed = gadget->speed; if (usb_bam_get_pipe_type(d->ipa_params.src_idx, &d->src_pipe_type) || usb_bam_get_pipe_type(d->ipa_params.dst_idx, Loading drivers/usb/gadget/u_bam_data.c +11 −1 Original line number Diff line number Diff line Loading @@ -659,7 +659,7 @@ static void bam2bam_data_connect_work(struct work_struct *w) struct teth_bridge_init_params teth_bridge_params; struct bam_data_ch_info *d = &port->data_ch; struct data_port *d_port = port->port_usb; struct usb_gadget *gadget = d_port->cdev->gadget; struct usb_gadget *gadget = NULL; u32 sps_params; int ret; unsigned long flags; Loading @@ -671,6 +671,14 @@ static void bam2bam_data_connect_work(struct work_struct *w) return; } if (d_port && d_port->cdev) gadget = d_port->cdev->gadget; if (!gadget) { pr_err("%s: NULL gadget\n", __func__); return; } spin_lock_irqsave(&port->port_lock_ul, flags); if (!port->port_usb) { spin_unlock_irqrestore(&port->port_lock_ul, flags); Loading Loading @@ -711,6 +719,8 @@ static void bam2bam_data_connect_work(struct work_struct *w) if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { d->ipa_params.usb_connection_speed = gadget->speed; if (d->dst_pipe_type != USB_BAM_PIPE_BAM2BAM) { pr_err("%s: no software preparation for DL not using bam2bam\n", __func__); Loading include/linux/usb_bam.h +35 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,34 @@ enum usb_bam_pipe_type { USB_BAM_MAX_PIPE_TYPES, }; /** * struct usb_bam_connect_ipa_params: Connect Bam pipe to IPA peer infromation. * @ src_idx: Source pipe index in usb bam pipes lists. * @ dst_idx: Destination pipe index in usb bam pipes lists. * @ src_pipe: The source pipe index in the sps level. * @ dst_pipe: The destination pipe index in the sps level. * @ keep_ipa_awake: When true, IPA will not be clock gated. * @ ipa_cons_ep_idx: The pipe index on the IPA peer bam side, consumer. * @ ipa_prod_ep_idx: The pipe index on the IPA peer bam side, producer. * @ prod_clnt_hdl: Producer client handle returned by IPA driver * @ cons_clnt_hdl: Consumer client handle returned by IPA driver * @ src_client: Source IPA client type. * @ dst_client: Destination IPA client type. * @ ipa_ep_cfg: Configuration of IPA end-point (see struct ipa_ep_cfg) * @priv: Callback cookie to the notify event. * @notify: Callback on data path event by IPA (see enum ipa_dp_evt_type) * This call back gets back the priv cookie. * for Bam2Bam mode, this callback is in the tethering bridge. * @ activity_notify: Callback to be notified on and data being pushed into the * USB consumer pipe. * @ inactivity_notify: Callback to be notified on inactivity of all the current * open pipes between the USB bam and its peer. * @ skip_ep_cfg: boolean field that determines if Apps-processor * should or should not confiugre this end-point. * (Please see struct teth_bridge_init_params) * @ reset_pipe_after_lpm: bool to indicate if IPA should reset pipe after LPM. * @ usb_connection_speed: The actual speed the USB core currently works at. */ struct usb_bam_connect_ipa_params { u8 src_idx; u8 dst_idx; Loading @@ -81,6 +109,7 @@ struct usb_bam_connect_ipa_params { int (*inactivity_notify)(void *priv); bool skip_ep_cfg; bool reset_pipe_after_lpm; enum usb_device_speed usb_connection_speed; }; /** Loading Loading @@ -177,6 +206,10 @@ struct usb_bam_pipe_connect { * @disable_clk_gating: Disable clock gating * @override_threshold: Override the default threshold value for Read/Write * event generation by the BAM towards another BAM. * @max_mbps_highspeed: Maximum Mbits per seconds that the USB core * can work at in bam2bam mode when connected to HS host. * @max_mbps_superspeed: Maximum Mbits per seconds that the USB core * can work at in bam2bam mode when connected to SS host. */ struct msm_usb_bam_platform_data { struct usb_bam_pipe_connect *connections; Loading @@ -187,6 +220,8 @@ struct msm_usb_bam_platform_data { bool reset_on_connect[MAX_BAMS]; bool disable_clk_gating; u32 override_threshold; u32 max_mbps_highspeed; u32 max_mbps_superspeed; }; #ifdef CONFIG_USB_BAM Loading Loading
Documentation/devicetree/bindings/platform/msm/usb-bam.txt +6 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,10 @@ Optional properties : - qcom,usb-bam-override-threshold: If present then the default 512 byte threshold is overriden. This threshold configures the threshold value for Read/Write event generation by the BAM towards another BAM. - qcom,usb-bam-max-mbps-highspeed: max mbps in high speed connection for either rx or tx direction. - qcom,usb-bam-max-mbps-superspeed: max mbps in super speed connection for either rx or tx direction. Example USB BAM controller device node: Loading @@ -99,6 +103,8 @@ Example USB BAM controller device node: qcom,usb-bam-num-pipes = <16>; qcom,ignore-core-reset-ack; qcom,disable-clk-gating; qcom,usb-bam-max-mbps-highspeed = <400>; qcom,usb-bam-max-mbps-superspeed = <3600>; qcom,pipe0 { label = "hsusb-ipa-out-0"; Loading
drivers/platform/msm/usb_bam.c +70 −7 Original line number Diff line number Diff line Loading @@ -2031,6 +2031,50 @@ void msm_bam_hsic_host_notify_on_resume(void) _msm_bam_host_notify_on_resume(HSIC_CTRL); } static int usb_bam_set_ipa_perf(enum usb_ctrl cur_bam, enum usb_bam_pipe_dir dir, enum usb_device_speed usb_connection_speed) { int ret; struct ipa_rm_perf_profile ipa_rm_perf_prof; struct msm_usb_bam_platform_data *pdata = ctx.usb_bam_pdev->dev.platform_data; if (usb_connection_speed == USB_SPEED_SUPER) ipa_rm_perf_prof.max_supported_bandwidth_mbps = pdata->max_mbps_superspeed; else /* Bam2Bam is supported only for SS and HS (HW limitation) */ ipa_rm_perf_prof.max_supported_bandwidth_mbps = pdata->max_mbps_highspeed; /* * Having a max mbps property in dtsi file is a must * for target with IPA capability. */ if (!ipa_rm_perf_prof.max_supported_bandwidth_mbps) { pr_err("%s: Max mbps is required for speed %d\n", __func__, usb_connection_speed); return -EINVAL; } if (dir == USB_TO_PEER_PERIPHERAL) { pr_debug("%s: vote ipa_perf resource=%d perf=%d mbps\n", __func__, ipa_rm_resource_prod[cur_bam], ipa_rm_perf_prof.max_supported_bandwidth_mbps); ret = ipa_rm_set_perf_profile(ipa_rm_resource_prod[cur_bam], &ipa_rm_perf_prof); } else { pr_debug("%s: vote ipa_perf resource=%d perf=%d mbps\n", __func__, ipa_rm_resource_cons[cur_bam], ipa_rm_perf_prof.max_supported_bandwidth_mbps); ret = ipa_rm_set_perf_profile(ipa_rm_resource_cons[cur_bam], &ipa_rm_perf_prof); } return ret; } int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params) { u8 idx; Loading Loading @@ -2061,13 +2105,6 @@ int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params) return -EINVAL; } pipe_connect = &usb_bam_connections[idx]; cur_bam = pipe_connect->bam_type; cur_mode = pipe_connect->bam_mode; bam2bam = (pdata->connections[idx].pipe_type == USB_BAM_PIPE_BAM2BAM); /* Set the BAM mode (host/device) according to connected pipe */ info[cur_bam].cur_bam_mode = pipe_connect->bam_mode; if (pipe_connect->enabled) { pr_err("%s: connection %d was already established\n", Loading @@ -2075,8 +2112,24 @@ int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params) return 0; } ret = usb_bam_set_ipa_perf(pipe_connect->bam_type, ipa_params->dir, ipa_params->usb_connection_speed); if (ret) { pr_err("%s: call to usb_bam_set_ipa_perf failed %d\n", __func__, ret); return ret; } pr_debug("%s: enter", __func__); cur_bam = pipe_connect->bam_type; cur_mode = pipe_connect->bam_mode; bam2bam = (pdata->connections[idx].pipe_type == USB_BAM_PIPE_BAM2BAM); /* Set the BAM mode (host/device) according to connected pipe */ info[cur_bam].cur_bam_mode = pipe_connect->bam_mode; if (cur_mode == USB_BAM_DEVICE) { mutex_lock(&info[cur_bam].suspend_resume_mutex); Loading Loading @@ -2800,6 +2853,16 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata( return NULL; } rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-highspeed", &pdata->max_mbps_highspeed); if (rc) pdata->max_mbps_highspeed = 0; rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-superspeed", &pdata->max_mbps_superspeed); if (rc) pdata->max_mbps_superspeed = 0; rc = of_property_read_u32(node, "qcom,usb-bam-fifo-baseaddr", &addr); if (rc) Loading
drivers/usb/gadget/u_bam.c +8 −0 Original line number Diff line number Diff line Loading @@ -1079,6 +1079,11 @@ static void gbam2bam_connect_work(struct work_struct *w) if (dev && dev->cdev) gadget = dev->cdev->gadget; if (!gadget) { pr_err("%s: NULL gadget\n", __func__); return; } spin_lock_irqsave(&port->port_lock_ul, flags); spin_lock(&port->port_lock_dl); if (!port->port_usb) { Loading Loading @@ -1128,6 +1133,9 @@ static void gbam2bam_connect_work(struct work_struct *w) return; } } else if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { d->ipa_params.usb_connection_speed = gadget->speed; if (usb_bam_get_pipe_type(d->ipa_params.src_idx, &d->src_pipe_type) || usb_bam_get_pipe_type(d->ipa_params.dst_idx, Loading
drivers/usb/gadget/u_bam_data.c +11 −1 Original line number Diff line number Diff line Loading @@ -659,7 +659,7 @@ static void bam2bam_data_connect_work(struct work_struct *w) struct teth_bridge_init_params teth_bridge_params; struct bam_data_ch_info *d = &port->data_ch; struct data_port *d_port = port->port_usb; struct usb_gadget *gadget = d_port->cdev->gadget; struct usb_gadget *gadget = NULL; u32 sps_params; int ret; unsigned long flags; Loading @@ -671,6 +671,14 @@ static void bam2bam_data_connect_work(struct work_struct *w) return; } if (d_port && d_port->cdev) gadget = d_port->cdev->gadget; if (!gadget) { pr_err("%s: NULL gadget\n", __func__); return; } spin_lock_irqsave(&port->port_lock_ul, flags); if (!port->port_usb) { spin_unlock_irqrestore(&port->port_lock_ul, flags); Loading Loading @@ -711,6 +719,8 @@ static void bam2bam_data_connect_work(struct work_struct *w) if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { d->ipa_params.usb_connection_speed = gadget->speed; if (d->dst_pipe_type != USB_BAM_PIPE_BAM2BAM) { pr_err("%s: no software preparation for DL not using bam2bam\n", __func__); Loading
include/linux/usb_bam.h +35 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,34 @@ enum usb_bam_pipe_type { USB_BAM_MAX_PIPE_TYPES, }; /** * struct usb_bam_connect_ipa_params: Connect Bam pipe to IPA peer infromation. * @ src_idx: Source pipe index in usb bam pipes lists. * @ dst_idx: Destination pipe index in usb bam pipes lists. * @ src_pipe: The source pipe index in the sps level. * @ dst_pipe: The destination pipe index in the sps level. * @ keep_ipa_awake: When true, IPA will not be clock gated. * @ ipa_cons_ep_idx: The pipe index on the IPA peer bam side, consumer. * @ ipa_prod_ep_idx: The pipe index on the IPA peer bam side, producer. * @ prod_clnt_hdl: Producer client handle returned by IPA driver * @ cons_clnt_hdl: Consumer client handle returned by IPA driver * @ src_client: Source IPA client type. * @ dst_client: Destination IPA client type. * @ ipa_ep_cfg: Configuration of IPA end-point (see struct ipa_ep_cfg) * @priv: Callback cookie to the notify event. * @notify: Callback on data path event by IPA (see enum ipa_dp_evt_type) * This call back gets back the priv cookie. * for Bam2Bam mode, this callback is in the tethering bridge. * @ activity_notify: Callback to be notified on and data being pushed into the * USB consumer pipe. * @ inactivity_notify: Callback to be notified on inactivity of all the current * open pipes between the USB bam and its peer. * @ skip_ep_cfg: boolean field that determines if Apps-processor * should or should not confiugre this end-point. * (Please see struct teth_bridge_init_params) * @ reset_pipe_after_lpm: bool to indicate if IPA should reset pipe after LPM. * @ usb_connection_speed: The actual speed the USB core currently works at. */ struct usb_bam_connect_ipa_params { u8 src_idx; u8 dst_idx; Loading @@ -81,6 +109,7 @@ struct usb_bam_connect_ipa_params { int (*inactivity_notify)(void *priv); bool skip_ep_cfg; bool reset_pipe_after_lpm; enum usb_device_speed usb_connection_speed; }; /** Loading Loading @@ -177,6 +206,10 @@ struct usb_bam_pipe_connect { * @disable_clk_gating: Disable clock gating * @override_threshold: Override the default threshold value for Read/Write * event generation by the BAM towards another BAM. * @max_mbps_highspeed: Maximum Mbits per seconds that the USB core * can work at in bam2bam mode when connected to HS host. * @max_mbps_superspeed: Maximum Mbits per seconds that the USB core * can work at in bam2bam mode when connected to SS host. */ struct msm_usb_bam_platform_data { struct usb_bam_pipe_connect *connections; Loading @@ -187,6 +220,8 @@ struct msm_usb_bam_platform_data { bool reset_on_connect[MAX_BAMS]; bool disable_clk_gating; u32 override_threshold; u32 max_mbps_highspeed; u32 max_mbps_superspeed; }; #ifdef CONFIG_USB_BAM Loading