You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'usb-for-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: USB: changes for v4.11 Here's the big pull request for the Gadget API. Again the majority of changes sit in dwc2 driver. Most important changes contain a workaround for GOTGCTL being wrong, a sleep-inside-spinlock fix and the big series of cleanups on dwc2. One important thing on dwc3 is that we don't anymore need gadget drivers to cope with unaligned OUT transfers for us. We have support for appending one extra chained TRB to align transfer ourselves. Apart from these, the usual set of typos, non-critical fixes, etc.
This commit is contained in:
@@ -20,10 +20,10 @@ See: Documentation/devicetree/bindings/reset/reset.txt
|
|||||||
with 'reg' property
|
with 'reg' property
|
||||||
|
|
||||||
- pinctl-names : A pinctrl state named "default" must be defined
|
- pinctl-names : A pinctrl state named "default" must be defined
|
||||||
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
|
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||||
|
|
||||||
- pinctrl-0 : Pin control group
|
- pinctrl-0 : Pin control group
|
||||||
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
|
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||||
|
|
||||||
- ranges : allows valid 1:1 translation between child's address space and
|
- ranges : allows valid 1:1 translation between child's address space and
|
||||||
parent's address space
|
parent's address space
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ Optional properties:
|
|||||||
|
|
||||||
- <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.
|
- <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.
|
||||||
|
|
||||||
|
- in addition all properties from usb-xhci.txt from the current directory are
|
||||||
|
supported as well
|
||||||
|
|
||||||
|
|
||||||
This is usually a subnode to DWC3 glue to which it is connected.
|
This is usually a subnode to DWC3 glue to which it is connected.
|
||||||
|
|
||||||
dwc3@4a030000 {
|
dwc3@4a030000 {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Required properties:
|
|||||||
- interrupts : one EHCI interrupt should be described here
|
- interrupts : one EHCI interrupt should be described here
|
||||||
- pinctrl-names : a pinctrl state named "default" must be defined
|
- pinctrl-names : a pinctrl state named "default" must be defined
|
||||||
- pinctrl-0 : phandle referencing pin configuration of the USB controller
|
- pinctrl-0 : phandle referencing pin configuration of the USB controller
|
||||||
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
|
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||||
- clocks : phandle list of usb clocks
|
- clocks : phandle list of usb clocks
|
||||||
- clock-names : should be "ic" for interconnect clock and "clk48"
|
- clock-names : should be "ic" for interconnect clock and "clk48"
|
||||||
See: Documentation/devicetree/bindings/clock/clock-bindings.txt
|
See: Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Optional properties:
|
|||||||
"id_float" and "id_ground" are optinal which depends on
|
"id_float" and "id_ground" are optinal which depends on
|
||||||
"mediatek,enable-manual-drd"
|
"mediatek,enable-manual-drd"
|
||||||
- pinctrl-0 : pin control group
|
- pinctrl-0 : pin control group
|
||||||
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
|
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||||
|
|
||||||
- maximum-speed : valid arguments are "super-speed", "high-speed" and
|
- maximum-speed : valid arguments are "super-speed", "high-speed" and
|
||||||
"full-speed"; refer to usb/generic.txt
|
"full-speed"; refer to usb/generic.txt
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ Optional properties:
|
|||||||
- usb3-lpm-capable : supports USB3.0 LPM
|
- usb3-lpm-capable : supports USB3.0 LPM
|
||||||
- pinctrl-names : a pinctrl state named "default" must be defined
|
- pinctrl-names : a pinctrl state named "default" must be defined
|
||||||
- pinctrl-0 : pin control group
|
- pinctrl-0 : pin control group
|
||||||
See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt
|
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
usb30: usb@11270000 {
|
usb30: usb@11270000 {
|
||||||
@@ -68,7 +68,7 @@ usb30: usb@11270000 {
|
|||||||
|
|
||||||
In the case, xhci is added as subnode to mtu3. An example and the DT binding
|
In the case, xhci is added as subnode to mtu3. An example and the DT binding
|
||||||
details of mtu3 can be found in:
|
details of mtu3 can be found in:
|
||||||
Documentation/devicetree/bindings/usb/mtu3.txt
|
Documentation/devicetree/bindings/usb/mt8173-mtu3.txt
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : should contain "mediatek,mt8173-xhci"
|
- compatible : should contain "mediatek,mt8173-xhci"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ 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.
|
the node is not important. The content of the node is defined in dwc3.txt.
|
||||||
|
|
||||||
Phy documentation is provided in the following places:
|
Phy documentation is provided in the following places:
|
||||||
Documentation/devicetree/bindings/phy/qcom,dwc3-usb-phy.txt
|
Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt
|
||||||
|
|
||||||
Example device nodes:
|
Example device nodes:
|
||||||
|
|
||||||
|
|||||||
@@ -632,6 +632,8 @@ The uac2 function provides these attributes in its function directory:
|
|||||||
p_chmask - playback channel mask
|
p_chmask - playback channel mask
|
||||||
p_srate - playback sampling rate
|
p_srate - playback sampling rate
|
||||||
p_ssize - playback sample size (bytes)
|
p_ssize - playback sample size (bytes)
|
||||||
|
req_number - the number of pre-allocated request for both capture
|
||||||
|
and playback
|
||||||
|
|
||||||
The attributes have sane default values.
|
The attributes have sane default values.
|
||||||
|
|
||||||
|
|||||||
+17
-22
@@ -104,7 +104,7 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
|
|||||||
gr = &hsotg->gr_backup;
|
gr = &hsotg->gr_backup;
|
||||||
if (!gr->valid) {
|
if (!gr->valid) {
|
||||||
dev_err(hsotg->dev, "%s: no global registers to restore\n",
|
dev_err(hsotg->dev, "%s: no global registers to restore\n",
|
||||||
__func__);
|
__func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
gr->valid = false;
|
gr->valid = false;
|
||||||
@@ -155,21 +155,21 @@ int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore)
|
|||||||
ret = dwc2_restore_global_registers(hsotg);
|
ret = dwc2_restore_global_registers(hsotg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hsotg->dev, "%s: failed to restore registers\n",
|
dev_err(hsotg->dev, "%s: failed to restore registers\n",
|
||||||
__func__);
|
__func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (dwc2_is_host_mode(hsotg)) {
|
if (dwc2_is_host_mode(hsotg)) {
|
||||||
ret = dwc2_restore_host_registers(hsotg);
|
ret = dwc2_restore_host_registers(hsotg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hsotg->dev, "%s: failed to restore host registers\n",
|
dev_err(hsotg->dev, "%s: failed to restore host registers\n",
|
||||||
__func__);
|
__func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = dwc2_restore_device_registers(hsotg);
|
ret = dwc2_restore_device_registers(hsotg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hsotg->dev, "%s: failed to restore device registers\n",
|
dev_err(hsotg->dev, "%s: failed to restore device registers\n",
|
||||||
__func__);
|
__func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg)
|
|||||||
ret = dwc2_backup_global_registers(hsotg);
|
ret = dwc2_backup_global_registers(hsotg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hsotg->dev, "%s: failed to backup global registers\n",
|
dev_err(hsotg->dev, "%s: failed to backup global registers\n",
|
||||||
__func__);
|
__func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,14 +203,14 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg)
|
|||||||
ret = dwc2_backup_host_registers(hsotg);
|
ret = dwc2_backup_host_registers(hsotg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hsotg->dev, "%s: failed to backup host registers\n",
|
dev_err(hsotg->dev, "%s: failed to backup host registers\n",
|
||||||
__func__);
|
__func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = dwc2_backup_device_registers(hsotg);
|
ret = dwc2_backup_device_registers(hsotg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hsotg->dev, "%s: failed to backup device registers\n",
|
dev_err(hsotg->dev, "%s: failed to backup device registers\n",
|
||||||
__func__);
|
__func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,7 +313,7 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg)
|
|||||||
* Do core a soft reset of the core. Be careful with this because it
|
* Do core a soft reset of the core. Be careful with this because it
|
||||||
* resets all the internal state machines of the core.
|
* resets all the internal state machines of the core.
|
||||||
*/
|
*/
|
||||||
int dwc2_core_reset(struct dwc2_hsotg *hsotg)
|
int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait)
|
||||||
{
|
{
|
||||||
u32 greset;
|
u32 greset;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -369,7 +369,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg)
|
|||||||
}
|
}
|
||||||
} while (!(greset & GRSTCTL_AHBIDLE));
|
} while (!(greset & GRSTCTL_AHBIDLE));
|
||||||
|
|
||||||
if (wait_for_host_mode)
|
if (wait_for_host_mode && !skip_wait)
|
||||||
dwc2_wait_for_mode(hsotg, true);
|
dwc2_wait_for_mode(hsotg, true);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -455,7 +455,7 @@ void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
|
|||||||
dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
|
dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
|
||||||
|
|
||||||
if (dwc2_iddig_filter_enabled(hsotg))
|
if (dwc2_iddig_filter_enabled(hsotg))
|
||||||
usleep_range(100000, 110000);
|
msleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -500,7 +500,7 @@ int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg)
|
|||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
retval = dwc2_core_reset(hsotg);
|
retval = dwc2_core_reset(hsotg, false);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
@@ -541,7 +541,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
|
|||||||
addr = hsotg->regs + HAINTMSK;
|
addr = hsotg->regs + HAINTMSK;
|
||||||
dev_dbg(hsotg->dev, "HAINTMSK @0x%08lX : 0x%08X\n",
|
dev_dbg(hsotg->dev, "HAINTMSK @0x%08lX : 0x%08X\n",
|
||||||
(unsigned long)addr, dwc2_readl(addr));
|
(unsigned long)addr, dwc2_readl(addr));
|
||||||
if (hsotg->params.dma_desc_enable > 0) {
|
if (hsotg->params.dma_desc_enable) {
|
||||||
addr = hsotg->regs + HFLBADDR;
|
addr = hsotg->regs + HFLBADDR;
|
||||||
dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n",
|
dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n",
|
||||||
(unsigned long)addr, dwc2_readl(addr));
|
(unsigned long)addr, dwc2_readl(addr));
|
||||||
@@ -571,7 +571,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
|
|||||||
addr = hsotg->regs + HCDMA(i);
|
addr = hsotg->regs + HCDMA(i);
|
||||||
dev_dbg(hsotg->dev, "HCDMA @0x%08lX : 0x%08X\n",
|
dev_dbg(hsotg->dev, "HCDMA @0x%08lX : 0x%08X\n",
|
||||||
(unsigned long)addr, dwc2_readl(addr));
|
(unsigned long)addr, dwc2_readl(addr));
|
||||||
if (hsotg->params.dma_desc_enable > 0) {
|
if (hsotg->params.dma_desc_enable) {
|
||||||
addr = hsotg->regs + HCDMAB(i);
|
addr = hsotg->regs + HCDMAB(i);
|
||||||
dev_dbg(hsotg->dev, "HCDMAB @0x%08lX : 0x%08X\n",
|
dev_dbg(hsotg->dev, "HCDMAB @0x%08lX : 0x%08X\n",
|
||||||
(unsigned long)addr, dwc2_readl(addr));
|
(unsigned long)addr, dwc2_readl(addr));
|
||||||
@@ -751,11 +751,6 @@ bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host)
|
|||||||
return dwc2_force_mode(hsotg, host);
|
return dwc2_force_mode(hsotg, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg)
|
|
||||||
{
|
|
||||||
return hsotg->params.otg_ver == 1 ? 0x0200 : 0x0103;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
|
bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
if (dwc2_readl(hsotg->regs + GSNPSID) == 0xffffffff)
|
if (dwc2_readl(hsotg->regs + GSNPSID) == 0xffffffff)
|
||||||
@@ -793,7 +788,7 @@ void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the controller's GHWCFG2.OTG_MODE. */
|
/* Returns the controller's GHWCFG2.OTG_MODE. */
|
||||||
unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg)
|
unsigned int dwc2_op_mode(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
u32 ghwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2);
|
u32 ghwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2);
|
||||||
|
|
||||||
@@ -804,7 +799,7 @@ unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg)
|
|||||||
/* Returns true if the controller is capable of DRD. */
|
/* Returns true if the controller is capable of DRD. */
|
||||||
bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg)
|
bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
unsigned op_mode = dwc2_op_mode(hsotg);
|
unsigned int op_mode = dwc2_op_mode(hsotg);
|
||||||
|
|
||||||
return (op_mode == GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) ||
|
return (op_mode == GHWCFG2_OP_MODE_HNP_SRP_CAPABLE) ||
|
||||||
(op_mode == GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE) ||
|
(op_mode == GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE) ||
|
||||||
@@ -814,7 +809,7 @@ bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg)
|
|||||||
/* Returns true if the controller is host-only. */
|
/* Returns true if the controller is host-only. */
|
||||||
bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg)
|
bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
unsigned op_mode = dwc2_op_mode(hsotg);
|
unsigned int op_mode = dwc2_op_mode(hsotg);
|
||||||
|
|
||||||
return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_HOST) ||
|
return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_HOST) ||
|
||||||
(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST);
|
(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST);
|
||||||
@@ -823,7 +818,7 @@ bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg)
|
|||||||
/* Returns true if the controller is device-only. */
|
/* Returns true if the controller is device-only. */
|
||||||
bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg)
|
bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
unsigned op_mode = dwc2_op_mode(hsotg);
|
unsigned int op_mode = dwc2_op_mode(hsotg);
|
||||||
|
|
||||||
return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
|
return (op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
|
||||||
(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE);
|
(op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE);
|
||||||
|
|||||||
+101
-107
@@ -127,6 +127,8 @@ static const char * const dwc2_hsotg_supply_names[] = {
|
|||||||
"vusb_a", /* analog USB supply, 1.1V */
|
"vusb_a", /* analog USB supply, 1.1V */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DWC2_NUM_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EP0_MPS_LIMIT
|
* EP0_MPS_LIMIT
|
||||||
*
|
*
|
||||||
@@ -246,7 +248,8 @@ struct dwc2_hsotg_req {
|
|||||||
void *saved_req_buf;
|
void *saved_req_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
|
||||||
|
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||||
#define call_gadget(_hs, _entry) \
|
#define call_gadget(_hs, _entry) \
|
||||||
do { \
|
do { \
|
||||||
if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \
|
if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \
|
||||||
@@ -271,13 +274,6 @@ enum dwc2_lx_state {
|
|||||||
DWC2_L3, /* Off state */
|
DWC2_L3, /* Off state */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Gadget periodic tx fifo sizes as used by legacy driver
|
|
||||||
* EP0 is not included
|
|
||||||
*/
|
|
||||||
#define DWC2_G_P_LEGACY_TX_FIFO_SIZE {256, 256, 256, 256, 768, 768, 768, \
|
|
||||||
768, 0, 0, 0, 0, 0, 0, 0}
|
|
||||||
|
|
||||||
/* Gadget ep0 states */
|
/* Gadget ep0 states */
|
||||||
enum dwc2_ep0_state {
|
enum dwc2_ep0_state {
|
||||||
DWC2_EP0_SETUP,
|
DWC2_EP0_SETUP,
|
||||||
@@ -295,9 +291,6 @@ enum dwc2_ep0_state {
|
|||||||
* 1 - SRP Only capable
|
* 1 - SRP Only capable
|
||||||
* 2 - No HNP/SRP capable (always available)
|
* 2 - No HNP/SRP capable (always available)
|
||||||
* Defaults to best available option (0, 1, then 2)
|
* Defaults to best available option (0, 1, then 2)
|
||||||
* @otg_ver: OTG version supported
|
|
||||||
* 0 - 1.3 (default)
|
|
||||||
* 1 - 2.0
|
|
||||||
* @host_dma: Specifies whether to use slave or DMA mode for accessing
|
* @host_dma: Specifies whether to use slave or DMA mode for accessing
|
||||||
* the data FIFOs. The driver will automatically detect the
|
* the data FIFOs. The driver will automatically detect the
|
||||||
* value for this parameter if none is specified.
|
* value for this parameter if none is specified.
|
||||||
@@ -444,6 +437,11 @@ enum dwc2_ep0_state {
|
|||||||
* in DWORDS with possible values from from
|
* in DWORDS with possible values from from
|
||||||
* 16-32768 (default: 256, 256, 256, 256, 768,
|
* 16-32768 (default: 256, 256, 256, 256, 768,
|
||||||
* 768, 768, 768, 0, 0, 0, 0, 0, 0, 0).
|
* 768, 768, 768, 0, 0, 0, 0, 0, 0, 0).
|
||||||
|
* @change_speed_quirk: Change speed configuration to DWC2_SPEED_PARAM_FULL
|
||||||
|
* while full&low speed device connect. And change speed
|
||||||
|
* back to DWC2_SPEED_PARAM_HIGH while device is gone.
|
||||||
|
* 0 - No (default)
|
||||||
|
* 1 - Yes
|
||||||
*
|
*
|
||||||
* The following parameters may be specified when starting the module. These
|
* The following parameters may be specified when starting the module. These
|
||||||
* parameters define how the DWC_otg controller should be configured. A
|
* parameters define how the DWC_otg controller should be configured. A
|
||||||
@@ -452,63 +450,48 @@ enum dwc2_ep0_state {
|
|||||||
* default described above.
|
* default described above.
|
||||||
*/
|
*/
|
||||||
struct dwc2_core_params {
|
struct dwc2_core_params {
|
||||||
/*
|
u8 otg_cap;
|
||||||
* Don't add any non-int members here, this will break
|
|
||||||
* dwc2_set_all_params!
|
|
||||||
*/
|
|
||||||
int otg_cap;
|
|
||||||
#define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0
|
#define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0
|
||||||
#define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1
|
#define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1
|
||||||
#define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
|
#define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
|
||||||
|
|
||||||
int otg_ver;
|
u8 phy_type;
|
||||||
int dma_desc_enable;
|
|
||||||
int dma_desc_fs_enable;
|
|
||||||
int speed;
|
|
||||||
#define DWC2_SPEED_PARAM_HIGH 0
|
|
||||||
#define DWC2_SPEED_PARAM_FULL 1
|
|
||||||
#define DWC2_SPEED_PARAM_LOW 2
|
|
||||||
|
|
||||||
int enable_dynamic_fifo;
|
|
||||||
int en_multiple_tx_fifo;
|
|
||||||
int host_rx_fifo_size;
|
|
||||||
int host_nperio_tx_fifo_size;
|
|
||||||
int host_perio_tx_fifo_size;
|
|
||||||
int max_transfer_size;
|
|
||||||
int max_packet_count;
|
|
||||||
int host_channels;
|
|
||||||
int phy_type;
|
|
||||||
#define DWC2_PHY_TYPE_PARAM_FS 0
|
#define DWC2_PHY_TYPE_PARAM_FS 0
|
||||||
#define DWC2_PHY_TYPE_PARAM_UTMI 1
|
#define DWC2_PHY_TYPE_PARAM_UTMI 1
|
||||||
#define DWC2_PHY_TYPE_PARAM_ULPI 2
|
#define DWC2_PHY_TYPE_PARAM_ULPI 2
|
||||||
|
|
||||||
int phy_utmi_width;
|
u8 speed;
|
||||||
int phy_ulpi_ddr;
|
#define DWC2_SPEED_PARAM_HIGH 0
|
||||||
int phy_ulpi_ext_vbus;
|
#define DWC2_SPEED_PARAM_FULL 1
|
||||||
#define DWC2_PHY_ULPI_INTERNAL_VBUS 0
|
#define DWC2_SPEED_PARAM_LOW 2
|
||||||
#define DWC2_PHY_ULPI_EXTERNAL_VBUS 1
|
|
||||||
|
|
||||||
int i2c_enable;
|
u8 phy_utmi_width;
|
||||||
int ulpi_fs_ls;
|
bool phy_ulpi_ddr;
|
||||||
int host_support_fs_ls_low_power;
|
bool phy_ulpi_ext_vbus;
|
||||||
int host_ls_low_power_phy_clk;
|
bool enable_dynamic_fifo;
|
||||||
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
|
bool en_multiple_tx_fifo;
|
||||||
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
|
bool i2c_enable;
|
||||||
|
bool ulpi_fs_ls;
|
||||||
int ts_dline;
|
bool ts_dline;
|
||||||
int reload_ctl;
|
bool reload_ctl;
|
||||||
int ahbcfg;
|
bool uframe_sched;
|
||||||
int uframe_sched;
|
bool external_id_pin_ctl;
|
||||||
int external_id_pin_ctl;
|
bool hibernation;
|
||||||
int hibernation;
|
u16 max_packet_count;
|
||||||
|
u32 max_transfer_size;
|
||||||
/*
|
u32 ahbcfg;
|
||||||
* The following parameters are *only* set via device
|
|
||||||
* properties and cannot be set directly in this structure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Host parameters */
|
/* Host parameters */
|
||||||
bool host_dma;
|
bool host_dma;
|
||||||
|
bool dma_desc_enable;
|
||||||
|
bool dma_desc_fs_enable;
|
||||||
|
bool host_support_fs_ls_low_power;
|
||||||
|
bool host_ls_low_power_phy_clk;
|
||||||
|
|
||||||
|
u8 host_channels;
|
||||||
|
u16 host_rx_fifo_size;
|
||||||
|
u16 host_nperio_tx_fifo_size;
|
||||||
|
u16 host_perio_tx_fifo_size;
|
||||||
|
|
||||||
/* Gadget parameters */
|
/* Gadget parameters */
|
||||||
bool g_dma;
|
bool g_dma;
|
||||||
@@ -516,6 +499,8 @@ struct dwc2_core_params {
|
|||||||
u32 g_rx_fifo_size;
|
u32 g_rx_fifo_size;
|
||||||
u32 g_np_tx_fifo_size;
|
u32 g_np_tx_fifo_size;
|
||||||
u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
|
u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
|
||||||
|
|
||||||
|
bool change_speed_quirk;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -603,8 +588,8 @@ struct dwc2_hw_params {
|
|||||||
#define DWC2_CTRL_BUFF_SIZE 8
|
#define DWC2_CTRL_BUFF_SIZE 8
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dwc2_gregs_backup - Holds global registers state before entering partial
|
* struct dwc2_gregs_backup - Holds global registers state before
|
||||||
* power down
|
* entering partial power down
|
||||||
* @gotgctl: Backup of GOTGCTL register
|
* @gotgctl: Backup of GOTGCTL register
|
||||||
* @gintmsk: Backup of GINTMSK register
|
* @gintmsk: Backup of GINTMSK register
|
||||||
* @gahbcfg: Backup of GAHBCFG register
|
* @gahbcfg: Backup of GAHBCFG register
|
||||||
@@ -634,8 +619,8 @@ struct dwc2_gregs_backup {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dwc2_dregs_backup - Holds device registers state before entering partial
|
* struct dwc2_dregs_backup - Holds device registers state before
|
||||||
* power down
|
* entering partial power down
|
||||||
* @dcfg: Backup of DCFG register
|
* @dcfg: Backup of DCFG register
|
||||||
* @dctl: Backup of DCTL register
|
* @dctl: Backup of DCTL register
|
||||||
* @daintmsk: Backup of DAINTMSK register
|
* @daintmsk: Backup of DAINTMSK register
|
||||||
@@ -664,8 +649,8 @@ struct dwc2_dregs_backup {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dwc2_hregs_backup - Holds host registers state before entering partial
|
* struct dwc2_hregs_backup - Holds host registers state before
|
||||||
* power down
|
* entering partial power down
|
||||||
* @hcfg: Backup of HCFG register
|
* @hcfg: Backup of HCFG register
|
||||||
* @haintmsk: Backup of HAINTMSK register
|
* @haintmsk: Backup of HAINTMSK register
|
||||||
* @hcintmsk: Backup of HCINTMSK register
|
* @hcintmsk: Backup of HCINTMSK register
|
||||||
@@ -782,9 +767,10 @@ struct dwc2_hregs_backup {
|
|||||||
* @gadget_enabled Peripheral mode sub-driver initialization indicator.
|
* @gadget_enabled Peripheral mode sub-driver initialization indicator.
|
||||||
* @ll_hw_enabled Status of low-level hardware resources.
|
* @ll_hw_enabled Status of low-level hardware resources.
|
||||||
* @phy: The otg phy transceiver structure for phy control.
|
* @phy: The otg phy transceiver structure for phy control.
|
||||||
* @uphy: The otg phy transceiver structure for old USB phy control.
|
* @uphy: The otg phy transceiver structure for old USB phy
|
||||||
* @plat: The platform specific configuration data. This can be removed once
|
* control.
|
||||||
* all SoCs support usb transceiver.
|
* @plat: The platform specific configuration data. This can be
|
||||||
|
* removed once all SoCs support usb transceiver.
|
||||||
* @supplies: Definition of USB power supplies
|
* @supplies: Definition of USB power supplies
|
||||||
* @phyif: PHY interface width
|
* @phyif: PHY interface width
|
||||||
* @lock: Spinlock that protects all the driver data structures
|
* @lock: Spinlock that protects all the driver data structures
|
||||||
@@ -921,7 +907,7 @@ struct dwc2_hsotg {
|
|||||||
struct phy *phy;
|
struct phy *phy;
|
||||||
struct usb_phy *uphy;
|
struct usb_phy *uphy;
|
||||||
struct dwc2_hsotg_plat *plat;
|
struct dwc2_hsotg_plat *plat;
|
||||||
struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)];
|
struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES];
|
||||||
u32 phyif;
|
u32 phyif;
|
||||||
|
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
@@ -947,6 +933,7 @@ struct dwc2_hsotg {
|
|||||||
/* DWC OTG HW Release versions */
|
/* DWC OTG HW Release versions */
|
||||||
#define DWC2_CORE_REV_2_71a 0x4f54271a
|
#define DWC2_CORE_REV_2_71a 0x4f54271a
|
||||||
#define DWC2_CORE_REV_2_90a 0x4f54290a
|
#define DWC2_CORE_REV_2_90a 0x4f54290a
|
||||||
|
#define DWC2_CORE_REV_2_91a 0x4f54291a
|
||||||
#define DWC2_CORE_REV_2_92a 0x4f54292a
|
#define DWC2_CORE_REV_2_92a 0x4f54292a
|
||||||
#define DWC2_CORE_REV_2_94a 0x4f54294a
|
#define DWC2_CORE_REV_2_94a 0x4f54294a
|
||||||
#define DWC2_CORE_REV_3_00a 0x4f54300a
|
#define DWC2_CORE_REV_3_00a 0x4f54300a
|
||||||
@@ -1033,7 +1020,8 @@ struct dwc2_hsotg {
|
|||||||
#endif
|
#endif
|
||||||
#endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */
|
#endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
|
||||||
|
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||||
/* Gadget structures */
|
/* Gadget structures */
|
||||||
struct usb_gadget_driver *driver;
|
struct usb_gadget_driver *driver;
|
||||||
int fifo_mem;
|
int fifo_mem;
|
||||||
@@ -1101,37 +1089,37 @@ static inline bool dwc2_is_hs_iot(struct dwc2_hsotg *hsotg)
|
|||||||
* The following functions support initialization of the core driver component
|
* The following functions support initialization of the core driver component
|
||||||
* and the DWC_otg controller
|
* and the DWC_otg controller
|
||||||
*/
|
*/
|
||||||
extern int dwc2_core_reset(struct dwc2_hsotg *hsotg);
|
int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait);
|
||||||
extern int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg);
|
int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg);
|
||||||
extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg);
|
int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg);
|
||||||
extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore);
|
int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore);
|
||||||
|
|
||||||
bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host);
|
bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host);
|
||||||
void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg);
|
void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg);
|
||||||
void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg);
|
void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
extern bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg);
|
bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common core Functions.
|
* Common core Functions.
|
||||||
* The following functions support managing the DWC_otg controller in either
|
* The following functions support managing the DWC_otg controller in either
|
||||||
* device or host mode.
|
* device or host mode.
|
||||||
*/
|
*/
|
||||||
extern void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes);
|
void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes);
|
||||||
extern void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num);
|
void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num);
|
||||||
extern void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg);
|
void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
extern void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd);
|
void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd);
|
||||||
extern void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd);
|
void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd);
|
||||||
|
|
||||||
/* This function should be called on every hardware interrupt. */
|
/* This function should be called on every hardware interrupt. */
|
||||||
extern irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
|
irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
|
||||||
|
|
||||||
/* The device ID match table */
|
/* The device ID match table */
|
||||||
extern const struct of_device_id dwc2_of_match_table[];
|
extern const struct of_device_id dwc2_of_match_table[];
|
||||||
|
|
||||||
extern int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg);
|
int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg);
|
||||||
extern int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg);
|
int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/* Parameters */
|
/* Parameters */
|
||||||
int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
|
int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
|
||||||
@@ -1145,7 +1133,7 @@ int dwc2_init_params(struct dwc2_hsotg *hsotg);
|
|||||||
* are read in and cached so they always read directly from the
|
* are read in and cached so they always read directly from the
|
||||||
* GHWCFG2 register.
|
* GHWCFG2 register.
|
||||||
*/
|
*/
|
||||||
unsigned dwc2_op_mode(struct dwc2_hsotg *hsotg);
|
unsigned int dwc2_op_mode(struct dwc2_hsotg *hsotg);
|
||||||
bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg);
|
bool dwc2_hw_is_otg(struct dwc2_hsotg *hsotg);
|
||||||
bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg);
|
bool dwc2_hw_is_host(struct dwc2_hsotg *hsotg);
|
||||||
bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg);
|
bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg);
|
||||||
@@ -1157,6 +1145,7 @@ static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg)
|
|||||||
{
|
{
|
||||||
return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
|
return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
|
static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
|
return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
|
||||||
@@ -1165,29 +1154,28 @@ static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
|
|||||||
/*
|
/*
|
||||||
* Dump core registers and SPRAM
|
* Dump core registers and SPRAM
|
||||||
*/
|
*/
|
||||||
extern void dwc2_dump_dev_registers(struct dwc2_hsotg *hsotg);
|
void dwc2_dump_dev_registers(struct dwc2_hsotg *hsotg);
|
||||||
extern void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg);
|
void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg);
|
||||||
extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg);
|
void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/*
|
|
||||||
* Return OTG version - either 1.3 or 2.0
|
|
||||||
*/
|
|
||||||
extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg);
|
|
||||||
|
|
||||||
/* Gadget defines */
|
/* Gadget defines */
|
||||||
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
|
||||||
extern int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg);
|
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||||
extern int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2);
|
int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg);
|
||||||
extern int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2);
|
int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2);
|
||||||
extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
|
int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2);
|
||||||
extern void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
|
int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
|
||||||
bool reset);
|
void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
|
||||||
extern void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg);
|
bool reset);
|
||||||
extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2);
|
void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg);
|
||||||
extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
|
void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2);
|
||||||
|
int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
|
||||||
#define dwc2_is_device_connected(hsotg) (hsotg->connected)
|
#define dwc2_is_device_connected(hsotg) (hsotg->connected)
|
||||||
int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
|
int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
|
||||||
int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg);
|
int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg);
|
||||||
|
int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
|
||||||
|
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
|
||||||
|
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
|
||||||
#else
|
#else
|
||||||
static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
|
static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
@@ -1198,25 +1186,31 @@ static inline int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2)
|
|||||||
static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
|
static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
static inline void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
|
static inline void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
|
||||||
bool reset) {}
|
bool reset) {}
|
||||||
static inline void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg) {}
|
static inline void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg) {}
|
||||||
static inline void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2) {}
|
static inline void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2) {}
|
||||||
static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
|
static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
|
||||||
int testmode)
|
int testmode)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
#define dwc2_is_device_connected(hsotg) (0)
|
#define dwc2_is_device_connected(hsotg) (0)
|
||||||
static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
|
static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
|
static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
|
||||||
|
{ return 0; }
|
||||||
|
static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
|
||||||
|
{ return 0; }
|
||||||
|
static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
|
||||||
|
{ return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||||
extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg);
|
int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg);
|
||||||
extern int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us);
|
int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us);
|
||||||
extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg);
|
void dwc2_hcd_connect(struct dwc2_hsotg *hsotg);
|
||||||
extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force);
|
void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force);
|
||||||
extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
|
void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
|
||||||
int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg);
|
int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg);
|
||||||
int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg);
|
int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg);
|
||||||
#else
|
#else
|
||||||
@@ -1229,7 +1223,7 @@ static inline void dwc2_hcd_connect(struct dwc2_hsotg *hsotg) {}
|
|||||||
static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {}
|
static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {}
|
||||||
static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {}
|
static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {}
|
||||||
static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {}
|
static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {}
|
||||||
static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
|
static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|||||||
@@ -159,9 +159,8 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
|
|||||||
" ++OTG Interrupt: Session Request Success Status Change++\n");
|
" ++OTG Interrupt: Session Request Success Status Change++\n");
|
||||||
gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
|
gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
|
||||||
if (gotgctl & GOTGCTL_SESREQSCS) {
|
if (gotgctl & GOTGCTL_SESREQSCS) {
|
||||||
if (hsotg->params.phy_type ==
|
if (hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS &&
|
||||||
DWC2_PHY_TYPE_PARAM_FS
|
hsotg->params.i2c_enable) {
|
||||||
&& hsotg->params.i2c_enable > 0) {
|
|
||||||
hsotg->srp_success = 1;
|
hsotg->srp_success = 1;
|
||||||
} else {
|
} else {
|
||||||
/* Clear Session Request */
|
/* Clear Session Request */
|
||||||
@@ -317,7 +316,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
|
|||||||
dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS);
|
dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS);
|
||||||
|
|
||||||
dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n",
|
dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n",
|
||||||
hsotg->lx_state);
|
hsotg->lx_state);
|
||||||
|
|
||||||
if (dwc2_is_device_mode(hsotg)) {
|
if (dwc2_is_device_mode(hsotg)) {
|
||||||
if (hsotg->lx_state == DWC2_L2) {
|
if (hsotg->lx_state == DWC2_L2) {
|
||||||
@@ -437,7 +436,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
|
|||||||
/* Ignore suspend request before enumeration */
|
/* Ignore suspend request before enumeration */
|
||||||
if (!dwc2_is_device_connected(hsotg)) {
|
if (!dwc2_is_device_connected(hsotg)) {
|
||||||
dev_dbg(hsotg->dev,
|
dev_dbg(hsotg->dev,
|
||||||
"ignore suspend request before enumeration\n");
|
"ignore suspend request before enumeration\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +444,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret != -ENOTSUPP)
|
if (ret != -ENOTSUPP)
|
||||||
dev_err(hsotg->dev,
|
dev_err(hsotg->dev,
|
||||||
"enter hibernation failed\n");
|
"enter hibernation failed\n");
|
||||||
goto skip_power_saving;
|
goto skip_power_saving;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
extern int dwc2_debugfs_init(struct dwc2_hsotg *);
|
int dwc2_debugfs_init(struct dwc2_hsotg *hsotg);
|
||||||
extern void dwc2_debugfs_exit(struct dwc2_hsotg *);
|
void dwc2_debugfs_exit(struct dwc2_hsotg *hsotg);
|
||||||
#else
|
#else
|
||||||
static inline int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
|
static inline int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|||||||
+169
-13
@@ -137,7 +137,7 @@ static int state_show(struct seq_file *seq, void *v)
|
|||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n",
|
seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n",
|
||||||
dwc2_readl(regs + DCFG),
|
dwc2_readl(regs + DCFG),
|
||||||
dwc2_readl(regs + DCTL),
|
dwc2_readl(regs + DCTL),
|
||||||
dwc2_readl(regs + DSTS));
|
dwc2_readl(regs + DSTS));
|
||||||
|
|
||||||
@@ -338,23 +338,23 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
|
|||||||
{
|
{
|
||||||
struct dentry *root;
|
struct dentry *root;
|
||||||
struct dentry *file;
|
struct dentry *file;
|
||||||
unsigned epidx;
|
unsigned int epidx;
|
||||||
|
|
||||||
root = hsotg->debug_root;
|
root = hsotg->debug_root;
|
||||||
|
|
||||||
/* create general state file */
|
/* create general state file */
|
||||||
|
|
||||||
file = debugfs_create_file("state", S_IRUGO, root, hsotg, &state_fops);
|
file = debugfs_create_file("state", 0444, root, hsotg, &state_fops);
|
||||||
if (IS_ERR(file))
|
if (IS_ERR(file))
|
||||||
dev_err(hsotg->dev, "%s: failed to create state\n", __func__);
|
dev_err(hsotg->dev, "%s: failed to create state\n", __func__);
|
||||||
|
|
||||||
file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, hsotg,
|
file = debugfs_create_file("testmode", 0644, root, hsotg,
|
||||||
&testmode_fops);
|
&testmode_fops);
|
||||||
if (IS_ERR(file))
|
if (IS_ERR(file))
|
||||||
dev_err(hsotg->dev, "%s: failed to create testmode\n",
|
dev_err(hsotg->dev, "%s: failed to create testmode\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
|
||||||
file = debugfs_create_file("fifo", S_IRUGO, root, hsotg, &fifo_fops);
|
file = debugfs_create_file("fifo", 0444, root, hsotg, &fifo_fops);
|
||||||
if (IS_ERR(file))
|
if (IS_ERR(file))
|
||||||
dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__);
|
dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__);
|
||||||
|
|
||||||
@@ -364,8 +364,8 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
|
|||||||
|
|
||||||
ep = hsotg->eps_out[epidx];
|
ep = hsotg->eps_out[epidx];
|
||||||
if (ep) {
|
if (ep) {
|
||||||
file = debugfs_create_file(ep->name, S_IRUGO,
|
file = debugfs_create_file(ep->name, 0444,
|
||||||
root, ep, &ep_fops);
|
root, ep, &ep_fops);
|
||||||
if (IS_ERR(file))
|
if (IS_ERR(file))
|
||||||
dev_err(hsotg->dev, "failed to create %s debug file\n",
|
dev_err(hsotg->dev, "failed to create %s debug file\n",
|
||||||
ep->name);
|
ep->name);
|
||||||
@@ -377,8 +377,8 @@ static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
|
|||||||
|
|
||||||
ep = hsotg->eps_in[epidx];
|
ep = hsotg->eps_in[epidx];
|
||||||
if (ep) {
|
if (ep) {
|
||||||
file = debugfs_create_file(ep->name, S_IRUGO,
|
file = debugfs_create_file(ep->name, 0444,
|
||||||
root, ep, &ep_fops);
|
root, ep, &ep_fops);
|
||||||
if (IS_ERR(file))
|
if (IS_ERR(file))
|
||||||
dev_err(hsotg->dev, "failed to create %s debug file\n",
|
dev_err(hsotg->dev, "failed to create %s debug file\n",
|
||||||
ep->name);
|
ep->name);
|
||||||
@@ -725,6 +725,143 @@ static const struct debugfs_reg32 dwc2_regs[] = {
|
|||||||
dump_register(HCDMAB(15)),
|
dump_register(HCDMAB(15)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define print_param(_seq, _ptr, _param) \
|
||||||
|
seq_printf((_seq), "%-30s: %d\n", #_param, (_ptr)->_param)
|
||||||
|
|
||||||
|
#define print_param_hex(_seq, _ptr, _param) \
|
||||||
|
seq_printf((_seq), "%-30s: 0x%x\n", #_param, (_ptr)->_param)
|
||||||
|
|
||||||
|
static int params_show(struct seq_file *seq, void *v)
|
||||||
|
{
|
||||||
|
struct dwc2_hsotg *hsotg = seq->private;
|
||||||
|
struct dwc2_core_params *p = &hsotg->params;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
print_param(seq, p, otg_cap);
|
||||||
|
print_param(seq, p, dma_desc_enable);
|
||||||
|
print_param(seq, p, dma_desc_fs_enable);
|
||||||
|
print_param(seq, p, speed);
|
||||||
|
print_param(seq, p, enable_dynamic_fifo);
|
||||||
|
print_param(seq, p, en_multiple_tx_fifo);
|
||||||
|
print_param(seq, p, host_rx_fifo_size);
|
||||||
|
print_param(seq, p, host_nperio_tx_fifo_size);
|
||||||
|
print_param(seq, p, host_perio_tx_fifo_size);
|
||||||
|
print_param(seq, p, max_transfer_size);
|
||||||
|
print_param(seq, p, max_packet_count);
|
||||||
|
print_param(seq, p, host_channels);
|
||||||
|
print_param(seq, p, phy_type);
|
||||||
|
print_param(seq, p, phy_utmi_width);
|
||||||
|
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, ulpi_fs_ls);
|
||||||
|
print_param(seq, p, host_support_fs_ls_low_power);
|
||||||
|
print_param(seq, p, host_ls_low_power_phy_clk);
|
||||||
|
print_param(seq, p, ts_dline);
|
||||||
|
print_param(seq, p, reload_ctl);
|
||||||
|
print_param_hex(seq, p, ahbcfg);
|
||||||
|
print_param(seq, p, uframe_sched);
|
||||||
|
print_param(seq, p, external_id_pin_ctl);
|
||||||
|
print_param(seq, p, hibernation);
|
||||||
|
print_param(seq, p, host_dma);
|
||||||
|
print_param(seq, p, g_dma);
|
||||||
|
print_param(seq, p, g_dma_desc);
|
||||||
|
print_param(seq, p, g_rx_fifo_size);
|
||||||
|
print_param(seq, p, g_np_tx_fifo_size);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_EPS_CHANNELS; i++) {
|
||||||
|
char str[32];
|
||||||
|
|
||||||
|
snprintf(str, 32, "g_tx_fifo_size[%d]", i);
|
||||||
|
seq_printf(seq, "%-30s: %d\n", str, p->g_tx_fifo_size[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int params_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, params_show, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations params_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = params_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int hw_params_show(struct seq_file *seq, void *v)
|
||||||
|
{
|
||||||
|
struct dwc2_hsotg *hsotg = seq->private;
|
||||||
|
struct dwc2_hw_params *hw = &hsotg->hw_params;
|
||||||
|
|
||||||
|
print_param(seq, hw, op_mode);
|
||||||
|
print_param(seq, hw, arch);
|
||||||
|
print_param(seq, hw, dma_desc_enable);
|
||||||
|
print_param(seq, hw, enable_dynamic_fifo);
|
||||||
|
print_param(seq, hw, en_multiple_tx_fifo);
|
||||||
|
print_param(seq, hw, rx_fifo_size);
|
||||||
|
print_param(seq, hw, host_nperio_tx_fifo_size);
|
||||||
|
print_param(seq, hw, dev_nperio_tx_fifo_size);
|
||||||
|
print_param(seq, hw, host_perio_tx_fifo_size);
|
||||||
|
print_param(seq, hw, nperio_tx_q_depth);
|
||||||
|
print_param(seq, hw, host_perio_tx_q_depth);
|
||||||
|
print_param(seq, hw, dev_token_q_depth);
|
||||||
|
print_param(seq, hw, max_transfer_size);
|
||||||
|
print_param(seq, hw, max_packet_count);
|
||||||
|
print_param(seq, hw, host_channels);
|
||||||
|
print_param(seq, hw, hs_phy_type);
|
||||||
|
print_param(seq, hw, fs_phy_type);
|
||||||
|
print_param(seq, hw, i2c_enable);
|
||||||
|
print_param(seq, hw, num_dev_ep);
|
||||||
|
print_param(seq, hw, num_dev_perio_in_ep);
|
||||||
|
print_param(seq, hw, total_fifo_size);
|
||||||
|
print_param(seq, hw, power_optimized);
|
||||||
|
print_param(seq, hw, utmi_phy_data_width);
|
||||||
|
print_param_hex(seq, hw, snpsid);
|
||||||
|
print_param_hex(seq, hw, dev_ep_dirs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hw_params_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, hw_params_show, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations hw_params_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = hw_params_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int dr_mode_show(struct seq_file *seq, void *v)
|
||||||
|
{
|
||||||
|
struct dwc2_hsotg *hsotg = seq->private;
|
||||||
|
const char *dr_mode = "";
|
||||||
|
|
||||||
|
device_property_read_string(hsotg->dev, "dr_mode", &dr_mode);
|
||||||
|
seq_printf(seq, "%s\n", dr_mode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dr_mode_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, dr_mode_show, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations dr_mode_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = dr_mode_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
|
int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -736,6 +873,25 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
|
|||||||
goto err0;
|
goto err0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file = debugfs_create_file("params", 0444,
|
||||||
|
hsotg->debug_root,
|
||||||
|
hsotg, ¶ms_fops);
|
||||||
|
if (IS_ERR(file))
|
||||||
|
dev_err(hsotg->dev, "%s: failed to create params\n", __func__);
|
||||||
|
|
||||||
|
file = debugfs_create_file("hw_params", 0444,
|
||||||
|
hsotg->debug_root,
|
||||||
|
hsotg, &hw_params_fops);
|
||||||
|
if (IS_ERR(file))
|
||||||
|
dev_err(hsotg->dev, "%s: failed to create hw_params\n",
|
||||||
|
__func__);
|
||||||
|
|
||||||
|
file = debugfs_create_file("dr_mode", 0444,
|
||||||
|
hsotg->debug_root,
|
||||||
|
hsotg, &dr_mode_fops);
|
||||||
|
if (IS_ERR(file))
|
||||||
|
dev_err(hsotg->dev, "%s: failed to create dr_mode\n", __func__);
|
||||||
|
|
||||||
/* Add gadget debugfs nodes */
|
/* Add gadget debugfs nodes */
|
||||||
dwc2_hsotg_create_debug(hsotg);
|
dwc2_hsotg_create_debug(hsotg);
|
||||||
|
|
||||||
@@ -750,8 +906,8 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
|
|||||||
hsotg->regset->nregs = ARRAY_SIZE(dwc2_regs);
|
hsotg->regset->nregs = ARRAY_SIZE(dwc2_regs);
|
||||||
hsotg->regset->base = hsotg->regs;
|
hsotg->regset->base = hsotg->regs;
|
||||||
|
|
||||||
file = debugfs_create_regset32("regdump", S_IRUGO, hsotg->debug_root,
|
file = debugfs_create_regset32("regdump", 0444, hsotg->debug_root,
|
||||||
hsotg->regset);
|
hsotg->regset);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|||||||
+206
-107
File diff suppressed because it is too large
Load Diff
+171
-92
File diff suppressed because it is too large
Load Diff
+37
-37
@@ -521,29 +521,29 @@ static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe)
|
|||||||
return !dwc2_hcd_is_pipe_in(pipe);
|
return !dwc2_hcd_is_pipe_in(pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq);
|
int dwc2_hcd_init(struct dwc2_hsotg *hsotg);
|
||||||
extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg);
|
void dwc2_hcd_remove(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/* Transaction Execution Functions */
|
/* Transaction Execution Functions */
|
||||||
extern enum dwc2_transaction_type dwc2_hcd_select_transactions(
|
enum dwc2_transaction_type dwc2_hcd_select_transactions(
|
||||||
struct dwc2_hsotg *hsotg);
|
struct dwc2_hsotg *hsotg);
|
||||||
extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
|
void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
|
||||||
enum dwc2_transaction_type tr_type);
|
enum dwc2_transaction_type tr_type);
|
||||||
|
|
||||||
/* Schedule Queue Functions */
|
/* Schedule Queue Functions */
|
||||||
/* Implemented in hcd_queue.c */
|
/* Implemented in hcd_queue.c */
|
||||||
extern struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_hcd_urb *urb,
|
struct dwc2_hcd_urb *urb,
|
||||||
gfp_t mem_flags);
|
gfp_t mem_flags);
|
||||||
extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
||||||
extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
||||||
extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
||||||
extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
||||||
int sched_csplit);
|
int sched_csplit);
|
||||||
|
|
||||||
extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb);
|
void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb);
|
||||||
extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
|
int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
|
||||||
struct dwc2_qh *qh);
|
struct dwc2_qh *qh);
|
||||||
|
|
||||||
/* Unlinks and frees a QTD */
|
/* Unlinks and frees a QTD */
|
||||||
static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
|
static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
|
||||||
@@ -556,15 +556,15 @@ static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Descriptor DMA support functions */
|
/* Descriptor DMA support functions */
|
||||||
extern void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg,
|
void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_qh *qh);
|
struct dwc2_qh *qh);
|
||||||
extern void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
|
void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_host_chan *chan, int chnum,
|
struct dwc2_host_chan *chan, int chnum,
|
||||||
enum dwc2_halt_status halt_status);
|
enum dwc2_halt_status halt_status);
|
||||||
|
|
||||||
extern int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
||||||
gfp_t mem_flags);
|
gfp_t mem_flags);
|
||||||
extern void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
|
||||||
|
|
||||||
/* Check if QH is non-periodic */
|
/* Check if QH is non-periodic */
|
||||||
#define dwc2_qh_is_non_per(_qh_ptr_) \
|
#define dwc2_qh_is_non_per(_qh_ptr_) \
|
||||||
@@ -732,8 +732,8 @@ static inline u16 dwc2_hcd_get_ep_bandwidth(struct dwc2_hsotg *hsotg,
|
|||||||
return qh->host_us;
|
return qh->host_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
|
void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_host_chan *chan, int chnum,
|
struct dwc2_host_chan *chan, int chnum,
|
||||||
struct dwc2_qtd *qtd);
|
struct dwc2_qtd *qtd);
|
||||||
|
|
||||||
/* HCD Core API */
|
/* HCD Core API */
|
||||||
@@ -746,14 +746,14 @@ extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
|
|||||||
* Returns IRQ_HANDLED if interrupt is handled
|
* Returns IRQ_HANDLED if interrupt is handled
|
||||||
* Return IRQ_NONE if interrupt is not handled
|
* Return IRQ_NONE if interrupt is not handled
|
||||||
*/
|
*/
|
||||||
extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg);
|
irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc2_hcd_stop() - Halts the DWC_otg host mode operation
|
* dwc2_hcd_stop() - Halts the DWC_otg host mode operation
|
||||||
*
|
*
|
||||||
* @hsotg: The DWC2 HCD
|
* @hsotg: The DWC2 HCD
|
||||||
*/
|
*/
|
||||||
extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
|
void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host,
|
* dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host,
|
||||||
@@ -761,7 +761,7 @@ extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
|
|||||||
*
|
*
|
||||||
* @hsotg: The DWC2 HCD
|
* @hsotg: The DWC2 HCD
|
||||||
*/
|
*/
|
||||||
extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
|
int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc2_hcd_dump_state() - Dumps hsotg state
|
* dwc2_hcd_dump_state() - Dumps hsotg state
|
||||||
@@ -771,7 +771,7 @@ extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
|
|||||||
* NOTE: This function will be removed once the peripheral controller code
|
* NOTE: This function will be removed once the peripheral controller code
|
||||||
* is integrated and the driver is stable
|
* is integrated and the driver is stable
|
||||||
*/
|
*/
|
||||||
extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg);
|
void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc2_hcd_dump_frrem() - Dumps the average frame remaining at SOF
|
* dwc2_hcd_dump_frrem() - Dumps the average frame remaining at SOF
|
||||||
@@ -784,7 +784,7 @@ extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg);
|
|||||||
* NOTE: This function will be removed once the peripheral controller code
|
* NOTE: This function will be removed once the peripheral controller code
|
||||||
* is integrated and the driver is stable
|
* is integrated and the driver is stable
|
||||||
*/
|
*/
|
||||||
extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
|
void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
|
||||||
|
|
||||||
/* URB interface */
|
/* URB interface */
|
||||||
|
|
||||||
@@ -793,15 +793,15 @@ extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
|
|||||||
#define URB_SEND_ZERO_PACKET 0x2
|
#define URB_SEND_ZERO_PACKET 0x2
|
||||||
|
|
||||||
/* Host driver callbacks */
|
/* Host driver callbacks */
|
||||||
extern struct dwc2_tt *dwc2_host_get_tt_info(struct dwc2_hsotg *hsotg,
|
struct dwc2_tt *dwc2_host_get_tt_info(struct dwc2_hsotg *hsotg,
|
||||||
void *context, gfp_t mem_flags,
|
void *context, gfp_t mem_flags,
|
||||||
int *ttport);
|
int *ttport);
|
||||||
|
|
||||||
extern void dwc2_host_put_tt_info(struct dwc2_hsotg *hsotg,
|
void dwc2_host_put_tt_info(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_tt *dwc_tt);
|
struct dwc2_tt *dwc_tt);
|
||||||
extern int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context);
|
int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context);
|
||||||
extern void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
|
void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
|
||||||
int status);
|
int status);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/*
|
/*
|
||||||
|
|||||||
+11
-12
@@ -89,8 +89,8 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
|||||||
{
|
{
|
||||||
struct kmem_cache *desc_cache;
|
struct kmem_cache *desc_cache;
|
||||||
|
|
||||||
if (qh->ep_type == USB_ENDPOINT_XFER_ISOC
|
if (qh->ep_type == USB_ENDPOINT_XFER_ISOC &&
|
||||||
&& qh->dev_speed == USB_SPEED_HIGH)
|
qh->dev_speed == USB_SPEED_HIGH)
|
||||||
desc_cache = hsotg->desc_hsisoc_cache;
|
desc_cache = hsotg->desc_hsisoc_cache;
|
||||||
else
|
else
|
||||||
desc_cache = hsotg->desc_gen_cache;
|
desc_cache = hsotg->desc_gen_cache;
|
||||||
@@ -106,7 +106,7 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
|||||||
qh->desc_list_sz,
|
qh->desc_list_sz,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
qh->n_bytes = kzalloc(sizeof(u32) * dwc2_max_desc_num(qh), flags);
|
qh->n_bytes = kcalloc(dwc2_max_desc_num(qh), sizeof(u32), flags);
|
||||||
if (!qh->n_bytes) {
|
if (!qh->n_bytes) {
|
||||||
dma_unmap_single(hsotg->dev, qh->desc_list_dma,
|
dma_unmap_single(hsotg->dev, qh->desc_list_dma,
|
||||||
qh->desc_list_sz,
|
qh->desc_list_sz,
|
||||||
@@ -123,8 +123,8 @@ static void dwc2_desc_list_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
{
|
{
|
||||||
struct kmem_cache *desc_cache;
|
struct kmem_cache *desc_cache;
|
||||||
|
|
||||||
if (qh->ep_type == USB_ENDPOINT_XFER_ISOC
|
if (qh->ep_type == USB_ENDPOINT_XFER_ISOC &&
|
||||||
&& qh->dev_speed == USB_SPEED_HIGH)
|
qh->dev_speed == USB_SPEED_HIGH)
|
||||||
desc_cache = hsotg->desc_hsisoc_cache;
|
desc_cache = hsotg->desc_hsisoc_cache;
|
||||||
else
|
else
|
||||||
desc_cache = hsotg->desc_gen_cache;
|
desc_cache = hsotg->desc_gen_cache;
|
||||||
@@ -175,7 +175,6 @@ static void dwc2_frame_list_free(struct dwc2_hsotg *hsotg)
|
|||||||
hsotg->frame_list = NULL;
|
hsotg->frame_list = NULL;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&hsotg->lock, flags);
|
spin_unlock_irqrestore(&hsotg->lock, flags);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en)
|
static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en)
|
||||||
@@ -297,7 +296,7 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg,
|
|||||||
struct dwc2_host_chan *chan = qh->channel;
|
struct dwc2_host_chan *chan = qh->channel;
|
||||||
|
|
||||||
if (dwc2_qh_is_non_per(qh)) {
|
if (dwc2_qh_is_non_per(qh)) {
|
||||||
if (hsotg->params.uframe_sched > 0)
|
if (hsotg->params.uframe_sched)
|
||||||
hsotg->available_host_channels++;
|
hsotg->available_host_channels++;
|
||||||
else
|
else
|
||||||
hsotg->non_periodic_channels--;
|
hsotg->non_periodic_channels--;
|
||||||
@@ -404,7 +403,7 @@ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
|
|
||||||
if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC ||
|
if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC ||
|
||||||
qh->ep_type == USB_ENDPOINT_XFER_INT) &&
|
qh->ep_type == USB_ENDPOINT_XFER_INT) &&
|
||||||
(hsotg->params.uframe_sched > 0 ||
|
(hsotg->params.uframe_sched ||
|
||||||
!hsotg->periodic_channels) && hsotg->frame_list) {
|
!hsotg->periodic_channels) && hsotg->frame_list) {
|
||||||
dwc2_per_sched_disable(hsotg);
|
dwc2_per_sched_disable(hsotg);
|
||||||
dwc2_frame_list_free(hsotg);
|
dwc2_frame_list_free(hsotg);
|
||||||
@@ -570,7 +569,7 @@ static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
dma_sync_single_for_device(hsotg->dev,
|
dma_sync_single_for_device(hsotg->dev,
|
||||||
qh->desc_list_dma +
|
qh->desc_list_dma +
|
||||||
(idx * sizeof(struct dwc2_dma_desc)),
|
(idx * sizeof(struct dwc2_dma_desc)),
|
||||||
sizeof(struct dwc2_dma_desc),
|
sizeof(struct dwc2_dma_desc),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
@@ -776,7 +775,7 @@ static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
|||||||
n_desc - 1,
|
n_desc - 1,
|
||||||
&qh->desc_list[n_desc - 1]);
|
&qh->desc_list[n_desc - 1]);
|
||||||
dma_sync_single_for_device(hsotg->dev,
|
dma_sync_single_for_device(hsotg->dev,
|
||||||
qh->desc_list_dma +
|
qh->desc_list_dma +
|
||||||
((n_desc - 1) *
|
((n_desc - 1) *
|
||||||
sizeof(struct dwc2_dma_desc)),
|
sizeof(struct dwc2_dma_desc)),
|
||||||
sizeof(struct dwc2_dma_desc),
|
sizeof(struct dwc2_dma_desc),
|
||||||
@@ -816,7 +815,7 @@ static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
|||||||
dev_vdbg(hsotg->dev, "set A bit in desc 0 (%p)\n",
|
dev_vdbg(hsotg->dev, "set A bit in desc 0 (%p)\n",
|
||||||
&qh->desc_list[0]);
|
&qh->desc_list[0]);
|
||||||
dma_sync_single_for_device(hsotg->dev,
|
dma_sync_single_for_device(hsotg->dev,
|
||||||
qh->desc_list_dma,
|
qh->desc_list_dma,
|
||||||
sizeof(struct dwc2_dma_desc),
|
sizeof(struct dwc2_dma_desc),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
}
|
}
|
||||||
@@ -1064,7 +1063,7 @@ stop_scan:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int dwc2_update_non_isoc_urb_state_ddma(struct dwc2_hsotg *hsotg,
|
static int dwc2_update_non_isoc_urb_state_ddma(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_host_chan *chan,
|
struct dwc2_host_chan *chan,
|
||||||
struct dwc2_qtd *qtd,
|
struct dwc2_qtd *qtd,
|
||||||
struct dwc2_dma_desc *dma_desc,
|
struct dwc2_dma_desc *dma_desc,
|
||||||
enum dwc2_halt_status halt_status,
|
enum dwc2_halt_status halt_status,
|
||||||
|
|||||||
+51
-47
@@ -60,7 +60,7 @@ static void dwc2_track_missed_sofs(struct dwc2_hsotg *hsotg)
|
|||||||
|
|
||||||
if (expected != curr_frame_number)
|
if (expected != curr_frame_number)
|
||||||
dwc2_sch_vdbg(hsotg, "MISSED SOF %04x != %04x\n",
|
dwc2_sch_vdbg(hsotg, "MISSED SOF %04x != %04x\n",
|
||||||
expected, curr_frame_number);
|
expected, curr_frame_number);
|
||||||
|
|
||||||
#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
|
#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
|
||||||
if (hsotg->frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
|
if (hsotg->frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
|
||||||
@@ -163,7 +163,7 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg)
|
|||||||
* (micro)frame
|
* (micro)frame
|
||||||
*/
|
*/
|
||||||
list_move_tail(&qh->qh_list_entry,
|
list_move_tail(&qh->qh_list_entry,
|
||||||
&hsotg->periodic_sched_ready);
|
&hsotg->periodic_sched_ready);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr_type = dwc2_hcd_select_transactions(hsotg);
|
tr_type = dwc2_hcd_select_transactions(hsotg);
|
||||||
@@ -297,8 +297,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
|
|||||||
HCFG_FSLSPCLKSEL_SHIFT;
|
HCFG_FSLSPCLKSEL_SHIFT;
|
||||||
|
|
||||||
if (prtspd == HPRT0_SPD_LOW_SPEED &&
|
if (prtspd == HPRT0_SPD_LOW_SPEED &&
|
||||||
params->host_ls_low_power_phy_clk ==
|
params->host_ls_low_power_phy_clk) {
|
||||||
DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ) {
|
|
||||||
/* 6 MHZ */
|
/* 6 MHZ */
|
||||||
dev_vdbg(hsotg->dev,
|
dev_vdbg(hsotg->dev,
|
||||||
"FS_PHY programming HCFG to 6 MHz\n");
|
"FS_PHY programming HCFG to 6 MHz\n");
|
||||||
@@ -398,7 +397,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
|
|||||||
if (hsotg->params.dma_desc_fs_enable) {
|
if (hsotg->params.dma_desc_fs_enable) {
|
||||||
u32 hcfg;
|
u32 hcfg;
|
||||||
|
|
||||||
hsotg->params.dma_desc_enable = 0;
|
hsotg->params.dma_desc_enable = false;
|
||||||
hsotg->new_connection = false;
|
hsotg->new_connection = false;
|
||||||
hcfg = dwc2_readl(hsotg->regs + HCFG);
|
hcfg = dwc2_readl(hsotg->regs + HCFG);
|
||||||
hcfg &= ~HCFG_DESCDMA;
|
hcfg &= ~HCFG_DESCDMA;
|
||||||
@@ -442,7 +441,7 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg,
|
|||||||
count = (hctsiz & TSIZ_XFERSIZE_MASK) >>
|
count = (hctsiz & TSIZ_XFERSIZE_MASK) >>
|
||||||
TSIZ_XFERSIZE_SHIFT;
|
TSIZ_XFERSIZE_SHIFT;
|
||||||
length = chan->xfer_len - count;
|
length = chan->xfer_len - count;
|
||||||
if (short_read != NULL)
|
if (short_read)
|
||||||
*short_read = (count != 0);
|
*short_read = (count != 0);
|
||||||
} else if (chan->qh->do_split) {
|
} else if (chan->qh->do_split) {
|
||||||
length = qtd->ssplit_out_xfer_count;
|
length = qtd->ssplit_out_xfer_count;
|
||||||
@@ -604,7 +603,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
|
|||||||
/* Skip whole frame */
|
/* Skip whole frame */
|
||||||
if (chan->qh->do_split &&
|
if (chan->qh->do_split &&
|
||||||
chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
|
chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
|
||||||
hsotg->params.host_dma > 0) {
|
hsotg->params.host_dma) {
|
||||||
qtd->complete_split = 0;
|
qtd->complete_split = 0;
|
||||||
qtd->isoc_split_offset = 0;
|
qtd->isoc_split_offset = 0;
|
||||||
}
|
}
|
||||||
@@ -743,7 +742,7 @@ cleanup:
|
|||||||
dwc2_hc_cleanup(hsotg, chan);
|
dwc2_hc_cleanup(hsotg, chan);
|
||||||
list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
|
list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
|
||||||
|
|
||||||
if (hsotg->params.uframe_sched > 0) {
|
if (hsotg->params.uframe_sched) {
|
||||||
hsotg->available_host_channels++;
|
hsotg->available_host_channels++;
|
||||||
} else {
|
} else {
|
||||||
switch (chan->ep_type) {
|
switch (chan->ep_type) {
|
||||||
@@ -789,7 +788,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
|
|||||||
if (dbg_hc(chan))
|
if (dbg_hc(chan))
|
||||||
dev_vdbg(hsotg->dev, "%s()\n", __func__);
|
dev_vdbg(hsotg->dev, "%s()\n", __func__);
|
||||||
|
|
||||||
if (hsotg->params.host_dma > 0) {
|
if (hsotg->params.host_dma) {
|
||||||
if (dbg_hc(chan))
|
if (dbg_hc(chan))
|
||||||
dev_vdbg(hsotg->dev, "DMA enabled\n");
|
dev_vdbg(hsotg->dev, "DMA enabled\n");
|
||||||
dwc2_release_channel(hsotg, chan, qtd, halt_status);
|
dwc2_release_channel(hsotg, chan, qtd, halt_status);
|
||||||
@@ -823,7 +822,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
|
|||||||
* processed.
|
* processed.
|
||||||
*/
|
*/
|
||||||
list_move_tail(&chan->qh->qh_list_entry,
|
list_move_tail(&chan->qh->qh_list_entry,
|
||||||
&hsotg->periodic_sched_assigned);
|
&hsotg->periodic_sched_assigned);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the Periodic Tx FIFO Empty interrupt is
|
* Make sure the Periodic Tx FIFO Empty interrupt is
|
||||||
@@ -979,7 +978,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
|
|||||||
|
|
||||||
pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info);
|
pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info);
|
||||||
|
|
||||||
if (hsotg->params.dma_desc_enable > 0) {
|
if (hsotg->params.dma_desc_enable) {
|
||||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status);
|
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status);
|
||||||
if (pipe_type == USB_ENDPOINT_XFER_ISOC)
|
if (pipe_type == USB_ENDPOINT_XFER_ISOC)
|
||||||
/* Do not disable the interrupt, just clear it */
|
/* Do not disable the interrupt, just clear it */
|
||||||
@@ -990,7 +989,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
|
|||||||
/* Handle xfer complete on CSPLIT */
|
/* Handle xfer complete on CSPLIT */
|
||||||
if (chan->qh->do_split) {
|
if (chan->qh->do_split) {
|
||||||
if (chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
|
if (chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
|
||||||
hsotg->params.host_dma > 0) {
|
hsotg->params.host_dma) {
|
||||||
if (qtd->complete_split &&
|
if (qtd->complete_split &&
|
||||||
dwc2_xfercomp_isoc_split_in(hsotg, chan, chnum,
|
dwc2_xfercomp_isoc_split_in(hsotg, chan, chnum,
|
||||||
qtd))
|
qtd))
|
||||||
@@ -1078,7 +1077,8 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
|
|||||||
dev_vdbg(hsotg->dev, " Isochronous transfer complete\n");
|
dev_vdbg(hsotg->dev, " Isochronous transfer complete\n");
|
||||||
if (qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_ALL)
|
if (qtd->isoc_split_pos == DWC2_HCSPLT_XACTPOS_ALL)
|
||||||
halt_status = dwc2_update_isoc_urb_state(hsotg, chan,
|
halt_status = dwc2_update_isoc_urb_state(hsotg, chan,
|
||||||
chnum, qtd, DWC2_HC_XFER_COMPLETE);
|
chnum, qtd,
|
||||||
|
DWC2_HC_XFER_COMPLETE);
|
||||||
dwc2_complete_periodic_xfer(hsotg, chan, chnum, qtd,
|
dwc2_complete_periodic_xfer(hsotg, chan, chnum, qtd,
|
||||||
halt_status);
|
halt_status);
|
||||||
break;
|
break;
|
||||||
@@ -1102,7 +1102,7 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg,
|
|||||||
dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n",
|
dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n",
|
||||||
chnum);
|
chnum);
|
||||||
|
|
||||||
if (hsotg->params.dma_desc_enable > 0) {
|
if (hsotg->params.dma_desc_enable) {
|
||||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||||
DWC2_HC_XFER_STALL);
|
DWC2_HC_XFER_STALL);
|
||||||
goto handle_stall_done;
|
goto handle_stall_done;
|
||||||
@@ -1212,7 +1212,7 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg,
|
|||||||
switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
|
switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
|
||||||
case USB_ENDPOINT_XFER_CONTROL:
|
case USB_ENDPOINT_XFER_CONTROL:
|
||||||
case USB_ENDPOINT_XFER_BULK:
|
case USB_ENDPOINT_XFER_BULK:
|
||||||
if (hsotg->params.host_dma > 0 && chan->ep_is_in) {
|
if (hsotg->params.host_dma && chan->ep_is_in) {
|
||||||
/*
|
/*
|
||||||
* NAK interrupts are enabled on bulk/control IN
|
* NAK interrupts are enabled on bulk/control IN
|
||||||
* transfers in DMA mode for the sole purpose of
|
* transfers in DMA mode for the sole purpose of
|
||||||
@@ -1358,7 +1358,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
|
|||||||
*/
|
*/
|
||||||
if (chan->do_split && chan->complete_split) {
|
if (chan->do_split && chan->complete_split) {
|
||||||
if (chan->ep_is_in && chan->ep_type == USB_ENDPOINT_XFER_ISOC &&
|
if (chan->ep_is_in && chan->ep_type == USB_ENDPOINT_XFER_ISOC &&
|
||||||
hsotg->params.host_dma > 0) {
|
hsotg->params.host_dma) {
|
||||||
qtd->complete_split = 0;
|
qtd->complete_split = 0;
|
||||||
qtd->isoc_split_offset = 0;
|
qtd->isoc_split_offset = 0;
|
||||||
qtd->isoc_frame_index++;
|
qtd->isoc_frame_index++;
|
||||||
@@ -1379,7 +1379,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
|
|||||||
struct dwc2_qh *qh = chan->qh;
|
struct dwc2_qh *qh = chan->qh;
|
||||||
bool past_end;
|
bool past_end;
|
||||||
|
|
||||||
if (hsotg->params.uframe_sched <= 0) {
|
if (!hsotg->params.uframe_sched) {
|
||||||
int frnum = dwc2_hcd_get_frame_number(hsotg);
|
int frnum = dwc2_hcd_get_frame_number(hsotg);
|
||||||
|
|
||||||
/* Don't have num_hs_transfers; simple logic */
|
/* Don't have num_hs_transfers; simple logic */
|
||||||
@@ -1389,22 +1389,27 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
|
|||||||
int end_frnum;
|
int end_frnum;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out the end frame based on schedule.
|
* Figure out the end frame based on
|
||||||
*
|
* schedule.
|
||||||
* We don't want to go on trying again and again
|
*
|
||||||
* forever. Let's stop when we've done all the
|
* We don't want to go on trying again
|
||||||
* transfers that were scheduled.
|
* and again forever. Let's stop when
|
||||||
*
|
* we've done all the transfers that
|
||||||
* We're going to be comparing start_active_frame
|
* were scheduled.
|
||||||
* and next_active_frame, both of which are 1
|
*
|
||||||
* before the time the packet goes on the wire,
|
* We're going to be comparing
|
||||||
* so that cancels out. Basically if had 1
|
* start_active_frame and
|
||||||
* transfer and we saw 1 NYET then we're done.
|
* next_active_frame, both of which
|
||||||
* We're getting a NYET here so if next >=
|
* are 1 before the time the packet
|
||||||
* (start + num_transfers) we're done. The
|
* goes on the wire, so that cancels
|
||||||
* complexity is that for all but ISOC_OUT we
|
* out. Basically if had 1 transfer
|
||||||
* skip one slot.
|
* and we saw 1 NYET then we're done.
|
||||||
*/
|
* We're getting a NYET here so if
|
||||||
|
* next >= (start + num_transfers)
|
||||||
|
* we're done. The complexity is that
|
||||||
|
* for all but ISOC_OUT we skip one
|
||||||
|
* slot.
|
||||||
|
*/
|
||||||
end_frnum = dwc2_frame_num_inc(
|
end_frnum = dwc2_frame_num_inc(
|
||||||
qh->start_active_frame,
|
qh->start_active_frame,
|
||||||
qh->num_hs_transfers);
|
qh->num_hs_transfers);
|
||||||
@@ -1472,7 +1477,7 @@ static void dwc2_hc_babble_intr(struct dwc2_hsotg *hsotg,
|
|||||||
|
|
||||||
dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
|
dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
|
||||||
|
|
||||||
if (hsotg->params.dma_desc_enable > 0) {
|
if (hsotg->params.dma_desc_enable) {
|
||||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||||
DWC2_HC_XFER_BABBLE_ERR);
|
DWC2_HC_XFER_BABBLE_ERR);
|
||||||
goto disable_int;
|
goto disable_int;
|
||||||
@@ -1577,7 +1582,7 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg,
|
|||||||
dev_err(hsotg->dev, " Interval: %d\n", urb->interval);
|
dev_err(hsotg->dev, " Interval: %d\n", urb->interval);
|
||||||
|
|
||||||
/* Core halts the channel for Descriptor DMA mode */
|
/* Core halts the channel for Descriptor DMA mode */
|
||||||
if (hsotg->params.dma_desc_enable > 0) {
|
if (hsotg->params.dma_desc_enable) {
|
||||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||||
DWC2_HC_XFER_AHB_ERR);
|
DWC2_HC_XFER_AHB_ERR);
|
||||||
goto handle_ahberr_done;
|
goto handle_ahberr_done;
|
||||||
@@ -1609,7 +1614,7 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg,
|
|||||||
|
|
||||||
dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
|
dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
|
||||||
|
|
||||||
if (hsotg->params.dma_desc_enable > 0) {
|
if (hsotg->params.dma_desc_enable) {
|
||||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||||
DWC2_HC_XFER_XACT_ERR);
|
DWC2_HC_XFER_XACT_ERR);
|
||||||
goto handle_xacterr_done;
|
goto handle_xacterr_done;
|
||||||
@@ -1620,7 +1625,6 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg,
|
|||||||
case USB_ENDPOINT_XFER_BULK:
|
case USB_ENDPOINT_XFER_BULK:
|
||||||
qtd->error_count++;
|
qtd->error_count++;
|
||||||
if (!chan->qh->ping_state) {
|
if (!chan->qh->ping_state) {
|
||||||
|
|
||||||
dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb,
|
dwc2_update_urb_state_abn(hsotg, chan, chnum, qtd->urb,
|
||||||
qtd, DWC2_HC_XFER_XACT_ERR);
|
qtd, DWC2_HC_XFER_XACT_ERR);
|
||||||
dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd);
|
dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd);
|
||||||
@@ -1645,7 +1649,7 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg,
|
|||||||
enum dwc2_halt_status halt_status;
|
enum dwc2_halt_status halt_status;
|
||||||
|
|
||||||
halt_status = dwc2_update_isoc_urb_state(hsotg, chan,
|
halt_status = dwc2_update_isoc_urb_state(hsotg, chan,
|
||||||
chnum, qtd, DWC2_HC_XFER_XACT_ERR);
|
chnum, qtd, DWC2_HC_XFER_XACT_ERR);
|
||||||
dwc2_halt_channel(hsotg, chan, qtd, halt_status);
|
dwc2_halt_channel(hsotg, chan, qtd, halt_status);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1803,8 +1807,8 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
|
|||||||
|
|
||||||
if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE ||
|
if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE ||
|
||||||
(chan->halt_status == DWC2_HC_XFER_AHB_ERR &&
|
(chan->halt_status == DWC2_HC_XFER_AHB_ERR &&
|
||||||
hsotg->params.dma_desc_enable <= 0)) {
|
!hsotg->params.dma_desc_enable)) {
|
||||||
if (hsotg->params.dma_desc_enable > 0)
|
if (hsotg->params.dma_desc_enable)
|
||||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||||
chan->halt_status);
|
chan->halt_status);
|
||||||
else
|
else
|
||||||
@@ -1835,7 +1839,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
|
|||||||
} else if (chan->hcint & HCINTMSK_STALL) {
|
} else if (chan->hcint & HCINTMSK_STALL) {
|
||||||
dwc2_hc_stall_intr(hsotg, chan, chnum, qtd);
|
dwc2_hc_stall_intr(hsotg, chan, chnum, qtd);
|
||||||
} else if ((chan->hcint & HCINTMSK_XACTERR) &&
|
} else if ((chan->hcint & HCINTMSK_XACTERR) &&
|
||||||
hsotg->params.dma_desc_enable <= 0) {
|
!hsotg->params.dma_desc_enable) {
|
||||||
if (out_nak_enh) {
|
if (out_nak_enh) {
|
||||||
if (chan->hcint &
|
if (chan->hcint &
|
||||||
(HCINTMSK_NYET | HCINTMSK_NAK | HCINTMSK_ACK)) {
|
(HCINTMSK_NYET | HCINTMSK_NAK | HCINTMSK_ACK)) {
|
||||||
@@ -1855,10 +1859,10 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
|
|||||||
*/
|
*/
|
||||||
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
|
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
|
||||||
} else if ((chan->hcint & HCINTMSK_XCS_XACT) &&
|
} else if ((chan->hcint & HCINTMSK_XCS_XACT) &&
|
||||||
hsotg->params.dma_desc_enable > 0) {
|
hsotg->params.dma_desc_enable) {
|
||||||
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
|
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
|
||||||
} else if ((chan->hcint & HCINTMSK_AHBERR) &&
|
} else if ((chan->hcint & HCINTMSK_AHBERR) &&
|
||||||
hsotg->params.dma_desc_enable > 0) {
|
hsotg->params.dma_desc_enable) {
|
||||||
dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd);
|
dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd);
|
||||||
} else if (chan->hcint & HCINTMSK_BBLERR) {
|
} else if (chan->hcint & HCINTMSK_BBLERR) {
|
||||||
dwc2_hc_babble_intr(hsotg, chan, chnum, qtd);
|
dwc2_hc_babble_intr(hsotg, chan, chnum, qtd);
|
||||||
@@ -1951,7 +1955,7 @@ static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg,
|
|||||||
dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: Channel Halted--\n",
|
dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: Channel Halted--\n",
|
||||||
chnum);
|
chnum);
|
||||||
|
|
||||||
if (hsotg->params.host_dma > 0) {
|
if (hsotg->params.host_dma) {
|
||||||
dwc2_hc_chhltd_intr_dma(hsotg, chan, chnum, qtd);
|
dwc2_hc_chhltd_intr_dma(hsotg, chan, chnum, qtd);
|
||||||
} else {
|
} else {
|
||||||
if (!dwc2_halt_status_ok(hsotg, chan, chnum, qtd))
|
if (!dwc2_halt_status_ok(hsotg, chan, chnum, qtd))
|
||||||
@@ -1970,7 +1974,7 @@ static bool dwc2_check_qtd_still_ok(struct dwc2_qtd *qtd, struct dwc2_qh *qh)
|
|||||||
{
|
{
|
||||||
struct dwc2_qtd *cur_head;
|
struct dwc2_qtd *cur_head;
|
||||||
|
|
||||||
if (qh == NULL)
|
if (!qh)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
cur_head = list_first_entry(&qh->qtd_list, struct dwc2_qtd,
|
cur_head = list_first_entry(&qh->qtd_list, struct dwc2_qtd,
|
||||||
@@ -2028,7 +2032,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
|
|||||||
* interrupt unmasked
|
* interrupt unmasked
|
||||||
*/
|
*/
|
||||||
WARN_ON(hcint != HCINTMSK_CHHLTD);
|
WARN_ON(hcint != HCINTMSK_CHHLTD);
|
||||||
if (hsotg->params.dma_desc_enable > 0)
|
if (hsotg->params.dma_desc_enable)
|
||||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||||
chan->halt_status);
|
chan->halt_status);
|
||||||
else
|
else
|
||||||
@@ -2056,7 +2060,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
|
|||||||
qtd = list_first_entry(&chan->qh->qtd_list, struct dwc2_qtd,
|
qtd = list_first_entry(&chan->qh->qtd_list, struct dwc2_qtd,
|
||||||
qtd_list_entry);
|
qtd_list_entry);
|
||||||
|
|
||||||
if (hsotg->params.host_dma <= 0) {
|
if (!hsotg->params.host_dma) {
|
||||||
if ((hcint & HCINTMSK_CHHLTD) && hcint != HCINTMSK_CHHLTD)
|
if ((hcint & HCINTMSK_CHHLTD) && hcint != HCINTMSK_CHHLTD)
|
||||||
hcint &= ~HCINTMSK_CHHLTD;
|
hcint &= ~HCINTMSK_CHHLTD;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,14 +76,13 @@ static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg)
|
|||||||
int num_channels;
|
int num_channels;
|
||||||
|
|
||||||
num_channels = hsotg->params.host_channels;
|
num_channels = hsotg->params.host_channels;
|
||||||
if (hsotg->periodic_channels + hsotg->non_periodic_channels <
|
if ((hsotg->periodic_channels + hsotg->non_periodic_channels <
|
||||||
num_channels
|
num_channels) && (hsotg->periodic_channels < num_channels - 1)) {
|
||||||
&& hsotg->periodic_channels < num_channels - 1) {
|
|
||||||
status = 0;
|
status = 0;
|
||||||
} else {
|
} else {
|
||||||
dev_dbg(hsotg->dev,
|
dev_dbg(hsotg->dev,
|
||||||
"%s: Total channels: %d, Periodic: %d, "
|
"%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n",
|
||||||
"Non-periodic: %d\n", __func__, num_channels,
|
__func__, num_channels,
|
||||||
hsotg->periodic_channels, hsotg->non_periodic_channels);
|
hsotg->periodic_channels, hsotg->non_periodic_channels);
|
||||||
status = -ENOSPC;
|
status = -ENOSPC;
|
||||||
}
|
}
|
||||||
@@ -485,7 +484,6 @@ static void pmap_print(unsigned long *map, int bits_per_period,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dwc2_qh_print_data {
|
struct dwc2_qh_print_data {
|
||||||
struct dwc2_hsotg *hsotg;
|
struct dwc2_hsotg *hsotg;
|
||||||
struct dwc2_qh *qh;
|
struct dwc2_qh *qh;
|
||||||
@@ -558,7 +556,6 @@ static void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
|
|||||||
DWC2_HS_SCHEDULE_UFRAMES, "uFrame", "us",
|
DWC2_HS_SCHEDULE_UFRAMES, "uFrame", "us",
|
||||||
dwc2_qh_print, &print_data);
|
dwc2_qh_print, &print_data);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
|
static inline void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
|
||||||
@@ -587,7 +584,7 @@ static int dwc2_ls_pmap_schedule(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
|||||||
unsigned long *map = dwc2_get_ls_map(hsotg, qh);
|
unsigned long *map = dwc2_get_ls_map(hsotg, qh);
|
||||||
int slice;
|
int slice;
|
||||||
|
|
||||||
if (map == NULL)
|
if (!map)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -626,7 +623,7 @@ static void dwc2_ls_pmap_unschedule(struct dwc2_hsotg *hsotg,
|
|||||||
unsigned long *map = dwc2_get_ls_map(hsotg, qh);
|
unsigned long *map = dwc2_get_ls_map(hsotg, qh);
|
||||||
|
|
||||||
/* Schedule should have failed, so no worries about no error code */
|
/* Schedule should have failed, so no worries about no error code */
|
||||||
if (map == NULL)
|
if (!map)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pmap_unschedule(map, DWC2_LS_PERIODIC_SLICES_PER_FRAME,
|
pmap_unschedule(map, DWC2_LS_PERIODIC_SLICES_PER_FRAME,
|
||||||
@@ -1107,7 +1104,7 @@ static void dwc2_pick_first_frame(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
next_active_frame = earliest_frame;
|
next_active_frame = earliest_frame;
|
||||||
|
|
||||||
/* Get the "no microframe schduler" out of the way... */
|
/* Get the "no microframe schduler" out of the way... */
|
||||||
if (hsotg->params.uframe_sched <= 0) {
|
if (!hsotg->params.uframe_sched) {
|
||||||
if (qh->do_split)
|
if (qh->do_split)
|
||||||
/* Splits are active at microframe 0 minus 1 */
|
/* Splits are active at microframe 0 minus 1 */
|
||||||
next_active_frame |= 0x7;
|
next_active_frame |= 0x7;
|
||||||
@@ -1182,7 +1179,7 @@ exit:
|
|||||||
qh->start_active_frame = next_active_frame;
|
qh->start_active_frame = next_active_frame;
|
||||||
|
|
||||||
dwc2_sch_vdbg(hsotg, "QH=%p First fn=%04x nxt=%04x\n",
|
dwc2_sch_vdbg(hsotg, "QH=%p First fn=%04x nxt=%04x\n",
|
||||||
qh, frame_number, qh->next_active_frame);
|
qh, frame_number, qh->next_active_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1200,7 +1197,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (hsotg->params.uframe_sched > 0) {
|
if (hsotg->params.uframe_sched) {
|
||||||
status = dwc2_uframe_schedule(hsotg, qh);
|
status = dwc2_uframe_schedule(hsotg, qh);
|
||||||
} else {
|
} else {
|
||||||
status = dwc2_periodic_channel_available(hsotg);
|
status = dwc2_periodic_channel_available(hsotg);
|
||||||
@@ -1221,7 +1218,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hsotg->params.uframe_sched <= 0)
|
if (!hsotg->params.uframe_sched)
|
||||||
/* Reserve periodic channel */
|
/* Reserve periodic channel */
|
||||||
hsotg->periodic_channels++;
|
hsotg->periodic_channels++;
|
||||||
|
|
||||||
@@ -1257,7 +1254,7 @@ static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
/* Update claimed usecs per (micro)frame */
|
/* Update claimed usecs per (micro)frame */
|
||||||
hsotg->periodic_usecs -= qh->host_us;
|
hsotg->periodic_usecs -= qh->host_us;
|
||||||
|
|
||||||
if (hsotg->params.uframe_sched > 0) {
|
if (hsotg->params.uframe_sched) {
|
||||||
dwc2_uframe_unschedule(hsotg, qh);
|
dwc2_uframe_unschedule(hsotg, qh);
|
||||||
} else {
|
} else {
|
||||||
/* Release periodic channel reservation */
|
/* Release periodic channel reservation */
|
||||||
@@ -1394,7 +1391,7 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
|
|
||||||
qh->unreserve_pending = 0;
|
qh->unreserve_pending = 0;
|
||||||
|
|
||||||
if (hsotg->params.dma_desc_enable > 0)
|
if (hsotg->params.dma_desc_enable)
|
||||||
/* Don't rely on SOF and start in ready schedule */
|
/* Don't rely on SOF and start in ready schedule */
|
||||||
list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready);
|
list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready);
|
||||||
else
|
else
|
||||||
@@ -1501,7 +1498,6 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
|||||||
device_ns += dwc_tt->usb_tt->think_time;
|
device_ns += dwc_tt->usb_tt->think_time;
|
||||||
qh->device_us = NS_TO_US(device_ns);
|
qh->device_us = NS_TO_US(device_ns);
|
||||||
|
|
||||||
|
|
||||||
qh->device_interval = urb->interval;
|
qh->device_interval = urb->interval;
|
||||||
qh->host_interval = urb->interval * (do_split ? 8 : 1);
|
qh->host_interval = urb->interval * (do_split ? 8 : 1);
|
||||||
|
|
||||||
@@ -1587,7 +1583,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
|||||||
* Return: Pointer to the newly allocated QH, or NULL on error
|
* Return: Pointer to the newly allocated QH, or NULL on error
|
||||||
*/
|
*/
|
||||||
struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_hcd_urb *urb,
|
struct dwc2_hcd_urb *urb,
|
||||||
gfp_t mem_flags)
|
gfp_t mem_flags)
|
||||||
{
|
{
|
||||||
struct dwc2_qh *qh;
|
struct dwc2_qh *qh;
|
||||||
@@ -1602,7 +1598,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
|||||||
|
|
||||||
dwc2_qh_init(hsotg, qh, urb, mem_flags);
|
dwc2_qh_init(hsotg, qh, urb, mem_flags);
|
||||||
|
|
||||||
if (hsotg->params.dma_desc_enable > 0 &&
|
if (hsotg->params.dma_desc_enable &&
|
||||||
dwc2_hcd_qh_init_ddma(hsotg, qh, mem_flags) < 0) {
|
dwc2_hcd_qh_init_ddma(hsotg, qh, mem_flags) < 0) {
|
||||||
dwc2_hcd_qh_free(hsotg, qh);
|
dwc2_hcd_qh_free(hsotg, qh);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1714,7 +1710,7 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
dwc2_deschedule_periodic(hsotg, qh);
|
dwc2_deschedule_periodic(hsotg, qh);
|
||||||
hsotg->periodic_qh_count--;
|
hsotg->periodic_qh_count--;
|
||||||
if (!hsotg->periodic_qh_count &&
|
if (!hsotg->periodic_qh_count &&
|
||||||
hsotg->params.dma_desc_enable <= 0) {
|
!hsotg->params.dma_desc_enable) {
|
||||||
intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
|
intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
|
||||||
intr_mask &= ~GINTSTS_SOF;
|
intr_mask &= ~GINTSTS_SOF;
|
||||||
dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
|
dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
|
||||||
@@ -1741,7 +1737,7 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|||||||
* Return: number missed by (or 0 if we didn't miss).
|
* Return: number missed by (or 0 if we didn't miss).
|
||||||
*/
|
*/
|
||||||
static int dwc2_next_for_periodic_split(struct dwc2_hsotg *hsotg,
|
static int dwc2_next_for_periodic_split(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_qh *qh, u16 frame_number)
|
struct dwc2_qh *qh, u16 frame_number)
|
||||||
{
|
{
|
||||||
u16 old_frame = qh->next_active_frame;
|
u16 old_frame = qh->next_active_frame;
|
||||||
u16 prev_frame_number = dwc2_frame_num_dec(frame_number, 1);
|
u16 prev_frame_number = dwc2_frame_num_dec(frame_number, 1);
|
||||||
@@ -1804,7 +1800,7 @@ static int dwc2_next_for_periodic_split(struct dwc2_hsotg *hsotg,
|
|||||||
* Return: number missed by (or 0 if we didn't miss).
|
* Return: number missed by (or 0 if we didn't miss).
|
||||||
*/
|
*/
|
||||||
static int dwc2_next_periodic_start(struct dwc2_hsotg *hsotg,
|
static int dwc2_next_periodic_start(struct dwc2_hsotg *hsotg,
|
||||||
struct dwc2_qh *qh, u16 frame_number)
|
struct dwc2_qh *qh, u16 frame_number)
|
||||||
{
|
{
|
||||||
int missed = 0;
|
int missed = 0;
|
||||||
u16 interval = qh->host_interval;
|
u16 interval = qh->host_interval;
|
||||||
@@ -1926,7 +1922,7 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
|||||||
missed = dwc2_next_periodic_start(hsotg, qh, frame_number);
|
missed = dwc2_next_periodic_start(hsotg, qh, frame_number);
|
||||||
|
|
||||||
dwc2_sch_vdbg(hsotg,
|
dwc2_sch_vdbg(hsotg,
|
||||||
"QH=%p next(%d) fn=%04x, sch=%04x=>%04x (%+d) miss=%d %s\n",
|
"QH=%p next(%d) fn=%04x, sch=%04x=>%04x (%+d) miss=%d %s\n",
|
||||||
qh, sched_next_periodic_split, frame_number, old_frame,
|
qh, sched_next_periodic_split, frame_number, old_frame,
|
||||||
qh->next_active_frame,
|
qh->next_active_frame,
|
||||||
dwc2_frame_num_dec(qh->next_active_frame, old_frame),
|
dwc2_frame_num_dec(qh->next_active_frame, old_frame),
|
||||||
|
|||||||
+298
-298
File diff suppressed because it is too large
Load Diff
+388
-1104
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user