mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 16:44:10 +08:00
usb: patches for v4.10 merge window
One big merge this time with a total of 166 non-merge commits. Most of the work, by far, is on dwc2 this time (68.2%) with dwc3 a far second (22.5%). The remaining 9.3% are scattered on gadget drivers. The most important changes for dwc2 are the peripheral side DMA support implemented by Synopsys folks and support for the new IOT dwc2 compatible core from Synopsys. In dwc3 land we have support for high-bandwidth, high-speed isochronous endpoints and some non-critical fixes for large scatter lists. Apart from these, we have our usual set of cleanups, non-critical fixes, etc. -----BEGIN PGP SIGNATURE----- iQJRBAABCAA7FiEElLzh7wn96CXwjh2IzL64meEamQYFAlgu7+gdHGZlbGlwZS5i YWxiaUBsaW51eC5pbnRlbC5jb20ACgkQzL64meEamQaDbxAAsgDPAp8QTx8D1d70 hSGyPZ55rmqlzBNbUUOQyk/AeN5xM3XVbjZNOxWn4c386iaDrngcqOrxjCbBRsje b9yMESMiZsTPVlKXE45yXt//NHg1KUfpHON7rybaiFq0uqjUhnQf95DeYPgJVxit 7F9B+05XcNMyxYRoz6bGkRTU+lcJ6g3/orgKfp4t/hs8WUNXH6+71keMF+IdLYNH mcPmJ8MXpfLzv8eweRwV0s/3flxCuFx1ksZ8cW6qHR5vX303X2sGTlinBmhfQapr t0a+OBtLpZdNmjw/yB2odc/1jjLNRHpYU5xGqwouMx9Ca2PocFT2xFbmUWR23xp1 X0rkICRxcLPjZql2Uld5QHO9dPnF/FbX0Njuvxo+2r8ENE5/eG4C/RcYcRDmYPsu u8k2rKFs0+yCOAU91rD8mayJVBWBJ4trqZFT0TcocCGsMTk8fTYpF1Iskj9Z4FKz yo+lgyCCtp673ykGZ1ezsL6YWOmdrQv/PurKZqrXAmdhi6+mImLI/nAHtAdOZx0X zK9MwPnwDxrPiqhrZ46+Bm/EjZI50TM44M1ldmCwKi/6/Nvy54DHMtjPI5/9205R bjftW3DkVWAC//29RNcGEHtwiJFPEU/kdoRFOPhKGJ7ocCzFVSTFBgo02kDsC6De Wouv2QTFuZN9s17o29YVD3bGJZM= =5WN9 -----END PGP SIGNATURE----- Merge tag 'usb-for-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next Felipe writes: usb: patches for v4.10 merge window One big merge this time with a total of 166 non-merge commits. Most of the work, by far, is on dwc2 this time (68.2%) with dwc3 a far second (22.5%). The remaining 9.3% are scattered on gadget drivers. The most important changes for dwc2 are the peripheral side DMA support implemented by Synopsys folks and support for the new IOT dwc2 compatible core from Synopsys. In dwc3 land we have support for high-bandwidth, high-speed isochronous endpoints and some non-critical fixes for large scatter lists. Apart from these, we have our usual set of cleanups, non-critical fixes, etc.
This commit is contained in:
commit
ae4d814bf1
@ -12,6 +12,7 @@ Required properties:
|
||||
- "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs;
|
||||
- "amlogic,meson8b-usb": The DWC2 USB controller instance in Amlogic Meson8b SoCs;
|
||||
- "amlogic,meson-gxbb-usb": The DWC2 USB controller instance in Amlogic S905 SoCs;
|
||||
- "amcc,dwc-otg": The DWC2 USB controller instance in AMCC Canyonlands 460EX SoCs;
|
||||
- snps,dwc2: A generic DWC2 USB controller with default parameters.
|
||||
- reg : Should contain 1 register range (address and length)
|
||||
- interrupts : Should contain 1 interrupt
|
||||
@ -25,11 +26,13 @@ Optional properties:
|
||||
Refer to phy/phy-bindings.txt for generic phy consumer properties
|
||||
- dr_mode: shall be one of "host", "peripheral" and "otg"
|
||||
Refer to usb/generic.txt
|
||||
- g-use-dma: enable dma usage in gadget driver.
|
||||
- g-rx-fifo-size: size of rx fifo size in gadget mode.
|
||||
- g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode.
|
||||
- g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode.
|
||||
|
||||
Deprecated properties:
|
||||
- g-use-dma: gadget DMA mode is automatically detected
|
||||
|
||||
Example:
|
||||
|
||||
usb@101c0000 {
|
||||
|
@ -204,7 +204,6 @@
|
||||
g-np-tx-fifo-size = <16>;
|
||||
g-rx-fifo-size = <275>;
|
||||
g-tx-fifo-size = <256 128 128 64 64 32>;
|
||||
g-use-dma;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -596,7 +596,6 @@
|
||||
g-np-tx-fifo-size = <16>;
|
||||
g-rx-fifo-size = <275>;
|
||||
g-tx-fifo-size = <256 128 128 64 64 32>;
|
||||
g-use-dma;
|
||||
phys = <&usbphy0>;
|
||||
phy-names = "usb2-phy";
|
||||
status = "disabled";
|
||||
|
@ -181,7 +181,6 @@
|
||||
g-np-tx-fifo-size = <16>;
|
||||
g-rx-fifo-size = <275>;
|
||||
g-tx-fifo-size = <256 128 128 64 64 32>;
|
||||
g-use-dma;
|
||||
phys = <&usbphy0>;
|
||||
phy-names = "usb2-phy";
|
||||
status = "disabled";
|
||||
|
@ -747,7 +747,6 @@
|
||||
clocks = <&sys_ctrl HI6220_USBOTG_HCLK>;
|
||||
clock-names = "otg";
|
||||
dr_mode = "otg";
|
||||
g-use-dma;
|
||||
g-rx-fifo-size = <512>;
|
||||
g-np-tx-fifo-size = <128>;
|
||||
g-tx-fifo-size = <128 128 128 128 128 128>;
|
||||
|
@ -537,7 +537,6 @@
|
||||
g-np-tx-fifo-size = <16>;
|
||||
g-rx-fifo-size = <275>;
|
||||
g-tx-fifo-size = <256 128 128 64 64 32>;
|
||||
g-use-dma;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -71,6 +71,7 @@ static int usbtv_probe(struct usb_interface *intf,
|
||||
int size;
|
||||
struct device *dev = &intf->dev;
|
||||
struct usbtv *usbtv;
|
||||
struct usb_host_endpoint *ep;
|
||||
|
||||
/* Checks that the device is what we think it is. */
|
||||
if (intf->num_altsetting != 2)
|
||||
@ -78,10 +79,12 @@ static int usbtv_probe(struct usb_interface *intf,
|
||||
if (intf->altsetting[1].desc.bNumEndpoints != 4)
|
||||
return -ENODEV;
|
||||
|
||||
ep = &intf->altsetting[1].endpoint[0];
|
||||
|
||||
/* Packet size is split into 11 bits of base size and count of
|
||||
* extra multiplies of it.*/
|
||||
size = usb_endpoint_maxp(&intf->altsetting[1].endpoint[0].desc);
|
||||
size = (size & 0x07ff) * (((size & 0x1800) >> 11) + 1);
|
||||
size = usb_endpoint_maxp(&ep->desc);
|
||||
size = (size & 0x07ff) * usb_endpoint_maxp_mult(&ep->desc);
|
||||
|
||||
/* Device structure */
|
||||
usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL);
|
||||
|
@ -1467,6 +1467,7 @@ static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
u16 psize;
|
||||
u16 mult;
|
||||
|
||||
switch (dev->speed) {
|
||||
case USB_SPEED_SUPER:
|
||||
@ -1474,7 +1475,8 @@ static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
|
||||
return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
|
||||
case USB_SPEED_HIGH:
|
||||
psize = usb_endpoint_maxp(&ep->desc);
|
||||
return (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
|
||||
mult = usb_endpoint_maxp_mult(&ep->desc);
|
||||
return (psize & 0x07ff) * mult;
|
||||
case USB_SPEED_WIRELESS:
|
||||
psize = usb_endpoint_maxp(&ep->desc);
|
||||
return psize;
|
||||
@ -1551,7 +1553,7 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream,
|
||||
u16 psize;
|
||||
u32 size;
|
||||
|
||||
psize = usb_endpoint_maxp(&ep->desc) & 0x7ff;
|
||||
psize = usb_endpoint_maxp(&ep->desc);
|
||||
size = stream->ctrl.dwMaxPayloadTransferSize;
|
||||
stream->bulk.max_payload_size = size;
|
||||
|
||||
|
@ -821,7 +821,7 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req,
|
||||
}
|
||||
|
||||
if (usb_endpoint_xfer_isoc(hwep->ep.desc) &&
|
||||
hwreq->req.length > (1 + hwep->ep.mult) * hwep->ep.maxpacket) {
|
||||
hwreq->req.length > hwep->ep.mult * hwep->ep.maxpacket) {
|
||||
dev_err(hwep->ci->dev, "request length too big for isochronous\n");
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
@ -1253,8 +1253,8 @@ static int ep_enable(struct usb_ep *ep,
|
||||
hwep->num = usb_endpoint_num(desc);
|
||||
hwep->type = usb_endpoint_type(desc);
|
||||
|
||||
hwep->ep.maxpacket = usb_endpoint_maxp(desc) & 0x07ff;
|
||||
hwep->ep.mult = QH_ISO_MULT(usb_endpoint_maxp(desc));
|
||||
hwep->ep.maxpacket = usb_endpoint_maxp(desc);
|
||||
hwep->ep.mult = usb_endpoint_maxp_mult(desc);
|
||||
|
||||
if (hwep->type == USB_ENDPOINT_XFER_CONTROL)
|
||||
cap |= QH_IOS;
|
||||
|
@ -182,14 +182,8 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
|
||||
|
||||
dir = usb_endpoint_dir_in(desc) ? 'I' : 'O';
|
||||
|
||||
if (speed == USB_SPEED_HIGH) {
|
||||
switch (usb_endpoint_maxp(desc) & (0x03 << 11)) {
|
||||
case 1 << 11:
|
||||
bandwidth = 2; break;
|
||||
case 2 << 11:
|
||||
bandwidth = 3; break;
|
||||
}
|
||||
}
|
||||
if (speed == USB_SPEED_HIGH)
|
||||
bandwidth = usb_endpoint_maxp_mult(desc);
|
||||
|
||||
/* this isn't checking for illegal values */
|
||||
switch (usb_endpoint_type(desc)) {
|
||||
@ -233,7 +227,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
|
||||
|
||||
start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
|
||||
desc->bmAttributes, type,
|
||||
(usb_endpoint_maxp(desc) & 0x07ff) *
|
||||
usb_endpoint_maxp(desc) *
|
||||
bandwidth,
|
||||
interval, unit);
|
||||
return start;
|
||||
|
@ -52,8 +52,7 @@ static ssize_t wMaxPacketSize_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ep_device *ep = to_ep_device(dev);
|
||||
return sprintf(buf, "%04x\n",
|
||||
usb_endpoint_maxp(ep->desc) & 0x07ff);
|
||||
return sprintf(buf, "%04x\n", usb_endpoint_maxp(ep->desc));
|
||||
}
|
||||
static DEVICE_ATTR_RO(wMaxPacketSize);
|
||||
|
||||
|
@ -412,11 +412,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
||||
}
|
||||
|
||||
/* "high bandwidth" mode, 1-3 packets/uframe? */
|
||||
if (dev->speed == USB_SPEED_HIGH) {
|
||||
int mult = 1 + ((max >> 11) & 0x03);
|
||||
max &= 0x07ff;
|
||||
max *= mult;
|
||||
}
|
||||
if (dev->speed == USB_SPEED_HIGH)
|
||||
max *= usb_endpoint_maxp_mult(&ep->desc);
|
||||
|
||||
if (urb->number_of_packets <= 0)
|
||||
return -EINVAL;
|
||||
|
@ -3,6 +3,7 @@ ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG
|
||||
|
||||
obj-$(CONFIG_USB_DWC2) += dwc2.o
|
||||
dwc2-y := core.o core_intr.o platform.o
|
||||
dwc2-y += params.o
|
||||
|
||||
ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),)
|
||||
dwc2-y += hcd.o hcd_intr.o
|
||||
|
@ -135,7 +135,7 @@ int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore)
|
||||
u32 pcgcctl;
|
||||
int ret = 0;
|
||||
|
||||
if (!hsotg->core_params->hibernation)
|
||||
if (!hsotg->params.hibernation)
|
||||
return -ENOTSUPP;
|
||||
|
||||
pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
|
||||
@ -188,7 +188,7 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg)
|
||||
u32 pcgcctl;
|
||||
int ret = 0;
|
||||
|
||||
if (!hsotg->core_params->hibernation)
|
||||
if (!hsotg->params.hibernation)
|
||||
return -ENOTSUPP;
|
||||
|
||||
/* Backup all registers */
|
||||
@ -445,7 +445,7 @@ static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host)
|
||||
* the force mode. We only need to call this once during probe if
|
||||
* dr_mode == OTG.
|
||||
*/
|
||||
static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
|
||||
void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
u32 gusbcfg;
|
||||
|
||||
@ -541,7 +541,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
|
||||
addr = hsotg->regs + HAINTMSK;
|
||||
dev_dbg(hsotg->dev, "HAINTMSK @0x%08lX : 0x%08X\n",
|
||||
(unsigned long)addr, dwc2_readl(addr));
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
addr = hsotg->regs + HFLBADDR;
|
||||
dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n",
|
||||
(unsigned long)addr, dwc2_readl(addr));
|
||||
@ -551,7 +551,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "HPRT0 @0x%08lX : 0x%08X\n",
|
||||
(unsigned long)addr, dwc2_readl(addr));
|
||||
|
||||
for (i = 0; i < hsotg->core_params->host_channels; i++) {
|
||||
for (i = 0; i < hsotg->params.host_channels; i++) {
|
||||
dev_dbg(hsotg->dev, "Host Channel %d Specific Registers\n", i);
|
||||
addr = hsotg->regs + HCCHAR(i);
|
||||
dev_dbg(hsotg->dev, "HCCHAR @0x%08lX : 0x%08X\n",
|
||||
@ -571,7 +571,7 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
|
||||
addr = hsotg->regs + HCDMA(i);
|
||||
dev_dbg(hsotg->dev, "HCDMA @0x%08lX : 0x%08X\n",
|
||||
(unsigned long)addr, dwc2_readl(addr));
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
addr = hsotg->regs + HCDMAB(i);
|
||||
dev_dbg(hsotg->dev, "HCDMAB @0x%08lX : 0x%08X\n",
|
||||
(unsigned long)addr, dwc2_readl(addr));
|
||||
@ -735,704 +735,13 @@ void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg)
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
#define DWC2_OUT_OF_BOUNDS(a, b, c) ((a) < (b) || (a) > (c))
|
||||
|
||||
/* Parameter access functions */
|
||||
void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
switch (val) {
|
||||
case DWC2_CAP_PARAM_HNP_SRP_CAPABLE:
|
||||
if (hsotg->hw_params.op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE)
|
||||
valid = 0;
|
||||
break;
|
||||
case DWC2_CAP_PARAM_SRP_ONLY_CAPABLE:
|
||||
switch (hsotg->hw_params.op_mode) {
|
||||
case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
|
||||
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
|
||||
case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
|
||||
case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
|
||||
break;
|
||||
default:
|
||||
valid = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE:
|
||||
/* always valid */
|
||||
break;
|
||||
default:
|
||||
valid = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for otg_cap parameter. Check HW configuration.\n",
|
||||
val);
|
||||
switch (hsotg->hw_params.op_mode) {
|
||||
case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
|
||||
val = DWC2_CAP_PARAM_HNP_SRP_CAPABLE;
|
||||
break;
|
||||
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
|
||||
case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
|
||||
case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
|
||||
val = DWC2_CAP_PARAM_SRP_ONLY_CAPABLE;
|
||||
break;
|
||||
default:
|
||||
val = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
|
||||
break;
|
||||
}
|
||||
dev_dbg(hsotg->dev, "Setting otg_cap to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->otg_cap = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val > 0 && hsotg->hw_params.arch == GHWCFG2_SLAVE_ONLY_ARCH)
|
||||
valid = 0;
|
||||
if (val < 0)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for dma_enable parameter. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.arch != GHWCFG2_SLAVE_ONLY_ARCH;
|
||||
dev_dbg(hsotg->dev, "Setting dma_enable to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->dma_enable = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val > 0 && (hsotg->core_params->dma_enable <= 0 ||
|
||||
!hsotg->hw_params.dma_desc_enable))
|
||||
valid = 0;
|
||||
if (val < 0)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for dma_desc_enable parameter. Check HW configuration.\n",
|
||||
val);
|
||||
val = (hsotg->core_params->dma_enable > 0 &&
|
||||
hsotg->hw_params.dma_desc_enable);
|
||||
dev_dbg(hsotg->dev, "Setting dma_desc_enable to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->dma_desc_enable = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_dma_desc_fs_enable(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val > 0 && (hsotg->core_params->dma_enable <= 0 ||
|
||||
!hsotg->hw_params.dma_desc_enable))
|
||||
valid = 0;
|
||||
if (val < 0)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for dma_desc_fs_enable parameter. Check HW configuration.\n",
|
||||
val);
|
||||
val = (hsotg->core_params->dma_enable > 0 &&
|
||||
hsotg->hw_params.dma_desc_enable);
|
||||
}
|
||||
|
||||
hsotg->core_params->dma_desc_fs_enable = val;
|
||||
dev_dbg(hsotg->dev, "Setting dma_desc_fs_enable to %d\n", val);
|
||||
}
|
||||
|
||||
void dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
|
||||
int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"Wrong value for host_support_fs_low_power\n");
|
||||
dev_err(hsotg->dev,
|
||||
"host_support_fs_low_power must be 0 or 1\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev,
|
||||
"Setting host_support_fs_low_power to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->host_support_fs_ls_low_power = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val > 0 && !hsotg->hw_params.enable_dynamic_fifo)
|
||||
valid = 0;
|
||||
if (val < 0)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for enable_dynamic_fifo parameter. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.enable_dynamic_fifo;
|
||||
dev_dbg(hsotg->dev, "Setting enable_dynamic_fifo to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->enable_dynamic_fifo = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val < 16 || val > hsotg->hw_params.host_rx_fifo_size)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for host_rx_fifo_size. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.host_rx_fifo_size;
|
||||
dev_dbg(hsotg->dev, "Setting host_rx_fifo_size to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->host_rx_fifo_size = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val < 16 || val > hsotg->hw_params.host_nperio_tx_fifo_size)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.host_nperio_tx_fifo_size;
|
||||
dev_dbg(hsotg->dev, "Setting host_nperio_tx_fifo_size to %d\n",
|
||||
val);
|
||||
}
|
||||
|
||||
hsotg->core_params->host_nperio_tx_fifo_size = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val < 16 || val > hsotg->hw_params.host_perio_tx_fifo_size)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.host_perio_tx_fifo_size;
|
||||
dev_dbg(hsotg->dev, "Setting host_perio_tx_fifo_size to %d\n",
|
||||
val);
|
||||
}
|
||||
|
||||
hsotg->core_params->host_perio_tx_fifo_size = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val < 2047 || val > hsotg->hw_params.max_transfer_size)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for max_transfer_size. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.max_transfer_size;
|
||||
dev_dbg(hsotg->dev, "Setting max_transfer_size to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->max_transfer_size = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val < 15 || val > hsotg->hw_params.max_packet_count)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for max_packet_count. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.max_packet_count;
|
||||
dev_dbg(hsotg->dev, "Setting max_packet_count to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->max_packet_count = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (val < 1 || val > hsotg->hw_params.host_channels)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for host_channels. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.host_channels;
|
||||
dev_dbg(hsotg->dev, "Setting host_channels to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->host_channels = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 0;
|
||||
u32 hs_phy_type, fs_phy_type;
|
||||
|
||||
if (DWC2_OUT_OF_BOUNDS(val, DWC2_PHY_TYPE_PARAM_FS,
|
||||
DWC2_PHY_TYPE_PARAM_ULPI)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev, "Wrong value for phy_type\n");
|
||||
dev_err(hsotg->dev, "phy_type must be 0, 1 or 2\n");
|
||||
}
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
hs_phy_type = hsotg->hw_params.hs_phy_type;
|
||||
fs_phy_type = hsotg->hw_params.fs_phy_type;
|
||||
if (val == DWC2_PHY_TYPE_PARAM_UTMI &&
|
||||
(hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ||
|
||||
hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI))
|
||||
valid = 1;
|
||||
else if (val == DWC2_PHY_TYPE_PARAM_ULPI &&
|
||||
(hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI ||
|
||||
hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI))
|
||||
valid = 1;
|
||||
else if (val == DWC2_PHY_TYPE_PARAM_FS &&
|
||||
fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED)
|
||||
valid = 1;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for phy_type. Check HW configuration.\n",
|
||||
val);
|
||||
val = DWC2_PHY_TYPE_PARAM_FS;
|
||||
if (hs_phy_type != GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED) {
|
||||
if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ||
|
||||
hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI)
|
||||
val = DWC2_PHY_TYPE_PARAM_UTMI;
|
||||
else
|
||||
val = DWC2_PHY_TYPE_PARAM_ULPI;
|
||||
}
|
||||
dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->phy_type = val;
|
||||
}
|
||||
|
||||
static int dwc2_get_param_phy_type(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
return hsotg->core_params->phy_type;
|
||||
}
|
||||
|
||||
void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev, "Wrong value for speed parameter\n");
|
||||
dev_err(hsotg->dev, "max_speed parameter must be 0 or 1\n");
|
||||
}
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
if (val == DWC2_SPEED_PARAM_HIGH &&
|
||||
dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for speed parameter. Check HW configuration.\n",
|
||||
val);
|
||||
val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS ?
|
||||
DWC2_SPEED_PARAM_FULL : DWC2_SPEED_PARAM_HIGH;
|
||||
dev_dbg(hsotg->dev, "Setting speed to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->speed = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (DWC2_OUT_OF_BOUNDS(val, DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ,
|
||||
DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"Wrong value for host_ls_low_power_phy_clk parameter\n");
|
||||
dev_err(hsotg->dev,
|
||||
"host_ls_low_power_phy_clk must be 0 or 1\n");
|
||||
}
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
if (val == DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ &&
|
||||
dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
|
||||
val);
|
||||
val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS
|
||||
? DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ
|
||||
: DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
|
||||
dev_dbg(hsotg->dev, "Setting host_ls_low_power_phy_clk to %d\n",
|
||||
val);
|
||||
}
|
||||
|
||||
hsotg->core_params->host_ls_low_power_phy_clk = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev, "Wrong value for phy_ulpi_ddr\n");
|
||||
dev_err(hsotg->dev, "phy_upli_ddr must be 0 or 1\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev, "Setting phy_upli_ddr to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->phy_ulpi_ddr = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"Wrong value for phy_ulpi_ext_vbus\n");
|
||||
dev_err(hsotg->dev,
|
||||
"phy_ulpi_ext_vbus must be 0 or 1\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev, "Setting phy_ulpi_ext_vbus to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->phy_ulpi_ext_vbus = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 0;
|
||||
|
||||
switch (hsotg->hw_params.utmi_phy_data_width) {
|
||||
case GHWCFG4_UTMI_PHY_DATA_WIDTH_8:
|
||||
valid = (val == 8);
|
||||
break;
|
||||
case GHWCFG4_UTMI_PHY_DATA_WIDTH_16:
|
||||
valid = (val == 16);
|
||||
break;
|
||||
case GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16:
|
||||
valid = (val == 8 || val == 16);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for phy_utmi_width. Check HW configuration.\n",
|
||||
val);
|
||||
}
|
||||
val = (hsotg->hw_params.utmi_phy_data_width ==
|
||||
GHWCFG4_UTMI_PHY_DATA_WIDTH_8) ? 8 : 16;
|
||||
dev_dbg(hsotg->dev, "Setting phy_utmi_width to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->phy_utmi_width = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev, "Wrong value for ulpi_fs_ls\n");
|
||||
dev_err(hsotg->dev, "ulpi_fs_ls must be 0 or 1\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev, "Setting ulpi_fs_ls to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->ulpi_fs_ls = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev, "Wrong value for ts_dline\n");
|
||||
dev_err(hsotg->dev, "ts_dline must be 0 or 1\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev, "Setting ts_dline to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->ts_dline = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev, "Wrong value for i2c_enable\n");
|
||||
dev_err(hsotg->dev, "i2c_enable must be 0 or 1\n");
|
||||
}
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
if (val == 1 && !(hsotg->hw_params.i2c_enable))
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for i2c_enable. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.i2c_enable;
|
||||
dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->i2c_enable = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"Wrong value for en_multiple_tx_fifo,\n");
|
||||
dev_err(hsotg->dev,
|
||||
"en_multiple_tx_fifo must be 0 or 1\n");
|
||||
}
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
if (val == 1 && !hsotg->hw_params.en_multiple_tx_fifo)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.en_multiple_tx_fifo;
|
||||
dev_dbg(hsotg->dev, "Setting en_multiple_tx_fifo to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->en_multiple_tx_fifo = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
int valid = 1;
|
||||
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"'%d' invalid for parameter reload_ctl\n", val);
|
||||
dev_err(hsotg->dev, "reload_ctl must be 0 or 1\n");
|
||||
}
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
if (val == 1 && hsotg->hw_params.snpsid < DWC2_CORE_REV_2_92a)
|
||||
valid = 0;
|
||||
|
||||
if (!valid) {
|
||||
if (val >= 0)
|
||||
dev_err(hsotg->dev,
|
||||
"%d invalid for parameter reload_ctl. Check HW configuration.\n",
|
||||
val);
|
||||
val = hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_92a;
|
||||
dev_dbg(hsotg->dev, "Setting reload_ctl to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->reload_ctl = val;
|
||||
}
|
||||
|
||||
void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
if (val != -1)
|
||||
hsotg->core_params->ahbcfg = val;
|
||||
else
|
||||
hsotg->core_params->ahbcfg = GAHBCFG_HBSTLEN_INCR4 <<
|
||||
GAHBCFG_HBSTLEN_SHIFT;
|
||||
}
|
||||
|
||||
void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"'%d' invalid for parameter otg_ver\n", val);
|
||||
dev_err(hsotg->dev,
|
||||
"otg_ver must be 0 (for OTG 1.3 support) or 1 (for OTG 2.0 support)\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev, "Setting otg_ver to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->otg_ver = val;
|
||||
}
|
||||
|
||||
static void dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"'%d' invalid for parameter uframe_sched\n",
|
||||
val);
|
||||
dev_err(hsotg->dev, "uframe_sched must be 0 or 1\n");
|
||||
}
|
||||
val = 1;
|
||||
dev_dbg(hsotg->dev, "Setting uframe_sched to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->uframe_sched = val;
|
||||
}
|
||||
|
||||
static void dwc2_set_param_external_id_pin_ctl(struct dwc2_hsotg *hsotg,
|
||||
int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"'%d' invalid for parameter external_id_pin_ctl\n",
|
||||
val);
|
||||
dev_err(hsotg->dev, "external_id_pin_ctl must be 0 or 1\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev, "Setting external_id_pin_ctl to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->external_id_pin_ctl = val;
|
||||
}
|
||||
|
||||
static void dwc2_set_param_hibernation(struct dwc2_hsotg *hsotg,
|
||||
int val)
|
||||
{
|
||||
if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
|
||||
if (val >= 0) {
|
||||
dev_err(hsotg->dev,
|
||||
"'%d' invalid for parameter hibernation\n",
|
||||
val);
|
||||
dev_err(hsotg->dev, "hibernation must be 0 or 1\n");
|
||||
}
|
||||
val = 0;
|
||||
dev_dbg(hsotg->dev, "Setting hibernation to %d\n", val);
|
||||
}
|
||||
|
||||
hsotg->core_params->hibernation = val;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called during module intialization to pass module parameters
|
||||
* for the DWC_otg core.
|
||||
*/
|
||||
void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
|
||||
const struct dwc2_core_params *params)
|
||||
{
|
||||
dev_dbg(hsotg->dev, "%s()\n", __func__);
|
||||
|
||||
dwc2_set_param_otg_cap(hsotg, params->otg_cap);
|
||||
dwc2_set_param_dma_enable(hsotg, params->dma_enable);
|
||||
dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable);
|
||||
dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable);
|
||||
dwc2_set_param_host_support_fs_ls_low_power(hsotg,
|
||||
params->host_support_fs_ls_low_power);
|
||||
dwc2_set_param_enable_dynamic_fifo(hsotg,
|
||||
params->enable_dynamic_fifo);
|
||||
dwc2_set_param_host_rx_fifo_size(hsotg,
|
||||
params->host_rx_fifo_size);
|
||||
dwc2_set_param_host_nperio_tx_fifo_size(hsotg,
|
||||
params->host_nperio_tx_fifo_size);
|
||||
dwc2_set_param_host_perio_tx_fifo_size(hsotg,
|
||||
params->host_perio_tx_fifo_size);
|
||||
dwc2_set_param_max_transfer_size(hsotg,
|
||||
params->max_transfer_size);
|
||||
dwc2_set_param_max_packet_count(hsotg,
|
||||
params->max_packet_count);
|
||||
dwc2_set_param_host_channels(hsotg, params->host_channels);
|
||||
dwc2_set_param_phy_type(hsotg, params->phy_type);
|
||||
dwc2_set_param_speed(hsotg, params->speed);
|
||||
dwc2_set_param_host_ls_low_power_phy_clk(hsotg,
|
||||
params->host_ls_low_power_phy_clk);
|
||||
dwc2_set_param_phy_ulpi_ddr(hsotg, params->phy_ulpi_ddr);
|
||||
dwc2_set_param_phy_ulpi_ext_vbus(hsotg,
|
||||
params->phy_ulpi_ext_vbus);
|
||||
dwc2_set_param_phy_utmi_width(hsotg, params->phy_utmi_width);
|
||||
dwc2_set_param_ulpi_fs_ls(hsotg, params->ulpi_fs_ls);
|
||||
dwc2_set_param_ts_dline(hsotg, params->ts_dline);
|
||||
dwc2_set_param_i2c_enable(hsotg, params->i2c_enable);
|
||||
dwc2_set_param_en_multiple_tx_fifo(hsotg,
|
||||
params->en_multiple_tx_fifo);
|
||||
dwc2_set_param_reload_ctl(hsotg, params->reload_ctl);
|
||||
dwc2_set_param_ahbcfg(hsotg, params->ahbcfg);
|
||||
dwc2_set_param_otg_ver(hsotg, params->otg_ver);
|
||||
dwc2_set_param_uframe_sched(hsotg, params->uframe_sched);
|
||||
dwc2_set_param_external_id_pin_ctl(hsotg, params->external_id_pin_ctl);
|
||||
dwc2_set_param_hibernation(hsotg, params->hibernation);
|
||||
}
|
||||
|
||||
/*
|
||||
* Forces either host or device mode if the controller is not
|
||||
* currently in that mode.
|
||||
*
|
||||
* Returns true if the mode was forced.
|
||||
*/
|
||||
static bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host)
|
||||
bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host)
|
||||
{
|
||||
if (host && dwc2_is_host_mode(hsotg))
|
||||
return false;
|
||||
@ -1442,232 +751,9 @@ static bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host)
|
||||
return dwc2_force_mode(hsotg, host);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets host hardware parameters. Forces host mode if not currently in
|
||||
* host mode. Should be called immediately after a core soft reset in
|
||||
* order to get the reset values.
|
||||
*/
|
||||
static void dwc2_get_host_hwparams(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct dwc2_hw_params *hw = &hsotg->hw_params;
|
||||
u32 gnptxfsiz;
|
||||
u32 hptxfsiz;
|
||||
bool forced;
|
||||
|
||||
if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
|
||||
return;
|
||||
|
||||
forced = dwc2_force_mode_if_needed(hsotg, true);
|
||||
|
||||
gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
|
||||
hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
|
||||
dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
|
||||
dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
|
||||
|
||||
if (forced)
|
||||
dwc2_clear_force_mode(hsotg);
|
||||
|
||||
hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
|
||||
FIFOSIZE_DEPTH_SHIFT;
|
||||
hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >>
|
||||
FIFOSIZE_DEPTH_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets device hardware parameters. Forces device mode if not
|
||||
* currently in device mode. Should be called immediately after a core
|
||||
* soft reset in order to get the reset values.
|
||||
*/
|
||||
static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct dwc2_hw_params *hw = &hsotg->hw_params;
|
||||
bool forced;
|
||||
u32 gnptxfsiz;
|
||||
|
||||
if (hsotg->dr_mode == USB_DR_MODE_HOST)
|
||||
return;
|
||||
|
||||
forced = dwc2_force_mode_if_needed(hsotg, false);
|
||||
|
||||
gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
|
||||
dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
|
||||
|
||||
if (forced)
|
||||
dwc2_clear_force_mode(hsotg);
|
||||
|
||||
hw->dev_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
|
||||
FIFOSIZE_DEPTH_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* During device initialization, read various hardware configuration
|
||||
* registers and interpret the contents.
|
||||
*/
|
||||
int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct dwc2_hw_params *hw = &hsotg->hw_params;
|
||||
unsigned width;
|
||||
u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4;
|
||||
u32 grxfsiz;
|
||||
|
||||
/*
|
||||
* Attempt to ensure this device is really a DWC_otg Controller.
|
||||
* Read and verify the GSNPSID register contents. The value should be
|
||||
* 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3",
|
||||
* as in "OTG version 2.xx" or "OTG version 3.xx".
|
||||
*/
|
||||
hw->snpsid = dwc2_readl(hsotg->regs + GSNPSID);
|
||||
if ((hw->snpsid & 0xfffff000) != 0x4f542000 &&
|
||||
(hw->snpsid & 0xfffff000) != 0x4f543000) {
|
||||
dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n",
|
||||
hw->snpsid);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x (snpsid=%x)\n",
|
||||
hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf,
|
||||
hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid);
|
||||
|
||||
hwcfg1 = dwc2_readl(hsotg->regs + GHWCFG1);
|
||||
hwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2);
|
||||
hwcfg3 = dwc2_readl(hsotg->regs + GHWCFG3);
|
||||
hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
|
||||
grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
|
||||
|
||||
dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1);
|
||||
dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2);
|
||||
dev_dbg(hsotg->dev, "hwcfg3=%08x\n", hwcfg3);
|
||||
dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4);
|
||||
dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz);
|
||||
|
||||
/*
|
||||
* Host specific hardware parameters. Reading these parameters
|
||||
* requires the controller to be in host mode. The mode will
|
||||
* be forced, if necessary, to read these values.
|
||||
*/
|
||||
dwc2_get_host_hwparams(hsotg);
|
||||
dwc2_get_dev_hwparams(hsotg);
|
||||
|
||||
/* hwcfg1 */
|
||||
hw->dev_ep_dirs = hwcfg1;
|
||||
|
||||
/* hwcfg2 */
|
||||
hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
|
||||
GHWCFG2_OP_MODE_SHIFT;
|
||||
hw->arch = (hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >>
|
||||
GHWCFG2_ARCHITECTURE_SHIFT;
|
||||
hw->enable_dynamic_fifo = !!(hwcfg2 & GHWCFG2_DYNAMIC_FIFO);
|
||||
hw->host_channels = 1 + ((hwcfg2 & GHWCFG2_NUM_HOST_CHAN_MASK) >>
|
||||
GHWCFG2_NUM_HOST_CHAN_SHIFT);
|
||||
hw->hs_phy_type = (hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >>
|
||||
GHWCFG2_HS_PHY_TYPE_SHIFT;
|
||||
hw->fs_phy_type = (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >>
|
||||
GHWCFG2_FS_PHY_TYPE_SHIFT;
|
||||
hw->num_dev_ep = (hwcfg2 & GHWCFG2_NUM_DEV_EP_MASK) >>
|
||||
GHWCFG2_NUM_DEV_EP_SHIFT;
|
||||
hw->nperio_tx_q_depth =
|
||||
(hwcfg2 & GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK) >>
|
||||
GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT << 1;
|
||||
hw->host_perio_tx_q_depth =
|
||||
(hwcfg2 & GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK) >>
|
||||
GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT << 1;
|
||||
hw->dev_token_q_depth =
|
||||
(hwcfg2 & GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK) >>
|
||||
GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT;
|
||||
|
||||
/* hwcfg3 */
|
||||
width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >>
|
||||
GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT;
|
||||
hw->max_transfer_size = (1 << (width + 11)) - 1;
|
||||
width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >>
|
||||
GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT;
|
||||
hw->max_packet_count = (1 << (width + 4)) - 1;
|
||||
hw->i2c_enable = !!(hwcfg3 & GHWCFG3_I2C);
|
||||
hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH_MASK) >>
|
||||
GHWCFG3_DFIFO_DEPTH_SHIFT;
|
||||
|
||||
/* hwcfg4 */
|
||||
hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
|
||||
hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
|
||||
GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
|
||||
hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
|
||||
hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
|
||||
hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
|
||||
GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
|
||||
|
||||
/* fifo sizes */
|
||||
hw->host_rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
|
||||
GRXFSIZ_DEPTH_SHIFT;
|
||||
|
||||
dev_dbg(hsotg->dev, "Detected values from hardware:\n");
|
||||
dev_dbg(hsotg->dev, " op_mode=%d\n",
|
||||
hw->op_mode);
|
||||
dev_dbg(hsotg->dev, " arch=%d\n",
|
||||
hw->arch);
|
||||
dev_dbg(hsotg->dev, " dma_desc_enable=%d\n",
|
||||
hw->dma_desc_enable);
|
||||
dev_dbg(hsotg->dev, " power_optimized=%d\n",
|
||||
hw->power_optimized);
|
||||
dev_dbg(hsotg->dev, " i2c_enable=%d\n",
|
||||
hw->i2c_enable);
|
||||
dev_dbg(hsotg->dev, " hs_phy_type=%d\n",
|
||||
hw->hs_phy_type);
|
||||
dev_dbg(hsotg->dev, " fs_phy_type=%d\n",
|
||||
hw->fs_phy_type);
|
||||
dev_dbg(hsotg->dev, " utmi_phy_data_width=%d\n",
|
||||
hw->utmi_phy_data_width);
|
||||
dev_dbg(hsotg->dev, " num_dev_ep=%d\n",
|
||||
hw->num_dev_ep);
|
||||
dev_dbg(hsotg->dev, " num_dev_perio_in_ep=%d\n",
|
||||
hw->num_dev_perio_in_ep);
|
||||
dev_dbg(hsotg->dev, " host_channels=%d\n",
|
||||
hw->host_channels);
|
||||
dev_dbg(hsotg->dev, " max_transfer_size=%d\n",
|
||||
hw->max_transfer_size);
|
||||
dev_dbg(hsotg->dev, " max_packet_count=%d\n",
|
||||
hw->max_packet_count);
|
||||
dev_dbg(hsotg->dev, " nperio_tx_q_depth=0x%0x\n",
|
||||
hw->nperio_tx_q_depth);
|
||||
dev_dbg(hsotg->dev, " host_perio_tx_q_depth=0x%0x\n",
|
||||
hw->host_perio_tx_q_depth);
|
||||
dev_dbg(hsotg->dev, " dev_token_q_depth=0x%0x\n",
|
||||
hw->dev_token_q_depth);
|
||||
dev_dbg(hsotg->dev, " enable_dynamic_fifo=%d\n",
|
||||
hw->enable_dynamic_fifo);
|
||||
dev_dbg(hsotg->dev, " en_multiple_tx_fifo=%d\n",
|
||||
hw->en_multiple_tx_fifo);
|
||||
dev_dbg(hsotg->dev, " total_fifo_size=%d\n",
|
||||
hw->total_fifo_size);
|
||||
dev_dbg(hsotg->dev, " host_rx_fifo_size=%d\n",
|
||||
hw->host_rx_fifo_size);
|
||||
dev_dbg(hsotg->dev, " host_nperio_tx_fifo_size=%d\n",
|
||||
hw->host_nperio_tx_fifo_size);
|
||||
dev_dbg(hsotg->dev, " host_perio_tx_fifo_size=%d\n",
|
||||
hw->host_perio_tx_fifo_size);
|
||||
dev_dbg(hsotg->dev, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets all parameters to the given value.
|
||||
*
|
||||
* Assumes that the dwc2_core_params struct contains only integers.
|
||||
*/
|
||||
void dwc2_set_all_params(struct dwc2_core_params *params, int value)
|
||||
{
|
||||
int *p = (int *)params;
|
||||
size_t size = sizeof(*params) / sizeof(*p);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
p[i] = value;
|
||||
}
|
||||
|
||||
|
||||
u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
return hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103;
|
||||
return hsotg->params.otg_ver == 1 ? 0x0200 : 0x0103;
|
||||
}
|
||||
|
||||
bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
|
||||
|
@ -172,6 +172,11 @@ struct dwc2_hsotg_req;
|
||||
* @periodic: Set if this is a periodic ep, such as Interrupt
|
||||
* @isochronous: Set if this is a isochronous ep
|
||||
* @send_zlp: Set if we need to send a zero-length packet.
|
||||
* @desc_list_dma: The DMA address of descriptor chain currently in use.
|
||||
* @desc_list: Pointer to descriptor DMA chain head currently in use.
|
||||
* @desc_count: Count of entries within the DMA descriptor chain of EP.
|
||||
* @isoc_chain_num: Number of ISOC chain currently in use - either 0 or 1.
|
||||
* @next_desc: index of next free descriptor in the ISOC chain under SW control.
|
||||
* @total_data: The total number of data bytes done.
|
||||
* @fifo_size: The size of the FIFO (for periodic IN endpoints)
|
||||
* @fifo_load: The amount of data loaded into the FIFO (periodic IN)
|
||||
@ -219,6 +224,13 @@ struct dwc2_hsotg_ep {
|
||||
#define TARGET_FRAME_INITIAL 0xFFFFFFFF
|
||||
bool frame_overrun;
|
||||
|
||||
dma_addr_t desc_list_dma;
|
||||
struct dwc2_dma_desc *desc_list;
|
||||
u8 desc_count;
|
||||
|
||||
unsigned char isoc_chain_num;
|
||||
unsigned int next_desc;
|
||||
|
||||
char name[10];
|
||||
};
|
||||
|
||||
@ -286,7 +298,7 @@ enum dwc2_ep0_state {
|
||||
* @otg_ver: OTG version supported
|
||||
* 0 - 1.3 (default)
|
||||
* 1 - 2.0
|
||||
* @dma_enable: 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
|
||||
* value for this parameter if none is specified.
|
||||
* 0 - Slave (always available)
|
||||
@ -314,7 +326,8 @@ enum dwc2_ep0_state {
|
||||
* @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters
|
||||
* 1 - Allow dynamic FIFO sizing (default, if available)
|
||||
* @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs
|
||||
* are enabled
|
||||
* are enabled for non-periodic IN endpoints in device
|
||||
* mode.
|
||||
* @host_rx_fifo_size: Number of 4-byte words in the Rx FIFO in host mode when
|
||||
* dynamic FIFO sizing is enabled
|
||||
* 16 to 32768
|
||||
@ -417,6 +430,20 @@ enum dwc2_ep0_state {
|
||||
* needed.
|
||||
* 0 - No (default)
|
||||
* 1 - Yes
|
||||
* @g_dma: Enables gadget dma usage (default: autodetect).
|
||||
* @g_dma_desc: Enables gadget descriptor DMA (default: autodetect).
|
||||
* @g_rx_fifo_size: The periodic rx fifo size for the device, in
|
||||
* DWORDS from 16-32768 (default: 2048 if
|
||||
* possible, otherwise autodetect).
|
||||
* @g_np_tx_fifo_size: The non-periodic tx fifo size for the device in
|
||||
* DWORDS from 16-32768 (default: 1024 if
|
||||
* possible, otherwise autodetect).
|
||||
* @g_tx_fifo_size: An array of TX fifo sizes in dedicated fifo
|
||||
* mode. Each value corresponds to one EP
|
||||
* starting from EP1 (max 15 values). Sizes are
|
||||
* in DWORDS with possible values from from
|
||||
* 16-32768 (default: 256, 256, 256, 256, 768,
|
||||
* 768, 768, 768, 0, 0, 0, 0, 0, 0, 0).
|
||||
*
|
||||
* The following parameters may be specified when starting the module. These
|
||||
* parameters define how the DWC_otg controller should be configured. A
|
||||
@ -430,11 +457,18 @@ struct dwc2_core_params {
|
||||
* dwc2_set_all_params!
|
||||
*/
|
||||
int otg_cap;
|
||||
#define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0
|
||||
#define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1
|
||||
#define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
|
||||
|
||||
int otg_ver;
|
||||
int dma_enable;
|
||||
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;
|
||||
@ -444,19 +478,44 @@ struct dwc2_core_params {
|
||||
int max_packet_count;
|
||||
int host_channels;
|
||||
int phy_type;
|
||||
#define DWC2_PHY_TYPE_PARAM_FS 0
|
||||
#define DWC2_PHY_TYPE_PARAM_UTMI 1
|
||||
#define DWC2_PHY_TYPE_PARAM_ULPI 2
|
||||
|
||||
int phy_utmi_width;
|
||||
int phy_ulpi_ddr;
|
||||
int phy_ulpi_ext_vbus;
|
||||
#define DWC2_PHY_ULPI_INTERNAL_VBUS 0
|
||||
#define DWC2_PHY_ULPI_EXTERNAL_VBUS 1
|
||||
|
||||
int i2c_enable;
|
||||
int ulpi_fs_ls;
|
||||
int host_support_fs_ls_low_power;
|
||||
int host_ls_low_power_phy_clk;
|
||||
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
|
||||
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
|
||||
|
||||
int ts_dline;
|
||||
int reload_ctl;
|
||||
int ahbcfg;
|
||||
int uframe_sched;
|
||||
int external_id_pin_ctl;
|
||||
int hibernation;
|
||||
|
||||
/*
|
||||
* The following parameters are *only* set via device
|
||||
* properties and cannot be set directly in this structure.
|
||||
*/
|
||||
|
||||
/* Host parameters */
|
||||
bool host_dma;
|
||||
|
||||
/* Gadget parameters */
|
||||
bool g_dma;
|
||||
bool g_dma_desc;
|
||||
u16 g_rx_fifo_size;
|
||||
u16 g_np_tx_fifo_size;
|
||||
u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -516,10 +575,9 @@ struct dwc2_hw_params {
|
||||
unsigned op_mode:3;
|
||||
unsigned arch:2;
|
||||
unsigned dma_desc_enable:1;
|
||||
unsigned dma_desc_fs_enable:1;
|
||||
unsigned enable_dynamic_fifo:1;
|
||||
unsigned en_multiple_tx_fifo:1;
|
||||
unsigned host_rx_fifo_size:16;
|
||||
unsigned rx_fifo_size:16;
|
||||
unsigned host_nperio_tx_fifo_size:16;
|
||||
unsigned dev_nperio_tx_fifo_size:16;
|
||||
unsigned host_perio_tx_fifo_size:16;
|
||||
@ -839,11 +897,13 @@ struct dwc2_hregs_backup {
|
||||
* @ctrl_req: Request for EP0 control packets.
|
||||
* @ep0_state: EP0 control transfers state
|
||||
* @test_mode: USB test mode requested by the host
|
||||
* @setup_desc_dma: EP0 setup stage desc chain DMA address
|
||||
* @setup_desc: EP0 setup stage desc chain pointer
|
||||
* @ctrl_in_desc_dma: EP0 IN data phase desc chain DMA address
|
||||
* @ctrl_in_desc: EP0 IN data phase desc chain pointer
|
||||
* @ctrl_out_desc_dma: EP0 OUT data phase desc chain DMA address
|
||||
* @ctrl_out_desc: EP0 OUT data phase desc chain pointer
|
||||
* @eps: The endpoints being supplied to the gadget framework
|
||||
* @g_using_dma: Indicate if dma usage is enabled
|
||||
* @g_rx_fifo_sz: Contains rx fifo size value
|
||||
* @g_np_g_tx_fifo_sz: Contains Non-Periodic tx fifo size value
|
||||
* @g_tx_fifo_sz: Contains tx fifo size value per endpoints
|
||||
*/
|
||||
struct dwc2_hsotg {
|
||||
struct device *dev;
|
||||
@ -851,7 +911,7 @@ struct dwc2_hsotg {
|
||||
/** Params detected from hardware */
|
||||
struct dwc2_hw_params hw_params;
|
||||
/** Params to actually use */
|
||||
struct dwc2_core_params *core_params;
|
||||
struct dwc2_core_params params;
|
||||
enum usb_otg_state op_state;
|
||||
enum usb_dr_mode dr_mode;
|
||||
unsigned int hcd_enabled:1;
|
||||
@ -891,6 +951,8 @@ struct dwc2_hsotg {
|
||||
#define DWC2_CORE_REV_2_94a 0x4f54294a
|
||||
#define DWC2_CORE_REV_3_00a 0x4f54300a
|
||||
#define DWC2_CORE_REV_3_10a 0x4f54310a
|
||||
#define DWC2_FS_IOT_REV_1_00a 0x5531100a
|
||||
#define DWC2_HS_IOT_REV_1_00a 0x5532100a
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||
union dwc2_hcd_internal_flags {
|
||||
@ -986,15 +1048,18 @@ struct dwc2_hsotg {
|
||||
enum dwc2_ep0_state ep0_state;
|
||||
u8 test_mode;
|
||||
|
||||
dma_addr_t setup_desc_dma[2];
|
||||
struct dwc2_dma_desc *setup_desc[2];
|
||||
dma_addr_t ctrl_in_desc_dma;
|
||||
struct dwc2_dma_desc *ctrl_in_desc;
|
||||
dma_addr_t ctrl_out_desc_dma;
|
||||
struct dwc2_dma_desc *ctrl_out_desc;
|
||||
|
||||
struct usb_gadget gadget;
|
||||
unsigned int enabled:1;
|
||||
unsigned int connected:1;
|
||||
struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
|
||||
struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
|
||||
u32 g_using_dma;
|
||||
u32 g_rx_fifo_sz;
|
||||
u32 g_np_g_tx_fifo_sz;
|
||||
u32 g_tx_fifo_sz[MAX_EPS_CHANNELS];
|
||||
#endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
|
||||
};
|
||||
|
||||
@ -1016,6 +1081,22 @@ enum dwc2_halt_status {
|
||||
DWC2_HC_XFER_URB_DEQUEUE,
|
||||
};
|
||||
|
||||
/* Core version information */
|
||||
static inline bool dwc2_is_iot(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
return (hsotg->hw_params.snpsid & 0xfff00000) == 0x55300000;
|
||||
}
|
||||
|
||||
static inline bool dwc2_is_fs_iot(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
return (hsotg->hw_params.snpsid & 0xffff0000) == 0x55310000;
|
||||
}
|
||||
|
||||
static inline bool dwc2_is_hs_iot(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
return (hsotg->hw_params.snpsid & 0xffff0000) == 0x55320000;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following functions support initialization of the core driver component
|
||||
* and the DWC_otg controller
|
||||
@ -1025,6 +1106,8 @@ extern int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg);
|
||||
extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg);
|
||||
extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore);
|
||||
|
||||
bool dwc2_force_mode_if_needed(struct dwc2_hsotg *hsotg, bool host);
|
||||
void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg);
|
||||
void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg);
|
||||
|
||||
extern bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg);
|
||||
@ -1044,217 +1127,16 @@ extern void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd);
|
||||
/* This function should be called on every hardware interrupt. */
|
||||
extern irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
|
||||
|
||||
/* OTG Core Parameters */
|
||||
|
||||
/*
|
||||
* Specifies the OTG capabilities. The driver will automatically
|
||||
* detect the value for this parameter if none is specified.
|
||||
* 0 - HNP and SRP capable (default)
|
||||
* 1 - SRP Only capable
|
||||
* 2 - No HNP/SRP capable
|
||||
*/
|
||||
extern void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val);
|
||||
#define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0
|
||||
#define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1
|
||||
#define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
|
||||
|
||||
/*
|
||||
* Specifies whether to use slave or DMA mode for accessing the data
|
||||
* FIFOs. The driver will automatically detect the value for this
|
||||
* parameter if none is specified.
|
||||
* 0 - Slave
|
||||
* 1 - DMA (default, if available)
|
||||
*/
|
||||
extern void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* When DMA mode is enabled specifies whether to use
|
||||
* address DMA or DMA Descritor mode for accessing the data
|
||||
* FIFOs in device mode. The driver will automatically detect
|
||||
* the value for this parameter if none is specified.
|
||||
* 0 - address DMA
|
||||
* 1 - DMA Descriptor(default, if available)
|
||||
*/
|
||||
extern void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* When DMA mode is enabled specifies whether to use
|
||||
* address DMA or DMA Descritor mode with full speed devices
|
||||
* for accessing the data FIFOs in host mode.
|
||||
* 0 - address DMA
|
||||
* 1 - FS DMA Descriptor(default, if available)
|
||||
*/
|
||||
extern void dwc2_set_param_dma_desc_fs_enable(struct dwc2_hsotg *hsotg,
|
||||
int val);
|
||||
|
||||
/*
|
||||
* Specifies the maximum speed of operation in host and device mode.
|
||||
* The actual speed depends on the speed of the attached device and
|
||||
* the value of phy_type. The actual speed depends on the speed of the
|
||||
* attached device.
|
||||
* 0 - High Speed (default)
|
||||
* 1 - Full Speed
|
||||
*/
|
||||
extern void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val);
|
||||
#define DWC2_SPEED_PARAM_HIGH 0
|
||||
#define DWC2_SPEED_PARAM_FULL 1
|
||||
|
||||
/*
|
||||
* Specifies whether low power mode is supported when attached
|
||||
* to a Full Speed or Low Speed device in host mode.
|
||||
*
|
||||
* 0 - Don't support low power mode (default)
|
||||
* 1 - Support low power mode
|
||||
*/
|
||||
extern void dwc2_set_param_host_support_fs_ls_low_power(
|
||||
struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* Specifies the PHY clock rate in low power mode when connected to a
|
||||
* Low Speed device in host mode. This parameter is applicable only if
|
||||
* HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS
|
||||
* then defaults to 6 MHZ otherwise 48 MHZ.
|
||||
*
|
||||
* 0 - 48 MHz
|
||||
* 1 - 6 MHz
|
||||
*/
|
||||
extern void dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg,
|
||||
int val);
|
||||
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
|
||||
#define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
|
||||
|
||||
/*
|
||||
* 0 - Use cC FIFO size parameters
|
||||
* 1 - Allow dynamic FIFO sizing (default)
|
||||
*/
|
||||
extern void dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg,
|
||||
int val);
|
||||
|
||||
/*
|
||||
* Number of 4-byte words in the Rx FIFO in host mode when dynamic
|
||||
* FIFO sizing is enabled.
|
||||
* 16 to 32768 (default 1024)
|
||||
*/
|
||||
extern void dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* Number of 4-byte words in the non-periodic Tx FIFO in host mode
|
||||
* when Dynamic FIFO sizing is enabled in the core.
|
||||
* 16 to 32768 (default 256)
|
||||
*/
|
||||
extern void dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg,
|
||||
int val);
|
||||
|
||||
/*
|
||||
* Number of 4-byte words in the host periodic Tx FIFO when dynamic
|
||||
* FIFO sizing is enabled.
|
||||
* 16 to 32768 (default 256)
|
||||
*/
|
||||
extern void dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg,
|
||||
int val);
|
||||
|
||||
/*
|
||||
* The maximum transfer size supported in bytes.
|
||||
* 2047 to 65,535 (default 65,535)
|
||||
*/
|
||||
extern void dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* The maximum number of packets in a transfer.
|
||||
* 15 to 511 (default 511)
|
||||
*/
|
||||
extern void dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* The number of host channel registers to use.
|
||||
* 1 to 16 (default 11)
|
||||
* Note: The FPGA configuration supports a maximum of 11 host channels.
|
||||
*/
|
||||
extern void dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* Specifies the type of PHY interface to use. By default, the driver
|
||||
* will automatically detect the phy_type.
|
||||
*
|
||||
* 0 - Full Speed PHY
|
||||
* 1 - UTMI+ (default)
|
||||
* 2 - ULPI
|
||||
*/
|
||||
extern void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val);
|
||||
#define DWC2_PHY_TYPE_PARAM_FS 0
|
||||
#define DWC2_PHY_TYPE_PARAM_UTMI 1
|
||||
#define DWC2_PHY_TYPE_PARAM_ULPI 2
|
||||
|
||||
/*
|
||||
* Specifies the UTMI+ Data Width. This parameter is
|
||||
* applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI
|
||||
* PHY_TYPE, this parameter indicates the data width between
|
||||
* the MAC and the ULPI Wrapper.) Also, this parameter is
|
||||
* applicable only if the OTG_HSPHY_WIDTH cC parameter was set
|
||||
* to "8 and 16 bits", meaning that the core has been
|
||||
* configured to work at either data path width.
|
||||
*
|
||||
* 8 or 16 bits (default 16)
|
||||
*/
|
||||
extern void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* Specifies whether the ULPI operates at double or single
|
||||
* data rate. This parameter is only applicable if PHY_TYPE is
|
||||
* ULPI.
|
||||
*
|
||||
* 0 - single data rate ULPI interface with 8 bit wide data
|
||||
* bus (default)
|
||||
* 1 - double data rate ULPI interface with 4 bit wide data
|
||||
* bus
|
||||
*/
|
||||
extern void dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* Specifies whether to use the internal or external supply to
|
||||
* drive the vbus with a ULPI phy.
|
||||
*/
|
||||
extern void dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val);
|
||||
#define DWC2_PHY_ULPI_INTERNAL_VBUS 0
|
||||
#define DWC2_PHY_ULPI_EXTERNAL_VBUS 1
|
||||
|
||||
/*
|
||||
* Specifies whether to use the I2Cinterface for full speed PHY. This
|
||||
* parameter is only applicable if PHY_TYPE is FS.
|
||||
* 0 - No (default)
|
||||
* 1 - Yes
|
||||
*/
|
||||
extern void dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
extern void dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
extern void dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
/*
|
||||
* Specifies whether dedicated transmit FIFOs are
|
||||
* enabled for non periodic IN endpoints in device mode
|
||||
* 0 - No
|
||||
* 1 - Yes
|
||||
*/
|
||||
extern void dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg,
|
||||
int val);
|
||||
|
||||
extern void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
extern void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
extern void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val);
|
||||
|
||||
extern void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
|
||||
const struct dwc2_core_params *params);
|
||||
|
||||
extern void dwc2_set_all_params(struct dwc2_core_params *params, int value);
|
||||
|
||||
extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
|
||||
/* The device ID match table */
|
||||
extern const struct of_device_id dwc2_of_match_table[];
|
||||
|
||||
extern int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg);
|
||||
extern int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg);
|
||||
|
||||
/* Parameters */
|
||||
int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
|
||||
int dwc2_init_params(struct dwc2_hsotg *hsotg);
|
||||
|
||||
/*
|
||||
* The following functions check the controller's OTG operation mode
|
||||
* capability (GHWCFG2.OTG_MODE).
|
||||
|
@ -159,9 +159,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
|
||||
" ++OTG Interrupt: Session Request Success Status Change++\n");
|
||||
gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
|
||||
if (gotgctl & GOTGCTL_SESREQSCS) {
|
||||
if (hsotg->core_params->phy_type ==
|
||||
if (hsotg->params.phy_type ==
|
||||
DWC2_PHY_TYPE_PARAM_FS
|
||||
&& hsotg->core_params->i2c_enable > 0) {
|
||||
&& hsotg->params.i2c_enable > 0) {
|
||||
hsotg->srp_success = 1;
|
||||
} else {
|
||||
/* Clear Session Request */
|
||||
@ -370,7 +370,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
|
||||
/* Change to L0 state */
|
||||
hsotg->lx_state = DWC2_L0;
|
||||
} else {
|
||||
if (hsotg->core_params->hibernation)
|
||||
if (hsotg->params.hibernation)
|
||||
return;
|
||||
|
||||
if (hsotg->lx_state != DWC2_L1) {
|
||||
|
@ -213,7 +213,7 @@ static int fifo_show(struct seq_file *seq, void *v)
|
||||
val = dwc2_readl(regs + GNPTXFSIZ);
|
||||
seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n",
|
||||
val >> FIFOSIZE_DEPTH_SHIFT,
|
||||
val & FIFOSIZE_DEPTH_MASK);
|
||||
val & FIFOSIZE_STARTADDR_MASK);
|
||||
|
||||
seq_puts(seq, "\nPeriodic TXFIFOs:\n");
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -79,9 +79,9 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg)
|
||||
/* Enable the interrupts in the GINTMSK */
|
||||
intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
|
||||
|
||||
if (hsotg->core_params->dma_enable <= 0)
|
||||
if (hsotg->params.host_dma <= 0)
|
||||
intmsk |= GINTSTS_RXFLVL;
|
||||
if (hsotg->core_params->external_id_pin_ctl <= 0)
|
||||
if (hsotg->params.external_id_pin_ctl <= 0)
|
||||
intmsk |= GINTSTS_CONIDSTSCHNG;
|
||||
|
||||
intmsk |= GINTSTS_WKUPINT | GINTSTS_USBSUSP |
|
||||
@ -100,8 +100,8 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
|
||||
|
||||
if ((hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
|
||||
hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
|
||||
hsotg->core_params->ulpi_fs_ls > 0) ||
|
||||
hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) {
|
||||
hsotg->params.ulpi_fs_ls > 0) ||
|
||||
hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
|
||||
/* Full speed PHY */
|
||||
val = HCFG_FSLSPCLKSEL_48_MHZ;
|
||||
} else {
|
||||
@ -152,7 +152,7 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
|
||||
if (dwc2_is_host_mode(hsotg))
|
||||
dwc2_init_fs_ls_pclk_sel(hsotg);
|
||||
|
||||
if (hsotg->core_params->i2c_enable > 0) {
|
||||
if (hsotg->params.i2c_enable > 0) {
|
||||
dev_dbg(hsotg->dev, "FS PHY enabling I2C\n");
|
||||
|
||||
/* Program GUSBCFG.OtgUtmiFsSel to I2C */
|
||||
@ -189,20 +189,20 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
|
||||
* so only program the first time. Do a soft reset immediately after
|
||||
* setting phyif.
|
||||
*/
|
||||
switch (hsotg->core_params->phy_type) {
|
||||
switch (hsotg->params.phy_type) {
|
||||
case DWC2_PHY_TYPE_PARAM_ULPI:
|
||||
/* ULPI interface */
|
||||
dev_dbg(hsotg->dev, "HS ULPI PHY selected\n");
|
||||
usbcfg |= GUSBCFG_ULPI_UTMI_SEL;
|
||||
usbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL);
|
||||
if (hsotg->core_params->phy_ulpi_ddr > 0)
|
||||
if (hsotg->params.phy_ulpi_ddr > 0)
|
||||
usbcfg |= GUSBCFG_DDRSEL;
|
||||
break;
|
||||
case DWC2_PHY_TYPE_PARAM_UTMI:
|
||||
/* UTMI+ interface */
|
||||
dev_dbg(hsotg->dev, "HS UTMI+ PHY selected\n");
|
||||
usbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16);
|
||||
if (hsotg->core_params->phy_utmi_width == 16)
|
||||
if (hsotg->params.phy_utmi_width == 16)
|
||||
usbcfg |= GUSBCFG_PHYIF16;
|
||||
break;
|
||||
default:
|
||||
@ -230,9 +230,10 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
|
||||
u32 usbcfg;
|
||||
int retval = 0;
|
||||
|
||||
if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL &&
|
||||
hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) {
|
||||
/* If FS mode with FS PHY */
|
||||
if ((hsotg->params.speed == DWC2_SPEED_PARAM_FULL ||
|
||||
hsotg->params.speed == DWC2_SPEED_PARAM_LOW) &&
|
||||
hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
|
||||
/* If FS/LS mode with FS/LS PHY */
|
||||
retval = dwc2_fs_phy_init(hsotg, select_phy);
|
||||
if (retval)
|
||||
return retval;
|
||||
@ -245,7 +246,7 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
|
||||
|
||||
if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
|
||||
hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
|
||||
hsotg->core_params->ulpi_fs_ls > 0) {
|
||||
hsotg->params.ulpi_fs_ls > 0) {
|
||||
dev_dbg(hsotg->dev, "Setting ULPI FSLS\n");
|
||||
usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
|
||||
usbcfg |= GUSBCFG_ULPI_FS_LS;
|
||||
@ -272,9 +273,9 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
|
||||
|
||||
case GHWCFG2_INT_DMA_ARCH:
|
||||
dev_dbg(hsotg->dev, "Internal DMA Mode\n");
|
||||
if (hsotg->core_params->ahbcfg != -1) {
|
||||
if (hsotg->params.ahbcfg != -1) {
|
||||
ahbcfg &= GAHBCFG_CTRL_MASK;
|
||||
ahbcfg |= hsotg->core_params->ahbcfg &
|
||||
ahbcfg |= hsotg->params.ahbcfg &
|
||||
~GAHBCFG_CTRL_MASK;
|
||||
}
|
||||
break;
|
||||
@ -285,21 +286,21 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(hsotg->dev, "dma_enable:%d dma_desc_enable:%d\n",
|
||||
hsotg->core_params->dma_enable,
|
||||
hsotg->core_params->dma_desc_enable);
|
||||
dev_dbg(hsotg->dev, "host_dma:%d dma_desc_enable:%d\n",
|
||||
hsotg->params.host_dma,
|
||||
hsotg->params.dma_desc_enable);
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->core_params->dma_desc_enable > 0)
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0)
|
||||
dev_dbg(hsotg->dev, "Using Descriptor DMA mode\n");
|
||||
else
|
||||
dev_dbg(hsotg->dev, "Using Buffer DMA mode\n");
|
||||
} else {
|
||||
dev_dbg(hsotg->dev, "Using Slave mode\n");
|
||||
hsotg->core_params->dma_desc_enable = 0;
|
||||
hsotg->params.dma_desc_enable = 0;
|
||||
}
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0)
|
||||
if (hsotg->params.host_dma > 0)
|
||||
ahbcfg |= GAHBCFG_DMA_EN;
|
||||
|
||||
dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
|
||||
@ -316,10 +317,10 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
|
||||
|
||||
switch (hsotg->hw_params.op_mode) {
|
||||
case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
|
||||
if (hsotg->core_params->otg_cap ==
|
||||
if (hsotg->params.otg_cap ==
|
||||
DWC2_CAP_PARAM_HNP_SRP_CAPABLE)
|
||||
usbcfg |= GUSBCFG_HNPCAP;
|
||||
if (hsotg->core_params->otg_cap !=
|
||||
if (hsotg->params.otg_cap !=
|
||||
DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE)
|
||||
usbcfg |= GUSBCFG_SRPCAP;
|
||||
break;
|
||||
@ -327,7 +328,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
|
||||
case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
|
||||
case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
|
||||
case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
|
||||
if (hsotg->core_params->otg_cap !=
|
||||
if (hsotg->params.otg_cap !=
|
||||
DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE)
|
||||
usbcfg |= GUSBCFG_SRPCAP;
|
||||
break;
|
||||
@ -390,7 +391,7 @@ static void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
|
||||
*/
|
||||
static void dwc2_calculate_dynamic_fifo(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct dwc2_core_params *params = hsotg->core_params;
|
||||
struct dwc2_core_params *params = &hsotg->params;
|
||||
struct dwc2_hw_params *hw = &hsotg->hw_params;
|
||||
u32 rxfsiz, nptxfsiz, ptxfsiz, total_fifo_size;
|
||||
|
||||
@ -449,7 +450,7 @@ static void dwc2_calculate_dynamic_fifo(struct dwc2_hsotg *hsotg)
|
||||
|
||||
static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct dwc2_core_params *params = hsotg->core_params;
|
||||
struct dwc2_core_params *params = &hsotg->params;
|
||||
u32 nptxfsiz, hptxfsiz, dfifocfg, grxfsiz;
|
||||
|
||||
if (!params->enable_dynamic_fifo)
|
||||
@ -490,7 +491,7 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "new hptxfsiz=%08x\n",
|
||||
dwc2_readl(hsotg->regs + HPTXFSIZ));
|
||||
|
||||
if (hsotg->core_params->en_multiple_tx_fifo > 0 &&
|
||||
if (hsotg->params.en_multiple_tx_fifo > 0 &&
|
||||
hsotg->hw_params.snpsid <= DWC2_CORE_REV_2_94a) {
|
||||
/*
|
||||
* Global DFIFOCFG calculation for Host mode -
|
||||
@ -598,7 +599,7 @@ static void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_host_chan *chan)
|
||||
{
|
||||
#ifdef VERBOSE_DEBUG
|
||||
int num_channels = hsotg->core_params->host_channels;
|
||||
int num_channels = hsotg->params.host_channels;
|
||||
struct dwc2_qh *qh;
|
||||
u32 hcchar;
|
||||
u32 hcsplt;
|
||||
@ -648,6 +649,35 @@ static void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg,
|
||||
#endif /* VERBOSE_DEBUG */
|
||||
}
|
||||
|
||||
static int _dwc2_hcd_start(struct usb_hcd *hcd);
|
||||
|
||||
static void dwc2_host_start(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct usb_hcd *hcd = dwc2_hsotg_to_hcd(hsotg);
|
||||
|
||||
hcd->self.is_b_host = dwc2_hcd_is_b_host(hsotg);
|
||||
_dwc2_hcd_start(hcd);
|
||||
}
|
||||
|
||||
static void dwc2_host_disconnect(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct usb_hcd *hcd = dwc2_hsotg_to_hcd(hsotg);
|
||||
|
||||
hcd->self.is_b_host = 0;
|
||||
}
|
||||
|
||||
static void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context,
|
||||
int *hub_addr, int *hub_port)
|
||||
{
|
||||
struct urb *urb = context;
|
||||
|
||||
if (urb->dev->tt)
|
||||
*hub_addr = urb->dev->tt->hub->devnum;
|
||||
else
|
||||
*hub_addr = 0;
|
||||
*hub_port = urb->dev->ttport;
|
||||
}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* Low Level Host Channel Access Functions
|
||||
@ -741,7 +771,7 @@ static void dwc2_hc_enable_dma_ints(struct dwc2_hsotg *hsotg,
|
||||
* For Descriptor DMA mode core halts the channel on AHB error.
|
||||
* Interrupt is not required.
|
||||
*/
|
||||
if (hsotg->core_params->dma_desc_enable <= 0) {
|
||||
if (hsotg->params.dma_desc_enable <= 0) {
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "desc DMA disabled\n");
|
||||
hcintmsk |= HCINTMSK_AHBERR;
|
||||
@ -774,7 +804,7 @@ static void dwc2_hc_enable_ints(struct dwc2_hsotg *hsotg,
|
||||
{
|
||||
u32 intmsk;
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "DMA enabled\n");
|
||||
dwc2_hc_enable_dma_ints(hsotg, chan);
|
||||
@ -994,7 +1024,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
|
||||
|
||||
/* No need to set the bit in DDMA for disabling the channel */
|
||||
/* TODO check it everywhere channel is disabled */
|
||||
if (hsotg->core_params->dma_desc_enable <= 0) {
|
||||
if (hsotg->params.dma_desc_enable <= 0) {
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "desc DMA disabled\n");
|
||||
hcchar |= HCCHAR_CHENA;
|
||||
@ -1004,7 +1034,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
|
||||
}
|
||||
hcchar |= HCCHAR_CHDIS;
|
||||
|
||||
if (hsotg->core_params->dma_enable <= 0) {
|
||||
if (hsotg->params.host_dma <= 0) {
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "DMA not enabled\n");
|
||||
hcchar |= HCCHAR_CHENA;
|
||||
@ -1143,7 +1173,7 @@ static void dwc2_hc_set_even_odd_frame(struct dwc2_hsotg *hsotg,
|
||||
fifo_space = (dwc2_readl(hsotg->regs + HPTXSTS) &
|
||||
TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT;
|
||||
bytes_in_fifo = sizeof(u32) *
|
||||
(hsotg->core_params->host_perio_tx_fifo_size -
|
||||
(hsotg->params.host_perio_tx_fifo_size -
|
||||
fifo_space);
|
||||
|
||||
/*
|
||||
@ -1339,8 +1369,8 @@ static void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg,
|
||||
static void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_host_chan *chan)
|
||||
{
|
||||
u32 max_hc_xfer_size = hsotg->core_params->max_transfer_size;
|
||||
u16 max_hc_pkt_count = hsotg->core_params->max_packet_count;
|
||||
u32 max_hc_xfer_size = hsotg->params.max_transfer_size;
|
||||
u16 max_hc_pkt_count = hsotg->params.max_packet_count;
|
||||
u32 hcchar;
|
||||
u32 hctsiz = 0;
|
||||
u16 num_packets;
|
||||
@ -1350,7 +1380,7 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
|
||||
dev_vdbg(hsotg->dev, "%s()\n", __func__);
|
||||
|
||||
if (chan->do_ping) {
|
||||
if (hsotg->core_params->dma_enable <= 0) {
|
||||
if (hsotg->params.host_dma <= 0) {
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "ping, no DMA\n");
|
||||
dwc2_hc_do_ping(hsotg, chan);
|
||||
@ -1478,7 +1508,7 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
|
||||
TSIZ_SC_MC_PID_SHIFT);
|
||||
}
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
dwc2_writel((u32)chan->xfer_dma,
|
||||
hsotg->regs + HCDMA(chan->hc_num));
|
||||
if (dbg_hc(chan))
|
||||
@ -1521,7 +1551,7 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
|
||||
chan->xfer_started = 1;
|
||||
chan->requests++;
|
||||
|
||||
if (hsotg->core_params->dma_enable <= 0 &&
|
||||
if (hsotg->params.host_dma <= 0 &&
|
||||
!chan->ep_is_in && chan->xfer_len > 0)
|
||||
/* Load OUT packet into the appropriate Tx FIFO */
|
||||
dwc2_hc_write_packet(hsotg, chan);
|
||||
@ -1799,12 +1829,12 @@ void dwc2_hcd_start(struct dwc2_hsotg *hsotg)
|
||||
/* Must be called with interrupt disabled and spinlock held */
|
||||
static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
int num_channels = hsotg->core_params->host_channels;
|
||||
int num_channels = hsotg->params.host_channels;
|
||||
struct dwc2_host_chan *channel;
|
||||
u32 hcchar;
|
||||
int i;
|
||||
|
||||
if (hsotg->core_params->dma_enable <= 0) {
|
||||
if (hsotg->params.host_dma <= 0) {
|
||||
/* Flush out any channel requests in slave mode */
|
||||
for (i = 0; i < num_channels; i++) {
|
||||
channel = hsotg->hc_ptr_array[i];
|
||||
@ -1840,9 +1870,9 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg)
|
||||
channel->qh = NULL;
|
||||
}
|
||||
/* All channels have been freed, mark them available */
|
||||
if (hsotg->core_params->uframe_sched > 0) {
|
||||
if (hsotg->params.uframe_sched > 0) {
|
||||
hsotg->available_host_channels =
|
||||
hsotg->core_params->host_channels;
|
||||
hsotg->params.host_channels;
|
||||
} else {
|
||||
hsotg->non_periodic_channels = 0;
|
||||
hsotg->periodic_channels = 0;
|
||||
@ -2077,7 +2107,7 @@ static int dwc2_hcd_urb_dequeue(struct dwc2_hsotg *hsotg,
|
||||
* Free the QTD and clean up the associated QH. Leave the QH in the
|
||||
* schedule if it has any remaining QTDs.
|
||||
*/
|
||||
if (hsotg->core_params->dma_desc_enable <= 0) {
|
||||
if (hsotg->params.dma_desc_enable <= 0) {
|
||||
u8 in_process = urb_qtd->in_process;
|
||||
|
||||
dwc2_hcd_qtd_unlink_and_free(hsotg, urb_qtd, qh);
|
||||
@ -2185,13 +2215,13 @@ static int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup)
|
||||
|
||||
/* Set ULPI External VBUS bit if needed */
|
||||
usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV;
|
||||
if (hsotg->core_params->phy_ulpi_ext_vbus ==
|
||||
if (hsotg->params.phy_ulpi_ext_vbus ==
|
||||
DWC2_PHY_ULPI_EXTERNAL_VBUS)
|
||||
usbcfg |= GUSBCFG_ULPI_EXT_VBUS_DRV;
|
||||
|
||||
/* Set external TS Dline pulsing bit if needed */
|
||||
usbcfg &= ~GUSBCFG_TERMSELDLPULSE;
|
||||
if (hsotg->core_params->ts_dline > 0)
|
||||
if (hsotg->params.ts_dline > 0)
|
||||
usbcfg |= GUSBCFG_TERMSELDLPULSE;
|
||||
|
||||
dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
|
||||
@ -2230,10 +2260,10 @@ static int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup)
|
||||
/* Program the GOTGCTL register */
|
||||
otgctl = dwc2_readl(hsotg->regs + GOTGCTL);
|
||||
otgctl &= ~GOTGCTL_OTGVER;
|
||||
if (hsotg->core_params->otg_ver > 0)
|
||||
if (hsotg->params.otg_ver > 0)
|
||||
otgctl |= GOTGCTL_OTGVER;
|
||||
dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
|
||||
dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->core_params->otg_ver);
|
||||
dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->params.otg_ver);
|
||||
|
||||
/* Clear the SRP success bit for FS-I2c */
|
||||
hsotg->srp_success = 0;
|
||||
@ -2277,7 +2307,8 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
|
||||
|
||||
/* Initialize Host Configuration Register */
|
||||
dwc2_init_fs_ls_pclk_sel(hsotg);
|
||||
if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL) {
|
||||
if (hsotg->params.speed == DWC2_SPEED_PARAM_FULL ||
|
||||
hsotg->params.speed == DWC2_SPEED_PARAM_LOW) {
|
||||
hcfg = dwc2_readl(hsotg->regs + HCFG);
|
||||
hcfg |= HCFG_FSLSSUPP;
|
||||
dwc2_writel(hcfg, hsotg->regs + HCFG);
|
||||
@ -2288,13 +2319,13 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
|
||||
* runtime. This bit needs to be programmed during initial configuration
|
||||
* and its value must not be changed during runtime.
|
||||
*/
|
||||
if (hsotg->core_params->reload_ctl > 0) {
|
||||
if (hsotg->params.reload_ctl > 0) {
|
||||
hfir = dwc2_readl(hsotg->regs + HFIR);
|
||||
hfir |= HFIR_RLDCTRL;
|
||||
dwc2_writel(hfir, hsotg->regs + HFIR);
|
||||
}
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
u32 op_mode = hsotg->hw_params.op_mode;
|
||||
|
||||
if (hsotg->hw_params.snpsid < DWC2_CORE_REV_2_90a ||
|
||||
@ -2306,7 +2337,7 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
|
||||
"Hardware does not support descriptor DMA mode -\n");
|
||||
dev_err(hsotg->dev,
|
||||
"falling back to buffer DMA mode.\n");
|
||||
hsotg->core_params->dma_desc_enable = 0;
|
||||
hsotg->params.dma_desc_enable = 0;
|
||||
} else {
|
||||
hcfg = dwc2_readl(hsotg->regs + HCFG);
|
||||
hcfg |= HCFG_DESCDMA;
|
||||
@ -2332,12 +2363,12 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
|
||||
otgctl &= ~GOTGCTL_HSTSETHNPEN;
|
||||
dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable <= 0) {
|
||||
if (hsotg->params.dma_desc_enable <= 0) {
|
||||
int num_channels, i;
|
||||
u32 hcchar;
|
||||
|
||||
/* Flush out any leftover queued requests */
|
||||
num_channels = hsotg->core_params->host_channels;
|
||||
num_channels = hsotg->params.host_channels;
|
||||
for (i = 0; i < num_channels; i++) {
|
||||
hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
|
||||
hcchar &= ~HCCHAR_CHENA;
|
||||
@ -2399,9 +2430,9 @@ static void dwc2_hcd_reinit(struct dwc2_hsotg *hsotg)
|
||||
hsotg->flags.d32 = 0;
|
||||
hsotg->non_periodic_qh_ptr = &hsotg->non_periodic_sched_active;
|
||||
|
||||
if (hsotg->core_params->uframe_sched > 0) {
|
||||
if (hsotg->params.uframe_sched > 0) {
|
||||
hsotg->available_host_channels =
|
||||
hsotg->core_params->host_channels;
|
||||
hsotg->params.host_channels;
|
||||
} else {
|
||||
hsotg->non_periodic_channels = 0;
|
||||
hsotg->periodic_channels = 0;
|
||||
@ -2415,7 +2446,7 @@ static void dwc2_hcd_reinit(struct dwc2_hsotg *hsotg)
|
||||
hc_list_entry)
|
||||
list_del_init(&chan->hc_list_entry);
|
||||
|
||||
num_channels = hsotg->core_params->host_channels;
|
||||
num_channels = hsotg->params.host_channels;
|
||||
for (i = 0; i < num_channels; i++) {
|
||||
chan = hsotg->hc_ptr_array[i];
|
||||
list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
|
||||
@ -2457,7 +2488,7 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
|
||||
chan->do_ping = 0;
|
||||
chan->ep_is_in = 0;
|
||||
chan->data_pid_start = DWC2_HC_PID_SETUP;
|
||||
if (hsotg->core_params->dma_enable > 0)
|
||||
if (hsotg->params.host_dma > 0)
|
||||
chan->xfer_dma = urb->setup_dma;
|
||||
else
|
||||
chan->xfer_buf = urb->setup_packet;
|
||||
@ -2484,7 +2515,7 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
|
||||
chan->do_ping = 0;
|
||||
chan->data_pid_start = DWC2_HC_PID_DATA1;
|
||||
chan->xfer_len = 0;
|
||||
if (hsotg->core_params->dma_enable > 0)
|
||||
if (hsotg->params.host_dma > 0)
|
||||
chan->xfer_dma = hsotg->status_buf_dma;
|
||||
else
|
||||
chan->xfer_buf = hsotg->status_buf;
|
||||
@ -2502,13 +2533,13 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
|
||||
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
chan->ep_type = USB_ENDPOINT_XFER_ISOC;
|
||||
if (hsotg->core_params->dma_desc_enable > 0)
|
||||
if (hsotg->params.dma_desc_enable > 0)
|
||||
break;
|
||||
|
||||
frame_desc = &urb->iso_descs[qtd->isoc_frame_index];
|
||||
frame_desc->status = 0;
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
chan->xfer_dma = urb->dma;
|
||||
chan->xfer_dma += frame_desc->offset +
|
||||
qtd->isoc_split_offset;
|
||||
@ -2690,7 +2721,7 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
!dwc2_hcd_is_pipe_in(&urb->pipe_info))
|
||||
urb->actual_length = urb->length;
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0)
|
||||
if (hsotg->params.host_dma > 0)
|
||||
chan->xfer_dma = urb->dma + urb->actual_length;
|
||||
else
|
||||
chan->xfer_buf = (u8 *)urb->buf + urb->actual_length;
|
||||
@ -2715,7 +2746,7 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
*/
|
||||
chan->multi_count = dwc2_hb_mult(qh->maxp);
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
chan->desc_list_addr = qh->desc_list_dma;
|
||||
chan->desc_list_sz = qh->desc_list_sz;
|
||||
}
|
||||
@ -2752,7 +2783,7 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
|
||||
while (qh_ptr != &hsotg->periodic_sched_ready) {
|
||||
if (list_empty(&hsotg->free_hc_list))
|
||||
break;
|
||||
if (hsotg->core_params->uframe_sched > 0) {
|
||||
if (hsotg->params.uframe_sched > 0) {
|
||||
if (hsotg->available_host_channels <= 1)
|
||||
break;
|
||||
hsotg->available_host_channels--;
|
||||
@ -2776,17 +2807,17 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
|
||||
* schedule. Some free host channels may not be used if they are
|
||||
* reserved for periodic transfers.
|
||||
*/
|
||||
num_channels = hsotg->core_params->host_channels;
|
||||
num_channels = hsotg->params.host_channels;
|
||||
qh_ptr = hsotg->non_periodic_sched_inactive.next;
|
||||
while (qh_ptr != &hsotg->non_periodic_sched_inactive) {
|
||||
if (hsotg->core_params->uframe_sched <= 0 &&
|
||||
if (hsotg->params.uframe_sched <= 0 &&
|
||||
hsotg->non_periodic_channels >= num_channels -
|
||||
hsotg->periodic_channels)
|
||||
break;
|
||||
if (list_empty(&hsotg->free_hc_list))
|
||||
break;
|
||||
qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
|
||||
if (hsotg->core_params->uframe_sched > 0) {
|
||||
if (hsotg->params.uframe_sched > 0) {
|
||||
if (hsotg->available_host_channels < 1)
|
||||
break;
|
||||
hsotg->available_host_channels--;
|
||||
@ -2808,7 +2839,7 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
|
||||
else
|
||||
ret_val = DWC2_TRANSACTION_ALL;
|
||||
|
||||
if (hsotg->core_params->uframe_sched <= 0)
|
||||
if (hsotg->params.uframe_sched <= 0)
|
||||
hsotg->non_periodic_channels++;
|
||||
}
|
||||
|
||||
@ -2847,8 +2878,8 @@ static int dwc2_queue_transaction(struct dwc2_hsotg *hsotg,
|
||||
list_move_tail(&chan->split_order_list_entry,
|
||||
&hsotg->split_order);
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
if (!chan->xfer_started ||
|
||||
chan->ep_type == USB_ENDPOINT_XFER_ISOC) {
|
||||
dwc2_hcd_start_xfer_ddma(hsotg, chan->qh);
|
||||
@ -2957,7 +2988,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
|
||||
* The flag prevents any halts to get into the request queue in
|
||||
* the middle of multiple high-bandwidth packets getting queued.
|
||||
*/
|
||||
if (hsotg->core_params->dma_enable <= 0 &&
|
||||
if (hsotg->params.host_dma <= 0 &&
|
||||
qh->channel->multi_count > 1)
|
||||
hsotg->queuing_high_bandwidth = 1;
|
||||
|
||||
@ -2976,7 +3007,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
|
||||
* controller automatically handles multiple packets for
|
||||
* high-bandwidth transfers.
|
||||
*/
|
||||
if (hsotg->core_params->dma_enable > 0 || status == 0 ||
|
||||
if (hsotg->params.host_dma > 0 || status == 0 ||
|
||||
qh->channel->requests == qh->channel->multi_count) {
|
||||
qh_ptr = qh_ptr->next;
|
||||
/*
|
||||
@ -2993,7 +3024,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
|
||||
|
||||
exit:
|
||||
if (no_queue_space || no_fifo_space ||
|
||||
(hsotg->core_params->dma_enable <= 0 &&
|
||||
(hsotg->params.host_dma <= 0 &&
|
||||
!list_empty(&hsotg->periodic_sched_assigned))) {
|
||||
/*
|
||||
* May need to queue more transactions as the request
|
||||
@ -3073,7 +3104,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
|
||||
tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
|
||||
qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
|
||||
TXSTS_QSPCAVAIL_SHIFT;
|
||||
if (hsotg->core_params->dma_enable <= 0 && qspcavail == 0) {
|
||||
if (hsotg->params.host_dma <= 0 && qspcavail == 0) {
|
||||
no_queue_space = 1;
|
||||
break;
|
||||
}
|
||||
@ -3106,7 +3137,7 @@ next:
|
||||
hsotg->non_periodic_qh_ptr->next;
|
||||
} while (hsotg->non_periodic_qh_ptr != orig_qh_ptr);
|
||||
|
||||
if (hsotg->core_params->dma_enable <= 0) {
|
||||
if (hsotg->params.host_dma <= 0) {
|
||||
tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
|
||||
qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
|
||||
TXSTS_QSPCAVAIL_SHIFT;
|
||||
@ -3307,7 +3338,7 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
|
||||
* If hibernation is supported, Phy clock will be suspended
|
||||
* after registers are backuped.
|
||||
*/
|
||||
if (!hsotg->core_params->hibernation) {
|
||||
if (!hsotg->params.hibernation) {
|
||||
/* Suspend the Phy Clock */
|
||||
pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
|
||||
pcgctl |= PCGCTL_STOPPCLK;
|
||||
@ -3342,7 +3373,7 @@ static void dwc2_port_resume(struct dwc2_hsotg *hsotg)
|
||||
* If hibernation is supported, Phy clock is already resumed
|
||||
* after registers restore.
|
||||
*/
|
||||
if (!hsotg->core_params->hibernation) {
|
||||
if (!hsotg->params.hibernation) {
|
||||
pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
|
||||
pcgctl &= ~PCGCTL_STOPPCLK;
|
||||
dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
|
||||
@ -3569,7 +3600,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
|
||||
port_status |= USB_PORT_STAT_TEST;
|
||||
/* USB_PORT_FEAT_INDICATOR unsupported always 0 */
|
||||
|
||||
if (hsotg->core_params->dma_desc_fs_enable) {
|
||||
if (hsotg->params.dma_desc_fs_enable) {
|
||||
/*
|
||||
* Enable descriptor DMA only if a full speed
|
||||
* device is connected.
|
||||
@ -3583,7 +3614,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
|
||||
u32 hcfg;
|
||||
|
||||
dev_info(hsotg->dev, "Enabling descriptor DMA mode\n");
|
||||
hsotg->core_params->dma_desc_enable = 1;
|
||||
hsotg->params.dma_desc_enable = 1;
|
||||
hcfg = dwc2_readl(hsotg->regs + HCFG);
|
||||
hcfg |= HCFG_DESCDMA;
|
||||
dwc2_writel(hcfg, hsotg->regs + HCFG);
|
||||
@ -3824,7 +3855,7 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg)
|
||||
u32 p_tx_status;
|
||||
int i;
|
||||
|
||||
num_channels = hsotg->core_params->host_channels;
|
||||
num_channels = hsotg->params.host_channels;
|
||||
dev_dbg(hsotg->dev, "\n");
|
||||
dev_dbg(hsotg->dev,
|
||||
"************************************************************\n");
|
||||
@ -4020,35 +4051,6 @@ static struct dwc2_hsotg *dwc2_hcd_to_hsotg(struct usb_hcd *hcd)
|
||||
return p->hsotg;
|
||||
}
|
||||
|
||||
static int _dwc2_hcd_start(struct usb_hcd *hcd);
|
||||
|
||||
void dwc2_host_start(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct usb_hcd *hcd = dwc2_hsotg_to_hcd(hsotg);
|
||||
|
||||
hcd->self.is_b_host = dwc2_hcd_is_b_host(hsotg);
|
||||
_dwc2_hcd_start(hcd);
|
||||
}
|
||||
|
||||
void dwc2_host_disconnect(struct dwc2_hsotg *hsotg)
|
||||
{
|
||||
struct usb_hcd *hcd = dwc2_hsotg_to_hcd(hsotg);
|
||||
|
||||
hcd->self.is_b_host = 0;
|
||||
}
|
||||
|
||||
void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context, int *hub_addr,
|
||||
int *hub_port)
|
||||
{
|
||||
struct urb *urb = context;
|
||||
|
||||
if (urb->dev->tt)
|
||||
*hub_addr = urb->dev->tt->hub->devnum;
|
||||
else
|
||||
*hub_addr = 0;
|
||||
*hub_port = urb->dev->ttport;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_host_get_tt_info() - Get the dwc2_tt associated with context
|
||||
*
|
||||
@ -4365,7 +4367,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
|
||||
if (!HCD_HW_ACCESSIBLE(hcd))
|
||||
goto unlock;
|
||||
|
||||
if (!hsotg->core_params->hibernation)
|
||||
if (!hsotg->params.hibernation)
|
||||
goto skip_power_saving;
|
||||
|
||||
/*
|
||||
@ -4417,7 +4419,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
|
||||
if (hsotg->lx_state != DWC2_L2)
|
||||
goto unlock;
|
||||
|
||||
if (!hsotg->core_params->hibernation) {
|
||||
if (!hsotg->params.hibernation) {
|
||||
hsotg->lx_state = DWC2_L0;
|
||||
goto unlock;
|
||||
}
|
||||
@ -4510,9 +4512,6 @@ static void dwc2_dump_urb_info(struct usb_hcd *hcd, struct urb *urb,
|
||||
case PIPE_ISOCHRONOUS:
|
||||
pipetype = "ISOCHRONOUS";
|
||||
break;
|
||||
default:
|
||||
pipetype = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
dev_vdbg(hsotg->dev, " Endpoint type: %s %s (%s)\n", pipetype,
|
||||
@ -4609,8 +4608,6 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
||||
case PIPE_INTERRUPT:
|
||||
ep_type = USB_ENDPOINT_XFER_INT;
|
||||
break;
|
||||
default:
|
||||
dev_warn(hsotg->dev, "Wrong ep type\n");
|
||||
}
|
||||
|
||||
dwc2_urb = dwc2_hcd_urb_alloc(hsotg, urb->number_of_packets,
|
||||
@ -4919,7 +4916,7 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg)
|
||||
}
|
||||
}
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
if (hsotg->status_buf) {
|
||||
dma_free_coherent(hsotg->dev, DWC2_HCD_STATUS_BUF_SIZE,
|
||||
hsotg->status_buf,
|
||||
@ -4999,16 +4996,16 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
||||
hsotg->last_frame_num = HFNUM_MAX_FRNUM;
|
||||
|
||||
/* Check if the bus driver or platform code has setup a dma_mask */
|
||||
if (hsotg->core_params->dma_enable > 0 &&
|
||||
if (hsotg->params.host_dma > 0 &&
|
||||
hsotg->dev->dma_mask == NULL) {
|
||||
dev_warn(hsotg->dev,
|
||||
"dma_mask not set, disabling DMA\n");
|
||||
hsotg->core_params->dma_enable = 0;
|
||||
hsotg->core_params->dma_desc_enable = 0;
|
||||
hsotg->params.host_dma = 0;
|
||||
hsotg->params.dma_desc_enable = 0;
|
||||
}
|
||||
|
||||
/* Set device flags indicating whether the HCD supports DMA */
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0)
|
||||
dev_warn(hsotg->dev, "can't set DMA mask\n");
|
||||
if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0)
|
||||
@ -5019,7 +5016,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
||||
if (!hcd)
|
||||
goto error1;
|
||||
|
||||
if (hsotg->core_params->dma_enable <= 0)
|
||||
if (hsotg->params.host_dma <= 0)
|
||||
hcd->self.uses_dma = 0;
|
||||
|
||||
hcd->has_tt = 1;
|
||||
@ -5067,7 +5064,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
||||
* in the controller. Initialize the channel descriptor array.
|
||||
*/
|
||||
INIT_LIST_HEAD(&hsotg->free_hc_list);
|
||||
num_channels = hsotg->core_params->host_channels;
|
||||
num_channels = hsotg->params.host_channels;
|
||||
memset(&hsotg->hc_ptr_array[0], 0, sizeof(hsotg->hc_ptr_array));
|
||||
|
||||
for (i = 0; i < num_channels; i++) {
|
||||
@ -5091,7 +5088,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
||||
* done after usb_add_hcd since that function allocates the DMA buffer
|
||||
* pool.
|
||||
*/
|
||||
if (hsotg->core_params->dma_enable > 0)
|
||||
if (hsotg->params.host_dma > 0)
|
||||
hsotg->status_buf = dma_alloc_coherent(hsotg->dev,
|
||||
DWC2_HCD_STATUS_BUF_SIZE,
|
||||
&hsotg->status_buf_dma, GFP_KERNEL);
|
||||
@ -5107,10 +5104,10 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
||||
* DMA mode.
|
||||
* Alignment must be set to 512 bytes.
|
||||
*/
|
||||
if (hsotg->core_params->dma_desc_enable ||
|
||||
hsotg->core_params->dma_desc_fs_enable) {
|
||||
if (hsotg->params.dma_desc_enable ||
|
||||
hsotg->params.dma_desc_fs_enable) {
|
||||
hsotg->desc_gen_cache = kmem_cache_create("dwc2-gen-desc",
|
||||
sizeof(struct dwc2_hcd_dma_desc) *
|
||||
sizeof(struct dwc2_dma_desc) *
|
||||
MAX_DMA_DESC_NUM_GENERIC, 512, SLAB_CACHE_DMA,
|
||||
NULL);
|
||||
if (!hsotg->desc_gen_cache) {
|
||||
@ -5121,12 +5118,12 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
||||
* Disable descriptor dma mode since it will not be
|
||||
* usable.
|
||||
*/
|
||||
hsotg->core_params->dma_desc_enable = 0;
|
||||
hsotg->core_params->dma_desc_fs_enable = 0;
|
||||
hsotg->params.dma_desc_enable = 0;
|
||||
hsotg->params.dma_desc_fs_enable = 0;
|
||||
}
|
||||
|
||||
hsotg->desc_hsisoc_cache = kmem_cache_create("dwc2-hsisoc-desc",
|
||||
sizeof(struct dwc2_hcd_dma_desc) *
|
||||
sizeof(struct dwc2_dma_desc) *
|
||||
MAX_DMA_DESC_NUM_HS_ISOC, 512, 0, NULL);
|
||||
if (!hsotg->desc_hsisoc_cache) {
|
||||
dev_err(hsotg->dev,
|
||||
@ -5138,8 +5135,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
|
||||
* Disable descriptor dma mode since it will not be
|
||||
* usable.
|
||||
*/
|
||||
hsotg->core_params->dma_desc_enable = 0;
|
||||
hsotg->core_params->dma_desc_fs_enable = 0;
|
||||
hsotg->params.dma_desc_enable = 0;
|
||||
hsotg->params.dma_desc_fs_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5184,7 +5181,6 @@ error3:
|
||||
error2:
|
||||
usb_put_hcd(hcd);
|
||||
error1:
|
||||
kfree(hsotg->core_params);
|
||||
|
||||
#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
|
||||
kfree(hsotg->last_frame_num_array);
|
||||
@ -5250,7 +5246,7 @@ int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
|
||||
hr = &hsotg->hr_backup;
|
||||
hr->hcfg = dwc2_readl(hsotg->regs + HCFG);
|
||||
hr->haintmsk = dwc2_readl(hsotg->regs + HAINTMSK);
|
||||
for (i = 0; i < hsotg->core_params->host_channels; ++i)
|
||||
for (i = 0; i < hsotg->params.host_channels; ++i)
|
||||
hr->hcintmsk[i] = dwc2_readl(hsotg->regs + HCINTMSK(i));
|
||||
|
||||
hr->hprt0 = dwc2_read_hprt0(hsotg);
|
||||
@ -5286,7 +5282,7 @@ int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
|
||||
dwc2_writel(hr->hcfg, hsotg->regs + HCFG);
|
||||
dwc2_writel(hr->haintmsk, hsotg->regs + HAINTMSK);
|
||||
|
||||
for (i = 0; i < hsotg->core_params->host_channels; ++i)
|
||||
for (i = 0; i < hsotg->params.host_channels; ++i)
|
||||
dwc2_writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i));
|
||||
|
||||
dwc2_writel(hr->hprt0, hsotg->regs + HPRT0);
|
||||
|
@ -348,7 +348,7 @@ struct dwc2_qh {
|
||||
struct list_head qtd_list;
|
||||
struct dwc2_host_chan *channel;
|
||||
struct list_head qh_list_entry;
|
||||
struct dwc2_hcd_dma_desc *desc_list;
|
||||
struct dwc2_dma_desc *desc_list;
|
||||
dma_addr_t desc_list_dma;
|
||||
u32 desc_list_sz;
|
||||
u32 *n_bytes;
|
||||
@ -793,11 +793,6 @@ extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
|
||||
#define URB_SEND_ZERO_PACKET 0x2
|
||||
|
||||
/* Host driver callbacks */
|
||||
|
||||
extern void dwc2_host_start(struct dwc2_hsotg *hsotg);
|
||||
extern void dwc2_host_disconnect(struct dwc2_hsotg *hsotg);
|
||||
extern void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context,
|
||||
int *hub_addr, int *hub_port);
|
||||
extern struct dwc2_tt *dwc2_host_get_tt_info(struct dwc2_hsotg *hsotg,
|
||||
void *context, gfp_t mem_flags,
|
||||
int *ttport);
|
||||
|
@ -95,7 +95,7 @@ static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
|
||||
else
|
||||
desc_cache = hsotg->desc_gen_cache;
|
||||
|
||||
qh->desc_list_sz = sizeof(struct dwc2_hcd_dma_desc) *
|
||||
qh->desc_list_sz = sizeof(struct dwc2_dma_desc) *
|
||||
dwc2_max_desc_num(qh);
|
||||
|
||||
qh->desc_list = kmem_cache_zalloc(desc_cache, flags | GFP_DMA);
|
||||
@ -297,7 +297,7 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_host_chan *chan = qh->channel;
|
||||
|
||||
if (dwc2_qh_is_non_per(qh)) {
|
||||
if (hsotg->core_params->uframe_sched > 0)
|
||||
if (hsotg->params.uframe_sched > 0)
|
||||
hsotg->available_host_channels++;
|
||||
else
|
||||
hsotg->non_periodic_channels--;
|
||||
@ -322,7 +322,7 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg,
|
||||
qh->ntd = 0;
|
||||
|
||||
if (qh->desc_list)
|
||||
memset(qh->desc_list, 0, sizeof(struct dwc2_hcd_dma_desc) *
|
||||
memset(qh->desc_list, 0, sizeof(struct dwc2_dma_desc) *
|
||||
dwc2_max_desc_num(qh));
|
||||
}
|
||||
|
||||
@ -404,7 +404,7 @@ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
|
||||
if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC ||
|
||||
qh->ep_type == USB_ENDPOINT_XFER_INT) &&
|
||||
(hsotg->core_params->uframe_sched > 0 ||
|
||||
(hsotg->params.uframe_sched > 0 ||
|
||||
!hsotg->periodic_channels) && hsotg->frame_list) {
|
||||
dwc2_per_sched_disable(hsotg);
|
||||
dwc2_frame_list_free(hsotg);
|
||||
@ -542,7 +542,7 @@ static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *qh, u32 max_xfer_size,
|
||||
u16 idx)
|
||||
{
|
||||
struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[idx];
|
||||
struct dwc2_dma_desc *dma_desc = &qh->desc_list[idx];
|
||||
struct dwc2_hcd_iso_packet_desc *frame_desc;
|
||||
|
||||
memset(dma_desc, 0, sizeof(*dma_desc));
|
||||
@ -571,8 +571,8 @@ static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
|
||||
dma_sync_single_for_device(hsotg->dev,
|
||||
qh->desc_list_dma +
|
||||
(idx * sizeof(struct dwc2_hcd_dma_desc)),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
(idx * sizeof(struct dwc2_dma_desc)),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
@ -645,8 +645,8 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
qh->desc_list[idx].status |= HOST_DMA_IOC;
|
||||
dma_sync_single_for_device(hsotg->dev,
|
||||
qh->desc_list_dma + (idx *
|
||||
sizeof(struct dwc2_hcd_dma_desc)),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
sizeof(struct dwc2_dma_desc)),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
#else
|
||||
@ -679,8 +679,8 @@ static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
qh->desc_list[idx].status |= HOST_DMA_IOC;
|
||||
dma_sync_single_for_device(hsotg->dev,
|
||||
qh->desc_list_dma +
|
||||
(idx * sizeof(struct dwc2_hcd_dma_desc)),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
(idx * sizeof(struct dwc2_dma_desc)),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_TO_DEVICE);
|
||||
#endif
|
||||
}
|
||||
@ -690,11 +690,11 @@ static void dwc2_fill_host_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qtd *qtd, struct dwc2_qh *qh,
|
||||
int n_desc)
|
||||
{
|
||||
struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[n_desc];
|
||||
struct dwc2_dma_desc *dma_desc = &qh->desc_list[n_desc];
|
||||
int len = chan->xfer_len;
|
||||
|
||||
if (len > MAX_DMA_DESC_SIZE - (chan->max_packet - 1))
|
||||
len = MAX_DMA_DESC_SIZE - (chan->max_packet - 1);
|
||||
if (len > HOST_DMA_NBYTES_LIMIT - (chan->max_packet - 1))
|
||||
len = HOST_DMA_NBYTES_LIMIT - (chan->max_packet - 1);
|
||||
|
||||
if (chan->ep_is_in) {
|
||||
int num_packets;
|
||||
@ -721,8 +721,8 @@ static void dwc2_fill_host_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
|
||||
dma_sync_single_for_device(hsotg->dev,
|
||||
qh->desc_list_dma +
|
||||
(n_desc * sizeof(struct dwc2_hcd_dma_desc)),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
(n_desc * sizeof(struct dwc2_dma_desc)),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
/*
|
||||
@ -778,8 +778,8 @@ static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
dma_sync_single_for_device(hsotg->dev,
|
||||
qh->desc_list_dma +
|
||||
((n_desc - 1) *
|
||||
sizeof(struct dwc2_hcd_dma_desc)),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
sizeof(struct dwc2_dma_desc)),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
dwc2_fill_host_dma_desc(hsotg, chan, qtd, qh, n_desc);
|
||||
@ -808,8 +808,8 @@ static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
n_desc - 1, &qh->desc_list[n_desc - 1]);
|
||||
dma_sync_single_for_device(hsotg->dev,
|
||||
qh->desc_list_dma + (n_desc - 1) *
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_TO_DEVICE);
|
||||
if (n_desc > 1) {
|
||||
qh->desc_list[0].status |= HOST_DMA_A;
|
||||
@ -817,7 +817,7 @@ static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
&qh->desc_list[0]);
|
||||
dma_sync_single_for_device(hsotg->dev,
|
||||
qh->desc_list_dma,
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
chan->ntd = n_desc;
|
||||
@ -893,7 +893,7 @@ static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qtd *qtd,
|
||||
struct dwc2_qh *qh, u16 idx)
|
||||
{
|
||||
struct dwc2_hcd_dma_desc *dma_desc;
|
||||
struct dwc2_dma_desc *dma_desc;
|
||||
struct dwc2_hcd_iso_packet_desc *frame_desc;
|
||||
u16 remain = 0;
|
||||
int rc = 0;
|
||||
@ -902,8 +902,8 @@ static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg,
|
||||
return -EINVAL;
|
||||
|
||||
dma_sync_single_for_cpu(hsotg->dev, qh->desc_list_dma + (idx *
|
||||
sizeof(struct dwc2_hcd_dma_desc)),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
sizeof(struct dwc2_dma_desc)),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
dma_desc = &qh->desc_list[idx];
|
||||
@ -1066,7 +1066,7 @@ stop_scan:
|
||||
static int dwc2_update_non_isoc_urb_state_ddma(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_host_chan *chan,
|
||||
struct dwc2_qtd *qtd,
|
||||
struct dwc2_hcd_dma_desc *dma_desc,
|
||||
struct dwc2_dma_desc *dma_desc,
|
||||
enum dwc2_halt_status halt_status,
|
||||
u32 n_bytes, int *xfer_done)
|
||||
{
|
||||
@ -1154,7 +1154,7 @@ static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg,
|
||||
{
|
||||
struct dwc2_qh *qh = chan->qh;
|
||||
struct dwc2_hcd_urb *urb = qtd->urb;
|
||||
struct dwc2_hcd_dma_desc *dma_desc;
|
||||
struct dwc2_dma_desc *dma_desc;
|
||||
u32 n_bytes;
|
||||
int failed;
|
||||
|
||||
@ -1165,8 +1165,8 @@ static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg,
|
||||
|
||||
dma_sync_single_for_cpu(hsotg->dev,
|
||||
qh->desc_list_dma + (desc_num *
|
||||
sizeof(struct dwc2_hcd_dma_desc)),
|
||||
sizeof(struct dwc2_hcd_dma_desc),
|
||||
sizeof(struct dwc2_dma_desc)),
|
||||
sizeof(struct dwc2_dma_desc),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
dma_desc = &qh->desc_list[desc_num];
|
||||
|
@ -256,7 +256,7 @@ static void dwc2_perio_tx_fifo_empty_intr(struct dwc2_hsotg *hsotg)
|
||||
static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
|
||||
u32 *hprt0_modify)
|
||||
{
|
||||
struct dwc2_core_params *params = hsotg->core_params;
|
||||
struct dwc2_core_params *params = &hsotg->params;
|
||||
int do_reset = 0;
|
||||
u32 usbcfg;
|
||||
u32 prtspd;
|
||||
@ -395,10 +395,10 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
|
||||
dwc2_hprt0_enable(hsotg, hprt0, &hprt0_modify);
|
||||
} else {
|
||||
hsotg->flags.b.port_enable_change = 1;
|
||||
if (hsotg->core_params->dma_desc_fs_enable) {
|
||||
if (hsotg->params.dma_desc_fs_enable) {
|
||||
u32 hcfg;
|
||||
|
||||
hsotg->core_params->dma_desc_enable = 0;
|
||||
hsotg->params.dma_desc_enable = 0;
|
||||
hsotg->new_connection = false;
|
||||
hcfg = dwc2_readl(hsotg->regs + HCFG);
|
||||
hcfg &= ~HCFG_DESCDMA;
|
||||
@ -604,7 +604,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
|
||||
/* Skip whole frame */
|
||||
if (chan->qh->do_split &&
|
||||
chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
|
||||
hsotg->core_params->dma_enable > 0) {
|
||||
hsotg->params.host_dma > 0) {
|
||||
qtd->complete_split = 0;
|
||||
qtd->isoc_split_offset = 0;
|
||||
}
|
||||
@ -743,7 +743,7 @@ cleanup:
|
||||
dwc2_hc_cleanup(hsotg, chan);
|
||||
list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
|
||||
|
||||
if (hsotg->core_params->uframe_sched > 0) {
|
||||
if (hsotg->params.uframe_sched > 0) {
|
||||
hsotg->available_host_channels++;
|
||||
} else {
|
||||
switch (chan->ep_type) {
|
||||
@ -789,7 +789,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "%s()\n", __func__);
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
if (dbg_hc(chan))
|
||||
dev_vdbg(hsotg->dev, "DMA enabled\n");
|
||||
dwc2_release_channel(hsotg, chan, qtd, halt_status);
|
||||
@ -915,6 +915,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg,
|
||||
{
|
||||
struct dwc2_hcd_iso_packet_desc *frame_desc;
|
||||
u32 len;
|
||||
u32 hctsiz;
|
||||
u32 pid;
|
||||
|
||||
if (!qtd->urb)
|
||||
return 0;
|
||||
@ -932,7 +934,10 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg,
|
||||
|
||||
qtd->isoc_split_offset += len;
|
||||
|
||||
if (frame_desc->actual_length >= frame_desc->length) {
|
||||
hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
|
||||
pid = (hctsiz & TSIZ_SC_MC_PID_MASK) >> TSIZ_SC_MC_PID_SHIFT;
|
||||
|
||||
if (frame_desc->actual_length >= frame_desc->length || pid == 0) {
|
||||
frame_desc->status = 0;
|
||||
qtd->isoc_frame_index++;
|
||||
qtd->complete_split = 0;
|
||||
@ -974,7 +979,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
|
||||
|
||||
pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info);
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status);
|
||||
if (pipe_type == USB_ENDPOINT_XFER_ISOC)
|
||||
/* Do not disable the interrupt, just clear it */
|
||||
@ -985,7 +990,7 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg,
|
||||
/* Handle xfer complete on CSPLIT */
|
||||
if (chan->qh->do_split) {
|
||||
if (chan->ep_type == USB_ENDPOINT_XFER_ISOC && chan->ep_is_in &&
|
||||
hsotg->core_params->dma_enable > 0) {
|
||||
hsotg->params.host_dma > 0) {
|
||||
if (qtd->complete_split &&
|
||||
dwc2_xfercomp_isoc_split_in(hsotg, chan, chnum,
|
||||
qtd))
|
||||
@ -1097,7 +1102,7 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg,
|
||||
dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n",
|
||||
chnum);
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||
DWC2_HC_XFER_STALL);
|
||||
goto handle_stall_done;
|
||||
@ -1207,7 +1212,7 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg,
|
||||
switch (dwc2_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
|
||||
case USB_ENDPOINT_XFER_CONTROL:
|
||||
case USB_ENDPOINT_XFER_BULK:
|
||||
if (hsotg->core_params->dma_enable > 0 && chan->ep_is_in) {
|
||||
if (hsotg->params.host_dma > 0 && chan->ep_is_in) {
|
||||
/*
|
||||
* NAK interrupts are enabled on bulk/control IN
|
||||
* transfers in DMA mode for the sole purpose of
|
||||
@ -1353,7 +1358,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
|
||||
*/
|
||||
if (chan->do_split && chan->complete_split) {
|
||||
if (chan->ep_is_in && chan->ep_type == USB_ENDPOINT_XFER_ISOC &&
|
||||
hsotg->core_params->dma_enable > 0) {
|
||||
hsotg->params.host_dma > 0) {
|
||||
qtd->complete_split = 0;
|
||||
qtd->isoc_split_offset = 0;
|
||||
qtd->isoc_frame_index++;
|
||||
@ -1374,7 +1379,7 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *qh = chan->qh;
|
||||
bool past_end;
|
||||
|
||||
if (hsotg->core_params->uframe_sched <= 0) {
|
||||
if (hsotg->params.uframe_sched <= 0) {
|
||||
int frnum = dwc2_hcd_get_frame_number(hsotg);
|
||||
|
||||
/* Don't have num_hs_transfers; simple logic */
|
||||
@ -1467,7 +1472,7 @@ static void dwc2_hc_babble_intr(struct dwc2_hsotg *hsotg,
|
||||
|
||||
dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||
DWC2_HC_XFER_BABBLE_ERR);
|
||||
goto disable_int;
|
||||
@ -1572,7 +1577,7 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg,
|
||||
dev_err(hsotg->dev, " Interval: %d\n", urb->interval);
|
||||
|
||||
/* Core halts the channel for Descriptor DMA mode */
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||
DWC2_HC_XFER_AHB_ERR);
|
||||
goto handle_ahberr_done;
|
||||
@ -1604,7 +1609,7 @@ static void dwc2_hc_xacterr_intr(struct dwc2_hsotg *hsotg,
|
||||
|
||||
dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0) {
|
||||
if (hsotg->params.dma_desc_enable > 0) {
|
||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||
DWC2_HC_XFER_XACT_ERR);
|
||||
goto handle_xacterr_done;
|
||||
@ -1798,8 +1803,8 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
|
||||
|
||||
if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE ||
|
||||
(chan->halt_status == DWC2_HC_XFER_AHB_ERR &&
|
||||
hsotg->core_params->dma_desc_enable <= 0)) {
|
||||
if (hsotg->core_params->dma_desc_enable > 0)
|
||||
hsotg->params.dma_desc_enable <= 0)) {
|
||||
if (hsotg->params.dma_desc_enable > 0)
|
||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||
chan->halt_status);
|
||||
else
|
||||
@ -1830,7 +1835,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
|
||||
} else if (chan->hcint & HCINTMSK_STALL) {
|
||||
dwc2_hc_stall_intr(hsotg, chan, chnum, qtd);
|
||||
} else if ((chan->hcint & HCINTMSK_XACTERR) &&
|
||||
hsotg->core_params->dma_desc_enable <= 0) {
|
||||
hsotg->params.dma_desc_enable <= 0) {
|
||||
if (out_nak_enh) {
|
||||
if (chan->hcint &
|
||||
(HCINTMSK_NYET | HCINTMSK_NAK | HCINTMSK_ACK)) {
|
||||
@ -1850,10 +1855,10 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
|
||||
*/
|
||||
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
|
||||
} else if ((chan->hcint & HCINTMSK_XCS_XACT) &&
|
||||
hsotg->core_params->dma_desc_enable > 0) {
|
||||
hsotg->params.dma_desc_enable > 0) {
|
||||
dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
|
||||
} else if ((chan->hcint & HCINTMSK_AHBERR) &&
|
||||
hsotg->core_params->dma_desc_enable > 0) {
|
||||
hsotg->params.dma_desc_enable > 0) {
|
||||
dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd);
|
||||
} else if (chan->hcint & HCINTMSK_BBLERR) {
|
||||
dwc2_hc_babble_intr(hsotg, chan, chnum, qtd);
|
||||
@ -1946,7 +1951,7 @@ static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg,
|
||||
dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: Channel Halted--\n",
|
||||
chnum);
|
||||
|
||||
if (hsotg->core_params->dma_enable > 0) {
|
||||
if (hsotg->params.host_dma > 0) {
|
||||
dwc2_hc_chhltd_intr_dma(hsotg, chan, chnum, qtd);
|
||||
} else {
|
||||
if (!dwc2_halt_status_ok(hsotg, chan, chnum, qtd))
|
||||
@ -2023,7 +2028,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
|
||||
* interrupt unmasked
|
||||
*/
|
||||
WARN_ON(hcint != HCINTMSK_CHHLTD);
|
||||
if (hsotg->core_params->dma_desc_enable > 0)
|
||||
if (hsotg->params.dma_desc_enable > 0)
|
||||
dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum,
|
||||
chan->halt_status);
|
||||
else
|
||||
@ -2051,7 +2056,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_entry);
|
||||
|
||||
if (hsotg->core_params->dma_enable <= 0) {
|
||||
if (hsotg->params.host_dma <= 0) {
|
||||
if ((hcint & HCINTMSK_CHHLTD) && hcint != HCINTMSK_CHHLTD)
|
||||
hcint &= ~HCINTMSK_CHHLTD;
|
||||
}
|
||||
@ -2156,7 +2161,7 @@ static void dwc2_hc_intr(struct dwc2_hsotg *hsotg)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < hsotg->core_params->host_channels; i++) {
|
||||
for (i = 0; i < hsotg->params.host_channels; i++) {
|
||||
if (haint & (1 << i))
|
||||
dwc2_hc_n_intr(hsotg, i);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg)
|
||||
int status;
|
||||
int num_channels;
|
||||
|
||||
num_channels = hsotg->core_params->host_channels;
|
||||
num_channels = hsotg->params.host_channels;
|
||||
if (hsotg->periodic_channels + hsotg->non_periodic_channels <
|
||||
num_channels
|
||||
&& hsotg->periodic_channels < num_channels - 1) {
|
||||
@ -355,6 +355,37 @@ static void pmap_unschedule(unsigned long *map, int bits_per_period,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_get_ls_map() - Get the map used for the given qh
|
||||
*
|
||||
* @hsotg: The HCD state structure for the DWC OTG controller.
|
||||
* @qh: QH for the periodic transfer.
|
||||
*
|
||||
* We'll always get the periodic map out of our TT. Note that even if we're
|
||||
* running the host straight in low speed / full speed mode it appears as if
|
||||
* a TT is allocated for us, so we'll use it. If that ever changes we can
|
||||
* add logic here to get a map out of "hsotg" if !qh->do_split.
|
||||
*
|
||||
* Returns: the map or NULL if a map couldn't be found.
|
||||
*/
|
||||
static unsigned long *dwc2_get_ls_map(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *qh)
|
||||
{
|
||||
unsigned long *map;
|
||||
|
||||
/* Don't expect to be missing a TT and be doing low speed scheduling */
|
||||
if (WARN_ON(!qh->dwc_tt))
|
||||
return NULL;
|
||||
|
||||
/* Get the map and adjust if this is a multi_tt hub */
|
||||
map = qh->dwc_tt->periodic_bitmaps;
|
||||
if (qh->dwc_tt->usb_tt->multi)
|
||||
map += DWC2_ELEMENTS_PER_LS_BITMAP * qh->ttport;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
#ifdef DWC2_PRINT_SCHEDULE
|
||||
/*
|
||||
* cat_printf() - A printf() + strcat() helper
|
||||
*
|
||||
@ -454,35 +485,6 @@ static void pmap_print(unsigned long *map, int bits_per_period,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_get_ls_map() - Get the map used for the given qh
|
||||
*
|
||||
* @hsotg: The HCD state structure for the DWC OTG controller.
|
||||
* @qh: QH for the periodic transfer.
|
||||
*
|
||||
* We'll always get the periodic map out of our TT. Note that even if we're
|
||||
* running the host straight in low speed / full speed mode it appears as if
|
||||
* a TT is allocated for us, so we'll use it. If that ever changes we can
|
||||
* add logic here to get a map out of "hsotg" if !qh->do_split.
|
||||
*
|
||||
* Returns: the map or NULL if a map couldn't be found.
|
||||
*/
|
||||
static unsigned long *dwc2_get_ls_map(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *qh)
|
||||
{
|
||||
unsigned long *map;
|
||||
|
||||
/* Don't expect to be missing a TT and be doing low speed scheduling */
|
||||
if (WARN_ON(!qh->dwc_tt))
|
||||
return NULL;
|
||||
|
||||
/* Get the map and adjust if this is a multi_tt hub */
|
||||
map = qh->dwc_tt->periodic_bitmaps;
|
||||
if (qh->dwc_tt->usb_tt->multi)
|
||||
map += DWC2_ELEMENTS_PER_LS_BITMAP * qh->ttport;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
struct dwc2_qh_print_data {
|
||||
struct dwc2_hsotg *hsotg;
|
||||
@ -519,9 +521,6 @@ static void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
|
||||
* If we don't have tracing turned on, don't run unless the special
|
||||
* define is turned on.
|
||||
*/
|
||||
#ifndef DWC2_PRINT_SCHEDULE
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (qh->schedule_low_speed) {
|
||||
unsigned long *map = dwc2_get_ls_map(hsotg, qh);
|
||||
@ -559,8 +558,12 @@ static void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
|
||||
DWC2_HS_SCHEDULE_UFRAMES, "uFrame", "us",
|
||||
dwc2_qh_print, &print_data);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
static inline void dwc2_qh_schedule_print(struct dwc2_hsotg *hsotg,
|
||||
struct dwc2_qh *qh) {};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dwc2_ls_pmap_schedule() - Schedule a low speed QH
|
||||
@ -1104,7 +1107,7 @@ static void dwc2_pick_first_frame(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
next_active_frame = earliest_frame;
|
||||
|
||||
/* Get the "no microframe schduler" out of the way... */
|
||||
if (hsotg->core_params->uframe_sched <= 0) {
|
||||
if (hsotg->params.uframe_sched <= 0) {
|
||||
if (qh->do_split)
|
||||
/* Splits are active at microframe 0 minus 1 */
|
||||
next_active_frame |= 0x7;
|
||||
@ -1197,7 +1200,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (hsotg->core_params->uframe_sched > 0) {
|
||||
if (hsotg->params.uframe_sched > 0) {
|
||||
status = dwc2_uframe_schedule(hsotg, qh);
|
||||
} else {
|
||||
status = dwc2_periodic_channel_available(hsotg);
|
||||
@ -1218,7 +1221,7 @@ static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (hsotg->core_params->uframe_sched <= 0)
|
||||
if (hsotg->params.uframe_sched <= 0)
|
||||
/* Reserve periodic channel */
|
||||
hsotg->periodic_channels++;
|
||||
|
||||
@ -1254,7 +1257,7 @@ static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
/* Update claimed usecs per (micro)frame */
|
||||
hsotg->periodic_usecs -= qh->host_us;
|
||||
|
||||
if (hsotg->core_params->uframe_sched > 0) {
|
||||
if (hsotg->params.uframe_sched > 0) {
|
||||
dwc2_uframe_unschedule(hsotg, qh);
|
||||
} else {
|
||||
/* Release periodic channel reservation */
|
||||
@ -1328,7 +1331,7 @@ static int dwc2_check_max_xfer_size(struct dwc2_hsotg *hsotg,
|
||||
int status = 0;
|
||||
|
||||
max_xfer_size = dwc2_max_packet(qh->maxp) * dwc2_hb_mult(qh->maxp);
|
||||
max_channel_xfer_size = hsotg->core_params->max_transfer_size;
|
||||
max_channel_xfer_size = hsotg->params.max_transfer_size;
|
||||
|
||||
if (max_xfer_size > max_channel_xfer_size) {
|
||||
dev_err(hsotg->dev,
|
||||
@ -1391,7 +1394,7 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
|
||||
qh->unreserve_pending = 0;
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0)
|
||||
if (hsotg->params.dma_desc_enable > 0)
|
||||
/* Don't rely on SOF and start in ready schedule */
|
||||
list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready);
|
||||
else
|
||||
@ -1599,7 +1602,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
|
||||
|
||||
dwc2_qh_init(hsotg, qh, urb, mem_flags);
|
||||
|
||||
if (hsotg->core_params->dma_desc_enable > 0 &&
|
||||
if (hsotg->params.dma_desc_enable > 0 &&
|
||||
dwc2_hcd_qh_init_ddma(hsotg, qh, mem_flags) < 0) {
|
||||
dwc2_hcd_qh_free(hsotg, qh);
|
||||
return NULL;
|
||||
@ -1711,7 +1714,7 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
||||
dwc2_deschedule_periodic(hsotg, qh);
|
||||
hsotg->periodic_qh_count--;
|
||||
if (!hsotg->periodic_qh_count &&
|
||||
hsotg->core_params->dma_desc_enable <= 0) {
|
||||
hsotg->params.dma_desc_enable <= 0) {
|
||||
intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
|
||||
intr_mask &= ~GINTSTS_SOF;
|
||||
dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
|
||||
|
@ -412,6 +412,7 @@
|
||||
/* Device mode registers */
|
||||
|
||||
#define DCFG HSOTG_REG(0x800)
|
||||
#define DCFG_DESCDMA_EN (1 << 23)
|
||||
#define DCFG_EPMISCNT_MASK (0x1f << 18)
|
||||
#define DCFG_EPMISCNT_SHIFT 18
|
||||
#define DCFG_EPMISCNT_LIMIT 0x1f
|
||||
@ -473,6 +474,7 @@
|
||||
#define DIEPMSK_XFERCOMPLMSK (1 << 0)
|
||||
|
||||
#define DOEPMSK HSOTG_REG(0x814)
|
||||
#define DOEPMSK_BNAMSK (1 << 9)
|
||||
#define DOEPMSK_BACK2BACKSETUP (1 << 6)
|
||||
#define DOEPMSK_STSPHSERCVDMSK (1 << 5)
|
||||
#define DOEPMSK_OUTTKNEPDISMSK (1 << 4)
|
||||
@ -790,7 +792,8 @@
|
||||
#define HCFIFO(_ch) HSOTG_REG(0x1000 + 0x1000 * (_ch))
|
||||
|
||||
/**
|
||||
* struct dwc2_hcd_dma_desc - Host-mode DMA descriptor structure
|
||||
* struct dwc2_dma_desc - DMA descriptor structure,
|
||||
* used for both host and gadget modes
|
||||
*
|
||||
* @status: DMA descriptor status quadlet
|
||||
* @buf: DMA descriptor data buffer pointer
|
||||
@ -798,10 +801,12 @@
|
||||
* DMA Descriptor structure contains two quadlets:
|
||||
* Status quadlet and Data buffer pointer.
|
||||
*/
|
||||
struct dwc2_hcd_dma_desc {
|
||||
struct dwc2_dma_desc {
|
||||
u32 status;
|
||||
u32 buf;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/* Host Mode DMA descriptor status quadlet */
|
||||
|
||||
#define HOST_DMA_A (1 << 31)
|
||||
#define HOST_DMA_STS_MASK (0x3 << 28)
|
||||
@ -817,8 +822,43 @@ struct dwc2_hcd_dma_desc {
|
||||
#define HOST_DMA_ISOC_NBYTES_SHIFT 0
|
||||
#define HOST_DMA_NBYTES_MASK (0x1ffff << 0)
|
||||
#define HOST_DMA_NBYTES_SHIFT 0
|
||||
#define HOST_DMA_NBYTES_LIMIT 131071
|
||||
|
||||
/* Device Mode DMA descriptor status quadlet */
|
||||
|
||||
#define DEV_DMA_BUFF_STS_MASK (0x3 << 30)
|
||||
#define DEV_DMA_BUFF_STS_SHIFT 30
|
||||
#define DEV_DMA_BUFF_STS_HREADY 0
|
||||
#define DEV_DMA_BUFF_STS_DMABUSY 1
|
||||
#define DEV_DMA_BUFF_STS_DMADONE 2
|
||||
#define DEV_DMA_BUFF_STS_HBUSY 3
|
||||
#define DEV_DMA_STS_MASK (0x3 << 28)
|
||||
#define DEV_DMA_STS_SHIFT 28
|
||||
#define DEV_DMA_STS_SUCC 0
|
||||
#define DEV_DMA_STS_BUFF_FLUSH 1
|
||||
#define DEV_DMA_STS_BUFF_ERR 3
|
||||
#define DEV_DMA_L (1 << 27)
|
||||
#define DEV_DMA_SHORT (1 << 26)
|
||||
#define DEV_DMA_IOC (1 << 25)
|
||||
#define DEV_DMA_SR (1 << 24)
|
||||
#define DEV_DMA_MTRF (1 << 23)
|
||||
#define DEV_DMA_ISOC_PID_MASK (0x3 << 23)
|
||||
#define DEV_DMA_ISOC_PID_SHIFT 23
|
||||
#define DEV_DMA_ISOC_PID_DATA0 0
|
||||
#define DEV_DMA_ISOC_PID_DATA2 1
|
||||
#define DEV_DMA_ISOC_PID_DATA1 2
|
||||
#define DEV_DMA_ISOC_PID_MDATA 3
|
||||
#define DEV_DMA_ISOC_FRNUM_MASK (0x7ff << 12)
|
||||
#define DEV_DMA_ISOC_FRNUM_SHIFT 12
|
||||
#define DEV_DMA_ISOC_TX_NBYTES_MASK (0xfff << 0)
|
||||
#define DEV_DMA_ISOC_TX_NBYTES_LIMIT 0xfff
|
||||
#define DEV_DMA_ISOC_RX_NBYTES_MASK (0x7ff << 0)
|
||||
#define DEV_DMA_ISOC_RX_NBYTES_LIMIT 0x7ff
|
||||
#define DEV_DMA_ISOC_NBYTES_SHIFT 0
|
||||
#define DEV_DMA_NBYTES_MASK (0xffff << 0)
|
||||
#define DEV_DMA_NBYTES_SHIFT 0
|
||||
#define DEV_DMA_NBYTES_LIMIT 0xffff
|
||||
|
||||
#define MAX_DMA_DESC_SIZE 131071
|
||||
#define MAX_DMA_DESC_NUM_GENERIC 64
|
||||
#define MAX_DMA_DESC_NUM_HS_ISOC 256
|
||||
|
||||
|
1435
drivers/usb/dwc2/params.c
Normal file
1435
drivers/usb/dwc2/params.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -62,6 +62,20 @@ struct dwc2_pci_glue {
|
||||
struct platform_device *phy;
|
||||
};
|
||||
|
||||
static int dwc2_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc2)
|
||||
{
|
||||
if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS &&
|
||||
pdev->device == PCI_PRODUCT_ID_HAPS_HSOTG) {
|
||||
struct property_entry properties[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
return platform_device_add_properties(dwc2, properties);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dwc2_pci_remove(struct pci_dev *pci)
|
||||
{
|
||||
struct dwc2_pci_glue *glue = pci_get_drvdata(pci);
|
||||
@ -122,6 +136,10 @@ static int dwc2_pci_probe(struct pci_dev *pci,
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
ret = dwc2_pci_quirks(pci, dwc2);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = platform_device_add(dwc2);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register dwc2 device\n");
|
||||
|
@ -55,165 +55,6 @@
|
||||
|
||||
static const char dwc2_driver_name[] = "dwc2";
|
||||
|
||||
static const struct dwc2_core_params params_hi6220 = {
|
||||
.otg_cap = 2, /* No HNP/SRP capable */
|
||||
.otg_ver = 0, /* 1.3 */
|
||||
.dma_enable = 1,
|
||||
.dma_desc_enable = 0,
|
||||
.dma_desc_fs_enable = 0,
|
||||
.speed = 0, /* High Speed */
|
||||
.enable_dynamic_fifo = 1,
|
||||
.en_multiple_tx_fifo = 1,
|
||||
.host_rx_fifo_size = 512,
|
||||
.host_nperio_tx_fifo_size = 512,
|
||||
.host_perio_tx_fifo_size = 512,
|
||||
.max_transfer_size = 65535,
|
||||
.max_packet_count = 511,
|
||||
.host_channels = 16,
|
||||
.phy_type = 1, /* UTMI */
|
||||
.phy_utmi_width = 8,
|
||||
.phy_ulpi_ddr = 0, /* Single */
|
||||
.phy_ulpi_ext_vbus = 0,
|
||||
.i2c_enable = 0,
|
||||
.ulpi_fs_ls = 0,
|
||||
.host_support_fs_ls_low_power = 0,
|
||||
.host_ls_low_power_phy_clk = 0, /* 48 MHz */
|
||||
.ts_dline = 0,
|
||||
.reload_ctl = 0,
|
||||
.ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
|
||||
GAHBCFG_HBSTLEN_SHIFT,
|
||||
.uframe_sched = 0,
|
||||
.external_id_pin_ctl = -1,
|
||||
.hibernation = -1,
|
||||
};
|
||||
|
||||
static const struct dwc2_core_params params_bcm2835 = {
|
||||
.otg_cap = 0, /* HNP/SRP capable */
|
||||
.otg_ver = 0, /* 1.3 */
|
||||
.dma_enable = 1,
|
||||
.dma_desc_enable = 0,
|
||||
.dma_desc_fs_enable = 0,
|
||||
.speed = 0, /* High Speed */
|
||||
.enable_dynamic_fifo = 1,
|
||||
.en_multiple_tx_fifo = 1,
|
||||
.host_rx_fifo_size = 774, /* 774 DWORDs */
|
||||
.host_nperio_tx_fifo_size = 256, /* 256 DWORDs */
|
||||
.host_perio_tx_fifo_size = 512, /* 512 DWORDs */
|
||||
.max_transfer_size = 65535,
|
||||
.max_packet_count = 511,
|
||||
.host_channels = 8,
|
||||
.phy_type = 1, /* UTMI */
|
||||
.phy_utmi_width = 8, /* 8 bits */
|
||||
.phy_ulpi_ddr = 0, /* Single */
|
||||
.phy_ulpi_ext_vbus = 0,
|
||||
.i2c_enable = 0,
|
||||
.ulpi_fs_ls = 0,
|
||||
.host_support_fs_ls_low_power = 0,
|
||||
.host_ls_low_power_phy_clk = 0, /* 48 MHz */
|
||||
.ts_dline = 0,
|
||||
.reload_ctl = 0,
|
||||
.ahbcfg = 0x10,
|
||||
.uframe_sched = 0,
|
||||
.external_id_pin_ctl = -1,
|
||||
.hibernation = -1,
|
||||
};
|
||||
|
||||
static const struct dwc2_core_params params_rk3066 = {
|
||||
.otg_cap = 2, /* non-HNP/non-SRP */
|
||||
.otg_ver = -1,
|
||||
.dma_enable = -1,
|
||||
.dma_desc_enable = 0,
|
||||
.dma_desc_fs_enable = 0,
|
||||
.speed = -1,
|
||||
.enable_dynamic_fifo = 1,
|
||||
.en_multiple_tx_fifo = -1,
|
||||
.host_rx_fifo_size = 525, /* 525 DWORDs */
|
||||
.host_nperio_tx_fifo_size = 128, /* 128 DWORDs */
|
||||
.host_perio_tx_fifo_size = 256, /* 256 DWORDs */
|
||||
.max_transfer_size = -1,
|
||||
.max_packet_count = -1,
|
||||
.host_channels = -1,
|
||||
.phy_type = -1,
|
||||
.phy_utmi_width = -1,
|
||||
.phy_ulpi_ddr = -1,
|
||||
.phy_ulpi_ext_vbus = -1,
|
||||
.i2c_enable = -1,
|
||||
.ulpi_fs_ls = -1,
|
||||
.host_support_fs_ls_low_power = -1,
|
||||
.host_ls_low_power_phy_clk = -1,
|
||||
.ts_dline = -1,
|
||||
.reload_ctl = -1,
|
||||
.ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
|
||||
GAHBCFG_HBSTLEN_SHIFT,
|
||||
.uframe_sched = -1,
|
||||
.external_id_pin_ctl = -1,
|
||||
.hibernation = -1,
|
||||
};
|
||||
|
||||
static const struct dwc2_core_params params_ltq = {
|
||||
.otg_cap = 2, /* non-HNP/non-SRP */
|
||||
.otg_ver = -1,
|
||||
.dma_enable = -1,
|
||||
.dma_desc_enable = -1,
|
||||
.dma_desc_fs_enable = -1,
|
||||
.speed = -1,
|
||||
.enable_dynamic_fifo = -1,
|
||||
.en_multiple_tx_fifo = -1,
|
||||
.host_rx_fifo_size = 288, /* 288 DWORDs */
|
||||
.host_nperio_tx_fifo_size = 128, /* 128 DWORDs */
|
||||
.host_perio_tx_fifo_size = 96, /* 96 DWORDs */
|
||||
.max_transfer_size = 65535,
|
||||
.max_packet_count = 511,
|
||||
.host_channels = -1,
|
||||
.phy_type = -1,
|
||||
.phy_utmi_width = -1,
|
||||
.phy_ulpi_ddr = -1,
|
||||
.phy_ulpi_ext_vbus = -1,
|
||||
.i2c_enable = -1,
|
||||
.ulpi_fs_ls = -1,
|
||||
.host_support_fs_ls_low_power = -1,
|
||||
.host_ls_low_power_phy_clk = -1,
|
||||
.ts_dline = -1,
|
||||
.reload_ctl = -1,
|
||||
.ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
|
||||
GAHBCFG_HBSTLEN_SHIFT,
|
||||
.uframe_sched = -1,
|
||||
.external_id_pin_ctl = -1,
|
||||
.hibernation = -1,
|
||||
};
|
||||
|
||||
static const struct dwc2_core_params params_amlogic = {
|
||||
.otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE,
|
||||
.otg_ver = -1,
|
||||
.dma_enable = 1,
|
||||
.dma_desc_enable = 0,
|
||||
.dma_desc_fs_enable = 0,
|
||||
.speed = DWC2_SPEED_PARAM_HIGH,
|
||||
.enable_dynamic_fifo = 1,
|
||||
.en_multiple_tx_fifo = -1,
|
||||
.host_rx_fifo_size = 512,
|
||||
.host_nperio_tx_fifo_size = 500,
|
||||
.host_perio_tx_fifo_size = 500,
|
||||
.max_transfer_size = -1,
|
||||
.max_packet_count = -1,
|
||||
.host_channels = 16,
|
||||
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
|
||||
.phy_utmi_width = -1,
|
||||
.phy_ulpi_ddr = -1,
|
||||
.phy_ulpi_ext_vbus = -1,
|
||||
.i2c_enable = -1,
|
||||
.ulpi_fs_ls = -1,
|
||||
.host_support_fs_ls_low_power = -1,
|
||||
.host_ls_low_power_phy_clk = -1,
|
||||
.ts_dline = -1,
|
||||
.reload_ctl = 1,
|
||||
.ahbcfg = GAHBCFG_HBSTLEN_INCR8 <<
|
||||
GAHBCFG_HBSTLEN_SHIFT,
|
||||
.uframe_sched = 0,
|
||||
.external_id_pin_ctl = -1,
|
||||
.hibernation = -1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Check the dr_mode against the module configuration and hardware
|
||||
* capabilities.
|
||||
@ -510,20 +351,6 @@ static void dwc2_driver_shutdown(struct platform_device *dev)
|
||||
disable_irq(hsotg->irq);
|
||||
}
|
||||
|
||||
static const struct of_device_id dwc2_of_match_table[] = {
|
||||
{ .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 },
|
||||
{ .compatible = "hisilicon,hi6220-usb", .data = ¶ms_hi6220 },
|
||||
{ .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 },
|
||||
{ .compatible = "lantiq,arx100-usb", .data = ¶ms_ltq },
|
||||
{ .compatible = "lantiq,xrx200-usb", .data = ¶ms_ltq },
|
||||
{ .compatible = "snps,dwc2", .data = NULL },
|
||||
{ .compatible = "samsung,s3c6400-hsotg", .data = NULL},
|
||||
{ .compatible = "amlogic,meson8b-usb", .data = ¶ms_amlogic },
|
||||
{ .compatible = "amlogic,meson-gxbb-usb", .data = ¶ms_amlogic },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
|
||||
|
||||
/**
|
||||
* dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg
|
||||
* driver
|
||||
@ -538,30 +365,10 @@ MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
|
||||
*/
|
||||
static int dwc2_driver_probe(struct platform_device *dev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct dwc2_core_params *params;
|
||||
struct dwc2_core_params defparams;
|
||||
struct dwc2_hsotg *hsotg;
|
||||
struct resource *res;
|
||||
int retval;
|
||||
|
||||
match = of_match_device(dwc2_of_match_table, &dev->dev);
|
||||
if (match && match->data) {
|
||||
params = match->data;
|
||||
} else {
|
||||
/* Default all params to autodetect */
|
||||
dwc2_set_all_params(&defparams, -1);
|
||||
params = &defparams;
|
||||
|
||||
/*
|
||||
* Disable descriptor dma mode by default as the HW can support
|
||||
* it, but does not support it for SPLIT transactions.
|
||||
* Disable it for FS devices as well.
|
||||
*/
|
||||
defparams.dma_desc_enable = 0;
|
||||
defparams.dma_desc_fs_enable = 0;
|
||||
}
|
||||
|
||||
hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL);
|
||||
if (!hsotg)
|
||||
return -ENOMEM;
|
||||
@ -591,13 +398,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
|
||||
|
||||
spin_lock_init(&hsotg->lock);
|
||||
|
||||
hsotg->core_params = devm_kzalloc(&dev->dev,
|
||||
sizeof(*hsotg->core_params), GFP_KERNEL);
|
||||
if (!hsotg->core_params)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc2_set_all_params(hsotg->core_params, -1);
|
||||
|
||||
hsotg->irq = platform_get_irq(dev, 0);
|
||||
if (hsotg->irq < 0) {
|
||||
dev_err(&dev->dev, "missing IRQ resource\n");
|
||||
@ -631,11 +431,12 @@ static int dwc2_driver_probe(struct platform_device *dev)
|
||||
if (retval)
|
||||
goto error;
|
||||
|
||||
/* Validate parameter values */
|
||||
dwc2_set_parameters(hsotg, params);
|
||||
|
||||
dwc2_force_dr_mode(hsotg);
|
||||
|
||||
retval = dwc2_init_params(hsotg);
|
||||
if (retval)
|
||||
goto error;
|
||||
|
||||
if (hsotg->dr_mode != USB_DR_MODE_HOST) {
|
||||
retval = dwc2_gadget_init(hsotg, hsotg->irq);
|
||||
if (retval)
|
||||
|
@ -62,7 +62,7 @@ config USB_DWC3_OMAP
|
||||
|
||||
config USB_DWC3_EXYNOS
|
||||
tristate "Samsung Exynos Platform"
|
||||
depends on ARCH_EXYNOS && OF || COMPILE_TEST
|
||||
depends on (ARCH_EXYNOS || COMPILE_TEST) && OF
|
||||
default USB_DWC3
|
||||
help
|
||||
Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside,
|
||||
@ -70,7 +70,7 @@ config USB_DWC3_EXYNOS
|
||||
|
||||
config USB_DWC3_PCI
|
||||
tristate "PCIe-based Platforms"
|
||||
depends on PCI
|
||||
depends on PCI && ACPI
|
||||
default USB_DWC3
|
||||
help
|
||||
If you're using the DesignWare Core IP with a PCIe, please say
|
||||
@ -98,7 +98,7 @@ config USB_DWC3_OF_SIMPLE
|
||||
|
||||
config USB_DWC3_ST
|
||||
tristate "STMicroelectronics Platforms"
|
||||
depends on ARCH_STI && OF
|
||||
depends on (ARCH_STI || COMPILE_TEST) && OF
|
||||
default USB_DWC3
|
||||
help
|
||||
STMicroelectronics SoCs with one DesignWare Core USB3 IP
|
||||
|
@ -3,7 +3,11 @@ CFLAGS_trace.o := -I$(src)
|
||||
|
||||
obj-$(CONFIG_USB_DWC3) += dwc3.o
|
||||
|
||||
dwc3-y := core.o debug.o trace.o
|
||||
dwc3-y := core.o
|
||||
|
||||
ifneq ($(CONFIG_FTRACE),)
|
||||
dwc3-y += trace.o
|
||||
endif
|
||||
|
||||
ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
|
||||
dwc3-y += host.o
|
||||
|
@ -169,33 +169,6 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_soft_reset - Issue soft reset
|
||||
* @dwc: Pointer to our controller context structure
|
||||
*/
|
||||
static int dwc3_soft_reset(struct dwc3 *dwc)
|
||||
{
|
||||
unsigned long timeout;
|
||||
u32 reg;
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(500);
|
||||
dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
|
||||
do {
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
if (!(reg & DWC3_DCTL_CSFTRST))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, timeout)) {
|
||||
dev_err(dwc->dev, "Reset Timed Out\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
} while (true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* dwc3_frame_length_adjustment - Adjusts frame length if required
|
||||
* @dwc3: Pointer to our controller context structure
|
||||
@ -229,7 +202,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
|
||||
static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
|
||||
struct dwc3_event_buffer *evt)
|
||||
{
|
||||
dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
|
||||
dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,7 +224,11 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
|
||||
|
||||
evt->dwc = dwc;
|
||||
evt->length = length;
|
||||
evt->buf = dma_alloc_coherent(dwc->dev, length,
|
||||
evt->cache = devm_kzalloc(dwc->dev, length, GFP_KERNEL);
|
||||
if (!evt->cache)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
evt->buf = dma_alloc_coherent(dwc->sysdev, length,
|
||||
&evt->dma, GFP_KERNEL);
|
||||
if (!evt->buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@ -305,13 +282,7 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
|
||||
struct dwc3_event_buffer *evt;
|
||||
|
||||
evt = dwc->ev_buf;
|
||||
dwc3_trace(trace_dwc3_core,
|
||||
"Event buf %p dma %08llx length %d\n",
|
||||
evt->buf, (unsigned long long) evt->dma,
|
||||
evt->length);
|
||||
|
||||
evt->lpos = 0;
|
||||
|
||||
dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
|
||||
lower_32_bits(evt->dma));
|
||||
dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
|
||||
@ -370,11 +341,11 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
|
||||
if (!WARN_ON(dwc->scratchbuf))
|
||||
return 0;
|
||||
|
||||
scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
|
||||
scratch_addr = dma_map_single(dwc->sysdev, dwc->scratchbuf,
|
||||
dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (dma_mapping_error(dwc->dev, scratch_addr)) {
|
||||
dev_err(dwc->dev, "failed to map scratch buffer\n");
|
||||
if (dma_mapping_error(dwc->sysdev, scratch_addr)) {
|
||||
dev_err(dwc->sysdev, "failed to map scratch buffer\n");
|
||||
ret = -EFAULT;
|
||||
goto err0;
|
||||
}
|
||||
@ -398,7 +369,7 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
|
||||
dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
|
||||
DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
|
||||
|
||||
err0:
|
||||
@ -417,7 +388,7 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
|
||||
if (!WARN_ON(dwc->scratchbuf))
|
||||
return;
|
||||
|
||||
dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
|
||||
dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
|
||||
DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
|
||||
kfree(dwc->scratchbuf);
|
||||
}
|
||||
@ -428,9 +399,6 @@ static void dwc3_core_num_eps(struct dwc3 *dwc)
|
||||
|
||||
dwc->num_in_eps = DWC3_NUM_IN_EPS(parms);
|
||||
dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps;
|
||||
|
||||
dwc3_trace(trace_dwc3_core, "found %d IN and %d OUT endpoints",
|
||||
dwc->num_in_eps, dwc->num_out_eps);
|
||||
}
|
||||
|
||||
static void dwc3_cache_hwparams(struct dwc3 *dwc)
|
||||
@ -524,13 +492,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
|
||||
/* Making sure the interface and PHY are operational */
|
||||
ret = dwc3_soft_reset(dwc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
udelay(1);
|
||||
|
||||
ret = dwc3_ulpi_init(dwc);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -594,19 +555,12 @@ static void dwc3_core_exit(struct dwc3 *dwc)
|
||||
phy_power_off(dwc->usb3_generic_phy);
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_core_init - Low-level initialization of DWC3 Core
|
||||
* @dwc: Pointer to our controller context structure
|
||||
*
|
||||
* Returns 0 on success otherwise negative errno.
|
||||
*/
|
||||
static int dwc3_core_init(struct dwc3 *dwc)
|
||||
static bool dwc3_core_is_valid(struct dwc3 *dwc)
|
||||
{
|
||||
u32 hwparams4 = dwc->hwparams.hwparams4;
|
||||
u32 reg;
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
|
||||
|
||||
/* This should read as U3 followed by revision number */
|
||||
if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
|
||||
/* Detected DWC_usb3 IP */
|
||||
@ -616,36 +570,16 @@ static int dwc3_core_init(struct dwc3 *dwc)
|
||||
dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
|
||||
dwc->revision |= DWC3_REVISION_IS_DWC31;
|
||||
} else {
|
||||
dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
|
||||
ret = -ENODEV;
|
||||
goto err0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write Linux Version Code to our GUID register so it's easy to figure
|
||||
* out which kernel version a bug was found.
|
||||
*/
|
||||
dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Handle USB2.0-only core configuration */
|
||||
if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
|
||||
DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
|
||||
if (dwc->maximum_speed == USB_SPEED_SUPER)
|
||||
dwc->maximum_speed = USB_SPEED_HIGH;
|
||||
}
|
||||
|
||||
/* issue device SoftReset too */
|
||||
ret = dwc3_soft_reset(dwc);
|
||||
if (ret)
|
||||
goto err0;
|
||||
|
||||
ret = dwc3_core_soft_reset(dwc);
|
||||
if (ret)
|
||||
goto err0;
|
||||
|
||||
ret = dwc3_phy_setup(dwc);
|
||||
if (ret)
|
||||
goto err0;
|
||||
static void dwc3_core_setup_global_control(struct dwc3 *dwc)
|
||||
{
|
||||
u32 hwparams4 = dwc->hwparams.hwparams4;
|
||||
u32 reg;
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
||||
reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
|
||||
@ -683,13 +617,13 @@ static int dwc3_core_init(struct dwc3 *dwc)
|
||||
reg |= DWC3_GCTL_GBLHIBERNATIONEN;
|
||||
break;
|
||||
default:
|
||||
dwc3_trace(trace_dwc3_core, "No power optimization available\n");
|
||||
/* nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if current dwc3 is on simulation board */
|
||||
if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) {
|
||||
dwc3_trace(trace_dwc3_core,
|
||||
"running on FPGA platform\n");
|
||||
dev_info(dwc->dev, "Running with FPGA optmizations\n");
|
||||
dwc->is_fpga = true;
|
||||
}
|
||||
|
||||
@ -714,7 +648,47 @@ static int dwc3_core_init(struct dwc3 *dwc)
|
||||
reg |= DWC3_GCTL_U2RSTECN;
|
||||
|
||||
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_core_init - Low-level initialization of DWC3 Core
|
||||
* @dwc: Pointer to our controller context structure
|
||||
*
|
||||
* Returns 0 on success otherwise negative errno.
|
||||
*/
|
||||
static int dwc3_core_init(struct dwc3 *dwc)
|
||||
{
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
if (!dwc3_core_is_valid(dwc)) {
|
||||
dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
|
||||
ret = -ENODEV;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write Linux Version Code to our GUID register so it's easy to figure
|
||||
* out which kernel version a bug was found.
|
||||
*/
|
||||
dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
|
||||
|
||||
/* Handle USB2.0-only core configuration */
|
||||
if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
|
||||
DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
|
||||
if (dwc->maximum_speed == USB_SPEED_SUPER)
|
||||
dwc->maximum_speed = USB_SPEED_HIGH;
|
||||
}
|
||||
|
||||
ret = dwc3_core_soft_reset(dwc);
|
||||
if (ret)
|
||||
goto err0;
|
||||
|
||||
ret = dwc3_phy_setup(dwc);
|
||||
if (ret)
|
||||
goto err0;
|
||||
|
||||
dwc3_core_setup_global_control(dwc);
|
||||
dwc3_core_num_eps(dwc);
|
||||
|
||||
ret = dwc3_setup_scratch_buffers(dwc);
|
||||
@ -766,6 +740,16 @@ static int dwc3_core_init(struct dwc3 *dwc)
|
||||
dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable hardware control of sending remote wakeup in HS when
|
||||
* the device is in the L1 state.
|
||||
*/
|
||||
if (dwc->revision >= DWC3_REVISION_290A) {
|
||||
reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
|
||||
reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
|
||||
dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
@ -919,57 +903,13 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
|
||||
}
|
||||
}
|
||||
|
||||
#define DWC3_ALIGN_MASK (16 - 1)
|
||||
|
||||
static int dwc3_probe(struct platform_device *pdev)
|
||||
static void dwc3_get_properties(struct dwc3 *dwc)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct dwc3 *dwc;
|
||||
struct device *dev = dwc->dev;
|
||||
u8 lpm_nyet_threshold;
|
||||
u8 tx_de_emphasis;
|
||||
u8 hird_threshold;
|
||||
|
||||
int ret;
|
||||
|
||||
void __iomem *regs;
|
||||
void *mem;
|
||||
|
||||
mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
|
||||
dwc->mem = mem;
|
||||
dwc->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "missing memory resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dwc->xhci_resources[0].start = res->start;
|
||||
dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
|
||||
DWC3_XHCI_REGS_END;
|
||||
dwc->xhci_resources[0].flags = res->flags;
|
||||
dwc->xhci_resources[0].name = res->name;
|
||||
|
||||
res->start += DWC3_GLOBALS_REGS_START;
|
||||
|
||||
/*
|
||||
* Request memory region but exclude xHCI regs,
|
||||
* since it will be requested by the xhci-plat driver.
|
||||
*/
|
||||
regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(regs)) {
|
||||
ret = PTR_ERR(regs);
|
||||
goto err0;
|
||||
}
|
||||
|
||||
dwc->regs = regs;
|
||||
dwc->regs_size = resource_size(res);
|
||||
|
||||
/* default to highest possible threshold */
|
||||
lpm_nyet_threshold = 0xff;
|
||||
|
||||
@ -986,6 +926,13 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
dwc->dr_mode = usb_get_dr_mode(dev);
|
||||
dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
|
||||
|
||||
dwc->sysdev_is_parent = device_property_read_bool(dev,
|
||||
"linux,sysdev_is_parent");
|
||||
if (dwc->sysdev_is_parent)
|
||||
dwc->sysdev = dwc->dev->parent;
|
||||
else
|
||||
dwc->sysdev = dwc->dev;
|
||||
|
||||
dwc->has_lpm_erratum = device_property_read_bool(dev,
|
||||
"snps,has-lpm-erratum");
|
||||
device_property_read_u8(dev, "snps,lpm-nyet-threshold",
|
||||
@ -1041,6 +988,112 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
dwc->hird_threshold = hird_threshold
|
||||
| (dwc->is_utmi_l1_suspend << 4);
|
||||
|
||||
dwc->imod_interval = 0;
|
||||
}
|
||||
|
||||
/* check whether the core supports IMOD */
|
||||
bool dwc3_has_imod(struct dwc3 *dwc)
|
||||
{
|
||||
return ((dwc3_is_usb3(dwc) &&
|
||||
dwc->revision >= DWC3_REVISION_300A) ||
|
||||
(dwc3_is_usb31(dwc) &&
|
||||
dwc->revision >= DWC3_USB31_REVISION_120A));
|
||||
}
|
||||
|
||||
static void dwc3_check_params(struct dwc3 *dwc)
|
||||
{
|
||||
struct device *dev = dwc->dev;
|
||||
|
||||
/* Check for proper value of imod_interval */
|
||||
if (dwc->imod_interval && !dwc3_has_imod(dwc)) {
|
||||
dev_warn(dwc->dev, "Interrupt moderation not supported\n");
|
||||
dwc->imod_interval = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for STAR 9000961433 which affects only version
|
||||
* 3.00a of the DWC_usb3 core. This prevents the controller
|
||||
* interrupt from being masked while handling events. IMOD
|
||||
* allows us to work around this issue. Enable it for the
|
||||
* affected version.
|
||||
*/
|
||||
if (!dwc->imod_interval &&
|
||||
(dwc->revision == DWC3_REVISION_300A))
|
||||
dwc->imod_interval = 1;
|
||||
|
||||
/* Check the maximum_speed parameter */
|
||||
switch (dwc->maximum_speed) {
|
||||
case USB_SPEED_LOW:
|
||||
case USB_SPEED_FULL:
|
||||
case USB_SPEED_HIGH:
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "invalid maximum_speed parameter %d\n",
|
||||
dwc->maximum_speed);
|
||||
/* fall through */
|
||||
case USB_SPEED_UNKNOWN:
|
||||
/* default to superspeed */
|
||||
dwc->maximum_speed = USB_SPEED_SUPER;
|
||||
|
||||
/*
|
||||
* default to superspeed plus if we are capable.
|
||||
*/
|
||||
if (dwc3_is_usb31(dwc) &&
|
||||
(DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
|
||||
DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
|
||||
dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int dwc3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct dwc3 *dwc;
|
||||
|
||||
int ret;
|
||||
|
||||
void __iomem *regs;
|
||||
|
||||
dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
|
||||
if (!dwc)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "missing memory resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dwc->xhci_resources[0].start = res->start;
|
||||
dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
|
||||
DWC3_XHCI_REGS_END;
|
||||
dwc->xhci_resources[0].flags = res->flags;
|
||||
dwc->xhci_resources[0].name = res->name;
|
||||
|
||||
res->start += DWC3_GLOBALS_REGS_START;
|
||||
|
||||
/*
|
||||
* Request memory region but exclude xHCI regs,
|
||||
* since it will be requested by the xhci-plat driver.
|
||||
*/
|
||||
regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(regs)) {
|
||||
ret = PTR_ERR(regs);
|
||||
goto err0;
|
||||
}
|
||||
|
||||
dwc->regs = regs;
|
||||
dwc->regs_size = resource_size(res);
|
||||
|
||||
dwc3_get_properties(dwc);
|
||||
|
||||
platform_set_drvdata(pdev, dwc);
|
||||
dwc3_cache_hwparams(dwc);
|
||||
|
||||
@ -1050,12 +1103,6 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
|
||||
spin_lock_init(&dwc->lock);
|
||||
|
||||
if (!dev->dma_mask) {
|
||||
dev->dma_mask = dev->parent->dma_mask;
|
||||
dev->dma_parms = dev->parent->dma_parms;
|
||||
dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);
|
||||
}
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
|
||||
@ -1087,32 +1134,7 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
goto err4;
|
||||
}
|
||||
|
||||
/* Check the maximum_speed parameter */
|
||||
switch (dwc->maximum_speed) {
|
||||
case USB_SPEED_LOW:
|
||||
case USB_SPEED_FULL:
|
||||
case USB_SPEED_HIGH:
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "invalid maximum_speed parameter %d\n",
|
||||
dwc->maximum_speed);
|
||||
/* fall through */
|
||||
case USB_SPEED_UNKNOWN:
|
||||
/* default to superspeed */
|
||||
dwc->maximum_speed = USB_SPEED_SUPER;
|
||||
|
||||
/*
|
||||
* default to superspeed plus if we are capable.
|
||||
*/
|
||||
if (dwc3_is_usb31(dwc) &&
|
||||
(DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
|
||||
DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
|
||||
dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
|
||||
|
||||
break;
|
||||
}
|
||||
dwc3_check_params(dwc);
|
||||
|
||||
ret = dwc3_core_init_mode(dwc);
|
||||
if (ret)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
@ -37,6 +38,7 @@
|
||||
#define DWC3_MSG_MAX 500
|
||||
|
||||
/* Global constants */
|
||||
#define DWC3_PULL_UP_TIMEOUT 500 /* ms */
|
||||
#define DWC3_ZLP_BUF_SIZE 1024 /* size of a superspeed bulk */
|
||||
#define DWC3_EP0_BOUNCE_SIZE 512
|
||||
#define DWC3_ENDPOINTS_NUM 32
|
||||
@ -65,6 +67,7 @@
|
||||
#define DWC3_DEVICE_EVENT_OVERFLOW 11
|
||||
|
||||
#define DWC3_GEVNTCOUNT_MASK 0xfffc
|
||||
#define DWC3_GEVNTCOUNT_EHB (1 << 31)
|
||||
#define DWC3_GSNPSID_MASK 0xffff0000
|
||||
#define DWC3_GSNPSREV_MASK 0xffff
|
||||
|
||||
@ -147,6 +150,8 @@
|
||||
#define DWC3_DEPCMDPAR0 0x08
|
||||
#define DWC3_DEPCMD 0x0c
|
||||
|
||||
#define DWC3_DEV_IMOD(n) (0xca00 + (n * 0x4))
|
||||
|
||||
/* OTG Registers */
|
||||
#define DWC3_OCFG 0xcc00
|
||||
#define DWC3_OCTL 0xcc04
|
||||
@ -198,6 +203,9 @@
|
||||
#define DWC3_GCTL_GBLHIBERNATIONEN (1 << 1)
|
||||
#define DWC3_GCTL_DSBLCLKGTNG (1 << 0)
|
||||
|
||||
/* Global User Control 1 Register */
|
||||
#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW (1 << 24)
|
||||
|
||||
/* Global USB2 PHY Configuration Register */
|
||||
#define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31)
|
||||
#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS (1 << 30)
|
||||
@ -450,6 +458,8 @@
|
||||
#define DWC3_DEPCMD_SETTRANSFRESOURCE (0x02 << 0)
|
||||
#define DWC3_DEPCMD_SETEPCONFIG (0x01 << 0)
|
||||
|
||||
#define DWC3_DEPCMD_CMD(x) ((x) & 0xf)
|
||||
|
||||
/* The EP number goes 0..31 so ep0 is always out and ep1 is always in */
|
||||
#define DWC3_DALEPENA_EP(n) (1 << n)
|
||||
|
||||
@ -458,6 +468,11 @@
|
||||
#define DWC3_DEPCMD_TYPE_BULK 2
|
||||
#define DWC3_DEPCMD_TYPE_INTR 3
|
||||
|
||||
#define DWC3_DEV_IMOD_COUNT_SHIFT 16
|
||||
#define DWC3_DEV_IMOD_COUNT_MASK (0xffff << 16)
|
||||
#define DWC3_DEV_IMOD_INTERVAL_SHIFT 0
|
||||
#define DWC3_DEV_IMOD_INTERVAL_MASK (0xffff << 0)
|
||||
|
||||
/* Structures */
|
||||
|
||||
struct dwc3_trb;
|
||||
@ -465,6 +480,7 @@ struct dwc3_trb;
|
||||
/**
|
||||
* struct dwc3_event_buffer - Software event buffer representation
|
||||
* @buf: _THE_ buffer
|
||||
* @cache: The buffer cache used in the threaded interrupt
|
||||
* @length: size of this buffer
|
||||
* @lpos: event offset
|
||||
* @count: cache of last read event count register
|
||||
@ -474,6 +490,7 @@ struct dwc3_trb;
|
||||
*/
|
||||
struct dwc3_event_buffer {
|
||||
void *buf;
|
||||
void *cache;
|
||||
unsigned length;
|
||||
unsigned int lpos;
|
||||
unsigned int count;
|
||||
@ -499,6 +516,7 @@ struct dwc3_event_buffer {
|
||||
* @endpoint: usb endpoint
|
||||
* @pending_list: list of pending requests for this endpoint
|
||||
* @started_list: list of started requests on this endpoint
|
||||
* @wait_end_transfer: wait_queue_head_t for waiting on End Transfer complete
|
||||
* @lock: spinlock for endpoint request queue traversal
|
||||
* @regs: pointer to first endpoint register
|
||||
* @trb_pool: array of transaction buffers
|
||||
@ -524,12 +542,13 @@ struct dwc3_ep {
|
||||
struct list_head pending_list;
|
||||
struct list_head started_list;
|
||||
|
||||
wait_queue_head_t wait_end_transfer;
|
||||
|
||||
spinlock_t lock;
|
||||
void __iomem *regs;
|
||||
|
||||
struct dwc3_trb *trb_pool;
|
||||
dma_addr_t trb_pool_dma;
|
||||
const struct usb_ss_ep_comp_descriptor *comp_desc;
|
||||
struct dwc3 *dwc;
|
||||
|
||||
u32 saved_state;
|
||||
@ -540,6 +559,8 @@ struct dwc3_ep {
|
||||
#define DWC3_EP_BUSY (1 << 4)
|
||||
#define DWC3_EP_PENDING_REQUEST (1 << 5)
|
||||
#define DWC3_EP_MISSED_ISOC (1 << 6)
|
||||
#define DWC3_EP_END_TRANSFER_PENDING (1 << 7)
|
||||
#define DWC3_EP_TRANSFER_STARTED (1 << 8)
|
||||
|
||||
/* This last one is specific to EP0 */
|
||||
#define DWC3_EP0_DIR_IN (1 << 31)
|
||||
@ -703,7 +724,7 @@ struct dwc3_hwparams {
|
||||
* @dep: struct dwc3_ep owning this request
|
||||
* @sg: pointer to first incomplete sg
|
||||
* @num_pending_sgs: counter to pending sgs
|
||||
* @first_trb_index: index to first trb used by this request
|
||||
* @remaining: amount of data remaining
|
||||
* @epnum: endpoint number to which this request refers
|
||||
* @trb: pointer to struct dwc3_trb
|
||||
* @trb_dma: DMA address of @trb
|
||||
@ -718,7 +739,7 @@ struct dwc3_request {
|
||||
struct scatterlist *sg;
|
||||
|
||||
unsigned num_pending_sgs;
|
||||
u8 first_trb_index;
|
||||
unsigned remaining;
|
||||
u8 epnum;
|
||||
struct dwc3_trb *trb;
|
||||
dma_addr_t trb_dma;
|
||||
@ -748,6 +769,7 @@ struct dwc3_scratchpad_array {
|
||||
* @ep0_usb_req: dummy req used while handling STD USB requests
|
||||
* @ep0_bounce_addr: dma address of ep0_bounce
|
||||
* @scratch_addr: dma address of scratchbuf
|
||||
* @ep0_in_setup: one control transfer is completed and enter setup phase
|
||||
* @lock: for synchronizing
|
||||
* @dev: pointer to our struct device
|
||||
* @xhci: pointer to our xHCI child
|
||||
@ -784,7 +806,6 @@ struct dwc3_scratchpad_array {
|
||||
* @ep0state: state of endpoint zero
|
||||
* @link_state: link state
|
||||
* @speed: device speed (super, high, full, low)
|
||||
* @mem: points to start of memory which is used for this struct.
|
||||
* @hwparams: copy of hwparams registers
|
||||
* @root: debugfs root folder pointer
|
||||
* @regset: debugfs pointer to regdump file
|
||||
@ -798,6 +819,7 @@ struct dwc3_scratchpad_array {
|
||||
* @ep0_bounced: true when we used bounce buffer
|
||||
* @ep0_expect_in: true when we expect a DATA IN transfer
|
||||
* @has_hibernation: true when dwc3 was configured with Hibernation
|
||||
* @sysdev_is_parent: true when dwc3 device has a parent driver
|
||||
* @has_lpm_erratum: true when core was configured with LPM Erratum. Note that
|
||||
* there's now way for software to detect this in runtime.
|
||||
* @is_utmi_l1_suspend: the core asserts output signal
|
||||
@ -833,6 +855,8 @@ struct dwc3_scratchpad_array {
|
||||
* 1 - -3.5dB de-emphasis
|
||||
* 2 - No de-emphasis
|
||||
* 3 - Reserved
|
||||
* @imod_interval: set the interrupt moderation interval in 250ns
|
||||
* increments or 0 to disable.
|
||||
*/
|
||||
struct dwc3 {
|
||||
struct usb_ctrlrequest *ctrl_req;
|
||||
@ -846,11 +870,13 @@ struct dwc3 {
|
||||
dma_addr_t ep0_bounce_addr;
|
||||
dma_addr_t scratch_addr;
|
||||
struct dwc3_request ep0_usb_req;
|
||||
struct completion ep0_in_setup;
|
||||
|
||||
/* device lock */
|
||||
spinlock_t lock;
|
||||
|
||||
struct device *dev;
|
||||
struct device *sysdev;
|
||||
|
||||
struct platform_device *xhci;
|
||||
struct resource xhci_resources[DWC3_XHCI_RESOURCES_NUM];
|
||||
@ -909,6 +935,7 @@ struct dwc3 {
|
||||
#define DWC3_REVISION_260A 0x5533260a
|
||||
#define DWC3_REVISION_270A 0x5533270a
|
||||
#define DWC3_REVISION_280A 0x5533280a
|
||||
#define DWC3_REVISION_290A 0x5533290a
|
||||
#define DWC3_REVISION_300A 0x5533300a
|
||||
#define DWC3_REVISION_310A 0x5533310a
|
||||
|
||||
@ -918,6 +945,7 @@ struct dwc3 {
|
||||
*/
|
||||
#define DWC3_REVISION_IS_DWC31 0x80000000
|
||||
#define DWC3_USB31_REVISION_110A (0x3131302a | DWC3_REVISION_IS_DWC31)
|
||||
#define DWC3_USB31_REVISION_120A (0x3132302a | DWC3_REVISION_IS_DWC31)
|
||||
|
||||
enum dwc3_ep0_next ep0_next_event;
|
||||
enum dwc3_ep0_state ep0state;
|
||||
@ -934,8 +962,6 @@ struct dwc3 {
|
||||
u8 num_out_eps;
|
||||
u8 num_in_eps;
|
||||
|
||||
void *mem;
|
||||
|
||||
struct dwc3_hwparams hwparams;
|
||||
struct dentry *root;
|
||||
struct debugfs_regset32 *regset;
|
||||
@ -952,6 +978,7 @@ struct dwc3 {
|
||||
unsigned ep0_bounced:1;
|
||||
unsigned ep0_expect_in:1;
|
||||
unsigned has_hibernation:1;
|
||||
unsigned sysdev_is_parent:1;
|
||||
unsigned has_lpm_erratum:1;
|
||||
unsigned is_utmi_l1_suspend:1;
|
||||
unsigned is_fpga:1;
|
||||
@ -978,6 +1005,8 @@ struct dwc3 {
|
||||
|
||||
unsigned tx_de_emphasis_quirk:1;
|
||||
unsigned tx_de_emphasis:2;
|
||||
|
||||
u16 imod_interval;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -1039,12 +1068,16 @@ struct dwc3_event_depevt {
|
||||
/* Control-only Status */
|
||||
#define DEPEVT_STATUS_CONTROL_DATA 1
|
||||
#define DEPEVT_STATUS_CONTROL_STATUS 2
|
||||
#define DEPEVT_STATUS_CONTROL_PHASE(n) ((n) & 3)
|
||||
|
||||
/* In response to Start Transfer */
|
||||
#define DEPEVT_TRANSFER_NO_RESOURCE 1
|
||||
#define DEPEVT_TRANSFER_BUS_EXPIRY 2
|
||||
|
||||
u32 parameters:16;
|
||||
|
||||
/* For Command Complete Events */
|
||||
#define DEPEVT_PARAMETER_CMD(n) (((n) & (0xf << 8)) >> 8)
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
@ -1133,12 +1166,20 @@ struct dwc3_gadget_ep_cmd_params {
|
||||
void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
|
||||
u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
|
||||
|
||||
/* check whether we are on the DWC_usb3 core */
|
||||
static inline bool dwc3_is_usb3(struct dwc3 *dwc)
|
||||
{
|
||||
return !(dwc->revision & DWC3_REVISION_IS_DWC31);
|
||||
}
|
||||
|
||||
/* check whether we are on the DWC_usb31 core */
|
||||
static inline bool dwc3_is_usb31(struct dwc3 *dwc)
|
||||
{
|
||||
return !!(dwc->revision & DWC3_REVISION_IS_DWC31);
|
||||
}
|
||||
|
||||
bool dwc3_has_imod(struct dwc3 *dwc);
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
|
||||
int dwc3_host_init(struct dwc3 *dwc);
|
||||
void dwc3_host_exit(struct dwc3 *dwc);
|
||||
|
@ -1,32 +0,0 @@
|
||||
/**
|
||||
* debug.c - DesignWare USB3 DRD Controller Debug/Trace Support
|
||||
*
|
||||
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
|
||||
*
|
||||
* Author: Felipe Balbi <balbi@ti.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 of
|
||||
* the License as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
|
||||
trace(&vaf);
|
||||
|
||||
va_end(args);
|
||||
}
|
@ -124,6 +124,22 @@ dwc3_gadget_link_string(enum dwc3_link_state link_state)
|
||||
}
|
||||
}
|
||||
|
||||
static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case EP0_UNCONNECTED:
|
||||
return "Unconnected";
|
||||
case EP0_SETUP_PHASE:
|
||||
return "Setup Phase";
|
||||
case EP0_DATA_PHASE:
|
||||
return "Data Phase";
|
||||
case EP0_STATUS_PHASE:
|
||||
return "Status Phase";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc3_gadget_event_string - returns event name
|
||||
* @event: the event code
|
||||
@ -184,10 +200,11 @@ dwc3_gadget_event_string(const struct dwc3_event_devt *event)
|
||||
* @event: then event code
|
||||
*/
|
||||
static inline const char *
|
||||
dwc3_ep_event_string(const struct dwc3_event_depevt *event)
|
||||
dwc3_ep_event_string(const struct dwc3_event_depevt *event, u32 ep0state)
|
||||
{
|
||||
u8 epnum = event->endpoint_number;
|
||||
static char str[256];
|
||||
size_t len;
|
||||
int status;
|
||||
int ret;
|
||||
|
||||
@ -199,6 +216,10 @@ dwc3_ep_event_string(const struct dwc3_event_depevt *event)
|
||||
switch (event->endpoint_event) {
|
||||
case DWC3_DEPEVT_XFERCOMPLETE:
|
||||
strcat(str, "Transfer Complete");
|
||||
len = strlen(str);
|
||||
|
||||
if (epnum <= 1)
|
||||
sprintf(str + len, " [%s]", dwc3_ep0_state_string(ep0state));
|
||||
break;
|
||||
case DWC3_DEPEVT_XFERINPROGRESS:
|
||||
strcat(str, "Transfer In-Progress");
|
||||
@ -207,6 +228,19 @@ dwc3_ep_event_string(const struct dwc3_event_depevt *event)
|
||||
strcat(str, "Transfer Not Ready");
|
||||
status = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE;
|
||||
strcat(str, status ? " (Active)" : " (Not Active)");
|
||||
|
||||
/* Control Endpoints */
|
||||
if (epnum <= 1) {
|
||||
int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status);
|
||||
|
||||
switch (phase) {
|
||||
case DEPEVT_STATUS_CONTROL_DATA:
|
||||
strcat(str, " [Data Phase]");
|
||||
break;
|
||||
case DEPEVT_STATUS_CONTROL_STATUS:
|
||||
strcat(str, " [Status Phase]");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DWC3_DEPEVT_RXTXFIFOEVT:
|
||||
strcat(str, "FIFO");
|
||||
@ -270,14 +304,14 @@ static inline const char *dwc3_gadget_event_type_string(u8 event)
|
||||
}
|
||||
}
|
||||
|
||||
static inline const char *dwc3_decode_event(u32 event)
|
||||
static inline const char *dwc3_decode_event(u32 event, u32 ep0state)
|
||||
{
|
||||
const union dwc3_event evt = (union dwc3_event) event;
|
||||
|
||||
if (evt.type.is_devspec)
|
||||
return dwc3_gadget_event_string(&evt.devt);
|
||||
else
|
||||
return dwc3_ep_event_string(&evt.depevt);
|
||||
return dwc3_ep_event_string(&evt.depevt, ep0state);
|
||||
}
|
||||
|
||||
static inline const char *dwc3_ep_cmd_status_string(int status)
|
||||
@ -310,7 +344,6 @@ static inline const char *dwc3_gadget_generic_cmd_status_string(int status)
|
||||
}
|
||||
}
|
||||
|
||||
void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
extern void dwc3_debugfs_init(struct dwc3 *);
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/usb/usb_phy_generic.h>
|
||||
@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
|
||||
if (!exynos)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Right now device-tree probed devices don't get dma_mask set.
|
||||
* Since shared usb code relies on it, set it here for now.
|
||||
* Once we move to full device tree support this will vanish off.
|
||||
*/
|
||||
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, exynos);
|
||||
|
||||
exynos->dev = dev;
|
||||
|
@ -39,6 +39,27 @@
|
||||
#define PCI_DEVICE_ID_INTEL_APL 0x5aaa
|
||||
#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0
|
||||
|
||||
#define PCI_INTEL_BXT_DSM_UUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
|
||||
#define PCI_INTEL_BXT_FUNC_PMU_PWR 4
|
||||
#define PCI_INTEL_BXT_STATE_D0 0
|
||||
#define PCI_INTEL_BXT_STATE_D3 3
|
||||
|
||||
/**
|
||||
* struct dwc3_pci - Driver private structure
|
||||
* @dwc3: child dwc3 platform_device
|
||||
* @pci: our link to PCI bus
|
||||
* @uuid: _DSM UUID
|
||||
* @has_dsm_for_pm: true for devices which need to run _DSM on runtime PM
|
||||
*/
|
||||
struct dwc3_pci {
|
||||
struct platform_device *dwc3;
|
||||
struct pci_dev *pci;
|
||||
|
||||
u8 uuid[16];
|
||||
|
||||
unsigned int has_dsm_for_pm:1;
|
||||
};
|
||||
|
||||
static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
|
||||
static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
|
||||
|
||||
@ -48,8 +69,21 @@ static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3)
|
||||
static int dwc3_pci_quirks(struct dwc3_pci *dwc)
|
||||
{
|
||||
struct platform_device *dwc3 = dwc->dwc3;
|
||||
struct pci_dev *pdev = dwc->pci;
|
||||
int ret;
|
||||
|
||||
struct property_entry sysdev_property[] = {
|
||||
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
|
||||
{ },
|
||||
};
|
||||
|
||||
ret = platform_device_add_properties(dwc3, sysdev_property);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
|
||||
pdev->device == PCI_DEVICE_ID_AMD_NL_USB) {
|
||||
struct property_entry properties[] = {
|
||||
@ -89,6 +123,12 @@ static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (pdev->device == PCI_DEVICE_ID_INTEL_BXT ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_BXT_M) {
|
||||
acpi_str_to_uuid(PCI_INTEL_BXT_DSM_UUID, dwc->uuid);
|
||||
dwc->has_dsm_for_pm = true;
|
||||
}
|
||||
|
||||
if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) {
|
||||
struct gpio_desc *gpio;
|
||||
|
||||
@ -139,8 +179,8 @@ static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3)
|
||||
static int dwc3_pci_probe(struct pci_dev *pci,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct dwc3_pci *dwc;
|
||||
struct resource res[2];
|
||||
struct platform_device *dwc3;
|
||||
int ret;
|
||||
struct device *dev = &pci->dev;
|
||||
|
||||
@ -152,11 +192,13 @@ static int dwc3_pci_probe(struct pci_dev *pci,
|
||||
|
||||
pci_set_master(pci);
|
||||
|
||||
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
|
||||
if (!dwc3) {
|
||||
dev_err(dev, "couldn't allocate dwc3 device\n");
|
||||
dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
|
||||
if (!dwc)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
|
||||
if (!dwc->dwc3)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
|
||||
|
||||
@ -169,20 +211,21 @@ static int dwc3_pci_probe(struct pci_dev *pci,
|
||||
res[1].name = "dwc_usb3";
|
||||
res[1].flags = IORESOURCE_IRQ;
|
||||
|
||||
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
|
||||
ret = platform_device_add_resources(dwc->dwc3, res, ARRAY_SIZE(res));
|
||||
if (ret) {
|
||||
dev_err(dev, "couldn't add resources to dwc3 device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dwc3->dev.parent = dev;
|
||||
ACPI_COMPANION_SET(&dwc3->dev, ACPI_COMPANION(dev));
|
||||
dwc->pci = pci;
|
||||
dwc->dwc3->dev.parent = dev;
|
||||
ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev));
|
||||
|
||||
ret = dwc3_pci_quirks(pci, dwc3);
|
||||
ret = dwc3_pci_quirks(dwc);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = platform_device_add(dwc3);
|
||||
ret = platform_device_add(dwc->dwc3);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register dwc3 device\n");
|
||||
goto err;
|
||||
@ -190,21 +233,23 @@ static int dwc3_pci_probe(struct pci_dev *pci,
|
||||
|
||||
device_init_wakeup(dev, true);
|
||||
device_set_run_wake(dev, true);
|
||||
pci_set_drvdata(pci, dwc3);
|
||||
pci_set_drvdata(pci, dwc);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
platform_device_put(dwc3);
|
||||
platform_device_put(dwc->dwc3);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dwc3_pci_remove(struct pci_dev *pci)
|
||||
{
|
||||
struct dwc3_pci *dwc = pci_get_drvdata(pci);
|
||||
|
||||
device_init_wakeup(&pci->dev, false);
|
||||
pm_runtime_get(&pci->dev);
|
||||
acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev));
|
||||
platform_device_unregister(pci_get_drvdata(pci));
|
||||
platform_device_unregister(dwc->dwc3);
|
||||
}
|
||||
|
||||
static const struct pci_device_id dwc3_pci_id_table[] = {
|
||||
@ -234,40 +279,75 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
|
||||
|
||||
#if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP)
|
||||
static int dwc3_pci_dsm(struct dwc3_pci *dwc, int param)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
union acpi_object tmp;
|
||||
union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp);
|
||||
|
||||
if (!dwc->has_dsm_for_pm)
|
||||
return 0;
|
||||
|
||||
tmp.type = ACPI_TYPE_INTEGER;
|
||||
tmp.integer.value = param;
|
||||
|
||||
obj = acpi_evaluate_dsm(ACPI_HANDLE(&dwc->pci->dev), dwc->uuid,
|
||||
1, PCI_INTEL_BXT_FUNC_PMU_PWR, &argv4);
|
||||
if (!obj) {
|
||||
dev_err(&dwc->pci->dev, "failed to evaluate _DSM\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ACPI_FREE(obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM || CONFIG_PM_SLEEP */
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int dwc3_pci_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct dwc3_pci *dwc = dev_get_drvdata(dev);
|
||||
|
||||
if (device_run_wake(dev))
|
||||
return 0;
|
||||
return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static int dwc3_pci_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *dwc3 = dev_get_drvdata(dev);
|
||||
struct dwc3_pci *dwc = dev_get_drvdata(dev);
|
||||
struct platform_device *dwc3 = dwc->dwc3;
|
||||
int ret;
|
||||
|
||||
ret = dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return pm_runtime_get(&dwc3->dev);
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int dwc3_pci_pm_dummy(struct device *dev)
|
||||
static int dwc3_pci_suspend(struct device *dev)
|
||||
{
|
||||
/*
|
||||
* There's nothing to do here. No, seriously. Everything is either taken
|
||||
* care either by PCI subsystem or dwc3/core.c, so we have nothing
|
||||
* missing here.
|
||||
*
|
||||
* So you'd think we didn't need this at all, but PCI subsystem will
|
||||
* bail out if we don't have a valid callback :-s
|
||||
*/
|
||||
return 0;
|
||||
struct dwc3_pci *dwc = dev_get_drvdata(dev);
|
||||
|
||||
return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
|
||||
}
|
||||
|
||||
static int dwc3_pci_resume(struct device *dev)
|
||||
{
|
||||
struct dwc3_pci *dwc = dev_get_drvdata(dev);
|
||||
|
||||
return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0);
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static struct dev_pm_ops dwc3_pci_dev_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume)
|
||||
SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume,
|
||||
NULL)
|
||||
};
|
||||
|
@ -219,7 +219,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
dma_set_coherent_mask(dev, dev->coherent_dma_mask);
|
||||
dwc3_data->dev = dev;
|
||||
dwc3_data->regmap = regmap;
|
||||
|
||||
|
@ -39,22 +39,6 @@ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
|
||||
static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
|
||||
struct dwc3_ep *dep, struct dwc3_request *req);
|
||||
|
||||
static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case EP0_UNCONNECTED:
|
||||
return "Unconnected";
|
||||
case EP0_SETUP_PHASE:
|
||||
return "Setup Phase";
|
||||
case EP0_DATA_PHASE:
|
||||
return "Data Phase";
|
||||
case EP0_STATUS_PHASE:
|
||||
return "Status Phase";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
|
||||
u32 len, u32 type, bool chain)
|
||||
{
|
||||
@ -65,10 +49,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
|
||||
int ret;
|
||||
|
||||
dep = dwc->eps[epnum];
|
||||
if (dep->flags & DWC3_EP_BUSY) {
|
||||
dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name);
|
||||
if (dep->flags & DWC3_EP_BUSY)
|
||||
return 0;
|
||||
}
|
||||
|
||||
trb = &dwc->ep0_trb[dep->trb_enqueue];
|
||||
|
||||
@ -99,11 +81,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
|
||||
trace_dwc3_prepare_trb(dep, trb);
|
||||
|
||||
ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms);
|
||||
if (ret < 0) {
|
||||
dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed",
|
||||
dep->name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dep->flags |= DWC3_EP_BUSY;
|
||||
dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep);
|
||||
@ -163,9 +142,6 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
|
||||
|
||||
if (dwc->ep0state == EP0_STATUS_PHASE)
|
||||
__dwc3_ep0_do_control_status(dwc, dwc->eps[direction]);
|
||||
else
|
||||
dwc3_trace(trace_dwc3_ep0,
|
||||
"too early for delayed status");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -229,9 +205,8 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
|
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
if (!dep->endpoint.desc) {
|
||||
dwc3_trace(trace_dwc3_ep0,
|
||||
"trying to queue request %p to disabled %s",
|
||||
request, dep->name);
|
||||
dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
|
||||
dep->name);
|
||||
ret = -ESHUTDOWN;
|
||||
goto out;
|
||||
}
|
||||
@ -242,11 +217,6 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
|
||||
goto out;
|
||||
}
|
||||
|
||||
dwc3_trace(trace_dwc3_ep0,
|
||||
"queueing request %p to %s length %d state '%s'",
|
||||
request, dep->name, request->length,
|
||||
dwc3_ep0_state_string(dwc->ep0state));
|
||||
|
||||
ret = __dwc3_gadget_ep0_queue(dep, req);
|
||||
|
||||
out:
|
||||
@ -308,6 +278,8 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
complete(&dwc->ep0_in_setup);
|
||||
|
||||
ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
|
||||
DWC3_TRBCTL_CONTROL_SETUP, false);
|
||||
WARN_ON(ret < 0);
|
||||
@ -395,121 +367,66 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
|
||||
return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
|
||||
}
|
||||
|
||||
static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
|
||||
struct usb_ctrlrequest *ctrl, int set)
|
||||
static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
|
||||
int set)
|
||||
{
|
||||
struct dwc3_ep *dep;
|
||||
u32 recip;
|
||||
u32 wValue;
|
||||
u32 wIndex;
|
||||
u32 reg;
|
||||
int ret;
|
||||
enum usb_device_state state;
|
||||
u32 reg;
|
||||
|
||||
wValue = le16_to_cpu(ctrl->wValue);
|
||||
wIndex = le16_to_cpu(ctrl->wIndex);
|
||||
recip = ctrl->bRequestType & USB_RECIP_MASK;
|
||||
state = dwc->gadget.state;
|
||||
if (state != USB_STATE_CONFIGURED)
|
||||
return -EINVAL;
|
||||
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
|
||||
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
|
||||
return -EINVAL;
|
||||
|
||||
switch (recip) {
|
||||
case USB_RECIP_DEVICE:
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
if (set)
|
||||
reg |= DWC3_DCTL_INITU1ENA;
|
||||
else
|
||||
reg &= ~DWC3_DCTL_INITU1ENA;
|
||||
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||
|
||||
switch (wValue) {
|
||||
case USB_DEVICE_REMOTE_WAKEUP:
|
||||
break;
|
||||
/*
|
||||
* 9.4.1 says only only for SS, in AddressState only for
|
||||
* default control pipe
|
||||
*/
|
||||
case USB_DEVICE_U1_ENABLE:
|
||||
if (state != USB_STATE_CONFIGURED)
|
||||
return -EINVAL;
|
||||
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
|
||||
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
if (set)
|
||||
reg |= DWC3_DCTL_INITU1ENA;
|
||||
else
|
||||
reg &= ~DWC3_DCTL_INITU1ENA;
|
||||
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||
break;
|
||||
static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
|
||||
int set)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
case USB_DEVICE_U2_ENABLE:
|
||||
if (state != USB_STATE_CONFIGURED)
|
||||
return -EINVAL;
|
||||
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
|
||||
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
|
||||
return -EINVAL;
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
if (set)
|
||||
reg |= DWC3_DCTL_INITU2ENA;
|
||||
else
|
||||
reg &= ~DWC3_DCTL_INITU2ENA;
|
||||
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||
break;
|
||||
if (state != USB_STATE_CONFIGURED)
|
||||
return -EINVAL;
|
||||
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
|
||||
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
|
||||
return -EINVAL;
|
||||
|
||||
case USB_DEVICE_LTM_ENABLE:
|
||||
return -EINVAL;
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
if (set)
|
||||
reg |= DWC3_DCTL_INITU2ENA;
|
||||
else
|
||||
reg &= ~DWC3_DCTL_INITU2ENA;
|
||||
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||
|
||||
case USB_DEVICE_TEST_MODE:
|
||||
if ((wIndex & 0xff) != 0)
|
||||
return -EINVAL;
|
||||
if (!set)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (wIndex >> 8) {
|
||||
case TEST_J:
|
||||
case TEST_K:
|
||||
case TEST_SE0_NAK:
|
||||
case TEST_PACKET:
|
||||
case TEST_FORCE_EN:
|
||||
dwc->test_mode_nr = wIndex >> 8;
|
||||
dwc->test_mode = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
static int dwc3_ep0_handle_test(struct dwc3 *dwc, enum usb_device_state state,
|
||||
u32 wIndex, int set)
|
||||
{
|
||||
if ((wIndex & 0xff) != 0)
|
||||
return -EINVAL;
|
||||
if (!set)
|
||||
return -EINVAL;
|
||||
|
||||
switch (wIndex >> 8) {
|
||||
case TEST_J:
|
||||
case TEST_K:
|
||||
case TEST_SE0_NAK:
|
||||
case TEST_PACKET:
|
||||
case TEST_FORCE_EN:
|
||||
dwc->test_mode_nr = wIndex >> 8;
|
||||
dwc->test_mode = true;
|
||||
break;
|
||||
|
||||
case USB_RECIP_INTERFACE:
|
||||
switch (wValue) {
|
||||
case USB_INTRF_FUNC_SUSPEND:
|
||||
if (wIndex & USB_INTRF_FUNC_SUSPEND_LP)
|
||||
/* XXX enable Low power suspend */
|
||||
;
|
||||
if (wIndex & USB_INTRF_FUNC_SUSPEND_RW)
|
||||
/* XXX enable remote wakeup */
|
||||
;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_RECIP_ENDPOINT:
|
||||
switch (wValue) {
|
||||
case USB_ENDPOINT_HALT:
|
||||
dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
|
||||
if (!dep)
|
||||
return -EINVAL;
|
||||
if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
|
||||
break;
|
||||
ret = __dwc3_gadget_ep_set_halt(dep, set, true);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -517,6 +434,133 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc3_ep0_handle_device(struct dwc3 *dwc,
|
||||
struct usb_ctrlrequest *ctrl, int set)
|
||||
{
|
||||
enum usb_device_state state;
|
||||
u32 wValue;
|
||||
u32 wIndex;
|
||||
int ret = 0;
|
||||
|
||||
wValue = le16_to_cpu(ctrl->wValue);
|
||||
wIndex = le16_to_cpu(ctrl->wIndex);
|
||||
state = dwc->gadget.state;
|
||||
|
||||
switch (wValue) {
|
||||
case USB_DEVICE_REMOTE_WAKEUP:
|
||||
break;
|
||||
/*
|
||||
* 9.4.1 says only only for SS, in AddressState only for
|
||||
* default control pipe
|
||||
*/
|
||||
case USB_DEVICE_U1_ENABLE:
|
||||
ret = dwc3_ep0_handle_u1(dwc, state, set);
|
||||
break;
|
||||
case USB_DEVICE_U2_ENABLE:
|
||||
ret = dwc3_ep0_handle_u2(dwc, state, set);
|
||||
break;
|
||||
case USB_DEVICE_LTM_ENABLE:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
case USB_DEVICE_TEST_MODE:
|
||||
ret = dwc3_ep0_handle_test(dwc, state, wIndex, set);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dwc3_ep0_handle_intf(struct dwc3 *dwc,
|
||||
struct usb_ctrlrequest *ctrl, int set)
|
||||
{
|
||||
enum usb_device_state state;
|
||||
u32 wValue;
|
||||
u32 wIndex;
|
||||
int ret = 0;
|
||||
|
||||
wValue = le16_to_cpu(ctrl->wValue);
|
||||
wIndex = le16_to_cpu(ctrl->wIndex);
|
||||
state = dwc->gadget.state;
|
||||
|
||||
switch (wValue) {
|
||||
case USB_INTRF_FUNC_SUSPEND:
|
||||
/*
|
||||
* REVISIT: Ideally we would enable some low power mode here,
|
||||
* however it's unclear what we should be doing here.
|
||||
*
|
||||
* For now, we're not doing anything, just making sure we return
|
||||
* 0 so USB Command Verifier tests pass without any errors.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dwc3_ep0_handle_endpoint(struct dwc3 *dwc,
|
||||
struct usb_ctrlrequest *ctrl, int set)
|
||||
{
|
||||
struct dwc3_ep *dep;
|
||||
enum usb_device_state state;
|
||||
u32 wValue;
|
||||
u32 wIndex;
|
||||
int ret;
|
||||
|
||||
wValue = le16_to_cpu(ctrl->wValue);
|
||||
wIndex = le16_to_cpu(ctrl->wIndex);
|
||||
state = dwc->gadget.state;
|
||||
|
||||
switch (wValue) {
|
||||
case USB_ENDPOINT_HALT:
|
||||
dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
|
||||
if (!dep)
|
||||
return -EINVAL;
|
||||
|
||||
if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
|
||||
break;
|
||||
|
||||
ret = __dwc3_gadget_ep_set_halt(dep, set, true);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
|
||||
struct usb_ctrlrequest *ctrl, int set)
|
||||
{
|
||||
u32 recip;
|
||||
int ret;
|
||||
enum usb_device_state state;
|
||||
|
||||
recip = ctrl->bRequestType & USB_RECIP_MASK;
|
||||
state = dwc->gadget.state;
|
||||
|
||||
switch (recip) {
|
||||
case USB_RECIP_DEVICE:
|
||||
ret = dwc3_ep0_handle_device(dwc, ctrl, set);
|
||||
break;
|
||||
case USB_RECIP_INTERFACE:
|
||||
ret = dwc3_ep0_handle_intf(dwc, ctrl, set);
|
||||
break;
|
||||
case USB_RECIP_ENDPOINT:
|
||||
ret = dwc3_ep0_handle_endpoint(dwc, ctrl, set);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
|
||||
{
|
||||
enum usb_device_state state = dwc->gadget.state;
|
||||
@ -525,13 +569,12 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
|
||||
|
||||
addr = le16_to_cpu(ctrl->wValue);
|
||||
if (addr > 127) {
|
||||
dwc3_trace(trace_dwc3_ep0, "invalid device address %d", addr);
|
||||
dev_err(dwc->dev, "invalid device address %d\n", addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (state == USB_STATE_CONFIGURED) {
|
||||
dwc3_trace(trace_dwc3_ep0,
|
||||
"trying to set address when configured");
|
||||
dev_err(dwc->dev, "can't SetAddress() from Configured State\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -716,35 +759,27 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
|
||||
|
||||
switch (ctrl->bRequest) {
|
||||
case USB_REQ_GET_STATUS:
|
||||
dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS");
|
||||
ret = dwc3_ep0_handle_status(dwc, ctrl);
|
||||
break;
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE");
|
||||
ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
|
||||
break;
|
||||
case USB_REQ_SET_FEATURE:
|
||||
dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE");
|
||||
ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);
|
||||
break;
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS");
|
||||
ret = dwc3_ep0_set_address(dwc, ctrl);
|
||||
break;
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION");
|
||||
ret = dwc3_ep0_set_config(dwc, ctrl);
|
||||
break;
|
||||
case USB_REQ_SET_SEL:
|
||||
dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL");
|
||||
ret = dwc3_ep0_set_sel(dwc, ctrl);
|
||||
break;
|
||||
case USB_REQ_SET_ISOCH_DELAY:
|
||||
dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY");
|
||||
ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
|
||||
break;
|
||||
default:
|
||||
dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver");
|
||||
ret = dwc3_ep0_delegate_req(dwc, ctrl);
|
||||
break;
|
||||
}
|
||||
@ -820,9 +855,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
|
||||
status = DWC3_TRB_SIZE_TRBSTS(trb->size);
|
||||
if (status == DWC3_TRBSTS_SETUP_PENDING) {
|
||||
dwc->setup_packet_pending = true;
|
||||
|
||||
dwc3_trace(trace_dwc3_ep0, "Setup Pending received");
|
||||
|
||||
if (r)
|
||||
dwc3_gadget_giveback(ep0, r, -ECONNRESET);
|
||||
|
||||
@ -912,7 +944,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
|
||||
|
||||
ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
|
||||
if (ret < 0) {
|
||||
dwc3_trace(trace_dwc3_ep0, "Invalid Test #%d",
|
||||
dev_err(dwc->dev, "invalid test #%d\n",
|
||||
dwc->test_mode_nr);
|
||||
dwc3_ep0_stall_and_restart(dwc);
|
||||
return;
|
||||
@ -920,10 +952,8 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
|
||||
}
|
||||
|
||||
status = DWC3_TRB_SIZE_TRBSTS(trb->size);
|
||||
if (status == DWC3_TRBSTS_SETUP_PENDING) {
|
||||
if (status == DWC3_TRBSTS_SETUP_PENDING)
|
||||
dwc->setup_packet_pending = true;
|
||||
dwc3_trace(trace_dwc3_ep0, "Setup Pending received");
|
||||
}
|
||||
|
||||
dwc->ep0state = EP0_SETUP_PHASE;
|
||||
dwc3_ep0_out_start(dwc);
|
||||
@ -940,17 +970,14 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
|
||||
|
||||
switch (dwc->ep0state) {
|
||||
case EP0_SETUP_PHASE:
|
||||
dwc3_trace(trace_dwc3_ep0, "Setup Phase");
|
||||
dwc3_ep0_inspect_setup(dwc, event);
|
||||
break;
|
||||
|
||||
case EP0_DATA_PHASE:
|
||||
dwc3_trace(trace_dwc3_ep0, "Data Phase");
|
||||
dwc3_ep0_complete_data(dwc, event);
|
||||
break;
|
||||
|
||||
case EP0_STATUS_PHASE:
|
||||
dwc3_trace(trace_dwc3_ep0, "Status Phase");
|
||||
dwc3_ep0_complete_status(dwc, event);
|
||||
break;
|
||||
default:
|
||||
@ -974,12 +1001,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
|
||||
u32 transfer_size = 0;
|
||||
u32 maxpacket;
|
||||
|
||||
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
|
||||
dep->number);
|
||||
if (ret) {
|
||||
dwc3_trace(trace_dwc3_ep0, "failed to map request");
|
||||
ret = usb_gadget_map_request_by_dev(dwc->sysdev,
|
||||
&req->request, dep->number);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
||||
maxpacket = dep->endpoint.maxpacket;
|
||||
|
||||
@ -1002,12 +1027,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
|
||||
dwc->ep0_bounce_addr, transfer_size,
|
||||
DWC3_TRBCTL_CONTROL_DATA, false);
|
||||
} else {
|
||||
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
|
||||
dep->number);
|
||||
if (ret) {
|
||||
dwc3_trace(trace_dwc3_ep0, "failed to map request");
|
||||
ret = usb_gadget_map_request_by_dev(dwc->sysdev,
|
||||
&req->request, dep->number);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
||||
ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,
|
||||
req->request.length, DWC3_TRBCTL_CONTROL_DATA,
|
||||
@ -1065,8 +1088,6 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
|
||||
{
|
||||
switch (event->status) {
|
||||
case DEPEVT_STATUS_CONTROL_DATA:
|
||||
dwc3_trace(trace_dwc3_ep0, "Control Data");
|
||||
|
||||
/*
|
||||
* We already have a DATA transfer in the controller's cache,
|
||||
* if we receive a XferNotReady(DATA) we will ignore it, unless
|
||||
@ -1079,8 +1100,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
|
||||
if (dwc->ep0_expect_in != event->endpoint_number) {
|
||||
struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in];
|
||||
|
||||
dwc3_trace(trace_dwc3_ep0,
|
||||
"Wrong direction for Data phase");
|
||||
dev_err(dwc->dev, "unexpected direction for Data Phase\n");
|
||||
dwc3_ep0_end_control_data(dwc, dep);
|
||||
dwc3_ep0_stall_and_restart(dwc);
|
||||
return;
|
||||
@ -1092,13 +1112,10 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
|
||||
if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS)
|
||||
return;
|
||||
|
||||
dwc3_trace(trace_dwc3_ep0, "Control Status");
|
||||
|
||||
dwc->ep0state = EP0_STATUS_PHASE;
|
||||
|
||||
if (dwc->delayed_status) {
|
||||
WARN_ON_ONCE(event->endpoint_number != 1);
|
||||
dwc3_trace(trace_dwc3_ep0, "Delayed Status");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1109,10 +1126,6 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
|
||||
void dwc3_ep0_interrupt(struct dwc3 *dwc,
|
||||
const struct dwc3_event_depevt *event)
|
||||
{
|
||||
dwc3_trace(trace_dwc3_ep0, "%s: state '%s'",
|
||||
dwc3_ep_event_string(event),
|
||||
dwc3_ep0_state_string(dwc->ep0state));
|
||||
|
||||
switch (event->endpoint_event) {
|
||||
case DWC3_DEPEVT_XFERCOMPLETE:
|
||||
dwc3_ep0_xfer_complete(dwc, event);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -62,10 +62,7 @@ struct dwc3;
|
||||
|
||||
static inline struct dwc3_request *next_request(struct list_head *list)
|
||||
{
|
||||
if (list_empty(list))
|
||||
return NULL;
|
||||
|
||||
return list_first_entry(list, struct dwc3_request, list);
|
||||
return list_first_entry_or_null(list, struct dwc3_request, list);
|
||||
}
|
||||
|
||||
static inline void dwc3_gadget_move_started_request(struct dwc3_request *req)
|
||||
|
@ -19,6 +19,39 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
static int dwc3_host_get_irq(struct dwc3 *dwc)
|
||||
{
|
||||
struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
|
||||
int irq;
|
||||
|
||||
irq = platform_get_irq_byname(dwc3_pdev, "host");
|
||||
if (irq > 0)
|
||||
goto out;
|
||||
|
||||
if (irq == -EPROBE_DEFER)
|
||||
goto out;
|
||||
|
||||
irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3");
|
||||
if (irq > 0)
|
||||
goto out;
|
||||
|
||||
if (irq == -EPROBE_DEFER)
|
||||
goto out;
|
||||
|
||||
irq = platform_get_irq(dwc3_pdev, 0);
|
||||
if (irq > 0)
|
||||
goto out;
|
||||
|
||||
if (irq != -EPROBE_DEFER)
|
||||
dev_err(dwc->dev, "missing host IRQ\n");
|
||||
|
||||
if (!irq)
|
||||
irq = -EINVAL;
|
||||
|
||||
out:
|
||||
return irq;
|
||||
}
|
||||
|
||||
int dwc3_host_init(struct dwc3 *dwc)
|
||||
{
|
||||
struct property_entry props[2];
|
||||
@ -27,39 +60,18 @@ int dwc3_host_init(struct dwc3 *dwc)
|
||||
struct resource *res;
|
||||
struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
|
||||
|
||||
irq = platform_get_irq_byname(dwc3_pdev, "host");
|
||||
if (irq == -EPROBE_DEFER)
|
||||
irq = dwc3_host_get_irq(dwc);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
if (irq <= 0) {
|
||||
irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3");
|
||||
if (irq == -EPROBE_DEFER)
|
||||
return irq;
|
||||
|
||||
if (irq <= 0) {
|
||||
irq = platform_get_irq(dwc3_pdev, 0);
|
||||
if (irq <= 0) {
|
||||
if (irq != -EPROBE_DEFER) {
|
||||
dev_err(dwc->dev,
|
||||
"missing host IRQ\n");
|
||||
}
|
||||
if (!irq)
|
||||
irq = -EINVAL;
|
||||
return irq;
|
||||
} else {
|
||||
res = platform_get_resource(dwc3_pdev,
|
||||
IORESOURCE_IRQ, 0);
|
||||
}
|
||||
} else {
|
||||
res = platform_get_resource_byname(dwc3_pdev,
|
||||
IORESOURCE_IRQ,
|
||||
"dwc_usb3");
|
||||
}
|
||||
|
||||
} else {
|
||||
res = platform_get_resource_byname(dwc3_pdev, IORESOURCE_IRQ, "host");
|
||||
if (!res)
|
||||
res = platform_get_resource_byname(dwc3_pdev, IORESOURCE_IRQ,
|
||||
"host");
|
||||
}
|
||||
"dwc_usb3");
|
||||
if (!res)
|
||||
res = platform_get_resource(dwc3_pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res)
|
||||
return -ENOMEM;
|
||||
|
||||
dwc->xhci_resources[1].start = irq;
|
||||
dwc->xhci_resources[1].end = irq;
|
||||
@ -72,11 +84,7 @@ int dwc3_host_init(struct dwc3 *dwc)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
|
||||
|
||||
xhci->dev.parent = dwc->dev;
|
||||
xhci->dev.dma_mask = dwc->dev->dma_mask;
|
||||
xhci->dev.dma_parms = dwc->dev->dma_parms;
|
||||
|
||||
dwc->xhci = xhci;
|
||||
|
||||
@ -99,9 +107,9 @@ int dwc3_host_init(struct dwc3 *dwc)
|
||||
}
|
||||
|
||||
phy_create_lookup(dwc->usb2_generic_phy, "usb2-phy",
|
||||
dev_name(&xhci->dev));
|
||||
dev_name(dwc->dev));
|
||||
phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy",
|
||||
dev_name(&xhci->dev));
|
||||
dev_name(dwc->dev));
|
||||
|
||||
ret = platform_device_add(xhci);
|
||||
if (ret) {
|
||||
@ -112,9 +120,9 @@ int dwc3_host_init(struct dwc3 *dwc)
|
||||
return 0;
|
||||
err2:
|
||||
phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
|
||||
dev_name(&xhci->dev));
|
||||
dev_name(dwc->dev));
|
||||
phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
|
||||
dev_name(&xhci->dev));
|
||||
dev_name(dwc->dev));
|
||||
err1:
|
||||
platform_device_put(xhci);
|
||||
return ret;
|
||||
@ -123,8 +131,8 @@ err1:
|
||||
void dwc3_host_exit(struct dwc3 *dwc)
|
||||
{
|
||||
phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
|
||||
dev_name(&dwc->xhci->dev));
|
||||
dev_name(dwc->dev));
|
||||
phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
|
||||
dev_name(&dwc->xhci->dev));
|
||||
dev_name(dwc->dev));
|
||||
platform_device_unregister(dwc->xhci);
|
||||
}
|
||||
|
@ -40,8 +40,7 @@ static inline u32 dwc3_readl(void __iomem *base, u32 offset)
|
||||
* documentation, so we revert it back to the proper addresses, the
|
||||
* same way they are described on SNPS documentation
|
||||
*/
|
||||
dwc3_trace(trace_dwc3_readl, "addr %p value %08x",
|
||||
base - DWC3_GLOBALS_REGS_START + offset, value);
|
||||
trace_dwc3_readl(base - DWC3_GLOBALS_REGS_START, offset, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
@ -60,8 +59,7 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
|
||||
* documentation, so we revert it back to the proper addresses, the
|
||||
* same way they are described on SNPS documentation
|
||||
*/
|
||||
dwc3_trace(trace_dwc3_writel, "addr %p value %08x",
|
||||
base - DWC3_GLOBALS_REGS_START + offset, value);
|
||||
trace_dwc3_writel(base - DWC3_GLOBALS_REGS_START, offset, value);
|
||||
}
|
||||
|
||||
#endif /* __DRIVERS_USB_DWC3_IO_H */
|
||||
|
@ -37,16 +37,6 @@ DECLARE_EVENT_CLASS(dwc3_log_msg,
|
||||
TP_printk("%s", __get_str(msg))
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_msg, dwc3_readl,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_msg, dwc3_writel,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_msg, dwc3_gadget,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
@ -62,22 +52,51 @@ DEFINE_EVENT(dwc3_log_msg, dwc3_ep0,
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_io,
|
||||
TP_PROTO(void *base, u32 offset, u32 value),
|
||||
TP_ARGS(base, offset, value),
|
||||
TP_STRUCT__entry(
|
||||
__field(void *, base)
|
||||
__field(u32, offset)
|
||||
__field(u32, value)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->base = base;
|
||||
__entry->offset = offset;
|
||||
__entry->value = value;
|
||||
),
|
||||
TP_printk("addr %p value %08x", __entry->base + __entry->offset,
|
||||
__entry->value)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_io, dwc3_readl,
|
||||
TP_PROTO(void *base, u32 offset, u32 value),
|
||||
TP_ARGS(base, offset, value)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_io, dwc3_writel,
|
||||
TP_PROTO(void *base, u32 offset, u32 value),
|
||||
TP_ARGS(base, offset, value)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_event,
|
||||
TP_PROTO(u32 event),
|
||||
TP_ARGS(event),
|
||||
TP_PROTO(u32 event, struct dwc3 *dwc),
|
||||
TP_ARGS(event, dwc),
|
||||
TP_STRUCT__entry(
|
||||
__field(u32, event)
|
||||
__field(u32, ep0state)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->event = event;
|
||||
__entry->ep0state = dwc->ep0state;
|
||||
),
|
||||
TP_printk("event (%08x): %s", __entry->event,
|
||||
dwc3_decode_event(__entry->event))
|
||||
dwc3_decode_event(__entry->event, __entry->ep0state))
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_event, dwc3_event,
|
||||
TP_PROTO(u32 event),
|
||||
TP_ARGS(event)
|
||||
TP_PROTO(u32 event, struct dwc3 *dwc),
|
||||
TP_ARGS(event, dwc)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_ctrl,
|
||||
@ -237,6 +256,7 @@ DECLARE_EVENT_CLASS(dwc3_log_trb,
|
||||
__field(u32, bph)
|
||||
__field(u32, size)
|
||||
__field(u32, ctrl)
|
||||
__field(u32, type)
|
||||
),
|
||||
TP_fast_assign(
|
||||
snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name);
|
||||
@ -247,11 +267,31 @@ DECLARE_EVENT_CLASS(dwc3_log_trb,
|
||||
__entry->bph = trb->bph;
|
||||
__entry->size = trb->size;
|
||||
__entry->ctrl = trb->ctrl;
|
||||
__entry->type = usb_endpoint_type(dep->endpoint.desc);
|
||||
),
|
||||
TP_printk("%s: %d/%d trb %p buf %08x%08x size %d ctrl %08x (%c%c%c%c:%c%c:%s)",
|
||||
TP_printk("%s: %d/%d trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)",
|
||||
__get_str(name), __entry->queued, __entry->allocated,
|
||||
__entry->trb, __entry->bph, __entry->bpl,
|
||||
__entry->size, __entry->ctrl,
|
||||
({char *s;
|
||||
int pcm = ((__entry->size >> 24) & 3) + 1;
|
||||
switch (__entry->type) {
|
||||
case USB_ENDPOINT_XFER_INT:
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
switch (pcm) {
|
||||
case 1:
|
||||
s = "1x ";
|
||||
break;
|
||||
case 2:
|
||||
s = "2x ";
|
||||
break;
|
||||
case 3:
|
||||
s = "3x ";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
s = "";
|
||||
} s; }),
|
||||
DWC3_TRB_SIZE_LENGTH(__entry->size), __entry->ctrl,
|
||||
__entry->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h',
|
||||
__entry->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l',
|
||||
__entry->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c',
|
||||
@ -301,6 +341,57 @@ DEFINE_EVENT(dwc3_log_trb, dwc3_complete_trb,
|
||||
TP_ARGS(dep, trb)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(dwc3_log_ep,
|
||||
TP_PROTO(struct dwc3_ep *dep),
|
||||
TP_ARGS(dep),
|
||||
TP_STRUCT__entry(
|
||||
__dynamic_array(char, name, DWC3_MSG_MAX)
|
||||
__field(unsigned, maxpacket)
|
||||
__field(unsigned, maxpacket_limit)
|
||||
__field(unsigned, max_streams)
|
||||
__field(unsigned, maxburst)
|
||||
__field(unsigned, flags)
|
||||
__field(unsigned, direction)
|
||||
__field(u8, trb_enqueue)
|
||||
__field(u8, trb_dequeue)
|
||||
),
|
||||
TP_fast_assign(
|
||||
snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name);
|
||||
__entry->maxpacket = dep->endpoint.maxpacket;
|
||||
__entry->maxpacket_limit = dep->endpoint.maxpacket_limit;
|
||||
__entry->max_streams = dep->endpoint.max_streams;
|
||||
__entry->maxburst = dep->endpoint.maxburst;
|
||||
__entry->flags = dep->flags;
|
||||
__entry->direction = dep->direction;
|
||||
__entry->trb_enqueue = dep->trb_enqueue;
|
||||
__entry->trb_dequeue = dep->trb_dequeue;
|
||||
),
|
||||
TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c%c:%c:%c",
|
||||
__get_str(name), __entry->maxpacket,
|
||||
__entry->maxpacket_limit, __entry->max_streams,
|
||||
__entry->maxburst, __entry->trb_enqueue,
|
||||
__entry->trb_dequeue,
|
||||
__entry->flags & DWC3_EP_ENABLED ? 'E' : 'e',
|
||||
__entry->flags & DWC3_EP_STALL ? 'S' : 's',
|
||||
__entry->flags & DWC3_EP_WEDGE ? 'W' : 'w',
|
||||
__entry->flags & DWC3_EP_BUSY ? 'B' : 'b',
|
||||
__entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',
|
||||
__entry->flags & DWC3_EP_MISSED_ISOC ? 'M' : 'm',
|
||||
__entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e',
|
||||
__entry->direction ? '<' : '>'
|
||||
)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_ep, dwc3_gadget_ep_enable,
|
||||
TP_PROTO(struct dwc3_ep *dep),
|
||||
TP_ARGS(dep)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(dwc3_log_ep, dwc3_gadget_ep_disable,
|
||||
TP_PROTO(struct dwc3_ep *dep),
|
||||
TP_ARGS(dep)
|
||||
);
|
||||
|
||||
#endif /* __DWC3_TRACE_H */
|
||||
|
||||
/* this part has to be here */
|
||||
|
@ -201,7 +201,12 @@ ep_found:
|
||||
_ep->desc = chosen_desc;
|
||||
_ep->comp_desc = NULL;
|
||||
_ep->maxburst = 0;
|
||||
_ep->mult = 0;
|
||||
_ep->mult = 1;
|
||||
|
||||
if (g->speed == USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) ||
|
||||
usb_endpoint_xfer_int(_ep->desc)))
|
||||
_ep->mult = usb_endpoint_maxp_mult(_ep->desc);
|
||||
|
||||
if (!want_comp_desc)
|
||||
return 0;
|
||||
|
||||
@ -218,7 +223,7 @@ ep_found:
|
||||
switch (usb_endpoint_type(_ep->desc)) {
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
/* mult: bits 1:0 of bmAttributes */
|
||||
_ep->mult = comp_desc->bmAttributes & 0x3;
|
||||
_ep->mult = (comp_desc->bmAttributes & 0x3) + 1;
|
||||
case USB_ENDPOINT_XFER_BULK:
|
||||
case USB_ENDPOINT_XFER_INT:
|
||||
_ep->maxburst = comp_desc->bMaxBurst + 1;
|
||||
@ -2382,18 +2387,8 @@ EXPORT_SYMBOL_GPL(usb_composite_setup_continue);
|
||||
|
||||
static char *composite_default_mfr(struct usb_gadget *gadget)
|
||||
{
|
||||
char *mfr;
|
||||
int len;
|
||||
|
||||
len = snprintf(NULL, 0, "%s %s with %s", init_utsname()->sysname,
|
||||
init_utsname()->release, gadget->name);
|
||||
len++;
|
||||
mfr = kmalloc(len, GFP_KERNEL);
|
||||
if (!mfr)
|
||||
return NULL;
|
||||
snprintf(mfr, len, "%s %s with %s", init_utsname()->sysname,
|
||||
init_utsname()->release, gadget->name);
|
||||
return mfr;
|
||||
return kasprintf(GFP_KERNEL, "%s %s with %s", init_utsname()->sysname,
|
||||
init_utsname()->release, gadget->name);
|
||||
}
|
||||
|
||||
void usb_composite_overwrite_options(struct usb_composite_dev *cdev,
|
||||
|
@ -266,7 +266,7 @@ static void ffs_ep0_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
struct ffs_data *ffs = req->context;
|
||||
|
||||
complete_all(&ffs->ep0req_completion);
|
||||
complete(&ffs->ep0req_completion);
|
||||
}
|
||||
|
||||
static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len)
|
||||
|
@ -98,6 +98,60 @@ static struct hid_descriptor hidg_desc = {
|
||||
/*.desc[0].wDescriptorLenght = DYNAMIC */
|
||||
};
|
||||
|
||||
/* Super-Speed Support */
|
||||
|
||||
static struct usb_endpoint_descriptor hidg_ss_in_ep_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
/*.wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 4, /* FIXME: Add this field in the
|
||||
* HID gadget configuration?
|
||||
* (struct hidg_func_descriptor)
|
||||
*/
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor hidg_ss_in_comp_desc = {
|
||||
.bLength = sizeof(hidg_ss_in_comp_desc),
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
/* .bMaxBurst = 0, */
|
||||
/* .bmAttributes = 0, */
|
||||
/* .wBytesPerInterval = DYNAMIC */
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hidg_ss_out_ep_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
/*.wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 4, /* FIXME: Add this field in the
|
||||
* HID gadget configuration?
|
||||
* (struct hidg_func_descriptor)
|
||||
*/
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor hidg_ss_out_comp_desc = {
|
||||
.bLength = sizeof(hidg_ss_out_comp_desc),
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
/* .bMaxBurst = 0, */
|
||||
/* .bmAttributes = 0, */
|
||||
/* .wBytesPerInterval = DYNAMIC */
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hidg_ss_descriptors[] = {
|
||||
(struct usb_descriptor_header *)&hidg_interface_desc,
|
||||
(struct usb_descriptor_header *)&hidg_desc,
|
||||
(struct usb_descriptor_header *)&hidg_ss_in_ep_desc,
|
||||
(struct usb_descriptor_header *)&hidg_ss_in_comp_desc,
|
||||
(struct usb_descriptor_header *)&hidg_ss_out_ep_desc,
|
||||
(struct usb_descriptor_header *)&hidg_ss_out_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* High-Speed Support */
|
||||
|
||||
static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = {
|
||||
@ -624,8 +678,14 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
/* set descriptor dynamic values */
|
||||
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
|
||||
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
|
||||
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_ss_in_comp_desc.wBytesPerInterval =
|
||||
cpu_to_le16(hidg->report_length);
|
||||
hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_ss_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_ss_out_comp_desc.wBytesPerInterval =
|
||||
cpu_to_le16(hidg->report_length);
|
||||
hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
/*
|
||||
@ -641,8 +701,13 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
hidg_hs_out_ep_desc.bEndpointAddress =
|
||||
hidg_fs_out_ep_desc.bEndpointAddress;
|
||||
|
||||
hidg_ss_in_ep_desc.bEndpointAddress =
|
||||
hidg_fs_in_ep_desc.bEndpointAddress;
|
||||
hidg_ss_out_ep_desc.bEndpointAddress =
|
||||
hidg_fs_out_ep_desc.bEndpointAddress;
|
||||
|
||||
status = usb_assign_descriptors(f, hidg_fs_descriptors,
|
||||
hidg_hs_descriptors, NULL, NULL);
|
||||
hidg_hs_descriptors, hidg_ss_descriptors, NULL);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
|
@ -998,7 +998,7 @@ static struct sk_buff *package_for_tx(struct f_ncm *ncm)
|
||||
/* Merge the skbs */
|
||||
swap(skb2, ncm->skb_tx_data);
|
||||
if (ncm->skb_tx_data) {
|
||||
dev_kfree_skb_any(ncm->skb_tx_data);
|
||||
dev_consume_skb_any(ncm->skb_tx_data);
|
||||
ncm->skb_tx_data = NULL;
|
||||
}
|
||||
|
||||
@ -1009,7 +1009,7 @@ static struct sk_buff *package_for_tx(struct f_ncm *ncm)
|
||||
/* Copy NTB across. */
|
||||
ntb_iter = (void *) skb_put(skb2, ncm->skb_tx_ndp->len);
|
||||
memcpy(ntb_iter, ncm->skb_tx_ndp->data, ncm->skb_tx_ndp->len);
|
||||
dev_kfree_skb_any(ncm->skb_tx_ndp);
|
||||
dev_consume_skb_any(ncm->skb_tx_ndp);
|
||||
ncm->skb_tx_ndp = NULL;
|
||||
|
||||
/* Insert zero'd datagram. */
|
||||
@ -1078,6 +1078,7 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port,
|
||||
if (!ncm->skb_tx_data)
|
||||
goto err;
|
||||
|
||||
ncm->skb_tx_data->dev = ncm->netdev;
|
||||
ntb_data = (void *) skb_put(ncm->skb_tx_data, ncb_len);
|
||||
memset(ntb_data, 0, ncb_len);
|
||||
/* dwSignature */
|
||||
@ -1096,6 +1097,8 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port,
|
||||
GFP_ATOMIC);
|
||||
if (!ncm->skb_tx_ndp)
|
||||
goto err;
|
||||
|
||||
ncm->skb_tx_ndp->dev = ncm->netdev;
|
||||
ntb_ndp = (void *) skb_put(ncm->skb_tx_ndp,
|
||||
opts->ndp_size);
|
||||
memset(ntb_ndp, 0, ncb_len);
|
||||
@ -1133,7 +1136,7 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port,
|
||||
memset(ntb_data, 0, dgram_pad);
|
||||
ntb_data = (void *) skb_put(ncm->skb_tx_data, skb->len);
|
||||
memcpy(ntb_data, skb->data, skb->len);
|
||||
dev_kfree_skb_any(skb);
|
||||
dev_consume_skb_any(skb);
|
||||
skb = NULL;
|
||||
|
||||
} else if (ncm->skb_tx_data && ncm->timer_force_tx) {
|
||||
@ -1329,7 +1332,7 @@ static int ncm_unwrap_ntb(struct gether *port,
|
||||
} while (ndp_len > 2 * (opts->dgram_item_len * 2));
|
||||
} while (ndp_index);
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
dev_consume_skb_any(skb);
|
||||
|
||||
VDBG(port->func.config->cdev,
|
||||
"Parsed NTB with %d frames\n", dgram_counter);
|
||||
|
@ -1067,13 +1067,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||
agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
|
||||
if (!agdev->out_ep) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
goto err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
|
||||
if (!agdev->in_ep) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
goto err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uac2->p_prm.uac2 = uac2;
|
||||
@ -1091,7 +1091,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||
ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL,
|
||||
NULL);
|
||||
if (ret)
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
prm = &agdev->uac2.c_prm;
|
||||
prm->max_psize = hs_epout_desc.wMaxPacketSize;
|
||||
@ -1106,19 +1106,19 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||
prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL);
|
||||
if (!prm->rbuf) {
|
||||
prm->max_psize = 0;
|
||||
goto err_free_descs;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = alsa_uac2_init(agdev);
|
||||
if (ret)
|
||||
goto err_free_descs;
|
||||
goto err;
|
||||
return 0;
|
||||
|
||||
err_free_descs:
|
||||
usb_free_all_descriptors(fn);
|
||||
err:
|
||||
kfree(agdev->uac2.p_prm.rbuf);
|
||||
kfree(agdev->uac2.c_prm.rbuf);
|
||||
err_free_descs:
|
||||
usb_free_all_descriptors(fn);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,7 @@ static const struct file_operations rndis_proc_fops;
|
||||
#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
|
||||
|
||||
/* supported OIDs */
|
||||
static const u32 oid_supported_list[] =
|
||||
{
|
||||
static const u32 oid_supported_list[] = {
|
||||
/* the general stuff */
|
||||
RNDIS_OID_GEN_SUPPORTED_LIST,
|
||||
RNDIS_OID_GEN_HARDWARE_STATUS,
|
||||
|
@ -22,8 +22,7 @@
|
||||
#define RNDIS_MAXIMUM_FRAME_SIZE 1518
|
||||
#define RNDIS_MAX_TOTAL_SIZE 1558
|
||||
|
||||
typedef struct rndis_init_msg_type
|
||||
{
|
||||
typedef struct rndis_init_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
@ -32,8 +31,7 @@ typedef struct rndis_init_msg_type
|
||||
__le32 MaxTransferSize;
|
||||
} rndis_init_msg_type;
|
||||
|
||||
typedef struct rndis_init_cmplt_type
|
||||
{
|
||||
typedef struct rndis_init_cmplt_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
@ -49,15 +47,13 @@ typedef struct rndis_init_cmplt_type
|
||||
__le32 AFListSize;
|
||||
} rndis_init_cmplt_type;
|
||||
|
||||
typedef struct rndis_halt_msg_type
|
||||
{
|
||||
typedef struct rndis_halt_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
} rndis_halt_msg_type;
|
||||
|
||||
typedef struct rndis_query_msg_type
|
||||
{
|
||||
typedef struct rndis_query_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
@ -67,8 +63,7 @@ typedef struct rndis_query_msg_type
|
||||
__le32 DeviceVcHandle;
|
||||
} rndis_query_msg_type;
|
||||
|
||||
typedef struct rndis_query_cmplt_type
|
||||
{
|
||||
typedef struct rndis_query_cmplt_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
@ -77,8 +72,7 @@ typedef struct rndis_query_cmplt_type
|
||||
__le32 InformationBufferOffset;
|
||||
} rndis_query_cmplt_type;
|
||||
|
||||
typedef struct rndis_set_msg_type
|
||||
{
|
||||
typedef struct rndis_set_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
@ -88,31 +82,27 @@ typedef struct rndis_set_msg_type
|
||||
__le32 DeviceVcHandle;
|
||||
} rndis_set_msg_type;
|
||||
|
||||
typedef struct rndis_set_cmplt_type
|
||||
{
|
||||
typedef struct rndis_set_cmplt_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
__le32 Status;
|
||||
} rndis_set_cmplt_type;
|
||||
|
||||
typedef struct rndis_reset_msg_type
|
||||
{
|
||||
typedef struct rndis_reset_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 Reserved;
|
||||
} rndis_reset_msg_type;
|
||||
|
||||
typedef struct rndis_reset_cmplt_type
|
||||
{
|
||||
typedef struct rndis_reset_cmplt_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 Status;
|
||||
__le32 AddressingReset;
|
||||
} rndis_reset_cmplt_type;
|
||||
|
||||
typedef struct rndis_indicate_status_msg_type
|
||||
{
|
||||
typedef struct rndis_indicate_status_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 Status;
|
||||
@ -120,23 +110,20 @@ typedef struct rndis_indicate_status_msg_type
|
||||
__le32 StatusBufferOffset;
|
||||
} rndis_indicate_status_msg_type;
|
||||
|
||||
typedef struct rndis_keepalive_msg_type
|
||||
{
|
||||
typedef struct rndis_keepalive_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
} rndis_keepalive_msg_type;
|
||||
|
||||
typedef struct rndis_keepalive_cmplt_type
|
||||
{
|
||||
typedef struct rndis_keepalive_cmplt_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 RequestID;
|
||||
__le32 Status;
|
||||
} rndis_keepalive_cmplt_type;
|
||||
|
||||
struct rndis_packet_msg_type
|
||||
{
|
||||
struct rndis_packet_msg_type {
|
||||
__le32 MessageType;
|
||||
__le32 MessageLength;
|
||||
__le32 DataOffset;
|
||||
@ -150,8 +137,7 @@ struct rndis_packet_msg_type
|
||||
__le32 Reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rndis_config_parameter
|
||||
{
|
||||
struct rndis_config_parameter {
|
||||
__le32 ParameterNameOffset;
|
||||
__le32 ParameterNameLength;
|
||||
__le32 ParameterType;
|
||||
@ -160,23 +146,20 @@ struct rndis_config_parameter
|
||||
};
|
||||
|
||||
/* implementation specific */
|
||||
enum rndis_state
|
||||
{
|
||||
enum rndis_state {
|
||||
RNDIS_UNINITIALIZED,
|
||||
RNDIS_INITIALIZED,
|
||||
RNDIS_DATA_INITIALIZED,
|
||||
};
|
||||
|
||||
typedef struct rndis_resp_t
|
||||
{
|
||||
typedef struct rndis_resp_t {
|
||||
struct list_head list;
|
||||
u8 *buf;
|
||||
u32 length;
|
||||
int send;
|
||||
} rndis_resp_t;
|
||||
|
||||
typedef struct rndis_params
|
||||
{
|
||||
typedef struct rndis_params {
|
||||
int confignr;
|
||||
u8 used;
|
||||
u16 saved_filter;
|
||||
|
@ -224,7 +224,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
|
||||
if (dev->port_usb->is_fixed)
|
||||
size = max_t(size_t, size, dev->port_usb->fixed_out_len);
|
||||
|
||||
skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags);
|
||||
skb = __netdev_alloc_skb(dev->net, size + NET_IP_ALIGN, gfp_flags);
|
||||
if (skb == NULL) {
|
||||
DBG(dev, "no rx skb\n");
|
||||
goto enomem;
|
||||
@ -455,16 +455,17 @@ static void tx_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
/* FALLTHROUGH */
|
||||
case -ECONNRESET: /* unlink */
|
||||
case -ESHUTDOWN: /* disconnect etc */
|
||||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
case 0:
|
||||
dev->net->stats.tx_bytes += skb->len;
|
||||
dev_consume_skb_any(skb);
|
||||
}
|
||||
dev->net->stats.tx_packets++;
|
||||
|
||||
spin_lock(&dev->req_lock);
|
||||
list_add(&req->list, &dev->tx_reqs);
|
||||
spin_unlock(&dev->req_lock);
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
atomic_dec(&dev->tx_qlen);
|
||||
if (netif_carrier_ok(dev->net))
|
||||
|
@ -1256,7 +1256,8 @@ static void gserial_console_exit(void)
|
||||
struct gscons_info *info = &gscons_info;
|
||||
|
||||
unregister_console(&gserial_cons);
|
||||
kthread_stop(info->console_thread);
|
||||
if (info->console_thread != NULL)
|
||||
kthread_stop(info->console_thread);
|
||||
gs_buf_free(&info->con_buf);
|
||||
}
|
||||
|
||||
|
@ -26,14 +26,12 @@
|
||||
#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5)
|
||||
#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5)
|
||||
|
||||
struct uvc_request_data
|
||||
{
|
||||
struct uvc_request_data {
|
||||
__s32 length;
|
||||
__u8 data[60];
|
||||
};
|
||||
|
||||
struct uvc_event
|
||||
{
|
||||
struct uvc_event {
|
||||
union {
|
||||
enum usb_device_speed speed;
|
||||
struct usb_ctrlrequest req;
|
||||
@ -104,8 +102,7 @@ extern unsigned int uvc_gadget_trace_param;
|
||||
* Structures
|
||||
*/
|
||||
|
||||
struct uvc_video
|
||||
{
|
||||
struct uvc_video {
|
||||
struct usb_ep *ep;
|
||||
|
||||
/* Frame parameters */
|
||||
@ -134,15 +131,13 @@ struct uvc_video
|
||||
unsigned int fid;
|
||||
};
|
||||
|
||||
enum uvc_state
|
||||
{
|
||||
enum uvc_state {
|
||||
UVC_STATE_DISCONNECTED,
|
||||
UVC_STATE_CONNECTED,
|
||||
UVC_STATE_STREAMING,
|
||||
};
|
||||
|
||||
struct uvc_device
|
||||
{
|
||||
struct uvc_device {
|
||||
struct video_device vdev;
|
||||
struct v4l2_device v4l2_dev;
|
||||
enum uvc_state state;
|
||||
@ -175,8 +170,7 @@ static inline struct uvc_device *to_uvc(struct usb_function *f)
|
||||
return container_of(f, struct uvc_device, func);
|
||||
}
|
||||
|
||||
struct uvc_file_handle
|
||||
{
|
||||
struct uvc_file_handle {
|
||||
struct v4l2_fh vfh;
|
||||
struct uvc_video *device;
|
||||
};
|
||||
|
@ -53,8 +53,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
|
||||
* V4L2 ioctls
|
||||
*/
|
||||
|
||||
struct uvc_format
|
||||
{
|
||||
struct uvc_format {
|
||||
u8 bpp;
|
||||
u32 fcc;
|
||||
};
|
||||
|
@ -243,7 +243,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
|
||||
|
||||
req_size = video->ep->maxpacket
|
||||
* max_t(unsigned int, video->ep->maxburst, 1)
|
||||
* (video->ep->mult + 1);
|
||||
* (video->ep->mult);
|
||||
|
||||
for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
|
||||
video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
|
||||
|
@ -529,7 +529,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
||||
|
||||
DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc);
|
||||
|
||||
maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
|
||||
maxpacket = usb_endpoint_maxp(desc);
|
||||
|
||||
if (((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != ep->index)
|
||||
|| ep->index == 0
|
||||
@ -573,7 +573,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
||||
* Bits 11:12 specify number of _additional_
|
||||
* transactions per microframe.
|
||||
*/
|
||||
nr_trans = ((usb_endpoint_maxp(desc) >> 11) & 3) + 1;
|
||||
nr_trans = usb_endpoint_maxp_mult(desc);
|
||||
if (nr_trans > 3)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -182,7 +182,7 @@ int bdc_config_ep(struct bdc *bdc, struct bdc_ep *ep)
|
||||
usb_endpoint_xfer_int(desc)) {
|
||||
param2 |= si;
|
||||
|
||||
mbs = (usb_endpoint_maxp(desc) & 0x1800) >> 11;
|
||||
mbs = usb_endpoint_maxp_mult(desc);
|
||||
param2 |= mbs << MB_SHIFT;
|
||||
}
|
||||
break;
|
||||
|
@ -446,7 +446,7 @@ static int setup_bd_list_xfr(struct bdc *bdc, struct bdc_req *req, int num_bds)
|
||||
bd_xfr->start_bdi = bd_list->eqp_bdi;
|
||||
bd = bdi_to_bd(ep, bd_list->eqp_bdi);
|
||||
req_len = req->usb_req.length;
|
||||
maxp = usb_endpoint_maxp(ep->desc) & 0x7ff;
|
||||
maxp = usb_endpoint_maxp(ep->desc);
|
||||
tfs = roundup(req->usb_req.length, maxp);
|
||||
tfs = tfs/maxp;
|
||||
dev_vdbg(bdc->dev, "%s ep:%s num_bds:%d tfs:%d r_len:%d bd:%p\n",
|
||||
|
@ -503,7 +503,7 @@ static int dummy_enable(struct usb_ep *_ep,
|
||||
* maximum packet size.
|
||||
* For SS devices the wMaxPacketSize is limited by 1024.
|
||||
*/
|
||||
max = usb_endpoint_maxp(desc) & 0x7ff;
|
||||
max = usb_endpoint_maxp(desc);
|
||||
|
||||
/* drivers must not request bad settings, since lower levels
|
||||
* (hardware or its drivers) may not check. some endpoints
|
||||
@ -1483,8 +1483,7 @@ static int periodic_bytes(struct dummy *dum, struct dummy_ep *ep)
|
||||
int tmp;
|
||||
|
||||
/* high bandwidth mode */
|
||||
tmp = usb_endpoint_maxp(ep->desc);
|
||||
tmp = (tmp >> 11) & 0x03;
|
||||
tmp = usb_endpoint_maxp_mult(ep->desc);
|
||||
tmp *= 8 /* applies to entire frame */;
|
||||
limit += limit * tmp;
|
||||
}
|
||||
|
@ -585,8 +585,7 @@ static int fsl_ep_enable(struct usb_ep *_ep,
|
||||
break;
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
/* Calculate transactions needed for high bandwidth iso */
|
||||
mult = (unsigned char)(1 + ((max >> 11) & 0x03));
|
||||
max = max & 0x7ff; /* bit 0~10 */
|
||||
mult = usb_endpoint_maxp_mult(desc);
|
||||
/* 3 transactions at most */
|
||||
if (mult > 3)
|
||||
goto en_done;
|
||||
|
@ -218,7 +218,7 @@ static int config_ep(struct fusb300_ep *ep,
|
||||
(info.type == USB_ENDPOINT_XFER_ISOC)) {
|
||||
info.interval = desc->bInterval;
|
||||
if (info.type == USB_ENDPOINT_XFER_ISOC)
|
||||
info.bw_num = ((desc->wMaxPacketSize & 0x1800) >> 11);
|
||||
info.bw_num = usb_endpoint_maxp_mult(desc);
|
||||
}
|
||||
|
||||
ep_fifo_setting(fusb300, info);
|
||||
|
@ -1539,7 +1539,7 @@ static int gr_ep_enable(struct usb_ep *_ep,
|
||||
* additional transactions.
|
||||
*/
|
||||
max = 0x7ff & usb_endpoint_maxp(desc);
|
||||
nt = 0x3 & (usb_endpoint_maxp(desc) >> 11);
|
||||
nt = usb_endpoint_maxp_mult(desc) - 1;
|
||||
buffer_size = GR_BUFFER_SIZE(epctrl);
|
||||
if (nt && (mode == 0 || mode == 2)) {
|
||||
dev_err(dev->dev,
|
||||
|
@ -462,6 +462,12 @@ static int mv_u3d_req_to_trb(struct mv_u3d_req *req)
|
||||
req->trb_head->trb_hw,
|
||||
trb_num * sizeof(*trb_hw),
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (dma_mapping_error(u3d->gadget.dev.parent,
|
||||
req->trb_head->trb_dma)) {
|
||||
kfree(req->trb_head->trb_hw);
|
||||
kfree(req->trb_head);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
req->chain = 1;
|
||||
}
|
||||
@ -487,30 +493,32 @@ mv_u3d_start_queue(struct mv_u3d_ep *ep)
|
||||
ret = usb_gadget_map_request(&u3d->gadget, &req->req,
|
||||
mv_u3d_ep_dir(ep));
|
||||
if (ret)
|
||||
return ret;
|
||||
goto break_processing;
|
||||
|
||||
req->req.status = -EINPROGRESS;
|
||||
req->req.actual = 0;
|
||||
req->trb_count = 0;
|
||||
|
||||
/* build trbs and push them to device queue */
|
||||
if (!mv_u3d_req_to_trb(req)) {
|
||||
ret = mv_u3d_queue_trb(ep, req);
|
||||
if (ret) {
|
||||
ep->processing = 0;
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ep->processing = 0;
|
||||
/* build trbs */
|
||||
ret = mv_u3d_req_to_trb(req);
|
||||
if (ret) {
|
||||
dev_err(u3d->dev, "%s, mv_u3d_req_to_trb fail\n", __func__);
|
||||
return -ENOMEM;
|
||||
goto break_processing;
|
||||
}
|
||||
|
||||
/* and push them to device queue */
|
||||
ret = mv_u3d_queue_trb(ep, req);
|
||||
if (ret)
|
||||
goto break_processing;
|
||||
|
||||
/* irq handler advances the queue */
|
||||
if (req)
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
|
||||
return 0;
|
||||
|
||||
break_processing:
|
||||
ep->processing = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mv_u3d_ep_enable(struct usb_ep *_ep,
|
||||
|
@ -494,8 +494,7 @@ static int mv_ep_enable(struct usb_ep *_ep,
|
||||
break;
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
/* Calculate transactions needed for high bandwidth iso */
|
||||
mult = (unsigned char)(1 + ((max >> 11) & 0x03));
|
||||
max = max & 0x7ff; /* bit 0~10 */
|
||||
mult = usb_endpoint_maxp_mult(desc);
|
||||
/* 3 transactions at most */
|
||||
if (mult > 3)
|
||||
goto en_done;
|
||||
|
@ -202,10 +202,10 @@ net2272_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
||||
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
|
||||
return -ESHUTDOWN;
|
||||
|
||||
max = usb_endpoint_maxp(desc) & 0x1fff;
|
||||
max = usb_endpoint_maxp(desc);
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
_ep->maxpacket = max & 0x7fff;
|
||||
_ep->maxpacket = max;
|
||||
ep->desc = desc;
|
||||
|
||||
/* net2272_ep_reset() has already been called */
|
||||
|
@ -224,14 +224,14 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
||||
}
|
||||
|
||||
/* sanity check ep-e/ep-f since their fifos are small */
|
||||
max = usb_endpoint_maxp(desc) & 0x1fff;
|
||||
max = usb_endpoint_maxp(desc);
|
||||
if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY)) {
|
||||
ret = -ERANGE;
|
||||
goto print_err;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
_ep->maxpacket = max & 0x7ff;
|
||||
_ep->maxpacket = max;
|
||||
ep->desc = desc;
|
||||
|
||||
/* ep_reset() has already been called */
|
||||
@ -1839,7 +1839,7 @@ static ssize_t queues_show(struct device *_dev, struct device_attribute *attr,
|
||||
ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK,
|
||||
(t & USB_DIR_IN) ? "in" : "out",
|
||||
type_string(d->bmAttributes),
|
||||
usb_endpoint_maxp(d) & 0x1fff,
|
||||
usb_endpoint_maxp(d),
|
||||
ep->dma ? "dma" : "pio", ep->fifo_size
|
||||
);
|
||||
} else /* ep0 should only have one transfer queued */
|
||||
|
@ -1047,10 +1047,10 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep,
|
||||
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
|
||||
return -ESHUTDOWN;
|
||||
|
||||
max = usb_endpoint_maxp(desc) & 0x1fff;
|
||||
max = usb_endpoint_maxp(desc);
|
||||
|
||||
local_irq_save(flags);
|
||||
_ep->maxpacket = max & 0x7ff;
|
||||
_ep->maxpacket = max;
|
||||
ep->ep.desc = desc;
|
||||
ep->halted = 0;
|
||||
ep->bEndpointAddress = desc->bEndpointAddress;
|
||||
|
@ -550,11 +550,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
|
||||
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
|
||||
// ... and packet size, for any kind of endpoint descriptor
|
||||
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
|
||||
|
||||
/*
|
||||
* reverse of qh_urb_transaction: free a list of TDs.
|
||||
* used for cleanup after errors, before HC sees an URB's TDs.
|
||||
@ -651,7 +646,7 @@ qh_urb_transaction (
|
||||
token |= (1 /* "in" */ << 8);
|
||||
/* else it's already initted to "out" pid (0 << 8) */
|
||||
|
||||
maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
|
||||
maxpacket = usb_maxpacket(urb->dev, urb->pipe, !is_input);
|
||||
|
||||
/*
|
||||
* buffer gets wrapped in one or more qtds;
|
||||
@ -770,9 +765,11 @@ qh_make (
|
||||
gfp_t flags
|
||||
) {
|
||||
struct ehci_qh *qh = ehci_qh_alloc (ehci, flags);
|
||||
struct usb_host_endpoint *ep;
|
||||
u32 info1 = 0, info2 = 0;
|
||||
int is_input, type;
|
||||
int maxp = 0;
|
||||
int mult;
|
||||
struct usb_tt *tt = urb->dev->tt;
|
||||
struct ehci_qh_hw *hw;
|
||||
|
||||
@ -787,13 +784,15 @@ qh_make (
|
||||
|
||||
is_input = usb_pipein (urb->pipe);
|
||||
type = usb_pipetype (urb->pipe);
|
||||
maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input);
|
||||
ep = usb_pipe_endpoint (urb->dev, urb->pipe);
|
||||
maxp = usb_endpoint_maxp (&ep->desc);
|
||||
mult = usb_endpoint_maxp_mult (&ep->desc);
|
||||
|
||||
/* 1024 byte maxpacket is a hardware ceiling. High bandwidth
|
||||
* acts like up to 3KB, but is built from smaller packets.
|
||||
*/
|
||||
if (max_packet(maxp) > 1024) {
|
||||
ehci_dbg(ehci, "bogus qh maxpacket %d\n", max_packet(maxp));
|
||||
if (maxp > 1024) {
|
||||
ehci_dbg(ehci, "bogus qh maxpacket %d\n", maxp);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -809,8 +808,7 @@ qh_make (
|
||||
unsigned tmp;
|
||||
|
||||
qh->ps.usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
|
||||
is_input, 0,
|
||||
hb_mult(maxp) * max_packet(maxp)));
|
||||
is_input, 0, mult * maxp));
|
||||
qh->ps.phase = NO_FRAME;
|
||||
|
||||
if (urb->dev->speed == USB_SPEED_HIGH) {
|
||||
@ -854,7 +852,7 @@ qh_make (
|
||||
think_time = tt ? tt->think_time : 0;
|
||||
qh->ps.tt_usecs = NS_TO_US(think_time +
|
||||
usb_calc_bus_time (urb->dev->speed,
|
||||
is_input, 0, max_packet (maxp)));
|
||||
is_input, 0, maxp));
|
||||
if (urb->interval > ehci->periodic_size)
|
||||
urb->interval = ehci->periodic_size;
|
||||
qh->ps.period = urb->interval;
|
||||
@ -925,11 +923,11 @@ qh_make (
|
||||
* to help them do so. So now people expect to use
|
||||
* such nonconformant devices with Linux too; sigh.
|
||||
*/
|
||||
info1 |= max_packet(maxp) << 16;
|
||||
info1 |= maxp << 16;
|
||||
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||
} else { /* PIPE_INTERRUPT */
|
||||
info1 |= max_packet (maxp) << 16;
|
||||
info2 |= hb_mult (maxp) << 30;
|
||||
info1 |= maxp << 16;
|
||||
info2 |= mult << 30;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1221,7 +1219,7 @@ static int submit_single_step_set_feature(
|
||||
|
||||
token |= (1 /* "in" */ << 8); /*This is IN stage*/
|
||||
|
||||
maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, 0));
|
||||
maxpacket = usb_maxpacket(urb->dev, urb->pipe, 0);
|
||||
|
||||
qtd_fill(ehci, qtd, buf, len, token, maxpacket);
|
||||
|
||||
|
@ -1064,11 +1064,10 @@ iso_stream_init(
|
||||
|
||||
/* knows about ITD vs SITD */
|
||||
if (dev->speed == USB_SPEED_HIGH) {
|
||||
unsigned multi = hb_mult(maxp);
|
||||
unsigned multi = usb_endpoint_maxp_mult(&urb->ep->desc);
|
||||
|
||||
stream->highspeed = 1;
|
||||
|
||||
maxp = max_packet(maxp);
|
||||
buf1 |= maxp;
|
||||
maxp *= multi;
|
||||
|
||||
|
@ -1369,7 +1369,7 @@ static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
|
||||
if (udev->speed == USB_SPEED_HIGH &&
|
||||
(usb_endpoint_xfer_isoc(&ep->desc) ||
|
||||
usb_endpoint_xfer_int(&ep->desc)))
|
||||
return (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11;
|
||||
return usb_endpoint_maxp_mult(&ep->desc) - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1414,10 +1414,10 @@ static u32 xhci_get_max_esit_payload(struct usb_device *udev,
|
||||
else if (udev->speed >= USB_SPEED_SUPER)
|
||||
return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
|
||||
|
||||
max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
|
||||
max_burst = (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11;
|
||||
max_packet = usb_endpoint_maxp(&ep->desc);
|
||||
max_burst = usb_endpoint_maxp_mult(&ep->desc);
|
||||
/* A 0 in max burst means 1 transfer per ESIT */
|
||||
return max_packet * (max_burst + 1);
|
||||
return max_packet * max_burst;
|
||||
}
|
||||
|
||||
/* Set up an endpoint with one ring segment. Do not allocate stream rings.
|
||||
@ -1460,7 +1460,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||
max_esit_payload = xhci_get_max_esit_payload(udev, ep);
|
||||
interval = xhci_get_endpoint_interval(udev, ep);
|
||||
mult = xhci_get_endpoint_mult(udev, ep);
|
||||
max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
|
||||
max_packet = usb_endpoint_maxp(&ep->desc);
|
||||
max_burst = xhci_get_endpoint_max_burst(udev, ep);
|
||||
avg_trb_len = max_esit_payload;
|
||||
|
||||
|
@ -337,7 +337,7 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n",
|
||||
__func__, usb_endpoint_type(&ep->desc), udev->speed,
|
||||
GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)),
|
||||
usb_endpoint_maxp(&ep->desc),
|
||||
usb_endpoint_dir_in(&ep->desc), ep);
|
||||
|
||||
if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) {
|
||||
@ -403,7 +403,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
xhci_dbg(xhci, "%s() type:%d, speed:%d, mpks:%d, dir:%d, ep:%p\n",
|
||||
__func__, usb_endpoint_type(&ep->desc), udev->speed,
|
||||
GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)),
|
||||
usb_endpoint_maxp(&ep->desc),
|
||||
usb_endpoint_dir_in(&ep->desc), ep);
|
||||
|
||||
if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
|
||||
|
@ -2991,7 +2991,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
|
||||
if (xhci->quirks & XHCI_MTK_HOST)
|
||||
trb_buff_len = 0;
|
||||
|
||||
maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
|
||||
maxp = usb_endpoint_maxp(&urb->ep->desc);
|
||||
total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
|
||||
|
||||
/* Queueing functions don't count the current TRB into transferred */
|
||||
@ -3007,7 +3007,7 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len,
|
||||
unsigned int max_pkt;
|
||||
u32 new_buff_len;
|
||||
|
||||
max_pkt = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
|
||||
max_pkt = usb_endpoint_maxp(&urb->ep->desc);
|
||||
unalign = (enqd_len + *trb_buff_len) % max_pkt;
|
||||
|
||||
/* we got lucky, last normal TRB data on segment is packet aligned */
|
||||
@ -3521,7 +3521,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
||||
addr = start_addr + urb->iso_frame_desc[i].offset;
|
||||
td_len = urb->iso_frame_desc[i].length;
|
||||
td_remain_len = td_len;
|
||||
max_pkt = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
|
||||
max_pkt = usb_endpoint_maxp(&urb->ep->desc);
|
||||
total_pkt_count = DIV_ROUND_UP(td_len, max_pkt);
|
||||
|
||||
/* A zero-length transfer still involves at least one packet. */
|
||||
|
@ -3213,7 +3213,7 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
for (i = 0; i < num_eps; i++) {
|
||||
ep_index = xhci_get_endpoint_index(&eps[i]->desc);
|
||||
max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&eps[i]->desc));
|
||||
max_packet = usb_endpoint_maxp(&eps[i]->desc);
|
||||
vdev->eps[ep_index].stream_info = xhci_alloc_stream_info(xhci,
|
||||
num_stream_ctxs,
|
||||
num_streams,
|
||||
|
@ -749,11 +749,6 @@ struct xhci_ep_ctx {
|
||||
#define MAX_PACKET_MASK (0xffff << 16)
|
||||
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
|
||||
|
||||
/* Get max packet size from ep desc. Bit 10..0 specify the max packet size.
|
||||
* USB2.0 spec 9.6.6.
|
||||
*/
|
||||
#define GET_MAX_PACKET(p) ((p) & 0x7ff)
|
||||
|
||||
/* tx_info bitmasks */
|
||||
#define EP_AVG_TRB_LENGTH(p) ((p) & 0xffff)
|
||||
#define EP_MAX_ESIT_PAYLOAD_LO(p) (((p) & 0xffff) << 16)
|
||||
|
@ -1915,7 +1915,7 @@ static struct urb *iso_alloc_urb(
|
||||
if (bytes < 0 || !desc)
|
||||
return NULL;
|
||||
maxp = 0x7ff & usb_endpoint_maxp(desc);
|
||||
maxp *= 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11));
|
||||
maxp *= usb_endpoint_maxp_mult(desc);
|
||||
packets = DIV_ROUND_UP(bytes, maxp);
|
||||
|
||||
urb = usb_alloc_urb(packets, GFP_KERNEL);
|
||||
@ -2001,8 +2001,8 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param,
|
||||
"iso period %d %sframes, wMaxPacket %d, transactions: %d\n",
|
||||
1 << (desc->bInterval - 1),
|
||||
(udev->speed == USB_SPEED_HIGH) ? "micro" : "",
|
||||
usb_endpoint_maxp(desc) & 0x7ff,
|
||||
1 + (0x3 & (usb_endpoint_maxp(desc) >> 11)));
|
||||
usb_endpoint_maxp(desc),
|
||||
usb_endpoint_maxp_mult(desc));
|
||||
|
||||
dev_info(&dev->intf->dev,
|
||||
"total %lu msec (%lu packets)\n",
|
||||
|
@ -974,8 +974,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
|
||||
goto fail;
|
||||
|
||||
/* REVISIT this rules out high bandwidth periodic transfers */
|
||||
tmp = usb_endpoint_maxp(desc);
|
||||
if (tmp & ~0x07ff) {
|
||||
tmp = usb_endpoint_maxp_mult(desc) - 1;
|
||||
if (tmp) {
|
||||
int ok;
|
||||
|
||||
if (usb_endpoint_dir_in(desc))
|
||||
@ -987,12 +987,12 @@ static int musb_gadget_enable(struct usb_ep *ep,
|
||||
musb_dbg(musb, "no support for high bandwidth ISO");
|
||||
goto fail;
|
||||
}
|
||||
musb_ep->hb_mult = (tmp >> 11) & 3;
|
||||
musb_ep->hb_mult = tmp;
|
||||
} else {
|
||||
musb_ep->hb_mult = 0;
|
||||
}
|
||||
|
||||
musb_ep->packet_sz = tmp & 0x7ff;
|
||||
musb_ep->packet_sz = usb_endpoint_maxp(desc);
|
||||
tmp = musb_ep->packet_sz * (musb_ep->hb_mult + 1);
|
||||
|
||||
/* enable the interrupts for the endpoint, set the endpoint
|
||||
|
@ -2237,7 +2237,7 @@ static int musb_urb_enqueue(
|
||||
* Some musb cores don't support high bandwidth ISO transfers; and
|
||||
* we don't (yet!) support high bandwidth interrupt transfers.
|
||||
*/
|
||||
qh->hb_mult = 1 + ((qh->maxpacket >> 11) & 0x03);
|
||||
qh->hb_mult = usb_endpoint_maxp_mult(epd);
|
||||
if (qh->hb_mult > 1) {
|
||||
int ok = (qh->type == USB_ENDPOINT_XFER_ISOC);
|
||||
|
||||
|
@ -84,6 +84,7 @@ config SAMSUNG_USBPHY
|
||||
config TWL6030_USB
|
||||
tristate "TWL6030 USB Transceiver Driver"
|
||||
depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS
|
||||
depends on OF
|
||||
help
|
||||
Enable this to support the USB OTG transceiver on TWL6030
|
||||
family chips. This TWL6030 transceiver has the VBUS and ID GND
|
||||
|
@ -134,10 +134,12 @@ struct phy_control *am335x_get_phy_control(struct device *dev)
|
||||
return NULL;
|
||||
|
||||
dev = bus_find_device(&platform_bus_type, NULL, node, match);
|
||||
of_node_put(node);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
ctrl_usb = dev_get_drvdata(dev);
|
||||
put_device(dev);
|
||||
if (!ctrl_usb)
|
||||
return NULL;
|
||||
return &ctrl_usb->phy_ctrl;
|
||||
|
@ -59,6 +59,15 @@ EXPORT_SYMBOL_GPL(usb_phy_generic_unregister);
|
||||
|
||||
static int nop_set_suspend(struct usb_phy *x, int suspend)
|
||||
{
|
||||
struct usb_phy_generic *nop = dev_get_drvdata(x->dev);
|
||||
|
||||
if (!IS_ERR(nop->clk)) {
|
||||
if (suspend)
|
||||
clk_disable_unprepare(nop->clk);
|
||||
else
|
||||
clk_prepare_enable(nop->clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ struct isp1301 {
|
||||
|
||||
#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3)
|
||||
|
||||
#if defined(CONFIG_TPS65010) || (defined(CONFIG_TPS65010_MODULE) && defined(MODULE))
|
||||
#if IS_REACHABLE(CONFIG_TPS65010)
|
||||
|
||||
#include <linux/i2c/tps65010.h>
|
||||
|
||||
|
@ -108,7 +108,6 @@ struct twl6030_usb {
|
||||
enum musb_vbus_id_status linkstat;
|
||||
u8 asleep;
|
||||
bool vbus_enable;
|
||||
const char *regulator;
|
||||
};
|
||||
|
||||
#define comparator_to_twl(x) container_of((x), struct twl6030_usb, comparator)
|
||||
@ -166,7 +165,7 @@ static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
|
||||
/* Program MISC2 register and set bit VUSB_IN_VBAT */
|
||||
twl6030_writeb(twl, TWL6030_MODULE_ID0, 0x10, TWL6030_MISC2);
|
||||
|
||||
twl->usb3v3 = regulator_get(twl->dev, twl->regulator);
|
||||
twl->usb3v3 = regulator_get(twl->dev, "usb");
|
||||
if (IS_ERR(twl->usb3v3))
|
||||
return -ENODEV;
|
||||
|
||||
@ -341,7 +340,11 @@ static int twl6030_usb_probe(struct platform_device *pdev)
|
||||
int status, err;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct twl4030_usb_data *pdata = dev_get_platdata(dev);
|
||||
|
||||
if (!np) {
|
||||
dev_err(dev, "no DT info\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
twl = devm_kzalloc(dev, sizeof(*twl), GFP_KERNEL);
|
||||
if (!twl)
|
||||
@ -361,18 +364,6 @@ static int twl6030_usb_probe(struct platform_device *pdev)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
if (np) {
|
||||
twl->regulator = "usb";
|
||||
} else if (pdata) {
|
||||
if (pdata->features & TWL6032_SUBCLASS)
|
||||
twl->regulator = "ldousb";
|
||||
else
|
||||
twl->regulator = "vusb";
|
||||
} else {
|
||||
dev_err(&pdev->dev, "twl6030 initialized without pdata\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* init spinlock for workqueue */
|
||||
spin_lock_init(&twl->lock);
|
||||
|
||||
@ -436,13 +427,11 @@ static int twl6030_usb_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id twl6030_usb_id_table[] = {
|
||||
{ .compatible = "ti,twl6030-usb" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, twl6030_usb_id_table);
|
||||
#endif
|
||||
|
||||
static struct platform_driver twl6030_usb_driver = {
|
||||
.probe = twl6030_usb_probe,
|
||||
|
@ -100,10 +100,7 @@ static void __usbhsf_pkt_del(struct usbhs_pkt *pkt)
|
||||
|
||||
static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
|
||||
{
|
||||
if (list_empty(&pipe->list))
|
||||
return NULL;
|
||||
|
||||
return list_first_entry(&pipe->list, struct usbhs_pkt, node);
|
||||
return list_first_entry_or_null(&pipe->list, struct usbhs_pkt, node);
|
||||
}
|
||||
|
||||
static void usbhsf_fifo_clear(struct usbhs_pipe *pipe,
|
||||
|
@ -259,7 +259,7 @@ static int vep_enable(struct usb_ep *_ep,
|
||||
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
|
||||
maxp = usb_endpoint_maxp(desc) & 0x7ff;
|
||||
maxp = usb_endpoint_maxp(desc);
|
||||
_ep->maxpacket = maxp;
|
||||
ep->desc = desc;
|
||||
ep->type = usb_endpoint_type(desc);
|
||||
|
@ -429,7 +429,9 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)
|
||||
*/
|
||||
static inline size_t usb_ep_align(struct usb_ep *ep, size_t len)
|
||||
{
|
||||
return round_up(len, (size_t)le16_to_cpu(ep->desc->wMaxPacketSize));
|
||||
int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc) & 0x7ff;
|
||||
|
||||
return round_up(len, max_packet_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,6 +423,12 @@ struct usb_endpoint_descriptor {
|
||||
#define USB_ENDPOINT_XFER_INT 3
|
||||
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
|
||||
|
||||
#define USB_ENDPOINT_MAXP_MASK 0x07ff
|
||||
#define USB_EP_MAXP_MULT_SHIFT 11
|
||||
#define USB_EP_MAXP_MULT_MASK (3 << USB_EP_MAXP_MULT_SHIFT)
|
||||
#define USB_EP_MAXP_MULT(m) \
|
||||
(((m) & USB_EP_MAXP_MULT_MASK) >> USB_EP_MAXP_MULT_SHIFT)
|
||||
|
||||
/* The USB 3.0 spec redefines bits 5:4 of bmAttributes as interrupt ep type. */
|
||||
#define USB_ENDPOINT_INTRTYPE 0x30
|
||||
#define USB_ENDPOINT_INTR_PERIODIC (0 << 4)
|
||||
@ -623,11 +629,25 @@ static inline int usb_endpoint_is_isoc_out(
|
||||
* usb_endpoint_maxp - get endpoint's max packet size
|
||||
* @epd: endpoint to be checked
|
||||
*
|
||||
* Returns @epd's max packet
|
||||
* Returns @epd's max packet bits [10:0]
|
||||
*/
|
||||
static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
return __le16_to_cpu(epd->wMaxPacketSize);
|
||||
return __le16_to_cpu(epd->wMaxPacketSize) & USB_ENDPOINT_MAXP_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_endpoint_maxp_mult - get endpoint's transactional opportunities
|
||||
* @epd: endpoint to be checked
|
||||
*
|
||||
* Return @epd's wMaxPacketSize[12:11] + 1
|
||||
*/
|
||||
static inline int
|
||||
usb_endpoint_maxp_mult(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
int maxp = __le16_to_cpu(epd->wMaxPacketSize);
|
||||
|
||||
return USB_EP_MAXP_MULT(maxp) + 1;
|
||||
}
|
||||
|
||||
static inline int usb_endpoint_interrupt_type(
|
||||
|
Loading…
Reference in New Issue
Block a user