| // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) |
| /* |
| * Copyright (C) 2004-2013 Synopsys, Inc. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions, and the following disclaimer, |
| * without modification. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. The names of the above-listed copyright holders may not be used |
| * to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * ALTERNATIVELY, this software may be distributed under the terms of the |
| * GNU General Public License ("GPL") as published by the Free Software |
| * Foundation; either version 2 of the License, or (at your option) any |
| * later version. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
| * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef __DWC2_CORE_H__ |
| #define __DWC2_CORE_H__ |
| #include "diag_USB.h" |
| #include "hw.h" |
| #include <stddef.h> |
| #include "usb_typedefs.h" |
| #include "ch9.h" |
| #include "core.h" |
| |
| #define ACPU_MEMMAP_USBAHB_REG_BASE MEMMAP_USB0_REG_BASE |
| #define MAX_DEVICE 16 |
| /* Maximum number of Endpoints/HostChannels */ |
| #define MAX_EPS_CHANNELS 16 |
| |
| |
| /* Create various pipes... */ |
| #define create_pipe(dev,endpoint) \ |
| (((dev)->devnum << 8) | ((endpoint) << 15) | \ |
| (dev)->maxpacketsize) |
| #define default_pipe(dev) ((dev)->speed << 26) |
| |
| #define usb_sndctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \ |
| create_pipe(dev, endpoint)) |
| #define usb_rcvctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \ |
| create_pipe(dev, endpoint) | \ |
| USB_DIR_IN) |
| #define usb_sndisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \ |
| create_pipe(dev, endpoint)) |
| #define usb_rcvisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \ |
| create_pipe(dev, endpoint) | \ |
| USB_DIR_IN) |
| #define usb_sndbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \ |
| create_pipe(dev, endpoint)) |
| #define usb_rcvbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \ |
| create_pipe(dev, endpoint) | \ |
| USB_DIR_IN) |
| #define usb_sndintpipe(dev, endpoint) ((PIPE_INTERRUPT << 30) | \ |
| create_pipe(dev, endpoint)) |
| #define usb_rcvintpipe(dev, endpoint) ((PIPE_INTERRUPT << 30) | \ |
| create_pipe(dev, endpoint) | \ |
| USB_DIR_IN) |
| #define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | \ |
| default_pipe(dev)) |
| #define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | \ |
| default_pipe(dev) | \ |
| USB_DIR_IN) |
| |
| /* Endpoint halt control/status */ |
| #define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1) |
| #define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep))) |
| #define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep))) |
| #define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep))) |
| #define usb_pipeout(pipe) ((((pipe) >> 7) & 1) ^ 1) |
| #define usb_pipein(pipe) (((pipe) >> 7) & 1) |
| #define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f) |
| #define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff) |
| #define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf) |
| #define usb_pipedata(pipe) (((pipe) >> 19) & 1) |
| #define usb_pipetype(pipe) (((pipe) >> 30) & 3) |
| #define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS) |
| #define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT) |
| #define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL) |
| #define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK) |
| |
| /** |
| * struct dwc2_hw_params - Autodetected parameters. |
| * |
| * These parameters are the various parameters read from hardware |
| * registers during initialization. They typically contain the best |
| * supported or maximum value that can be configured in the |
| * corresponding dwc2_core_params value. |
| * |
| * The values that are not in dwc2_core_params are documented below. |
| * |
| * @op_mode: Mode of Operation |
| * 0 - HNP- and SRP-Capable OTG (Host & Device) |
| * 1 - SRP-Capable OTG (Host & Device) |
| * 2 - Non-HNP and Non-SRP Capable OTG (Host & Device) |
| * 3 - SRP-Capable Device |
| * 4 - Non-OTG Device |
| * 5 - SRP-Capable Host |
| * 6 - Non-OTG Host |
| * @arch: Architecture |
| * 0 - Slave only |
| * 1 - External DMA |
| * 2 - Internal DMA |
| * @ipg_isoc_en: This feature indicates that the controller supports |
| * the worst-case scenario of Rx followed by Rx |
| * Interpacket Gap (IPG) (32 bitTimes) as per the utmi |
| * specification for any token following ISOC OUT token. |
| * 0 - Don't support |
| * 1 - Support |
| * @power_optimized: Are power optimizations enabled? |
| * @num_dev_ep: Number of device endpoints available |
| * @num_dev_in_eps: Number of device IN endpoints available |
| * @num_dev_perio_in_ep: Number of device periodic IN endpoints |
| * available |
| * @dev_token_q_depth: Device Mode IN Token Sequence Learning Queue |
| * Depth |
| * 0 to 30 |
| * @host_perio_tx_q_depth: |
| * Host Mode Periodic Request Queue Depth |
| * 2, 4 or 8 |
| * @nperio_tx_q_depth: |
| * Non-Periodic Request Queue Depth |
| * 2, 4 or 8 |
| * @hs_phy_type: High-speed PHY interface type |
| * 0 - High-speed interface not supported |
| * 1 - UTMI+ |
| * 2 - ULPI |
| * 3 - UTMI+ and ULPI |
| * @fs_phy_type: Full-speed PHY interface type |
| * 0 - Full speed interface not supported |
| * 1 - Dedicated full speed interface |
| * 2 - FS pins shared with UTMI+ pins |
| * 3 - FS pins shared with ULPI pins |
| * @total_fifo_size: Total internal RAM for FIFOs (bytes) |
| * @hibernation: Is hibernation enabled? |
| * @utmi_phy_data_width: UTMI+ PHY data width |
| * 0 - 8 bits |
| * 1 - 16 bits |
| * 2 - 8 or 16 bits |
| * @snpsid: Value from SNPSID register |
| * @dev_ep_dirs: Direction of device endpoints (GHWCFG1) |
| * @g_tx_fifo_size: Power-on values of TxFIFO sizes |
| * @dma_desc_enable: When DMA mode is enabled, specifies whether to use |
| * address DMA mode or descriptor DMA mode for accessing |
| * the data FIFOs. The driver will automatically detect the |
| * value for this if none is specified. |
| * 0 - Address DMA |
| * 1 - Descriptor DMA (default, if available) |
| * @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters |
| * 1 - Allow dynamic FIFO sizing (default, if available) |
| * @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs |
| * are enabled for non-periodic IN endpoints in device |
| * mode. |
| * @host_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO |
| * in host mode when dynamic FIFO sizing is enabled |
| * 16 to 32768 |
| * Actual maximum value is autodetected and also |
| * the default. |
| * @host_perio_tx_fifo_size: Number of 4-byte words in the periodic Tx FIFO in |
| * host mode when dynamic FIFO sizing is enabled |
| * 16 to 32768 |
| * Actual maximum value is autodetected and also |
| * the default. |
| * @max_transfer_size: The maximum transfer size supported, in bytes |
| * 2047 to 65,535 |
| * Actual maximum value is autodetected and also |
| * the default. |
| * @max_packet_count: The maximum number of packets in a transfer |
| * 15 to 511 |
| * Actual maximum value is autodetected and also |
| * the default. |
| * @host_channels: The number of host channel registers to use |
| * 1 to 16 |
| * Actual maximum value is autodetected and also |
| * the default. |
| * @dev_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO |
| * in device mode when dynamic FIFO sizing is enabled |
| * 16 to 32768 |
| * Actual maximum value is autodetected and also |
| * the default. |
| * @i2c_enable: Specifies whether to use the I2Cinterface for a full |
| * speed PHY. This parameter is only applicable if phy_type |
| * is FS. |
| * 0 - No (default) |
| * 1 - Yes |
| * @acg_enable: For enabling Active Clock Gating in the controller |
| * 0 - Disable |
| * 1 - Enable |
| * @lpm_mode: For enabling Link Power Management in the controller |
| * 0 - Disable |
| * 1 - Enable |
| * @rx_fifo_size: Number of 4-byte words in the Rx FIFO when dynamic |
| * FIFO sizing is enabled 16 to 32768 |
| * Actual maximum value is autodetected and also |
| * the default. |
| */ |
| struct dwc2_hw_params { |
| unsigned op_mode:3; |
| unsigned arch:2; |
| unsigned dma_desc_enable:1; |
| unsigned enable_dynamic_fifo:1; |
| unsigned en_multiple_tx_fifo:1; |
| unsigned rx_fifo_size:16; |
| unsigned host_nperio_tx_fifo_size:16; |
| unsigned dev_nperio_tx_fifo_size:16; |
| unsigned host_perio_tx_fifo_size:16; |
| unsigned nperio_tx_q_depth:3; |
| unsigned host_perio_tx_q_depth:3; |
| unsigned dev_token_q_depth:5; |
| unsigned max_transfer_size:26; |
| unsigned max_packet_count:11; |
| unsigned host_channels:5; |
| unsigned hs_phy_type:2; |
| unsigned fs_phy_type:2; |
| unsigned i2c_enable:1; |
| unsigned acg_enable:1; |
| unsigned num_dev_ep:4; |
| unsigned num_dev_in_eps : 4; |
| unsigned num_dev_perio_in_ep:4; |
| unsigned total_fifo_size:16; |
| unsigned power_optimized:1; |
| unsigned hibernation:1; |
| unsigned utmi_phy_data_width:2; |
| unsigned lpm_mode:1; |
| unsigned ipg_isoc_en:1; |
| u32 snpsid; |
| u32 dev_ep_dirs; |
| u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; |
| }; |
| |
| /** |
| * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic |
| * and periodic schedules |
| * |
| * These are common for both host and peripheral modes: |
| * |
| * @dev: The struct device pointer |
| * @regs: Pointer to controller regs |
| * @hw_params: Parameters that were autodetected from the |
| * hardware registers |
| * @params: Parameters that define how the core should be configured |
| * @op_state: The operational State, during transitions (a_host=> |
| * a_peripheral and b_device=>b_host) this may not match |
| * the core, but allows the software to determine |
| * transitions |
| * @dr_mode: Requested mode of operation, one of following: |
| * - USB_DR_MODE_PERIPHERAL |
| * - USB_DR_MODE_HOST |
| * - USB_DR_MODE_OTG |
| * @hcd_enabled: Host mode sub-driver initialization indicator. |
| * @gadget_enabled: Peripheral mode sub-driver initialization indicator. |
| * @ll_hw_enabled: Status of low-level hardware resources. |
| * @hibernated: True if core is hibernated |
| * @frame_number: Frame number read from the core. For both device |
| * and host modes. The value ranges are from 0 |
| * to HFNUM_MAX_FRNUM. |
| * @phy: The otg phy transceiver structure for phy control. |
| * @uphy: The otg phy transceiver structure for old USB phy |
| * control. |
| * @plat: The platform specific configuration data. This can be |
| * removed once all SoCs support usb transceiver. |
| * @supplies: Definition of USB power supplies |
| * @vbus_supply: Regulator supplying vbus. |
| * @phyif: PHY interface width |
| * @lock: Spinlock that protects all the driver data structures |
| * @priv: Stores a pointer to the struct usb_hcd |
| * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth |
| * transfer are in process of being queued |
| * @srp_success: Stores status of SRP request in the case of a FS PHY |
| * with an I2C interface |
| * @wq_otg: Workqueue object used for handling of some interrupts |
| * @wf_otg: Work object for handling Connector ID Status Change |
| * interrupt |
| * @wkp_timer: Timer object for handling Wakeup Detected interrupt |
| * @lx_state: Lx state of connected device |
| * @gr_backup: Backup of global registers during suspend |
| * @dr_backup: Backup of device registers during suspend |
| * @hr_backup: Backup of host registers during suspend |
| * @needs_byte_swap: Specifies whether the opposite endianness. |
| * |
| * These are for host mode: |
| * |
| * @flags: Flags for handling root port state changes |
| * @flags.d32: Contain all root port flags |
| * @flags.b: Separate root port flags from each other |
| * @flags.b.port_connect_status_change: True if root port connect status |
| * changed |
| * @flags.b.port_connect_status: True if device connected to root port |
| * @flags.b.port_reset_change: True if root port reset status changed |
| * @flags.b.port_enable_change: True if root port enable status changed |
| * @flags.b.port_suspend_change: True if root port suspend status changed |
| * @flags.b.port_over_current_change: True if root port over current state |
| * changed. |
| * @flags.b.port_l1_change: True if root port l1 status changed |
| * @flags.b.reserved: Reserved bits of root port register |
| * @non_periodic_sched_inactive: Inactive QHs in the non-periodic schedule. |
| * Transfers associated with these QHs are not currently |
| * assigned to a host channel. |
| * @non_periodic_sched_active: Active QHs in the non-periodic schedule. |
| * Transfers associated with these QHs are currently |
| * assigned to a host channel. |
| * @non_periodic_qh_ptr: Pointer to next QH to process in the active |
| * non-periodic schedule |
| * @non_periodic_sched_waiting: Waiting QHs in the non-periodic schedule. |
| * Transfers associated with these QHs are not currently |
| * assigned to a host channel. |
| * @periodic_sched_inactive: Inactive QHs in the periodic schedule. This is a |
| * list of QHs for periodic transfers that are _not_ |
| * scheduled for the next frame. Each QH in the list has an |
| * interval counter that determines when it needs to be |
| * scheduled for execution. This scheduling mechanism |
| * allows only a simple calculation for periodic bandwidth |
| * used (i.e. must assume that all periodic transfers may |
| * need to execute in the same frame). However, it greatly |
| * simplifies scheduling and should be sufficient for the |
| * vast majority of OTG hosts, which need to connect to a |
| * small number of peripherals at one time. Items move from |
| * this list to periodic_sched_ready when the QH interval |
| * counter is 0 at SOF. |
| * @periodic_sched_ready: List of periodic QHs that are ready for execution in |
| * the next frame, but have not yet been assigned to host |
| * channels. Items move from this list to |
| * periodic_sched_assigned as host channels become |
| * available during the current frame. |
| * @periodic_sched_assigned: List of periodic QHs to be executed in the next |
| * frame that are assigned to host channels. Items move |
| * from this list to periodic_sched_queued as the |
| * transactions for the QH are queued to the DWC_otg |
| * controller. |
| * @periodic_sched_queued: List of periodic QHs that have been queued for |
| * execution. Items move from this list to either |
| * periodic_sched_inactive or periodic_sched_ready when the |
| * channel associated with the transfer is released. If the |
| * interval for the QH is 1, the item moves to |
| * periodic_sched_ready because it must be rescheduled for |
| * the next frame. Otherwise, the item moves to |
| * periodic_sched_inactive. |
| * @split_order: List keeping track of channels doing splits, in order. |
| * @periodic_usecs: Total bandwidth claimed so far for periodic transfers. |
| * This value is in microseconds per (micro)frame. The |
| * assumption is that all periodic transfers may occur in |
| * the same (micro)frame. |
| * @hs_periodic_bitmap: Bitmap used by the microframe scheduler any time the |
| * host is in high speed mode; low speed schedules are |
| * stored elsewhere since we need one per TT. |
| * @periodic_qh_count: Count of periodic QHs, if using several eps. Used for |
| * SOF enable/disable. |
| * @free_hc_list: Free host channels in the controller. This is a list of |
| * struct dwc2_host_chan items. |
| * @periodic_channels: Number of host channels assigned to periodic transfers. |
| * Currently assuming that there is a dedicated host |
| * channel for each periodic transaction and at least one |
| * host channel is available for non-periodic transactions. |
| * @non_periodic_channels: Number of host channels assigned to non-periodic |
| * transfers |
| * @available_host_channels: Number of host channels available for the |
| * microframe scheduler to use |
| * @hc_ptr_array: Array of pointers to the host channel descriptors. |
| * Allows accessing a host channel descriptor given the |
| * host channel number. This is useful in interrupt |
| * handlers. |
| * @status_buf: Buffer used for data received during the status phase of |
| * a control transfer. |
| * @status_buf_dma: DMA address for status_buf |
| * @start_work: Delayed work for handling host A-cable connection |
| * @reset_work: Delayed work for handling a port reset |
| * @otg_port: OTG port number |
| * @frame_list: Frame list |
| * @frame_list_dma: Frame list DMA address |
| * @frame_list_sz: Frame list size |
| * @desc_gen_cache: Kmem cache for generic descriptors |
| * @desc_hsisoc_cache: Kmem cache for hs isochronous descriptors |
| * @unaligned_cache: Kmem cache for DMA mode to handle non-aligned buf |
| * |
| * These are for peripheral mode: |
| * |
| * @driver: USB gadget driver |
| * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. |
| * @num_of_eps: Number of available EPs (excluding EP0) |
| * @debug_root: Root directrory for debugfs. |
| * @ep0_reply: Request used for ep0 reply. |
| * @ep0_buff: Buffer for EP0 reply data, if needed. |
| * @ctrl_buff: Buffer for EP0 control requests. |
| * @ctrl_req: Request for EP0 control packets. |
| * @ep0_state: EP0 control transfers state |
| * @test_mode: USB test mode requested by the host |
| * @remote_wakeup_allowed: True if device is allowed to wake-up host by |
| * remote-wakeup signalling |
| * @setup_desc_dma: EP0 setup stage desc chain DMA address |
| * @setup_desc: EP0 setup stage desc chain pointer |
| * @ctrl_in_desc_dma: EP0 IN data phase desc chain DMA address |
| * @ctrl_in_desc: EP0 IN data phase desc chain pointer |
| * @ctrl_out_desc_dma: EP0 OUT data phase desc chain DMA address |
| * @ctrl_out_desc: EP0 OUT data phase desc chain pointer |
| * @irq: Interrupt request line number |
| * @clk: Pointer to otg clock |
| * @reset: Pointer to dwc2 reset controller |
| * @reset_ecc: Pointer to dwc2 optional reset controller in Stratix10. |
| * @regset: A pointer to a struct debugfs_regset32, which contains |
| * a pointer to an array of register definitions, the |
| * array size and the base address where the register bank |
| * is to be found. |
| * @bus_suspended: True if bus is suspended |
| * @last_frame_num: Number of last frame. Range from 0 to 32768 |
| * @frame_num_array: Used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is |
| * defined, for missed SOFs tracking. Array holds that |
| * frame numbers, which not equal to last_frame_num +1 |
| * @last_frame_num_array: Used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is |
| * defined, for missed SOFs tracking. |
| * If current_frame_number != last_frame_num+1 |
| * then last_frame_num added to this array |
| * @frame_num_idx: Actual size of frame_num_array and last_frame_num_array |
| * @dumped_frame_num_array: 1 - if missed SOFs frame numbers dumbed |
| * 0 - if missed SOFs frame numbers not dumbed |
| * @fifo_mem: Total internal RAM for FIFOs (bytes) |
| * @fifo_map: Each bit intend for concrete fifo. If that bit is set, |
| * then that fifo is used |
| * @gadget: Represents a usb slave device |
| * @connected: Used in slave mode. True if device connected with host |
| * @eps_in: The IN endpoints being supplied to the gadget framework |
| * @eps_out: The OUT endpoints being supplied to the gadget framework |
| * @new_connection: Used in host mode. True if there are new connected |
| * device |
| * @enabled: Indicates the enabling state of controller |
| * |
| */ |
| /* DWC OTG HW Release versions */ |
| #define DWC2_CORE_REV_2_71a 0x4f54271a |
| #define DWC2_CORE_REV_2_72a 0x4f54272a |
| #define DWC2_CORE_REV_2_80a 0x4f54280a |
| #define DWC2_CORE_REV_2_90a 0x4f54290a |
| #define DWC2_CORE_REV_2_91a 0x4f54291a |
| #define DWC2_CORE_REV_2_92a 0x4f54292a |
| #define DWC2_CORE_REV_2_94a 0x4f54294a |
| #define DWC2_CORE_REV_3_00a 0x4f54300a |
| #define DWC2_CORE_REV_3_10a 0x4f54310a |
| #define DWC2_CORE_REV_4_00a 0x4f54400a |
| #define DWC2_FS_IOT_REV_1_00a 0x5531100a |
| #define DWC2_HS_IOT_REV_1_00a 0x5532100a |
| |
| /* DWC OTG HW Core ID */ |
| #define DWC2_OTG_ID 0x4f540000 |
| #define DWC2_FS_IOT_ID 0x55310000 |
| #define DWC2_HS_IOT_ID 0x55320000 |
| |
| struct dwc2_hsotg { |
| uint8_t *aligned_buffer; |
| uint8_t *status_buffer; |
| u8 in_data_toggle[MAX_DEVICE][MAX_EPS_CHANNELS]; |
| u8 out_data_toggle[MAX_DEVICE][MAX_EPS_CHANNELS]; |
| struct dwc2_core_regs *regs; |
| u32 reg_base; |
| struct dwc2_hw_params hw_params; |
| int root_hub_devnum; |
| |
| /*from Linux start*/ |
| u8 otg_cap; |
| #define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0 |
| #define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1 |
| #define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2 |
| |
| u8 phy_type; |
| #define DWC2_PHY_TYPE_PARAM_FS 0 |
| #define DWC2_PHY_TYPE_PARAM_UTMI 1 |
| #define DWC2_PHY_TYPE_PARAM_ULPI 2 |
| |
| u8 speed; |
| #define DWC2_SPEED_PARAM_HIGH 0 |
| #define DWC2_SPEED_PARAM_FULL 1 |
| #define DWC2_SPEED_PARAM_LOW 2 |
| |
| u8 phy_utmi_width; |
| bool phy_ulpi_ddr; |
| bool phy_ulpi_ext_vbus; |
| bool enable_dynamic_fifo; |
| bool en_multiple_tx_fifo; |
| bool i2c_enable; |
| bool acg_enable; |
| bool ulpi_fs_ls; |
| bool ts_dline; |
| bool reload_ctl; |
| bool uframe_sched; |
| bool external_id_pin_ctl; |
| |
| int power_down; |
| #define DWC2_POWER_DOWN_PARAM_NONE 0 |
| #define DWC2_POWER_DOWN_PARAM_PARTIAL 1 |
| #define DWC2_POWER_DOWN_PARAM_HIBERNATION 2 |
| |
| bool lpm; |
| bool lpm_clock_gating; |
| bool besl; |
| bool hird_threshold_en; |
| u8 hird_threshold; |
| bool activate_stm_fs_transceiver; |
| bool ipg_isoc_en; |
| u16 max_packet_count; |
| u32 max_transfer_size; |
| u32 ahbcfg; |
| |
| /* Host parameters */ |
| bool host_dma; |
| bool dma_desc_enable; |
| bool dma_desc_fs_enable; |
| bool host_support_fs_ls_low_power; |
| bool host_ls_low_power_phy_clk; |
| bool oc_disable; |
| |
| u8 host_channels; |
| u16 host_rx_fifo_size; |
| u16 host_nperio_tx_fifo_size; |
| u16 host_perio_tx_fifo_size; |
| |
| /* Gadget parameters */ |
| bool g_dma; |
| bool g_dma_desc; |
| u32 g_rx_fifo_size; |
| u32 g_np_tx_fifo_size; |
| u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; |
| |
| bool change_speed_quirk; |
| |
| /*from Linux end*/ |
| |
| /* |
| * The hnp/srp capability must be disabled if the platform |
| * does't support hnp/srp. Otherwise the force mode can't work. |
| */ |
| bool hnp_srp_disable; |
| |
| }; |
| |
| /* device request (setup) */ |
| struct devrequest { |
| __u8 requesttype; |
| __u8 request; |
| __le16 value; |
| __le16 index; |
| __le16 length; |
| } __attribute__ ((packed)); |
| |
| /* Interface */ |
| struct usb_interface { |
| struct usb_interface_descriptor desc; |
| |
| __u8 no_of_ep; |
| __u8 num_altsetting; |
| __u8 act_altsetting; |
| |
| struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS]; |
| /* |
| * Super Speed Device will have Super Speed Endpoint |
| * Companion Descriptor (section 9.6.7 of usb 3.0 spec) |
| * Revision 1.0 June 6th 2011 |
| */ |
| struct usb_ss_ep_comp_descriptor ss_ep_comp_desc[USB_MAXENDPOINTS]; |
| } __attribute__ ((packed)); |
| |
| /* Configuration information.. */ |
| struct usb_config { |
| struct usb_config_descriptor desc; |
| |
| __u8 no_of_if; /* number of interfaces */ |
| struct usb_interface if_desc[USB_MAXINTERFACES]; |
| } __attribute__ ((packed)); |
| |
| enum { |
| /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */ |
| PACKET_SIZE_8 = 0, |
| PACKET_SIZE_16 = 1, |
| PACKET_SIZE_32 = 2, |
| PACKET_SIZE_64 = 3, |
| }; |
| |
| struct usb_device { |
| int devnum; /* Device number on USB bus */ |
| int speed; /* full/low/high */ |
| char mf[32]; /* manufacturer */ |
| char prod[32]; /* product */ |
| char serial[32]; /* serial number */ |
| |
| /* Maximum packet size; one of: PACKET_SIZE_* */ |
| int maxpacketsize; |
| /* one bit for each endpoint ([0] = IN, [1] = OUT) */ |
| unsigned int toggle[2]; |
| /* endpoint halts; one bit per endpoint # & direction; |
| * [0] = IN, [1] = OUT |
| */ |
| unsigned int halted[2]; |
| int epmaxpacketin[16]; /* INput endpoint specific maximums */ |
| int epmaxpacketout[16]; /* OUTput endpoint specific maximums */ |
| |
| int configno; /* selected config number */ |
| /* Device Descriptor */ |
| struct usb_device_descriptor descriptor; |
| struct usb_config config; /* config descriptor */ |
| |
| int have_langid; /* whether string_langid is valid yet */ |
| int string_langid; /* language ID for strings */ |
| int (*irq_handle)(struct usb_device *dev); |
| unsigned long irq_status; |
| int irq_act_len; /* transferred bytes */ |
| void *privptr; |
| |
| /* |
| * Child devices - if this is a hub device |
| * Each instance needs its own set of data structures. |
| */ |
| unsigned long status; |
| unsigned long int_pending; /* 1 bit per ep, used by int_queue */ |
| int transfer_len; /* transferred bytes */ |
| int maxchild; /* Number of ports if hub */ |
| int portnr; /* Port number, 1=first */ |
| /* parent hub, or NULL if this is the root hub */ |
| struct usb_device *parent; |
| struct usb_device *children[USB_MAXCHILDREN]; |
| void *controller; /* hardware controller private data */ |
| /* slot_id - for xHCI enabled devices */ |
| unsigned int slot_id; |
| }; |
| |
| /* USB Command Block Wrapper */ |
| typedef struct cbw_struct { |
| uint_8 DCBWSIGNATURE[4]; |
| uint_8 DCBWTAG[4]; |
| uint_8 DCBWDATALENGTH[4]; |
| uchar BMCBWFLAGS; |
| /* 4 MSBs bits reserved */ |
| uchar BCBWCBLUN; |
| /* 3 MSB reserved */ |
| uchar BCBWCBLENGTH; |
| uchar CBWCB[16]; |
| } CBW_STRUCT, _PTR_ CBW_STRUCT_PTR; |
| |
| /* UFI Typical Command Block Wrapper for Extended commands */ |
| typedef struct _UFI_CBWCB_EXTENDED |
| { |
| uint_8 BUFIOPCODE; /* 0 */ |
| uint_8 BUFILUN; /* 1 */ |
| uint_8 BUFILOGICALBLOCKADDRESS[4]; /* 2,3,4,5 */ |
| uint_8 BLENGTH[4]; /* 6,7,8,9 length of the data block */ |
| uint_8 RESERVED10; /* 10 Reserved */ |
| uint_8 RESERVED11; /* 11 Reserved */ |
| } UFI_CBWCB_EXTENDED, _PTR_ UFI_CBWCB_EXTENDED_STRUCT_PTR; |
| |
| struct usb_mass_data { |
| struct usb_device *pusb_dev; /* this usb_device */ |
| unsigned char ifnum; /* interface number */ |
| unsigned char ep_in; /* in endpoint */ |
| unsigned char ep_out; /* out ....... */ |
| unsigned char ep_int; /* interrupt . */ |
| unsigned char irqinterval; /* Intervall for IRQ Pipe */ |
| }; |
| |
| enum { |
| MASS_WAIT_NEW_CMD = 0, |
| MASS_WAIT_CMD_DONE, |
| MASS_WAIT_DATA_DONE, |
| MASS_WAIT_STATUS_DONE, |
| } usb_mass_isr_state_e; |
| |
| |
| /* Normal architectures just use readl/write */ |
| static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset) |
| { |
| u32 val; |
| |
| val = readl((long long)(hsotg->reg_base + offset)); |
| return val; |
| } |
| |
| static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset) |
| { |
| writel(value, (long long)(hsotg->reg_base + offset)); |
| } |
| |
| /* |
| * The following functions support initialization of the core driver component |
| * and the DWC_otg controller |
| */ |
| int dwc2_core_reset(struct dwc2_hsotg *hsotg); |
| |
| /* |
| * Common core Functions. |
| * The following functions support managing the DWC_otg controller in either |
| * device or host mode. |
| */ |
| void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num); |
| void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg); |
| |
| /* Common polling functions */ |
| int dwc2_hsotg_wait_bit_set(struct dwc2_hsotg *hs_otg, u32 reg, u32 bit, |
| u32 timeout); |
| int dwc2_hsotg_wait_bit_clear(struct dwc2_hsotg *hs_otg, u32 reg, u32 bit, |
| u32 timeout); |
| #if defined(CONFIG_USB_MUSB_HOST) || defined(CONFIG_DM_USB) |
| int usb_reset_root_port(struct usb_device *dev); |
| #else |
| #define usb_reset_root_port(dev) |
| #endif |
| |
| extern int g_mass_blen; |
| extern int g_mass_blocking; |
| extern int g_mass_storage_timeout; |
| |
| |
| extern struct usb_device *pdev_usb; |
| extern void free(void *ptr); |
| extern void dbg_dump_buffer(unsigned char *b, int len); |
| extern int register_isr(void (*isr)(void), int irq_id); |
| extern void set_irq_enable(int irq_id); |
| extern void usb_mass_callback(); |
| extern int dwc2_wait_device_detection(); |
| extern void dwc2_init(struct dwc2_hsotg *hsotg); |
| extern int dwc2_hw_init(struct dwc2_hsotg *hsotg); |
| extern void dwc2_host_reset(struct dwc2_core_regs *regs); |
| extern int que_blk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int len); |
| extern void mydelay_us(int n); //From diag_USB.c |
| extern void dbg_dump_buffer(unsigned char *b, int len); |
| extern void dbg_dump_buffer_long(unsigned long *b, int len); |
| extern void dbg_out(char *s); |
| extern void dbg_outhex(int n); |
| extern void dbg_outb(unsigned char n); |
| extern void dbg_outw(unsigned int n); |
| extern void dbg_disp(char *s); |
| extern void usb_reset(); |
| extern int usb_host_init(); |
| extern int usb_mass_start(); |
| extern int usb_storage_read(unsigned char *buff, int lba, int blk_count); |
| extern int usb_storage_write(unsigned char *buff, int lba, int blk_count); |
| |
| extern int urb_control(struct usb_device *dev, unsigned int pipe, |
| unsigned char request, unsigned char requesttype, |
| unsigned short value, unsigned short index, |
| void *data, unsigned short size, int timeout); |
| extern int urb_bulk(struct usb_device *dev, unsigned int pipe, |
| void *data, int len, int *actual_length, int timeout); |
| extern int usb_maxpacket(struct usb_device *dev, unsigned long pipe); |
| extern int usb_get_configuration_no(struct usb_device *dev, |
| unsigned char *buffer, int length); |
| extern int usb_get_configuration_len(struct usb_device *dev); |
| extern int usb_descriptor_u2c(struct usb_device *dev, int index, char *buf, size_t size); |
| extern int set_interface(struct usb_device *dev, int interface, int alternate); |
| extern int snd_blk_msg(struct usb_device *dev, unsigned long pipe, |
| void *buffer, int transfer_len); |
| extern int snd_ctl_msg(struct usb_device *dev, unsigned long pipe, void *buffer, |
| int transfer_len, struct devrequest *setup); |
| |
| extern int usb2_phy_status(int long_dump); |
| extern int usb_phy_init(void); |
| |
| extern void * USB_memalloc(unsigned int n); |
| extern void USB_memfree(void * aligned_ptr); |
| extern void mydelay_us(int n); |
| extern void mydelay_ms(int n); |
| |
| extern int usb_host_init(); |
| extern int usb_mass_start(); |
| extern int usb_storage_read(unsigned char *buff, int lba, int blk_count); |
| extern int usb_storage_write(unsigned char *buff, int lba, int blk_count); |
| extern int usb_storage_prevent_medium_removal(); |
| |
| extern void usb2_set_dbg_mode(unsigned int mode); |
| extern void dbg_display(); |
| extern void dbg_out( char *s ); |
| extern void dbg_outdw(unsigned int n); |
| extern void dbg_outw(unsigned int n); |
| extern void dbg_outb(unsigned char n); |
| extern void dbg_dump_buffer(unsigned char *b, int len); |
| extern void dbg_dump_buffer_long(unsigned long *b, int len); |
| extern void dbg_disp(char *s); |
| extern int usb_hub_probe(struct usb_device *dev, int ifnum); |
| extern void usb_find_usb2_hub_address_port(struct usb_device *udev, |
| uint8_t *hub_address, uint8_t *hub_port); |
| int usb_device_data_init(struct usb_device **devp); |
| |
| |
| |
| typedef struct usb_dwc2_ops { |
| int (*packet_msg)(struct dwc2_hsotg *hsotg, struct usb_device *dev, |
| unsigned long pipe, u8 *pid, int in, void *buffer, int len); |
| |
| int (*packet_snd)(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, |
| u8 *pid, int in, void *buffer, int num_packets, |
| int xfer_len, int *actual_len, int odd_frame); |
| |
| int (*ctl)(struct dwc2_hsotg *hsotg, struct usb_device *dev, |
| unsigned long pipe, void *buffer, int len, struct devrequest *setup); |
| |
| int (*blk)(struct dwc2_hsotg *hsotg, struct usb_device *dev, |
| unsigned long pipe, void *buffer, int len); |
| } hcd_dwc2_ops_t; |
| |
| /* routines */ |
| int usb_init(void); /* initialize the USB Controller */ |
| int usb_stop(void); /* stop the USB Controller */ |
| int usb_get_port_status(struct usb_device *dev, int port, void *data); |
| |
| /************************************************************************* |
| * Hub Stuff |
| */ |
| struct usb_port_status { |
| unsigned short wPortStatus; |
| unsigned short wPortChange; |
| } __attribute__ ((packed)); |
| |
| struct usb_hub_status { |
| unsigned short wHubStatus; |
| unsigned short wHubChange; |
| } __attribute__ ((packed)); |
| |
| /* |
| * Hub Device descriptor |
| * USB Hub class device protocols |
| */ |
| #define USB_HUB_PR_FS 0 /* Full speed hub */ |
| #define USB_HUB_PR_HS_NO_TT 0 /* Hi-speed hub without TT */ |
| #define USB_HUB_PR_HS_SINGLE_TT 1 /* Hi-speed hub with single TT */ |
| #define USB_HUB_PR_HS_MULTI_TT 2 /* Hi-speed hub with multiple TT */ |
| #define USB_HUB_PR_SS 3 /* Super speed hub */ |
| |
| /* Transaction Translator Think Times, in bits */ |
| #define HUB_TTTT_8_BITS 0x00 |
| #define HUB_TTTT_16_BITS 0x20 |
| #define HUB_TTTT_24_BITS 0x40 |
| #define HUB_TTTT_32_BITS 0x60 |
| |
| /* Hub descriptor */ |
| struct usb_hub_descriptor { |
| unsigned char bLength; |
| unsigned char bDescriptorType; |
| unsigned char bNbrPorts; |
| unsigned short wHubCharacteristics; |
| unsigned char bPwrOn2PwrGood; |
| unsigned char bHubContrCurrent; |
| /* 2.0 and 3.0 hubs differ here */ |
| union { |
| struct { |
| /* add 1 bit for hub status change; round to bytes */ |
| __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8]; |
| __u8 PortPowerCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8]; |
| } __attribute__ ((packed)) hs; |
| |
| struct { |
| __u8 bHubHdrDecLat; |
| __le16 wHubDelay; |
| __le16 DeviceRemovable; |
| } __attribute__ ((packed)) ss; |
| } u; |
| } __attribute__ ((packed)); |
| |
| /* |
| * As of USB 2.0, full/low speed devices are segregated into trees. |
| * One type grows from USB 1.1 host controllers (OHCI, UHCI etc). |
| * The other type grows from high speed hubs when they connect to |
| * full/low speed devices using "Transaction Translators" (TTs). |
| */ |
| struct usb_tt { |
| bool multi; /* true means one TT per port */ |
| unsigned think_time; /* think time in ns */ |
| }; |
| |
| struct usb_hub_device { |
| struct usb_device *pusb_dev; |
| struct usb_hub_descriptor desc; |
| |
| ulong connect_timeout; /* Device connection timeout in ms */ |
| ulong query_delay; /* Device query delay in ms */ |
| int overcurrent_count[USB_MAXCHILDREN]; /* Over-current counter */ |
| int hub_depth; /* USB 3.0 hub depth */ |
| struct usb_tt tt; /* Transaction Translator */ |
| }; |
| |
| bool usb_device_has_child_on_port(struct usb_device *parent, int port); |
| void usb_hub_reset(void); |
| int usb_new_device(struct usb_device *dev); |
| void usb_free_device(struct usb_device *controller); |
| |
| #define USB_DT_HID (USB_TYPE_CLASS | 0x01) |
| #define USB_DT_REPORT (USB_TYPE_CLASS | 0x02) |
| #define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) |
| #define USB_DT_HUB (USB_TYPE_CLASS | 0x09) |
| #define USB_DT_SS_HUB (USB_TYPE_CLASS | 0x0a) |
| |
| /************************************************************************* |
| * Hub defines |
| */ |
| |
| /* |
| * Hub request types |
| */ |
| |
| #define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE) |
| #define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER) |
| |
| /* |
| * Hub Class feature numbers |
| */ |
| #define C_HUB_LOCAL_POWER 0 |
| #define C_HUB_OVER_CURRENT 1 |
| |
| /* |
| * Port feature numbers |
| */ |
| #define USB_PORT_FEAT_CONNECTION 0 |
| #define USB_PORT_FEAT_ENABLE 1 |
| #define USB_PORT_FEAT_SUSPEND 2 |
| #define USB_PORT_FEAT_OVER_CURRENT 3 |
| #define USB_PORT_FEAT_RESET 4 |
| #define USB_PORT_FEAT_POWER 8 |
| #define USB_PORT_FEAT_LOWSPEED 9 |
| #define USB_PORT_FEAT_HIGHSPEED 10 |
| #define USB_PORT_FEAT_C_CONNECTION 16 |
| #define USB_PORT_FEAT_C_ENABLE 17 |
| #define USB_PORT_FEAT_C_SUSPEND 18 |
| #define USB_PORT_FEAT_C_OVER_CURRENT 19 |
| #define USB_PORT_FEAT_C_RESET 20 |
| #define USB_PORT_FEAT_TEST 21 |
| |
| /* |
| * Changes to Port feature numbers for Super speed, |
| * from USB 3.0 spec Table 10-8 |
| */ |
| #define USB_SS_PORT_FEAT_U1_TIMEOUT 23 |
| #define USB_SS_PORT_FEAT_U2_TIMEOUT 24 |
| #define USB_SS_PORT_FEAT_C_LINK_STATE 25 |
| #define USB_SS_PORT_FEAT_C_CONFIG_ERROR 26 |
| #define USB_SS_PORT_FEAT_BH_RESET 28 |
| #define USB_SS_PORT_FEAT_C_BH_RESET 29 |
| |
| /* wPortStatus bits */ |
| #define USB_PORT_STAT_CONNECTION 0x0001 |
| #define USB_PORT_STAT_ENABLE 0x0002 |
| #define USB_PORT_STAT_SUSPEND 0x0004 |
| #define USB_PORT_STAT_OVERCURRENT 0x0008 |
| #define USB_PORT_STAT_RESET 0x0010 |
| #define USB_PORT_STAT_POWER 0x0100 |
| #define USB_PORT_STAT_LOW_SPEED 0x0200 |
| #define USB_PORT_STAT_HIGH_SPEED 0x0400 /* support for EHCI */ |
| #define USB_PORT_STAT_SUPER_SPEED 0x0600 /* faking support to XHCI */ |
| #define USB_PORT_STAT_SPEED_MASK \ |
| (USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED) |
| |
| /* |
| * Changes to wPortStatus bit field in USB 3.0 |
| * See USB 3.0 spec Table 10-10 |
| */ |
| #define USB_SS_PORT_STAT_LINK_STATE 0x01e0 |
| #define USB_SS_PORT_STAT_POWER 0x0200 |
| #define USB_SS_PORT_STAT_SPEED 0x1c00 |
| #define USB_SS_PORT_STAT_SPEED_5GBPS 0x0000 |
| /* Bits that are the same from USB 2.0 */ |
| #define USB_SS_PORT_STAT_MASK (USB_PORT_STAT_CONNECTION | \ |
| USB_PORT_STAT_ENABLE | \ |
| USB_PORT_STAT_OVERCURRENT | \ |
| USB_PORT_STAT_RESET) |
| |
| /* wPortChange bits */ |
| #define USB_PORT_STAT_C_CONNECTION 0x0001 |
| #define USB_PORT_STAT_C_ENABLE 0x0002 |
| #define USB_PORT_STAT_C_SUSPEND 0x0004 |
| #define USB_PORT_STAT_C_OVERCURRENT 0x0008 |
| #define USB_PORT_STAT_C_RESET 0x0010 |
| |
| /* |
| * Changes to wPortChange bit fields in USB 3.0 |
| * See USB 3.0 spec Table 10-12 |
| */ |
| #define USB_SS_PORT_STAT_C_BH_RESET 0x0020 |
| #define USB_SS_PORT_STAT_C_LINK_STATE 0x0040 |
| #define USB_SS_PORT_STAT_C_CONFIG_ERROR 0x0080 |
| |
| /* wHubCharacteristics (masks) */ |
| #define HUB_CHAR_LPSM 0x0003 |
| #define HUB_CHAR_COMPOUND 0x0004 |
| #define HUB_CHAR_OCPM 0x0018 |
| #define HUB_CHAR_TTTT 0x0060 /* TT Think Time mask */ |
| |
| /* |
| * Hub Status & Hub Change bit masks |
| */ |
| #define HUB_STATUS_LOCAL_POWER 0x0001 |
| #define HUB_STATUS_OVERCURRENT 0x0002 |
| |
| #define HUB_CHANGE_LOCAL_POWER 0x0001 |
| #define HUB_CHANGE_OVERCURRENT 0x0002 |
| |
| /* Mask for wIndex in get/set port feature */ |
| #define USB_HUB_PORT_MASK 0xf |
| |
| /* Hub class request codes */ |
| #define USB_REQ_SET_HUB_DEPTH 0x0c |
| #endif /* __DWC2_CORE_H__ */ |