aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Zhang <zhangwm@marvell.com>2011-10-12 04:49:24 -0400
committerFelipe Balbi <balbi@ti.com>2011-10-13 13:41:56 -0400
commitdde34cc5019b51088c18ca789d4b1a20cf9bc617 (patch)
tree8d9032db3b0ed2a21364c073cd327c46665c383c
parent8a9775ab71218690ac34bed9e237e2b968857d3a (diff)
usb: gadget: mv_udc: refine the driver structure
This patch do the following things: 1. Add header and Copyright for marvell usb driver. 2. Add mv_usb.h in include/linux/platform_data, make the driver fits all the marvell platform using the same ChipIdea usb ip. 3. Some SOC may has mutiple clock sources, so let me define it in mv_usb_platform_data and give two helper functions named udc_clock_enable/udc_clock_disable to deal with the clocks. 4. Different SOCs will have some difference in PHY initialization, so we will remove file mv_udc_phy.c and add two funtions in mv_usb_platform_data, let the platform relative driver to realize it. 5. Rewrite probe function according to the modification list above. Find it will kernel panic when probe failed. The root cause is as follows: When probe failed, the error handle may call device_unregister() which in return will call gadget_release.In current code, gadget_release have two issues: 1: the_controller is a NULL pointer. 2: if we free udc here, then the following code in probe will access NULL pointer. Signed-off-by: Neil Zhang <zhangwm@marvell.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/gadget/Makefile2
-rw-r--r--drivers/usb/gadget/mv_udc.h17
-rw-r--r--drivers/usb/gadget/mv_udc_core.c158
-rw-r--r--drivers/usb/gadget/mv_udc_phy.c214
-rw-r--r--include/linux/platform_data/mv_usb.h50
5 files changed, 182 insertions, 259 deletions
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 9ba725af4a08..c36da63009db 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -28,7 +28,7 @@ obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o
28obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o 28obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o
29obj-$(CONFIG_USB_EG20T) += pch_udc.o 29obj-$(CONFIG_USB_EG20T) += pch_udc.o
30obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o 30obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o
31mv_udc-y := mv_udc_core.o mv_udc_phy.o 31mv_udc-y := mv_udc_core.o
32obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o 32obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o
33obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o 33obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o
34 34
diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h
index 65f1f7c3bd4e..d3d26454b8bb 100644
--- a/drivers/usb/gadget/mv_udc.h
+++ b/drivers/usb/gadget/mv_udc.h
@@ -1,3 +1,11 @@
1/*
2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
1 9
2#ifndef __MV_UDC_H 10#ifndef __MV_UDC_H
3#define __MV_UDC_H 11#define __MV_UDC_H
@@ -201,7 +209,12 @@ struct mv_udc {
201 remote_wakeup:1, 209 remote_wakeup:1,
202 softconnected:1, 210 softconnected:1,
203 force_fs:1; 211 force_fs:1;
204 struct clk *clk; 212
213 struct mv_usb_platform_data *pdata;
214
215 /* some SOC has mutiple clock sources for USB*/
216 unsigned int clknum;
217 struct clk *clk[0];
205}; 218};
206 219
207/* endpoint data structure */ 220/* endpoint data structure */
@@ -289,6 +302,4 @@ struct mv_dtd {
289 struct mv_dtd *next_dtd_virt; 302 struct mv_dtd *next_dtd_virt;
290}; 303};
291 304
292extern int mv_udc_phy_init(unsigned int base);
293
294#endif 305#endif
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index 0d0e9e39f8b2..40a25e75cc6a 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -1,3 +1,14 @@
1/*
2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
3 * Author: Chao Xie <chao.xie@marvell.com>
4 * Neil Zhang <zhangwm@marvell.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
1#include <linux/module.h> 12#include <linux/module.h>
2#include <linux/pci.h> 13#include <linux/pci.h>
3#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
@@ -22,6 +33,7 @@
22#include <linux/irq.h> 33#include <linux/irq.h>
23#include <linux/platform_device.h> 34#include <linux/platform_device.h>
24#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/platform_data/mv_usb.h>
25#include <asm/system.h> 37#include <asm/system.h>
26#include <asm/unaligned.h> 38#include <asm/unaligned.h>
27 39
@@ -45,6 +57,8 @@
45#define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) 57#define LOOPS_USEC (1 << LOOPS_USEC_SHIFT)
46#define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT) 58#define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT)
47 59
60static DECLARE_COMPLETION(release_done);
61
48static const char driver_name[] = "mv_udc"; 62static const char driver_name[] = "mv_udc";
49static const char driver_desc[] = DRIVER_DESC; 63static const char driver_desc[] = DRIVER_DESC;
50 64
@@ -987,6 +1001,22 @@ static struct usb_ep_ops mv_ep_ops = {
987 .fifo_flush = mv_ep_fifo_flush, /* flush fifo */ 1001 .fifo_flush = mv_ep_fifo_flush, /* flush fifo */
988}; 1002};
989 1003
1004static void udc_clock_enable(struct mv_udc *udc)
1005{
1006 unsigned int i;
1007
1008 for (i = 0; i < udc->clknum; i++)
1009 clk_enable(udc->clk[i]);
1010}
1011
1012static void udc_clock_disable(struct mv_udc *udc)
1013{
1014 unsigned int i;
1015
1016 for (i = 0; i < udc->clknum; i++)
1017 clk_disable(udc->clk[i]);
1018}
1019
990static void udc_stop(struct mv_udc *udc) 1020static void udc_stop(struct mv_udc *udc)
991{ 1021{
992 u32 tmp; 1022 u32 tmp;
@@ -1877,18 +1907,15 @@ static void gadget_release(struct device *_dev)
1877 struct mv_udc *udc = the_controller; 1907 struct mv_udc *udc = the_controller;
1878 1908
1879 complete(udc->done); 1909 complete(udc->done);
1880 kfree(udc);
1881} 1910}
1882 1911
1883static int mv_udc_remove(struct platform_device *dev) 1912static int mv_udc_remove(struct platform_device *dev)
1884{ 1913{
1885 struct mv_udc *udc = the_controller; 1914 struct mv_udc *udc = the_controller;
1886 DECLARE_COMPLETION(done); 1915 int clk_i;
1887 1916
1888 usb_del_gadget_udc(&udc->gadget); 1917 usb_del_gadget_udc(&udc->gadget);
1889 1918
1890 udc->done = &done;
1891
1892 /* free memory allocated in probe */ 1919 /* free memory allocated in probe */
1893 if (udc->dtd_pool) 1920 if (udc->dtd_pool)
1894 dma_pool_destroy(udc->dtd_pool); 1921 dma_pool_destroy(udc->dtd_pool);
@@ -1915,10 +1942,14 @@ static int mv_udc_remove(struct platform_device *dev)
1915 kfree(udc->status_req); 1942 kfree(udc->status_req);
1916 } 1943 }
1917 1944
1945 for (clk_i = 0; clk_i <= udc->clknum; clk_i++)
1946 clk_put(udc->clk[clk_i]);
1947
1918 device_unregister(&udc->gadget.dev); 1948 device_unregister(&udc->gadget.dev);
1919 1949
1920 /* free dev, wait for the release() finished */ 1950 /* free dev, wait for the release() finished */
1921 wait_for_completion(&done); 1951 wait_for_completion(udc->done);
1952 kfree(udc);
1922 1953
1923 the_controller = NULL; 1954 the_controller = NULL;
1924 1955
@@ -1927,33 +1958,46 @@ static int mv_udc_remove(struct platform_device *dev)
1927 1958
1928int mv_udc_probe(struct platform_device *dev) 1959int mv_udc_probe(struct platform_device *dev)
1929{ 1960{
1961 struct mv_usb_platform_data *pdata = dev->dev.platform_data;
1930 struct mv_udc *udc; 1962 struct mv_udc *udc;
1931 int retval = 0; 1963 int retval = 0;
1964 int clk_i = 0;
1932 struct resource *r; 1965 struct resource *r;
1933 size_t size; 1966 size_t size;
1934 1967
1935 udc = kzalloc(sizeof *udc, GFP_KERNEL); 1968 if (pdata == NULL) {
1969 dev_err(&dev->dev, "missing platform_data\n");
1970 return -ENODEV;
1971 }
1972
1973 size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum;
1974 udc = kzalloc(size, GFP_KERNEL);
1936 if (udc == NULL) { 1975 if (udc == NULL) {
1937 dev_err(&dev->dev, "failed to allocate memory for udc\n"); 1976 dev_err(&dev->dev, "failed to allocate memory for udc\n");
1938 retval = -ENOMEM; 1977 return -ENOMEM;
1939 goto error;
1940 } 1978 }
1941 1979
1980 the_controller = udc;
1981 udc->done = &release_done;
1982 udc->pdata = dev->dev.platform_data;
1942 spin_lock_init(&udc->lock); 1983 spin_lock_init(&udc->lock);
1943 1984
1944 udc->dev = dev; 1985 udc->dev = dev;
1945 1986
1946 udc->clk = clk_get(&dev->dev, "U2OCLK"); 1987 udc->clknum = pdata->clknum;
1947 if (IS_ERR(udc->clk)) { 1988 for (clk_i = 0; clk_i < udc->clknum; clk_i++) {
1948 retval = PTR_ERR(udc->clk); 1989 udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]);
1949 goto error; 1990 if (IS_ERR(udc->clk[clk_i])) {
1991 retval = PTR_ERR(udc->clk[clk_i]);
1992 goto err_put_clk;
1993 }
1950 } 1994 }
1951 1995
1952 r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2o"); 1996 r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs");
1953 if (r == NULL) { 1997 if (r == NULL) {
1954 dev_err(&dev->dev, "no I/O memory resource defined\n"); 1998 dev_err(&dev->dev, "no I/O memory resource defined\n");
1955 retval = -ENODEV; 1999 retval = -ENODEV;
1956 goto error; 2000 goto err_put_clk;
1957 } 2001 }
1958 2002
1959 udc->cap_regs = (struct mv_cap_regs __iomem *) 2003 udc->cap_regs = (struct mv_cap_regs __iomem *)
@@ -1961,29 +2005,31 @@ int mv_udc_probe(struct platform_device *dev)
1961 if (udc->cap_regs == NULL) { 2005 if (udc->cap_regs == NULL) {
1962 dev_err(&dev->dev, "failed to map I/O memory\n"); 2006 dev_err(&dev->dev, "failed to map I/O memory\n");
1963 retval = -EBUSY; 2007 retval = -EBUSY;
1964 goto error; 2008 goto err_put_clk;
1965 } 2009 }
1966 2010
1967 r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2ophy"); 2011 r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs");
1968 if (r == NULL) { 2012 if (r == NULL) {
1969 dev_err(&dev->dev, "no phy I/O memory resource defined\n"); 2013 dev_err(&dev->dev, "no phy I/O memory resource defined\n");
1970 retval = -ENODEV; 2014 retval = -ENODEV;
1971 goto error; 2015 goto err_iounmap_capreg;
1972 } 2016 }
1973 2017
1974 udc->phy_regs = (unsigned int)ioremap(r->start, resource_size(r)); 2018 udc->phy_regs = (unsigned int)ioremap(r->start, resource_size(r));
1975 if (udc->phy_regs == 0) { 2019 if (udc->phy_regs == 0) {
1976 dev_err(&dev->dev, "failed to map phy I/O memory\n"); 2020 dev_err(&dev->dev, "failed to map phy I/O memory\n");
1977 retval = -EBUSY; 2021 retval = -EBUSY;
1978 goto error; 2022 goto err_iounmap_capreg;
1979 } 2023 }
1980 2024
1981 /* we will acces controller register, so enable the clk */ 2025 /* we will acces controller register, so enable the clk */
1982 clk_enable(udc->clk); 2026 udc_clock_enable(udc);
1983 retval = mv_udc_phy_init(udc->phy_regs); 2027 if (pdata->phy_init) {
1984 if (retval) { 2028 retval = pdata->phy_init(udc->phy_regs);
1985 dev_err(&dev->dev, "phy initialization error %d\n", retval); 2029 if (retval) {
1986 goto error; 2030 dev_err(&dev->dev, "phy init error %d\n", retval);
2031 goto err_iounmap_phyreg;
2032 }
1987 } 2033 }
1988 2034
1989 udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs 2035 udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs
@@ -1999,7 +2045,7 @@ int mv_udc_probe(struct platform_device *dev)
1999 if (udc->ep_dqh == NULL) { 2045 if (udc->ep_dqh == NULL) {
2000 dev_err(&dev->dev, "allocate dQH memory failed\n"); 2046 dev_err(&dev->dev, "allocate dQH memory failed\n");
2001 retval = -ENOMEM; 2047 retval = -ENOMEM;
2002 goto error; 2048 goto err_disable_clock;
2003 } 2049 }
2004 udc->ep_dqh_size = size; 2050 udc->ep_dqh_size = size;
2005 2051
@@ -2012,7 +2058,7 @@ int mv_udc_probe(struct platform_device *dev)
2012 2058
2013 if (!udc->dtd_pool) { 2059 if (!udc->dtd_pool) {
2014 retval = -ENOMEM; 2060 retval = -ENOMEM;
2015 goto error; 2061 goto err_free_dma;
2016 } 2062 }
2017 2063
2018 size = udc->max_eps * sizeof(struct mv_ep) *2; 2064 size = udc->max_eps * sizeof(struct mv_ep) *2;
@@ -2020,7 +2066,7 @@ int mv_udc_probe(struct platform_device *dev)
2020 if (udc->eps == NULL) { 2066 if (udc->eps == NULL) {
2021 dev_err(&dev->dev, "allocate ep memory failed\n"); 2067 dev_err(&dev->dev, "allocate ep memory failed\n");
2022 retval = -ENOMEM; 2068 retval = -ENOMEM;
2023 goto error; 2069 goto err_destroy_dma;
2024 } 2070 }
2025 2071
2026 /* initialize ep0 status request structure */ 2072 /* initialize ep0 status request structure */
@@ -2028,7 +2074,7 @@ int mv_udc_probe(struct platform_device *dev)
2028 if (!udc->status_req) { 2074 if (!udc->status_req) {
2029 dev_err(&dev->dev, "allocate status_req memory failed\n"); 2075 dev_err(&dev->dev, "allocate status_req memory failed\n");
2030 retval = -ENOMEM; 2076 retval = -ENOMEM;
2031 goto error; 2077 goto err_free_eps;
2032 } 2078 }
2033 INIT_LIST_HEAD(&udc->status_req->queue); 2079 INIT_LIST_HEAD(&udc->status_req->queue);
2034 2080
@@ -2045,7 +2091,7 @@ int mv_udc_probe(struct platform_device *dev)
2045 if (r == NULL) { 2091 if (r == NULL) {
2046 dev_err(&dev->dev, "no IRQ resource defined\n"); 2092 dev_err(&dev->dev, "no IRQ resource defined\n");
2047 retval = -ENODEV; 2093 retval = -ENODEV;
2048 goto error; 2094 goto err_free_status_req;
2049 } 2095 }
2050 udc->irq = r->start; 2096 udc->irq = r->start;
2051 if (request_irq(udc->irq, mv_udc_irq, 2097 if (request_irq(udc->irq, mv_udc_irq,
@@ -2053,7 +2099,7 @@ int mv_udc_probe(struct platform_device *dev)
2053 dev_err(&dev->dev, "Request irq %d for UDC failed\n", 2099 dev_err(&dev->dev, "Request irq %d for UDC failed\n",
2054 udc->irq); 2100 udc->irq);
2055 retval = -ENODEV; 2101 retval = -ENODEV;
2056 goto error; 2102 goto err_free_status_req;
2057 } 2103 }
2058 2104
2059 /* initialize gadget structure */ 2105 /* initialize gadget structure */
@@ -2072,18 +2118,43 @@ int mv_udc_probe(struct platform_device *dev)
2072 2118
2073 retval = device_register(&udc->gadget.dev); 2119 retval = device_register(&udc->gadget.dev);
2074 if (retval) 2120 if (retval)
2075 goto error; 2121 goto err_free_irq;
2076 2122
2077 eps_init(udc); 2123 eps_init(udc);
2078 2124
2079 the_controller = udc;
2080
2081 retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); 2125 retval = usb_add_gadget_udc(&dev->dev, &udc->gadget);
2082 if (!retval) 2126 if (retval)
2083 return retval; 2127 goto err_unregister;
2084error: 2128
2085 if (udc) 2129 return 0;
2086 mv_udc_remove(udc->dev); 2130
2131err_unregister:
2132 device_unregister(&udc->gadget.dev);
2133err_free_irq:
2134 free_irq(udc->irq, &dev->dev);
2135err_free_status_req:
2136 kfree(udc->status_req->req.buf);
2137 kfree(udc->status_req);
2138err_free_eps:
2139 kfree(udc->eps);
2140err_destroy_dma:
2141 dma_pool_destroy(udc->dtd_pool);
2142err_free_dma:
2143 dma_free_coherent(&dev->dev, udc->ep_dqh_size,
2144 udc->ep_dqh, udc->ep_dqh_dma);
2145err_disable_clock:
2146 if (udc->pdata->phy_deinit)
2147 udc->pdata->phy_deinit(udc->phy_regs);
2148 udc_clock_disable(udc);
2149err_iounmap_phyreg:
2150 iounmap((void *)udc->phy_regs);
2151err_iounmap_capreg:
2152 iounmap(udc->cap_regs);
2153err_put_clk:
2154 for (clk_i--; clk_i >= 0; clk_i--)
2155 clk_put(udc->clk[clk_i]);
2156 the_controller = NULL;
2157 kfree(udc);
2087 return retval; 2158 return retval;
2088} 2159}
2089 2160
@@ -2102,11 +2173,16 @@ static int mv_udc_resume(struct device *_dev)
2102 struct mv_udc *udc = the_controller; 2173 struct mv_udc *udc = the_controller;
2103 int retval; 2174 int retval;
2104 2175
2105 retval = mv_udc_phy_init(udc->phy_regs); 2176 if (udc->pdata->phy_init) {
2106 if (retval) { 2177 retval = udc->pdata->phy_init(udc->phy_regs);
2107 dev_err(_dev, "phy initialization error %d\n", retval); 2178 if (retval) {
2108 return retval; 2179 dev_err(&udc->dev->dev,
2180 "init phy error %d when resume back\n",
2181 retval);
2182 return retval;
2183 }
2109 } 2184 }
2185
2110 udc_reset(udc); 2186 udc_reset(udc);
2111 ep0_reset(udc); 2187 ep0_reset(udc);
2112 udc_start(udc); 2188 udc_start(udc);
diff --git a/drivers/usb/gadget/mv_udc_phy.c b/drivers/usb/gadget/mv_udc_phy.c
deleted file mode 100644
index d4dea97e38a5..000000000000
--- a/drivers/usb/gadget/mv_udc_phy.c
+++ /dev/null
@@ -1,214 +0,0 @@
1#include <linux/delay.h>
2#include <linux/timer.h>
3#include <linux/io.h>
4#include <linux/errno.h>
5
6#include <mach/cputype.h>
7
8#ifdef CONFIG_ARCH_MMP
9
10#define UTMI_REVISION 0x0
11#define UTMI_CTRL 0x4
12#define UTMI_PLL 0x8
13#define UTMI_TX 0xc
14#define UTMI_RX 0x10
15#define UTMI_IVREF 0x14
16#define UTMI_T0 0x18
17#define UTMI_T1 0x1c
18#define UTMI_T2 0x20
19#define UTMI_T3 0x24
20#define UTMI_T4 0x28
21#define UTMI_T5 0x2c
22#define UTMI_RESERVE 0x30
23#define UTMI_USB_INT 0x34
24#define UTMI_DBG_CTL 0x38
25#define UTMI_OTG_ADDON 0x3c
26
27/* For UTMICTRL Register */
28#define UTMI_CTRL_USB_CLK_EN (1 << 31)
29/* pxa168 */
30#define UTMI_CTRL_SUSPEND_SET1 (1 << 30)
31#define UTMI_CTRL_SUSPEND_SET2 (1 << 29)
32#define UTMI_CTRL_RXBUF_PDWN (1 << 24)
33#define UTMI_CTRL_TXBUF_PDWN (1 << 11)
34
35#define UTMI_CTRL_INPKT_DELAY_SHIFT 30
36#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT 28
37#define UTMI_CTRL_PU_REF_SHIFT 20
38#define UTMI_CTRL_ARC_PULLDN_SHIFT 12
39#define UTMI_CTRL_PLL_PWR_UP_SHIFT 1
40#define UTMI_CTRL_PWR_UP_SHIFT 0
41/* For UTMI_PLL Register */
42#define UTMI_PLL_CLK_BLK_EN_SHIFT 24
43#define UTMI_PLL_FBDIV_SHIFT 4
44#define UTMI_PLL_REFDIV_SHIFT 0
45#define UTMI_PLL_FBDIV_MASK 0x00000FF0
46#define UTMI_PLL_REFDIV_MASK 0x0000000F
47#define UTMI_PLL_ICP_MASK 0x00007000
48#define UTMI_PLL_KVCO_MASK 0x00031000
49#define UTMI_PLL_PLLCALI12_SHIFT 29
50#define UTMI_PLL_PLLCALI12_MASK (0x3 << 29)
51#define UTMI_PLL_PLLVDD18_SHIFT 27
52#define UTMI_PLL_PLLVDD18_MASK (0x3 << 27)
53#define UTMI_PLL_PLLVDD12_SHIFT 25
54#define UTMI_PLL_PLLVDD12_MASK (0x3 << 25)
55#define UTMI_PLL_KVCO_SHIFT 15
56#define UTMI_PLL_ICP_SHIFT 12
57/* For UTMI_TX Register */
58#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT 27
59#define UTMI_TX_REG_EXT_FS_RCAL_MASK (0xf << 27)
60#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK 26
61#define UTMI_TX_REG_EXT_FS_RCAL_EN (0x1 << 26)
62#define UTMI_TX_LOW_VDD_EN_SHIFT 11
63#define UTMI_TX_IMPCAL_VTH_SHIFT 14
64#define UTMI_TX_IMPCAL_VTH_MASK (0x7 << 14)
65#define UTMI_TX_CK60_PHSEL_SHIFT 17
66#define UTMI_TX_CK60_PHSEL_MASK (0xf << 17)
67#define UTMI_TX_TXVDD12_SHIFT 22
68#define UTMI_TX_TXVDD12_MASK (0x3 << 22)
69#define UTMI_TX_AMP_SHIFT 0
70#define UTMI_TX_AMP_MASK (0x7 << 0)
71/* For UTMI_RX Register */
72#define UTMI_RX_SQ_THRESH_SHIFT 4
73#define UTMI_RX_SQ_THRESH_MASK (0xf << 4)
74#define UTMI_REG_SQ_LENGTH_SHIFT 15
75#define UTMI_REG_SQ_LENGTH_MASK (0x3 << 15)
76
77#define REG_RCAL_START 0x00001000
78#define VCOCAL_START 0x00200000
79#define KVCO_EXT 0x00400000
80#define PLL_READY 0x00800000
81#define CLK_BLK_EN 0x01000000
82#endif
83
84static unsigned int u2o_read(unsigned int base, unsigned int offset)
85{
86 return readl(base + offset);
87}
88
89static void u2o_set(unsigned int base, unsigned int offset, unsigned int value)
90{
91 unsigned int reg;
92
93 reg = readl(base + offset);
94 reg |= value;
95 writel(reg, base + offset);
96 readl(base + offset);
97}
98
99static void u2o_clear(unsigned int base, unsigned int offset,
100 unsigned int value)
101{
102 unsigned int reg;
103
104 reg = readl(base + offset);
105 reg &= ~value;
106 writel(reg, base + offset);
107 readl(base + offset);
108}
109
110static void u2o_write(unsigned int base, unsigned int offset,
111 unsigned int value)
112{
113 writel(value, base + offset);
114 readl(base + offset);
115}
116
117#ifdef CONFIG_ARCH_MMP
118int mv_udc_phy_init(unsigned int base)
119{
120 unsigned long timeout;
121
122 /* Initialize the USB PHY power */
123 if (cpu_is_pxa910()) {
124 u2o_set(base, UTMI_CTRL, (1 << UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
125 | (1 << UTMI_CTRL_PU_REF_SHIFT));
126 }
127
128 u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PLL_PWR_UP_SHIFT);
129 u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PWR_UP_SHIFT);
130
131 /* UTMI_PLL settings */
132 u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
133 | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
134 | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
135 | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);
136
137 u2o_set(base, UTMI_PLL, (0xee << UTMI_PLL_FBDIV_SHIFT)
138 | (0xb << UTMI_PLL_REFDIV_SHIFT)
139 | (3 << UTMI_PLL_PLLVDD18_SHIFT)
140 | (3 << UTMI_PLL_PLLVDD12_SHIFT)
141 | (3 << UTMI_PLL_PLLCALI12_SHIFT)
142 | (1 << UTMI_PLL_ICP_SHIFT) | (3 << UTMI_PLL_KVCO_SHIFT));
143
144 /* UTMI_TX */
145 u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
146 | UTMI_TX_TXVDD12_MASK
147 | UTMI_TX_CK60_PHSEL_MASK | UTMI_TX_IMPCAL_VTH_MASK
148 | UTMI_TX_REG_EXT_FS_RCAL_MASK | UTMI_TX_AMP_MASK);
149 u2o_set(base, UTMI_TX, (3 << UTMI_TX_TXVDD12_SHIFT)
150 | (4 << UTMI_TX_CK60_PHSEL_SHIFT)
151 | (4 << UTMI_TX_IMPCAL_VTH_SHIFT)
152 | (8 << UTMI_TX_REG_EXT_FS_RCAL_SHIFT)
153 | (3 << UTMI_TX_AMP_SHIFT));
154
155 /* UTMI_RX */
156 u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
157 | UTMI_REG_SQ_LENGTH_MASK);
158 if (cpu_is_pxa168())
159 u2o_set(base, UTMI_RX, (7 << UTMI_RX_SQ_THRESH_SHIFT)
160 | (2 << UTMI_REG_SQ_LENGTH_SHIFT));
161 else
162 u2o_set(base, UTMI_RX, (0x7 << UTMI_RX_SQ_THRESH_SHIFT)
163 | (2 << UTMI_REG_SQ_LENGTH_SHIFT));
164
165 /* UTMI_IVREF */
166 if (cpu_is_pxa168())
167 /*
168 * fixing Microsoft Altair board interface with NEC hub issue -
169 * Set UTMI_IVREF from 0x4a3 to 0x4bf
170 */
171 u2o_write(base, UTMI_IVREF, 0x4bf);
172
173 /* calibrate */
174 timeout = jiffies + 100;
175 while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) {
176 if (time_after(jiffies, timeout))
177 return -ETIME;
178 cpu_relax();
179 }
180
181 /* toggle VCOCAL_START bit of UTMI_PLL */
182 udelay(200);
183 u2o_set(base, UTMI_PLL, VCOCAL_START);
184 udelay(40);
185 u2o_clear(base, UTMI_PLL, VCOCAL_START);
186
187 /* toggle REG_RCAL_START bit of UTMI_TX */
188 udelay(200);
189 u2o_set(base, UTMI_TX, REG_RCAL_START);
190 udelay(40);
191 u2o_clear(base, UTMI_TX, REG_RCAL_START);
192 udelay(200);
193
194 /* make sure phy is ready */
195 timeout = jiffies + 100;
196 while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) {
197 if (time_after(jiffies, timeout))
198 return -ETIME;
199 cpu_relax();
200 }
201
202 if (cpu_is_pxa168()) {
203 u2o_set(base, UTMI_RESERVE, 1 << 5);
204 /* Turn on UTMI PHY OTG extension */
205 u2o_write(base, UTMI_OTG_ADDON, 1);
206 }
207 return 0;
208}
209#else
210int mv_udc_phy_init(unsigned int base)
211{
212 return 0;
213}
214#endif
diff --git a/include/linux/platform_data/mv_usb.h b/include/linux/platform_data/mv_usb.h
new file mode 100644
index 000000000000..e9d9149ddf38
--- /dev/null
+++ b/include/linux/platform_data/mv_usb.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#ifndef __MV_PLATFORM_USB_H
11#define __MV_PLATFORM_USB_H
12
13enum pxa_ehci_type {
14 EHCI_UNDEFINED = 0,
15 PXA_U2OEHCI, /* pxa 168, 9xx */
16 PXA_SPH, /* pxa 168, 9xx SPH */
17 MMP3_HSIC, /* mmp3 hsic */
18 MMP3_FSIC, /* mmp3 fsic */
19};
20
21enum {
22 MV_USB_MODE_OTG,
23 MV_USB_MODE_HOST,
24};
25
26enum {
27 VBUS_LOW = 0,
28 VBUS_HIGH = 1 << 0,
29};
30
31struct mv_usb_addon_irq {
32 unsigned int irq;
33 int (*poll)(void);
34};
35
36struct mv_usb_platform_data {
37 unsigned int clknum;
38 char **clkname;
39 struct mv_usb_addon_irq *id; /* Only valid for OTG. ID pin change*/
40 struct mv_usb_addon_irq *vbus; /* valid for OTG/UDC. VBUS change*/
41
42 /* only valid for HCD. OTG or Host only*/
43 unsigned int mode;
44
45 int (*phy_init)(unsigned int regbase);
46 void (*phy_deinit)(unsigned int regbase);
47 int (*set_vbus)(unsigned int vbus);
48};
49
50#endif