Commit ae4d814b authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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.
parents 37be6676 d5c024f3
......@@ -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 @@ usb_otg: usb@10180000 {
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 @@ usb_otg: usb@ff580000 {
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 @@ usb_otg: usb@10180000 {
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 @@ usb: usb@f72c0000 {
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 @@ usb_otg: usb@ff580000 {
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
......
This diff is collapsed.
This diff is collapsed.
......@@ -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");
......
This diff is collapsed.
This diff is collapsed.
......@@ -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 @@ static void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg,
static int dwc2_update_non_isoc_urb_state_ddma(struct dwc2_hsotg *hsotg,
struct dwc2_host_chan *chan,
struct dwc2_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 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
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
......
This diff is collapsed.
......@@ -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 = &params_bcm2835 },
{ .compatible = "hisilicon,hi6220-usb", .data = &params_hi6220 },
{ .compatible = "rockchip,rk3066-usb", .data = &params_rk3066 },
{ .compatible = "lantiq,arx100-usb", .data = &params_ltq },
{ .compatible = "lantiq,xrx200-usb", .data = &params_ltq },
{ .compatible = "snps,dwc2", .data = NULL },
{ .compatible = "samsung,s3c6400-hsotg", .data = NULL},
{ .compatible = "amlogic,meson8b-usb", .data = &params_amlogic },
{ .compatible = "amlogic,meson-gxbb-usb", .data = &params_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
......
This diff is collapsed.
This diff is collapsed.
/**
* 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;
......
This diff is collapsed.
......@@ -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;
......
This diff is collapsed.
This diff is collapsed.
......@@ -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)
......
This diff is collapsed.
......@@ -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 */
This diff is collapsed.
This diff is collapsed.
......@@ -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)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment