162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * core.h - DesignWare HS OTG Controller common declarations 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2004-2013 Synopsys, Inc. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef __DWC2_CORE_H__ 962306a36Sopenharmony_ci#define __DWC2_CORE_H__ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/acpi.h> 1262306a36Sopenharmony_ci#include <linux/phy/phy.h> 1362306a36Sopenharmony_ci#include <linux/regulator/consumer.h> 1462306a36Sopenharmony_ci#include <linux/usb/gadget.h> 1562306a36Sopenharmony_ci#include <linux/usb/otg.h> 1662306a36Sopenharmony_ci#include <linux/usb/phy.h> 1762306a36Sopenharmony_ci#include "hw.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* 2062306a36Sopenharmony_ci * Suggested defines for tracers: 2162306a36Sopenharmony_ci * - no_printk: Disable tracing 2262306a36Sopenharmony_ci * - pr_info: Print this info to the console 2362306a36Sopenharmony_ci * - trace_printk: Print this info to trace buffer (good for verbose logging) 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define DWC2_TRACE_SCHEDULER no_printk 2762306a36Sopenharmony_ci#define DWC2_TRACE_SCHEDULER_VB no_printk 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* Detailed scheduler tracing, but won't overwhelm console */ 3062306a36Sopenharmony_ci#define dwc2_sch_dbg(hsotg, fmt, ...) \ 3162306a36Sopenharmony_ci DWC2_TRACE_SCHEDULER(pr_fmt("%s: SCH: " fmt), \ 3262306a36Sopenharmony_ci dev_name(hsotg->dev), ##__VA_ARGS__) 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/* Verbose scheduler tracing */ 3562306a36Sopenharmony_ci#define dwc2_sch_vdbg(hsotg, fmt, ...) \ 3662306a36Sopenharmony_ci DWC2_TRACE_SCHEDULER_VB(pr_fmt("%s: SCH: " fmt), \ 3762306a36Sopenharmony_ci dev_name(hsotg->dev), ##__VA_ARGS__) 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* Maximum number of Endpoints/HostChannels */ 4062306a36Sopenharmony_ci#define MAX_EPS_CHANNELS 16 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* dwc2-hsotg declarations */ 4362306a36Sopenharmony_cistatic const char * const dwc2_hsotg_supply_names[] = { 4462306a36Sopenharmony_ci "vusb_d", /* digital USB supply, 1.2V */ 4562306a36Sopenharmony_ci "vusb_a", /* analog USB supply, 1.1V */ 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define DWC2_NUM_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/* 5162306a36Sopenharmony_ci * EP0_MPS_LIMIT 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * Unfortunately there seems to be a limit of the amount of data that can 5462306a36Sopenharmony_ci * be transferred by IN transactions on EP0. This is either 127 bytes or 3 5562306a36Sopenharmony_ci * packets (which practically means 1 packet and 63 bytes of data) when the 5662306a36Sopenharmony_ci * MPS is set to 64. 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * This means if we are wanting to move >127 bytes of data, we need to 5962306a36Sopenharmony_ci * split the transactions up, but just doing one packet at a time does 6062306a36Sopenharmony_ci * not work (this may be an implicit DATA0 PID on first packet of the 6162306a36Sopenharmony_ci * transaction) and doing 2 packets is outside the controller's limits. 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * If we try to lower the MPS size for EP0, then no transfers work properly 6462306a36Sopenharmony_ci * for EP0, and the system will fail basic enumeration. As no cause for this 6562306a36Sopenharmony_ci * has currently been found, we cannot support any large IN transfers for 6662306a36Sopenharmony_ci * EP0. 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_ci#define EP0_MPS_LIMIT 64 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistruct dwc2_hsotg; 7162306a36Sopenharmony_cistruct dwc2_hsotg_req; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/** 7462306a36Sopenharmony_ci * struct dwc2_hsotg_ep - driver endpoint definition. 7562306a36Sopenharmony_ci * @ep: The gadget layer representation of the endpoint. 7662306a36Sopenharmony_ci * @name: The driver generated name for the endpoint. 7762306a36Sopenharmony_ci * @queue: Queue of requests for this endpoint. 7862306a36Sopenharmony_ci * @parent: Reference back to the parent device structure. 7962306a36Sopenharmony_ci * @req: The current request that the endpoint is processing. This is 8062306a36Sopenharmony_ci * used to indicate an request has been loaded onto the endpoint 8162306a36Sopenharmony_ci * and has yet to be completed (maybe due to data move, or simply 8262306a36Sopenharmony_ci * awaiting an ack from the core all the data has been completed). 8362306a36Sopenharmony_ci * @debugfs: File entry for debugfs file for this endpoint. 8462306a36Sopenharmony_ci * @dir_in: Set to true if this endpoint is of the IN direction, which 8562306a36Sopenharmony_ci * means that it is sending data to the Host. 8662306a36Sopenharmony_ci * @map_dir: Set to the value of dir_in when the DMA buffer is mapped. 8762306a36Sopenharmony_ci * @index: The index for the endpoint registers. 8862306a36Sopenharmony_ci * @mc: Multi Count - number of transactions per microframe 8962306a36Sopenharmony_ci * @interval: Interval for periodic endpoints, in frames or microframes. 9062306a36Sopenharmony_ci * @name: The name array passed to the USB core. 9162306a36Sopenharmony_ci * @halted: Set if the endpoint has been halted. 9262306a36Sopenharmony_ci * @periodic: Set if this is a periodic ep, such as Interrupt 9362306a36Sopenharmony_ci * @isochronous: Set if this is a isochronous ep 9462306a36Sopenharmony_ci * @send_zlp: Set if we need to send a zero-length packet. 9562306a36Sopenharmony_ci * @wedged: Set if ep is wedged. 9662306a36Sopenharmony_ci * @desc_list_dma: The DMA address of descriptor chain currently in use. 9762306a36Sopenharmony_ci * @desc_list: Pointer to descriptor DMA chain head currently in use. 9862306a36Sopenharmony_ci * @desc_count: Count of entries within the DMA descriptor chain of EP. 9962306a36Sopenharmony_ci * @next_desc: index of next free descriptor in the ISOC chain under SW control. 10062306a36Sopenharmony_ci * @compl_desc: index of next descriptor to be completed by xFerComplete 10162306a36Sopenharmony_ci * @total_data: The total number of data bytes done. 10262306a36Sopenharmony_ci * @fifo_size: The size of the FIFO (for periodic IN endpoints) 10362306a36Sopenharmony_ci * @fifo_index: For Dedicated FIFO operation, only FIFO0 can be used for EP0. 10462306a36Sopenharmony_ci * @fifo_load: The amount of data loaded into the FIFO (periodic IN) 10562306a36Sopenharmony_ci * @last_load: The offset of data for the last start of request. 10662306a36Sopenharmony_ci * @size_loaded: The last loaded size for DxEPTSIZE for periodic IN 10762306a36Sopenharmony_ci * @target_frame: Targeted frame num to setup next ISOC transfer 10862306a36Sopenharmony_ci * @frame_overrun: Indicates SOF number overrun in DSTS 10962306a36Sopenharmony_ci * 11062306a36Sopenharmony_ci * This is the driver's state for each registered endpoint, allowing it 11162306a36Sopenharmony_ci * to keep track of transactions that need doing. Each endpoint has a 11262306a36Sopenharmony_ci * lock to protect the state, to try and avoid using an overall lock 11362306a36Sopenharmony_ci * for the host controller as much as possible. 11462306a36Sopenharmony_ci * 11562306a36Sopenharmony_ci * For periodic IN endpoints, we have fifo_size and fifo_load to try 11662306a36Sopenharmony_ci * and keep track of the amount of data in the periodic FIFO for each 11762306a36Sopenharmony_ci * of these as we don't have a status register that tells us how much 11862306a36Sopenharmony_ci * is in each of them. (note, this may actually be useless information 11962306a36Sopenharmony_ci * as in shared-fifo mode periodic in acts like a single-frame packet 12062306a36Sopenharmony_ci * buffer than a fifo) 12162306a36Sopenharmony_ci */ 12262306a36Sopenharmony_cistruct dwc2_hsotg_ep { 12362306a36Sopenharmony_ci struct usb_ep ep; 12462306a36Sopenharmony_ci struct list_head queue; 12562306a36Sopenharmony_ci struct dwc2_hsotg *parent; 12662306a36Sopenharmony_ci struct dwc2_hsotg_req *req; 12762306a36Sopenharmony_ci struct dentry *debugfs; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci unsigned long total_data; 13062306a36Sopenharmony_ci unsigned int size_loaded; 13162306a36Sopenharmony_ci unsigned int last_load; 13262306a36Sopenharmony_ci unsigned int fifo_load; 13362306a36Sopenharmony_ci unsigned short fifo_size; 13462306a36Sopenharmony_ci unsigned short fifo_index; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci unsigned char dir_in; 13762306a36Sopenharmony_ci unsigned char map_dir; 13862306a36Sopenharmony_ci unsigned char index; 13962306a36Sopenharmony_ci unsigned char mc; 14062306a36Sopenharmony_ci u16 interval; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci unsigned int halted:1; 14362306a36Sopenharmony_ci unsigned int periodic:1; 14462306a36Sopenharmony_ci unsigned int isochronous:1; 14562306a36Sopenharmony_ci unsigned int send_zlp:1; 14662306a36Sopenharmony_ci unsigned int wedged:1; 14762306a36Sopenharmony_ci unsigned int target_frame; 14862306a36Sopenharmony_ci#define TARGET_FRAME_INITIAL 0xFFFFFFFF 14962306a36Sopenharmony_ci bool frame_overrun; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci dma_addr_t desc_list_dma; 15262306a36Sopenharmony_ci struct dwc2_dma_desc *desc_list; 15362306a36Sopenharmony_ci u8 desc_count; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci unsigned int next_desc; 15662306a36Sopenharmony_ci unsigned int compl_desc; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci char name[10]; 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/** 16262306a36Sopenharmony_ci * struct dwc2_hsotg_req - data transfer request 16362306a36Sopenharmony_ci * @req: The USB gadget request 16462306a36Sopenharmony_ci * @queue: The list of requests for the endpoint this is queued for. 16562306a36Sopenharmony_ci * @saved_req_buf: variable to save req.buf when bounce buffers are used. 16662306a36Sopenharmony_ci */ 16762306a36Sopenharmony_cistruct dwc2_hsotg_req { 16862306a36Sopenharmony_ci struct usb_request req; 16962306a36Sopenharmony_ci struct list_head queue; 17062306a36Sopenharmony_ci void *saved_req_buf; 17162306a36Sopenharmony_ci}; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ 17462306a36Sopenharmony_ci IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) 17562306a36Sopenharmony_ci#define call_gadget(_hs, _entry) \ 17662306a36Sopenharmony_cido { \ 17762306a36Sopenharmony_ci if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ 17862306a36Sopenharmony_ci (_hs)->driver && (_hs)->driver->_entry) { \ 17962306a36Sopenharmony_ci spin_unlock(&_hs->lock); \ 18062306a36Sopenharmony_ci (_hs)->driver->_entry(&(_hs)->gadget); \ 18162306a36Sopenharmony_ci spin_lock(&_hs->lock); \ 18262306a36Sopenharmony_ci } \ 18362306a36Sopenharmony_ci} while (0) 18462306a36Sopenharmony_ci#else 18562306a36Sopenharmony_ci#define call_gadget(_hs, _entry) do {} while (0) 18662306a36Sopenharmony_ci#endif 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistruct dwc2_hsotg; 18962306a36Sopenharmony_cistruct dwc2_host_chan; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/* Device States */ 19262306a36Sopenharmony_cienum dwc2_lx_state { 19362306a36Sopenharmony_ci DWC2_L0, /* On state */ 19462306a36Sopenharmony_ci DWC2_L1, /* LPM sleep state */ 19562306a36Sopenharmony_ci DWC2_L2, /* USB suspend state */ 19662306a36Sopenharmony_ci DWC2_L3, /* Off state */ 19762306a36Sopenharmony_ci}; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci/* Gadget ep0 states */ 20062306a36Sopenharmony_cienum dwc2_ep0_state { 20162306a36Sopenharmony_ci DWC2_EP0_SETUP, 20262306a36Sopenharmony_ci DWC2_EP0_DATA_IN, 20362306a36Sopenharmony_ci DWC2_EP0_DATA_OUT, 20462306a36Sopenharmony_ci DWC2_EP0_STATUS_IN, 20562306a36Sopenharmony_ci DWC2_EP0_STATUS_OUT, 20662306a36Sopenharmony_ci}; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci/** 20962306a36Sopenharmony_ci * struct dwc2_core_params - Parameters for configuring the core 21062306a36Sopenharmony_ci * 21162306a36Sopenharmony_ci * @otg_caps: Specifies the OTG capabilities. OTG caps from the platform parameters, 21262306a36Sopenharmony_ci * used to setup the: 21362306a36Sopenharmony_ci * - HNP and SRP capable 21462306a36Sopenharmony_ci * - SRP Only capable 21562306a36Sopenharmony_ci * - No HNP/SRP capable (always available) 21662306a36Sopenharmony_ci * Defaults to best available option 21762306a36Sopenharmony_ci * - OTG revision number the device is compliant with, in binary-coded 21862306a36Sopenharmony_ci * decimal (i.e. 2.0 is 0200H). (see struct usb_otg_caps) 21962306a36Sopenharmony_ci * @host_dma: Specifies whether to use slave or DMA mode for accessing 22062306a36Sopenharmony_ci * the data FIFOs. The driver will automatically detect the 22162306a36Sopenharmony_ci * value for this parameter if none is specified. 22262306a36Sopenharmony_ci * 0 - Slave (always available) 22362306a36Sopenharmony_ci * 1 - DMA (default, if available) 22462306a36Sopenharmony_ci * @dma_desc_enable: When DMA mode is enabled, specifies whether to use 22562306a36Sopenharmony_ci * address DMA mode or descriptor DMA mode for accessing 22662306a36Sopenharmony_ci * the data FIFOs. The driver will automatically detect the 22762306a36Sopenharmony_ci * value for this if none is specified. 22862306a36Sopenharmony_ci * 0 - Address DMA 22962306a36Sopenharmony_ci * 1 - Descriptor DMA (default, if available) 23062306a36Sopenharmony_ci * @dma_desc_fs_enable: When DMA mode is enabled, specifies whether to use 23162306a36Sopenharmony_ci * address DMA mode or descriptor DMA mode for accessing 23262306a36Sopenharmony_ci * the data FIFOs in Full Speed mode only. The driver 23362306a36Sopenharmony_ci * will automatically detect the value for this if none is 23462306a36Sopenharmony_ci * specified. 23562306a36Sopenharmony_ci * 0 - Address DMA 23662306a36Sopenharmony_ci * 1 - Descriptor DMA in FS (default, if available) 23762306a36Sopenharmony_ci * @speed: Specifies the maximum speed of operation in host and 23862306a36Sopenharmony_ci * device mode. The actual speed depends on the speed of 23962306a36Sopenharmony_ci * the attached device and the value of phy_type. 24062306a36Sopenharmony_ci * 0 - High Speed 24162306a36Sopenharmony_ci * (default when phy_type is UTMI+ or ULPI) 24262306a36Sopenharmony_ci * 1 - Full Speed 24362306a36Sopenharmony_ci * (default when phy_type is Full Speed) 24462306a36Sopenharmony_ci * @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters 24562306a36Sopenharmony_ci * 1 - Allow dynamic FIFO sizing (default, if available) 24662306a36Sopenharmony_ci * @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs 24762306a36Sopenharmony_ci * are enabled for non-periodic IN endpoints in device 24862306a36Sopenharmony_ci * mode. 24962306a36Sopenharmony_ci * @host_rx_fifo_size: Number of 4-byte words in the Rx FIFO in host mode when 25062306a36Sopenharmony_ci * dynamic FIFO sizing is enabled 25162306a36Sopenharmony_ci * 16 to 32768 25262306a36Sopenharmony_ci * Actual maximum value is autodetected and also 25362306a36Sopenharmony_ci * the default. 25462306a36Sopenharmony_ci * @host_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO 25562306a36Sopenharmony_ci * in host mode when dynamic FIFO sizing is enabled 25662306a36Sopenharmony_ci * 16 to 32768 25762306a36Sopenharmony_ci * Actual maximum value is autodetected and also 25862306a36Sopenharmony_ci * the default. 25962306a36Sopenharmony_ci * @host_perio_tx_fifo_size: Number of 4-byte words in the periodic Tx FIFO in 26062306a36Sopenharmony_ci * host mode when dynamic FIFO sizing is enabled 26162306a36Sopenharmony_ci * 16 to 32768 26262306a36Sopenharmony_ci * Actual maximum value is autodetected and also 26362306a36Sopenharmony_ci * the default. 26462306a36Sopenharmony_ci * @max_transfer_size: The maximum transfer size supported, in bytes 26562306a36Sopenharmony_ci * 2047 to 65,535 26662306a36Sopenharmony_ci * Actual maximum value is autodetected and also 26762306a36Sopenharmony_ci * the default. 26862306a36Sopenharmony_ci * @max_packet_count: The maximum number of packets in a transfer 26962306a36Sopenharmony_ci * 15 to 511 27062306a36Sopenharmony_ci * Actual maximum value is autodetected and also 27162306a36Sopenharmony_ci * the default. 27262306a36Sopenharmony_ci * @host_channels: The number of host channel registers to use 27362306a36Sopenharmony_ci * 1 to 16 27462306a36Sopenharmony_ci * Actual maximum value is autodetected and also 27562306a36Sopenharmony_ci * the default. 27662306a36Sopenharmony_ci * @phy_type: Specifies the type of PHY interface to use. By default, 27762306a36Sopenharmony_ci * the driver will automatically detect the phy_type. 27862306a36Sopenharmony_ci * 0 - Full Speed Phy 27962306a36Sopenharmony_ci * 1 - UTMI+ Phy 28062306a36Sopenharmony_ci * 2 - ULPI Phy 28162306a36Sopenharmony_ci * Defaults to best available option (2, 1, then 0) 28262306a36Sopenharmony_ci * @phy_utmi_width: Specifies the UTMI+ Data Width (in bits). This parameter 28362306a36Sopenharmony_ci * is applicable for a phy_type of UTMI+ or ULPI. (For a 28462306a36Sopenharmony_ci * ULPI phy_type, this parameter indicates the data width 28562306a36Sopenharmony_ci * between the MAC and the ULPI Wrapper.) Also, this 28662306a36Sopenharmony_ci * parameter is applicable only if the OTG_HSPHY_WIDTH cC 28762306a36Sopenharmony_ci * parameter was set to "8 and 16 bits", meaning that the 28862306a36Sopenharmony_ci * core has been configured to work at either data path 28962306a36Sopenharmony_ci * width. 29062306a36Sopenharmony_ci * 8 or 16 (default 16 if available) 29162306a36Sopenharmony_ci * @phy_ulpi_ddr: Specifies whether the ULPI operates at double or single 29262306a36Sopenharmony_ci * data rate. This parameter is only applicable if phy_type 29362306a36Sopenharmony_ci * is ULPI. 29462306a36Sopenharmony_ci * 0 - single data rate ULPI interface with 8 bit wide 29562306a36Sopenharmony_ci * data bus (default) 29662306a36Sopenharmony_ci * 1 - double data rate ULPI interface with 4 bit wide 29762306a36Sopenharmony_ci * data bus 29862306a36Sopenharmony_ci * @phy_ulpi_ext_vbus: For a ULPI phy, specifies whether to use the internal or 29962306a36Sopenharmony_ci * external supply to drive the VBus 30062306a36Sopenharmony_ci * 0 - Internal supply (default) 30162306a36Sopenharmony_ci * 1 - External supply 30262306a36Sopenharmony_ci * @i2c_enable: Specifies whether to use the I2Cinterface for a full 30362306a36Sopenharmony_ci * speed PHY. This parameter is only applicable if phy_type 30462306a36Sopenharmony_ci * is FS. 30562306a36Sopenharmony_ci * 0 - No (default) 30662306a36Sopenharmony_ci * 1 - Yes 30762306a36Sopenharmony_ci * @ipg_isoc_en: Indicates the IPG supports is enabled or disabled. 30862306a36Sopenharmony_ci * 0 - Disable (default) 30962306a36Sopenharmony_ci * 1 - Enable 31062306a36Sopenharmony_ci * @acg_enable: For enabling Active Clock Gating in the controller 31162306a36Sopenharmony_ci * 0 - No 31262306a36Sopenharmony_ci * 1 - Yes 31362306a36Sopenharmony_ci * @ulpi_fs_ls: Make ULPI phy operate in FS/LS mode only 31462306a36Sopenharmony_ci * 0 - No (default) 31562306a36Sopenharmony_ci * 1 - Yes 31662306a36Sopenharmony_ci * @host_support_fs_ls_low_power: Specifies whether low power mode is supported 31762306a36Sopenharmony_ci * when attached to a Full Speed or Low Speed device in 31862306a36Sopenharmony_ci * host mode. 31962306a36Sopenharmony_ci * 0 - Don't support low power mode (default) 32062306a36Sopenharmony_ci * 1 - Support low power mode 32162306a36Sopenharmony_ci * @host_ls_low_power_phy_clk: Specifies the PHY clock rate in low power mode 32262306a36Sopenharmony_ci * when connected to a Low Speed device in host 32362306a36Sopenharmony_ci * mode. This parameter is applicable only if 32462306a36Sopenharmony_ci * host_support_fs_ls_low_power is enabled. 32562306a36Sopenharmony_ci * 0 - 48 MHz 32662306a36Sopenharmony_ci * (default when phy_type is UTMI+ or ULPI) 32762306a36Sopenharmony_ci * 1 - 6 MHz 32862306a36Sopenharmony_ci * (default when phy_type is Full Speed) 32962306a36Sopenharmony_ci * @oc_disable: Flag to disable overcurrent condition. 33062306a36Sopenharmony_ci * 0 - Allow overcurrent condition to get detected 33162306a36Sopenharmony_ci * 1 - Disable overcurrent condtion to get detected 33262306a36Sopenharmony_ci * @ts_dline: Enable Term Select Dline pulsing 33362306a36Sopenharmony_ci * 0 - No (default) 33462306a36Sopenharmony_ci * 1 - Yes 33562306a36Sopenharmony_ci * @reload_ctl: Allow dynamic reloading of HFIR register during runtime 33662306a36Sopenharmony_ci * 0 - No (default for core < 2.92a) 33762306a36Sopenharmony_ci * 1 - Yes (default for core >= 2.92a) 33862306a36Sopenharmony_ci * @ahbcfg: This field allows the default value of the GAHBCFG 33962306a36Sopenharmony_ci * register to be overridden 34062306a36Sopenharmony_ci * -1 - GAHBCFG value will be set to 0x06 34162306a36Sopenharmony_ci * (INCR, default) 34262306a36Sopenharmony_ci * all others - GAHBCFG value will be overridden with 34362306a36Sopenharmony_ci * this value 34462306a36Sopenharmony_ci * Not all bits can be controlled like this, the 34562306a36Sopenharmony_ci * bits defined by GAHBCFG_CTRL_MASK are controlled 34662306a36Sopenharmony_ci * by the driver and are ignored in this 34762306a36Sopenharmony_ci * configuration value. 34862306a36Sopenharmony_ci * @uframe_sched: True to enable the microframe scheduler 34962306a36Sopenharmony_ci * @external_id_pin_ctl: Specifies whether ID pin is handled externally. 35062306a36Sopenharmony_ci * Disable CONIDSTSCHNG controller interrupt in such 35162306a36Sopenharmony_ci * case. 35262306a36Sopenharmony_ci * 0 - No (default) 35362306a36Sopenharmony_ci * 1 - Yes 35462306a36Sopenharmony_ci * @power_down: Specifies whether the controller support power_down. 35562306a36Sopenharmony_ci * If power_down is enabled, the controller will enter 35662306a36Sopenharmony_ci * power_down in both peripheral and host mode when 35762306a36Sopenharmony_ci * needed. 35862306a36Sopenharmony_ci * 0 - No (default) 35962306a36Sopenharmony_ci * 1 - Partial power down 36062306a36Sopenharmony_ci * 2 - Hibernation 36162306a36Sopenharmony_ci * @no_clock_gating: Specifies whether to avoid clock gating feature. 36262306a36Sopenharmony_ci * 0 - No (use clock gating) 36362306a36Sopenharmony_ci * 1 - Yes (avoid it) 36462306a36Sopenharmony_ci * @lpm: Enable LPM support. 36562306a36Sopenharmony_ci * 0 - No 36662306a36Sopenharmony_ci * 1 - Yes 36762306a36Sopenharmony_ci * @lpm_clock_gating: Enable core PHY clock gating. 36862306a36Sopenharmony_ci * 0 - No 36962306a36Sopenharmony_ci * 1 - Yes 37062306a36Sopenharmony_ci * @besl: Enable LPM Errata support. 37162306a36Sopenharmony_ci * 0 - No 37262306a36Sopenharmony_ci * 1 - Yes 37362306a36Sopenharmony_ci * @hird_threshold_en: HIRD or HIRD Threshold enable. 37462306a36Sopenharmony_ci * 0 - No 37562306a36Sopenharmony_ci * 1 - Yes 37662306a36Sopenharmony_ci * @hird_threshold: Value of BESL or HIRD Threshold. 37762306a36Sopenharmony_ci * @ref_clk_per: Indicates in terms of pico seconds the period 37862306a36Sopenharmony_ci * of ref_clk. 37962306a36Sopenharmony_ci * 62500 - 16MHz 38062306a36Sopenharmony_ci * 58823 - 17MHz 38162306a36Sopenharmony_ci * 52083 - 19.2MHz 38262306a36Sopenharmony_ci * 50000 - 20MHz 38362306a36Sopenharmony_ci * 41666 - 24MHz 38462306a36Sopenharmony_ci * 33333 - 30MHz (default) 38562306a36Sopenharmony_ci * 25000 - 40MHz 38662306a36Sopenharmony_ci * @sof_cnt_wkup_alert: Indicates in term of number of SOF's after which 38762306a36Sopenharmony_ci * the controller should generate an interrupt if the 38862306a36Sopenharmony_ci * device had been in L1 state until that period. 38962306a36Sopenharmony_ci * This is used by SW to initiate Remote WakeUp in the 39062306a36Sopenharmony_ci * controller so as to sync to the uF number from the host. 39162306a36Sopenharmony_ci * @activate_stm_fs_transceiver: Activate internal transceiver using GGPIO 39262306a36Sopenharmony_ci * register. 39362306a36Sopenharmony_ci * 0 - Deactivate the transceiver (default) 39462306a36Sopenharmony_ci * 1 - Activate the transceiver 39562306a36Sopenharmony_ci * @activate_stm_id_vb_detection: Activate external ID pin and Vbus level 39662306a36Sopenharmony_ci * detection using GGPIO register. 39762306a36Sopenharmony_ci * 0 - Deactivate the external level detection (default) 39862306a36Sopenharmony_ci * 1 - Activate the external level detection 39962306a36Sopenharmony_ci * @activate_ingenic_overcurrent_detection: Activate Ingenic overcurrent 40062306a36Sopenharmony_ci * detection. 40162306a36Sopenharmony_ci * 0 - Deactivate the overcurrent detection 40262306a36Sopenharmony_ci * 1 - Activate the overcurrent detection (default) 40362306a36Sopenharmony_ci * @g_dma: Enables gadget dma usage (default: autodetect). 40462306a36Sopenharmony_ci * @g_dma_desc: Enables gadget descriptor DMA (default: autodetect). 40562306a36Sopenharmony_ci * @g_rx_fifo_size: The periodic rx fifo size for the device, in 40662306a36Sopenharmony_ci * DWORDS from 16-32768 (default: 2048 if 40762306a36Sopenharmony_ci * possible, otherwise autodetect). 40862306a36Sopenharmony_ci * @g_np_tx_fifo_size: The non-periodic tx fifo size for the device in 40962306a36Sopenharmony_ci * DWORDS from 16-32768 (default: 1024 if 41062306a36Sopenharmony_ci * possible, otherwise autodetect). 41162306a36Sopenharmony_ci * @g_tx_fifo_size: An array of TX fifo sizes in dedicated fifo 41262306a36Sopenharmony_ci * mode. Each value corresponds to one EP 41362306a36Sopenharmony_ci * starting from EP1 (max 15 values). Sizes are 41462306a36Sopenharmony_ci * in DWORDS with possible values from 41562306a36Sopenharmony_ci * 16-32768 (default: 256, 256, 256, 256, 768, 41662306a36Sopenharmony_ci * 768, 768, 768, 0, 0, 0, 0, 0, 0, 0). 41762306a36Sopenharmony_ci * @change_speed_quirk: Change speed configuration to DWC2_SPEED_PARAM_FULL 41862306a36Sopenharmony_ci * while full&low speed device connect. And change speed 41962306a36Sopenharmony_ci * back to DWC2_SPEED_PARAM_HIGH while device is gone. 42062306a36Sopenharmony_ci * 0 - No (default) 42162306a36Sopenharmony_ci * 1 - Yes 42262306a36Sopenharmony_ci * @service_interval: Enable service interval based scheduling. 42362306a36Sopenharmony_ci * 0 - No 42462306a36Sopenharmony_ci * 1 - Yes 42562306a36Sopenharmony_ci * 42662306a36Sopenharmony_ci * The following parameters may be specified when starting the module. These 42762306a36Sopenharmony_ci * parameters define how the DWC_otg controller should be configured. A 42862306a36Sopenharmony_ci * value of -1 (or any other out of range value) for any parameter means 42962306a36Sopenharmony_ci * to read the value from hardware (if possible) or use the builtin 43062306a36Sopenharmony_ci * default described above. 43162306a36Sopenharmony_ci */ 43262306a36Sopenharmony_cistruct dwc2_core_params { 43362306a36Sopenharmony_ci struct usb_otg_caps otg_caps; 43462306a36Sopenharmony_ci u8 phy_type; 43562306a36Sopenharmony_ci#define DWC2_PHY_TYPE_PARAM_FS 0 43662306a36Sopenharmony_ci#define DWC2_PHY_TYPE_PARAM_UTMI 1 43762306a36Sopenharmony_ci#define DWC2_PHY_TYPE_PARAM_ULPI 2 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci u8 speed; 44062306a36Sopenharmony_ci#define DWC2_SPEED_PARAM_HIGH 0 44162306a36Sopenharmony_ci#define DWC2_SPEED_PARAM_FULL 1 44262306a36Sopenharmony_ci#define DWC2_SPEED_PARAM_LOW 2 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci u8 phy_utmi_width; 44562306a36Sopenharmony_ci bool phy_ulpi_ddr; 44662306a36Sopenharmony_ci bool phy_ulpi_ext_vbus; 44762306a36Sopenharmony_ci bool enable_dynamic_fifo; 44862306a36Sopenharmony_ci bool en_multiple_tx_fifo; 44962306a36Sopenharmony_ci bool i2c_enable; 45062306a36Sopenharmony_ci bool acg_enable; 45162306a36Sopenharmony_ci bool ulpi_fs_ls; 45262306a36Sopenharmony_ci bool ts_dline; 45362306a36Sopenharmony_ci bool reload_ctl; 45462306a36Sopenharmony_ci bool uframe_sched; 45562306a36Sopenharmony_ci bool external_id_pin_ctl; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci int power_down; 45862306a36Sopenharmony_ci#define DWC2_POWER_DOWN_PARAM_NONE 0 45962306a36Sopenharmony_ci#define DWC2_POWER_DOWN_PARAM_PARTIAL 1 46062306a36Sopenharmony_ci#define DWC2_POWER_DOWN_PARAM_HIBERNATION 2 46162306a36Sopenharmony_ci bool no_clock_gating; 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci bool lpm; 46462306a36Sopenharmony_ci bool lpm_clock_gating; 46562306a36Sopenharmony_ci bool besl; 46662306a36Sopenharmony_ci bool hird_threshold_en; 46762306a36Sopenharmony_ci bool service_interval; 46862306a36Sopenharmony_ci u8 hird_threshold; 46962306a36Sopenharmony_ci bool activate_stm_fs_transceiver; 47062306a36Sopenharmony_ci bool activate_stm_id_vb_detection; 47162306a36Sopenharmony_ci bool activate_ingenic_overcurrent_detection; 47262306a36Sopenharmony_ci bool ipg_isoc_en; 47362306a36Sopenharmony_ci u16 max_packet_count; 47462306a36Sopenharmony_ci u32 max_transfer_size; 47562306a36Sopenharmony_ci u32 ahbcfg; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci /* GREFCLK parameters */ 47862306a36Sopenharmony_ci u32 ref_clk_per; 47962306a36Sopenharmony_ci u16 sof_cnt_wkup_alert; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci /* Host parameters */ 48262306a36Sopenharmony_ci bool host_dma; 48362306a36Sopenharmony_ci bool dma_desc_enable; 48462306a36Sopenharmony_ci bool dma_desc_fs_enable; 48562306a36Sopenharmony_ci bool host_support_fs_ls_low_power; 48662306a36Sopenharmony_ci bool host_ls_low_power_phy_clk; 48762306a36Sopenharmony_ci bool oc_disable; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci u8 host_channels; 49062306a36Sopenharmony_ci u16 host_rx_fifo_size; 49162306a36Sopenharmony_ci u16 host_nperio_tx_fifo_size; 49262306a36Sopenharmony_ci u16 host_perio_tx_fifo_size; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci /* Gadget parameters */ 49562306a36Sopenharmony_ci bool g_dma; 49662306a36Sopenharmony_ci bool g_dma_desc; 49762306a36Sopenharmony_ci u32 g_rx_fifo_size; 49862306a36Sopenharmony_ci u32 g_np_tx_fifo_size; 49962306a36Sopenharmony_ci u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci bool change_speed_quirk; 50262306a36Sopenharmony_ci}; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci/** 50562306a36Sopenharmony_ci * struct dwc2_hw_params - Autodetected parameters. 50662306a36Sopenharmony_ci * 50762306a36Sopenharmony_ci * These parameters are the various parameters read from hardware 50862306a36Sopenharmony_ci * registers during initialization. They typically contain the best 50962306a36Sopenharmony_ci * supported or maximum value that can be configured in the 51062306a36Sopenharmony_ci * corresponding dwc2_core_params value. 51162306a36Sopenharmony_ci * 51262306a36Sopenharmony_ci * The values that are not in dwc2_core_params are documented below. 51362306a36Sopenharmony_ci * 51462306a36Sopenharmony_ci * @op_mode: Mode of Operation 51562306a36Sopenharmony_ci * 0 - HNP- and SRP-Capable OTG (Host & Device) 51662306a36Sopenharmony_ci * 1 - SRP-Capable OTG (Host & Device) 51762306a36Sopenharmony_ci * 2 - Non-HNP and Non-SRP Capable OTG (Host & Device) 51862306a36Sopenharmony_ci * 3 - SRP-Capable Device 51962306a36Sopenharmony_ci * 4 - Non-OTG Device 52062306a36Sopenharmony_ci * 5 - SRP-Capable Host 52162306a36Sopenharmony_ci * 6 - Non-OTG Host 52262306a36Sopenharmony_ci * @arch: Architecture 52362306a36Sopenharmony_ci * 0 - Slave only 52462306a36Sopenharmony_ci * 1 - External DMA 52562306a36Sopenharmony_ci * 2 - Internal DMA 52662306a36Sopenharmony_ci * @ipg_isoc_en: This feature indicates that the controller supports 52762306a36Sopenharmony_ci * the worst-case scenario of Rx followed by Rx 52862306a36Sopenharmony_ci * Interpacket Gap (IPG) (32 bitTimes) as per the utmi 52962306a36Sopenharmony_ci * specification for any token following ISOC OUT token. 53062306a36Sopenharmony_ci * 0 - Don't support 53162306a36Sopenharmony_ci * 1 - Support 53262306a36Sopenharmony_ci * @power_optimized: Are power optimizations enabled? 53362306a36Sopenharmony_ci * @num_dev_ep: Number of device endpoints available 53462306a36Sopenharmony_ci * @num_dev_in_eps: Number of device IN endpoints available 53562306a36Sopenharmony_ci * @num_dev_perio_in_ep: Number of device periodic IN endpoints 53662306a36Sopenharmony_ci * available 53762306a36Sopenharmony_ci * @dev_token_q_depth: Device Mode IN Token Sequence Learning Queue 53862306a36Sopenharmony_ci * Depth 53962306a36Sopenharmony_ci * 0 to 30 54062306a36Sopenharmony_ci * @host_perio_tx_q_depth: 54162306a36Sopenharmony_ci * Host Mode Periodic Request Queue Depth 54262306a36Sopenharmony_ci * 2, 4 or 8 54362306a36Sopenharmony_ci * @nperio_tx_q_depth: 54462306a36Sopenharmony_ci * Non-Periodic Request Queue Depth 54562306a36Sopenharmony_ci * 2, 4 or 8 54662306a36Sopenharmony_ci * @hs_phy_type: High-speed PHY interface type 54762306a36Sopenharmony_ci * 0 - High-speed interface not supported 54862306a36Sopenharmony_ci * 1 - UTMI+ 54962306a36Sopenharmony_ci * 2 - ULPI 55062306a36Sopenharmony_ci * 3 - UTMI+ and ULPI 55162306a36Sopenharmony_ci * @fs_phy_type: Full-speed PHY interface type 55262306a36Sopenharmony_ci * 0 - Full speed interface not supported 55362306a36Sopenharmony_ci * 1 - Dedicated full speed interface 55462306a36Sopenharmony_ci * 2 - FS pins shared with UTMI+ pins 55562306a36Sopenharmony_ci * 3 - FS pins shared with ULPI pins 55662306a36Sopenharmony_ci * @total_fifo_size: Total internal RAM for FIFOs (bytes) 55762306a36Sopenharmony_ci * @hibernation: Is hibernation enabled? 55862306a36Sopenharmony_ci * @utmi_phy_data_width: UTMI+ PHY data width 55962306a36Sopenharmony_ci * 0 - 8 bits 56062306a36Sopenharmony_ci * 1 - 16 bits 56162306a36Sopenharmony_ci * 2 - 8 or 16 bits 56262306a36Sopenharmony_ci * @snpsid: Value from SNPSID register 56362306a36Sopenharmony_ci * @dev_ep_dirs: Direction of device endpoints (GHWCFG1) 56462306a36Sopenharmony_ci * @g_tx_fifo_size: Power-on values of TxFIFO sizes 56562306a36Sopenharmony_ci * @dma_desc_enable: When DMA mode is enabled, specifies whether to use 56662306a36Sopenharmony_ci * address DMA mode or descriptor DMA mode for accessing 56762306a36Sopenharmony_ci * the data FIFOs. The driver will automatically detect the 56862306a36Sopenharmony_ci * value for this if none is specified. 56962306a36Sopenharmony_ci * 0 - Address DMA 57062306a36Sopenharmony_ci * 1 - Descriptor DMA (default, if available) 57162306a36Sopenharmony_ci * @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters 57262306a36Sopenharmony_ci * 1 - Allow dynamic FIFO sizing (default, if available) 57362306a36Sopenharmony_ci * @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs 57462306a36Sopenharmony_ci * are enabled for non-periodic IN endpoints in device 57562306a36Sopenharmony_ci * mode. 57662306a36Sopenharmony_ci * @host_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO 57762306a36Sopenharmony_ci * in host mode when dynamic FIFO sizing is enabled 57862306a36Sopenharmony_ci * 16 to 32768 57962306a36Sopenharmony_ci * Actual maximum value is autodetected and also 58062306a36Sopenharmony_ci * the default. 58162306a36Sopenharmony_ci * @host_perio_tx_fifo_size: Number of 4-byte words in the periodic Tx FIFO in 58262306a36Sopenharmony_ci * host mode when dynamic FIFO sizing is enabled 58362306a36Sopenharmony_ci * 16 to 32768 58462306a36Sopenharmony_ci * Actual maximum value is autodetected and also 58562306a36Sopenharmony_ci * the default. 58662306a36Sopenharmony_ci * @max_transfer_size: The maximum transfer size supported, in bytes 58762306a36Sopenharmony_ci * 2047 to 65,535 58862306a36Sopenharmony_ci * Actual maximum value is autodetected and also 58962306a36Sopenharmony_ci * the default. 59062306a36Sopenharmony_ci * @max_packet_count: The maximum number of packets in a transfer 59162306a36Sopenharmony_ci * 15 to 511 59262306a36Sopenharmony_ci * Actual maximum value is autodetected and also 59362306a36Sopenharmony_ci * the default. 59462306a36Sopenharmony_ci * @host_channels: The number of host channel registers to use 59562306a36Sopenharmony_ci * 1 to 16 59662306a36Sopenharmony_ci * Actual maximum value is autodetected and also 59762306a36Sopenharmony_ci * the default. 59862306a36Sopenharmony_ci * @dev_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO 59962306a36Sopenharmony_ci * in device mode when dynamic FIFO sizing is enabled 60062306a36Sopenharmony_ci * 16 to 32768 60162306a36Sopenharmony_ci * Actual maximum value is autodetected and also 60262306a36Sopenharmony_ci * the default. 60362306a36Sopenharmony_ci * @i2c_enable: Specifies whether to use the I2Cinterface for a full 60462306a36Sopenharmony_ci * speed PHY. This parameter is only applicable if phy_type 60562306a36Sopenharmony_ci * is FS. 60662306a36Sopenharmony_ci * 0 - No (default) 60762306a36Sopenharmony_ci * 1 - Yes 60862306a36Sopenharmony_ci * @acg_enable: For enabling Active Clock Gating in the controller 60962306a36Sopenharmony_ci * 0 - Disable 61062306a36Sopenharmony_ci * 1 - Enable 61162306a36Sopenharmony_ci * @lpm_mode: For enabling Link Power Management in the controller 61262306a36Sopenharmony_ci * 0 - Disable 61362306a36Sopenharmony_ci * 1 - Enable 61462306a36Sopenharmony_ci * @rx_fifo_size: Number of 4-byte words in the Rx FIFO when dynamic 61562306a36Sopenharmony_ci * FIFO sizing is enabled 16 to 32768 61662306a36Sopenharmony_ci * Actual maximum value is autodetected and also 61762306a36Sopenharmony_ci * the default. 61862306a36Sopenharmony_ci * @service_interval_mode: For enabling service interval based scheduling in the 61962306a36Sopenharmony_ci * controller. 62062306a36Sopenharmony_ci * 0 - Disable 62162306a36Sopenharmony_ci * 1 - Enable 62262306a36Sopenharmony_ci */ 62362306a36Sopenharmony_cistruct dwc2_hw_params { 62462306a36Sopenharmony_ci unsigned op_mode:3; 62562306a36Sopenharmony_ci unsigned arch:2; 62662306a36Sopenharmony_ci unsigned dma_desc_enable:1; 62762306a36Sopenharmony_ci unsigned enable_dynamic_fifo:1; 62862306a36Sopenharmony_ci unsigned en_multiple_tx_fifo:1; 62962306a36Sopenharmony_ci unsigned rx_fifo_size:16; 63062306a36Sopenharmony_ci unsigned host_nperio_tx_fifo_size:16; 63162306a36Sopenharmony_ci unsigned dev_nperio_tx_fifo_size:16; 63262306a36Sopenharmony_ci unsigned host_perio_tx_fifo_size:16; 63362306a36Sopenharmony_ci unsigned nperio_tx_q_depth:3; 63462306a36Sopenharmony_ci unsigned host_perio_tx_q_depth:3; 63562306a36Sopenharmony_ci unsigned dev_token_q_depth:5; 63662306a36Sopenharmony_ci unsigned max_transfer_size:26; 63762306a36Sopenharmony_ci unsigned max_packet_count:11; 63862306a36Sopenharmony_ci unsigned host_channels:5; 63962306a36Sopenharmony_ci unsigned hs_phy_type:2; 64062306a36Sopenharmony_ci unsigned fs_phy_type:2; 64162306a36Sopenharmony_ci unsigned i2c_enable:1; 64262306a36Sopenharmony_ci unsigned acg_enable:1; 64362306a36Sopenharmony_ci unsigned num_dev_ep:4; 64462306a36Sopenharmony_ci unsigned num_dev_in_eps : 4; 64562306a36Sopenharmony_ci unsigned num_dev_perio_in_ep:4; 64662306a36Sopenharmony_ci unsigned total_fifo_size:16; 64762306a36Sopenharmony_ci unsigned power_optimized:1; 64862306a36Sopenharmony_ci unsigned hibernation:1; 64962306a36Sopenharmony_ci unsigned utmi_phy_data_width:2; 65062306a36Sopenharmony_ci unsigned lpm_mode:1; 65162306a36Sopenharmony_ci unsigned ipg_isoc_en:1; 65262306a36Sopenharmony_ci unsigned service_interval_mode:1; 65362306a36Sopenharmony_ci u32 snpsid; 65462306a36Sopenharmony_ci u32 dev_ep_dirs; 65562306a36Sopenharmony_ci u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; 65662306a36Sopenharmony_ci}; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci/* Size of control and EP0 buffers */ 65962306a36Sopenharmony_ci#define DWC2_CTRL_BUFF_SIZE 8 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci/** 66262306a36Sopenharmony_ci * struct dwc2_gregs_backup - Holds global registers state before 66362306a36Sopenharmony_ci * entering partial power down 66462306a36Sopenharmony_ci * @gotgctl: Backup of GOTGCTL register 66562306a36Sopenharmony_ci * @gintmsk: Backup of GINTMSK register 66662306a36Sopenharmony_ci * @gahbcfg: Backup of GAHBCFG register 66762306a36Sopenharmony_ci * @gusbcfg: Backup of GUSBCFG register 66862306a36Sopenharmony_ci * @grxfsiz: Backup of GRXFSIZ register 66962306a36Sopenharmony_ci * @gnptxfsiz: Backup of GNPTXFSIZ register 67062306a36Sopenharmony_ci * @gi2cctl: Backup of GI2CCTL register 67162306a36Sopenharmony_ci * @glpmcfg: Backup of GLPMCFG register 67262306a36Sopenharmony_ci * @gdfifocfg: Backup of GDFIFOCFG register 67362306a36Sopenharmony_ci * @pcgcctl: Backup of PCGCCTL register 67462306a36Sopenharmony_ci * @pcgcctl1: Backup of PCGCCTL1 register 67562306a36Sopenharmony_ci * @dtxfsiz: Backup of DTXFSIZ registers for each endpoint 67662306a36Sopenharmony_ci * @gpwrdn: Backup of GPWRDN register 67762306a36Sopenharmony_ci * @valid: True if registers values backuped. 67862306a36Sopenharmony_ci */ 67962306a36Sopenharmony_cistruct dwc2_gregs_backup { 68062306a36Sopenharmony_ci u32 gotgctl; 68162306a36Sopenharmony_ci u32 gintmsk; 68262306a36Sopenharmony_ci u32 gahbcfg; 68362306a36Sopenharmony_ci u32 gusbcfg; 68462306a36Sopenharmony_ci u32 grxfsiz; 68562306a36Sopenharmony_ci u32 gnptxfsiz; 68662306a36Sopenharmony_ci u32 gi2cctl; 68762306a36Sopenharmony_ci u32 glpmcfg; 68862306a36Sopenharmony_ci u32 pcgcctl; 68962306a36Sopenharmony_ci u32 pcgcctl1; 69062306a36Sopenharmony_ci u32 gdfifocfg; 69162306a36Sopenharmony_ci u32 gpwrdn; 69262306a36Sopenharmony_ci bool valid; 69362306a36Sopenharmony_ci}; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci/** 69662306a36Sopenharmony_ci * struct dwc2_dregs_backup - Holds device registers state before 69762306a36Sopenharmony_ci * entering partial power down 69862306a36Sopenharmony_ci * @dcfg: Backup of DCFG register 69962306a36Sopenharmony_ci * @dctl: Backup of DCTL register 70062306a36Sopenharmony_ci * @daintmsk: Backup of DAINTMSK register 70162306a36Sopenharmony_ci * @diepmsk: Backup of DIEPMSK register 70262306a36Sopenharmony_ci * @doepmsk: Backup of DOEPMSK register 70362306a36Sopenharmony_ci * @diepctl: Backup of DIEPCTL register 70462306a36Sopenharmony_ci * @dieptsiz: Backup of DIEPTSIZ register 70562306a36Sopenharmony_ci * @diepdma: Backup of DIEPDMA register 70662306a36Sopenharmony_ci * @doepctl: Backup of DOEPCTL register 70762306a36Sopenharmony_ci * @doeptsiz: Backup of DOEPTSIZ register 70862306a36Sopenharmony_ci * @doepdma: Backup of DOEPDMA register 70962306a36Sopenharmony_ci * @dtxfsiz: Backup of DTXFSIZ registers for each endpoint 71062306a36Sopenharmony_ci * @valid: True if registers values backuped. 71162306a36Sopenharmony_ci */ 71262306a36Sopenharmony_cistruct dwc2_dregs_backup { 71362306a36Sopenharmony_ci u32 dcfg; 71462306a36Sopenharmony_ci u32 dctl; 71562306a36Sopenharmony_ci u32 daintmsk; 71662306a36Sopenharmony_ci u32 diepmsk; 71762306a36Sopenharmony_ci u32 doepmsk; 71862306a36Sopenharmony_ci u32 diepctl[MAX_EPS_CHANNELS]; 71962306a36Sopenharmony_ci u32 dieptsiz[MAX_EPS_CHANNELS]; 72062306a36Sopenharmony_ci u32 diepdma[MAX_EPS_CHANNELS]; 72162306a36Sopenharmony_ci u32 doepctl[MAX_EPS_CHANNELS]; 72262306a36Sopenharmony_ci u32 doeptsiz[MAX_EPS_CHANNELS]; 72362306a36Sopenharmony_ci u32 doepdma[MAX_EPS_CHANNELS]; 72462306a36Sopenharmony_ci u32 dtxfsiz[MAX_EPS_CHANNELS]; 72562306a36Sopenharmony_ci bool valid; 72662306a36Sopenharmony_ci}; 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci/** 72962306a36Sopenharmony_ci * struct dwc2_hregs_backup - Holds host registers state before 73062306a36Sopenharmony_ci * entering partial power down 73162306a36Sopenharmony_ci * @hcfg: Backup of HCFG register 73262306a36Sopenharmony_ci * @haintmsk: Backup of HAINTMSK register 73362306a36Sopenharmony_ci * @hcintmsk: Backup of HCINTMSK register 73462306a36Sopenharmony_ci * @hprt0: Backup of HPTR0 register 73562306a36Sopenharmony_ci * @hfir: Backup of HFIR register 73662306a36Sopenharmony_ci * @hptxfsiz: Backup of HPTXFSIZ register 73762306a36Sopenharmony_ci * @valid: True if registers values backuped. 73862306a36Sopenharmony_ci */ 73962306a36Sopenharmony_cistruct dwc2_hregs_backup { 74062306a36Sopenharmony_ci u32 hcfg; 74162306a36Sopenharmony_ci u32 haintmsk; 74262306a36Sopenharmony_ci u32 hcintmsk[MAX_EPS_CHANNELS]; 74362306a36Sopenharmony_ci u32 hprt0; 74462306a36Sopenharmony_ci u32 hfir; 74562306a36Sopenharmony_ci u32 hptxfsiz; 74662306a36Sopenharmony_ci bool valid; 74762306a36Sopenharmony_ci}; 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci/* 75062306a36Sopenharmony_ci * Constants related to high speed periodic scheduling 75162306a36Sopenharmony_ci * 75262306a36Sopenharmony_ci * We have a periodic schedule that is DWC2_HS_SCHEDULE_UFRAMES long. From a 75362306a36Sopenharmony_ci * reservation point of view it's assumed that the schedule goes right back to 75462306a36Sopenharmony_ci * the beginning after the end of the schedule. 75562306a36Sopenharmony_ci * 75662306a36Sopenharmony_ci * What does that mean for scheduling things with a long interval? It means 75762306a36Sopenharmony_ci * we'll reserve time for them in every possible microframe that they could 75862306a36Sopenharmony_ci * ever be scheduled in. ...but we'll still only actually schedule them as 75962306a36Sopenharmony_ci * often as they were requested. 76062306a36Sopenharmony_ci * 76162306a36Sopenharmony_ci * We keep our schedule in a "bitmap" structure. This simplifies having 76262306a36Sopenharmony_ci * to keep track of and merge intervals: we just let the bitmap code do most 76362306a36Sopenharmony_ci * of the heavy lifting. In a way scheduling is much like memory allocation. 76462306a36Sopenharmony_ci * 76562306a36Sopenharmony_ci * We schedule 100us per uframe or 80% of 125us (the maximum amount you're 76662306a36Sopenharmony_ci * supposed to schedule for periodic transfers). That's according to spec. 76762306a36Sopenharmony_ci * 76862306a36Sopenharmony_ci * Note that though we only schedule 80% of each microframe, the bitmap that we 76962306a36Sopenharmony_ci * keep the schedule in is tightly packed (AKA it doesn't have 100us worth of 77062306a36Sopenharmony_ci * space for each uFrame). 77162306a36Sopenharmony_ci * 77262306a36Sopenharmony_ci * Requirements: 77362306a36Sopenharmony_ci * - DWC2_HS_SCHEDULE_UFRAMES must even divide 0x4000 (HFNUM_MAX_FRNUM + 1) 77462306a36Sopenharmony_ci * - DWC2_HS_SCHEDULE_UFRAMES must be 8 times DWC2_LS_SCHEDULE_FRAMES (probably 77562306a36Sopenharmony_ci * could be any multiple of 8 times DWC2_LS_SCHEDULE_FRAMES, but there might 77662306a36Sopenharmony_ci * be bugs). The 8 comes from the USB spec: number of microframes per frame. 77762306a36Sopenharmony_ci */ 77862306a36Sopenharmony_ci#define DWC2_US_PER_UFRAME 125 77962306a36Sopenharmony_ci#define DWC2_HS_PERIODIC_US_PER_UFRAME 100 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci#define DWC2_HS_SCHEDULE_UFRAMES 8 78262306a36Sopenharmony_ci#define DWC2_HS_SCHEDULE_US (DWC2_HS_SCHEDULE_UFRAMES * \ 78362306a36Sopenharmony_ci DWC2_HS_PERIODIC_US_PER_UFRAME) 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci/* 78662306a36Sopenharmony_ci * Constants related to low speed scheduling 78762306a36Sopenharmony_ci * 78862306a36Sopenharmony_ci * For high speed we schedule every 1us. For low speed that's a bit overkill, 78962306a36Sopenharmony_ci * so we make up a unit called a "slice" that's worth 25us. There are 40 79062306a36Sopenharmony_ci * slices in a full frame and we can schedule 36 of those (90%) for periodic 79162306a36Sopenharmony_ci * transfers. 79262306a36Sopenharmony_ci * 79362306a36Sopenharmony_ci * Our low speed schedule can be as short as 1 frame or could be longer. When 79462306a36Sopenharmony_ci * we only schedule 1 frame it means that we'll need to reserve a time every 79562306a36Sopenharmony_ci * frame even for things that only transfer very rarely, so something that runs 79662306a36Sopenharmony_ci * every 2048 frames will get time reserved in every frame. Our low speed 79762306a36Sopenharmony_ci * schedule can be longer and we'll be able to handle more overlap, but that 79862306a36Sopenharmony_ci * will come at increased memory cost and increased time to schedule. 79962306a36Sopenharmony_ci * 80062306a36Sopenharmony_ci * Note: one other advantage of a short low speed schedule is that if we mess 80162306a36Sopenharmony_ci * up and miss scheduling we can jump in and use any of the slots that we 80262306a36Sopenharmony_ci * happened to reserve. 80362306a36Sopenharmony_ci * 80462306a36Sopenharmony_ci * With 25 us per slice and 1 frame in the schedule, we only need 4 bytes for 80562306a36Sopenharmony_ci * the schedule. There will be one schedule per TT. 80662306a36Sopenharmony_ci * 80762306a36Sopenharmony_ci * Requirements: 80862306a36Sopenharmony_ci * - DWC2_US_PER_SLICE must evenly divide DWC2_LS_PERIODIC_US_PER_FRAME. 80962306a36Sopenharmony_ci */ 81062306a36Sopenharmony_ci#define DWC2_US_PER_SLICE 25 81162306a36Sopenharmony_ci#define DWC2_SLICES_PER_UFRAME (DWC2_US_PER_UFRAME / DWC2_US_PER_SLICE) 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci#define DWC2_ROUND_US_TO_SLICE(us) \ 81462306a36Sopenharmony_ci (DIV_ROUND_UP((us), DWC2_US_PER_SLICE) * \ 81562306a36Sopenharmony_ci DWC2_US_PER_SLICE) 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci#define DWC2_LS_PERIODIC_US_PER_FRAME \ 81862306a36Sopenharmony_ci 900 81962306a36Sopenharmony_ci#define DWC2_LS_PERIODIC_SLICES_PER_FRAME \ 82062306a36Sopenharmony_ci (DWC2_LS_PERIODIC_US_PER_FRAME / \ 82162306a36Sopenharmony_ci DWC2_US_PER_SLICE) 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci#define DWC2_LS_SCHEDULE_FRAMES 1 82462306a36Sopenharmony_ci#define DWC2_LS_SCHEDULE_SLICES (DWC2_LS_SCHEDULE_FRAMES * \ 82562306a36Sopenharmony_ci DWC2_LS_PERIODIC_SLICES_PER_FRAME) 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci/** 82862306a36Sopenharmony_ci * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic 82962306a36Sopenharmony_ci * and periodic schedules 83062306a36Sopenharmony_ci * 83162306a36Sopenharmony_ci * These are common for both host and peripheral modes: 83262306a36Sopenharmony_ci * 83362306a36Sopenharmony_ci * @dev: The struct device pointer 83462306a36Sopenharmony_ci * @regs: Pointer to controller regs 83562306a36Sopenharmony_ci * @hw_params: Parameters that were autodetected from the 83662306a36Sopenharmony_ci * hardware registers 83762306a36Sopenharmony_ci * @params: Parameters that define how the core should be configured 83862306a36Sopenharmony_ci * @op_state: The operational State, during transitions (a_host=> 83962306a36Sopenharmony_ci * a_peripheral and b_device=>b_host) this may not match 84062306a36Sopenharmony_ci * the core, but allows the software to determine 84162306a36Sopenharmony_ci * transitions 84262306a36Sopenharmony_ci * @dr_mode: Requested mode of operation, one of following: 84362306a36Sopenharmony_ci * - USB_DR_MODE_PERIPHERAL 84462306a36Sopenharmony_ci * - USB_DR_MODE_HOST 84562306a36Sopenharmony_ci * - USB_DR_MODE_OTG 84662306a36Sopenharmony_ci * @role_sw: usb_role_switch handle 84762306a36Sopenharmony_ci * @role_sw_default_mode: default operation mode of controller while usb role 84862306a36Sopenharmony_ci * is USB_ROLE_NONE 84962306a36Sopenharmony_ci * @hcd_enabled: Host mode sub-driver initialization indicator. 85062306a36Sopenharmony_ci * @gadget_enabled: Peripheral mode sub-driver initialization indicator. 85162306a36Sopenharmony_ci * @ll_hw_enabled: Status of low-level hardware resources. 85262306a36Sopenharmony_ci * @hibernated: True if core is hibernated 85362306a36Sopenharmony_ci * @in_ppd: True if core is partial power down mode. 85462306a36Sopenharmony_ci * @bus_suspended: True if bus is suspended 85562306a36Sopenharmony_ci * @reset_phy_on_wake: Quirk saying that we should assert PHY reset on a 85662306a36Sopenharmony_ci * remote wakeup. 85762306a36Sopenharmony_ci * @phy_off_for_suspend: Status of whether we turned the PHY off at suspend. 85862306a36Sopenharmony_ci * @need_phy_for_wake: Quirk saying that we should keep the PHY on at 85962306a36Sopenharmony_ci * suspend if we need USB to wake us up. 86062306a36Sopenharmony_ci * @frame_number: Frame number read from the core. For both device 86162306a36Sopenharmony_ci * and host modes. The value ranges are from 0 86262306a36Sopenharmony_ci * to HFNUM_MAX_FRNUM. 86362306a36Sopenharmony_ci * @phy: The otg phy transceiver structure for phy control. 86462306a36Sopenharmony_ci * @uphy: The otg phy transceiver structure for old USB phy 86562306a36Sopenharmony_ci * control. 86662306a36Sopenharmony_ci * @plat: The platform specific configuration data. This can be 86762306a36Sopenharmony_ci * removed once all SoCs support usb transceiver. 86862306a36Sopenharmony_ci * @supplies: Definition of USB power supplies 86962306a36Sopenharmony_ci * @vbus_supply: Regulator supplying vbus. 87062306a36Sopenharmony_ci * @usb33d: Optional 3.3v regulator used on some stm32 devices to 87162306a36Sopenharmony_ci * supply ID and VBUS detection hardware. 87262306a36Sopenharmony_ci * @lock: Spinlock that protects all the driver data structures 87362306a36Sopenharmony_ci * @priv: Stores a pointer to the struct usb_hcd 87462306a36Sopenharmony_ci * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth 87562306a36Sopenharmony_ci * transfer are in process of being queued 87662306a36Sopenharmony_ci * @srp_success: Stores status of SRP request in the case of a FS PHY 87762306a36Sopenharmony_ci * with an I2C interface 87862306a36Sopenharmony_ci * @wq_otg: Workqueue object used for handling of some interrupts 87962306a36Sopenharmony_ci * @wf_otg: Work object for handling Connector ID Status Change 88062306a36Sopenharmony_ci * interrupt 88162306a36Sopenharmony_ci * @wkp_timer: Timer object for handling Wakeup Detected interrupt 88262306a36Sopenharmony_ci * @lx_state: Lx state of connected device 88362306a36Sopenharmony_ci * @gr_backup: Backup of global registers during suspend 88462306a36Sopenharmony_ci * @dr_backup: Backup of device registers during suspend 88562306a36Sopenharmony_ci * @hr_backup: Backup of host registers during suspend 88662306a36Sopenharmony_ci * @needs_byte_swap: Specifies whether the opposite endianness. 88762306a36Sopenharmony_ci * 88862306a36Sopenharmony_ci * These are for host mode: 88962306a36Sopenharmony_ci * 89062306a36Sopenharmony_ci * @flags: Flags for handling root port state changes 89162306a36Sopenharmony_ci * @flags.d32: Contain all root port flags 89262306a36Sopenharmony_ci * @flags.b: Separate root port flags from each other 89362306a36Sopenharmony_ci * @flags.b.port_connect_status_change: True if root port connect status 89462306a36Sopenharmony_ci * changed 89562306a36Sopenharmony_ci * @flags.b.port_connect_status: True if device connected to root port 89662306a36Sopenharmony_ci * @flags.b.port_reset_change: True if root port reset status changed 89762306a36Sopenharmony_ci * @flags.b.port_enable_change: True if root port enable status changed 89862306a36Sopenharmony_ci * @flags.b.port_suspend_change: True if root port suspend status changed 89962306a36Sopenharmony_ci * @flags.b.port_over_current_change: True if root port over current state 90062306a36Sopenharmony_ci * changed. 90162306a36Sopenharmony_ci * @flags.b.port_l1_change: True if root port l1 status changed 90262306a36Sopenharmony_ci * @flags.b.reserved: Reserved bits of root port register 90362306a36Sopenharmony_ci * @non_periodic_sched_inactive: Inactive QHs in the non-periodic schedule. 90462306a36Sopenharmony_ci * Transfers associated with these QHs are not currently 90562306a36Sopenharmony_ci * assigned to a host channel. 90662306a36Sopenharmony_ci * @non_periodic_sched_active: Active QHs in the non-periodic schedule. 90762306a36Sopenharmony_ci * Transfers associated with these QHs are currently 90862306a36Sopenharmony_ci * assigned to a host channel. 90962306a36Sopenharmony_ci * @non_periodic_qh_ptr: Pointer to next QH to process in the active 91062306a36Sopenharmony_ci * non-periodic schedule 91162306a36Sopenharmony_ci * @non_periodic_sched_waiting: Waiting QHs in the non-periodic schedule. 91262306a36Sopenharmony_ci * Transfers associated with these QHs are not currently 91362306a36Sopenharmony_ci * assigned to a host channel. 91462306a36Sopenharmony_ci * @periodic_sched_inactive: Inactive QHs in the periodic schedule. This is a 91562306a36Sopenharmony_ci * list of QHs for periodic transfers that are _not_ 91662306a36Sopenharmony_ci * scheduled for the next frame. Each QH in the list has an 91762306a36Sopenharmony_ci * interval counter that determines when it needs to be 91862306a36Sopenharmony_ci * scheduled for execution. This scheduling mechanism 91962306a36Sopenharmony_ci * allows only a simple calculation for periodic bandwidth 92062306a36Sopenharmony_ci * used (i.e. must assume that all periodic transfers may 92162306a36Sopenharmony_ci * need to execute in the same frame). However, it greatly 92262306a36Sopenharmony_ci * simplifies scheduling and should be sufficient for the 92362306a36Sopenharmony_ci * vast majority of OTG hosts, which need to connect to a 92462306a36Sopenharmony_ci * small number of peripherals at one time. Items move from 92562306a36Sopenharmony_ci * this list to periodic_sched_ready when the QH interval 92662306a36Sopenharmony_ci * counter is 0 at SOF. 92762306a36Sopenharmony_ci * @periodic_sched_ready: List of periodic QHs that are ready for execution in 92862306a36Sopenharmony_ci * the next frame, but have not yet been assigned to host 92962306a36Sopenharmony_ci * channels. Items move from this list to 93062306a36Sopenharmony_ci * periodic_sched_assigned as host channels become 93162306a36Sopenharmony_ci * available during the current frame. 93262306a36Sopenharmony_ci * @periodic_sched_assigned: List of periodic QHs to be executed in the next 93362306a36Sopenharmony_ci * frame that are assigned to host channels. Items move 93462306a36Sopenharmony_ci * from this list to periodic_sched_queued as the 93562306a36Sopenharmony_ci * transactions for the QH are queued to the DWC_otg 93662306a36Sopenharmony_ci * controller. 93762306a36Sopenharmony_ci * @periodic_sched_queued: List of periodic QHs that have been queued for 93862306a36Sopenharmony_ci * execution. Items move from this list to either 93962306a36Sopenharmony_ci * periodic_sched_inactive or periodic_sched_ready when the 94062306a36Sopenharmony_ci * channel associated with the transfer is released. If the 94162306a36Sopenharmony_ci * interval for the QH is 1, the item moves to 94262306a36Sopenharmony_ci * periodic_sched_ready because it must be rescheduled for 94362306a36Sopenharmony_ci * the next frame. Otherwise, the item moves to 94462306a36Sopenharmony_ci * periodic_sched_inactive. 94562306a36Sopenharmony_ci * @split_order: List keeping track of channels doing splits, in order. 94662306a36Sopenharmony_ci * @periodic_usecs: Total bandwidth claimed so far for periodic transfers. 94762306a36Sopenharmony_ci * This value is in microseconds per (micro)frame. The 94862306a36Sopenharmony_ci * assumption is that all periodic transfers may occur in 94962306a36Sopenharmony_ci * the same (micro)frame. 95062306a36Sopenharmony_ci * @hs_periodic_bitmap: Bitmap used by the microframe scheduler any time the 95162306a36Sopenharmony_ci * host is in high speed mode; low speed schedules are 95262306a36Sopenharmony_ci * stored elsewhere since we need one per TT. 95362306a36Sopenharmony_ci * @periodic_qh_count: Count of periodic QHs, if using several eps. Used for 95462306a36Sopenharmony_ci * SOF enable/disable. 95562306a36Sopenharmony_ci * @free_hc_list: Free host channels in the controller. This is a list of 95662306a36Sopenharmony_ci * struct dwc2_host_chan items. 95762306a36Sopenharmony_ci * @periodic_channels: Number of host channels assigned to periodic transfers. 95862306a36Sopenharmony_ci * Currently assuming that there is a dedicated host 95962306a36Sopenharmony_ci * channel for each periodic transaction and at least one 96062306a36Sopenharmony_ci * host channel is available for non-periodic transactions. 96162306a36Sopenharmony_ci * @non_periodic_channels: Number of host channels assigned to non-periodic 96262306a36Sopenharmony_ci * transfers 96362306a36Sopenharmony_ci * @available_host_channels: Number of host channels available for the 96462306a36Sopenharmony_ci * microframe scheduler to use 96562306a36Sopenharmony_ci * @hc_ptr_array: Array of pointers to the host channel descriptors. 96662306a36Sopenharmony_ci * Allows accessing a host channel descriptor given the 96762306a36Sopenharmony_ci * host channel number. This is useful in interrupt 96862306a36Sopenharmony_ci * handlers. 96962306a36Sopenharmony_ci * @status_buf: Buffer used for data received during the status phase of 97062306a36Sopenharmony_ci * a control transfer. 97162306a36Sopenharmony_ci * @status_buf_dma: DMA address for status_buf 97262306a36Sopenharmony_ci * @start_work: Delayed work for handling host A-cable connection 97362306a36Sopenharmony_ci * @reset_work: Delayed work for handling a port reset 97462306a36Sopenharmony_ci * @phy_reset_work: Work structure for doing a PHY reset 97562306a36Sopenharmony_ci * @otg_port: OTG port number 97662306a36Sopenharmony_ci * @frame_list: Frame list 97762306a36Sopenharmony_ci * @frame_list_dma: Frame list DMA address 97862306a36Sopenharmony_ci * @frame_list_sz: Frame list size 97962306a36Sopenharmony_ci * @desc_gen_cache: Kmem cache for generic descriptors 98062306a36Sopenharmony_ci * @desc_hsisoc_cache: Kmem cache for hs isochronous descriptors 98162306a36Sopenharmony_ci * @unaligned_cache: Kmem cache for DMA mode to handle non-aligned buf 98262306a36Sopenharmony_ci * 98362306a36Sopenharmony_ci * These are for peripheral mode: 98462306a36Sopenharmony_ci * 98562306a36Sopenharmony_ci * @driver: USB gadget driver 98662306a36Sopenharmony_ci * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. 98762306a36Sopenharmony_ci * @num_of_eps: Number of available EPs (excluding EP0) 98862306a36Sopenharmony_ci * @debug_root: Root directrory for debugfs. 98962306a36Sopenharmony_ci * @ep0_reply: Request used for ep0 reply. 99062306a36Sopenharmony_ci * @ep0_buff: Buffer for EP0 reply data, if needed. 99162306a36Sopenharmony_ci * @ctrl_buff: Buffer for EP0 control requests. 99262306a36Sopenharmony_ci * @ctrl_req: Request for EP0 control packets. 99362306a36Sopenharmony_ci * @ep0_state: EP0 control transfers state 99462306a36Sopenharmony_ci * @delayed_status: true when gadget driver asks for delayed status 99562306a36Sopenharmony_ci * @test_mode: USB test mode requested by the host 99662306a36Sopenharmony_ci * @remote_wakeup_allowed: True if device is allowed to wake-up host by 99762306a36Sopenharmony_ci * remote-wakeup signalling 99862306a36Sopenharmony_ci * @setup_desc_dma: EP0 setup stage desc chain DMA address 99962306a36Sopenharmony_ci * @setup_desc: EP0 setup stage desc chain pointer 100062306a36Sopenharmony_ci * @ctrl_in_desc_dma: EP0 IN data phase desc chain DMA address 100162306a36Sopenharmony_ci * @ctrl_in_desc: EP0 IN data phase desc chain pointer 100262306a36Sopenharmony_ci * @ctrl_out_desc_dma: EP0 OUT data phase desc chain DMA address 100362306a36Sopenharmony_ci * @ctrl_out_desc: EP0 OUT data phase desc chain pointer 100462306a36Sopenharmony_ci * @irq: Interrupt request line number 100562306a36Sopenharmony_ci * @clk: Pointer to otg clock 100662306a36Sopenharmony_ci * @utmi_clk: Pointer to utmi_clk clock 100762306a36Sopenharmony_ci * @reset: Pointer to dwc2 reset controller 100862306a36Sopenharmony_ci * @reset_ecc: Pointer to dwc2 optional reset controller in Stratix10. 100962306a36Sopenharmony_ci * @regset: A pointer to a struct debugfs_regset32, which contains 101062306a36Sopenharmony_ci * a pointer to an array of register definitions, the 101162306a36Sopenharmony_ci * array size and the base address where the register bank 101262306a36Sopenharmony_ci * is to be found. 101362306a36Sopenharmony_ci * @last_frame_num: Number of last frame. Range from 0 to 32768 101462306a36Sopenharmony_ci * @frame_num_array: Used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is 101562306a36Sopenharmony_ci * defined, for missed SOFs tracking. Array holds that 101662306a36Sopenharmony_ci * frame numbers, which not equal to last_frame_num +1 101762306a36Sopenharmony_ci * @last_frame_num_array: Used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is 101862306a36Sopenharmony_ci * defined, for missed SOFs tracking. 101962306a36Sopenharmony_ci * If current_frame_number != last_frame_num+1 102062306a36Sopenharmony_ci * then last_frame_num added to this array 102162306a36Sopenharmony_ci * @frame_num_idx: Actual size of frame_num_array and last_frame_num_array 102262306a36Sopenharmony_ci * @dumped_frame_num_array: 1 - if missed SOFs frame numbers dumbed 102362306a36Sopenharmony_ci * 0 - if missed SOFs frame numbers not dumbed 102462306a36Sopenharmony_ci * @fifo_mem: Total internal RAM for FIFOs (bytes) 102562306a36Sopenharmony_ci * @fifo_map: Each bit intend for concrete fifo. If that bit is set, 102662306a36Sopenharmony_ci * then that fifo is used 102762306a36Sopenharmony_ci * @gadget: Represents a usb gadget device 102862306a36Sopenharmony_ci * @connected: Used in slave mode. True if device connected with host 102962306a36Sopenharmony_ci * @eps_in: The IN endpoints being supplied to the gadget framework 103062306a36Sopenharmony_ci * @eps_out: The OUT endpoints being supplied to the gadget framework 103162306a36Sopenharmony_ci * @new_connection: Used in host mode. True if there are new connected 103262306a36Sopenharmony_ci * device 103362306a36Sopenharmony_ci * @enabled: Indicates the enabling state of controller 103462306a36Sopenharmony_ci * 103562306a36Sopenharmony_ci */ 103662306a36Sopenharmony_cistruct dwc2_hsotg { 103762306a36Sopenharmony_ci struct device *dev; 103862306a36Sopenharmony_ci void __iomem *regs; 103962306a36Sopenharmony_ci /** Params detected from hardware */ 104062306a36Sopenharmony_ci struct dwc2_hw_params hw_params; 104162306a36Sopenharmony_ci /** Params to actually use */ 104262306a36Sopenharmony_ci struct dwc2_core_params params; 104362306a36Sopenharmony_ci enum usb_otg_state op_state; 104462306a36Sopenharmony_ci enum usb_dr_mode dr_mode; 104562306a36Sopenharmony_ci struct usb_role_switch *role_sw; 104662306a36Sopenharmony_ci enum usb_dr_mode role_sw_default_mode; 104762306a36Sopenharmony_ci unsigned int hcd_enabled:1; 104862306a36Sopenharmony_ci unsigned int gadget_enabled:1; 104962306a36Sopenharmony_ci unsigned int ll_hw_enabled:1; 105062306a36Sopenharmony_ci unsigned int hibernated:1; 105162306a36Sopenharmony_ci unsigned int in_ppd:1; 105262306a36Sopenharmony_ci bool bus_suspended; 105362306a36Sopenharmony_ci unsigned int reset_phy_on_wake:1; 105462306a36Sopenharmony_ci unsigned int need_phy_for_wake:1; 105562306a36Sopenharmony_ci unsigned int phy_off_for_suspend:1; 105662306a36Sopenharmony_ci u16 frame_number; 105762306a36Sopenharmony_ci 105862306a36Sopenharmony_ci struct phy *phy; 105962306a36Sopenharmony_ci struct usb_phy *uphy; 106062306a36Sopenharmony_ci struct dwc2_hsotg_plat *plat; 106162306a36Sopenharmony_ci struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES]; 106262306a36Sopenharmony_ci struct regulator *vbus_supply; 106362306a36Sopenharmony_ci struct regulator *usb33d; 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_ci spinlock_t lock; 106662306a36Sopenharmony_ci void *priv; 106762306a36Sopenharmony_ci int irq; 106862306a36Sopenharmony_ci struct clk *clk; 106962306a36Sopenharmony_ci struct clk *utmi_clk; 107062306a36Sopenharmony_ci struct reset_control *reset; 107162306a36Sopenharmony_ci struct reset_control *reset_ecc; 107262306a36Sopenharmony_ci 107362306a36Sopenharmony_ci unsigned int queuing_high_bandwidth:1; 107462306a36Sopenharmony_ci unsigned int srp_success:1; 107562306a36Sopenharmony_ci 107662306a36Sopenharmony_ci struct workqueue_struct *wq_otg; 107762306a36Sopenharmony_ci struct work_struct wf_otg; 107862306a36Sopenharmony_ci struct timer_list wkp_timer; 107962306a36Sopenharmony_ci enum dwc2_lx_state lx_state; 108062306a36Sopenharmony_ci struct dwc2_gregs_backup gr_backup; 108162306a36Sopenharmony_ci struct dwc2_dregs_backup dr_backup; 108262306a36Sopenharmony_ci struct dwc2_hregs_backup hr_backup; 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci struct dentry *debug_root; 108562306a36Sopenharmony_ci struct debugfs_regset32 *regset; 108662306a36Sopenharmony_ci bool needs_byte_swap; 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci /* DWC OTG HW Release versions */ 108962306a36Sopenharmony_ci#define DWC2_CORE_REV_2_71a 0x4f54271a 109062306a36Sopenharmony_ci#define DWC2_CORE_REV_2_72a 0x4f54272a 109162306a36Sopenharmony_ci#define DWC2_CORE_REV_2_80a 0x4f54280a 109262306a36Sopenharmony_ci#define DWC2_CORE_REV_2_90a 0x4f54290a 109362306a36Sopenharmony_ci#define DWC2_CORE_REV_2_91a 0x4f54291a 109462306a36Sopenharmony_ci#define DWC2_CORE_REV_2_92a 0x4f54292a 109562306a36Sopenharmony_ci#define DWC2_CORE_REV_2_94a 0x4f54294a 109662306a36Sopenharmony_ci#define DWC2_CORE_REV_3_00a 0x4f54300a 109762306a36Sopenharmony_ci#define DWC2_CORE_REV_3_10a 0x4f54310a 109862306a36Sopenharmony_ci#define DWC2_CORE_REV_4_00a 0x4f54400a 109962306a36Sopenharmony_ci#define DWC2_CORE_REV_4_20a 0x4f54420a 110062306a36Sopenharmony_ci#define DWC2_FS_IOT_REV_1_00a 0x5531100a 110162306a36Sopenharmony_ci#define DWC2_HS_IOT_REV_1_00a 0x5532100a 110262306a36Sopenharmony_ci#define DWC2_CORE_REV_MASK 0x0000ffff 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci /* DWC OTG HW Core ID */ 110562306a36Sopenharmony_ci#define DWC2_OTG_ID 0x4f540000 110662306a36Sopenharmony_ci#define DWC2_FS_IOT_ID 0x55310000 110762306a36Sopenharmony_ci#define DWC2_HS_IOT_ID 0x55320000 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) 111062306a36Sopenharmony_ci union dwc2_hcd_internal_flags { 111162306a36Sopenharmony_ci u32 d32; 111262306a36Sopenharmony_ci struct { 111362306a36Sopenharmony_ci unsigned port_connect_status_change:1; 111462306a36Sopenharmony_ci unsigned port_connect_status:1; 111562306a36Sopenharmony_ci unsigned port_reset_change:1; 111662306a36Sopenharmony_ci unsigned port_enable_change:1; 111762306a36Sopenharmony_ci unsigned port_suspend_change:1; 111862306a36Sopenharmony_ci unsigned port_over_current_change:1; 111962306a36Sopenharmony_ci unsigned port_l1_change:1; 112062306a36Sopenharmony_ci unsigned reserved:25; 112162306a36Sopenharmony_ci } b; 112262306a36Sopenharmony_ci } flags; 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci struct list_head non_periodic_sched_inactive; 112562306a36Sopenharmony_ci struct list_head non_periodic_sched_waiting; 112662306a36Sopenharmony_ci struct list_head non_periodic_sched_active; 112762306a36Sopenharmony_ci struct list_head *non_periodic_qh_ptr; 112862306a36Sopenharmony_ci struct list_head periodic_sched_inactive; 112962306a36Sopenharmony_ci struct list_head periodic_sched_ready; 113062306a36Sopenharmony_ci struct list_head periodic_sched_assigned; 113162306a36Sopenharmony_ci struct list_head periodic_sched_queued; 113262306a36Sopenharmony_ci struct list_head split_order; 113362306a36Sopenharmony_ci u16 periodic_usecs; 113462306a36Sopenharmony_ci DECLARE_BITMAP(hs_periodic_bitmap, DWC2_HS_SCHEDULE_US); 113562306a36Sopenharmony_ci u16 periodic_qh_count; 113662306a36Sopenharmony_ci bool new_connection; 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci u16 last_frame_num; 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_ci#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS 114162306a36Sopenharmony_ci#define FRAME_NUM_ARRAY_SIZE 1000 114262306a36Sopenharmony_ci u16 *frame_num_array; 114362306a36Sopenharmony_ci u16 *last_frame_num_array; 114462306a36Sopenharmony_ci int frame_num_idx; 114562306a36Sopenharmony_ci int dumped_frame_num_array; 114662306a36Sopenharmony_ci#endif 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci struct list_head free_hc_list; 114962306a36Sopenharmony_ci int periodic_channels; 115062306a36Sopenharmony_ci int non_periodic_channels; 115162306a36Sopenharmony_ci int available_host_channels; 115262306a36Sopenharmony_ci struct dwc2_host_chan *hc_ptr_array[MAX_EPS_CHANNELS]; 115362306a36Sopenharmony_ci u8 *status_buf; 115462306a36Sopenharmony_ci dma_addr_t status_buf_dma; 115562306a36Sopenharmony_ci#define DWC2_HCD_STATUS_BUF_SIZE 64 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci struct delayed_work start_work; 115862306a36Sopenharmony_ci struct delayed_work reset_work; 115962306a36Sopenharmony_ci struct work_struct phy_reset_work; 116062306a36Sopenharmony_ci u8 otg_port; 116162306a36Sopenharmony_ci u32 *frame_list; 116262306a36Sopenharmony_ci dma_addr_t frame_list_dma; 116362306a36Sopenharmony_ci u32 frame_list_sz; 116462306a36Sopenharmony_ci struct kmem_cache *desc_gen_cache; 116562306a36Sopenharmony_ci struct kmem_cache *desc_hsisoc_cache; 116662306a36Sopenharmony_ci struct kmem_cache *unaligned_cache; 116762306a36Sopenharmony_ci#define DWC2_KMEM_UNALIGNED_BUF_SIZE 1024 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci#endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */ 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ 117262306a36Sopenharmony_ci IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) 117362306a36Sopenharmony_ci /* Gadget structures */ 117462306a36Sopenharmony_ci struct usb_gadget_driver *driver; 117562306a36Sopenharmony_ci int fifo_mem; 117662306a36Sopenharmony_ci unsigned int dedicated_fifos:1; 117762306a36Sopenharmony_ci unsigned char num_of_eps; 117862306a36Sopenharmony_ci u32 fifo_map; 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci struct usb_request *ep0_reply; 118162306a36Sopenharmony_ci struct usb_request *ctrl_req; 118262306a36Sopenharmony_ci void *ep0_buff; 118362306a36Sopenharmony_ci void *ctrl_buff; 118462306a36Sopenharmony_ci enum dwc2_ep0_state ep0_state; 118562306a36Sopenharmony_ci unsigned delayed_status : 1; 118662306a36Sopenharmony_ci u8 test_mode; 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci dma_addr_t setup_desc_dma[2]; 118962306a36Sopenharmony_ci struct dwc2_dma_desc *setup_desc[2]; 119062306a36Sopenharmony_ci dma_addr_t ctrl_in_desc_dma; 119162306a36Sopenharmony_ci struct dwc2_dma_desc *ctrl_in_desc; 119262306a36Sopenharmony_ci dma_addr_t ctrl_out_desc_dma; 119362306a36Sopenharmony_ci struct dwc2_dma_desc *ctrl_out_desc; 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci struct usb_gadget gadget; 119662306a36Sopenharmony_ci unsigned int enabled:1; 119762306a36Sopenharmony_ci unsigned int connected:1; 119862306a36Sopenharmony_ci unsigned int remote_wakeup_allowed:1; 119962306a36Sopenharmony_ci struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS]; 120062306a36Sopenharmony_ci struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS]; 120162306a36Sopenharmony_ci#endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */ 120262306a36Sopenharmony_ci}; 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_ci/* Normal architectures just use readl/write */ 120562306a36Sopenharmony_cistatic inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset) 120662306a36Sopenharmony_ci{ 120762306a36Sopenharmony_ci u32 val; 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci val = readl(hsotg->regs + offset); 121062306a36Sopenharmony_ci if (hsotg->needs_byte_swap) 121162306a36Sopenharmony_ci return swab32(val); 121262306a36Sopenharmony_ci else 121362306a36Sopenharmony_ci return val; 121462306a36Sopenharmony_ci} 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_cistatic inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset) 121762306a36Sopenharmony_ci{ 121862306a36Sopenharmony_ci if (hsotg->needs_byte_swap) 121962306a36Sopenharmony_ci writel(swab32(value), hsotg->regs + offset); 122062306a36Sopenharmony_ci else 122162306a36Sopenharmony_ci writel(value, hsotg->regs + offset); 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci#ifdef DWC2_LOG_WRITES 122462306a36Sopenharmony_ci pr_info("info:: wrote %08x to %p\n", value, hsotg->regs + offset); 122562306a36Sopenharmony_ci#endif 122662306a36Sopenharmony_ci} 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_cistatic inline void dwc2_readl_rep(struct dwc2_hsotg *hsotg, u32 offset, 122962306a36Sopenharmony_ci void *buffer, unsigned int count) 123062306a36Sopenharmony_ci{ 123162306a36Sopenharmony_ci if (count) { 123262306a36Sopenharmony_ci u32 *buf = buffer; 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci do { 123562306a36Sopenharmony_ci u32 x = dwc2_readl(hsotg, offset); 123662306a36Sopenharmony_ci *buf++ = x; 123762306a36Sopenharmony_ci } while (--count); 123862306a36Sopenharmony_ci } 123962306a36Sopenharmony_ci} 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_cistatic inline void dwc2_writel_rep(struct dwc2_hsotg *hsotg, u32 offset, 124262306a36Sopenharmony_ci const void *buffer, unsigned int count) 124362306a36Sopenharmony_ci{ 124462306a36Sopenharmony_ci if (count) { 124562306a36Sopenharmony_ci const u32 *buf = buffer; 124662306a36Sopenharmony_ci 124762306a36Sopenharmony_ci do { 124862306a36Sopenharmony_ci dwc2_writel(hsotg, *buf++, offset); 124962306a36Sopenharmony_ci } while (--count); 125062306a36Sopenharmony_ci } 125162306a36Sopenharmony_ci} 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_ci/* Reasons for halting a host channel */ 125462306a36Sopenharmony_cienum dwc2_halt_status { 125562306a36Sopenharmony_ci DWC2_HC_XFER_NO_HALT_STATUS, 125662306a36Sopenharmony_ci DWC2_HC_XFER_COMPLETE, 125762306a36Sopenharmony_ci DWC2_HC_XFER_URB_COMPLETE, 125862306a36Sopenharmony_ci DWC2_HC_XFER_ACK, 125962306a36Sopenharmony_ci DWC2_HC_XFER_NAK, 126062306a36Sopenharmony_ci DWC2_HC_XFER_NYET, 126162306a36Sopenharmony_ci DWC2_HC_XFER_STALL, 126262306a36Sopenharmony_ci DWC2_HC_XFER_XACT_ERR, 126362306a36Sopenharmony_ci DWC2_HC_XFER_FRAME_OVERRUN, 126462306a36Sopenharmony_ci DWC2_HC_XFER_BABBLE_ERR, 126562306a36Sopenharmony_ci DWC2_HC_XFER_DATA_TOGGLE_ERR, 126662306a36Sopenharmony_ci DWC2_HC_XFER_AHB_ERR, 126762306a36Sopenharmony_ci DWC2_HC_XFER_PERIODIC_INCOMPLETE, 126862306a36Sopenharmony_ci DWC2_HC_XFER_URB_DEQUEUE, 126962306a36Sopenharmony_ci}; 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci/* Core version information */ 127262306a36Sopenharmony_cistatic inline bool dwc2_is_iot(struct dwc2_hsotg *hsotg) 127362306a36Sopenharmony_ci{ 127462306a36Sopenharmony_ci return (hsotg->hw_params.snpsid & 0xfff00000) == 0x55300000; 127562306a36Sopenharmony_ci} 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_cistatic inline bool dwc2_is_fs_iot(struct dwc2_hsotg *hsotg) 127862306a36Sopenharmony_ci{ 127962306a36Sopenharmony_ci return (hsotg->hw_params.snpsid & 0xffff0000) == 0x55310000; 128062306a36Sopenharmony_ci} 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_cistatic inline bool dwc2_is_hs_iot(struct dwc2_hsotg *hsotg) 128362306a36Sopenharmony_ci{ 128462306a36Sopenharmony_ci return (hsotg->hw_params.snpsid & 0xffff0000) == 0x55320000; 128562306a36Sopenharmony_ci} 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_ci/* 128862306a36Sopenharmony_ci * The following functions support initialization of the core driver component 128962306a36Sopenharmony_ci * and the DWC_otg controller 129062306a36Sopenharmony_ci */ 129162306a36Sopenharmony_ciint dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait); 129262306a36Sopenharmony_ciint dwc2_enter_partial_power_down(struct dwc2_hsotg *hsotg); 129362306a36Sopenharmony_ciint dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, int rem_wakeup, 129462306a36Sopenharmony_ci bool restore); 129562306a36Sopenharmony_ciint dwc2_enter_hibernation(struct dwc2_hsotg *hsotg, int is_host); 129662306a36Sopenharmony_ciint dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup, 129762306a36Sopenharmony_ci int reset, int is_host); 129862306a36Sopenharmony_civoid dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg); 129962306a36Sopenharmony_ciint dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy); 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_civoid dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host); 130262306a36Sopenharmony_civoid dwc2_force_dr_mode(struct dwc2_hsotg *hsotg); 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_cibool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg); 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ciint dwc2_check_core_version(struct dwc2_hsotg *hsotg); 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci/* 130962306a36Sopenharmony_ci * Common core Functions. 131062306a36Sopenharmony_ci * The following functions support managing the DWC_otg controller in either 131162306a36Sopenharmony_ci * device or host mode. 131262306a36Sopenharmony_ci */ 131362306a36Sopenharmony_civoid dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes); 131462306a36Sopenharmony_civoid dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num); 131562306a36Sopenharmony_civoid dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg); 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_civoid dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd); 131862306a36Sopenharmony_civoid dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd); 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_civoid dwc2_hib_restore_common(struct dwc2_hsotg *hsotg, int rem_wakeup, 132162306a36Sopenharmony_ci int is_host); 132262306a36Sopenharmony_ciint dwc2_backup_global_registers(struct dwc2_hsotg *hsotg); 132362306a36Sopenharmony_ciint dwc2_restore_global_registers(struct dwc2_hsotg *hsotg); 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_civoid dwc2_enable_acg(struct dwc2_hsotg *hsotg); 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci/* This function should be called on every hardware interrupt. */ 132862306a36Sopenharmony_ciirqreturn_t dwc2_handle_common_intr(int irq, void *dev); 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci/* The device ID match table */ 133162306a36Sopenharmony_ciextern const struct of_device_id dwc2_of_match_table[]; 133262306a36Sopenharmony_ciextern const struct acpi_device_id dwc2_acpi_match[]; 133362306a36Sopenharmony_ciextern const struct pci_device_id dwc2_pci_ids[]; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ciint dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg); 133662306a36Sopenharmony_ciint dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg); 133762306a36Sopenharmony_ci 133862306a36Sopenharmony_ci/* Common polling functions */ 133962306a36Sopenharmony_ciint dwc2_hsotg_wait_bit_set(struct dwc2_hsotg *hs_otg, u32 reg, u32 bit, 134062306a36Sopenharmony_ci u32 timeout); 134162306a36Sopenharmony_ciint dwc2_hsotg_wait_bit_clear(struct dwc2_hsotg *hs_otg, u32 reg, u32 bit, 134262306a36Sopenharmony_ci u32 timeout); 134362306a36Sopenharmony_ci/* Parameters */ 134462306a36Sopenharmony_ciint dwc2_get_hwparams(struct dwc2_hsotg *hsotg); 134562306a36Sopenharmony_ciint dwc2_init_params(struct dwc2_hsotg *hsotg); 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci/* 134862306a36Sopenharmony_ci * The following functions check the controller's OTG operation mode 134962306a36Sopenharmony_ci * capability (GHWCFG2.OTG_MODE). 135062306a36Sopenharmony_ci * 135162306a36Sopenharmony_ci * These functions can be used before the internal hsotg->hw_params 135262306a36Sopenharmony_ci * are read in and cached so they always read directly from the 135362306a36Sopenharmony_ci * GHWCFG2 register. 135462306a36Sopenharmony_ci */ 135562306a36Sopenharmony_ciunsigned int dwc2_op_mode(struct dwc2_hsotg *hsotg); 135662306a36Sopenharmony_cibool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg); 135762306a36Sopenharmony_cibool dwc2_hw_is_host(struct dwc2_hsotg *hsotg); 135862306a36Sopenharmony_cibool dwc2_hw_is_device(struct dwc2_hsotg *hsotg); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci/* 136162306a36Sopenharmony_ci * Returns the mode of operation, host or device 136262306a36Sopenharmony_ci */ 136362306a36Sopenharmony_cistatic inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg) 136462306a36Sopenharmony_ci{ 136562306a36Sopenharmony_ci return (dwc2_readl(hsotg, GINTSTS) & GINTSTS_CURMODE_HOST) != 0; 136662306a36Sopenharmony_ci} 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_cistatic inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) 136962306a36Sopenharmony_ci{ 137062306a36Sopenharmony_ci return (dwc2_readl(hsotg, GINTSTS) & GINTSTS_CURMODE_HOST) == 0; 137162306a36Sopenharmony_ci} 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ciint dwc2_drd_init(struct dwc2_hsotg *hsotg); 137462306a36Sopenharmony_civoid dwc2_drd_suspend(struct dwc2_hsotg *hsotg); 137562306a36Sopenharmony_civoid dwc2_drd_resume(struct dwc2_hsotg *hsotg); 137662306a36Sopenharmony_civoid dwc2_drd_exit(struct dwc2_hsotg *hsotg); 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci/* 137962306a36Sopenharmony_ci * Dump core registers and SPRAM 138062306a36Sopenharmony_ci */ 138162306a36Sopenharmony_civoid dwc2_dump_dev_registers(struct dwc2_hsotg *hsotg); 138262306a36Sopenharmony_civoid dwc2_dump_host_registers(struct dwc2_hsotg *hsotg); 138362306a36Sopenharmony_civoid dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci/* Gadget defines */ 138662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ 138762306a36Sopenharmony_ci IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) 138862306a36Sopenharmony_ciint dwc2_hsotg_remove(struct dwc2_hsotg *hsotg); 138962306a36Sopenharmony_ciint dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2); 139062306a36Sopenharmony_ciint dwc2_hsotg_resume(struct dwc2_hsotg *dwc2); 139162306a36Sopenharmony_ciint dwc2_gadget_init(struct dwc2_hsotg *hsotg); 139262306a36Sopenharmony_civoid dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, 139362306a36Sopenharmony_ci bool reset); 139462306a36Sopenharmony_civoid dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg); 139562306a36Sopenharmony_civoid dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg); 139662306a36Sopenharmony_civoid dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2); 139762306a36Sopenharmony_ciint dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); 139862306a36Sopenharmony_ci#define dwc2_is_device_connected(hsotg) (hsotg->connected) 139962306a36Sopenharmony_ci#define dwc2_is_device_enabled(hsotg) (hsotg->enabled) 140062306a36Sopenharmony_ciint dwc2_backup_device_registers(struct dwc2_hsotg *hsotg); 140162306a36Sopenharmony_ciint dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup); 140262306a36Sopenharmony_ciint dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg); 140362306a36Sopenharmony_ciint dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg, 140462306a36Sopenharmony_ci int rem_wakeup, int reset); 140562306a36Sopenharmony_ciint dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg); 140662306a36Sopenharmony_ciint dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg, 140762306a36Sopenharmony_ci bool restore); 140862306a36Sopenharmony_civoid dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg); 140962306a36Sopenharmony_civoid dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg, 141062306a36Sopenharmony_ci int rem_wakeup); 141162306a36Sopenharmony_ciint dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg); 141262306a36Sopenharmony_ciint dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg); 141362306a36Sopenharmony_ciint dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg); 141462306a36Sopenharmony_civoid dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg); 141562306a36Sopenharmony_civoid dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg); 141662306a36Sopenharmony_cistatic inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg) 141762306a36Sopenharmony_ci{ hsotg->fifo_map = 0; } 141862306a36Sopenharmony_ci#else 141962306a36Sopenharmony_cistatic inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2) 142062306a36Sopenharmony_ci{ return 0; } 142162306a36Sopenharmony_cistatic inline int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2) 142262306a36Sopenharmony_ci{ return 0; } 142362306a36Sopenharmony_cistatic inline int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2) 142462306a36Sopenharmony_ci{ return 0; } 142562306a36Sopenharmony_cistatic inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg) 142662306a36Sopenharmony_ci{ return 0; } 142762306a36Sopenharmony_cistatic inline void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, 142862306a36Sopenharmony_ci bool reset) {} 142962306a36Sopenharmony_cistatic inline void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) {} 143062306a36Sopenharmony_cistatic inline void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} 143162306a36Sopenharmony_cistatic inline void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} 143262306a36Sopenharmony_cistatic inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, 143362306a36Sopenharmony_ci int testmode) 143462306a36Sopenharmony_ci{ return 0; } 143562306a36Sopenharmony_ci#define dwc2_is_device_connected(hsotg) (0) 143662306a36Sopenharmony_ci#define dwc2_is_device_enabled(hsotg) (0) 143762306a36Sopenharmony_cistatic inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) 143862306a36Sopenharmony_ci{ return 0; } 143962306a36Sopenharmony_cistatic inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, 144062306a36Sopenharmony_ci int remote_wakeup) 144162306a36Sopenharmony_ci{ return 0; } 144262306a36Sopenharmony_cistatic inline int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg) 144362306a36Sopenharmony_ci{ return 0; } 144462306a36Sopenharmony_cistatic inline int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg, 144562306a36Sopenharmony_ci int rem_wakeup, int reset) 144662306a36Sopenharmony_ci{ return 0; } 144762306a36Sopenharmony_cistatic inline int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg) 144862306a36Sopenharmony_ci{ return 0; } 144962306a36Sopenharmony_cistatic inline int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg, 145062306a36Sopenharmony_ci bool restore) 145162306a36Sopenharmony_ci{ return 0; } 145262306a36Sopenharmony_cistatic inline void dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg) {} 145362306a36Sopenharmony_cistatic inline void dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg, 145462306a36Sopenharmony_ci int rem_wakeup) {} 145562306a36Sopenharmony_cistatic inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg) 145662306a36Sopenharmony_ci{ return 0; } 145762306a36Sopenharmony_cistatic inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) 145862306a36Sopenharmony_ci{ return 0; } 145962306a36Sopenharmony_cistatic inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg) 146062306a36Sopenharmony_ci{ return 0; } 146162306a36Sopenharmony_cistatic inline void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg) {} 146262306a36Sopenharmony_cistatic inline void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg) {} 146362306a36Sopenharmony_cistatic inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg) {} 146462306a36Sopenharmony_ci#endif 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) 146762306a36Sopenharmony_ciint dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); 146862306a36Sopenharmony_ciint dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us); 146962306a36Sopenharmony_civoid dwc2_hcd_connect(struct dwc2_hsotg *hsotg); 147062306a36Sopenharmony_civoid dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); 147162306a36Sopenharmony_civoid dwc2_hcd_start(struct dwc2_hsotg *hsotg); 147262306a36Sopenharmony_ciint dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup); 147362306a36Sopenharmony_ciint dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex); 147462306a36Sopenharmony_ciint dwc2_port_resume(struct dwc2_hsotg *hsotg); 147562306a36Sopenharmony_ciint dwc2_backup_host_registers(struct dwc2_hsotg *hsotg); 147662306a36Sopenharmony_ciint dwc2_restore_host_registers(struct dwc2_hsotg *hsotg); 147762306a36Sopenharmony_ciint dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg); 147862306a36Sopenharmony_ciint dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, 147962306a36Sopenharmony_ci int rem_wakeup, int reset); 148062306a36Sopenharmony_ciint dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg); 148162306a36Sopenharmony_ciint dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg, 148262306a36Sopenharmony_ci int rem_wakeup, bool restore); 148362306a36Sopenharmony_civoid dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg); 148462306a36Sopenharmony_civoid dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup); 148562306a36Sopenharmony_cibool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2); 148662306a36Sopenharmony_cistatic inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) 148762306a36Sopenharmony_ci{ schedule_work(&hsotg->phy_reset_work); } 148862306a36Sopenharmony_ci#else 148962306a36Sopenharmony_cistatic inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) 149062306a36Sopenharmony_ci{ return 0; } 149162306a36Sopenharmony_cistatic inline int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, 149262306a36Sopenharmony_ci int us) 149362306a36Sopenharmony_ci{ return 0; } 149462306a36Sopenharmony_cistatic inline void dwc2_hcd_connect(struct dwc2_hsotg *hsotg) {} 149562306a36Sopenharmony_cistatic inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {} 149662306a36Sopenharmony_cistatic inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} 149762306a36Sopenharmony_cistatic inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} 149862306a36Sopenharmony_cistatic inline int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup) 149962306a36Sopenharmony_ci{ return 0; } 150062306a36Sopenharmony_cistatic inline int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) 150162306a36Sopenharmony_ci{ return 0; } 150262306a36Sopenharmony_cistatic inline int dwc2_port_resume(struct dwc2_hsotg *hsotg) 150362306a36Sopenharmony_ci{ return 0; } 150462306a36Sopenharmony_cistatic inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg) 150562306a36Sopenharmony_ci{ return 0; } 150662306a36Sopenharmony_cistatic inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) 150762306a36Sopenharmony_ci{ return 0; } 150862306a36Sopenharmony_cistatic inline int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) 150962306a36Sopenharmony_ci{ return 0; } 151062306a36Sopenharmony_cistatic inline int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg) 151162306a36Sopenharmony_ci{ return 0; } 151262306a36Sopenharmony_cistatic inline int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, 151362306a36Sopenharmony_ci int rem_wakeup, int reset) 151462306a36Sopenharmony_ci{ return 0; } 151562306a36Sopenharmony_cistatic inline int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg) 151662306a36Sopenharmony_ci{ return 0; } 151762306a36Sopenharmony_cistatic inline int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg, 151862306a36Sopenharmony_ci int rem_wakeup, bool restore) 151962306a36Sopenharmony_ci{ return 0; } 152062306a36Sopenharmony_cistatic inline void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg) {} 152162306a36Sopenharmony_cistatic inline void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, 152262306a36Sopenharmony_ci int rem_wakeup) {} 152362306a36Sopenharmony_cistatic inline bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2) 152462306a36Sopenharmony_ci{ return false; } 152562306a36Sopenharmony_cistatic inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) {} 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci#endif 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci#endif /* __DWC2_CORE_H__ */ 1530