|
@@ -40,6 +40,7 @@ typedef int pm_message_t;
|
|
|
#define __devinit
|
|
|
#define pr_warning printf
|
|
|
#define pr_debug(args...)
|
|
|
+//#define VDBG(str, args...) printf(str "\n", ## args)
|
|
|
|
|
|
#define DRIVER_DESC "ARC USBOTG Device Controller driver"
|
|
|
#define DRIVER_AUTHOR "Freescale Semiconductor"
|
|
@@ -193,6 +194,31 @@ fsl_platform_pullup_disable(struct fsl_usb2_platform_data *pdata)
|
|
|
pdata->xcvr_ops->pullup(0);
|
|
|
}
|
|
|
|
|
|
+static void *malloc_dma_buffer(u32 *dmaaddr, int size, int align)
|
|
|
+{
|
|
|
+ void *mem;
|
|
|
+ mem = memalign(align, size);
|
|
|
+ *dmaaddr = mem;
|
|
|
+ return mem;
|
|
|
+
|
|
|
+ int msize = (size + align - 1);
|
|
|
+ u32 vir, vir_align;
|
|
|
+
|
|
|
+ vir = (u32)malloc(msize);
|
|
|
+#ifdef CONFIG_ARCH_MMU
|
|
|
+ vir = ioremap_nocache(iomem_to_phys(vir), msize);
|
|
|
+#endif
|
|
|
+ memset((void *)vir, 0, msize);
|
|
|
+ vir_align = (vir + align - 1) & (~(align - 1));
|
|
|
+#ifdef CONFIG_ARCH_MMU
|
|
|
+ *dmaaddr = (u32)iomem_to_phys(vir_align);
|
|
|
+#else
|
|
|
+ *dmaaddr = vir_align;
|
|
|
+#endif
|
|
|
+ DBG("vir addr %x, dma addr %x\n", vir_align, *dmaaddr);
|
|
|
+ return (void *)vir_align;
|
|
|
+}
|
|
|
+
|
|
|
/*-----------------------------------------------------------------
|
|
|
* done() - retire a request; caller blocked irqs
|
|
|
* @status : request status to be set, only works when
|
|
@@ -214,7 +240,6 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, int status)
|
|
|
req->req.status = status;
|
|
|
else
|
|
|
status = req->req.status;
|
|
|
-
|
|
|
/* Free dtd for the request */
|
|
|
next_td = req->head;
|
|
|
for (j = 0; j < req->dtd_count; j++) {
|
|
@@ -234,11 +259,14 @@ static void done(struct fsl_ep *ep, struct fsl_req *req, int status)
|
|
|
free(curr_td);
|
|
|
#endif
|
|
|
}
|
|
|
-
|
|
|
if (USE_MSC_WR(req->req.length)) {
|
|
|
memmove(req->req.buf, req->req.buf + 1, MSC_BULK_CB_WRAP_LEN);
|
|
|
}
|
|
|
|
|
|
+ if (req->mapped) {
|
|
|
+ req->req.dma = DMA_ADDR_INVALID;
|
|
|
+ req->mapped = 0;
|
|
|
+ }
|
|
|
if (status && (status != -ESHUTDOWN))
|
|
|
VDBG("complete %s req %p stat %d len %u/%u",
|
|
|
ep->ep.name, &req->req, status,
|
|
@@ -500,6 +528,8 @@ static void dr_controller_run(struct fsl_udc *udc)
|
|
|
/* disable pulldown dp and dm */
|
|
|
dr_discharge_line(udc->pdata, false);
|
|
|
udc->vbus_active = true;
|
|
|
+ fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP),
|
|
|
+ &dr_regs->usbcmd);
|
|
|
}
|
|
|
|
|
|
return;
|
|
@@ -929,6 +959,7 @@ out:
|
|
|
static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
|
|
|
dma_addr_t *dma, int *is_last)
|
|
|
{
|
|
|
+ //VDBG("top of build_dtd\n");
|
|
|
u32 swap_temp;
|
|
|
struct ep_td_struct *dtd;
|
|
|
|
|
@@ -937,7 +968,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
|
|
|
(unsigned)EP_MAX_LENGTH_TRANSFER);
|
|
|
if (NEED_IRAM(req->ep))
|
|
|
*length = min(*length, g_iram_size);
|
|
|
- dtd = malloc(sizeof(*dtd));
|
|
|
+ dtd = malloc_dma_buffer(dma, sizeof(struct ep_td_struct), DTD_ALIGNMENT);
|
|
|
if (dtd == NULL)
|
|
|
return dtd;
|
|
|
|
|
@@ -1402,6 +1433,7 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active)
|
|
|
*/
|
|
|
static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA)
|
|
|
{
|
|
|
+ VDBG("in vbus_draw\n");
|
|
|
struct fsl_udc *udc;
|
|
|
struct fsl_usb2_platform_data *pdata;
|
|
|
|
|
@@ -1459,6 +1491,7 @@ static struct usb_gadget_ops fsl_gadget_ops = {
|
|
|
on new transaction */
|
|
|
static void ep0stall(struct fsl_udc *udc)
|
|
|
{
|
|
|
+ VDBG("in ep0stall");
|
|
|
u32 tmp;
|
|
|
|
|
|
/* must set tx and rx to stall at the same time */
|
|
@@ -1598,6 +1631,7 @@ static void setup_received_irq(struct fsl_udc *udc,
|
|
|
unsigned mA = 500;
|
|
|
udc_reset_ep_queue(udc, 0);
|
|
|
|
|
|
+ VDBG("request: %x", setup->bRequest);
|
|
|
/* We process some stardard setup requests here */
|
|
|
switch (setup->bRequest) {
|
|
|
case USB_REQ_GET_STATUS:
|
|
@@ -1621,7 +1655,7 @@ static void setup_received_irq(struct fsl_udc *udc,
|
|
|
return;
|
|
|
case USB_REQ_SET_CONFIGURATION:
|
|
|
spin_unlock(&udc->lock);
|
|
|
- fsl_vbus_draw(gadget, mA);
|
|
|
+ //fsl_vbus_draw(gadget, mA);
|
|
|
spin_lock(&udc->lock);
|
|
|
break;
|
|
|
case USB_REQ_CLEAR_FEATURE:
|
|
@@ -1722,6 +1756,7 @@ static void setup_received_irq(struct fsl_udc *udc,
|
|
|
}
|
|
|
} else {
|
|
|
/* No data phase, IN status from gadget */
|
|
|
+ VDBG("in else branch");
|
|
|
udc->ep0_dir = USB_DIR_IN;
|
|
|
spin_unlock(&udc->lock);
|
|
|
if (udc->driver->setup(&udc->gadget,
|
|
@@ -1729,6 +1764,7 @@ static void setup_received_irq(struct fsl_udc *udc,
|
|
|
ep0stall(udc);
|
|
|
}
|
|
|
spin_lock(&udc->lock);
|
|
|
+ VDBG("end of setup_received_irq");
|
|
|
}
|
|
|
|
|
|
/* Process request for Data or Status phase of ep0
|
|
@@ -2280,7 +2316,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
|
|
|
if (irq_src == 0x0)
|
|
|
goto irq_end;
|
|
|
|
|
|
- VDBG("0x%x\n", irq_src);
|
|
|
+ VDBG("IRQ: 0x%x\n", irq_src);
|
|
|
|
|
|
/* Need to resume? */
|
|
|
if (udc->usb_state == USB_STATE_SUSPENDED)
|
|
@@ -2375,7 +2411,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
|
|
/* bind udc driver to gadget driver */
|
|
|
retval = driver->bind(&udc_controller->gadget);
|
|
|
if (retval) {
|
|
|
- VDBG("bind to %s --> %d", driver->driver.name, retval);
|
|
|
+ VDBG("bind udc driver to gadget driver --> %d", retval);
|
|
|
//udc_controller->gadget.dev.driver = 0;
|
|
|
udc_controller->driver = 0;
|
|
|
dr_clk_gate(false);
|
|
@@ -2514,7 +2550,7 @@ static int __init struct_udc_setup(struct fsl_udc *udc,
|
|
|
size += QH_ALIGNMENT + 1;
|
|
|
size &= ~(QH_ALIGNMENT - 1);
|
|
|
}
|
|
|
- udc->ep_qh = malloc(size);
|
|
|
+ udc->ep_qh = malloc_dma_buffer(&udc->ep_qh_dma, size, QH_ALIGNMENT);
|
|
|
if (!udc->ep_qh) {
|
|
|
ERR("malloc QHs for udc failed\n");
|
|
|
kfree(udc->eps);
|
|
@@ -2628,7 +2664,7 @@ struct usb_dr_device *get_dr_regs(void)
|
|
|
* all intialization operations implemented here except enabling usb_intr reg
|
|
|
* board setup should have been done in the platform code
|
|
|
*/
|
|
|
-int __devinit fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
|
|
|
+int fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
|
|
|
{
|
|
|
int ret = -ENODEV;
|
|
|
unsigned int i;
|
|
@@ -2665,6 +2701,7 @@ int __devinit fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
|
|
|
set_usb_phy1_clk();
|
|
|
enable_usboh3_clk(1);
|
|
|
enable_usb_phy1_clk(1);
|
|
|
+ //usb_phy_enable();
|
|
|
#if 0
|
|
|
if (pdata->init && pdata->init(pdata)) {
|
|
|
pdata->lowpower = false;
|