mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -07:00
Merge tag 'usb-for-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
usb: changes for v4.18 merge window A total of 98 non-merge commits, the biggest part being in dwc3 this time around with a large refactoring of dwc3's transfer handling code. We also have a new driver for Aspeed virtual hub controller. Apart from that, just a list of miscellaneous fixes all over the place.
This commit is contained in:
commit
109e37a673
58 files changed
+5510
-831
No files matched your search
@@ -7,6 +7,26 @@ Required properties:
|
||||
- compatible: must be "snps,dwc3"
|
||||
- reg : Address and length of the register set for the device
|
||||
- interrupts: Interrupts used by the dwc3 controller.
|
||||
- clock-names: should contain "ref", "bus_early", "suspend"
|
||||
- clocks: list of phandle and clock specifier pairs corresponding to
|
||||
entries in the clock-names property.
|
||||
|
||||
Exception for clocks:
|
||||
clocks are optional if the parent node (i.e. glue-layer) is compatible to
|
||||
one of the following:
|
||||
"amlogic,meson-axg-dwc3"
|
||||
"amlogic,meson-gxl-dwc3"
|
||||
"cavium,octeon-7130-usb-uctl"
|
||||
"qcom,dwc3"
|
||||
"samsung,exynos5250-dwusb3"
|
||||
"samsung,exynos7-dwusb3"
|
||||
"sprd,sc9860-dwc3"
|
||||
"st,stih407-dwc3"
|
||||
"ti,am437x-dwc3"
|
||||
"ti,dwc3"
|
||||
"ti,keystone-dwc3"
|
||||
"rockchip,rk3399-dwc3"
|
||||
"xlnx,zynqmp-dwc3"
|
||||
|
||||
Optional properties:
|
||||
- usb-phy : array of phandle for the PHY device. The first element
|
||||
@@ -15,6 +35,7 @@ Optional properties:
|
||||
- phys: from the *Generic PHY* bindings
|
||||
- phy-names: from the *Generic PHY* bindings; supported names are "usb2-phy"
|
||||
or "usb3-phy".
|
||||
- resets: a single pair of phandle and reset specifier
|
||||
- snps,usb3_lpm_capable: determines if platform is USB3 LPM capable
|
||||
- snps,disable_scramble_quirk: true when SW should disable data scrambling.
|
||||
Only really useful for FPGA builds.
|
||||
|
||||
@@ -1,54 +1,95 @@
|
||||
Qualcomm SuperSpeed DWC3 USB SoC controller
|
||||
|
||||
Required properties:
|
||||
- compatible: should contain "qcom,dwc3"
|
||||
- compatible: Compatible list, contains
|
||||
"qcom,dwc3"
|
||||
"qcom,msm8996-dwc3" for msm8996 SOC.
|
||||
"qcom,sdm845-dwc3" for sdm845 SOC.
|
||||
- reg: Offset and length of register set for QSCRATCH wrapper
|
||||
- power-domains: specifies a phandle to PM domain provider node
|
||||
- clocks: A list of phandle + clock-specifier pairs for the
|
||||
clocks listed in clock-names
|
||||
- clock-names: Should contain the following:
|
||||
- clock-names: Should contain the following:
|
||||
"core" Master/Core clock, have to be >= 125 MHz for SS
|
||||
operation and >= 60MHz for HS operation
|
||||
"mock_utmi" Mock utmi clock needed for ITP/SOF generation in
|
||||
host mode. Its frequency should be 19.2MHz.
|
||||
"sleep" Sleep clock, used for wakeup when USB3 core goes
|
||||
into low power mode (U3).
|
||||
|
||||
Optional clocks:
|
||||
"iface" System bus AXI clock. Not present on all platforms
|
||||
"sleep" Sleep clock, used when USB3 core goes into low
|
||||
power mode (U3).
|
||||
"iface" System bus AXI clock.
|
||||
Not present on "qcom,msm8996-dwc3" compatible.
|
||||
"cfg_noc" System Config NOC clock.
|
||||
Not present on "qcom,msm8996-dwc3" compatible.
|
||||
- assigned-clocks: Should be:
|
||||
MOCK_UTMI_CLK
|
||||
MASTER_CLK
|
||||
- assigned-clock-rates: Should be:
|
||||
19.2Mhz (192000000) for MOCK_UTMI_CLK
|
||||
>=125Mhz (125000000) for MASTER_CLK in SS mode
|
||||
>=60Mhz (60000000) for MASTER_CLK in HS mode
|
||||
|
||||
Optional properties:
|
||||
- resets: Phandle to reset control that resets core and wrapper.
|
||||
- interrupts: specifies interrupts from controller wrapper used
|
||||
to wakeup from low power/susepnd state. Must contain
|
||||
one or more entry for interrupt-names property
|
||||
- interrupt-names: Must include the following entries:
|
||||
- "hs_phy_irq": The interrupt that is asserted when a
|
||||
wakeup event is received on USB2 bus
|
||||
- "ss_phy_irq": The interrupt that is asserted when a
|
||||
wakeup event is received on USB3 bus
|
||||
- "dm_hs_phy_irq" and "dp_hs_phy_irq": Separate
|
||||
interrupts for any wakeup event on DM and DP lines
|
||||
- qcom,select-utmi-as-pipe-clk: if present, disable USB3 pipe_clk requirement.
|
||||
Used when dwc3 operates without SSPHY and only
|
||||
HS/FS/LS modes are supported.
|
||||
|
||||
Required child node:
|
||||
A child node must exist to represent the core DWC3 IP block. The name of
|
||||
the node is not important. The content of the node is defined in dwc3.txt.
|
||||
|
||||
Phy documentation is provided in the following places:
|
||||
Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
|
||||
Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt - USB3 QMP PHY
|
||||
Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
|
||||
|
||||
Example device nodes:
|
||||
|
||||
hs_phy: phy@100f8800 {
|
||||
compatible = "qcom,dwc3-hs-usb-phy";
|
||||
reg = <0x100f8800 0x30>;
|
||||
clocks = <&gcc USB30_0_UTMI_CLK>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <0>;
|
||||
|
||||
compatible = "qcom,qusb2-v2-phy";
|
||||
...
|
||||
};
|
||||
|
||||
ss_phy: phy@100f8830 {
|
||||
compatible = "qcom,dwc3-ss-usb-phy";
|
||||
reg = <0x100f8830 0x30>;
|
||||
clocks = <&gcc USB30_0_MASTER_CLK>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <0>;
|
||||
|
||||
compatible = "qcom,qmp-v3-usb3-phy";
|
||||
...
|
||||
};
|
||||
|
||||
usb3_0: usb30@0 {
|
||||
usb3_0: usb30@a6f8800 {
|
||||
compatible = "qcom,dwc3";
|
||||
reg = <0xa6f8800 0x400>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
clocks = <&gcc USB30_0_MASTER_CLK>;
|
||||
clock-names = "core";
|
||||
|
||||
ranges;
|
||||
|
||||
interrupts = <0 131 0>, <0 486 0>, <0 488 0>, <0 489 0>;
|
||||
interrupt-names = "hs_phy_irq", "ss_phy_irq",
|
||||
"dm_hs_phy_irq", "dp_hs_phy_irq";
|
||||
|
||||
clocks = <&gcc GCC_USB30_PRIM_MASTER_CLK>,
|
||||
<&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
|
||||
<&gcc GCC_USB30_PRIM_SLEEP_CLK>;
|
||||
clock-names = "core", "mock_utmi", "sleep";
|
||||
|
||||
assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
|
||||
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
|
||||
assigned-clock-rates = <19200000>, <133000000>;
|
||||
|
||||
resets = <&gcc GCC_USB30_PRIM_BCR>;
|
||||
reset-names = "core_reset";
|
||||
power-domains = <&gcc USB30_PRIM_GDSC>;
|
||||
qcom,select-utmi-as-pipe-clk;
|
||||
|
||||
dwc3@10000000 {
|
||||
compatible = "snps,dwc3";
|
||||
|
||||
@@ -674,9 +674,8 @@ operations, both of which can be traced. Format is::
|
||||
__entry->flags & DWC3_EP_ENABLED ? 'E' : 'e',
|
||||
__entry->flags & DWC3_EP_STALL ? 'S' : 's',
|
||||
__entry->flags & DWC3_EP_WEDGE ? 'W' : 'w',
|
||||
__entry->flags & DWC3_EP_BUSY ? 'B' : 'b',
|
||||
__entry->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b',
|
||||
__entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',
|
||||
__entry->flags & DWC3_EP_MISSED_ISOC ? 'M' : 'm',
|
||||
__entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e',
|
||||
__entry->direction ? '<' : '>'
|
||||
)
|
||||
|
||||
@@ -419,6 +419,8 @@ static void dwc2_wait_for_mode(struct dwc2_hsotg *hsotg,
|
||||
/**
|
||||
* dwc2_iddig_filter_enabled() - Returns true if the IDDIG debounce
|
||||
* filter is enabled.
|
||||
*
|
||||
* @hsotg: Programming view of DWC_otg controller
|
||||
*/
|
||||
static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
@@ -564,6 +566,9 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait)
|
||||
* If a force is done, it requires a IDDIG debounce filter delay if
|
||||
* the filter is configured and enabled. We poll the current mode of
|
||||
* the controller to account for this delay.
|
||||
*
|
||||
* @hsotg: Programming view of DWC_otg controller
|
||||
* @host: Host mode flag
|
||||
*/
|
||||
void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host)
|
||||
{
|
||||
@@ -610,6 +615,8 @@ void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host)
|
||||
* or not because the value of the connector ID status is affected by
|
||||
* the force mode. We only need to call this once during probe if
|
||||
* dr_mode == OTG.
|
||||
*
|
||||
* @hsotg: Programming view of DWC_otg controller
|
||||
*/
|
||||
static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
|
||||
+152
-36
@@ -164,12 +164,11 @@ struct dwc2_hsotg_req;
|
||||
* and has yet to be completed (maybe due to data move, or simply
|
||||
* awaiting an ack from the core all the data has been completed).
|
||||
* @debugfs: File entry for debugfs file for this endpoint.
|
||||
* @lock: State lock to protect contents of endpoint.
|
||||
* @dir_in: Set to true if this endpoint is of the IN direction, which
|
||||
* means that it is sending data to the Host.
|
||||
* @index: The index for the endpoint registers.
|
||||
* @mc: Multi Count - number of transactions per microframe
|
||||
* @interval - Interval for periodic endpoints, in frames or microframes.
|
||||
* @interval: Interval for periodic endpoints, in frames or microframes.
|
||||
* @name: The name array passed to the USB core.
|
||||
* @halted: Set if the endpoint has been halted.
|
||||
* @periodic: Set if this is a periodic ep, such as Interrupt
|
||||
@@ -178,10 +177,11 @@ struct dwc2_hsotg_req;
|
||||
* @desc_list_dma: The DMA address of descriptor chain currently in use.
|
||||
* @desc_list: Pointer to descriptor DMA chain head currently in use.
|
||||
* @desc_count: Count of entries within the DMA descriptor chain of EP.
|
||||
* @isoc_chain_num: Number of ISOC chain currently in use - either 0 or 1.
|
||||
* @next_desc: index of next free descriptor in the ISOC chain under SW control.
|
||||
* @compl_desc: index of next descriptor to be completed by xFerComplete
|
||||
* @total_data: The total number of data bytes done.
|
||||
* @fifo_size: The size of the FIFO (for periodic IN endpoints)
|
||||
* @fifo_index: For Dedicated FIFO operation, only FIFO0 can be used for EP0.
|
||||
* @fifo_load: The amount of data loaded into the FIFO (periodic IN)
|
||||
* @last_load: The offset of data for the last start of request.
|
||||
* @size_loaded: The last loaded size for DxEPTSIZE for periodic IN
|
||||
@@ -231,8 +231,8 @@ struct dwc2_hsotg_ep {
|
||||
struct dwc2_dma_desc *desc_list;
|
||||
u8 desc_count;
|
||||
|
||||
unsigned char isoc_chain_num;
|
||||
unsigned int next_desc;
|
||||
unsigned int compl_desc;
|
||||
|
||||
char name[10];
|
||||
};
|
||||
@@ -380,6 +380,12 @@ enum dwc2_ep0_state {
|
||||
* is FS.
|
||||
* 0 - No (default)
|
||||
* 1 - Yes
|
||||
* @ipg_isoc_en: Indicates the IPG supports is enabled or disabled.
|
||||
* 0 - Disable (default)
|
||||
* 1 - Enable
|
||||
* @acg_enable: For enabling Active Clock Gating in the controller
|
||||
* 0 - No
|
||||
* 1 - Yes
|
||||
* @ulpi_fs_ls: Make ULPI phy operate in FS/LS mode only
|
||||
* 0 - No (default)
|
||||
* 1 - Yes
|
||||
@@ -511,6 +517,7 @@ struct dwc2_core_params {
|
||||
bool hird_threshold_en;
|
||||
u8 hird_threshold;
|
||||
bool activate_stm_fs_transceiver;
|
||||
bool ipg_isoc_en;
|
||||
u16 max_packet_count;
|
||||
u32 max_transfer_size;
|
||||
u32 ahbcfg;
|
||||
@@ -548,7 +555,7 @@ struct dwc2_core_params {
|
||||
*
|
||||
* The values that are not in dwc2_core_params are documented below.
|
||||
*
|
||||
* @op_mode Mode of Operation
|
||||
* @op_mode: Mode of Operation
|
||||
* 0 - HNP- and SRP-Capable OTG (Host & Device)
|
||||
* 1 - SRP-Capable OTG (Host & Device)
|
||||
* 2 - Non-HNP and Non-SRP Capable OTG (Host & Device)
|
||||
@@ -556,43 +563,102 @@ struct dwc2_core_params {
|
||||
* 4 - Non-OTG Device
|
||||
* 5 - SRP-Capable Host
|
||||
* 6 - Non-OTG Host
|
||||
* @arch Architecture
|
||||
* @arch: Architecture
|
||||
* 0 - Slave only
|
||||
* 1 - External DMA
|
||||
* 2 - Internal DMA
|
||||
* @power_optimized Are power optimizations enabled?
|
||||
* @num_dev_ep Number of device endpoints available
|
||||
* @num_dev_in_eps Number of device IN endpoints available
|
||||
* @num_dev_perio_in_ep Number of device periodic IN endpoints
|
||||
* available
|
||||
* @dev_token_q_depth Device Mode IN Token Sequence Learning Queue
|
||||
* @ipg_isoc_en: This feature indicates that the controller supports
|
||||
* the worst-case scenario of Rx followed by Rx
|
||||
* Interpacket Gap (IPG) (32 bitTimes) as per the utmi
|
||||
* specification for any token following ISOC OUT token.
|
||||
* 0 - Don't support
|
||||
* 1 - Support
|
||||
* @power_optimized: Are power optimizations enabled?
|
||||
* @num_dev_ep: Number of device endpoints available
|
||||
* @num_dev_in_eps: Number of device IN endpoints available
|
||||
* @num_dev_perio_in_ep: Number of device periodic IN endpoints
|
||||
* available
|
||||
* @dev_token_q_depth: Device Mode IN Token Sequence Learning Queue
|
||||
* Depth
|
||||
* 0 to 30
|
||||
* @host_perio_tx_q_depth
|
||||
* @host_perio_tx_q_depth:
|
||||
* Host Mode Periodic Request Queue Depth
|
||||
* 2, 4 or 8
|
||||
* @nperio_tx_q_depth
|
||||
* @nperio_tx_q_depth:
|
||||
* Non-Periodic Request Queue Depth
|
||||
* 2, 4 or 8
|
||||
* @hs_phy_type High-speed PHY interface type
|
||||
* @hs_phy_type: High-speed PHY interface type
|
||||
* 0 - High-speed interface not supported
|
||||
* 1 - UTMI+
|
||||
* 2 - ULPI
|
||||
* 3 - UTMI+ and ULPI
|
||||
* @fs_phy_type Full-speed PHY interface type
|
||||
* @fs_phy_type: Full-speed PHY interface type
|
||||
* 0 - Full speed interface not supported
|
||||
* 1 - Dedicated full speed interface
|
||||
* 2 - FS pins shared with UTMI+ pins
|
||||
* 3 - FS pins shared with ULPI pins
|
||||
* @total_fifo_size: Total internal RAM for FIFOs (bytes)
|
||||
* @hibernation Is hibernation enabled?
|
||||
* @utmi_phy_data_width UTMI+ PHY data width
|
||||
* @hibernation: Is hibernation enabled?
|
||||
* @utmi_phy_data_width: UTMI+ PHY data width
|
||||
* 0 - 8 bits
|
||||
* 1 - 16 bits
|
||||
* 2 - 8 or 16 bits
|
||||
* @snpsid: Value from SNPSID register
|
||||
* @dev_ep_dirs: Direction of device endpoints (GHWCFG1)
|
||||
* @g_tx_fifo_size[] Power-on values of TxFIFO sizes
|
||||
* @g_tx_fifo_size: Power-on values of TxFIFO sizes
|
||||
* @dma_desc_enable: When DMA mode is enabled, specifies whether to use
|
||||
* address DMA mode or descriptor DMA mode for accessing
|
||||
* the data FIFOs. The driver will automatically detect the
|
||||
* value for this if none is specified.
|
||||
* 0 - Address DMA
|
||||
* 1 - Descriptor DMA (default, if available)
|
||||
* @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters
|
||||
* 1 - Allow dynamic FIFO sizing (default, if available)
|
||||
* @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs
|
||||
* are enabled for non-periodic IN endpoints in device
|
||||
* mode.
|
||||
* @host_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO
|
||||
* in host mode when dynamic FIFO sizing is enabled
|
||||
* 16 to 32768
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @host_perio_tx_fifo_size: Number of 4-byte words in the periodic Tx FIFO in
|
||||
* host mode when dynamic FIFO sizing is enabled
|
||||
* 16 to 32768
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @max_transfer_size: The maximum transfer size supported, in bytes
|
||||
* 2047 to 65,535
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @max_packet_count: The maximum number of packets in a transfer
|
||||
* 15 to 511
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @host_channels: The number of host channel registers to use
|
||||
* 1 to 16
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @dev_nperio_tx_fifo_size: Number of 4-byte words in the non-periodic Tx FIFO
|
||||
* in device mode when dynamic FIFO sizing is enabled
|
||||
* 16 to 32768
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
* @i2c_enable: Specifies whether to use the I2Cinterface for a full
|
||||
* speed PHY. This parameter is only applicable if phy_type
|
||||
* is FS.
|
||||
* 0 - No (default)
|
||||
* 1 - Yes
|
||||
* @acg_enable: For enabling Active Clock Gating in the controller
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
* @lpm_mode: For enabling Link Power Management in the controller
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
* @rx_fifo_size: Number of 4-byte words in the Rx FIFO when dynamic
|
||||
* FIFO sizing is enabled 16 to 32768
|
||||
* Actual maximum value is autodetected and also
|
||||
* the default.
|
||||
*/
|
||||
struct dwc2_hw_params {
|
||||
unsigned op_mode:3;
|
||||
@@ -622,6 +688,7 @@ struct dwc2_hw_params {
|
||||
unsigned hibernation:1;
|
||||
unsigned utmi_phy_data_width:2;
|
||||
unsigned lpm_mode:1;
|
||||
unsigned ipg_isoc_en:1;
|
||||
u32 snpsid;
|
||||
u32 dev_ep_dirs;
|
||||
u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
|
||||
@@ -642,7 +709,11 @@ struct dwc2_hw_params {
|
||||
* @gi2cctl: Backup of GI2CCTL register
|
||||
* @glpmcfg: Backup of GLPMCFG register
|
||||
* @gdfifocfg: Backup of GDFIFOCFG register
|
||||
* @pcgcctl: Backup of PCGCCTL register
|
||||
* @pcgcctl1: Backup of PCGCCTL1 register
|
||||
* @dtxfsiz: Backup of DTXFSIZ registers for each endpoint
|
||||
* @gpwrdn: Backup of GPWRDN register
|
||||
* @valid: True if registers values backuped.
|
||||
*/
|
||||
struct dwc2_gregs_backup {
|
||||
u32 gotgctl;
|
||||
@@ -675,6 +746,7 @@ struct dwc2_gregs_backup {
|
||||
* @doeptsiz: Backup of DOEPTSIZ register
|
||||
* @doepdma: Backup of DOEPDMA register
|
||||
* @dtxfsiz: Backup of DTXFSIZ registers for each endpoint
|
||||
* @valid: True if registers values backuped.
|
||||
*/
|
||||
struct dwc2_dregs_backup {
|
||||
u32 dcfg;
|
||||
@@ -698,9 +770,10 @@ struct dwc2_dregs_backup {
|
||||
* @hcfg: Backup of HCFG register
|
||||
* @haintmsk: Backup of HAINTMSK register
|
||||
* @hcintmsk: Backup of HCINTMSK register
|
||||
* @hptr0: Backup of HPTR0 register
|
||||
* @hprt0: Backup of HPTR0 register
|
||||
* @hfir: Backup of HFIR register
|
||||
* @hptxfsiz: Backup of HPTXFSIZ register
|
||||
* @valid: True if registers values backuped.
|
||||
*/
|
||||
struct dwc2_hregs_backup {
|
||||
u32 hcfg;
|
||||
@@ -800,7 +873,7 @@ struct dwc2_hregs_backup {
|
||||
* @regs: Pointer to controller regs
|
||||
* @hw_params: Parameters that were autodetected from the
|
||||
* hardware registers
|
||||
* @core_params: Parameters that define how the core should be configured
|
||||
* @params: Parameters that define how the core should be configured
|
||||
* @op_state: The operational State, during transitions (a_host=>
|
||||
* a_peripheral and b_device=>b_host) this may not match
|
||||
* the core, but allows the software to determine
|
||||
@@ -809,10 +882,13 @@ struct dwc2_hregs_backup {
|
||||
* - USB_DR_MODE_PERIPHERAL
|
||||
* - USB_DR_MODE_HOST
|
||||
* - USB_DR_MODE_OTG
|
||||
* @hcd_enabled Host mode sub-driver initialization indicator.
|
||||
* @gadget_enabled Peripheral mode sub-driver initialization indicator.
|
||||
* @ll_hw_enabled Status of low-level hardware resources.
|
||||
* @hcd_enabled: Host mode sub-driver initialization indicator.
|
||||
* @gadget_enabled: Peripheral mode sub-driver initialization indicator.
|
||||
* @ll_hw_enabled: Status of low-level hardware resources.
|
||||
* @hibernated: True if core is hibernated
|
||||
* @frame_number: Frame number read from the core. For both device
|
||||
* and host modes. The value ranges are from 0
|
||||
* to HFNUM_MAX_FRNUM.
|
||||
* @phy: The otg phy transceiver structure for phy control.
|
||||
* @uphy: The otg phy transceiver structure for old USB phy
|
||||
* control.
|
||||
@@ -832,13 +908,25 @@ struct dwc2_hregs_backup {
|
||||
* interrupt
|
||||
* @wkp_timer: Timer object for handling Wakeup Detected interrupt
|
||||
* @lx_state: Lx state of connected device
|
||||
* @gregs_backup: Backup of global registers during suspend
|
||||
* @dregs_backup: Backup of device registers during suspend
|
||||
* @hregs_backup: Backup of host registers during suspend
|
||||
* @gr_backup: Backup of global registers during suspend
|
||||
* @dr_backup: Backup of device registers during suspend
|
||||
* @hr_backup: Backup of host registers during suspend
|
||||
*
|
||||
* These are for host mode:
|
||||
*
|
||||
* @flags: Flags for handling root port state changes
|
||||
* @flags.d32: Contain all root port flags
|
||||
* @flags.b: Separate root port flags from each other
|
||||
* @flags.b.port_connect_status_change: True if root port connect status
|
||||
* changed
|
||||
* @flags.b.port_connect_status: True if device connected to root port
|
||||
* @flags.b.port_reset_change: True if root port reset status changed
|
||||
* @flags.b.port_enable_change: True if root port enable status changed
|
||||
* @flags.b.port_suspend_change: True if root port suspend status changed
|
||||
* @flags.b.port_over_current_change: True if root port over current state
|
||||
* changed.
|
||||
* @flags.b.port_l1_change: True if root port l1 status changed
|
||||
* @flags.b.reserved: Reserved bits of root port register
|
||||
* @non_periodic_sched_inactive: Inactive QHs in the non-periodic schedule.
|
||||
* Transfers associated with these QHs are not currently
|
||||
* assigned to a host channel.
|
||||
@@ -847,6 +935,9 @@ struct dwc2_hregs_backup {
|
||||
* assigned to a host channel.
|
||||
* @non_periodic_qh_ptr: Pointer to next QH to process in the active
|
||||
* non-periodic schedule
|
||||
* @non_periodic_sched_waiting: Waiting QHs in the non-periodic schedule.
|
||||
* Transfers associated with these QHs are not currently
|
||||
* assigned to a host channel.
|
||||
* @periodic_sched_inactive: Inactive QHs in the periodic schedule. This is a
|
||||
* list of QHs for periodic transfers that are _not_
|
||||
* scheduled for the next frame. Each QH in the list has an
|
||||
@@ -886,8 +977,6 @@ struct dwc2_hregs_backup {
|
||||
* @hs_periodic_bitmap: Bitmap used by the microframe scheduler any time the
|
||||
* host is in high speed mode; low speed schedules are
|
||||
* stored elsewhere since we need one per TT.
|
||||
* @frame_number: Frame number read from the core at SOF. The value ranges
|
||||
* from 0 to HFNUM_MAX_FRNUM.
|
||||
* @periodic_qh_count: Count of periodic QHs, if using several eps. Used for
|
||||
* SOF enable/disable.
|
||||
* @free_hc_list: Free host channels in the controller. This is a list of
|
||||
@@ -898,8 +987,8 @@ struct dwc2_hregs_backup {
|
||||
* host channel is available for non-periodic transactions.
|
||||
* @non_periodic_channels: Number of host channels assigned to non-periodic
|
||||
* transfers
|
||||
* @available_host_channels Number of host channels available for the microframe
|
||||
* scheduler to use
|
||||
* @available_host_channels: Number of host channels available for the
|
||||
* microframe scheduler to use
|
||||
* @hc_ptr_array: Array of pointers to the host channel descriptors.
|
||||
* Allows accessing a host channel descriptor given the
|
||||
* host channel number. This is useful in interrupt
|
||||
@@ -922,9 +1011,6 @@ struct dwc2_hregs_backup {
|
||||
* @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos.
|
||||
* @num_of_eps: Number of available EPs (excluding EP0)
|
||||
* @debug_root: Root directrory for debugfs.
|
||||
* @debug_file: Main status file for debugfs.
|
||||
* @debug_testmode: Testmode status file for debugfs.
|
||||
* @debug_fifo: FIFO status file for debugfs.
|
||||
* @ep0_reply: Request used for ep0 reply.
|
||||
* @ep0_buff: Buffer for EP0 reply data, if needed.
|
||||
* @ctrl_buff: Buffer for EP0 control requests.
|
||||
@@ -939,7 +1025,37 @@ struct dwc2_hregs_backup {
|
||||
* @ctrl_in_desc: EP0 IN data phase desc chain pointer
|
||||
* @ctrl_out_desc_dma: EP0 OUT data phase desc chain DMA address
|
||||
* @ctrl_out_desc: EP0 OUT data phase desc chain pointer
|
||||
* @eps: The endpoints being supplied to the gadget framework
|
||||
* @irq: Interrupt request line number
|
||||
* @clk: Pointer to otg clock
|
||||
* @reset: Pointer to dwc2 reset controller
|
||||
* @reset_ecc: Pointer to dwc2 optional reset controller in Stratix10.
|
||||
* @regset: A pointer to a struct debugfs_regset32, which contains
|
||||
* a pointer to an array of register definitions, the
|
||||
* array size and the base address where the register bank
|
||||
* is to be found.
|
||||
* @bus_suspended: True if bus is suspended
|
||||
* @last_frame_num: Number of last frame. Range from 0 to 32768
|
||||
* @frame_num_array: Used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is
|
||||
* defined, for missed SOFs tracking. Array holds that
|
||||
* frame numbers, which not equal to last_frame_num +1
|
||||
* @last_frame_num_array: Used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is
|
||||
* defined, for missed SOFs tracking.
|
||||
* If current_frame_number != last_frame_num+1
|
||||
* then last_frame_num added to this array
|
||||
* @frame_num_idx: Actual size of frame_num_array and last_frame_num_array
|
||||
* @dumped_frame_num_array: 1 - if missed SOFs frame numbers dumbed
|
||||
* 0 - if missed SOFs frame numbers not dumbed
|
||||
* @fifo_mem: Total internal RAM for FIFOs (bytes)
|
||||
* @fifo_map: Each bit intend for concrete fifo. If that bit is set,
|
||||
* then that fifo is used
|
||||
* @gadget: Represents a usb slave device
|
||||
* @connected: Used in slave mode. True if device connected with host
|
||||
* @eps_in: The IN endpoints being supplied to the gadget framework
|
||||
* @eps_out: The OUT endpoints being supplied to the gadget framework
|
||||
* @new_connection: Used in host mode. True if there are new connected
|
||||
* device
|
||||
* @enabled: Indicates the enabling state of controller
|
||||
*
|
||||
*/
|
||||
struct dwc2_hsotg {
|
||||
struct device *dev;
|
||||
@@ -954,6 +1070,7 @@ struct dwc2_hsotg {
|
||||
unsigned int gadget_enabled:1;
|
||||
unsigned int ll_hw_enabled:1;
|
||||
unsigned int hibernated:1;
|
||||
u16 frame_number;
|
||||
|
||||
struct phy *phy;
|
||||
struct usb_phy *uphy;
|
||||
@@ -1029,7 +1146,6 @@ struct dwc2_hsotg {
|
||||
u16 periodic_usecs;
|
||||
unsigned long hs_periodic_bitmap[
|
||||
DIV_ROUND_UP(DWC2_HS_SCHEDULE_US, BITS_PER_LONG)];
|
||||
u16 frame_number;
|
||||
u16 periodic_qh_count;
|
||||
bool bus_suspended;
|
||||
bool new_connection;
|
||||
|
||||
@@ -778,6 +778,14 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Reading current frame number value in device or host modes. */
|
||||
if (dwc2_is_device_mode(hsotg))
|
||||
hsotg->frame_number = (dwc2_readl(hsotg->regs + DSTS)
|
||||
& DSTS_SOFFN_MASK) >> DSTS_SOFFN_SHIFT;
|
||||
else
|
||||
hsotg->frame_number = (dwc2_readl(hsotg->regs + HFNUM)
|
||||
& HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
|
||||
|
||||
gintsts = dwc2_read_common_intr(hsotg);
|
||||
if (gintsts & ~GINTSTS_PRTINT)
|
||||
retval = IRQ_HANDLED;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/**
|
||||
/*
|
||||
* debug.h - Designware USB2 DRD controller debug header
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/**
|
||||
/*
|
||||
* debugfs.c - Designware USB2 DRD controller debugfs
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
|
||||
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||
|
||||
/**
|
||||
* testmode_write - debugfs: change usb test mode
|
||||
* @seq: The seq file to write to.
|
||||
* @v: Unused parameter.
|
||||
*
|
||||
* This debugfs entry modify the current usb test mode.
|
||||
* testmode_write() - change usb test mode state.
|
||||
* @file: The file to write to.
|
||||
* @ubuf: The buffer where user wrote.
|
||||
* @count: The ubuf size.
|
||||
* @ppos: Unused parameter.
|
||||
*/
|
||||
static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t
|
||||
count, loff_t *ppos)
|
||||
@@ -55,9 +56,9 @@ static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t
|
||||
}
|
||||
|
||||
/**
|
||||
* testmode_show - debugfs: show usb test mode state
|
||||
* @seq: The seq file to write to.
|
||||
* @v: Unused parameter.
|
||||
* testmode_show() - debugfs: show usb test mode state
|
||||
* @s: The seq file to write to.
|
||||
* @unused: Unused parameter.
|
||||
*
|
||||
* This debugfs entry shows which usb test mode is currently enabled.
|
||||
*/
|
||||
@@ -368,7 +369,7 @@ static const struct debugfs_reg32 dwc2_regs[] = {
|
||||
dump_register(GINTSTS),
|
||||
dump_register(GINTMSK),
|
||||
dump_register(GRXSTSR),
|
||||
dump_register(GRXSTSP),
|
||||
/* Omit GRXSTSP */
|
||||
dump_register(GRXFSIZ),
|
||||
dump_register(GNPTXFSIZ),
|
||||
dump_register(GNPTXSTS),
|
||||
@@ -710,6 +711,7 @@ static int params_show(struct seq_file *seq, void *v)
|
||||
print_param(seq, p, phy_ulpi_ddr);
|
||||
print_param(seq, p, phy_ulpi_ext_vbus);
|
||||
print_param(seq, p, i2c_enable);
|
||||
print_param(seq, p, ipg_isoc_en);
|
||||
print_param(seq, p, ulpi_fs_ls);
|
||||
print_param(seq, p, host_support_fs_ls_low_power);
|
||||
print_param(seq, p, host_ls_low_power_phy_clk);
|
||||
|
||||
+181
-161
File diff suppressed because it is too large.
Load diff
@@ -597,7 +597,7 @@ u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg)
|
||||
* dwc2_read_packet() - Reads a packet from the Rx FIFO into the destination
|
||||
* buffer
|
||||
*
|
||||
* @core_if: Programming view of DWC_otg controller
|
||||
* @hsotg: Programming view of DWC_otg controller
|
||||
* @dest: Destination buffer for the packet
|
||||
* @bytes: Number of bytes to copy to the destination
|
||||
*/
|
||||
@@ -4087,7 +4087,6 @@ static struct dwc2_hsotg *dwc2_hcd_to_hsotg(struct usb_hcd *hcd)
|
||||
* then the refcount for the structure will go to 0 and we'll free it.
|
||||
*
|
||||
* @hsotg: The HCD state structure for the DWC OTG controller.
|
||||
* @qh: The QH structure.
|
||||
* @context: The priv pointer from a struct dwc2_hcd_urb.
|
||||
* @mem_flags: Flags for allocating memory.
|
||||
* @ttport: We'll return this device's port number here. That's used to
|
||||
|
||||
@@ -80,7 +80,7 @@ struct dwc2_qh;
|
||||
* @xfer_count: Number of bytes transferred so far
|
||||
* @start_pkt_count: Packet count at start of transfer
|
||||
* @xfer_started: True if the transfer has been started
|
||||
* @ping: True if a PING request should be issued on this channel
|
||||
* @do_ping: True if a PING request should be issued on this channel
|
||||
* @error_state: True if the error count for this transaction is non-zero
|
||||
* @halt_on_queue: True if this channel should be halted the next time a
|
||||
* request is queued for the channel. This is necessary in
|
||||
@@ -102,7 +102,7 @@ struct dwc2_qh;
|
||||
* @schinfo: Scheduling micro-frame bitmap
|
||||
* @ntd: Number of transfer descriptors for the transfer
|
||||
* @halt_status: Reason for halting the host channel
|
||||
* @hcint Contents of the HCINT register when the interrupt came
|
||||
* @hcint: Contents of the HCINT register when the interrupt came
|
||||
* @qh: QH for the transfer being processed by this channel
|
||||
* @hc_list_entry: For linking to list of host channels
|
||||
* @desc_list_addr: Current QH's descriptor list DMA address
|
||||
@@ -237,7 +237,7 @@ struct dwc2_tt {
|
||||
/**
|
||||
* struct dwc2_hs_transfer_time - Info about a transfer on the high speed bus.
|
||||
*
|
||||
* @start_schedule_usecs: The start time on the main bus schedule. Note that
|
||||
* @start_schedule_us: The start time on the main bus schedule. Note that
|
||||
* the main bus schedule is tightly packed and this
|
||||
* time should be interpreted as tightly packed (so
|
||||
* uFrame 0 starts at 0 us, uFrame 1 starts at 100 us
|
||||
@@ -301,7 +301,6 @@ struct dwc2_hs_transfer_time {
|
||||
* "struct dwc2_tt". Not used if this device is high
|
||||
* speed. Note that this is in "schedule slice" which
|
||||
* is tightly packed.
|
||||
* @ls_duration_us: Duration on the low speed bus schedule.
|
||||
* @ntd: Actual number of transfer descriptors in a list
|
||||
* @qtd_list: List of QTDs for this QH
|
||||
* @channel: Host channel currently processing transfers for this QH
|
||||
@@ -315,7 +314,7 @@ struct dwc2_hs_transfer_time {
|
||||
* descriptor
|
||||
* @unreserve_timer: Timer for releasing periodic reservation.
|
||||
* @wait_timer: Timer used to wait before re-queuing.
|
||||
* @dwc2_tt: Pointer to our tt info (or NULL if no tt).
|
||||
* @dwc_tt: Pointer to our tt info (or NULL if no tt).
|
||||
* @ttport: Port number within our tt.
|
||||
* @tt_buffer_dirty True if clear_tt_buffer_complete is pending
|
||||
* @unreserve_pending: True if we planned to unreserve but haven't yet.
|
||||
@@ -325,6 +324,7 @@ struct dwc2_hs_transfer_time {
|
||||
* periodic transfers and is ignored for periodic ones.
|
||||
* @wait_timer_cancel: Set to true to cancel the wait_timer.
|
||||
*
|
||||
* @tt_buffer_dirty: True if EP's TT buffer is not clean.
|
||||
* A Queue Head (QH) holds the static characteristics of an endpoint and
|
||||
* maintains a list of transfers (QTDs) for that endpoint. A QH structure may
|
||||
* be entered in either the non-periodic or periodic schedule.
|
||||
@@ -400,6 +400,10 @@ struct dwc2_qh {
|
||||
* @urb: URB for this transfer
|
||||
* @qh: Queue head for this QTD
|
||||
* @qtd_list_entry: For linking to the QH's list of QTDs
|
||||
* @isoc_td_first: Index of first activated isochronous transfer
|
||||
* descriptor in Descriptor DMA mode
|
||||
* @isoc_td_last: Index of last activated isochronous transfer
|
||||
* descriptor in Descriptor DMA mode
|
||||
*
|
||||
* A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
|
||||
* interrupt, or isochronous transfer. A single QTD is created for each URB
|
||||
|
||||
@@ -332,6 +332,7 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg,
|
||||
*
|
||||
* @hsotg: The HCD state structure for the DWC OTG controller
|
||||
* @qh: The QH to init
|
||||
* @mem_flags: Indicates the type of memory allocation
|
||||
*
|
||||
* Return: 0 if successful, negative error code otherwise
|
||||
*
|
||||
|
||||
@@ -478,6 +478,12 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg,
|
||||
* of the URB based on the number of bytes transferred via the host channel.
|
||||
* Sets the URB status if the data transfer is finished.
|
||||
*
|
||||
* @hsotg: Programming view of the DWC_otg controller
|
||||
* @chan: Programming view of host channel
|
||||
* @chnum: Channel number
|
||||
* @urb: Processing URB
|
||||
* @qtd: Queue transfer descriptor
|
||||
*
|
||||
* Return: 1 if the data transfer specified by the URB is completely finished,
|
||||
* 0 otherwise
|
||||
*/
|
||||
@@ -566,6 +572,12 @@ void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
|
||||
* halt_status. Completes the Isochronous URB if all the URB frames have been
|
||||
* completed.
|
||||
*
|
||||
* @hsotg: Programming view of the DWC_otg controller
|
||||
* @chan: Programming view of host channel
|
||||
* @chnum: Channel number
|
||||
* @halt_status: Reason for halting a host channel
|
||||
* @qtd: Queue transfer descriptor
|
||||
*
|
||||
* Return: DWC2_HC_XFER_COMPLETE if there are more frames remaining to be
|
||||
* transferred in the URB. Otherwise return DWC2_HC_XFER_URB_COMPLETE.
|
||||
*/
|
||||
|
||||
@@ -679,6 +679,7 @@ static int dwc2_hs_pmap_schedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
||||
*
|
||||
* @hsotg: The HCD state structure for the DWC OTG controller.
|
||||
* @qh: QH for the periodic transfer.
|
||||
* @index: Transfer index
|
||||
*/
|
||||
static void dwc2_hs_pmap_unschedule(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *qh, int index)
|
||||
@@ -1276,7 +1277,7 @@ static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
* release the reservation. This worker is called after the appropriate
|
||||
* delay.
|
||||
*
|
||||
* @work: Pointer to a qh unreserve_work.
|
||||
* @t: Address to a qh unreserve_work.
|
||||
*/
|
||||
static void dwc2_unreserve_timer_fn(struct timer_list *t)
|
||||
{
|
||||
@@ -1631,7 +1632,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
||||
* @hsotg: The HCD state structure for the DWC OTG controller
|
||||
* @urb: Holds the information about the device/endpoint needed
|
||||
* to initialize the QH
|
||||
* @atomic_alloc: Flag to do atomic allocation if needed
|
||||
* @mem_flags: Flags for allocating memory.
|
||||
*
|
||||
* Return: Pointer to the newly allocated QH, or NULL on error
|
||||
*/
|
||||
|
||||
@@ -311,6 +311,7 @@
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14
|
||||
#define GHWCFG4_ACG_SUPPORTED BIT(12)
|
||||
#define GHWCFG4_IPG_ISOC_SUPPORTED BIT(11)
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1
|
||||
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2
|
||||
@@ -424,6 +425,7 @@
|
||||
#define DCFG_EPMISCNT_SHIFT 18
|
||||
#define DCFG_EPMISCNT_LIMIT 0x1f
|
||||
#define DCFG_EPMISCNT(_x) ((_x) << 18)
|
||||
#define DCFG_IPG_ISOC_SUPPORDED BIT(17)
|
||||
#define DCFG_PERFRINT_MASK (0x3 << 11)
|
||||
#define DCFG_PERFRINT_SHIFT 11
|
||||
#define DCFG_PERFRINT_LIMIT 0x3
|
||||
|
||||
@@ -70,6 +70,7 @@ static void dwc2_set_his_params(struct dwc2_hsotg *hsotg)
|
||||
GAHBCFG_HBSTLEN_SHIFT;
|
||||
p->uframe_sched = false;
|
||||
p->change_speed_quirk = true;
|
||||
p->power_down = false;
|
||||
}
|
||||
|
||||
static void dwc2_set_rk_params(struct dwc2_hsotg *hsotg)
|
||||
@@ -269,6 +270,9 @@ static void dwc2_set_param_power_down(struct dwc2_hsotg *hsotg)
|
||||
/**
|
||||
* dwc2_set_default_params() - Set all core parameters to their
|
||||
* auto-detected default values.
|
||||
*
|
||||
* @hsotg: Programming view of the DWC_otg controller
|
||||
*
|
||||
*/
|
||||
static void dwc2_set_default_params(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
@@ -298,6 +302,7 @@ static void dwc2_set_default_params(struct dwc2_hsotg *hsotg)
|
||||
p->besl = true;
|
||||
p->hird_threshold_en = true;
|
||||
p->hird_threshold = 4;
|
||||
p->ipg_isoc_en = false;
|
||||
p->max_packet_count = hw->max_packet_count;
|
||||
p->max_transfer_size = hw->max_transfer_size;
|
||||
p->ahbcfg = GAHBCFG_HBSTLEN_INCR << GAHBCFG_HBSTLEN_SHIFT;
|
||||
@@ -338,6 +343,8 @@ static void dwc2_set_default_params(struct dwc2_hsotg *hsotg)
|
||||
/**
|
||||
* dwc2_get_device_properties() - Read in device properties.
|
||||
*
|
||||
* @hsotg: Programming view of the DWC_otg controller
|
||||
*
|
||||
* Read in the device properties and adjust core parameters if needed.
|
||||
*/
|
||||
static void dwc2_get_device_properties(struct dwc2_hsotg *hsotg)
|
||||
@@ -549,7 +556,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
|
||||
}
|
||||
|
||||
#define CHECK_RANGE(_param, _min, _max, _def) do { \
|
||||
if ((hsotg->params._param) < (_min) || \
|
||||
if ((int)(hsotg->params._param) < (_min) || \
|
||||
(hsotg->params._param) > (_max)) { \
|
||||
dev_warn(hsotg->dev, "%s: Invalid parameter %s=%d\n", \
|
||||
__func__, #_param, hsotg->params._param); \
|
||||
@@ -579,6 +586,7 @@ static void dwc2_check_params(struct dwc2_hsotg *hsotg)
|
||||
CHECK_BOOL(enable_dynamic_fifo, hw->enable_dynamic_fifo);
|
||||
CHECK_BOOL(en_multiple_tx_fifo, hw->en_multiple_tx_fifo);
|
||||
CHECK_BOOL(i2c_enable, hw->i2c_enable);
|
||||
CHECK_BOOL(ipg_isoc_en, hw->ipg_isoc_en);
|
||||
CHECK_BOOL(acg_enable, hw->acg_enable);
|
||||
CHECK_BOOL(reload_ctl, (hsotg->hw_params.snpsid > DWC2_CORE_REV_2_92a));
|
||||
CHECK_BOOL(lpm, (hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_80a));
|
||||
@@ -688,6 +696,9 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
|
||||
/**
|
||||
* During device initialization, read various hardware configuration
|
||||
* registers and interpret the contents.
|
||||
*
|
||||
* @hsotg: Programming view of the DWC_otg controller
|
||||
*
|
||||
*/
|
||||
int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
@@ -772,6 +783,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
|
||||
hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
|
||||
GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
|
||||
hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED);
|
||||
hw->ipg_isoc_en = !!(hwcfg4 & GHWCFG4_IPG_ISOC_SUPPORTED);
|
||||
|
||||
/* fifo sizes */
|
||||
hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
|
||||
|
||||
@@ -77,6 +77,12 @@ static int dwc2_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_pci_probe() - Provides the cleanup entry points for the DWC_otg PCI
|
||||
* driver
|
||||
*
|
||||
* @pci: The programming view of DWC_otg PCI
|
||||
*/
|
||||
static void dwc2_pci_remove(struct pci_dev *pci)
|
||||
{
|
||||
struct dwc2_pci_glue *glue = pci_get_drvdata(pci);
|
||||
|
||||
@@ -106,4 +106,16 @@ config USB_DWC3_ST
|
||||
inside (i.e. STiH407).
|
||||
Say 'Y' or 'M' if you have one such device.
|
||||
|
||||
config USB_DWC3_QCOM
|
||||
tristate "Qualcomm Platform"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on OF
|
||||
default USB_DWC3
|
||||
help
|
||||
Some Qualcomm SoCs use DesignWare Core IP for USB2/3
|
||||
functionality.
|
||||
This driver also handles Qscratch wrapper which is needed
|
||||
for peripheral mode support.
|
||||
Say 'Y' or 'M' if you have one such device.
|
||||
|
||||
endif
|
||||
@@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o
|
||||
obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o
|
||||
obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o
|
||||
obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o
|
||||
obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
|
||||
+126
-28
@@ -8,6 +8,7 @@
|
||||
* Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -24,6 +25,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
@@ -266,6 +268,12 @@ done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_bulk_data dwc3_core_clks[] = {
|
||||
{ .id = "ref" },
|
||||
{ .id = "bus_early" },
|
||||
{ .id = "suspend" },
|
||||
};
|
||||
|
||||
/*
|
||||
* dwc3_frame_length_adjustment - Adjusts frame length if required
|
||||
* @dwc3: Pointer to our controller context structure
|
||||
@@ -667,6 +675,9 @@ static void dwc3_core_exit(struct dwc3 *dwc)
|
||||
usb_phy_set_suspend(dwc->usb3_phy, 1);
|
||||
phy_power_off(dwc->usb2_generic_phy);
|
||||
phy_power_off(dwc->usb3_generic_phy);
|
||||
clk_bulk_disable(dwc->num_clks, dwc->clks);
|
||||
clk_bulk_unprepare(dwc->num_clks, dwc->clks);
|
||||
reset_control_assert(dwc->reset);
|
||||
}
|
||||
|
||||
static bool dwc3_core_is_valid(struct dwc3 *dwc)
|
||||
@@ -1245,7 +1256,7 @@ static void dwc3_check_params(struct dwc3 *dwc)
|
||||
static int dwc3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct resource *res, dwc_res;
|
||||
struct dwc3 *dwc;
|
||||
|
||||
int ret;
|
||||
@@ -1256,6 +1267,12 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
if (!dwc)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc->clks = devm_kmemdup(dev, dwc3_core_clks, sizeof(dwc3_core_clks),
|
||||
GFP_KERNEL);
|
||||
if (!dwc->clks)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc->num_clks = ARRAY_SIZE(dwc3_core_clks);
|
||||
dwc->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
@@ -1270,23 +1287,48 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
dwc->xhci_resources[0].flags = res->flags;
|
||||
dwc->xhci_resources[0].name = res->name;
|
||||
|
||||
res->start += DWC3_GLOBALS_REGS_START;
|
||||
|
||||
/*
|
||||
* Request memory region but exclude xHCI regs,
|
||||
* since it will be requested by the xhci-plat driver.
|
||||
*/
|
||||
regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(regs)) {
|
||||
ret = PTR_ERR(regs);
|
||||
goto err0;
|
||||
}
|
||||
dwc_res = *res;
|
||||
dwc_res.start += DWC3_GLOBALS_REGS_START;
|
||||
|
||||
regs = devm_ioremap_resource(dev, &dwc_res);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
dwc->regs = regs;
|
||||
dwc->regs_size = resource_size(res);
|
||||
dwc->regs_size = resource_size(&dwc_res);
|
||||
|
||||
dwc3_get_properties(dwc);
|
||||
|
||||
dwc->reset = devm_reset_control_get_optional_shared(dev, NULL);
|
||||
if (IS_ERR(dwc->reset))
|
||||
return PTR_ERR(dwc->reset);
|
||||
|
||||
ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
/*
|
||||
* Clocks are optional, but new DT platforms should support all clocks
|
||||
* as required by the DT-binding.
|
||||
*/
|
||||
if (ret)
|
||||
dwc->num_clks = 0;
|
||||
|
||||
ret = reset_control_deassert(dwc->reset);
|
||||
if (ret)
|
||||
goto put_clks;
|
||||
|
||||
ret = clk_bulk_prepare(dwc->num_clks, dwc->clks);
|
||||
if (ret)
|
||||
goto assert_reset;
|
||||
|
||||
ret = clk_bulk_enable(dwc->num_clks, dwc->clks);
|
||||
if (ret)
|
||||
goto unprepare_clks;
|
||||
|
||||
platform_set_drvdata(pdev, dwc);
|
||||
dwc3_cache_hwparams(dwc);
|
||||
|
||||
@@ -1350,13 +1392,13 @@ err1:
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
err0:
|
||||
/*
|
||||
* restore res->start back to its original value so that, in case the
|
||||
* probe is deferred, we don't end up getting error in request the
|
||||
* memory region the next time probe is called.
|
||||
*/
|
||||
res->start -= DWC3_GLOBALS_REGS_START;
|
||||
clk_bulk_disable(dwc->num_clks, dwc->clks);
|
||||
unprepare_clks:
|
||||
clk_bulk_unprepare(dwc->num_clks, dwc->clks);
|
||||
assert_reset:
|
||||
reset_control_assert(dwc->reset);
|
||||
put_clks:
|
||||
clk_bulk_put(dwc->num_clks, dwc->clks);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1364,15 +1406,8 @@ err0:
|
||||
static int dwc3_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dwc3 *dwc = platform_get_drvdata(pdev);
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
/*
|
||||
* restore res->start back to its original value so that, in case the
|
||||
* probe is deferred, we don't end up getting error in request the
|
||||
* memory region the next time probe is called.
|
||||
*/
|
||||
res->start -= DWC3_GLOBALS_REGS_START;
|
||||
|
||||
dwc3_debugfs_exit(dwc);
|
||||
dwc3_core_exit_mode(dwc);
|
||||
@@ -1386,14 +1421,48 @@ static int dwc3_remove(struct platform_device *pdev)
|
||||
|
||||
dwc3_free_event_buffers(dwc);
|
||||
dwc3_free_scratch_buffers(dwc);
|
||||
clk_bulk_put(dwc->num_clks, dwc->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int dwc3_core_init_for_resume(struct dwc3 *dwc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = reset_control_deassert(dwc->reset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_bulk_prepare(dwc->num_clks, dwc->clks);
|
||||
if (ret)
|
||||
goto assert_reset;
|
||||
|
||||
ret = clk_bulk_enable(dwc->num_clks, dwc->clks);
|
||||
if (ret)
|
||||
goto unprepare_clks;
|
||||
|
||||
ret = dwc3_core_init(dwc);
|
||||
if (ret)
|
||||
goto disable_clks;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clks:
|
||||
clk_bulk_disable(dwc->num_clks, dwc->clks);
|
||||
unprepare_clks:
|
||||
clk_bulk_unprepare(dwc->num_clks, dwc->clks);
|
||||
assert_reset:
|
||||
reset_control_assert(dwc->reset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
switch (dwc->current_dr_role) {
|
||||
case DWC3_GCTL_PRTCAP_DEVICE:
|
||||
@@ -1403,9 +1472,25 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
dwc3_core_exit(dwc);
|
||||
break;
|
||||
case DWC3_GCTL_PRTCAP_HOST:
|
||||
/* do nothing during host runtime_suspend */
|
||||
if (!PMSG_IS_AUTO(msg))
|
||||
if (!PMSG_IS_AUTO(msg)) {
|
||||
dwc3_core_exit(dwc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Let controller to suspend HSPHY before PHY driver suspends */
|
||||
if (dwc->dis_u2_susphy_quirk ||
|
||||
dwc->dis_enblslpm_quirk) {
|
||||
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
||||
reg |= DWC3_GUSB2PHYCFG_ENBLSLPM |
|
||||
DWC3_GUSB2PHYCFG_SUSPHY;
|
||||
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
||||
|
||||
/* Give some time for USB2 PHY to suspend */
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
|
||||
phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
|
||||
phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
|
||||
break;
|
||||
case DWC3_GCTL_PRTCAP_OTG:
|
||||
/* do nothing during runtime_suspend */
|
||||
@@ -1433,10 +1518,11 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
switch (dwc->current_dr_role) {
|
||||
case DWC3_GCTL_PRTCAP_DEVICE:
|
||||
ret = dwc3_core_init(dwc);
|
||||
ret = dwc3_core_init_for_resume(dwc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1446,13 +1532,25 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
break;
|
||||
case DWC3_GCTL_PRTCAP_HOST:
|
||||
/* nothing to do on host runtime_resume */
|
||||
if (!PMSG_IS_AUTO(msg)) {
|
||||
ret = dwc3_core_init(dwc);
|
||||
ret = dwc3_core_init_for_resume(dwc);
|
||||
if (ret)
|
||||
return ret;
|
||||
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
|
||||
break;
|
||||
}
|
||||
/* Restore GUSB2PHYCFG bits that were modified in suspend */
|
||||
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
||||
if (dwc->dis_u2_susphy_quirk)
|
||||
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
|
||||
|
||||
if (dwc->dis_enblslpm_quirk)
|
||||
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
|
||||
|
||||
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
||||
|
||||
phy_pm_runtime_get_sync(dwc->usb2_generic_phy);
|
||||
phy_pm_runtime_get_sync(dwc->usb3_generic_phy);
|
||||
break;
|
||||
case DWC3_GCTL_PRTCAP_OTG:
|
||||
/* nothing to do on runtime_resume */
|
||||
|
||||
Loaded 20 of 58 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user