提交 37a842d3 编写于 作者: G Greg Kroah-Hartman

Merge tag 'usb-ci-v4.3-rc1' of...

Merge tag 'usb-ci-v4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb into usb-next

Peter writes:

USB: chipidea updates for v4.3-rc1

The main changes are adding several system interfaces for
tuning performance, and each vendors can adjust them according
to their design configurations.

Others are tiny improvements, like more well siTD supports,
USB_DEVICE_A_HNP_SUPPORT supports, etc.
...@@ -30,6 +30,21 @@ Optional properties: ...@@ -30,6 +30,21 @@ Optional properties:
argument that indicate usb controller index argument that indicate usb controller index
- disable-over-current: (FSL only) disable over current detect - disable-over-current: (FSL only) disable over current detect
- external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus - external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus
- itc-setting: interrupt threshold control register control, the setting
should be aligned with ITC bits at register USBCMD.
- ahb-burst-config: it is vendor dependent, the required value should be
aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7. This
property is used to change AHB burst configuration, check the chipidea
spec for meaning of each value. If this property is not existed, it
will use the reset value.
- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
(4 bytes), This register represents the maximum length of a the burst
in 32-bit words while moving data from system memory to the USB
bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.
- rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
(4 bytes), This register represents the maximum length of a the burst
in 32-bit words while moving data from the USB bus to system memory,
changing this value takes effect only the SBUSCFG.AHBBRST is 0.
Example: Example:
...@@ -41,4 +56,9 @@ Example: ...@@ -41,4 +56,9 @@ Example:
phys = <&usb_phy0>; phys = <&usb_phy0>;
phy-names = "usb-phy"; phy-names = "usb-phy";
vbus-supply = <&reg_usb0_vbus>; vbus-supply = <&reg_usb0_vbus>;
gadget-itc-setting = <0x4>; /* 4 micro-frames */
/* Incremental burst of unspecified length */
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>; /* 64 bytes */
rx-burst-size-dword = <0x10>;
}; };
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
#define VERSION (0xF << 25) #define VERSION (0xF << 25)
#define CIVERSION (0x7 << 29) #define CIVERSION (0x7 << 29)
/* SBUSCFG */
#define AHBBRST_MASK 0x7
/* HCCPARAMS */ /* HCCPARAMS */
#define HCCPARAMS_LEN BIT(17) #define HCCPARAMS_LEN BIT(17)
...@@ -53,6 +56,15 @@ ...@@ -53,6 +56,15 @@
#define DEVICEADDR_USBADRA BIT(24) #define DEVICEADDR_USBADRA BIT(24)
#define DEVICEADDR_USBADR (0x7FUL << 25) #define DEVICEADDR_USBADR (0x7FUL << 25)
/* TTCTRL */
#define TTCTRL_TTHA_MASK (0x7fUL << 24)
/* Set non-zero value for internal TT Hub address representation */
#define TTCTRL_TTHA (0x7fUL << 24)
/* BURSTSIZE */
#define RX_BURST_MASK 0xff
#define TX_BURST_MASK 0xff00
/* PORTSC */ /* PORTSC */
#define PORTSC_CCS BIT(0) #define PORTSC_CCS BIT(0)
#define PORTSC_CSC BIT(1) #define PORTSC_CSC BIT(1)
......
...@@ -50,6 +50,8 @@ enum ci_hw_regs { ...@@ -50,6 +50,8 @@ enum ci_hw_regs {
OP_USBINTR, OP_USBINTR,
OP_DEVICEADDR, OP_DEVICEADDR,
OP_ENDPTLISTADDR, OP_ENDPTLISTADDR,
OP_TTCTRL,
OP_BURSTSIZE,
OP_PORTSC, OP_PORTSC,
OP_DEVLC, OP_DEVLC,
OP_OTGSC, OP_OTGSC,
...@@ -429,4 +431,6 @@ u8 hw_port_test_get(struct ci_hdrc *ci); ...@@ -429,4 +431,6 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
u32 value, unsigned int timeout_ms); u32 value, unsigned int timeout_ms);
void ci_platform_configure(struct ci_hdrc *ci);
#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */ #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
...@@ -29,26 +29,31 @@ struct ci_hdrc_imx_platform_flag { ...@@ -29,26 +29,31 @@ struct ci_hdrc_imx_platform_flag {
}; };
static const struct ci_hdrc_imx_platform_flag imx27_usb_data = { static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
CI_HDRC_DISABLE_STREAMING,
}; };
static const struct ci_hdrc_imx_platform_flag imx28_usb_data = { static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
.flags = CI_HDRC_IMX28_WRITE_FIX | .flags = CI_HDRC_IMX28_WRITE_FIX |
CI_HDRC_TURN_VBUS_EARLY_ON, CI_HDRC_TURN_VBUS_EARLY_ON |
CI_HDRC_DISABLE_STREAMING,
}; };
static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = { static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
CI_HDRC_TURN_VBUS_EARLY_ON, CI_HDRC_TURN_VBUS_EARLY_ON |
CI_HDRC_DISABLE_STREAMING,
}; };
static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = { static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
CI_HDRC_TURN_VBUS_EARLY_ON, CI_HDRC_TURN_VBUS_EARLY_ON |
CI_HDRC_DISABLE_HOST_STREAMING,
}; };
static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = { static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
CI_HDRC_TURN_VBUS_EARLY_ON, CI_HDRC_TURN_VBUS_EARLY_ON |
CI_HDRC_DISABLE_HOST_STREAMING,
}; };
static const struct of_device_id ci_hdrc_imx_dt_ids[] = { static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
...@@ -104,7 +109,7 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) ...@@ -104,7 +109,7 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
misc_pdev = of_find_device_by_node(args.np); misc_pdev = of_find_device_by_node(args.np);
of_node_put(args.np); of_node_put(args.np);
if (!misc_pdev) if (!misc_pdev || !platform_get_drvdata(misc_pdev))
return ERR_PTR(-EPROBE_DEFER); return ERR_PTR(-EPROBE_DEFER);
data->dev = &misc_pdev->dev; data->dev = &misc_pdev->dev;
...@@ -126,7 +131,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) ...@@ -126,7 +131,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
struct ci_hdrc_platform_data pdata = { struct ci_hdrc_platform_data pdata = {
.name = dev_name(&pdev->dev), .name = dev_name(&pdev->dev),
.capoffset = DEF_CAPOFFSET, .capoffset = DEF_CAPOFFSET,
.flags = CI_HDRC_DISABLE_STREAMING, .flags = CI_HDRC_SET_NON_ZERO_TTHA,
}; };
int ret; int ret;
const struct of_device_id *of_id = const struct of_device_id *of_id =
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/usb/ehci_def.h>
#include "ci.h" #include "ci.h"
#include "udc.h" #include "udc.h"
...@@ -84,6 +85,8 @@ static const u8 ci_regs_nolpm[] = { ...@@ -84,6 +85,8 @@ static const u8 ci_regs_nolpm[] = {
[OP_USBINTR] = 0x08U, [OP_USBINTR] = 0x08U,
[OP_DEVICEADDR] = 0x14U, [OP_DEVICEADDR] = 0x14U,
[OP_ENDPTLISTADDR] = 0x18U, [OP_ENDPTLISTADDR] = 0x18U,
[OP_TTCTRL] = 0x1CU,
[OP_BURSTSIZE] = 0x20U,
[OP_PORTSC] = 0x44U, [OP_PORTSC] = 0x44U,
[OP_DEVLC] = 0x84U, [OP_DEVLC] = 0x84U,
[OP_OTGSC] = 0x64U, [OP_OTGSC] = 0x64U,
...@@ -106,6 +109,8 @@ static const u8 ci_regs_lpm[] = { ...@@ -106,6 +109,8 @@ static const u8 ci_regs_lpm[] = {
[OP_USBINTR] = 0x08U, [OP_USBINTR] = 0x08U,
[OP_DEVICEADDR] = 0x14U, [OP_DEVICEADDR] = 0x14U,
[OP_ENDPTLISTADDR] = 0x18U, [OP_ENDPTLISTADDR] = 0x18U,
[OP_TTCTRL] = 0x1CU,
[OP_BURSTSIZE] = 0x20U,
[OP_PORTSC] = 0x44U, [OP_PORTSC] = 0x44U,
[OP_DEVLC] = 0x84U, [OP_DEVLC] = 0x84U,
[OP_OTGSC] = 0xC4U, [OP_OTGSC] = 0xC4U,
...@@ -118,7 +123,7 @@ static const u8 ci_regs_lpm[] = { ...@@ -118,7 +123,7 @@ static const u8 ci_regs_lpm[] = {
[OP_ENDPTCTRL] = 0xECU, [OP_ENDPTCTRL] = 0xECU,
}; };
static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm) static void hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm)
{ {
int i; int i;
...@@ -134,7 +139,6 @@ static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm) ...@@ -134,7 +139,6 @@ static int hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm)
? ci_regs_lpm[OP_ENDPTCTRL] ? ci_regs_lpm[OP_ENDPTCTRL]
: ci_regs_nolpm[OP_ENDPTCTRL]); : ci_regs_nolpm[OP_ENDPTCTRL]);
return 0;
} }
static enum ci_revision ci_get_revision(struct ci_hdrc *ci) static enum ci_revision ci_get_revision(struct ci_hdrc *ci)
...@@ -403,6 +407,55 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) ...@@ -403,6 +407,55 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
return ret; return ret;
} }
/**
* ci_platform_configure: do controller configure
* @ci: the controller
*
*/
void ci_platform_configure(struct ci_hdrc *ci)
{
bool is_device_mode, is_host_mode;
is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
if (is_device_mode &&
(ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING))
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
if (is_host_mode &&
(ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING))
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
if (ci->hw_bank.lpm)
hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC);
else
hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
}
if (ci->platdata->flags & CI_HDRC_SET_NON_ZERO_TTHA)
hw_write(ci, OP_TTCTRL, TTCTRL_TTHA_MASK, TTCTRL_TTHA);
hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);
if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
ci->platdata->ahb_burst_config);
/* override burst size, take effect only when ahb_burst_config is 0 */
if (!hw_read_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK)) {
if (ci->platdata->flags & CI_HDRC_OVERRIDE_TX_BURST)
hw_write(ci, OP_BURSTSIZE, TX_BURST_MASK,
ci->platdata->tx_burst_size << __ffs(TX_BURST_MASK));
if (ci->platdata->flags & CI_HDRC_OVERRIDE_RX_BURST)
hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
ci->platdata->rx_burst_size);
}
}
/** /**
* hw_controller_reset: do controller reset * hw_controller_reset: do controller reset
* @ci: the controller * @ci: the controller
...@@ -447,16 +500,6 @@ int hw_device_reset(struct ci_hdrc *ci) ...@@ -447,16 +500,6 @@ int hw_device_reset(struct ci_hdrc *ci)
ci->platdata->notify_event(ci, ci->platdata->notify_event(ci,
CI_HDRC_CONTROLLER_RESET_EVENT); CI_HDRC_CONTROLLER_RESET_EVENT);
if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
if (ci->hw_bank.lpm)
hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC);
else
hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
}
/* USBMODE should be configured step by step */ /* USBMODE should be configured step by step */
hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC); hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC);
...@@ -469,6 +512,8 @@ int hw_device_reset(struct ci_hdrc *ci) ...@@ -469,6 +512,8 @@ int hw_device_reset(struct ci_hdrc *ci)
return -ENODEV; return -ENODEV;
} }
ci_platform_configure(ci);
return 0; return 0;
} }
...@@ -606,6 +651,50 @@ static int ci_get_platdata(struct device *dev, ...@@ -606,6 +651,50 @@ static int ci_get_platdata(struct device *dev,
if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL) if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL)
platdata->flags |= CI_HDRC_FORCE_FULLSPEED; platdata->flags |= CI_HDRC_FORCE_FULLSPEED;
platdata->itc_setting = 1;
if (of_find_property(dev->of_node, "itc-setting", NULL)) {
ret = of_property_read_u32(dev->of_node, "itc-setting",
&platdata->itc_setting);
if (ret) {
dev_err(dev,
"failed to get itc-setting\n");
return ret;
}
}
if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) {
ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
&platdata->ahb_burst_config);
if (ret) {
dev_err(dev,
"failed to get ahb-burst-config\n");
return ret;
}
platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
}
if (of_find_property(dev->of_node, "tx-burst-size-dword", NULL)) {
ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword",
&platdata->tx_burst_size);
if (ret) {
dev_err(dev,
"failed to get tx-burst-size-dword\n");
return ret;
}
platdata->flags |= CI_HDRC_OVERRIDE_TX_BURST;
}
if (of_find_property(dev->of_node, "rx-burst-size-dword", NULL)) {
ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword",
&platdata->rx_burst_size);
if (ret) {
dev_err(dev,
"failed to get rx-burst-size-dword\n");
return ret;
}
platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
}
return 0; return 0;
} }
......
...@@ -67,9 +67,11 @@ static int ci_port_test_show(struct seq_file *s, void *data) ...@@ -67,9 +67,11 @@ static int ci_port_test_show(struct seq_file *s, void *data)
unsigned long flags; unsigned long flags;
unsigned mode; unsigned mode;
pm_runtime_get_sync(ci->dev);
spin_lock_irqsave(&ci->lock, flags); spin_lock_irqsave(&ci->lock, flags);
mode = hw_port_test_get(ci); mode = hw_port_test_get(ci);
spin_unlock_irqrestore(&ci->lock, flags); spin_unlock_irqrestore(&ci->lock, flags);
pm_runtime_put_sync(ci->dev);
seq_printf(s, "mode = %u\n", mode); seq_printf(s, "mode = %u\n", mode);
...@@ -99,9 +101,11 @@ static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf, ...@@ -99,9 +101,11 @@ static ssize_t ci_port_test_write(struct file *file, const char __user *ubuf,
if (sscanf(buf, "%u", &mode) != 1) if (sscanf(buf, "%u", &mode) != 1)
return -EINVAL; return -EINVAL;
pm_runtime_get_sync(ci->dev);
spin_lock_irqsave(&ci->lock, flags); spin_lock_irqsave(&ci->lock, flags);
ret = hw_port_test_set(ci, mode); ret = hw_port_test_set(ci, mode);
spin_unlock_irqrestore(&ci->lock, flags); spin_unlock_irqrestore(&ci->lock, flags);
pm_runtime_put_sync(ci->dev);
return ret ? ret : count; return ret ? ret : count;
} }
...@@ -317,8 +321,10 @@ static ssize_t ci_role_write(struct file *file, const char __user *ubuf, ...@@ -317,8 +321,10 @@ static ssize_t ci_role_write(struct file *file, const char __user *ubuf,
if (role == CI_ROLE_END || role == ci->role) if (role == CI_ROLE_END || role == ci->role)
return -EINVAL; return -EINVAL;
pm_runtime_get_sync(ci->dev);
ci_role_stop(ci); ci_role_stop(ci);
ret = ci_role_start(ci, role); ret = ci_role_start(ci, role);
pm_runtime_put_sync(ci->dev);
return ret ? ret : count; return ret ? ret : count;
} }
......
...@@ -37,15 +37,14 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd); ...@@ -37,15 +37,14 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd);
struct ehci_ci_priv { struct ehci_ci_priv {
struct regulator *reg_vbus; struct regulator *reg_vbus;
struct ci_hdrc *ci;
}; };
static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
{ {
struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv;
struct ci_hdrc *ci = priv->ci;
struct device *dev = hcd->self.controller; struct device *dev = hcd->self.controller;
struct ci_hdrc *ci = dev_get_drvdata(dev);
int ret = 0; int ret = 0;
int port = HCS_N_PORTS(ehci->hcs_params); int port = HCS_N_PORTS(ehci->hcs_params);
...@@ -78,9 +77,25 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) ...@@ -78,9 +77,25 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
return 0; return 0;
}; };
static int ehci_ci_reset(struct usb_hcd *hcd)
{
struct device *dev = hcd->self.controller;
struct ci_hdrc *ci = dev_get_drvdata(dev);
int ret;
ret = ehci_setup(hcd);
if (ret)
return ret;
ci_platform_configure(ci);
return ret;
}
static const struct ehci_driver_overrides ehci_ci_overrides = { static const struct ehci_driver_overrides ehci_ci_overrides = {
.extra_priv_size = sizeof(struct ehci_ci_priv), .extra_priv_size = sizeof(struct ehci_ci_priv),
.port_power = ehci_ci_portpower, .port_power = ehci_ci_portpower,
.reset = ehci_ci_reset,
}; };
static irqreturn_t host_irq(struct ci_hdrc *ci) static irqreturn_t host_irq(struct ci_hdrc *ci)
...@@ -123,7 +138,6 @@ static int host_start(struct ci_hdrc *ci) ...@@ -123,7 +138,6 @@ static int host_start(struct ci_hdrc *ci)
priv = (struct ehci_ci_priv *)ehci->priv; priv = (struct ehci_ci_priv *)ehci->priv;
priv->reg_vbus = NULL; priv->reg_vbus = NULL;
priv->ci = ci;
if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) {
if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) { if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) {
...@@ -153,12 +167,6 @@ static int host_start(struct ci_hdrc *ci) ...@@ -153,12 +167,6 @@ static int host_start(struct ci_hdrc *ci)
} }
} }
if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED)
hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
return ret; return ret;
disable_reg: disable_reg:
......
...@@ -525,7 +525,6 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on) ...@@ -525,7 +525,6 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on)
ci_role_start(ci, CI_ROLE_HOST); ci_role_start(ci, CI_ROLE_HOST);
} else { } else {
ci_role_stop(ci); ci_role_stop(ci);
hw_device_reset(ci);
ci_role_start(ci, CI_ROLE_GADGET); ci_role_start(ci, CI_ROLE_GADGET);
} }
return 0; return 0;
......
...@@ -445,7 +445,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) ...@@ -445,7 +445,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
rest -= count; rest -= count;
} }
if (hwreq->req.zero && hwreq->req.length if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX
&& (hwreq->req.length % hwep->ep.maxpacket == 0)) && (hwreq->req.length % hwep->ep.maxpacket == 0))
add_td_to_list(hwep, hwreq, 0); add_td_to_list(hwep, hwreq, 0);
...@@ -1090,6 +1090,13 @@ __acquires(ci->lock) ...@@ -1090,6 +1090,13 @@ __acquires(ci->lock)
if (ci_otg_is_fsm_mode(ci)) if (ci_otg_is_fsm_mode(ci))
err = otg_a_alt_hnp_support(ci); err = otg_a_alt_hnp_support(ci);
break; break;
case USB_DEVICE_A_HNP_SUPPORT:
if (ci_otg_is_fsm_mode(ci)) {
ci->gadget.a_hnp_support = 1;
err = isr_setup_status_phase(
ci);
}
break;
default: default:
goto delegate; goto delegate;
} }
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3
#define MX53_USB_PLL_DIV_24_MHZ 0x01 #define MX53_USB_PLL_DIV_24_MHZ 0x01
#define MX6_BM_NON_BURST_SETTING BIT(1)
#define MX6_BM_OVER_CUR_DIS BIT(7) #define MX6_BM_OVER_CUR_DIS BIT(7)
#define MX6_BM_WAKEUP_ENABLE BIT(10) #define MX6_BM_WAKEUP_ENABLE BIT(10)
#define MX6_BM_ID_WAKEUP BIT(16) #define MX6_BM_ID_WAKEUP BIT(16)
...@@ -255,14 +256,21 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) ...@@ -255,14 +256,21 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
if (data->index > 3) if (data->index > 3)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&usbmisc->lock, flags);
if (data->disable_oc) { if (data->disable_oc) {
spin_lock_irqsave(&usbmisc->lock, flags);
reg = readl(usbmisc->base + data->index * 4); reg = readl(usbmisc->base + data->index * 4);
writel(reg | MX6_BM_OVER_CUR_DIS, writel(reg | MX6_BM_OVER_CUR_DIS,
usbmisc->base + data->index * 4); usbmisc->base + data->index * 4);
spin_unlock_irqrestore(&usbmisc->lock, flags);
} }
/* SoC non-burst setting */
reg = readl(usbmisc->base + data->index * 4);
writel(reg | MX6_BM_NON_BURST_SETTING,
usbmisc->base + data->index * 4);
spin_unlock_irqrestore(&usbmisc->lock, flags);
usbmisc_imx6q_set_wakeup(data, false); usbmisc_imx6q_set_wakeup(data, false);
return 0; return 0;
......
...@@ -19,8 +19,11 @@ struct ci_hdrc_platform_data { ...@@ -19,8 +19,11 @@ struct ci_hdrc_platform_data {
enum usb_phy_interface phy_mode; enum usb_phy_interface phy_mode;
unsigned long flags; unsigned long flags;
#define CI_HDRC_REGS_SHARED BIT(0) #define CI_HDRC_REGS_SHARED BIT(0)
#define CI_HDRC_DISABLE_DEVICE_STREAMING BIT(1)
#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2) #define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2)
#define CI_HDRC_DISABLE_STREAMING BIT(3) #define CI_HDRC_DISABLE_HOST_STREAMING BIT(3)
#define CI_HDRC_DISABLE_STREAMING (CI_HDRC_DISABLE_DEVICE_STREAMING | \
CI_HDRC_DISABLE_HOST_STREAMING)
/* /*
* Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1, * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
* but otg is not supported (no register otgsc). * but otg is not supported (no register otgsc).
...@@ -29,6 +32,10 @@ struct ci_hdrc_platform_data { ...@@ -29,6 +32,10 @@ struct ci_hdrc_platform_data {
#define CI_HDRC_IMX28_WRITE_FIX BIT(5) #define CI_HDRC_IMX28_WRITE_FIX BIT(5)
#define CI_HDRC_FORCE_FULLSPEED BIT(6) #define CI_HDRC_FORCE_FULLSPEED BIT(6)
#define CI_HDRC_TURN_VBUS_EARLY_ON BIT(7) #define CI_HDRC_TURN_VBUS_EARLY_ON BIT(7)
#define CI_HDRC_SET_NON_ZERO_TTHA BIT(8)
#define CI_HDRC_OVERRIDE_AHB_BURST BIT(9)
#define CI_HDRC_OVERRIDE_TX_BURST BIT(10)
#define CI_HDRC_OVERRIDE_RX_BURST BIT(11)
enum usb_dr_mode dr_mode; enum usb_dr_mode dr_mode;
#define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_RESET_EVENT 0
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
...@@ -36,6 +43,11 @@ struct ci_hdrc_platform_data { ...@@ -36,6 +43,11 @@ struct ci_hdrc_platform_data {
struct regulator *reg_vbus; struct regulator *reg_vbus;
struct usb_otg_caps ci_otg_caps; struct usb_otg_caps ci_otg_caps;
bool tpl_support; bool tpl_support;
/* interrupt threshold setting */
u32 itc_setting;
u32 ahb_burst_config;
u32 tx_burst_size;
u32 rx_burst_size;
}; };
/* Default offset of capability registers */ /* Default offset of capability registers */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册