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