/* Copyright (c) 2011-2017, 2019-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef _USB_BAM_H_ #define _USB_BAM_H_ #include #include #include #include #include #include #define MAX_BAMS NUM_CTRL /* Bam per USB controllers */ /* Supported USB controllers*/ enum usb_ctrl { DWC3_CTRL = 0, /* DWC3 controller */ CI_CTRL, /* ChipIdea controller */ HSIC_CTRL, /* HSIC controller */ NUM_CTRL, }; enum usb_bam_mode { USB_BAM_DEVICE = 0, USB_BAM_HOST, }; enum peer_bam { QDSS_P_BAM = 0, IPA_P_BAM, MAX_PEER_BAMS, }; enum usb_bam_pipe_dir { USB_TO_PEER_PERIPHERAL, PEER_PERIPHERAL_TO_USB, }; enum usb_pipe_mem_type { SPS_PIPE_MEM = 0, /* Default, SPS dedicated pipe memory */ SYSTEM_MEM, /* System RAM, requires allocation */ OCI_MEM, /* Shared memory among peripherals */ }; enum usb_bam_pipe_type { USB_BAM_PIPE_BAM2BAM = 0, /* Connection is BAM2BAM (default) */ USB_BAM_PIPE_SYS2BAM, /* Connection is SYS2BAM or BAM2SYS * depending on usb_bam_pipe_dir */ USB_BAM_MAX_PIPE_TYPES, }; /* * struct usb_bam_connect_ipa_params: Connect Bam pipe to IPA peer information. * @ 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; u32 *src_pipe; u32 *dst_pipe; bool keep_ipa_awake; enum usb_bam_pipe_dir dir; /* Parameters for Port Mapper */ u32 ipa_cons_ep_idx; u32 ipa_prod_ep_idx; /* client handle assigned by IPA to client */ u32 prod_clnt_hdl; u32 cons_clnt_hdl; /* params assigned by the CD */ enum ipa_client_type src_client; enum ipa_client_type dst_client; struct ipa_ep_cfg ipa_ep_cfg; void *priv; void (*notify)(void *priv, enum ipa_dp_evt_type evt, unsigned long data); int (*activity_notify)(void *priv); int (*inactivity_notify)(void *priv); bool skip_ep_cfg; bool reset_pipe_after_lpm; enum usb_device_speed usb_connection_speed; }; #if IS_ENABLED(CONFIG_USB_BAM) /** * Connect USB-to-Peripheral SPS connection. * * This function returns the allocated pipe number. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @idx - Connection index. * * @bam_pipe_idx - allocated pipe index. * * @iova - IPA address of USB peer BAM (i.e. QDSS BAM) * * @return 0 on success, negative value on error * */ int usb_bam_connect(enum usb_ctrl bam_type, int idx, u32 *bam_pipe_idx, unsigned long iova); /** * Connect USB-to-IPA SPS connection. * * This function returns the allocated pipes number and clnt * handles. Assumes that the user first connects producer pipes * and only after that consumer pipes, since that's the correct * sequence for the handshake with the IPA. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @ipa_params - in/out parameters * * @return 0 on success, negative value on error */ int usb_bam_connect_ipa(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params); /** * Disconnect USB-to-IPA SPS connection. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @ipa_params - in/out parameters * * @return 0 on success, negative value on error */ int usb_bam_disconnect_ipa(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params); /** * Register a wakeup callback from peer BAM. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @idx - Connection index. * * @callback - the callback function * * @return 0 on success, negative value on error */ int usb_bam_register_wake_cb(enum usb_ctrl bam_type, u8 idx, int (*callback)(void *), void *param); /** * Register callbacks for start/stop of transfers. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @idx - Connection index * * @start - the callback function that will be called in USB * driver to start transfers * @stop - the callback function that will be called in USB * driver to stop transfers * * @param - context that the caller can supply * * @return 0 on success, negative value on error */ int usb_bam_register_start_stop_cbs(enum usb_ctrl bam_type, u8 idx, void (*start)(void *, enum usb_bam_pipe_dir), void (*stop)(void *, enum usb_bam_pipe_dir), void *param); /** * Start usb suspend sequence * * @ipa_params - in/out parameters * * @bam_type - USB BAM type - dwc3/CI/hsic */ void usb_bam_suspend(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params); /** * Start usb resume sequence * * @bam_type - USB BAM type - dwc3/CI/hsic * * @ipa_params - in/out parameters */ void usb_bam_resume(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params); /** * Disconnect USB-to-Periperal SPS connection. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @idx - Connection index. * * @return 0 on success, negative value on error */ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx); /** * Returns usb bam connection parameters. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @idx - Connection index. * * @usb_bam_pipe_idx - Usb bam pipe index. * * @desc_fifo - Descriptor fifo parameters. * * @data_fifo - Data fifo parameters. * * @return pipe index on success, negative value on error. */ int get_bam2bam_connection_info(enum usb_ctrl bam_type, u8 idx, u32 *usb_bam_pipe_idx, struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type); /** * Returns usb bam connection parameters for qdss pipe. * @usb_bam_handle - Usb bam handle. * @usb_bam_pipe_idx - Usb bam pipe index. * @peer_pipe_idx - Peer pipe index. * @desc_fifo - Descriptor fifo parameters. * @data_fifo - Data fifo parameters. * @return pipe index on success, negative value on error. */ int get_qdss_bam_connection_info( unsigned long *usb_bam_handle, u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx, struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type); /* * Indicates if the client of the USB BAM is ready to start * sending/receiving transfers. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @client - Usb pipe peer (a2, ipa, qdss...) * * @dir - In (from peer to usb) or out (from usb to peer) * * @num - Pipe number. * * @return 0 on success, negative value on error */ int usb_bam_get_connection_idx(enum usb_ctrl bam_type, enum peer_bam client, enum usb_bam_pipe_dir dir, u32 num); /* * return the usb controller bam type used for the supplied connection index * * @core_name - Core name (ssusb/hsusb/hsic). * * @return usb control bam type */ enum usb_ctrl usb_bam_get_bam_type(const char *core_name); /* * Indicates the type of connection the USB side of the connection is. * * @bam_type - USB BAM type - dwc3/CI/hsic * * @idx - Pipe number. * * @type - Type of connection * * @return 0 on success, negative value on error */ int usb_bam_get_pipe_type(enum usb_ctrl bam_type, u8 idx, enum usb_bam_pipe_type *type); /* * Indicates whether USB producer is granted to IPA resource manager. * * @return true when producer granted, false when prodcuer is released. */ bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx); /* Allocates memory for data fifo and descriptor fifos. */ int usb_bam_alloc_fifos(enum usb_ctrl cur_bam, u8 idx); /* Frees memory for data fifo and descriptor fifos. */ int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx); int get_qdss_bam_info(enum usb_ctrl cur_bam, u8 idx, phys_addr_t *p_addr, u32 *bam_size); bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable); void msm_bam_set_hsic_host_dev(struct device *dev); bool msm_bam_hsic_lpm_ok(void); void msm_bam_hsic_host_notify_on_resume(void); void msm_bam_wait_for_hsic_host_prod_granted(void); bool msm_bam_hsic_host_pipe_empty(void); #else static inline int usb_bam_connect(enum usb_ctrl bam, u8 idx, u32 *bam_pipe_idx, unsigned long iova) { return -ENODEV; } static inline int usb_bam_connect_ipa(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params) { return -ENODEV; } static inline int usb_bam_disconnect_ipa(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params) { return -ENODEV; } static inline int usb_bam_register_wake_cb(enum usb_ctrl bam_type, u8 idx, int (*callback)(void *), void *param) { return -ENODEV; } static inline int usb_bam_register_start_stop_cbs(enum usb_ctrl bam, u8 idx, void (*start)(void *, enum usb_bam_pipe_dir), void (*stop)(void *, enum usb_bam_pipe_dir), void *param) { return -ENODEV; } static inline void usb_bam_suspend(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params){} static inline void usb_bam_resume(enum usb_ctrl bam_type, struct usb_bam_connect_ipa_params *ipa_params) {} static inline int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx) { return -ENODEV; } static inline int get_bam2bam_connection_info(enum usb_ctrl bam_type, u8 idx, u32 *usb_bam_pipe_idx, struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type) { return -ENODEV; } static inline int get_qdss_bam_connection_info( unsigned long *usb_bam_handle, u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx, struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type) { return -ENODEV; } static inline int usb_bam_get_connection_idx(enum usb_ctrl bam_type, enum peer_bam client, enum usb_bam_pipe_dir dir, u32 num) { return -ENODEV; } static inline enum usb_ctrl usb_bam_get_bam_type(const char *core_nam) { return -ENODEV; } static inline int usb_bam_get_pipe_type(enum usb_ctrl bam_type, u8 idx, enum usb_bam_pipe_type *type) { return -ENODEV; } static inline bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx) { return false; } static inline int usb_bam_alloc_fifos(enum usb_ctrl cur_bam, u8 idx) { return false; } static inline int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx) { return false; } static inline int get_qdss_bam_info(enum usb_ctrl cur_bam, u8 idx, phys_addr_t *p_addr, u32 *bam_size) { return false; } static inline bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable) { return true; } static inline void msm_bam_set_hsic_host_dev(struct device *dev) {} static inline bool msm_bam_hsic_lpm_ok(void) { return false; } static inline void msm_bam_hsic_host_notify_on_resume(void) {} static inline void msm_bam_wait_for_hsic_host_prod_granted(void) {} static inline bool msm_bam_hsic_host_pipe_empty(void) { return false; } #endif /* CONFIG_PM */ #ifdef CONFIG_PM static inline int get_pm_runtime_counter(struct device *dev) { return atomic_read(&dev->power.usage_count); } #else /* !CONFIG_PM */ static inline int get_pm_runtime_counter(struct device *dev) { return -EOPNOTSUPP; } #endif #ifdef CONFIG_USB_CI13XXX_MSM void msm_hw_bam_disable(bool bam_disable); #else static inline void msm_hw_bam_disable(bool bam_disable) { } #endif #endif /* _USB_BAM_H_ */