|
@@ -38,6 +38,7 @@
|
|
#include <linux/platform_device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/fsl_devices.h>
|
|
#include <linux/fsl_devices.h>
|
|
#include <linux/dmapool.h>
|
|
#include <linux/dmapool.h>
|
|
|
|
+#include <linux/delay.h>
|
|
|
|
|
|
#include <asm/byteorder.h>
|
|
#include <asm/byteorder.h>
|
|
#include <asm/io.h>
|
|
#include <asm/io.h>
|
|
@@ -57,7 +58,9 @@ static const char driver_name[] = "fsl-usb2-udc";
|
|
static const char driver_desc[] = DRIVER_DESC;
|
|
static const char driver_desc[] = DRIVER_DESC;
|
|
|
|
|
|
static struct usb_dr_device *dr_regs;
|
|
static struct usb_dr_device *dr_regs;
|
|
|
|
+#ifndef CONFIG_ARCH_MXC
|
|
static struct usb_sys_interface *usb_sys_regs;
|
|
static struct usb_sys_interface *usb_sys_regs;
|
|
|
|
+#endif
|
|
|
|
|
|
/* it is initialized in probe() */
|
|
/* it is initialized in probe() */
|
|
static struct fsl_udc *udc_controller = NULL;
|
|
static struct fsl_udc *udc_controller = NULL;
|
|
@@ -174,10 +177,34 @@ static void nuke(struct fsl_ep *ep, int status)
|
|
|
|
|
|
static int dr_controller_setup(struct fsl_udc *udc)
|
|
static int dr_controller_setup(struct fsl_udc *udc)
|
|
{
|
|
{
|
|
- unsigned int tmp = 0, portctrl = 0, ctrl = 0;
|
|
|
|
|
|
+ unsigned int tmp, portctrl;
|
|
|
|
+#ifndef CONFIG_ARCH_MXC
|
|
|
|
+ unsigned int ctrl;
|
|
|
|
+#endif
|
|
unsigned long timeout;
|
|
unsigned long timeout;
|
|
#define FSL_UDC_RESET_TIMEOUT 1000
|
|
#define FSL_UDC_RESET_TIMEOUT 1000
|
|
|
|
|
|
|
|
+ /* Config PHY interface */
|
|
|
|
+ portctrl = fsl_readl(&dr_regs->portsc1);
|
|
|
|
+ portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
|
|
|
|
+ switch (udc->phy_mode) {
|
|
|
|
+ case FSL_USB2_PHY_ULPI:
|
|
|
|
+ portctrl |= PORTSCX_PTS_ULPI;
|
|
|
|
+ break;
|
|
|
|
+ case FSL_USB2_PHY_UTMI_WIDE:
|
|
|
|
+ portctrl |= PORTSCX_PTW_16BIT;
|
|
|
|
+ /* fall through */
|
|
|
|
+ case FSL_USB2_PHY_UTMI:
|
|
|
|
+ portctrl |= PORTSCX_PTS_UTMI;
|
|
|
|
+ break;
|
|
|
|
+ case FSL_USB2_PHY_SERIAL:
|
|
|
|
+ portctrl |= PORTSCX_PTS_FSLS;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ fsl_writel(portctrl, &dr_regs->portsc1);
|
|
|
|
+
|
|
/* Stop and reset the usb controller */
|
|
/* Stop and reset the usb controller */
|
|
tmp = fsl_readl(&dr_regs->usbcmd);
|
|
tmp = fsl_readl(&dr_regs->usbcmd);
|
|
tmp &= ~USB_CMD_RUN_STOP;
|
|
tmp &= ~USB_CMD_RUN_STOP;
|
|
@@ -215,31 +242,12 @@ static int dr_controller_setup(struct fsl_udc *udc)
|
|
udc->ep_qh, (int)tmp,
|
|
udc->ep_qh, (int)tmp,
|
|
fsl_readl(&dr_regs->endpointlistaddr));
|
|
fsl_readl(&dr_regs->endpointlistaddr));
|
|
|
|
|
|
- /* Config PHY interface */
|
|
|
|
- portctrl = fsl_readl(&dr_regs->portsc1);
|
|
|
|
- portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
|
|
|
|
- switch (udc->phy_mode) {
|
|
|
|
- case FSL_USB2_PHY_ULPI:
|
|
|
|
- portctrl |= PORTSCX_PTS_ULPI;
|
|
|
|
- break;
|
|
|
|
- case FSL_USB2_PHY_UTMI_WIDE:
|
|
|
|
- portctrl |= PORTSCX_PTW_16BIT;
|
|
|
|
- /* fall through */
|
|
|
|
- case FSL_USB2_PHY_UTMI:
|
|
|
|
- portctrl |= PORTSCX_PTS_UTMI;
|
|
|
|
- break;
|
|
|
|
- case FSL_USB2_PHY_SERIAL:
|
|
|
|
- portctrl |= PORTSCX_PTS_FSLS;
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- fsl_writel(portctrl, &dr_regs->portsc1);
|
|
|
|
-
|
|
|
|
/* Config control enable i/o output, cpu endian register */
|
|
/* Config control enable i/o output, cpu endian register */
|
|
|
|
+#ifndef CONFIG_ARCH_MXC
|
|
ctrl = __raw_readl(&usb_sys_regs->control);
|
|
ctrl = __raw_readl(&usb_sys_regs->control);
|
|
ctrl |= USB_CTRL_IOENB;
|
|
ctrl |= USB_CTRL_IOENB;
|
|
__raw_writel(ctrl, &usb_sys_regs->control);
|
|
__raw_writel(ctrl, &usb_sys_regs->control);
|
|
|
|
+#endif
|
|
|
|
|
|
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
|
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
|
/* Turn on cache snooping hardware, since some PowerPC platforms
|
|
/* Turn on cache snooping hardware, since some PowerPC platforms
|
|
@@ -2043,6 +2051,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|
size -= t;
|
|
size -= t;
|
|
next += t;
|
|
next += t;
|
|
|
|
|
|
|
|
+#ifndef CONFIG_ARCH_MXC
|
|
tmp_reg = usb_sys_regs->snoop1;
|
|
tmp_reg = usb_sys_regs->snoop1;
|
|
t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
|
|
t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
|
|
size -= t;
|
|
size -= t;
|
|
@@ -2053,6 +2062,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|
tmp_reg);
|
|
tmp_reg);
|
|
size -= t;
|
|
size -= t;
|
|
next += t;
|
|
next += t;
|
|
|
|
+#endif
|
|
|
|
|
|
/* ------fsl_udc, fsl_ep, fsl_request structure information ----- */
|
|
/* ------fsl_udc, fsl_ep, fsl_request structure information ----- */
|
|
ep = &udc->eps[0];
|
|
ep = &udc->eps[0];
|
|
@@ -2263,14 +2273,21 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|
goto err_kfree;
|
|
goto err_kfree;
|
|
}
|
|
}
|
|
|
|
|
|
- dr_regs = ioremap(res->start, res->end - res->start + 1);
|
|
|
|
|
|
+ dr_regs = ioremap(res->start, resource_size(res));
|
|
if (!dr_regs) {
|
|
if (!dr_regs) {
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
goto err_release_mem_region;
|
|
goto err_release_mem_region;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifndef CONFIG_ARCH_MXC
|
|
usb_sys_regs = (struct usb_sys_interface *)
|
|
usb_sys_regs = (struct usb_sys_interface *)
|
|
((u32)dr_regs + USB_DR_SYS_OFFSET);
|
|
((u32)dr_regs + USB_DR_SYS_OFFSET);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ /* Initialize USB clocks */
|
|
|
|
+ ret = fsl_udc_clk_init(pdev);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ goto err_iounmap_noclk;
|
|
|
|
|
|
/* Read Device Controller Capability Parameters register */
|
|
/* Read Device Controller Capability Parameters register */
|
|
dccparams = fsl_readl(&dr_regs->dccparams);
|
|
dccparams = fsl_readl(&dr_regs->dccparams);
|
|
@@ -2308,6 +2325,8 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|
* leave usbintr reg untouched */
|
|
* leave usbintr reg untouched */
|
|
dr_controller_setup(udc_controller);
|
|
dr_controller_setup(udc_controller);
|
|
|
|
|
|
|
|
+ fsl_udc_clk_finalize(pdev);
|
|
|
|
+
|
|
/* Setup gadget structure */
|
|
/* Setup gadget structure */
|
|
udc_controller->gadget.ops = &fsl_gadget_ops;
|
|
udc_controller->gadget.ops = &fsl_gadget_ops;
|
|
udc_controller->gadget.is_dualspeed = 1;
|
|
udc_controller->gadget.is_dualspeed = 1;
|
|
@@ -2362,6 +2381,8 @@ err_unregister:
|
|
err_free_irq:
|
|
err_free_irq:
|
|
free_irq(udc_controller->irq, udc_controller);
|
|
free_irq(udc_controller->irq, udc_controller);
|
|
err_iounmap:
|
|
err_iounmap:
|
|
|
|
+ fsl_udc_clk_release();
|
|
|
|
+err_iounmap_noclk:
|
|
iounmap(dr_regs);
|
|
iounmap(dr_regs);
|
|
err_release_mem_region:
|
|
err_release_mem_region:
|
|
release_mem_region(res->start, res->end - res->start + 1);
|
|
release_mem_region(res->start, res->end - res->start + 1);
|
|
@@ -2384,6 +2405,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
udc_controller->done = &done;
|
|
udc_controller->done = &done;
|
|
|
|
|
|
|
|
+ fsl_udc_clk_release();
|
|
|
|
+
|
|
/* DR has been stopped in usb_gadget_unregister_driver() */
|
|
/* DR has been stopped in usb_gadget_unregister_driver() */
|
|
remove_proc_file();
|
|
remove_proc_file();
|
|
|
|
|